diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7f941da6b32..9cb0726ca08 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -8,8 +8,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/cache@v1 + - uses: actions/checkout@v2 + - uses: actions/cache@v2 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} @@ -24,31 +24,31 @@ jobs: - name: Build with Maven run: mvn -B package - name: Archive artifacts (Geyser Standalone) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 if: success() with: name: Geyser Standalone path: bootstrap/standalone/target/Geyser.jar - - name: Archive artifacts (Geyser Bukkit) - uses: actions/upload-artifact@v1 + - name: Archive artifacts (Geyser Spigot) + uses: actions/upload-artifact@v2 if: success() with: - name: Geyser Bukkit - path: bootstrap/bukkit/target/Geyser-Bukkit.jar + name: Geyser Spigot + path: bootstrap/spigot/target/Geyser-Spigot.jar - name: Archive artifacts (Geyser BungeeCord) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 if: success() with: name: Geyser BungeeCord path: bootstrap/bungeecord/target/Geyser-BungeeCord.jar - name: Archive artifacts (Geyser Sponge) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 if: success() with: name: Geyser Sponge path: bootstrap/sponge/target/Geyser-Sponge.jar - name: Archive artifacts (Geyser Velocity) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 if: success() with: name: Geyser Velocity diff --git a/.gitmodules b/.gitmodules index 0090e64ab87..207825e83fb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "connector/src/main/resources/mappings"] path = connector/src/main/resources/mappings url = https://github.com/GeyserMC/mappings.git + branch = feature/1.16 diff --git a/README.md b/README.md index 874c79f33a2..5cf34473de1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Geyser +Geyser [![forthebadge made-with-java](http://ForTheBadge.com/images/badges/made-with-java.svg)](https://java.com/) @@ -17,7 +17,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 now joined us here! -### Currently supporting Minecraft Bedrock v1.14.6(0) and Minecraft Java v1.15.2. +### Currently supporting Minecraft Bedrock v1.16.0 and Minecraft Java v1.16.1. ## Setting Up Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. @@ -37,7 +37,6 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set - [ ] Beacon - [ ] Cartography Table - [ ] Stonecutter - - [ ] Villager Trading - Some Entity Flags ## Compiling diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java deleted file mode 100644 index df98b408dba..00000000000 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2019-2020 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.platform.bukkit; - -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.Plugin; -import org.geysermc.connector.FloodgateKeyLoader; -import org.geysermc.connector.GeyserConfiguration; - -import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; - -public class GeyserBukkitConfiguration implements GeyserConfiguration { - - private FileConfiguration config; - private File dataFolder; - - private BukkitBedrockConfiguration bedrockConfig; - private BukkitRemoteConfiguration remoteConfig; - private BukkitMetricsInfo metricsInfo; - - private Map userAuthInfo = new HashMap<>(); - - private Path floodgateKey; - - public GeyserBukkitConfiguration(File dataFolder, FileConfiguration config) { - this.dataFolder = dataFolder; - this.config = config; - - bedrockConfig = new BukkitBedrockConfiguration(); - remoteConfig = new BukkitRemoteConfiguration(); - metricsInfo = new BukkitMetricsInfo(); - - if (!config.contains("userAuths")) - return; - - for (String key : config.getConfigurationSection("userAuths").getKeys(false)) { - userAuthInfo.put(key, new BukkitUserAuthenticationInfo(key)); - } - } - - public void loadFloodgate(GeyserBukkitPlugin plugin) { - Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate-bukkit"); - floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), config.getString("floodgate-key-file", "public-key.pem")), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null); - } - - @Override - public IBedrockConfiguration getBedrock() { - return bedrockConfig; - } - - @Override - public IRemoteConfiguration getRemote() { - return remoteConfig; - } - - @Override - public Map getUserAuths() { - return userAuthInfo; - } - - @Override - public boolean isCommandSuggestions() { - return config.getBoolean("command-suggestions", true); - } - - @Override - public boolean isPassthroughMotd() { - return config.getBoolean("passthrough-motd", false); - } - - @Override - public boolean isPassthroughPlayerCounts() { - return config.getBoolean("passthrough-player-counts", false); - } - - @Override - public boolean isLegacyPingPassthrough() { - return config.getBoolean("legacy-ping-passthrough", false); - } - - @Override - public int getPingPassthroughInterval() { - return config.getInt("ping-passthrough-interval", 3); - } - - @Override - public int getMaxPlayers() { - return config.getInt("max-players", 10); - } - - @Override - public boolean isDebugMode() { - return config.getBoolean("debug-mode", false); - } - - @Override - public int getGeneralThreadPool() { - return config.getInt("general-thread-pool", 32); - } - - @Override - public boolean isAllowThirdPartyCapes() { - return config.getBoolean("allow-third-party-capes", true); - } - - @Override - public boolean isAllowThirdPartyEars() { - return config.getBoolean("allow-third-party-ears", false); - } - - @Override - public String getDefaultLocale() { - return config.getString("default-locale", "en_us"); - } - - @Override - public Path getFloodgateKeyFile() { - return floodgateKey; - } - - @Override - public boolean isCacheChunks() { - return true; // We override this as with Bukkit, we have direct access to the server implementation - } - - @Override - public boolean isAboveBedrockNetherBuilding() { - return config.getBoolean("above-bedrock-nether-building", false); - } - - @Override - public IMetricsInfo getMetrics() { - return metricsInfo; - } - - public class BukkitBedrockConfiguration implements IBedrockConfiguration { - - @Override - public String getAddress() { - return config.getString("bedrock.address", "0.0.0.0"); - } - - @Override - public int getPort() { - return config.getInt("bedrock.port", 25565); - } - - @Override - public String getMotd1() { - return config.getString("bedrock.motd1", "GeyserMC"); - } - - @Override - public String getMotd2() { - return config.getString("bedrock.motd2", "GeyserMC"); - } - } - - public class BukkitRemoteConfiguration implements IRemoteConfiguration { - - @Override - public String getAddress() { - return config.getString("remote.address", "127.0.0.1"); - } - - @Override - public int getPort() { - return config.getInt("remote.port", 25565); - } - - @Override - public String getAuthType() { - return config.getString("remote.auth-type", "online"); - } - } - - public class BukkitUserAuthenticationInfo implements IUserAuthenticationInfo { - - private String key; - - public BukkitUserAuthenticationInfo(String key) { - this.key = key; - } - - @Override - public String getEmail() { - return config.getString("userAuths." + key + ".email"); - } - - @Override - public String getPassword() { - return config.getString("userAuths." + key + ".password"); - } - } - - public class BukkitMetricsInfo implements IMetricsInfo { - - @Override - public boolean isEnabled() { - return config.getBoolean("metrics.enabled", true); - } - - @Override - public String getUniqueId() { - return config.getString("metrics.uuid", "generateduuid"); - } - } - - @Override - public int getConfigVersion() { - return config.getInt("config-version", 0); - } -} diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml index dd66db322ac..875991fa0e6 100644 --- a/bootstrap/bungeecord/pom.xml +++ b/bootstrap/bungeecord/pom.xml @@ -65,6 +65,10 @@ io.netty org.geysermc.platform.bungeecord.shaded.netty + + org.reflections.reflections + org.geysermc.platform.bungeecord.shaded.reflections + diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java index d983aec1c0d..839fc185de6 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java @@ -25,216 +25,29 @@ package org.geysermc.platform.bungeecord; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.config.Configuration; import org.geysermc.connector.FloodgateKeyLoader; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.configuration.GeyserJacksonConfiguration; -import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -public class GeyserBungeeConfiguration implements GeyserConfiguration { - - private File dataFolder; - private Configuration config; - - private BungeeBedrockConfiguration bedrockConfig; - private BungeeRemoteConfiguration remoteConfig; - private BungeeMetricsInfo metricsInfo; - - private Map userAuthInfo = new HashMap<>(); +@Getter +@JsonIgnoreProperties(ignoreUnknown = true) +public class GeyserBungeeConfiguration extends GeyserJacksonConfiguration { private Path floodgateKey; - public GeyserBungeeConfiguration(File dataFolder, Configuration config) { - this.dataFolder = dataFolder; - this.config = config; - - bedrockConfig = new BungeeBedrockConfiguration(); - remoteConfig = new BungeeRemoteConfiguration(); - metricsInfo = new BungeeMetricsInfo(); - - if (!config.contains("userAuths")) - return; - - for (String key : config.getSection("userAuths").getKeys()) { - userAuthInfo.put(key, new BungeeUserAuthenticationInfo(key)); - } - } - - public void loadFloodgate(GeyserBungeePlugin plugin) { + public void loadFloodgate(GeyserBungeePlugin plugin, Configuration configuration) { Plugin floodgate = plugin.getProxy().getPluginManager().getPlugin("floodgate-bungee"); - floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), config.getString("floodgate-key-file", "public-key.pem")), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null); - } - - @Override - public BungeeBedrockConfiguration getBedrock() { - return bedrockConfig; - } - - @Override - public BungeeRemoteConfiguration getRemote() { - return remoteConfig; - } - - @Override - public Map getUserAuths() { - return userAuthInfo; - } - - @Override - public boolean isCommandSuggestions() { - return config.getBoolean("command-suggestions", true); - } - - @Override - public boolean isPassthroughMotd() { - return config.getBoolean("passthrough-motd", false); - } - - @Override - public boolean isPassthroughPlayerCounts() { - return config.getBoolean("passthrough-player-counts", false); - } - - @Override - public boolean isLegacyPingPassthrough() { - return config.getBoolean("legacy-ping-passthrough", false); - } - - @Override - public int getPingPassthroughInterval() { - return config.getInt("ping-passthrough-interval", 3); - } - - @Override - public int getMaxPlayers() { - return config.getInt("max-players", 10); - } - - @Override - public boolean isDebugMode() { - return config.getBoolean("debug-mode", false); - } - - @Override - public int getGeneralThreadPool() { - return config.getInt("general-thread-pool", 32); - } - - @Override - public boolean isAllowThirdPartyCapes() { - return config.getBoolean("allow-third-party-capes", true); - } - - @Override - public boolean isAllowThirdPartyEars() { - return config.getBoolean("allow-third-party-ears", false); - } - - @Override - public String getDefaultLocale() { - return config.getString("default-locale", "en_us"); + floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(plugin.getDataFolder().toString(), configuration.getString("floodgate-key-file"), "public-key.pem"), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null); } @Override public Path getFloodgateKeyFile() { return floodgateKey; } - - @Override - public boolean isCacheChunks() { - return config.getBoolean("cache-chunks", false); - } - - @Override - public boolean isAboveBedrockNetherBuilding() { - return config.getBoolean("above-bedrock-nether-building", false); - } - - @Override - public BungeeMetricsInfo getMetrics() { - return metricsInfo; - } - - public class BungeeBedrockConfiguration implements IBedrockConfiguration { - - @Override - public String getAddress() { - return config.getString("bedrock.address", "0.0.0.0"); - } - - @Override - public int getPort() { - return config.getInt("bedrock.port", 25565); - } - - @Override - public String getMotd1() { - return config.getString("bedrock.motd1", "GeyserMC"); - } - - @Override - public String getMotd2() { - return config.getString("bedrock.motd2", "GeyserMC"); - } - } - - public class BungeeRemoteConfiguration implements IRemoteConfiguration { - - @Override - public String getAddress() { - return config.getString("remote.address", "127.0.0.1"); - } - - @Override - public int getPort() { - return config.getInt("remote.port", 25565); - } - - @Override - public String getAuthType() { - return config.getString("remote.auth-type", "online"); - } - } - - public class BungeeUserAuthenticationInfo implements IUserAuthenticationInfo { - - private String key; - - public BungeeUserAuthenticationInfo(String key) { - this.key = key; - } - - @Override - public String getEmail() { - return config.getString("userAuths." + key + ".email"); - } - - @Override - public String getPassword() { - return config.getString("userAuths." + key + ".password"); - } - } - - public class BungeeMetricsInfo implements IMetricsInfo { - - @Override - public boolean isEnabled() { - return config.getBoolean("metrics.enabled", true); - } - - @Override - public String getUniqueId() { - return config.getString("metrics.uuid", "generateduuid"); - } - } - - @Override - public int getConfigVersion() { - return config.getInt("config-version", 0); - } } diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeDumpInfo.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeDumpInfo.java new file mode 100644 index 00000000000..54701116276 --- /dev/null +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeDumpInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019-2020 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.platform.bungeecord; + +import lombok.Getter; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.plugin.Plugin; +import org.geysermc.connector.dump.BootstrapDumpInfo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Getter +public class GeyserBungeeDumpInfo extends BootstrapDumpInfo { + + private String platformName; + private String platformVersion; + private boolean onlineMode; + private List listeners; + private List plugins; + + GeyserBungeeDumpInfo(ProxyServer proxy) { + super(); + this.platformName = proxy.getName(); + this.platformVersion = proxy.getVersion(); + this.onlineMode = proxy.getConfig().isOnlineMode(); + this.listeners = new ArrayList<>(); + this.plugins = new ArrayList<>(); + + for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) { + this.listeners.add(new ListenerInfo(listener.getHost().getHostString(), listener.getHost().getPort())); + } + + for (Plugin plugin : proxy.getPluginManager().getPlugins()) { + this.plugins.add(new PluginInfo(true, plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), Arrays.asList(plugin.getDescription().getAuthor()))); + } + } +} diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeMain.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeMain.java index eabbcc6984b..999b29eaffc 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeMain.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeMain.java @@ -26,7 +26,7 @@ package org.geysermc.platform.bungeecord; -import org.geysermc.common.main.IGeyserMain; +import org.geysermc.connector.common.main.IGeyserMain; public class GeyserBungeeMain extends IGeyserMain { diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePingPassthrough.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePingPassthrough.java index c7f8f276296..ab400052092 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePingPassthrough.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePingPassthrough.java @@ -35,7 +35,7 @@ import net.md_5.bungee.api.event.ProxyPingEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.protocol.ProtocolConstants; -import org.geysermc.common.ping.GeyserPingInfo; +import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; import java.net.Inet4Address; diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java index 525b9b6db42..ac718cbaee2 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java @@ -30,21 +30,22 @@ import net.md_5.bungee.config.Configuration; import net.md_5.bungee.config.ConfigurationProvider; import net.md_5.bungee.config.YamlConfiguration; -import org.geysermc.common.PlatformType; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.configuration.GeyserConfiguration; +import org.geysermc.connector.dump.BootstrapDumpInfo; import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; +import org.geysermc.connector.utils.FileUtils; import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor; import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.net.InetSocketAddress; -import java.nio.file.Files; +import java.nio.file.Path; import java.util.UUID; import java.util.logging.Level; @@ -62,32 +63,18 @@ public void onEnable() { if (!getDataFolder().exists()) getDataFolder().mkdir(); - File file = new File(getDataFolder(), "config.yml"); Configuration configuration = null; - - if (!file.exists()) { - try (InputStream in = getResourceAsStream("config.yml")) { - Files.copy(in, file.toPath()); - } catch (IOException ex) { - getLogger().log(Level.SEVERE, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); - return; - } - } try { + if (!getDataFolder().exists()) + getDataFolder().mkdir(); + File configFile = FileUtils.fileOrCopiedFromResource(new File(getDataFolder(), "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); + this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class); configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "config.yml")); - } catch(IOException e) { - e.printStackTrace(); - } - - if (configuration == null) { - getLogger().severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!"); - return; + } catch (IOException ex) { + getLogger().log(Level.WARNING, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + ex.printStackTrace(); } - this.geyserConfig = new GeyserBungeeConfiguration(getDataFolder(), configuration); - - boolean configHasChanged = false; - if (getProxy().getConfig().getListeners().size() == 1) { ListenerInfo listener = getProxy().getConfig().getListeners().toArray(new ListenerInfo[0])[0]; @@ -96,33 +83,21 @@ public void onEnable() { // Don't change the ip if its listening on all interfaces // By default this should be 127.0.0.1 but may need to be changed in some circumstances if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) { - configuration.set("remote.address", javaAddr.getHostString()); + this.geyserConfig.getRemote().setAddress(javaAddr.getHostString()); } - configuration.set("remote.port", javaAddr.getPort()); - - configHasChanged = true; - } - - if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) { - configuration.set("metrics.uuid", UUID.randomUUID().toString()); - - configHasChanged = true; - } - - if (configHasChanged) { - try { - ConfigurationProvider.getProvider(YamlConfiguration.class).save(configuration, new File(getDataFolder(), "config.yml")); - } catch (IOException ex) { - getLogger().log(Level.SEVERE, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); - return; - } + this.geyserConfig.getRemote().setPort(javaAddr.getPort()); } this.geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); - geyserConfig.loadFloodgate(this); + if (geyserConfig.getRemote().getAuthType().equals("floodgate") && getProxy().getPluginManager().getPlugin("floodgate-bungee") == null) { + geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling..."); + return; + } + + geyserConfig.loadFloodgate(this, configuration); this.connector = GeyserConnector.start(PlatformType.BUNGEECORD, this); @@ -161,4 +136,14 @@ public CommandManager getGeyserCommandManager() { public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserBungeePingPassthrough; } + + @Override + public Path getConfigFolder() { + return getDataFolder().toPath(); + } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserBungeeDumpInfo(getProxy()); + } } diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 6d12b6732d4..87302d4d82c 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -35,8 +35,8 @@ - bukkit bungeecord + spigot sponge standalone velocity diff --git a/bootstrap/bukkit/pom.xml b/bootstrap/spigot/pom.xml similarity index 78% rename from bootstrap/bukkit/pom.xml rename to bootstrap/spigot/pom.xml index 1f831d6733a..6439eb23326 100644 --- a/bootstrap/bukkit/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -9,7 +9,7 @@ 1.0-SNAPSHOT ../ - bootstrap-bukkit + bootstrap-spigot org.geysermc @@ -26,12 +26,12 @@ us.myles viaversion - 3.0.0-SNAPSHOT + 3.0.1 provided - ${outputName}-Bukkit + ${outputName}-Spigot src/main/resources/ @@ -46,7 +46,7 @@ - org.geysermc.platform.bukkit.GeyserBukkitMain + org.geysermc.platform.spigot.GeyserSpigotMain @@ -65,11 +65,19 @@ io.netty - org.geysermc.platform.bukkit.shaded.netty + org.geysermc.platform.spigot.shaded.netty it.unimi.dsi.fastutil - org.geysermc.platform.bukkit.shaded.fastutil + org.geysermc.platform.spigot.shaded.fastutil + + + com.fasterxml.jackson + org.geysermc.platform.spigot.shaded.jackson + + + org.reflections.reflections + org.geysermc.platform.spigot.shaded.reflections diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotConfiguration.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotConfiguration.java new file mode 100644 index 00000000000..9a681156299 --- /dev/null +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotConfiguration.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2020 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.platform.spigot; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.geysermc.connector.FloodgateKeyLoader; +import org.geysermc.connector.configuration.GeyserJacksonConfiguration; + +import java.nio.file.Path; +import java.nio.file.Paths; + +@Getter +@JsonIgnoreProperties(ignoreUnknown = true) +public class GeyserSpigotConfiguration extends GeyserJacksonConfiguration { + + @JsonProperty("floodgate-key-file") + private String floodgateKeyFile; + + private Path floodgateKey; + + public void loadFloodgate(GeyserSpigotPlugin plugin) { + Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate-bukkit"); + floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(plugin.getDataFolder().toString(), plugin.getConfig().getString("floodgate-key-file", "public-key.pem")), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null); + } + + @Override + public Path getFloodgateKeyFile() { + return floodgateKey; + } + + @Override + public boolean isCacheChunks() { + return true; // We override this as with Bukkit, we have direct access to the server implementation + } +} diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotDumpInfo.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotDumpInfo.java new file mode 100644 index 00000000000..01d513fa85c --- /dev/null +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotDumpInfo.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019-2020 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.platform.spigot; + +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.geysermc.connector.dump.BootstrapDumpInfo; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class GeyserSpigotDumpInfo extends BootstrapDumpInfo { + + private String platformName; + private String platformVersion; + private String platformAPIVersion; + private boolean onlineMode; + private String serverIP; + private int serverPort; + private List plugins; + + GeyserSpigotDumpInfo() { + super(); + this.platformName = Bukkit.getName(); + this.platformVersion = Bukkit.getVersion(); + this.platformAPIVersion = Bukkit.getBukkitVersion(); + this.onlineMode = Bukkit.getOnlineMode(); + this.serverIP = Bukkit.getIp(); + this.serverPort = Bukkit.getPort(); + this.plugins = new ArrayList<>(); + + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + this.plugins.add(new PluginInfo(plugin.isEnabled(), plugin.getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), plugin.getDescription().getAuthors())); + } + } +} diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotLogger.java similarity index 95% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotLogger.java index 08822568c44..252d6bbed33 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotLogger.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.platform.bukkit; +package org.geysermc.platform.spigot; import lombok.AllArgsConstructor; @@ -33,7 +33,7 @@ import java.util.logging.Logger; @AllArgsConstructor -public class GeyserBukkitLogger implements GeyserLogger { +public class GeyserSpigotLogger implements GeyserLogger { private Logger logger; private boolean debugMode; diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitMain.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java similarity index 88% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitMain.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java index b6da66c1b59..15826d334fe 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitMain.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java @@ -24,14 +24,14 @@ * */ -package org.geysermc.platform.bukkit; +package org.geysermc.platform.spigot; -import org.geysermc.common.main.IGeyserMain; +import org.geysermc.connector.common.main.IGeyserMain; -public class GeyserBukkitMain extends IGeyserMain { +public class GeyserSpigotMain extends IGeyserMain { public static void main(String[] args) { - new GeyserBukkitMain().displayMessage(); + new GeyserSpigotMain().displayMessage(); } public String getPluginType() { diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPingPassthrough.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java similarity index 93% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPingPassthrough.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java index 812467be785..07999d87617 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPingPassthrough.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java @@ -24,14 +24,14 @@ * */ -package org.geysermc.platform.bukkit; +package org.geysermc.platform.spigot; import lombok.AllArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.util.CachedServerIcon; -import org.geysermc.common.ping.GeyserPingInfo; +import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; import java.net.InetAddress; @@ -39,9 +39,9 @@ import java.util.Iterator; @AllArgsConstructor -public class GeyserBukkitPingPassthrough implements IGeyserPingPassthrough { +public class GeyserSpigotPingPassthrough implements IGeyserPingPassthrough { - private final GeyserBukkitLogger logger; + private final GeyserSpigotLogger logger; @Override public GeyserPingInfo getPingInformation() { diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java similarity index 55% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index 5f0e967a2f2..de2b7186c5e 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -23,106 +23,119 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.platform.bukkit; +package org.geysermc.platform.spigot; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; -import org.geysermc.common.PlatformType; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.configuration.GeyserConfiguration; +import org.geysermc.connector.dump.BootstrapDumpInfo; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; -import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor; -import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager; -import org.geysermc.platform.bukkit.world.GeyserBukkitBlockPlaceListener; -import org.geysermc.platform.bukkit.world.GeyserBukkitWorldManager; -import us.myles.ViaVersion.api.Via; - +import org.geysermc.connector.utils.FileUtils; +import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor; +import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager; +import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener; +import org.geysermc.platform.spigot.world.GeyserSpigotWorldManager; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.UUID; +import java.util.logging.Level; -public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { +public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { - private GeyserBukkitCommandManager geyserCommandManager; - private GeyserBukkitConfiguration geyserConfig; - private GeyserBukkitLogger geyserLogger; - private IGeyserPingPassthrough geyserBukkitPingPassthrough; - private GeyserBukkitBlockPlaceListener blockPlaceListener; - private GeyserBukkitWorldManager geyserWorldManager; + private GeyserSpigotCommandManager geyserCommandManager; + private GeyserSpigotConfiguration geyserConfig; + private GeyserSpigotLogger geyserLogger; + private IGeyserPingPassthrough geyserSpigotPingPassthrough; + private GeyserSpigotBlockPlaceListener blockPlaceListener; + private GeyserSpigotWorldManager geyserWorldManager; private GeyserConnector connector; @Override public void onEnable() { - saveDefaultConfig(); - - this.geyserConfig = new GeyserBukkitConfiguration(getDataFolder(), getConfig()); - if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) { - getConfig().set("metrics.uuid", UUID.randomUUID().toString()); - saveConfig(); + // This is manually done instead of using Bukkit methods to save the config because otherwise comments get removed + try { + if (!getDataFolder().exists()) { + getDataFolder().mkdir(); + File bukkitConfig = new File("plugins/Geyser-Bukkit/config.yml"); + if (bukkitConfig.exists()) { // Copy over old configs + getLogger().log(Level.INFO, "Existing config found in the Geyser-Bukkit folder; copying over..."); + Files.copy(bukkitConfig.toPath(), new File(getDataFolder().toString() + "/config.yml").toPath()); + getLogger().log(Level.INFO, "Copied!"); + } + } + File configFile = FileUtils.fileOrCopiedFromResource(new File(getDataFolder(), "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); + this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpigotConfiguration.class); + } catch (IOException ex) { + getLogger().log(Level.WARNING, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + ex.printStackTrace(); } // Don't change the ip if its listening on all interfaces // By default this should be 127.0.0.1 but may need to be changed in some circumstances if (!Bukkit.getIp().equals("0.0.0.0") && !Bukkit.getIp().equals("")) { - getConfig().set("remote.address", Bukkit.getIp()); + geyserConfig.getRemote().setAddress(Bukkit.getIp()); } - getConfig().set("remote.port", Bukkit.getPort()); - saveConfig(); + geyserConfig.getRemote().setPort(Bukkit.getPort()); - this.geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode()); + this.geyserLogger = new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); + if (geyserConfig.getRemote().getAuthType().equals("floodgate") && Bukkit.getPluginManager().getPlugin("floodgate-bukkit") == null) { + geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling..."); + this.getPluginLoader().disablePlugin(this); + return; + } + geyserConfig.loadFloodgate(this); - this.connector = GeyserConnector.start(PlatformType.BUKKIT, this); + this.connector = GeyserConnector.start(PlatformType.SPIGOT, this); if (geyserConfig.isLegacyPingPassthrough()) { - this.geyserBukkitPingPassthrough = GeyserLegacyPingPassthrough.init(connector); + this.geyserSpigotPingPassthrough = GeyserLegacyPingPassthrough.init(connector); } else { - this.geyserBukkitPingPassthrough = new GeyserBukkitPingPassthrough(geyserLogger); + this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger); } - this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector); + this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector); - boolean isViaVersion = false; + boolean isViaVersion = (Bukkit.getPluginManager().getPlugin("ViaVersion") != null); // Used to determine if Block.getBlockData() is present. boolean isLegacy = !isCompatible(Bukkit.getServer().getVersion(), "1.13.0"); if (isLegacy) geyserLogger.debug("Legacy version of Minecraft (1.12.2 or older) detected."); - if (Bukkit.getPluginManager().getPlugin("ViaVersion") != null) { - // TODO: Update when ViaVersion updates - // API changes between 2.2.3 and 3.0.0-SNAPSHOT require this check - if (!Via.getAPI().getVersion().equals("3.0.0-SNAPSHOT") && isLegacy) { - geyserLogger.info("ViaVersion detected but not ViaVersion-ABSTRACTION. Please update your ViaVersion plugin for compatibility with Geyser."); - } else { - isViaVersion = true; - } - } + this.geyserWorldManager = new GeyserSpigotWorldManager(isLegacy, isViaVersion); + this.blockPlaceListener = new GeyserSpigotBlockPlaceListener(connector, isLegacy, isViaVersion); - this.geyserWorldManager = new GeyserBukkitWorldManager(isLegacy, isViaVersion); - this.blockPlaceListener = new GeyserBukkitBlockPlaceListener(connector, isLegacy, isViaVersion); Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this); - this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector)); + this.getCommand("geyser").setExecutor(new GeyserSpigotCommandExecutor(connector)); } @Override public void onDisable() { - connector.shutdown(); + if (connector != null) + connector.shutdown(); } @Override - public GeyserBukkitConfiguration getGeyserConfig() { + public GeyserSpigotConfiguration getGeyserConfig() { return geyserConfig; } @Override - public GeyserBukkitLogger getGeyserLogger() { + public GeyserSpigotLogger getGeyserLogger() { return geyserLogger; } @@ -133,7 +146,7 @@ public CommandManager getGeyserCommandManager() { @Override public IGeyserPingPassthrough getGeyserPingPassthrough() { - return geyserBukkitPingPassthrough; + return geyserSpigotPingPassthrough; } @Override @@ -141,6 +154,11 @@ public WorldManager getWorldManager() { return this.geyserWorldManager; } + @Override + public Path getConfigFolder() { + return getDataFolder().toPath(); + } + public boolean isCompatible(String version, String whichVersion) { int[] currentVersion = parseVersion(version); int[] otherVersion = parseVersion(whichVersion); @@ -174,4 +192,9 @@ private int[] parseVersion(String versionParam) { } return temp; } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserSpigotDumpInfo(); + } } diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandExecutor.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java similarity index 91% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandExecutor.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java index d2603f7c59e..b956a0d8428 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandExecutor.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.platform.bukkit.command; +package org.geysermc.platform.spigot.command; import lombok.AllArgsConstructor; @@ -39,7 +39,7 @@ import java.util.List; @AllArgsConstructor -public class GeyserBukkitCommandExecutor implements TabExecutor { +public class GeyserSpigotCommandExecutor implements TabExecutor { private GeyserConnector connector; @@ -51,11 +51,11 @@ public boolean onCommand(CommandSender sender, Command command, String label, St sender.sendMessage(ChatColor.RED + "You do not have permission to execute this command!"); return true; } - getCommand(args[0]).execute(new BukkitCommandSender(sender), args); + getCommand(args[0]).execute(new SpigotCommandSender(sender), args); return true; } } else { - getCommand("help").execute(new BukkitCommandSender(sender), args); + getCommand("help").execute(new SpigotCommandSender(sender), args); return true; } return true; diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandManager.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandManager.java similarity index 88% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandManager.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandManager.java index b826ab1f58d..2fbec1562ed 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandManager.java @@ -23,18 +23,18 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.platform.bukkit.command; +package org.geysermc.platform.spigot.command; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandMap; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandManager; -import org.geysermc.platform.bukkit.GeyserBukkitPlugin; +import org.geysermc.platform.spigot.GeyserSpigotPlugin; import java.lang.reflect.Field; -public class GeyserBukkitCommandManager extends CommandManager { +public class GeyserSpigotCommandManager extends CommandManager { private static CommandMap COMMAND_MAP; @@ -48,9 +48,9 @@ public class GeyserBukkitCommandManager extends CommandManager { } } - private GeyserBukkitPlugin plugin; + private GeyserSpigotPlugin plugin; - public GeyserBukkitCommandManager(GeyserBukkitPlugin plugin, GeyserConnector connector) { + public GeyserSpigotCommandManager(GeyserSpigotPlugin plugin, GeyserConnector connector) { super(connector); this.plugin = plugin; diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/BukkitCommandSender.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/SpigotCommandSender.java similarity index 94% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/BukkitCommandSender.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/SpigotCommandSender.java index 05e371e5aa8..55475a3037f 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/command/BukkitCommandSender.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/SpigotCommandSender.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.platform.bukkit.command; +package org.geysermc.platform.spigot.command; import lombok.AllArgsConstructor; @@ -31,7 +31,7 @@ import org.geysermc.connector.command.CommandSender; @AllArgsConstructor -public class BukkitCommandSender implements CommandSender { +public class SpigotCommandSender implements CommandSender { private org.bukkit.command.CommandSender handle; diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java similarity index 95% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java index 76d1564ea9d..f17a97e3766 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java @@ -24,7 +24,7 @@ * */ -package org.geysermc.platform.bukkit.world; +package org.geysermc.platform.spigot.world; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.SoundEvent; @@ -39,7 +39,7 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator; @AllArgsConstructor -public class GeyserBukkitBlockPlaceListener implements Listener { +public class GeyserSpigotBlockPlaceListener implements Listener { private final GeyserConnector connector; private final boolean isLegacy; @@ -55,7 +55,7 @@ public void place(final BlockPlaceEvent event) { placeBlockSoundPacket.setBabySound(false); String javaBlockId; if (isLegacy) { - javaBlockId = BlockTranslator.getJavaIdBlockMap().inverse().get(GeyserBukkitWorldManager.getLegacyBlock(session, + javaBlockId = BlockTranslator.getJavaIdBlockMap().inverse().get(GeyserSpigotWorldManager.getLegacyBlock(session, event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ(), isViaVersion)); } else { javaBlockId = event.getBlockPlaced().getBlockData().getAsString(); diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotWorldManager.java similarity index 83% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotWorldManager.java index fbdf2a47b32..d785fabca6a 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotWorldManager.java @@ -24,23 +24,19 @@ * */ -package org.geysermc.platform.bukkit.world; - -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +package org.geysermc.platform.spigot.world; import lombok.AllArgsConstructor; -import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.network.translators.world.block.BlockTranslator; -import org.geysermc.platform.bukkit.GeyserBukkitPlugin; import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13; -import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData; +import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.data.MappingData; @AllArgsConstructor -public class GeyserBukkitWorldManager extends WorldManager { +public class GeyserSpigotWorldManager extends WorldManager { private final boolean isLegacy; // You need ViaVersion to connect to an older server with Geyser. @@ -48,7 +44,7 @@ public class GeyserBukkitWorldManager extends WorldManager { private final boolean isViaVersion; @Override - public BlockState getBlockAt(GeyserSession session, int x, int y, int z) { + public int getBlockAt(GeyserSession session, int x, int y, int z) { if (session.getPlayerEntity() == null) { return BlockTranslator.AIR; } @@ -59,16 +55,17 @@ public BlockState getBlockAt(GeyserSession session, int x, int y, int z) { } @SuppressWarnings("deprecation") - public static BlockState getLegacyBlock(GeyserSession session, int x, int y, int z, boolean isViaVersion) { + public static int getLegacyBlock(GeyserSession session, int x, int y, int z, boolean isViaVersion) { if (isViaVersion) { Block block = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z); // Black magic that gets the old block state ID int oldBlockId = (block.getType().getId() << 4) | (block.getData() & 0xF); - // Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 + // Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 int thirteenBlockId = us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.blockMappings.getNewId(oldBlockId); int thirteenPointOneBlockId = Protocol1_13_1To1_13.getNewBlockStateId(thirteenBlockId); int fourteenBlockId = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.blockStateMappings.getNewId(thirteenPointOneBlockId); - return new BlockState(MappingData.blockStateMappings.getNewId(fourteenBlockId)); + int fifteenBlockId = us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData.blockStateMappings.getNewId(fourteenBlockId); + return MappingData.blockStateMappings.getNewId(fifteenBlockId); } else { return BlockTranslator.AIR; } diff --git a/bootstrap/bukkit/src/main/resources/plugin.yml b/bootstrap/spigot/src/main/resources/plugin.yml similarity index 74% rename from bootstrap/bukkit/src/main/resources/plugin.yml rename to bootstrap/spigot/src/main/resources/plugin.yml index 89c90789e74..fee71ab1f08 100644 --- a/bootstrap/bukkit/src/main/resources/plugin.yml +++ b/bootstrap/spigot/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ -main: org.geysermc.platform.bukkit.GeyserBukkitPlugin -name: ${outputName}-Bukkit +main: org.geysermc.platform.spigot.GeyserSpigotPlugin +name: ${outputName}-Spigot author: ${project.organization.name} website: ${project.organization.url} version: ${project.version} diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml index c9abbe3eda5..4a995711a83 100644 --- a/bootstrap/sponge/pom.xml +++ b/bootstrap/sponge/pom.xml @@ -69,6 +69,10 @@ it.unimi.dsi.fastutil org.geysermc.platform.sponge.shaded.fastutil + + org.reflections.reflections + org.geysermc.platform.sponge.shaded.reflections + diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java index fc14847081b..79e7621cca1 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java @@ -29,7 +29,7 @@ import ninja.leaping.configurate.ConfigurationNode; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.configuration.GeyserConfiguration; import java.io.File; import java.nio.file.Path; @@ -129,6 +129,11 @@ public boolean isAllowThirdPartyEars() { return node.getNode("allow-third-party-ears").getBoolean(false); } + @Override + public boolean isShowCooldown() { + return node.getNode("show-cooldown").getBoolean(true); + } + @Override public String getDefaultLocale() { return node.getNode("default-locale").getString("en_us"); diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeDumpInfo.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeDumpInfo.java new file mode 100644 index 00000000000..e8f0feaef2c --- /dev/null +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeDumpInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019-2020 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.platform.sponge; + +import lombok.Getter; +import org.geysermc.connector.dump.BootstrapDumpInfo; +import org.spongepowered.api.Platform; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.plugin.PluginContainer; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class GeyserSpongeDumpInfo extends BootstrapDumpInfo { + + private String platformName; + private String platformVersion; + private boolean onlineMode; + private String serverIP; + private int serverPort; + private List plugins; + + GeyserSpongeDumpInfo() { + super(); + PluginContainer container = Sponge.getPlatform().getContainer(Platform.Component.IMPLEMENTATION); + this.platformName = container.getName(); + this.platformVersion = container.getVersion().get(); + this.onlineMode = Sponge.getServer().getOnlineMode(); + this.serverIP = Sponge.getServer().getBoundAddress().get().getHostString(); + this.serverPort = Sponge.getServer().getBoundAddress().get().getPort(); + this.plugins = new ArrayList<>(); + + for (PluginContainer plugin : Sponge.getPluginManager().getPlugins()) { + String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown"); + this.plugins.add(new PluginInfo(true, plugin.getName(), plugin.getVersion().get(), pluginClass, plugin.getAuthors())); + } + } +} diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeMain.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeMain.java index 11b9583f9f8..1c9605d0ab7 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeMain.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeMain.java @@ -26,7 +26,7 @@ package org.geysermc.platform.sponge; -import org.geysermc.common.main.IGeyserMain; +import org.geysermc.connector.common.main.IGeyserMain; public class GeyserSpongeMain extends IGeyserMain { diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePingPassthrough.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePingPassthrough.java index 31b6dc7fba5..99e8ed2f26b 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePingPassthrough.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePingPassthrough.java @@ -26,7 +26,7 @@ package org.geysermc.platform.sponge; -import org.geysermc.common.ping.GeyserPingInfo; +import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.spongepowered.api.MinecraftVersion; import org.spongepowered.api.Sponge; diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java index d226add77cc..4214255e830 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java @@ -29,11 +29,12 @@ import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.loader.ConfigurationLoader; import ninja.leaping.configurate.yaml.YAMLConfigurationLoader; -import org.geysermc.common.PlatformType; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.common.PlatformType; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.dump.BootstrapDumpInfo; import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.utils.FileUtils; @@ -50,6 +51,7 @@ import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; +import java.nio.file.Path; import java.util.UUID; @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Sponge", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") @@ -147,6 +149,11 @@ public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserSpongePingPassthrough; } + @Override + public Path getConfigFolder() { + return configDir.toPath(); + } + @Listener public void onServerStart(GameStartedServerEvent event) { onEnable(); @@ -156,4 +163,9 @@ public void onServerStart(GameStartedServerEvent event) { public void onServerStop(GameStoppedEvent event) { onDisable(); } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserSpongeDumpInfo(); + } } diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java index 91cb59b0f70..8f857b66553 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java @@ -27,7 +27,7 @@ import lombok.AllArgsConstructor; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.GeyserCommand; import org.spongepowered.api.command.CommandCallable; diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java index aa0d2392e5a..3fb561a1d22 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java @@ -25,18 +25,21 @@ package org.geysermc.platform.standalone; -import org.geysermc.common.PlatformType; -import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; -import org.geysermc.connector.GeyserConfiguration; -import org.geysermc.connector.bootstrap.GeyserBootstrap; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.bootstrap.GeyserBootstrap; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.dump.BootstrapDumpInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; +import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.utils.FileUtils; import org.geysermc.platform.standalone.command.GeyserCommandManager; import java.io.File; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.UUID; public class GeyserStandaloneBootstrap implements GeyserBootstrap { @@ -100,4 +103,15 @@ public CommandManager getGeyserCommandManager() { public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserPingPassthrough; } + + @Override + public Path getConfigFolder() { + // Return the current working directory + return Paths.get(System.getProperty("user.dir")); + } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new BootstrapDumpInfo(); + } } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneConfiguration.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneConfiguration.java index bd0292040e2..29e18d08f50 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneConfiguration.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneConfiguration.java @@ -27,110 +27,21 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.Getter; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.configuration.GeyserJacksonConfiguration; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Map; -@JsonIgnoreProperties(ignoreUnknown = true) @Getter -public class GeyserStandaloneConfiguration implements GeyserConfiguration { - - private BedrockConfiguration bedrock; - private RemoteConfiguration remote; +@JsonIgnoreProperties(ignoreUnknown = true) +public class GeyserStandaloneConfiguration extends GeyserJacksonConfiguration { @JsonProperty("floodgate-key-file") private String floodgateKeyFile; - private Map userAuths; - - @JsonProperty("command-suggestions") - private boolean isCommandSuggestions; - - @JsonProperty("passthrough-motd") - private boolean isPassthroughMotd; - - @JsonProperty("passthrough-player-counts") - private boolean isPassthroughPlayerCounts; - - @JsonProperty("legacy-ping-passthrough") - private boolean isLegacyPingPassthrough; - - @JsonProperty("ping-passthrough-interval") - private int pingPassthroughInterval; - - @JsonProperty("max-players") - private int maxPlayers; - - @JsonProperty("debug-mode") - private boolean debugMode; - - @JsonProperty("general-thread-pool") - private int generalThreadPool; - - @JsonProperty("allow-third-party-capes") - private boolean allowThirdPartyCapes; - - @JsonProperty("allow-third-party-ears") - private boolean allowThirdPartyEars; - - @JsonProperty("default-locale") - private String defaultLocale; - - @JsonProperty("cache-chunks") - private boolean cacheChunks; - - @JsonProperty("above-bedrock-nether-building") - private boolean isAboveBedrockNetherBuilding; - - private MetricsInfo metrics; - @Override public Path getFloodgateKeyFile() { return Paths.get(floodgateKeyFile); } - - @Getter - public static class BedrockConfiguration implements IBedrockConfiguration { - - private String address; - private int port; - - private String motd1; - private String motd2; - } - - @Getter - public static class RemoteConfiguration implements IRemoteConfiguration { - - private String address; - private int port; - - private String motd1; - private String motd2; - - @JsonProperty("auth-type") - private String authType; - } - - @Getter - public static class UserAuthenticationInfo implements IUserAuthenticationInfo { - private String email; - private String password; - } - - @Getter - public static class MetricsInfo implements IMetricsInfo { - - private boolean enabled; - - @JsonProperty("uuid") - private String uniqueId; - } - - @JsonProperty("config-version") - private int configVersion; } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneLogger.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneLogger.java index ffb252b2ef9..ae7f1871841 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneLogger.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneLogger.java @@ -31,7 +31,7 @@ import net.minecrell.terminalconsole.SimpleTerminalConsole; import org.apache.logging.log4j.core.config.Configurator; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; @@ -82,7 +82,7 @@ public void warning(String message) { @Override public void info(String message) { - log.info(printConsole(ChatColor.WHITE + message, colored)); + log.info(printConsole(ChatColor.RESET + ChatColor.BOLD + message, colored)); } @Override diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/LoopbackUtil.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/LoopbackUtil.java index 03c49705dee..00ff14de731 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/LoopbackUtil.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/LoopbackUtil.java @@ -5,7 +5,7 @@ import java.nio.file.OpenOption; import java.nio.file.Paths; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; public class LoopbackUtil { private static final String checkExemption = "powershell -Command \"CheckNetIsolation LoopbackExempt -s\""; // Java's Exec feature runs as CMD, NetIsolation is only accessible from PowerShell. diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml index fb06767e0af..78f21973138 100644 --- a/bootstrap/velocity/pom.xml +++ b/bootstrap/velocity/pom.xml @@ -61,6 +61,10 @@ it.unimi.dsi.fastutil org.geysermc.platform.velocity.shaded.fastutil + + org.reflections.reflections + org.geysermc.platform.velocity.shaded.reflections + diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java index aef0edaa5c8..574941c4805 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java @@ -30,122 +30,30 @@ import com.velocitypowered.api.plugin.PluginContainer; import com.velocitypowered.api.proxy.ProxyServer; import lombok.Getter; -import lombok.Setter; import org.geysermc.connector.FloodgateKeyLoader; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.configuration.GeyserJacksonConfiguration; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Map; import java.util.Optional; -@JsonIgnoreProperties(ignoreUnknown = true) @Getter -public class GeyserVelocityConfiguration implements GeyserConfiguration { - - private BedrockConfiguration bedrock; - private RemoteConfiguration remote; +@JsonIgnoreProperties(ignoreUnknown = true) +public class GeyserVelocityConfiguration extends GeyserJacksonConfiguration { @JsonProperty("floodgate-key-file") private String floodgateKeyFile; - private Map userAuths; - - @JsonProperty("command-suggestions") - private boolean commandSuggestions; - - @JsonProperty("passthrough-motd") - private boolean isPassthroughMotd; - - @JsonProperty("passthrough-player-counts") - private boolean isPassthroughPlayerCounts; - - @JsonProperty("legacy-ping-passthrough") - private boolean isLegacyPingPassthrough; - - @JsonProperty("ping-passthrough-interval") - private int pingPassthroughInterval; - - @JsonProperty("max-players") - private int maxPlayers; - - @JsonProperty("debug-mode") - private boolean debugMode; - - @JsonProperty("general-thread-pool") - private int generalThreadPool; - - @JsonProperty("allow-third-party-capes") - private boolean allowThirdPartyCapes; - - @JsonProperty("allow-third-party-ears") - private boolean allowThirdPartyEars; - - @JsonProperty("default-locale") - private String defaultLocale; - - @JsonProperty("cache-chunks") - private boolean cacheChunks; - - @JsonProperty("above-bedrock-nether-building") - private boolean aboveBedrockNetherBuilding; - - private MetricsInfo metrics; - private Path floodgateKey; - public void loadFloodgate(GeyserVelocityPlugin plugin, ProxyServer proxyServer, File dataFolder) { - Optional floodgate = proxyServer.getPluginManager().getPlugin("floodgate"); - floodgate.ifPresent(it -> floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), floodgateKeyFile.isEmpty() ? floodgateKeyFile : "public-key.pem"), it, Paths.get("plugins/floodgate/"))); - } - @Override public Path getFloodgateKeyFile() { return floodgateKey; } - @Getter - public static class BedrockConfiguration implements IBedrockConfiguration { - - private String address; - private int port; - - private String motd1; - private String motd2; - } - - @Getter - public static class RemoteConfiguration implements IRemoteConfiguration { - - @Setter - private String address; - - @Setter - private int port; - - private String motd1; - private String motd2; - - @JsonProperty("auth-type") - private String authType; - } - - @Getter - public static class UserAuthenticationInfo implements IUserAuthenticationInfo { - private String email; - private String password; - } - - @Getter - public static class MetricsInfo implements IMetricsInfo { - - private boolean enabled; - - @JsonProperty("uuid") - private String uniqueId; + public void loadFloodgate(GeyserVelocityPlugin plugin, ProxyServer proxyServer, File dataFolder) { + Optional floodgate = proxyServer.getPluginManager().getPlugin("floodgate"); + floodgate.ifPresent(it -> floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(dataFolder.toString(), floodgateKeyFile.isEmpty() ? floodgateKeyFile : "public-key.pem"), it, Paths.get("plugins/floodgate/"))); } - - @JsonProperty("config-version") - private int configVersion; } diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityDumpInfo.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityDumpInfo.java new file mode 100644 index 00000000000..906a0414247 --- /dev/null +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityDumpInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019-2020 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.platform.velocity; + +import com.velocitypowered.api.plugin.PluginContainer; +import com.velocitypowered.api.proxy.ProxyServer; +import lombok.Getter; +import org.geysermc.connector.dump.BootstrapDumpInfo; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class GeyserVelocityDumpInfo extends BootstrapDumpInfo { + + private String platformName; + private String platformVersion; + private String platformVendor; + private boolean onlineMode; + private String serverIP; + private int serverPort; + private List plugins; + + GeyserVelocityDumpInfo(ProxyServer proxy) { + super(); + this.platformName = proxy.getVersion().getName(); + this.platformVersion = proxy.getVersion().getVersion(); + this.platformVendor = proxy.getVersion().getVendor(); + this.onlineMode = proxy.getConfiguration().isOnlineMode(); + this.serverIP = proxy.getBoundAddress().getHostString(); + this.serverPort = proxy.getBoundAddress().getPort(); + this.plugins = new ArrayList<>(); + + for (PluginContainer plugin : proxy.getPluginManager().getPlugins()) { + String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown"); + this.plugins.add(new PluginInfo(true, plugin.getDescription().getName().get(), plugin.getDescription().getVersion().get(), pluginClass, plugin.getDescription().getAuthors())); + } + } +} diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityMain.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityMain.java index 73eaddf09c8..b5c79cc2b99 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityMain.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityMain.java @@ -26,7 +26,7 @@ package org.geysermc.platform.velocity; -import org.geysermc.common.main.IGeyserMain; +import org.geysermc.connector.common.main.IGeyserMain; public class GeyserVelocityMain extends IGeyserMain { diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java index 01be949b828..934c577405c 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java @@ -32,9 +32,8 @@ import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.server.ServerPing; import lombok.AllArgsConstructor; -import net.kyori.text.TextComponent; import net.kyori.text.serializer.legacy.LegacyComponentSerializer; -import org.geysermc.common.ping.GeyserPingInfo; +import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; import java.net.Inet4Address; diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java index e7b44da53ab..f00119ca932 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java @@ -34,10 +34,12 @@ import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.proxy.ProxyServer; -import org.geysermc.common.PlatformType; -import org.geysermc.connector.GeyserConfiguration; +import lombok.Getter; +import org.geysermc.connector.common.PlatformType; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; +import org.geysermc.connector.dump.BootstrapDumpInfo; import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.utils.FileUtils; @@ -48,6 +50,8 @@ import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.UUID; @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Velocity", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") @@ -69,14 +73,16 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { private GeyserConnector connector; + @Getter + private final Path configFolder = Paths.get("plugins/" + GeyserConnector.NAME + "-Velocity/"); + @Override public void onEnable() { - File configDir = new File("plugins/" + GeyserConnector.NAME + "-Velocity/"); - try { - if (!configDir.exists()) - configDir.mkdir(); - File configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); + if (!configFolder.toFile().exists()) + //noinspection ResultOfMethodCallIgnored + configFolder.toFile().mkdirs(); + File configFile = FileUtils.fileOrCopiedFromResource(configFolder.resolve("config.yml").toFile(), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class); } catch (IOException ex) { logger.warn("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); @@ -96,7 +102,12 @@ public void onEnable() { this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); - geyserConfig.loadFloodgate(this, proxyServer, configDir); + if (geyserConfig.getRemote().getAuthType().equals("floodgate") && !proxyServer.getPluginManager().getPlugin("floodgate").isPresent()) { + geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling..."); + return; + } + + geyserConfig.loadFloodgate(this, proxyServer, configFolder.toFile()); this.connector = GeyserConnector.start(PlatformType.VELOCITY, this); @@ -143,4 +154,9 @@ public void onInit(ProxyInitializeEvent event) { public void onShutdown(ProxyShutdownEvent event) { onDisable(); } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserVelocityDumpInfo(proxyServer); + } } diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java index 940c52244cd..4632f4404bf 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java @@ -32,7 +32,7 @@ import net.kyori.text.TextComponent; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.GeyserCommand; diff --git a/common/src/main/java/org/geysermc/common/AuthType.java b/common/src/main/java/org/geysermc/common/AuthType.java deleted file mode 100644 index 8edbc4d5561..00000000000 --- a/common/src/main/java/org/geysermc/common/AuthType.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.geysermc.common; - -import lombok.Getter; - -@Getter -public enum AuthType { - OFFLINE, - ONLINE, - FLOODGATE; - - public static final AuthType[] VALUES = values(); - - public static AuthType getById(int id) { - return id < VALUES.length ? VALUES[id] : OFFLINE; - } - - /** - * Convert the AuthType string (from config) to the enum, OFFLINE on fail - * - * @param name AuthType string - * - * @return The converted AuthType - */ - public static AuthType getByName(String name) { - String upperCase = name.toUpperCase(); - for (AuthType type : VALUES) { - if (type.name().equals(upperCase)) { - return type; - } - } - return OFFLINE; - } -} \ No newline at end of file diff --git a/common/src/main/java/org/geysermc/common/PlatformType.java b/common/src/main/java/org/geysermc/common/PlatformType.java deleted file mode 100644 index fa6f57fda8d..00000000000 --- a/common/src/main/java/org/geysermc/common/PlatformType.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.geysermc.common; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public enum PlatformType { - - BUKKIT("Bukkit"), - BUNGEECORD("BungeeCord"), - SPONGE("Sponge"), - STANDALONE("Standalone"), - VELOCITY("Velocity"); - - private String platformName; -} diff --git a/common/src/main/java/org/geysermc/common/window/button/FormImage.java b/common/src/main/java/org/geysermc/common/window/button/FormImage.java index b700b046b1c..72579f7acfc 100644 --- a/common/src/main/java/org/geysermc/common/window/button/FormImage.java +++ b/common/src/main/java/org/geysermc/common/window/button/FormImage.java @@ -32,14 +32,14 @@ public class FormImage { @Getter @Setter - private FormImageType type; + private String type; @Getter @Setter private String data; public FormImage(FormImageType type, String data) { - this.type = type; + this.type = type.getName(); this.data = data; } diff --git a/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java b/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java index 50a5c631a9c..f972d590685 100644 --- a/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java +++ b/common/src/main/java/org/geysermc/common/window/component/ToggleComponent.java @@ -25,9 +25,17 @@ package org.geysermc.common.window.component; +import lombok.Getter; +import lombok.Setter; + public class ToggleComponent extends FormComponent { + @Getter + @Setter private String text; + + @Getter + @Setter private boolean defaultValue; public ToggleComponent(String text) { diff --git a/connector/pom.xml b/connector/pom.xml index 5743c0c6351..ddc62bf2a17 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -31,9 +31,9 @@ compile - com.nukkitx.protocol - bedrock-v390 - 2.5.6-SNAPSHOT + com.github.bundabrg.Protocol + bedrock-v407 + feature~1.16-protocol-SNAPSHOT compile @@ -66,6 +66,12 @@ 8.3.1 compile + + com.nukkitx.fastutil + fastutil-int-byte-maps + 8.3.1 + compile + com.nukkitx.fastutil fastutil-int-double-maps @@ -97,15 +103,9 @@ compile - com.github.steveice10 - opennbt - 1.4-SNAPSHOT - compile - - - com.github.steveice10 - packetlib - 1.6-SNAPSHOT + com.github.GeyserMC + MCProtocolLib + feature~1.16-1.12.1-1-g74ee57a-310 compile @@ -115,31 +115,11 @@ - com.github.steveice10 - mcauthlib - 1.3-SNAPSHOT + io.netty + netty-resolver-dns + 4.1.43.Final compile - - com.github.steveice10 - mcprotocollib - 1.15.2-1-SNAPSHOT - compile - - - com.github.steveice10 - opennbt - - - com.github.steveice10 - packetlib - - - com.github.steveice10 - mcauthlib - - - org.reflections reflections @@ -190,6 +170,11 @@ false git.user.* + git.*.user.* + git.closest.* + git.commit.id.describe + git.commit.id.describe-short + git.commit.message.short flat diff --git a/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java b/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java index 0b631b2d2ad..617ac83eb3f 100644 --- a/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java +++ b/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java @@ -26,6 +26,8 @@ package org.geysermc.connector; +import org.geysermc.connector.configuration.GeyserConfiguration; + import java.nio.file.Files; import java.nio.file.Path; diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 02e0c500360..20a7712665b 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -29,12 +29,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockServer; -import com.nukkitx.protocol.bedrock.v390.Bedrock_v390; +import com.nukkitx.protocol.bedrock.v407.Bedrock_v407; import lombok.Getter; -import org.geysermc.common.AuthType; -import org.geysermc.common.PlatformType; +import lombok.Setter; +import org.geysermc.connector.common.AuthType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.metrics.Metrics; import org.geysermc.connector.network.ConnectorServerEventHandler; import org.geysermc.connector.network.remote.RemoteServer; @@ -68,7 +70,7 @@ public class GeyserConnector { public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES); - public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v390.V390_CODEC; + public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v407.V407_CODEC; public static final String NAME = "Geyser"; public static final String VERSION = "DEV"; // A fallback for running in IDEs @@ -78,6 +80,7 @@ public class GeyserConnector { private static GeyserConnector instance; private RemoteServer remoteServer; + @Setter private AuthType authType; private boolean shuttingDown = false; diff --git a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java index 24ce81cfd42..f089350fb58 100644 --- a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java +++ b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java @@ -26,13 +26,16 @@ package org.geysermc.connector.bootstrap; +import org.geysermc.connector.dump.BootstrapDumpInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserLogger; import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.network.translators.world.CachedChunkManager; import org.geysermc.connector.network.translators.world.WorldManager; +import java.nio.file.Path; + public interface GeyserBootstrap { CachedChunkManager DEFAULT_CHUNK_MANAGER = new CachedChunkManager(); @@ -83,4 +86,18 @@ public interface GeyserBootstrap { default WorldManager getWorldManager() { return DEFAULT_CHUNK_MANAGER; } + + /** + * Return the data folder where files get stored + * + * @return Path location of data folder + */ + Path getConfigFolder(); + + /** + * Information used for the bootstrap section of the debug dump + * + * @return The info about the bootstrap + */ + BootstrapDumpInfo getDumpInfo(); } diff --git a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java index 88b9e795de7..217a9df1fa3 100644 --- a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java +++ b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java @@ -49,6 +49,7 @@ public CommandManager(GeyserConnector connector) { registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload")); registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop")); registerCommand(new OffhandCommand(connector, "offhand", "Puts an items in your offhand.", "geyser.command.offhand")); + registerCommand(new DumpCommand(connector, "dump", "Dumps Geyser debug infomation for bug reports.", "geyser.command.dump")); } public void registerCommand(GeyserCommand command) { @@ -75,7 +76,7 @@ public void runCommand(CommandSender sender, String command) { args = new String[0]; } else { label = command.substring(0, command.indexOf(" ")).toLowerCase(); - String argLine = command.substring(command.indexOf(" " + 1)); + String argLine = command.substring(command.indexOf(" ") + 1); args = argLine.contains(" ") ? argLine.split(" ") : new String[] { argLine }; } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java new file mode 100644 index 00000000000..617c9d43644 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019-2020 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.connector.command.defaults; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter; +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider; +import org.geysermc.connector.common.ChatColor; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; +import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.dump.DumpInfo; +import org.geysermc.connector.utils.WebUtils; + +import java.io.IOException; + +public class DumpCommand extends GeyserCommand { + + private final GeyserConnector connector; + private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final String DUMP_URL = "https://dump.geysermc.org/"; + + public DumpCommand(GeyserConnector connector, String name, String description, String permission) { + super(name, description, permission); + + this.connector = connector; + + final SimpleFilterProvider filter = new SimpleFilterProvider(); + filter.addFilter("dump_user_auth", SimpleBeanPropertyFilter.serializeAllExcept(new String[] {"password"})); + + MAPPER.setFilterProvider(filter); + } + + @Override + public void execute(CommandSender sender, String[] args) { + sender.sendMessage("Collecting dump info"); + String dumpData = ""; + try { + dumpData = MAPPER.writeValueAsString(new DumpInfo()); + } catch (IOException e) { + sender.sendMessage(ChatColor.RED + "Failed to collect dump info, check console for more information"); + connector.getLogger().error("Failed to collect dump info", e); + return; + } + + sender.sendMessage("Uploading dump"); + String response; + JsonNode responseNode; + try { + response = WebUtils.post(DUMP_URL + "documents", dumpData); + responseNode = MAPPER.readTree(response); + } catch (IOException e) { + sender.sendMessage(ChatColor.RED + "Failed to upload dump, check console for more information"); + connector.getLogger().error("Failed to upload dump", e); + return; + } + + if (!responseNode.has("key")) { + sender.sendMessage(ChatColor.RED + "Failed to upload dump: " + (responseNode.has("message") ? responseNode.get("message").asText() : response)); + return; + } + + String uploadedDumpUrl = DUMP_URL + responseNode.get("key").asText(); + sender.sendMessage("We've made a dump with useful information, report your issue and provide this url: " + ChatColor.DARK_AQUA + uploadedDumpUrl); + if (!sender.isConsole()) { + connector.getLogger().info(sender.getName() + " created a GeyserDump at " + uploadedDumpUrl); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java index 6acb7822bb1..a5942ee6b90 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java @@ -25,7 +25,7 @@ package org.geysermc.connector.command.defaults; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java index 21fa425354c..99845ee9419 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java @@ -25,7 +25,7 @@ package org.geysermc.connector.command.defaults; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java index c38a0c23de9..2ddd61ed8a9 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java @@ -25,8 +25,8 @@ package org.geysermc.connector.command.defaults; -import org.geysermc.common.ChatColor; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.ChatColor; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java index 2222cdef546..636058a02f1 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java @@ -25,7 +25,7 @@ package org.geysermc.connector.command.defaults; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; diff --git a/connector/src/main/java/org/geysermc/connector/common/AuthType.java b/connector/src/main/java/org/geysermc/connector/common/AuthType.java new file mode 100644 index 00000000000..f15e3ff586a --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/common/AuthType.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019-2020 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.connector.common; + +import lombok.Getter; + +@Getter +public enum AuthType { + OFFLINE, + ONLINE, + FLOODGATE; + + public static final AuthType[] VALUES = values(); + + public static AuthType getById(int id) { + return id < VALUES.length ? VALUES[id] : OFFLINE; + } + + /** + * Convert the AuthType string (from config) to the enum, OFFLINE on fail + * + * @param name AuthType string + * + * @return The converted AuthType + */ + public static AuthType getByName(String name) { + String upperCase = name.toUpperCase(); + for (AuthType type : VALUES) { + if (type.name().equals(upperCase)) { + return type; + } + } + return OFFLINE; + } +} \ No newline at end of file diff --git a/common/src/main/java/org/geysermc/common/ChatColor.java b/connector/src/main/java/org/geysermc/connector/common/ChatColor.java similarity index 75% rename from common/src/main/java/org/geysermc/common/ChatColor.java rename to connector/src/main/java/org/geysermc/connector/common/ChatColor.java index 8868b063c0f..1397f88cf51 100644 --- a/common/src/main/java/org/geysermc/common/ChatColor.java +++ b/connector/src/main/java/org/geysermc/connector/common/ChatColor.java @@ -1,29 +1,30 @@ /* * Copyright (c) 2019-2020 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: + * 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 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. + * 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 * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.common; +package org.geysermc.connector.common; public class ChatColor { diff --git a/connector/src/main/java/org/geysermc/connector/common/PlatformType.java b/connector/src/main/java/org/geysermc/connector/common/PlatformType.java new file mode 100644 index 00000000000..ee68b6d7b1a --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/common/PlatformType.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020 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.connector.common; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum PlatformType { + + BUNGEECORD("BungeeCord"), + SPIGOT("Spigot"), + SPONGE("Sponge"), + STANDALONE("Standalone"), + VELOCITY("Velocity"); + + private String platformName; +} diff --git a/common/src/main/java/org/geysermc/common/main/IGeyserMain.java b/connector/src/main/java/org/geysermc/connector/common/main/IGeyserMain.java similarity index 98% rename from common/src/main/java/org/geysermc/common/main/IGeyserMain.java rename to connector/src/main/java/org/geysermc/connector/common/main/IGeyserMain.java index 75da4e6b930..906bd7865ef 100644 --- a/common/src/main/java/org/geysermc/common/main/IGeyserMain.java +++ b/connector/src/main/java/org/geysermc/connector/common/main/IGeyserMain.java @@ -24,7 +24,7 @@ * */ -package org.geysermc.common.main; +package org.geysermc.connector.common.main; import javax.swing.*; import java.io.InputStream; diff --git a/common/src/main/java/org/geysermc/common/ping/GeyserPingInfo.java b/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java similarity index 97% rename from common/src/main/java/org/geysermc/common/ping/GeyserPingInfo.java rename to connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java index 40ef6da62be..69b24ea1e1d 100644 --- a/common/src/main/java/org/geysermc/common/ping/GeyserPingInfo.java +++ b/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java @@ -24,7 +24,7 @@ * */ -package org.geysermc.common.ping; +package org.geysermc.connector.common.ping; import lombok.Data; import lombok.Getter; diff --git a/connector/src/main/java/org/geysermc/connector/common/serializer/AsteriskSerializer.java b/connector/src/main/java/org/geysermc/connector/common/serializer/AsteriskSerializer.java new file mode 100644 index 00000000000..3fac2e08a29 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/common/serializer/AsteriskSerializer.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019-2020 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.connector.common.serializer; + +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.BeanProperty; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.ContextualSerializer; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Optional; + +public class AsteriskSerializer extends StdSerializer implements ContextualSerializer { + @Target({ElementType.FIELD}) + @Retention(RetentionPolicy.RUNTIME) + @JacksonAnnotationsInside + @JsonSerialize(using = AsteriskSerializer.class) + public @interface Asterisk { + String value() default "***"; + } + + String asterisk; + + public AsteriskSerializer() { + super(Object.class); + } + + public AsteriskSerializer(String asterisk) { + super(Object.class); + this.asterisk = asterisk; + } + + @Override + public JsonSerializer createContextual(SerializerProvider serializerProvider, BeanProperty property) { + Optional anno = Optional.ofNullable(property) + .map(prop -> prop.getAnnotation(Asterisk.class)); + return new AsteriskSerializer(anno.map(Asterisk::value).orElse(null)); + } + + @Override + public void serialize(Object obj, JsonGenerator gen, SerializerProvider prov) throws IOException { + gen.writeString(asterisk); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java similarity index 96% rename from connector/src/main/java/org/geysermc/connector/GeyserConfiguration.java rename to connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java index 8a39323b606..5ea942c1a98 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java @@ -24,7 +24,9 @@ * */ -package org.geysermc.connector; +package org.geysermc.connector.configuration; + +import org.geysermc.connector.GeyserLogger; import java.nio.file.Path; import java.util.Map; @@ -60,6 +62,8 @@ public interface GeyserConfiguration { boolean isAllowThirdPartyEars(); + boolean isShowCooldown(); + String getDefaultLocale(); Path getFloodgateKeyFile(); diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java new file mode 100644 index 00000000000..867de9adf54 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2019-2020 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.connector.configuration; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import org.geysermc.connector.common.serializer.AsteriskSerializer; + +import java.nio.file.Path; +import java.util.Map; + +@Getter +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class GeyserJacksonConfiguration implements GeyserConfiguration { + + private BedrockConfiguration bedrock; + private RemoteConfiguration remote; + + @JsonProperty("floodgate-key-file") + private String floodgateKeyFile; + + public abstract Path getFloodgateKeyFile(); + + private Map userAuths; + + @JsonProperty("command-suggestions") + private boolean commandSuggestions; + + @JsonProperty("passthrough-motd") + private boolean isPassthroughMotd; + + @JsonProperty("passthrough-player-counts") + private boolean isPassthroughPlayerCounts; + + @JsonProperty("legacy-ping-passthrough") + private boolean isLegacyPingPassthrough; + + @JsonProperty("ping-passthrough-interval") + private int pingPassthroughInterval; + + @JsonProperty("max-players") + private int maxPlayers; + + @JsonProperty("debug-mode") + private boolean debugMode; + + @JsonProperty("general-thread-pool") + private int generalThreadPool; + + @JsonProperty("allow-third-party-capes") + private boolean allowThirdPartyCapes; + + @JsonProperty("show-cooldown") + private boolean showCooldown = true; + + @JsonProperty("allow-third-party-ears") + private boolean allowThirdPartyEars; + + @JsonProperty("default-locale") + private String defaultLocale; + + @JsonProperty("cache-chunks") + private boolean cacheChunks; + + @JsonProperty("above-bedrock-nether-building") + private boolean aboveBedrockNetherBuilding; + + private MetricsInfo metrics; + + @Getter + public static class BedrockConfiguration implements IBedrockConfiguration { + + private String address; + private int port; + + private String motd1; + private String motd2; + } + + @Getter + public static class RemoteConfiguration implements IRemoteConfiguration { + + @Setter + private String address; + + @Setter + private int port; + + @JsonProperty("auth-type") + private String authType; + } + + @Getter + public static class UserAuthenticationInfo implements IUserAuthenticationInfo { + @AsteriskSerializer.Asterisk() + private String email; + + @AsteriskSerializer.Asterisk() + private String password; + } + + @Getter + public static class MetricsInfo implements IMetricsInfo { + + private boolean enabled; + + @JsonProperty("uuid") + private String uniqueId; + } + + @JsonProperty("config-version") + private int configVersion; +} diff --git a/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java b/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java new file mode 100644 index 00000000000..04495b49e7d --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019-2020 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.connector.dump; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.geysermc.connector.common.PlatformType; +import org.geysermc.connector.GeyserConnector; + +import java.util.List; + +@Getter +public class BootstrapDumpInfo { + + private PlatformType platform; + + public BootstrapDumpInfo() { + this.platform = GeyserConnector.getInstance().getPlatformType(); + } + + @Getter + @AllArgsConstructor + public class PluginInfo { + + public boolean enabled; + public String name; + public String version; + public String main; + public List authors; + } + + @Getter + @AllArgsConstructor + public class ListenerInfo { + + public String ip; + public int port; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/dump/DumpInfo.java b/connector/src/main/java/org/geysermc/connector/dump/DumpInfo.java new file mode 100644 index 00000000000..6d4b83db8bb --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/dump/DumpInfo.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019-2020 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.connector.dump; + +import com.github.steveice10.mc.protocol.MinecraftConstants; +import lombok.Getter; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.configuration.GeyserConfiguration; +import org.geysermc.connector.utils.DockerCheck; +import org.geysermc.connector.utils.FileUtils; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Properties; + +@Getter +public class DumpInfo { + + private final DumpInfo.VersionInfo versionInfo; + private Properties gitInfo; + private final GeyserConfiguration config; + private final BootstrapDumpInfo bootstrapInfo; + + public DumpInfo() { + try { + this.gitInfo = new Properties(); + this.gitInfo.load(FileUtils.getResource("git.properties")); + } catch (IOException ignored) { } + + this.config = GeyserConnector.getInstance().getConfig(); + + this.versionInfo = new DumpInfo.VersionInfo(); + this.bootstrapInfo = GeyserConnector.getInstance().getBootstrap().getDumpInfo(); + } + + @Getter + public class VersionInfo { + + private final String name; + private final String version; + private final String javaVersion; + private final String architecture; + private final String operatingSystem; + + private final NetworkInfo network; + private final MCInfo mcInfo; + + VersionInfo() { + this.name = GeyserConnector.NAME; + this.version = GeyserConnector.VERSION; + this.javaVersion = System.getProperty("java.version"); + this.architecture = System.getProperty("os.arch"); // Usually gives Java architecture but still may be helpful. + this.operatingSystem = System.getProperty("os.name"); + + this.network = new NetworkInfo(); + this.mcInfo = new MCInfo(); + } + } + + @Getter + public static class NetworkInfo { + + private String internalIP; + private final boolean dockerCheck; + + NetworkInfo() { + try { + // This is the most reliable for getting the main local IP + Socket socket = new Socket(); + socket.connect(new InetSocketAddress("geysermc.org", 80)); + this.internalIP = socket.getLocalAddress().getHostAddress(); + } catch (IOException e1) { + try { + // Fallback to the normal way of getting the local IP + this.internalIP = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException ignored) { } + } + + this.dockerCheck = DockerCheck.checkBasic(); + } + } + + @Getter + public static class MCInfo { + + private final String bedrockVersion; + private final int bedrockProtocol; + private final String javaVersion; + private final int javaProtocol; + + MCInfo() { + this.bedrockVersion = GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion(); + this.bedrockProtocol = GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion(); + this.javaVersion = MinecraftConstants.GAME_VERSION; + this.javaProtocol = MinecraftConstants.PROTOCOL_VERSION; + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/AbstractArrowEntity.java b/connector/src/main/java/org/geysermc/connector/entity/AbstractArrowEntity.java index fa089707c6e..f174747b778 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/AbstractArrowEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/AbstractArrowEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java b/connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java index 79e67f34545..21861589995 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/AreaEffectCloudEntity.java @@ -28,7 +28,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.world.particle.Particle; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.effect.EffectRegistry; @@ -42,19 +42,19 @@ public AreaEffectCloudEntity(long entityId, long geyserId, EntityType entityType metadata.put(EntityData.AREA_EFFECT_CLOUD_DURATION, 600); // This disabled client side shrink of the cloud - metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS_PER_TICK, 0.0f); + metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, 0.0f); } @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 7) { - metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, (float) entityMetadata.getValue()); + metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, entityMetadata.getValue()); metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue()); } else if (entityMetadata.getId() == 10) { Particle particle = (Particle) entityMetadata.getValue(); metadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, EffectRegistry.getParticleString(particle.getType())); } else if (entityMetadata.getId() == 8) { - metadata.put(EntityData.POTION_COLOR, entityMetadata.getValue()); + metadata.put(EntityData.POTION_AUX_VALUE, entityMetadata.getValue()); } super.updateBedrockMetadata(entityMetadata, session); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java b/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java index 8f79526de27..c067416dff4 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -44,19 +44,28 @@ public class BoatEntity extends Entity { private final float ROWING_SPEED = 0.05f; public BoatEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { - super(entityId, geyserId, entityType, position.add(0d, entityType.getOffset(), 0d), motion, rotation.add(0, 0, 90)); + super(entityId, geyserId, entityType, position.add(0d, entityType.getOffset(), 0d), motion, rotation.add(90, 0, 90)); } @Override public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) { - // Rotation is basically only called when entering/exiting a boat. // We don't include the rotation (y) as it causes the boat to appear sideways - super.moveAbsolute(session, position.add(0d, this.entityType.getOffset(), 0d), Vector3f.from(0, 0, rotation.getZ() + 90), isOnGround, teleported); + super.moveAbsolute(session, position.add(0d, this.entityType.getOffset(), 0d), Vector3f.from(rotation.getX() + 90, 0, rotation.getX() + 90), isOnGround, teleported); } @Override public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) { - super.moveRelative(session, relX, relY, relZ, Vector3f.from(0, 0, rotation.getZ()), isOnGround); + super.moveRelative(session, relX, relY, relZ, Vector3f.from(rotation.getX(), 0, rotation.getX()), isOnGround); + } + + @Override + public void updatePositionAndRotation(GeyserSession session, double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) { + moveRelative(session, moveX, moveY, moveZ, yaw + 90, pitch, isOnGround); + } + + @Override + public void updateRotation(GeyserSession session, float yaw, float pitch, boolean isOnGround) { + moveRelative(session, 0, 0, 0, Vector3f.from(yaw + 90, 0, 0), isOnGround); } @Override @@ -83,7 +92,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s } else if (entityMetadata.getId() == 11) { isPaddlingLeft = (boolean) entityMetadata.getValue(); if (!isPaddlingLeft) { - metadata.put(EntityData.PADDLE_TIME_LEFT, 0f); + metadata.put(EntityData.ROW_TIME_LEFT, 0f); } else { // Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing @@ -97,7 +106,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s else if (entityMetadata.getId() == 12) { isPaddlingRight = (boolean) entityMetadata.getValue(); if (!isPaddlingRight) { - metadata.put(EntityData.PADDLE_TIME_RIGHT, 0f); + metadata.put(EntityData.ROW_TIME_RIGHT, 0f); } else { paddleTimeRight = 0f; session.getConnector().getGeneralThreadPool().execute(() -> @@ -115,7 +124,7 @@ else if (entityMetadata.getId() == 12) { public void updateLeftPaddle(GeyserSession session, EntityMetadata entityMetadata) { if (isPaddlingLeft) { paddleTimeLeft += ROWING_SPEED; - metadata.put(EntityData.PADDLE_TIME_LEFT, paddleTimeLeft); + metadata.put(EntityData.ROW_TIME_LEFT, paddleTimeLeft); super.updateBedrockMetadata(entityMetadata, session); session.getConnector().getGeneralThreadPool().schedule(() -> updateLeftPaddle(session, entityMetadata), @@ -127,7 +136,7 @@ public void updateLeftPaddle(GeyserSession session, EntityMetadata entityMetadat public void updateRightPaddle(GeyserSession session, EntityMetadata entityMetadata) { if (isPaddlingRight) { paddleTimeRight += ROWING_SPEED; - metadata.put(EntityData.PADDLE_TIME_RIGHT, paddleTimeRight); + metadata.put(EntityData.ROW_TIME_RIGHT, paddleTimeRight); super.updateBedrockMetadata(entityMetadata, session); session.getConnector().getGeneralThreadPool().schedule(() -> updateRightPaddle(session, entityMetadata), diff --git a/connector/src/main/java/org/geysermc/connector/entity/DefaultBlockMinecartEntity.java b/connector/src/main/java/org/geysermc/connector/entity/DefaultBlockMinecartEntity.java new file mode 100644 index 00000000000..dda4577d238 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/DefaultBlockMinecartEntity.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019-2020 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.connector.entity; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; + +/** + * This class is used as a base for minecarts with a default block to display like furnaces and spawners + */ +public class DefaultBlockMinecartEntity extends MinecartEntity { + + public int customBlock = 0; + public int customBlockOffset = 0; + public boolean showCustomBlock = false; + + public DefaultBlockMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + + updateDefaultBlockMetadata(); + metadata.put(EntityData.CUSTOM_DISPLAY, (byte) 1); + } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + + // Custom block + if (entityMetadata.getId() == 10) { + customBlock = (int) entityMetadata.getValue(); + + if (showCustomBlock) { + metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(customBlock)); + } + } + + // Custom block offset + if (entityMetadata.getId() == 11) { + customBlockOffset = (int) entityMetadata.getValue(); + + if (showCustomBlock) { + metadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset); + } + } + + // If the custom block should be enabled + if (entityMetadata.getId() == 12) { + if ((boolean) entityMetadata.getValue()) { + showCustomBlock = true; + metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(customBlock)); + metadata.put(EntityData.DISPLAY_OFFSET, customBlockOffset); + } else { + showCustomBlock = false; + updateDefaultBlockMetadata(); + } + } + + super.updateBedrockMetadata(entityMetadata, session); + } + + public void updateDefaultBlockMetadata() { } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java b/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java index 727df90c10c..4b665683eda 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/EnderCrystalEntity.java @@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/Entity.java b/connector/src/main/java/org/geysermc/connector/entity/Entity.java index 434c983bb3b..4d4d097f04a 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -32,16 +32,17 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.data.message.TextMessage; +import com.github.steveice10.mc.protocol.data.message.TranslationMessage; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityDataMap; -import com.nukkitx.protocol.bedrock.data.EntityFlag; -import com.nukkitx.protocol.bedrock.data.EntityFlags; +import com.nukkitx.protocol.bedrock.data.AttributeData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlags; import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import lombok.Getter; @@ -67,7 +68,7 @@ public class Entity { protected long entityId; protected long geyserId; - protected int dimension; + protected String dimension; protected Vector3f position; protected Vector3f motion; @@ -77,6 +78,11 @@ public class Entity { */ protected Vector3f rotation; + /** + * Saves if the entity should be on the ground. Otherwise entities like parrots are flapping when rotating + */ + protected boolean onGround; + protected float scale = 1; protected EntityType entityType; @@ -95,15 +101,15 @@ public Entity(long entityId, long geyserId, EntityType entityType, Vector3f posi this.rotation = rotation; this.valid = false; - this.dimension = 0; + this.dimension = "minecraft:overworld"; setPosition(position); metadata.put(EntityData.SCALE, 1f); metadata.put(EntityData.COLOR, 0); - metadata.put(EntityData.MAX_AIR, (short) 300); - metadata.put(EntityData.AIR, (short) 0); - metadata.put(EntityData.LEAD_HOLDER_EID, -1L); + metadata.put(EntityData.MAX_AIR_SUPPLY, (short) 300); + metadata.put(EntityData.AIR_SUPPLY, (short) 0); + metadata.put(EntityData.LEASH_HOLDER_EID, -1L); metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight()); metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth()); EntityFlags flags = new EntityFlags(); @@ -149,11 +155,12 @@ public boolean despawnEntity(GeyserSession session) { } public void moveRelative(GeyserSession session, double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) { - moveRelative(session, relX, relY, relZ, Vector3f.from(yaw, pitch, yaw), isOnGround); + moveRelative(session, relX, relY, relZ, Vector3f.from(yaw, pitch, this.rotation.getZ()), isOnGround); } public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) { setRotation(rotation); + setOnGround(isOnGround); this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ); MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); @@ -167,12 +174,13 @@ public void moveRelative(GeyserSession session, double relX, double relY, double } public void moveAbsolute(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround, boolean teleported) { - moveAbsolute(session, position, Vector3f.from(yaw, pitch, yaw), isOnGround, teleported); + moveAbsolute(session, position, Vector3f.from(yaw, pitch, this.rotation.getZ()), isOnGround, teleported); } public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) { setPosition(position); setRotation(rotation); + setOnGround(isOnGround); MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); moveEntityPacket.setRuntimeEntityId(geyserId); @@ -184,10 +192,56 @@ public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rota session.sendUpstreamPacket(moveEntityPacket); } + /** + * Teleports an entity to a new location. Used in JavaEntityTeleportTranslator. + * @param session GeyserSession. + * @param position The new position of the entity. + * @param yaw The new yaw of the entity. + * @param pitch The new pitch of the entity. + * @param isOnGround Whether the entity is currently on the ground. + */ + public void teleport(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround) { + moveAbsolute(session, position, yaw, pitch, isOnGround, false); + } + + /** + * Updates an entity's head position. Used in JavaEntityHeadLookTranslator. + * @param session GeyserSession. + * @param headYaw The new head rotation of the entity. + */ + public void updateHeadLookRotation(GeyserSession session, float headYaw) { + moveRelative(session, 0, 0, 0, Vector3f.from(headYaw, rotation.getY(), rotation.getZ()), onGround); + } + + /** + * Updates an entity's position and rotation. Used in JavaEntityPositionRotationTranslator. + * @param session GeyserSession + * @param moveX The new X offset of the current position. + * @param moveY The new Y offset of the current position. + * @param moveZ The new Z offset of the current position. + * @param yaw The new yaw of the entity. + * @param pitch The new pitch of the entity. + * @param isOnGround Whether the entity is currently on the ground. + */ + public void updatePositionAndRotation(GeyserSession session, double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) { + moveRelative(session, moveX, moveY, moveZ, Vector3f.from(rotation.getX(), pitch, yaw), isOnGround); + } + + /** + * Updates an entity's rotation. Used in JavaEntityRotationTranslator. + * @param session GeyserSession. + * @param yaw The new yaw of the entity. + * @param pitch The new pitch of the entity. + * @param isOnGround Whether the entity is currently on the ground. + */ + public void updateRotation(GeyserSession session, float yaw, float pitch, boolean isOnGround) { + updatePositionAndRotation(session, 0, 0, 0, yaw, pitch, isOnGround); + } + public void updateBedrockAttributes(GeyserSession session) { if (!valid) return; - List attributes = new ArrayList<>(); + List attributes = new ArrayList<>(); for (Map.Entry entry : this.attributes.entrySet()) { if (!entry.getValue().getType().isBedrockAttribute()) continue; @@ -209,13 +263,12 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01); metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02); metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); - metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); + metadata.getFlags().setFlag(EntityFlag.SWIMMING, ((xd & 0x10) == 0x10) && metadata.getFlags().getFlag(EntityFlag.SPRINTING)); // Otherwise swimming is enabled on older servers metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); if ((xd & 0x20) == 0x20) { - if (this.is(ArmorStandEntity.class)) { - metadata.put(EntityData.SCALE, 0.0f); - } else { + // Armour stands are handled in their own class + if (!this.is(ArmorStandEntity.class)) { metadata.getFlags().setFlag(EntityFlag.INVISIBLE, true); } } else { @@ -239,7 +292,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s } } else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) { metadata.getFlags().setFlag(EntityFlag.BLOCKING, false); - metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true); + metadata.getFlags().setFlag(EntityFlag.IS_AVOIDING_BLOCK, true); //TODO: CHECK ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0, 0, 0), BlockFace.DOWN); session.sendDownstreamPacket(releaseItemPacket); } @@ -247,19 +300,25 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s break; case 1: // Air/bubbles if ((int) entityMetadata.getValue() == 300) { - metadata.put(EntityData.AIR, (short) 0); // Otherwise the bubble counter remains in the UI + metadata.put(EntityData.AIR_SUPPLY, (short) 0); // Otherwise the bubble counter remains in the UI } else { - metadata.put(EntityData.AIR, (short) (int) entityMetadata.getValue()); + metadata.put(EntityData.AIR_SUPPLY, (short) (int) entityMetadata.getValue()); } break; case 2: // custom name - TextMessage name = (TextMessage) entityMetadata.getValue(); - if (name != null) - metadata.put(EntityData.NAMETAG, MessageUtils.getBedrockMessage(name)); + if (entityMetadata.getValue() instanceof TextMessage) { + TextMessage name = (TextMessage) entityMetadata.getValue(); + if (name != null) + metadata.put(EntityData.NAMETAG, MessageUtils.getBedrockMessage(name)); + } else if (entityMetadata.getValue() instanceof TranslationMessage) { + TranslationMessage message = (TranslationMessage) entityMetadata.getValue(); + if (message != null) + metadata.put(EntityData.NAMETAG, MessageUtils.getTranslatedBedrockMessage(message, session.getClientData().getLanguageCode(), true)); + } break; case 3: // is custom name visible if (!this.is(PlayerEntity.class)) - metadata.put(EntityData.ALWAYS_SHOW_NAMETAG, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); + metadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); break; case 4: // silent metadata.getFlags().setFlag(EntityFlag.SILENT, (boolean) entityMetadata.getValue()); @@ -271,18 +330,18 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s if (entityMetadata.getValue().equals(Pose.SLEEPING)) { metadata.getFlags().setFlag(EntityFlag.SLEEPING, true); // Has to be a byte or it does not work - metadata.put(EntityData.CAN_START_SLEEP, (byte) 2); + metadata.put(EntityData.PLAYER_FLAGS, (byte) 2); //TODO: CHECK if (entityId == session.getPlayerEntity().getEntityId()) { Vector3i lastInteractionPos = session.getLastInteractionPosition(); - metadata.put(EntityData.BED_RESPAWN_POS, lastInteractionPos); + metadata.put(EntityData.BED_POSITION, lastInteractionPos); if (session.getConnector().getConfig().isCacheChunks()) { - BlockState bed = session.getConnector().getWorldManager().getBlockAt(session, lastInteractionPos.getX(), + int bed = session.getConnector().getWorldManager().getBlockAt(session, lastInteractionPos.getX(), lastInteractionPos.getY(), lastInteractionPos.getZ()); // Bed has to be updated, or else player is floating in the air ChunkUtils.updateBlock(session, bed, lastInteractionPos); } } else { - metadata.put(EntityData.BED_RESPAWN_POS, Vector3i.from(position.getFloorX(), position.getFloorY() - 2, position.getFloorZ())); + metadata.put(EntityData.BED_POSITION, Vector3i.from(position.getFloorX(), position.getFloorY() - 2, position.getFloorZ())); } metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.2f); metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.2f); @@ -290,7 +349,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s metadata.getFlags().setFlag(EntityFlag.SLEEPING, false); metadata.put(EntityData.BOUNDING_BOX_WIDTH, getEntityType().getWidth()); metadata.put(EntityData.BOUNDING_BOX_HEIGHT, getEntityType().getHeight()); - metadata.put(EntityData.CAN_START_SLEEP, (byte) 0); + metadata.put(EntityData.PLAYER_FLAGS, (byte) 0); } break; case 7: // blocking diff --git a/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java index bfd3e1cae5e..c830d259613 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ExpOrbEntity.java @@ -26,7 +26,7 @@ package org.geysermc.connector.entity; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java index 59e1d408e40..54757b71f97 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java @@ -26,7 +26,7 @@ package org.geysermc.connector.entity; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.translators.world.block.BlockTranslator; diff --git a/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java index 1db4f757a06..e1a8e08af67 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java @@ -32,7 +32,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java index 1b648f7cf4d..cc7d749d99d 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java @@ -28,7 +28,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -63,6 +63,8 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s } } + //TODO Is ID 8 needed? + super.updateBedrockMetadata(entityMetadata, session); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/FurnaceMinecartEntity.java b/connector/src/main/java/org/geysermc/connector/entity/FurnaceMinecartEntity.java index ad2db877f2d..8f0d97b090f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FurnaceMinecartEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FurnaceMinecartEntity.java @@ -27,28 +27,32 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; -public class FurnaceMinecartEntity extends MinecartEntity { +public class FurnaceMinecartEntity extends DefaultBlockMinecartEntity { + + private boolean hasFuel = false; public FurnaceMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); - - metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(BlockTranslator.JAVA_RUNTIME_FURNACE_ID)); - metadata.put(EntityData.HAS_DISPLAY, (byte) 1); } @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 13) { - boolean hasFuel = (boolean) entityMetadata.getValue(); - - metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(hasFuel ? BlockTranslator.JAVA_RUNTIME_FURNACE_LIT_ID : BlockTranslator.JAVA_RUNTIME_FURNACE_ID)); + if (entityMetadata.getId() == 13 && !showCustomBlock) { + hasFuel = (boolean) entityMetadata.getValue(); + updateDefaultBlockMetadata(); } super.updateBedrockMetadata(entityMetadata, session); } + + @Override + public void updateDefaultBlockMetadata() { + metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(hasFuel ? BlockTranslator.JAVA_RUNTIME_FURNACE_LIT_ID : BlockTranslator.JAVA_RUNTIME_FURNACE_ID)); + metadata.put(EntityData.DISPLAY_OFFSET, 6); + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java index bd18dc46e76..41308a0ded6 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemEntity.java @@ -49,7 +49,7 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s itemPacket.setUniqueEntityId(geyserId); itemPacket.setFromFishing(false); itemPacket.getMetadata().putAll(metadata); - itemPacket.setItemInHand(ItemTranslator.translateToBedrock((ItemStack) entityMetadata.getValue())); + itemPacket.setItemInHand(ItemTranslator.translateToBedrock(session, (ItemStack) entityMetadata.getValue())); session.sendUpstreamPacket(itemPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java index a6d8af154c6..58edf29ddf5 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -32,7 +32,7 @@ import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.CompoundTag; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; @@ -98,7 +98,7 @@ public void spawnEntity(GeyserSession session) { @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) { - ItemData itemData = ItemTranslator.translateToBedrock((ItemStack) entityMetadata.getValue()); + ItemData itemData = ItemTranslator.translateToBedrock(session, (ItemStack) entityMetadata.getValue()); ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue()); CompoundTagBuilder builder = CompoundTag.builder(); @@ -150,7 +150,7 @@ public boolean despawnEntity(GeyserSession session) { updateBlockPacket.setBlockPosition(bedrockPosition); updateBlockPacket.setRuntimeId(0); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NO_GRAPHIC); //TODO: Used to be NONE updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); session.sendUpstreamPacket(updateBlockPacket); session.getItemFrameCache().remove(position, entityId); @@ -178,7 +178,7 @@ public void updateBlock(GeyserSession session) { updateBlockPacket.setBlockPosition(bedrockPosition); updateBlockPacket.setRuntimeId(bedrockRuntimeId); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NO_GRAPHIC); //TODO Same updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); session.sendUpstreamPacket(updateBlockPacket); diff --git a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java index f5aa4a544ab..3d1a1456f98 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java @@ -27,15 +27,13 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.ContainerId; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket; import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket; - import lombok.Getter; import lombok.Setter; - import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -58,13 +56,13 @@ public LivingEntity(long entityId, long geyserId, EntityType entityType, Vector3 public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { switch (entityMetadata.getId()) { case 8: - metadata.put(EntityData.HEALTH, (float) entityMetadata.getValue()); + metadata.put(EntityData.HEALTH, entityMetadata.getValue()); break; case 9: - metadata.put(EntityData.POTION_COLOR, (int) entityMetadata.getValue()); + metadata.put(EntityData.POTION_AUX_VALUE, entityMetadata.getValue()); //TODO: CHECK THIS AND THE BOTTOM ONE break; case 10: - metadata.put(EntityData.POTION_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); + metadata.put(EntityData.EFFECT_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); break; } diff --git a/connector/src/main/java/org/geysermc/connector/entity/MinecartEntity.java b/connector/src/main/java/org/geysermc/connector/entity/MinecartEntity.java index c2d7d47d515..72b5ee82097 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/MinecartEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/MinecartEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; @@ -55,20 +55,22 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s metadata.put(EntityData.HURT_TIME, Math.min((int) (float) entityMetadata.getValue(), 15)); } - // Custom block - if (entityMetadata.getId() == 10) { - metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId((int) entityMetadata.getValue())); - } + if (!(this instanceof DefaultBlockMinecartEntity)) { // Handled in the DefaultBlockMinecartEntity class + // Custom block + if (entityMetadata.getId() == 10) { + metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId((int) entityMetadata.getValue())); + } - // Custom block offset - if (entityMetadata.getId() == 11) { - metadata.put(EntityData.DISPLAY_OFFSET, entityMetadata.getValue()); - } + // Custom block offset + if (entityMetadata.getId() == 11) { + metadata.put(EntityData.DISPLAY_OFFSET, entityMetadata.getValue()); + } - // If the custom block should be enabled - if (entityMetadata.getId() == 12) { - // Needs a byte based off of Java's boolean - metadata.put(EntityData.HAS_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); + // If the custom block should be enabled + if (entityMetadata.getId() == 12) { + // Needs a byte based off of Java's boolean + metadata.put(EntityData.CUSTOM_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); + } } super.updateBedrockMetadata(entityMetadata, session); diff --git a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java index 1711fd38c31..d509b41f69a 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PaintingEntity.java @@ -52,7 +52,7 @@ public void spawnEntity(GeyserSession session) { AddPaintingPacket addPaintingPacket = new AddPaintingPacket(); addPaintingPacket.setUniqueEntityId(geyserId); addPaintingPacket.setRuntimeEntityId(geyserId); - addPaintingPacket.setName(paintingName.getBedrockName()); + addPaintingPacket.setMotive(paintingName.getBedrockName()); //TODO: This is what it's called now? addPaintingPacket.setPosition(fixOffset(true)); addPaintingPacket.setDirection(direction); session.sendUpstreamPacket(addPaintingPacket); @@ -62,6 +62,11 @@ public void spawnEntity(GeyserSession session) { session.getConnector().getLogger().debug("Spawned painting on " + position); } + @Override + public void updateHeadLookRotation(GeyserSession session, float headYaw) { + // Do nothing, as head look messes up paintings + } + public Vector3f fixOffset(boolean toBedrock) { if (toBedrock) { Vector3f position = super.position; diff --git a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java index aa7848da233..c567aa078e3 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -26,23 +26,24 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.auth.data.GameProfile; -import com.github.steveice10.mc.protocol.data.game.entity.Effect; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.*; +import com.nukkitx.protocol.bedrock.data.AttributeData; +import com.nukkitx.protocol.bedrock.data.PlayerPermission; +import com.nukkitx.protocol.bedrock.data.command.CommandPermission; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData; import com.nukkitx.protocol.bedrock.packet.*; - import lombok.Getter; import lombok.Setter; - import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.session.cache.EntityEffectCache; import org.geysermc.connector.scoreboard.Team; import org.geysermc.connector.utils.MessageUtils; -import org.geysermc.connector.network.session.cache.EntityEffectCache; import org.geysermc.connector.utils.SkinUtils; import java.util.ArrayList; @@ -57,7 +58,6 @@ public class PlayerEntity extends LivingEntity { private String username; private long lastSkinUpdate = -1; private boolean playerList = true; - private boolean onGround; private final EntityEffectCache effectCache; private Entity leftParrot; @@ -100,7 +100,7 @@ public void spawnEntity(GeyserSession session) { long linkedEntityId = session.getEntityCache().getCachedPlayerEntityLink(entityId); if (linkedEntityId != -1) { - addPlayerPacket.getEntityLinks().add(new EntityLink(session.getEntityCache().getEntityByJavaId(linkedEntityId).getGeyserId(), geyserId, EntityLink.Type.RIDER, false)); + addPlayerPacket.getEntityLinks().add(new EntityLinkData(session.getEntityCache().getEntityByJavaId(linkedEntityId).getGeyserId(), geyserId, EntityLinkData.Type.RIDER, false)); } valid = true; @@ -144,7 +144,7 @@ public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rota setPosition(position); setRotation(rotation); - this.onGround = isOnGround; + setOnGround(isOnGround); MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); movePlayerPacket.setRuntimeEntityId(geyserId); @@ -171,7 +171,7 @@ public void moveRelative(GeyserSession session, double relX, double relY, double setRotation(rotation); this.position = Vector3f.from(position.getX() + relX, position.getY() + relY, position.getZ() + relZ); - this.onGround = isOnGround; + setOnGround(isOnGround); MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); movePlayerPacket.setRuntimeEntityId(geyserId); @@ -188,6 +188,35 @@ public void moveRelative(GeyserSession session, double relX, double relY, double } } + @Override + public void updateHeadLookRotation(GeyserSession session, float headYaw) { + moveRelative(session, 0, 0, 0, Vector3f.from(rotation.getX(), rotation.getY(), headYaw), onGround); + MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); + movePlayerPacket.setRuntimeEntityId(geyserId); + movePlayerPacket.setPosition(position); + movePlayerPacket.setRotation(getBedrockRotation()); + movePlayerPacket.setMode(MovePlayerPacket.Mode.HEAD_ROTATION); + session.sendUpstreamPacket(movePlayerPacket); + } + + @Override + public void updatePositionAndRotation(GeyserSession session, double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) { + moveRelative(session, moveX, moveY, moveZ, yaw, pitch, isOnGround); + } + + @Override + public void updateRotation(GeyserSession session, float yaw, float pitch, boolean isOnGround) { + super.updateRotation(session, yaw, pitch, isOnGround); + // Both packets need to be sent or else player head rotation isn't correctly updated + MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); + movePlayerPacket.setRuntimeEntityId(geyserId); + movePlayerPacket.setPosition(position); + movePlayerPacket.setRotation(getBedrockRotation()); + movePlayerPacket.setOnGround(isOnGround); + movePlayerPacket.setMode(MovePlayerPacket.Mode.HEAD_ROTATION); + session.sendUpstreamPacket(movePlayerPacket); + } + @Override public void setPosition(Vector3f position) { this.position = position.add(0, entityType.getOffset(), 0); @@ -219,15 +248,15 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s if (entityMetadata.getId() == 14) { UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); attributesPacket.setRuntimeEntityId(geyserId); - List attributes = new ArrayList<>(); + List attributes = new ArrayList<>(); // Setting to a higher maximum since plugins/datapacks can probably extend the Bedrock soft limit - attributes.add(new Attribute("minecraft:absorption", 0.0f, 1024f, (float) entityMetadata.getValue(), 0.0f)); + attributes.add(new AttributeData("minecraft:absorption", 0.0f, 1024f, (float) entityMetadata.getValue(), 0.0f)); attributesPacket.setAttributes(attributes); session.sendUpstreamPacket(attributesPacket); } // Parrot occupying shoulder - if (entityMetadata.getId() == 18 || entityMetadata.getId() == 19) { + if ((entityMetadata.getId() == 18 && leftParrot == null) || (entityMetadata.getId() == 19 && rightParrot == null)) { // null check since this code just creates the parrot CompoundTag tag = (CompoundTag) entityMetadata.getValue(); if (tag != null && !tag.isEmpty()) { // The parrot is a separate entity in Bedrock, but part of the player entity in Java @@ -241,8 +270,8 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s parrot.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, 1); parrot.updateBedrockMetadata(session); SetEntityLinkPacket linkPacket = new SetEntityLinkPacket(); - EntityLink.Type type = (entityMetadata.getId() == 18) ? EntityLink.Type.RIDER : EntityLink.Type.PASSENGER; - linkPacket.setEntityLink(new EntityLink(geyserId, parrot.getGeyserId(), type, false)); + EntityLinkData.Type type = (entityMetadata.getId() == 18) ? EntityLinkData.Type.RIDER : EntityLinkData.Type.PASSENGER; + linkPacket.setEntityLink(new EntityLinkData(geyserId, parrot.getGeyserId(), type, false)); // Delay, or else spawned-in players won't get the link // TODO: Find a better solution. This problem also exists with item frames session.getConnector().getGeneralThreadPool().schedule(() -> session.sendUpstreamPacket(linkPacket), 500, TimeUnit.MILLISECONDS); diff --git a/connector/src/main/java/org/geysermc/connector/entity/SpawnerMinecartEntity.java b/connector/src/main/java/org/geysermc/connector/entity/SpawnerMinecartEntity.java new file mode 100644 index 00000000000..56341b3b051 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/SpawnerMinecartEntity.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2020 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.connector.entity; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; + +public class SpawnerMinecartEntity extends DefaultBlockMinecartEntity { + + public SpawnerMinecartEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } + + @Override + public void updateDefaultBlockMetadata() { + metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId(BlockTranslator.JAVA_RUNTIME_SPAWNER_ID)); + metadata.put(EntityData.DISPLAY_OFFSET, 6); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java b/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java index 629c9e51c5e..d2addbfbaec 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java @@ -28,8 +28,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/TridentEntity.java b/connector/src/main/java/org/geysermc/connector/entity/TridentEntity.java index 7c2442b0af1..4a9007aba5e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/TridentEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/TridentEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -39,7 +39,7 @@ public TridentEntity(long entityId, long geyserId, EntityType entityType, Vector @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 11) { + if (entityMetadata.getId() == 10) { metadata.getFlags().setFlag(EntityFlag.ENCHANTED, (boolean) entityMetadata.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/attribute/AttributeType.java b/connector/src/main/java/org/geysermc/connector/entity/attribute/AttributeType.java index 2061b89535c..1d692e2a7cb 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/attribute/AttributeType.java +++ b/connector/src/main/java/org/geysermc/connector/entity/attribute/AttributeType.java @@ -33,20 +33,20 @@ public enum AttributeType { // Universal Attributes - FOLLOW_RANGE("generic.followRange", "minecraft:follow_range", 0f, 2048f, 32f), - KNOCKBACK_RESISTANCE("generic.knockbackResistance", "minecraft:knockback_resistance", 0f, 1f, 0f), - MOVEMENT_SPEED("generic.movementSpeed", "minecraft:movement", 0f, 1024f, 0.1f), - FLYING_SPEED("generic.flyingSpeed", "minecraft:movement", 0.0f, 1024.0f, 0.4000000059604645f), - ATTACK_DAMAGE("generic.attackDamage", "minecraft:attack_damage", 0f, 2048f, 1f), - HORSE_JUMP_STRENGTH("horse.jumpStrength", "minecraft:horse.jump_strength", 0.0f, 2.0f, 0.7f), + FOLLOW_RANGE("minecraft:generic.follow_range", "minecraft:follow_range", 0f, 2048f, 32f), + KNOCKBACK_RESISTANCE("minecraft:generic.knockback_resistance", "minecraft:knockback_resistance", 0f, 1f, 0f), + MOVEMENT_SPEED("minecraft:generic.movement_speed", "minecraft:movement", 0f, 1024f, 0.1f), + FLYING_SPEED("minecraft:generic.flying_speed", "minecraft:movement", 0.0f, 1024.0f, 0.4000000059604645f), + ATTACK_DAMAGE("minecraft:generic.attack_damage", "minecraft:attack_damage", 0f, 2048f, 1f), + HORSE_JUMP_STRENGTH("minecraft:horse.jump_strength", "minecraft:horse.jump_strength", 0.0f, 2.0f, 0.7f), // Java Attributes - ARMOR("generic.armor", null, 0f, 30f, 0f), - ARMOR_TOUGHNESS("generic.armorToughness", null, 0F, 20f, 0f), - ATTACK_KNOCKBACK("generic.attackKnockback", null, 1.5f, Float.MAX_VALUE, 0f), - ATTACK_SPEED("generic.attackSpeed", null, 0f, 1024f, 4f), - LUCK("generic.luck", null, -1024f, 1024f, 0f), - MAX_HEALTH("generic.maxHealth", null, 0f, 1024f, 20f), + ARMOR("minecraft:generic.armor", null, 0f, 30f, 0f), + ARMOR_TOUGHNESS("minecraft:generic.armor_toughness", null, 0F, 20f, 0f), + ATTACK_KNOCKBACK("minecraft:generic.attack_knockback", null, 1.5f, Float.MAX_VALUE, 0f), + ATTACK_SPEED("minecraft:generic.attack_speed", null, 0f, 1024f, 4f), + LUCK("minecraft:generic.luck", null, -1024f, 1024f, 0f), + MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f), // Bedrock Attributes ABSORPTION(null, "minecraft:absorption", 0f, Float.MAX_VALUE, 0f), diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java index de5fa1b5be6..9c3e208404f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java @@ -26,7 +26,7 @@ package org.geysermc.connector.entity.living; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; public class AbstractFishEntity extends WaterEntity { diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java index b90983f7822..2175efcd6cb 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/AgeableEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java index 8d3c8f8fde4..07496093fcd 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/ArmorStandEntity.java @@ -28,24 +28,49 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.LivingEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; public class ArmorStandEntity extends LivingEntity { + // These are used to store the state of the armour stand for use when handling invisibility + private boolean isMarker = false; + private boolean isInvisible = false; + private boolean isSmall = false; + public ArmorStandEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } + @Override + public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) { + // Fake the height to be above where it is so the nametag appears in the right location for invisible non-marker armour stands + if (!isMarker && isInvisible) { + position = position.add(0d, entityType.getHeight() * (isSmall ? 0.55d : 1d), 0d); + } + + super.moveAbsolute(session, position, rotation, isOnGround, teleported); + } + @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getType() == MetadataType.BYTE) { + if (entityMetadata.getId() == 0 && entityMetadata.getType() == MetadataType.BYTE) { + byte xd = (byte) entityMetadata.getValue(); + + // Check if the armour stand is invisible and store accordingly + if ((xd & 0x20) == 0x20) { + metadata.put(EntityData.SCALE, 0.0f); + isInvisible = true; + } + } else if (entityMetadata.getId() == 14 && entityMetadata.getType() == MetadataType.BYTE) { byte xd = (byte) entityMetadata.getValue(); // isSmall if ((xd & 0x01) == 0x01) { + isSmall = true; + if (metadata.getFloat(EntityData.SCALE) != 0.55f && metadata.getFloat(EntityData.SCALE) != 0.0f) { metadata.put(EntityData.SCALE, 0.55f); } @@ -60,9 +85,10 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s } // setMarker - if ((xd & 0x10) == 0x10 && (metadata.get(EntityData.BOUNDING_BOX_WIDTH) != null && !metadata.get(EntityData.BOUNDING_BOX_WIDTH).equals(0.0f))) { + if ((xd & 0x10) == 0x10 && (metadata.get(EntityData.BOUNDING_BOX_WIDTH) == null || !metadata.get(EntityData.BOUNDING_BOX_WIDTH).equals(0.0f))) { metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.0f); metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.0f); + isMarker = true; } } super.updateBedrockMetadata(entityMetadata, session); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/InsentientEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/InsentientEntity.java index 2467dfe0d5a..808eb3cbb63 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/InsentientEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/InsentientEntity.java @@ -28,7 +28,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.LivingEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java index 26106f0a552..2ee22de7b30 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/SlimeEntity.java @@ -28,7 +28,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java index 69afd9754ae..b0692eab065 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/WaterEntity.java @@ -26,7 +26,7 @@ package org.geysermc.connector.entity.living; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; public class WaterEntity extends CreatureEntity { @@ -34,6 +34,6 @@ public class WaterEntity extends CreatureEntity { public WaterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); - metadata.put(EntityData.AIR, (short) 400); + metadata.put(EntityData.AIR_SUPPLY, (short) 400); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/BeeEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/BeeEntity.java index 537a1251198..c46f00fe824 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/BeeEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/BeeEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/FoxEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/FoxEntity.java index a277f8ee168..88c30cbfad1 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/FoxEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/FoxEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/OcelotEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/OcelotEntity.java index 1c5dc975220..36a67dbb7f7 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/OcelotEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/OcelotEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PandaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PandaEntity.java index f22815c684b..7e5551226f8 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PandaEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PandaEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java index b28ad99f571..0a7c83e7528 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PigEntity.java @@ -27,21 +27,58 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.AttributeData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; +import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.AttributeUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; public class PigEntity extends AnimalEntity { + // For updating the pig heart visual easier + private float health = 20f; + public PigEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 8) { + health = (float) entityMetadata.getValue(); + updateBedrockAttributes(session); + } + if (entityMetadata.getId() == 16) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); } super.updateBedrockMetadata(entityMetadata, session); } + + @Override + public void updateBedrockAttributes(GeyserSession session) { + if (!valid) return; + + float maxHealth = attributes.containsKey(AttributeType.MAX_HEALTH) ? attributes.get(AttributeType.MAX_HEALTH).getValue() : 20f; + + List attributesLocal = new ArrayList<>(); + for (Map.Entry entry : this.attributes.entrySet()) { + if (!entry.getValue().getType().isBedrockAttribute()) + continue; + + attributesLocal.add(AttributeUtils.getBedrockAttribute(entry.getValue())); + } + attributesLocal.add(new AttributeData("minecraft:health", 0.0f, maxHealth, health, maxHealth)); + + UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); + updateAttributesPacket.setRuntimeEntityId(geyserId); + updateAttributesPacket.setAttributes(attributesLocal); + session.sendUpstreamPacket(updateAttributesPacket); + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PolarBearEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PolarBearEntity.java index 6011d513001..2b09ca91228 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PolarBearEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PolarBearEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PufferFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PufferFishEntity.java index d5503dc06ed..407708a5592 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/PufferFishEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PufferFishEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.living.AbstractFishEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/RabbitEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/RabbitEntity.java index 6bc64bfd0c9..0b61713aac5 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/RabbitEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/RabbitEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/SheepEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/SheepEntity.java index e2b1b9791c1..464377efd55 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/SheepEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/SheepEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java new file mode 100644 index 00000000000..18bb8166e6f --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2020 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.connector.entity.living.animal; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class StriderEntity extends AnimalEntity { + + public StriderEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } + + @Override + public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + + if (entityMetadata.getId() == 18) { + metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); + } + + super.updateBedrockMetadata(entityMetadata, session); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java index a8866d7ecd8..eadc3db0c04 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import lombok.AllArgsConstructor; import lombok.Getter; import org.geysermc.connector.entity.living.AbstractFishEntity; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java index 3773011a322..48586c78fd6 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/AbstractHorseEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.Attribute; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.AttributeData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.living.animal.AnimalEntity; @@ -78,14 +78,14 @@ public void updateBedrockAttributes(GeyserSession session) { float maxHealth = attributes.containsKey(AttributeType.MAX_HEALTH) ? attributes.get(AttributeType.MAX_HEALTH).getValue() : 20f; - List attributesLocal = new ArrayList<>(); + List attributesLocal = new ArrayList<>(); for (Map.Entry entry : this.attributes.entrySet()) { if (!entry.getValue().getType().isBedrockAttribute()) continue; attributesLocal.add(AttributeUtils.getBedrockAttribute(entry.getValue())); } - attributesLocal.add(new Attribute("minecraft:health", 0.0f, maxHealth, health, maxHealth)); + attributesLocal.add(new AttributeData("minecraft:health", 0.0f, maxHealth, health, maxHealth)); UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); updateAttributesPacket.setRuntimeEntityId(geyserId); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/ChestedHorseEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/ChestedHorseEntity.java index df35435757c..7343f5e847f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/ChestedHorseEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/ChestedHorseEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/HorseEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/HorseEntity.java index 27f4b83c746..da3ff349317 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/HorseEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/HorseEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java index d4d7b72623e..ddac4a63fe9 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/LlamaEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java index b9505509f77..f01326730cf 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/horse/TraderLlamaEntity.java @@ -26,7 +26,7 @@ package org.geysermc.connector.entity.living.animal.horse; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/CatEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/CatEntity.java index 63a67a0a71b..067a360cfa4 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/CatEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/CatEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -38,6 +38,11 @@ public CatEntity(long entityId, long geyserId, EntityType entityType, Vector3f p super(entityId, geyserId, entityType, position, motion, rotation); } + @Override + public void updateRotation(GeyserSession session, float yaw, float pitch, boolean isOnGround) { + moveRelative(session, 0, 0, 0, Vector3f.from(this.rotation.getX(), pitch, yaw), isOnGround); + } + @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 18) { diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/ParrotEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/ParrotEntity.java index e02b3e7be8b..a867517a85a 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/ParrotEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/ParrotEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/TameableEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/TameableEntity.java index 2d3e0b1d153..2e8ab816c43 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/TameableEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/TameableEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.living.animal.AnimalEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/WolfEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/WolfEntity.java index 118262dcd00..aa578acb2dd 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/WolfEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/WolfEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -40,11 +40,6 @@ public WolfEntity(long entityId, long geyserId, EntityType entityType, Vector3f @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - // "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head - if (entityMetadata.getId() == 18) { - metadata.getFlags().setFlag(EntityFlag.INTERESTED, (boolean) entityMetadata.getValue()); - } - //Reset wolf color if (entityMetadata.getId() == 16) { byte xd = (byte) entityMetadata.getValue(); @@ -54,11 +49,17 @@ public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession s } } + // "Begging" on wiki.vg, "Interested" in Nukkit - the tilt of the head + if (entityMetadata.getId() == 18) { + metadata.getFlags().setFlag(EntityFlag.INTERESTED, (boolean) entityMetadata.getValue()); + } + // Wolf collar color // Relies on EntityData.OWNER_EID being set in TameableEntity.java if (entityMetadata.getId() == 19 && !metadata.getFlags().getFlag(EntityFlag.ANGRY)) { metadata.put(EntityData.COLOR, (byte) (int) entityMetadata.getValue()); } + //TODO: Anger time int? super.updateBedrockMetadata(entityMetadata, session); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/merchant/AbstractMerchantEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/merchant/AbstractMerchantEntity.java index ddeb31bd13d..11028b79e36 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/merchant/AbstractMerchantEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/merchant/AbstractMerchantEntity.java @@ -28,10 +28,16 @@ import com.nukkitx.math.vector.Vector3f; import org.geysermc.connector.entity.living.AgeableEntity; import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; public class AbstractMerchantEntity extends AgeableEntity { public AbstractMerchantEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } + + @Override + public void teleport(GeyserSession session, Vector3f position, float yaw, float pitch, boolean isOnGround) { + super.teleport(session, position, yaw - 180, pitch, isOnGround); + } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java index 895f8cc1d41..a2fa1c49a0d 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java @@ -28,7 +28,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import org.geysermc.connector.entity.type.EntityType; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/BlazeEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/BlazeEntity.java index 1683697671c..75fec18fc07 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/BlazeEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/BlazeEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java index 9b5c3822023..3c3a76bd708 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/CreeperEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java index fedd7980e9c..76b1ba2cd1a 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ElderGuardianEntity.java @@ -27,7 +27,7 @@ package org.geysermc.connector.entity.living.monster; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; public class ElderGuardianEntity extends GuardianEntity { diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java index 394be544b0d..aa2b4e026fe 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/EnderDragonEntity.java @@ -27,9 +27,9 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.Attribute; -import com.nukkitx.protocol.bedrock.data.EntityEventType; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.AttributeData; +import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.connector.entity.living.InsentientEntity; @@ -76,7 +76,7 @@ public void spawnEntity(GeyserSession session) { addEntityPacket.getMetadata().putAll(metadata); // Otherwise dragon is always 'dying' - addEntityPacket.getAttributes().add(new Attribute("minecraft:health", 0.0f, 200f, 200f, 200f)); + addEntityPacket.getAttributes().add(new AttributeData("minecraft:health", 0.0f, 200f, 200f, 200f)); valid = true; session.sendUpstreamPacket(addEntityPacket); diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/EndermanEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/EndermanEntity.java index 644181ab78a..914b208593e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/EndermanEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/EndermanEntity.java @@ -26,10 +26,9 @@ package org.geysermc.connector.entity.living.monster; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; @@ -44,7 +43,7 @@ public EndermanEntity(long entityId, long geyserId, EntityType entityType, Vecto public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { // Held block if (entityMetadata.getId() == 15) { - metadata.put(EntityData.ENDERMAN_HELD_ITEM_ID, BlockTranslator.getBedrockBlockId((BlockState) entityMetadata.getValue())); + metadata.put(EntityData.DISPLAY_ITEM, BlockTranslator.getBedrockBlockId((int) entityMetadata.getValue())); //TODO: Check } // 'Angry' - mouth open if (entityMetadata.getId() == 16) { diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.java index b9dc9e66bfa..aa22d8d672f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GiantEntity.java @@ -26,7 +26,7 @@ package org.geysermc.connector.entity.living.monster; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; public class GiantEntity extends MonsterEntity { diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java index 821faa85014..aa9ce4ca58c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/GuardianEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ShulkerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ShulkerEntity.java index bca9e689199..8728547fc08 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ShulkerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ShulkerEntity.java @@ -30,7 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.living.GolemEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/SpiderEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/SpiderEntity.java index 301145e6520..f0ad6f05835 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/SpiderEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/SpiderEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java index 005d0db3ab6..8b864525f3e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/WitherEntity.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombieEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombieEntity.java index 2ca212ff99d..218a2ca08c8 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombieEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombieEntity.java @@ -27,8 +27,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index cbe8e4cc9ea..4ec3471c712 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java +++ b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java @@ -68,7 +68,7 @@ public enum EntityType { CREEPER(CreeperEntity.class, 33, 1.7f, 0.6f, 0.6f, 1.62f), SKELETON(AbstractSkeletonEntity.class, 34, 1.8f, 0.6f, 0.6f, 1.62f), SPIDER(SpiderEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f), - ZOMBIE_PIGMAN(MonsterEntity.class, 36, 1.8f, 0.6f, 0.6f, 1.62f), + ZOMBIFIED_PIGLIN(MonsterEntity.class, 0, 1.8f, 0.6f, 0.6f, 1.62f, "minecraft:zombie_pigman"), SLIME(SlimeEntity.class, 37, 0.51f), ENDERMAN(EndermanEntity.class, 38, 2.9f, 0.6f), SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f), @@ -105,7 +105,7 @@ public enum EntityType { THROWN_EXP_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f, 0f, 0f, "minecraft:xp_bottle"), EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f, 0f, 0f, 0f, "minecraft:xp_orb"), EYE_OF_ENDER(Entity.class, 70, 0.25f, 0.25f, 0f, 0f, "minecraft:eye_of_ender_signal"), - END_CRYSTAL(EnderCrystalEntity.class, 71, 0f, 0f, 0f, 0f, "minecraft:ender_crystal"), + END_CRYSTAL(EnderCrystalEntity.class, 71, 2.0f, 2.0f, 2.0f, 0f, "minecraft:ender_crystal"), FIREWORK_ROCKET(FireworkEntity.class, 72, 0.25f, 0.25f, 0.25f, 0f, "minecraft:fireworks_rocket"), TRIDENT(TridentEntity.class, 73, 0f, 0f, 0f, 0f, "minecraft:thrown_trident"), TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f), @@ -134,11 +134,12 @@ public enum EntityType { MINECART_TNT(MinecartEntity.class, 97, 0.7f, 0.98f, 0.98f, 0.35f, "minecraft:tnt_minecart"), MINECART_CHEST(MinecartEntity.class, 98, 0.7f, 0.98f, 0.98f, 0.35f, "minecraft:chest_minecart"), MINECART_FURNACE(FurnaceMinecartEntity.class, 98, 0.7f, 0.98f, 0.98f, 0.35f, "minecraft:minecart"), + MINECART_SPAWNER(SpawnerMinecartEntity.class, 98, 0.7f, 0.98f, 0.98f, 0.35f, "minecraft:minecart"), MINECART_COMMAND_BLOCK(MinecartEntity.class, 100, 0.7f, 0.98f, 0.98f, 0.35f, "minecraft:command_block_minecart"), LINGERING_POTION(ThrowableEntity.class, 101, 0f), LLAMA_SPIT(Entity.class, 102, 0.25f), - EVOKER_FANGS(Entity.class, 103, 0.8f, 0.5f), - EVOKER(SpellcasterIllagerEntity.class, 104, 1.95f, 0.5f), + EVOKER_FANGS(Entity.class, 103, 0.8f, 0.5f, 0.5f, 0f, "minecraft:evocation_fang"), + EVOKER(SpellcasterIllagerEntity.class, 104, 1.95f, 0.6f, 0.6f, 0f, "minecraft:evocation_illager"), VEX(MonsterEntity.class, 105, 0.8f, 0.4f), ICE_BOMB(Entity.class, 106, 0f), BALLOON(Entity.class, 107, 0f), //TODO @@ -150,6 +151,10 @@ public enum EntityType { PANDA(PandaEntity.class, 113, 1.25f, 1.125f, 1.825f), FOX(FoxEntity.class, 121, 0.5f, 1.25f), BEE(BeeEntity.class, 122, 0.6f, 0.6f), + STRIDER(StriderEntity.class, 0, 1.7f, 0.9f, 0f, 0f, "minecraft:strider"), //TODO - update entity metadata + HOGLIN(AnimalEntity.class, 0, 0.9f, 0.9f, 0f, 0f, "minecraft:hoglin"), //TODO + ZOGLIN(MonsterEntity.class, 0, 0.9f, 0.9f, 0f, 0f, "minecraft:zoglin"), //TODO + PIGLIN(MonsterEntity.class, 0, 1.9f, 0.6f, 0f, 0f, "minecraft:piglin"), //TODO /** * Item frames are handled differently since they are a block in Bedrock. diff --git a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java index 29ba1567852..11ff9a029c0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -25,15 +25,17 @@ package org.geysermc.connector.network; -import com.github.steveice10.mc.protocol.data.message.Message; -import com.nukkitx.protocol.bedrock.*; +import com.github.steveice10.mc.protocol.data.message.MessageSerializer; +import com.nukkitx.protocol.bedrock.BedrockPong; +import com.nukkitx.protocol.bedrock.BedrockServerEventHandler; +import com.nukkitx.protocol.bedrock.BedrockServerSession; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.socket.DatagramPacket; -import org.geysermc.common.ping.GeyserPingInfo; -import org.geysermc.connector.ping.IGeyserPingPassthrough; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.utils.MessageUtils; import java.net.InetSocketAddress; @@ -73,7 +75,7 @@ public BedrockPong onQuery(InetSocketAddress inetSocketAddress) { pong.setIpv4Port(config.getBedrock().getPort()); if (config.isPassthroughMotd() && pingInfo != null && pingInfo.motd != null) { - String[] motd = MessageUtils.getBedrockMessage(Message.fromString(pingInfo.motd)).split("\n"); + String[] motd = MessageUtils.getBedrockMessage(MessageSerializer.fromString(pingInfo.motd)).split("\n"); String mainMotd = motd[0]; // First line of the motd. String subMotd = (motd.length != 1) ? motd[1] : ""; // Second line of the motd if present, otherwise blank. diff --git a/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java index 91b3ebd40e8..c41c64c7196 100644 --- a/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java @@ -628,12 +628,12 @@ public boolean handle(StructureBlockUpdatePacket packet) { } @Override - public boolean handle(StructureTemplateDataExportRequestPacket packet) { + public boolean handle(StructureTemplateDataRequestPacket packet) { return defaultHandler(packet); } @Override - public boolean handle(StructureTemplateDataExportResponsePacket packet) { + public boolean handle(StructureTemplateDataResponsePacket packet) { return defaultHandler(packet); } @@ -756,4 +756,74 @@ public boolean handle(CompletedUsingItemPacket packet) { public boolean handle(MultiplayerSettingsPacket packet) { return defaultHandler(packet); } + + // 1.16 new packets + + @Override + public boolean handle(DebugInfoPacket packet) { + return defaultHandler(packet); + } + + // I question if God exists because of this packet - God does not exist if I find out there's a built-in dab + // TODO for the future: redirect this as a /me command + // TODO for the far future: should we have a client mod that handles skins, handle these too + @Override + public boolean handle(EmoteListPacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(CodeBuilderPacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(CreativeContentPacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(ItemStackRequestPacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(LevelSoundEvent1Packet packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(ItemStackResponsePacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(PlayerArmorDamagePacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(PlayerEnchantOptionsPacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(UpdatePlayerGameTypePacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(PacketViolationWarningPacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(PositionTrackingDBClientRequestPacket packet) { + return defaultHandler(packet); + } + + @Override + public boolean handle(PositionTrackingDBServerBroadcastPacket packet) { + return defaultHandler(packet); + } } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java index 061e0f86b44..ba654c75beb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java @@ -26,10 +26,10 @@ package org.geysermc.connector.network; -import com.github.steveice10.mc.protocol.data.message.Message; +import com.github.steveice10.mc.protocol.data.message.MessageSerializer; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; -import org.geysermc.common.ping.GeyserPingInfo; +import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.utils.MessageUtils; @@ -60,6 +60,7 @@ public class QueryPacketHandler { /** * The Query packet handler instance + * * @param connector Geyser Connector * @param sender The Sender IP/Port for the Query * @param buffer The Query data @@ -79,11 +80,12 @@ public QueryPacketHandler(GeyserConnector connector, InetSocketAddress sender, B /** * Checks the packet is in fact a query packet + * * @param buffer Query data * @return if the packet is a query packet */ private boolean isQueryPacket(ByteBuf buffer) { - return (buffer.readableBytes() >= 2) ? buffer.readUnsignedShort() == 65277 : false; + return (buffer.readableBytes() >= 2) ? buffer.readUnsignedShort() == 0xFEFD : false; } /** @@ -130,6 +132,7 @@ private void sendQueryData() { /** * Gets the game data for the query + * * @return the game data for the query */ private byte[] getGameData() { @@ -145,7 +148,7 @@ private byte[] getGameData() { } if (connector.getConfig().isPassthroughMotd() && pingInfo != null) { - String[] javaMotd = MessageUtils.getBedrockMessage(Message.fromString(pingInfo.motd)).split("\n"); + String[] javaMotd = MessageUtils.getBedrockMessage(MessageSerializer.fromString(pingInfo.motd)).split("\n"); motd = javaMotd[0].trim(); // First line of the motd. } else { motd = connector.getConfig().getBedrock().getMotd1(); @@ -177,7 +180,7 @@ private byte[] getGameData() { // Blank Buffer Bytes query.write("GeyserMC".getBytes()); query.write((byte) 0x00); - query.write((byte) 128); + query.write((byte) 0x80); query.write((byte) 0x00); // Fills the game data @@ -189,7 +192,7 @@ private byte[] getGameData() { } // Final byte to show the end of the game data - query.write(new byte[]{0x00, 0x01}); + query.write(new byte[] { 0x00, 0x01 }); return query.toByteArray(); } catch (IOException e) { e.printStackTrace(); @@ -197,6 +200,11 @@ private byte[] getGameData() { } } + /** + * Generate a byte[] storing the player names + * + * @return The byte[] representation of players + */ private byte[] getPlayers() { ByteArrayOutputStream query = new ByteArrayOutputStream(); @@ -208,7 +216,7 @@ private byte[] getPlayers() { try { // Start the player section query.write("player_".getBytes()); - query.write(new byte[]{0x00, 0x00}); + query.write(new byte[] { 0x00, 0x00 }); // Fill player names if(pingInfo != null) { @@ -229,6 +237,7 @@ private byte[] getPlayers() { /** * Sends a packet to the sender + * * @param data packet data */ private void sendPacket(ByteBuf data) { @@ -251,18 +260,28 @@ public void regenerateToken() { * Gets an MD5 token for the current IP/Port. * This should reset every 30 seconds but a new one is generated per instance * Seems wasteful to code something in to clear it when it has no use. + * * @param token the token * @param address the address * @return an MD5 token for the current IP/Port */ public static byte[] getTokenString(byte[] token, InetAddress address) { try { + // Generate an MD5 hash from the address MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(address.toString().getBytes(StandardCharsets.UTF_8)); digest.update(token); - return Arrays.copyOf(digest.digest(), 4); + + // Get the first 4 bytes of the digest + byte[] digestBytes = Arrays.copyOf(digest.digest(), 4); + + // Convert the bytes to a buffer + ByteBuffer byteBuffer = ByteBuffer.wrap(digestBytes); + + // Turn the number into a null terminated string + return (byteBuffer.getInt() + "\0").getBytes(); } catch (NoSuchAlgorithmException e) { - return ByteBuffer.allocate(4).putInt(ThreadLocalRandom.current().nextInt()).array(); + return (ByteBuffer.allocate(4).putInt(ThreadLocalRandom.current().nextInt()).getInt() + "\0").getBytes(); } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java index 67862d0e733..79dcf138519 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -27,8 +27,8 @@ import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.packet.*; -import org.geysermc.common.AuthType; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.common.AuthType; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslatorRegistry; diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 73a2d7dd2e5..aadd69cf588 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -31,7 +31,8 @@ import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.github.steveice10.mc.protocol.data.game.window.VillagerTrade; +import com.github.steveice10.mc.protocol.data.message.MessageSerializer; import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket; import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; @@ -41,23 +42,21 @@ import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.tcp.TcpSessionFactory; import com.nukkitx.math.GenericMath; -import com.nukkitx.math.TrigMath; import com.nukkitx.math.vector.*; import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockServerSession; -import com.nukkitx.protocol.bedrock.data.ContainerId; -import com.nukkitx.protocol.bedrock.data.GamePublishSetting; -import com.nukkitx.protocol.bedrock.data.GameRuleData; -import com.nukkitx.protocol.bedrock.data.PlayerPermission; +import com.nukkitx.protocol.bedrock.data.*; import com.nukkitx.protocol.bedrock.packet.*; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2LongMap; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import lombok.Getter; import lombok.Setter; -import org.geysermc.common.AuthType; import org.geysermc.common.window.FormWindow; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; +import org.geysermc.connector.common.AuthType; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.inventory.PlayerInventory; @@ -70,9 +69,7 @@ import org.geysermc.connector.network.translators.PacketTranslatorRegistry; import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.world.block.BlockTranslator; -import org.geysermc.connector.utils.ChunkUtils; -import org.geysermc.connector.utils.LocaleUtils; -import org.geysermc.connector.utils.SkinUtils; +import org.geysermc.connector.utils.*; import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.EncryptionUtil; @@ -81,6 +78,8 @@ import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -108,6 +107,9 @@ public class GeyserSession implements CommandSender { @Setter private TeleportCache teleportCache; + @Getter + private final Long2ObjectMap storedMaps = new Long2ObjectOpenHashMap<>(); + /** * A map of Vector3i positions to Java entity IDs. * Used for translating Bedrock block actions to Java entity actions. @@ -142,7 +144,7 @@ public class GeyserSession implements CommandSender { private boolean jumping; @Setter - private BlockState breakingBlock; + private int breakingBlock; @Setter private Vector3i lastBlockPlacePosition; @@ -167,6 +169,26 @@ public class GeyserSession implements CommandSender { @Setter private int craftSlot = 0; + @Setter + private long lastWindowCloseTime = 0; + + @Setter + private VillagerTrade[] villagerTrades; + @Setter + private long lastInteractedVillagerEid; + + /** + * The current attack speed of the player. Used for sending proper cooldown timings. + */ + @Setter + private double attackSpeed; + /** + * The time of the last hit. Used to gauge how long the cooldown is taking. + * This is a session variable in order to prevent more scheduled threads than necessary. + */ + @Setter + private long lastHitTime; + private MinecraftProtocol protocol; public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { @@ -206,14 +228,24 @@ public void connect(RemoteServer remoteServer) { entityPacket.setTag(EntityIdentifierRegistry.ENTITY_IDENTIFIERS); upstream.sendPacket(entityPacket); - InventoryContentPacket creativePacket = new InventoryContentPacket(); - creativePacket.setContainerId(ContainerId.CREATIVE); - creativePacket.setContents(ItemRegistry.CREATIVE_ITEMS); + CreativeContentPacket creativePacket = new CreativeContentPacket(); + for (int i = 0; i < ItemRegistry.CREATIVE_ITEMS.length; i++) { + creativePacket.getEntries().put(i + 1, ItemRegistry.CREATIVE_ITEMS[i]); + } upstream.sendPacket(creativePacket); PlayStatusPacket playStatusPacket = new PlayStatusPacket(); playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); upstream.sendPacket(playStatusPacket); + + UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); + attributesPacket.setRuntimeEntityId(getPlayerEntity().getGeyserId()); + List attributes = new ArrayList<>(); + // Default move speed + // Bedrock clients move very fast by default until they get an attribute packet correcting the speed + attributes.add(new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f)); + attributesPacket.setAttributes(attributes); + upstream.sendPacket(attributesPacket); }, 500, TimeUnit.MILLISECONDS); } @@ -339,7 +371,8 @@ public void disconnected(DisconnectedEvent event) { if (event.getCause() != null) { event.getCause().printStackTrace(); } - upstream.disconnect(event.getReason()); + + upstream.disconnect(MessageUtils.getBedrockMessage(MessageSerializer.fromString(event.getReason()))); } @Override @@ -448,7 +481,7 @@ public void sendForm(FormWindow window, int id) { } public void setRenderDistance(int renderDistance) { - renderDistance = GenericMath.ceil(++renderDistance * TrigMath.SQRT_OF_TWO); //square to circle + renderDistance = GenericMath.ceil(++renderDistance * MathUtils.SQRT_OF_TWO); //square to circle if (renderDistance > 32) renderDistance = 32; // <3 u ViaVersion but I don't like crashing clients x) this.renderDistance = renderDistance; @@ -469,18 +502,18 @@ private void startGame() { StartGamePacket startGamePacket = new StartGamePacket(); startGamePacket.setUniqueEntityId(playerEntity.getGeyserId()); startGamePacket.setRuntimeEntityId(playerEntity.getGeyserId()); - startGamePacket.setPlayerGamemode(0); + startGamePacket.setPlayerGameType(GameType.SURVIVAL); startGamePacket.setPlayerPosition(Vector3f.from(0, 69, 0)); startGamePacket.setRotation(Vector2f.from(1, 1)); startGamePacket.setSeed(-1); - startGamePacket.setDimensionId(playerEntity.getDimension()); + startGamePacket.setDimensionId(DimensionUtils.javaToBedrock(playerEntity.getDimension())); startGamePacket.setGeneratorId(1); - startGamePacket.setLevelGamemode(0); + startGamePacket.setLevelGameType(GameType.SURVIVAL); startGamePacket.setDifficulty(1); startGamePacket.setDefaultSpawn(Vector3i.ZERO); startGamePacket.setAchievementsDisabled(true); - startGamePacket.setTime(-1); + startGamePacket.setCurrentTick(-1); startGamePacket.setEduEditionOffers(0); startGamePacket.setEduFeaturesEnabled(false); startGamePacket.setRainLevel(0); @@ -505,7 +538,7 @@ private void startGame() { startGamePacket.setWorldTemplateOptionLocked(false); startGamePacket.setLevelId("world"); - startGamePacket.setWorldName("world"); + startGamePacket.setLevelName("world"); startGamePacket.setPremiumWorldTemplateId("00000000-0000-0000-0000-000000000000"); // startGamePacket.setCurrentTick(0); startGamePacket.setEnchantmentSeed(0); diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java index 267f3cb1fda..68e8519c177 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.message.Message; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.packet.AddEntityPacket; import com.nukkitx.protocol.bedrock.packet.BossEventPacket; import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket; @@ -52,10 +52,12 @@ public void addBossBar() { updateBossBar(); } + //TODO: There is a player unique entity ID - if this didn't exist before, we may be able to get rid of our hack + public void updateBossBar() { BossEventPacket bossEventPacket = new BossEventPacket(); bossEventPacket.setBossUniqueEntityId(entityId); - bossEventPacket.setAction(BossEventPacket.Action.SHOW); + bossEventPacket.setAction(BossEventPacket.Action.CREATE); bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(title, session.getClientData().getLanguageCode())); bossEventPacket.setHealthPercentage(health); bossEventPacket.setColor(color); //ignored by client @@ -69,7 +71,7 @@ public void updateTitle(Message title) { this.title = title; BossEventPacket bossEventPacket = new BossEventPacket(); bossEventPacket.setBossUniqueEntityId(entityId); - bossEventPacket.setAction(BossEventPacket.Action.TITLE); + bossEventPacket.setAction(BossEventPacket.Action.UPDATE_NAME); bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(title, session.getClientData().getLanguageCode())); session.sendUpstreamPacket(bossEventPacket); @@ -79,7 +81,7 @@ public void updateHealth(float health) { this.health = health; BossEventPacket bossEventPacket = new BossEventPacket(); bossEventPacket.setBossUniqueEntityId(entityId); - bossEventPacket.setAction(BossEventPacket.Action.HEALTH_PERCENTAGE); + bossEventPacket.setAction(BossEventPacket.Action.UPDATE_PERCENTAGE); bossEventPacket.setHealthPercentage(health); session.sendUpstreamPacket(bossEventPacket); @@ -88,7 +90,7 @@ public void updateHealth(float health) { public void removeBossBar() { BossEventPacket bossEventPacket = new BossEventPacket(); bossEventPacket.setBossUniqueEntityId(entityId); - bossEventPacket.setAction(BossEventPacket.Action.HIDE); + bossEventPacket.setAction(BossEventPacket.Action.REMOVE); session.sendUpstreamPacket(bossEventPacket); removeBossEntity(); diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/ChunkCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/ChunkCache.java index ac7ab06cffd..a7b0c96653f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/ChunkCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/ChunkCache.java @@ -28,7 +28,6 @@ import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; import com.github.steveice10.mc.protocol.data.game.chunk.Column; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import lombok.Getter; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; @@ -58,7 +57,7 @@ public void addToCache(Column chunk) { chunks.put(position, chunk); } - public void updateBlock(Position position, BlockState block) { + public void updateBlock(Position position, int block) { if (!cache) { return; } @@ -74,7 +73,7 @@ public void updateBlock(Position position, BlockState block) { } } - public BlockState getBlockAt(Position position) { + public int getBlockAt(Position position) { if (!cache) { return BlockTranslator.AIR; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java index c3ec8ff2d7b..a11dd40aff2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java @@ -26,6 +26,7 @@ package org.geysermc.connector.network.translators; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerKeepAlivePacket; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerPlayerListDataPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateLightPacket; import com.github.steveice10.packetlib.packet.Packet; import com.nukkitx.protocol.bedrock.BedrockPacket; @@ -74,6 +75,7 @@ public class PacketTranslatorRegistry { IGNORED_PACKETS.add(ServerKeepAlivePacket.class); // Handled by MCProtocolLib IGNORED_PACKETS.add(ServerUpdateLightPacket.class); // Light is handled on Bedrock for us + IGNORED_PACKETS.add(ServerPlayerListDataPacket.class); // Cant be implemented in bedrock } private PacketTranslatorRegistry() { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java index 2c44e4fdbea..7d8772fbdfb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java @@ -25,15 +25,6 @@ package org.geysermc.connector.network.translators.bedrock; -import java.util.concurrent.TimeUnit; - -import com.nukkitx.protocol.bedrock.data.LevelEventType; -import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; -import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.PacketTranslator; -import org.geysermc.connector.network.translators.Translator; - import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; @@ -41,10 +32,18 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket; import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import java.util.concurrent.TimeUnit; + @Translator(packet = PlayerActionPacket.class) public class BedrockActionTranslator extends PacketTranslator { @@ -113,8 +112,8 @@ public void translate(PlayerActionPacket packet, GeyserSession session) { break; case CONTINUE_BREAK: LevelEventPacket continueBreakPacket = new LevelEventPacket(); - continueBreakPacket.setType(LevelEventType.PUNCH_BLOCK); - continueBreakPacket.setData(BlockTranslator.getBedrockBlockId(session.getBreakingBlock() == null ? BlockTranslator.AIR : session.getBreakingBlock())); + continueBreakPacket.setType(LevelEventType.BLOCK_UPDATE_BREAK); //TODO: There are now level event types for all breaks. Important? + continueBreakPacket.setData(BlockTranslator.getBedrockBlockId(session.getBreakingBlock())); continueBreakPacket.setPosition(packet.getBlockPosition().toFloat()); session.sendUpstreamPacket(continueBreakPacket); break; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java index 75a1547f508..e741ca35c13 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java @@ -28,6 +28,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerAbilitiesPacket; +import com.nukkitx.protocol.bedrock.data.AdventureSetting; import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -40,11 +41,11 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator= 0 && packet.getData() < trades.length) { + VillagerTrade trade = session.getVillagerTrades()[packet.getData()]; + openInventory.setItem(2, trade.getOutput()); + villager.getMetadata().put(EntityData.TRADE_XP, trade.getXp() + villager.getMetadata().getInt(EntityData.TRADE_XP)); + villager.updateBedrockMetadata(session); + } + } + return; } session.getConnector().getLogger().debug("Did not translate incoming EntityEventPacket: " + packet.toString()); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java index bfd4a90a5e0..167073273a3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInteractTranslator.java @@ -25,8 +25,11 @@ package org.geysermc.connector.network.translators.bedrock; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; +import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -45,7 +48,13 @@ public class BedrockInteractTranslator extends PacketTranslator @Override public void translate(InteractPacket packet, GeyserSession session) { - Entity entity = session.getEntityCache().getEntityByGeyserId(packet.getRuntimeEntityId()); + Entity entity; + if (packet.getRuntimeEntityId() == session.getPlayerEntity().getGeyserId()) { + //Player is not in entity cache + entity = session.getPlayerEntity(); + } else { + entity = session.getEntityCache().getEntityByGeyserId(packet.getRuntimeEntityId()); + } if (entity == null) return; @@ -55,12 +64,12 @@ public void translate(InteractPacket packet, GeyserSession session) { break; } ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), - InteractAction.INTERACT, Hand.MAIN_HAND); + InteractAction.INTERACT, Hand.MAIN_HAND, session.isSneaking()); session.sendDownstreamPacket(interactPacket); break; case DAMAGE: ClientPlayerInteractEntityPacket attackPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), - InteractAction.ATTACK, Hand.MAIN_HAND); + InteractAction.ATTACK, Hand.MAIN_HAND, session.isSneaking()); session.sendDownstreamPacket(attackPacket); break; case LEAVE_VEHICLE: @@ -74,33 +83,43 @@ public void translate(InteractPacket packet, GeyserSession session) { Entity interactEntity = session.getEntityCache().getEntityByGeyserId(packet.getRuntimeEntityId()); if (interactEntity == null) return; + EntityDataMap entityMetadata = interactEntity.getMetadata(); String interactiveTag; switch (interactEntity.getEntityType()) { - case PIG: - if (interactEntity.getMetadata().getFlags().getFlag(EntityFlag.SADDLED)) { - interactiveTag = "action.interact.mount"; - } else interactiveTag = ""; + case BOAT: + interactiveTag = "action.interact.ride.boat"; break; - case HORSE: - case SKELETON_HORSE: - case ZOMBIE_HORSE: case DONKEY: - case MULE: + case HORSE: case LLAMA: + case MULE: + case SKELETON_HORSE: case TRADER_LLAMA: - if (interactEntity.getMetadata().getFlags().getFlag(EntityFlag.TAMED)) { + case ZOMBIE_HORSE: + if (entityMetadata.getFlags().getFlag(EntityFlag.TAMED)) { interactiveTag = "action.interact.ride.horse"; } else { interactiveTag = "action.interact.mount"; } break; - case BOAT: - interactiveTag = "action.interact.ride.boat"; - break; case MINECART: interactiveTag = "action.interact.ride.minecart"; break; + case PIG: + if (entityMetadata.getFlags().getFlag(EntityFlag.SADDLED)) { + interactiveTag = "action.interact.mount"; + } else interactiveTag = ""; + break; + case VILLAGER: + if (entityMetadata.getInt(EntityData.VARIANT) != 14 && entityMetadata.getInt(EntityData.VARIANT) != 0 + && entityMetadata.getFloat(EntityData.SCALE) >= 0.75f) { // Not a nitwit, has a profession and is not a baby + interactiveTag = "action.interact.trade"; + } else interactiveTag = ""; + break; + case WANDERING_TRADER: + interactiveTag = "action.interact.trade"; // Since you can always trade with a wandering villager, presumably. + break; default: return; // No need to process any further since there is no interactive tag } @@ -115,6 +134,14 @@ public void translate(InteractPacket packet, GeyserSession session) { } } break; + case OPEN_INVENTORY: + ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket(); + containerOpenPacket.setId((byte) 0); + containerOpenPacket.setType(ContainerType.INVENTORY); + containerOpenPacket.setUniqueEntityId(-1); + containerOpenPacket.setBlockPosition(entity.getPosition().toInt()); + session.sendUpstreamPacket(containerOpenPacket); + break; } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java index 8f96b8004a0..f05c46f2497 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java @@ -36,7 +36,6 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.LevelEventType; @@ -45,6 +44,7 @@ import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.ItemFrameEntity; +import org.geysermc.connector.entity.living.merchant.AbstractMerchantEntity; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -82,9 +82,9 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session) session.getEntityCache().getEntityByJavaId(ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition())) != null) { Vector3f vector = packet.getClickPosition(); ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition()), - InteractAction.INTERACT, Hand.MAIN_HAND); + InteractAction.INTERACT, Hand.MAIN_HAND, session.isSneaking()); ClientPlayerInteractEntityPacket interactAtPacket = new ClientPlayerInteractEntityPacket((int) ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition()), - InteractAction.INTERACT_AT, vector.getX(), vector.getY(), vector.getZ(), Hand.MAIN_HAND); + InteractAction.INTERACT_AT, vector.getX(), vector.getY(), vector.getZ(), Hand.MAIN_HAND, session.isSneaking()); session.sendDownstreamPacket(interactPacket); session.sendDownstreamPacket(interactAtPacket); break; @@ -92,7 +92,7 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session) ClientPlayerPlaceBlockPacket blockPacket = new ClientPlayerPlaceBlockPacket( new Position(packet.getBlockPosition().getX(), packet.getBlockPosition().getY(), packet.getBlockPosition().getZ()), - BlockFace.values()[packet.getFace()], + BlockFace.values()[packet.getBlockFace()], Hand.MAIN_HAND, packet.getClickPosition().getX(), packet.getClickPosition().getY(), packet.getClickPosition().getZ(), false); @@ -106,7 +106,7 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session) Vector3i blockPos = packet.getBlockPosition(); // TODO: Find a better way to do this? - switch (packet.getFace()) { + switch (packet.getBlockFace()) { case 0: blockPos = blockPos.sub(0, 1, 0); break; @@ -145,14 +145,14 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session) session.setLastInteractionPosition(packet.getBlockPosition()); break; case 2: - BlockState blockState = session.getConnector().getWorldManager().getBlockAt(session, packet.getBlockPosition().getX(), packet.getBlockPosition().getY(), packet.getBlockPosition().getZ()); - double blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(blockState.getId()); + int blockState = session.getConnector().getWorldManager().getBlockAt(session, packet.getBlockPosition().getX(), packet.getBlockPosition().getY(), packet.getBlockPosition().getZ()); + double blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(blockState); if (session.getGameMode() == GameMode.CREATIVE || (session.getConnector().getConfig().isCacheChunks() && blockHardness == 0)) { session.setLastBlockPlacedId(null); session.setLastBlockPlacePosition(null); LevelEventPacket blockBreakPacket = new LevelEventPacket(); - blockBreakPacket.setType(LevelEventType.DESTROY); + blockBreakPacket.setType(LevelEventType.BLOCK_STOP_BREAK); //TODO: Make sure this is the right new enum blockBreakPacket.setPosition(packet.getBlockPosition().toFloat()); blockBreakPacket.setData(BlockTranslator.getBedrockBlockId(blockState)); session.sendUpstreamPacket(blockBreakPacket); @@ -161,14 +161,14 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session) if (ItemFrameEntity.positionContainsItemFrame(session, packet.getBlockPosition()) && session.getEntityCache().getEntityByJavaId(ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition())) != null) { ClientPlayerInteractEntityPacket attackPacket = new ClientPlayerInteractEntityPacket((int) ItemFrameEntity.getItemFrameEntityId(session, packet.getBlockPosition()), - InteractAction.ATTACK); + InteractAction.ATTACK, session.isSneaking()); session.sendDownstreamPacket(attackPacket); break; } PlayerAction action = session.getGameMode() == GameMode.CREATIVE ? PlayerAction.START_DIGGING : PlayerAction.FINISH_DIGGING; Position pos = new Position(packet.getBlockPosition().getX(), packet.getBlockPosition().getY(), packet.getBlockPosition().getZ()); - ClientPlayerActionPacket breakPacket = new ClientPlayerActionPacket(action, pos, BlockFace.values()[packet.getFace()]); + ClientPlayerActionPacket breakPacket = new ClientPlayerActionPacket(action, pos, BlockFace.values()[packet.getBlockFace()]); session.sendDownstreamPacket(breakPacket); break; } @@ -191,17 +191,21 @@ public void translate(InventoryTransactionPacket packet, GeyserSession session) case 0: //Interact Vector3f vector = packet.getClickPosition(); ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), - InteractAction.INTERACT, Hand.MAIN_HAND); + InteractAction.INTERACT, Hand.MAIN_HAND, session.isSneaking()); ClientPlayerInteractEntityPacket interactAtPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), - InteractAction.INTERACT_AT, vector.getX(), vector.getY(), vector.getZ(), Hand.MAIN_HAND); + InteractAction.INTERACT_AT, vector.getX(), vector.getY(), vector.getZ(), Hand.MAIN_HAND, session.isSneaking()); session.sendDownstreamPacket(interactPacket); session.sendDownstreamPacket(interactAtPacket); EntitySoundInteractionHandler.handleEntityInteraction(session, vector, entity); + + if (entity instanceof AbstractMerchantEntity) { + session.setLastInteractedVillagerEid(packet.getRuntimeEntityId()); + } break; case 1: //Attack ClientPlayerInteractEntityPacket attackPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), - InteractAction.ATTACK); + InteractAction.ATTACK, session.isSneaking()); session.sendDownstreamPacket(attackPacket); break; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockItemFrameDropItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockItemFrameDropItemTranslator.java index 73939894242..168e552b65f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockItemFrameDropItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockItemFrameDropItemTranslator.java @@ -50,7 +50,7 @@ public void translate(ItemFrameDropItemPacket packet, GeyserSession session) { } Vector3i position = Vector3i.from(packet.getBlockPosition().getX(), y, packet.getBlockPosition().getZ()); ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) ItemFrameEntity.getItemFrameEntityId(session, position), - InteractAction.ATTACK, Hand.MAIN_HAND); + InteractAction.ATTACK, Hand.MAIN_HAND, session.isSneaking()); session.sendDownstreamPacket(interactPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLevelSoundEventTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLevelSoundEventTranslator.java index 6395f0a132a..08ad10bfbc8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLevelSoundEventTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockLevelSoundEventTranslator.java @@ -25,10 +25,12 @@ package org.geysermc.connector.network.translators.bedrock; +import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.utils.CooldownUtils; @Translator(packet = LevelSoundEventPacket.class) public class BedrockLevelSoundEventTranslator extends PacketTranslator { @@ -37,5 +39,12 @@ public class BedrockLevelSoundEventTranslator extends PacketTranslator { +@Translator(packet = MapInfoRequestPacket.class) +public class BedrockMapInfoRequestTranslator extends PacketTranslator { @Override - public void translate(ServerSpawnWeatherEntityPacket packet, GeyserSession session) { - Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ()); + public void translate(MapInfoRequestPacket packet, GeyserSession session) { + long mapID = packet.getUniqueMapId(); - // Currently WeatherEntityType only has a lightning bolt - Entity entity = new Entity( - packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), - EntityType.LIGHTNING_BOLT, position, Vector3f.ZERO, Vector3f.ZERO - ); - - session.getEntityCache().spawnEntity(entity); + if (session.getStoredMaps().containsKey(mapID)) { + // Delay the packet 100ms to prevent the client from ignoring the packet + GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> { + session.sendUpstreamPacket(session.getStoredMaps().get(mapID)); + session.getStoredMaps().remove(mapID); + }, 100, TimeUnit.MILLISECONDS); + } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMobEquipmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMobEquipmentTranslator.java index 5fc7f41aed3..02835151a7c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMobEquipmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMobEquipmentTranslator.java @@ -30,8 +30,9 @@ import org.geysermc.connector.network.translators.Translator; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerChangeHeldItemPacket; -import com.nukkitx.protocol.bedrock.data.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket; +import org.geysermc.connector.utils.CooldownUtils; @Translator(packet = MobEquipmentPacket.class) public class BedrockMobEquipmentTranslator extends PacketTranslator { @@ -47,5 +48,8 @@ public void translate(MobEquipmentPacket packet, GeyserSession session) { ClientPlayerChangeHeldItemPacket changeHeldItemPacket = new ClientPlayerChangeHeldItemPacket(packet.getHotbarSlot()); session.sendDownstreamPacket(changeHeldItemPacket); + + // Java sends a cooldown indicator whenever you switch an item + CooldownUtils.sendCooldown(session); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java index 14d597fd58c..0abf8150571 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMovePlayerTranslator.java @@ -26,7 +26,7 @@ package org.geysermc.connector.network.translators.bedrock; import com.nukkitx.math.vector.Vector3d; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.type.EntityType; @@ -137,7 +137,7 @@ public void recalculatePosition(GeyserSession session, Entity entity, Vector3f c movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); movePlayerPacket.setPosition(entity.getPosition()); movePlayerPacket.setRotation(entity.getBedrockRotation()); - movePlayerPacket.setMode(MovePlayerPacket.Mode.RESET); + movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN); session.sendUpstreamPacket(movePlayerPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPacketViolationWarningTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPacketViolationWarningTranslator.java new file mode 100644 index 00000000000..9e3c14e6dc3 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPacketViolationWarningTranslator.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019-2020 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.connector.network.translators.bedrock; + +import com.nukkitx.protocol.bedrock.packet.PacketViolationWarningPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; + +@Translator(packet = PacketViolationWarningPacket.class) +public class BedrockPacketViolationWarningTranslator extends PacketTranslator { + + @Override + public void translate(PacketViolationWarningPacket packet, GeyserSession session) { + session.getConnector().getLogger().error("Packet violation warning sent from client! " + packet.toString()); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java index f301d2b5d22..c5d1de252d7 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java @@ -26,18 +26,17 @@ package org.geysermc.connector.network.translators.inventory; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; -import com.github.steveice10.mc.protocol.data.message.Message; +import com.github.steveice10.mc.protocol.data.message.MessageSerializer; +import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientRenameItemPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.nukkitx.protocol.bedrock.data.ContainerId; -import com.nukkitx.protocol.bedrock.data.ContainerType; -import com.nukkitx.protocol.bedrock.data.InventoryActionData; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.*; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.updater.CursorInventoryUpdater; import java.util.List; +import java.util.stream.Collectors; public class AnvilInventoryTranslator extends BlockInventoryTranslator { public AnvilInventoryTranslator() { @@ -46,7 +45,7 @@ public AnvilInventoryTranslator() { @Override public int bedrockSlotToJava(InventoryActionData action) { - if (action.getSource().getContainerId() == ContainerId.CURSOR) { + if (action.getSource().getContainerId() == ContainerId.UI) { switch (action.getSlot()) { case 1: return 0; @@ -56,6 +55,9 @@ public int bedrockSlotToJava(InventoryActionData action) { return 2; } } + if (action.getSource().getContainerId() == ContainerId.ANVIL_RESULT) { + return 2; + } return super.bedrockSlotToJava(action); } @@ -111,7 +113,13 @@ public void translateActions(GeyserSession session, Inventory inventory, List strippedActions = actions.stream() + .filter(action -> action.getSource().getContainerId() == ContainerId.ANVIL_RESULT + || (action.getSource().getType() == InventorySource.Type.CONTAINER + && !(action.getSource().getContainerId() == ContainerId.UI && action.getSlot() != 0))) + .collect(Collectors.toList()); + super.translateActions(session, inventory, strippedActions); return; } @@ -120,7 +128,7 @@ public void translateActions(GeyserSession session, Inventory inventory, List= 0 && slot <= 2) { + if (slot == 0) { ItemStack item = inventory.getItem(slot); if (item != null) { String rename; @@ -129,7 +137,7 @@ public void updateSlot(GeyserSession session, Inventory inventory, int slot) { CompoundTag displayTag = tag.get("display"); if (displayTag != null) { String itemName = displayTag.get("Name").getValue().toString(); - Message message = Message.fromString(itemName); + TextMessage message = (TextMessage) MessageSerializer.fromString(itemName); rename = message.getText(); } else { rename = ""; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java index 5deb0370a14..6f00fc4d773 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BaseInventoryTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.connector.network.translators.inventory; -import com.nukkitx.protocol.bedrock.data.ContainerId; -import com.nukkitx.protocol.bedrock.data.InventoryActionData; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java index ab410ea8b7f..4b8b57e8fa6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java @@ -25,8 +25,7 @@ package org.geysermc.connector.network.translators.inventory; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; -import com.nukkitx.protocol.bedrock.data.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; @@ -40,7 +39,7 @@ public class BlockInventoryTranslator extends BaseInventoryTranslator { public BlockInventoryTranslator(int size, String javaBlockIdentifier, ContainerType containerType, InventoryUpdater updater) { super(size); - BlockState javaBlockState = BlockTranslator.getJavaBlockState(javaBlockIdentifier); + int javaBlockState = BlockTranslator.getJavaBlockState(javaBlockIdentifier); int blockId = BlockTranslator.getBedrockBlockId(javaBlockState); this.holder = new BlockInventoryHolder(blockId, containerType); this.updater = updater; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java index acda7c918cb..89cdbe8d742 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BrewingInventoryTranslator.java @@ -25,8 +25,8 @@ package org.geysermc.connector.network.translators.inventory; -import com.nukkitx.protocol.bedrock.data.ContainerType; -import com.nukkitx.protocol.bedrock.data.InventoryActionData; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; import com.nukkitx.protocol.bedrock.packet.ContainerSetDataPacket; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/ChestInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/ChestInventoryTranslator.java new file mode 100644 index 00000000000..152f4a85274 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/ChestInventoryTranslator.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019-2020 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.connector.network.translators.inventory; + +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; +import org.geysermc.connector.inventory.Inventory; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.inventory.updater.ChestInventoryUpdater; +import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; +import org.geysermc.connector.utils.InventoryUtils; + +import java.util.List; + +public abstract class ChestInventoryTranslator extends BaseInventoryTranslator { + private final InventoryUpdater updater; + + public ChestInventoryTranslator(int size, int paddedSize) { + super(size); + this.updater = new ChestInventoryUpdater(paddedSize); + } + + @Override + public void updateInventory(GeyserSession session, Inventory inventory) { + updater.updateInventory(this, session, inventory); + } + + @Override + public void updateSlot(GeyserSession session, Inventory inventory, int slot) { + updater.updateSlot(this, session, inventory, slot); + } + + @Override + public void translateActions(GeyserSession session, Inventory inventory, List actions) { + for (InventoryActionData action : actions) { + if (action.getSource().getContainerId() == inventory.getId()) { + if (action.getSlot() >= size) { + updateInventory(session, inventory); + InventoryUtils.updateCursor(session); + return; + } + } + } + + super.translateActions(session, inventory, actions); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java index 3f887001f0e..afcb321a416 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java @@ -26,10 +26,10 @@ package org.geysermc.connector.network.translators.inventory; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; -import com.nukkitx.protocol.bedrock.data.ContainerId; -import com.nukkitx.protocol.bedrock.data.ContainerType; -import com.nukkitx.protocol.bedrock.data.InventoryActionData; -import com.nukkitx.protocol.bedrock.data.InventorySource; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; +import com.nukkitx.protocol.bedrock.data.inventory.InventorySource; import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; @@ -39,52 +39,17 @@ import java.util.List; -public class CraftingInventoryTranslator extends BaseInventoryTranslator { - private final InventoryUpdater updater; - +public class CraftingInventoryTranslator extends BlockInventoryTranslator { public CraftingInventoryTranslator() { - super(10); - this.updater = new CursorInventoryUpdater(); - } - - @Override - public void prepareInventory(GeyserSession session, Inventory inventory) { - // - } - - @Override - public void openInventory(GeyserSession session, Inventory inventory) { - ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket(); - containerOpenPacket.setWindowId((byte) inventory.getId()); - containerOpenPacket.setType((byte) ContainerType.WORKBENCH.id()); - containerOpenPacket.setBlockPosition(inventory.getHolderPosition()); - containerOpenPacket.setUniqueEntityId(inventory.getHolderId()); - session.sendUpstreamPacket(containerOpenPacket); - } - - @Override - public void closeInventory(GeyserSession session, Inventory inventory) { - // - } - - @Override - public void updateInventory(GeyserSession session, Inventory inventory) { - updater.updateInventory(this, session, inventory); - } - - @Override - public void updateSlot(GeyserSession session, Inventory inventory, int slot) { - updater.updateSlot(this, session, inventory, slot); + super(10, "minecraft:crafting_table", ContainerType.WORKBENCH, new CursorInventoryUpdater()); } @Override public int bedrockSlotToJava(InventoryActionData action) { - if (action.getSource().getContainerId() == ContainerId.CURSOR) { + if (action.getSource().getContainerId() == ContainerId.UI) { int slotnum = action.getSlot(); if (slotnum >= 32 && 42 >= slotnum) { return slotnum - 31; - } else if (slotnum == 50) { - return 0; } } return super.bedrockSlotToJava(action); @@ -92,7 +57,10 @@ public int bedrockSlotToJava(InventoryActionData action) { @Override public int javaSlotToBedrock(int slot) { - return slot == 0 ? 50 : slot + 31; + if (slot < size) { + return slot == 0 ? 50 : slot + 31; + } + return super.javaSlotToBedrock(slot); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java index 8c5b2cf20e9..a467e2186d8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/DoubleChestInventoryTranslator.java @@ -26,28 +26,23 @@ package org.geysermc.connector.network.translators.inventory; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.tag.CompoundTag; -import com.nukkitx.protocol.bedrock.data.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; -import org.geysermc.connector.network.translators.inventory.updater.ChestInventoryUpdater; -import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; -public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { +public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { private final int blockId; - private final InventoryUpdater updater; public DoubleChestInventoryTranslator(int size) { - super(size); - BlockState javaBlockState = BlockTranslator.getJavaBlockState("minecraft:chest[facing=north,type=single,waterlogged=false]"); + super(size, 54); + int javaBlockState = BlockTranslator.getJavaBlockState("minecraft:chest[facing=north,type=single,waterlogged=false]"); this.blockId = BlockTranslator.getBedrockBlockId(javaBlockState); - this.updater = new ChestInventoryUpdater(54); } @Override @@ -101,8 +96,8 @@ public void prepareInventory(GeyserSession session, Inventory inventory) { @Override public void openInventory(GeyserSession session, Inventory inventory) { ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket(); - containerOpenPacket.setWindowId((byte) inventory.getId()); - containerOpenPacket.setType((byte) ContainerType.CONTAINER.id()); + containerOpenPacket.setId((byte) inventory.getId()); + containerOpenPacket.setType(ContainerType.CONTAINER); containerOpenPacket.setBlockPosition(inventory.getHolderPosition()); containerOpenPacket.setUniqueEntityId(inventory.getHolderId()); session.sendUpstreamPacket(containerOpenPacket); @@ -112,7 +107,7 @@ public void openInventory(GeyserSession session, Inventory inventory) { public void closeInventory(GeyserSession session, Inventory inventory) { Vector3i holderPos = inventory.getHolderPosition(); Position pos = new Position(holderPos.getX(), holderPos.getY(), holderPos.getZ()); - BlockState realBlock = session.getConnector().getWorldManager().getBlockAt(session, pos.getX(), pos.getY(), pos.getZ()); + int realBlock = session.getConnector().getWorldManager().getBlockAt(session, pos.getX(), pos.getY(), pos.getZ()); UpdateBlockPacket blockPacket = new UpdateBlockPacket(); blockPacket.setDataLayer(0); blockPacket.setBlockPosition(holderPos); @@ -128,14 +123,4 @@ public void closeInventory(GeyserSession session, Inventory inventory) { blockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(realBlock)); session.sendUpstreamPacket(blockPacket); } - - @Override - public void updateInventory(GeyserSession session, Inventory inventory) { - updater.updateInventory(this, session, inventory); - } - - @Override - public void updateSlot(GeyserSession session, Inventory inventory, int slot) { - updater.updateSlot(this, session, inventory, slot); - } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/EnchantmentInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/EnchantmentInventoryTranslator.java index ba7f8cc7a7e..c8e9ed18690 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/EnchantmentInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/EnchantmentInventoryTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.connector.network.translators.inventory; -import com.nukkitx.protocol.bedrock.data.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.updater.ContainerInventoryUpdater; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java index 5c6de0e8a5d..1f148e02402 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/FurnaceInventoryTranslator.java @@ -26,7 +26,7 @@ package org.geysermc.connector.network.translators.inventory; import com.github.steveice10.mc.protocol.data.game.window.WindowType; -import com.nukkitx.protocol.bedrock.data.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.packet.ContainerSetDataPacket; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/GrindstoneInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/GrindstoneInventoryTranslator.java index 174cfbc1180..4b4a12465e1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/GrindstoneInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/GrindstoneInventoryTranslator.java @@ -25,8 +25,9 @@ package org.geysermc.connector.network.translators.inventory; -import com.nukkitx.protocol.bedrock.data.ContainerType; -import com.nukkitx.protocol.bedrock.data.InventoryActionData; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; import org.geysermc.connector.network.translators.inventory.updater.CursorInventoryUpdater; public class GrindstoneInventoryTranslator extends BlockInventoryTranslator { @@ -38,7 +39,7 @@ public GrindstoneInventoryTranslator() { @Override public int bedrockSlotToJava(InventoryActionData action) { final int slot = super.bedrockSlotToJava(action); - if (action.getSource().getContainerId() == 124) { + if (action.getSource().getContainerId() == ContainerId.UI) { switch (slot) { case 16: return 0; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java index 7b4b26e6258..7d06aed1404 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/InventoryTranslator.java @@ -26,8 +26,8 @@ package org.geysermc.connector.network.translators.inventory; import com.github.steveice10.mc.protocol.data.game.window.WindowType; -import com.nukkitx.protocol.bedrock.data.ContainerType; -import com.nukkitx.protocol.bedrock.data.InventoryActionData; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; import lombok.AllArgsConstructor; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; @@ -54,6 +54,8 @@ public abstract class InventoryTranslator { put(WindowType.ANVIL, new AnvilInventoryTranslator()); put(WindowType.CRAFTING, new CraftingInventoryTranslator()); put(WindowType.GRINDSTONE, new GrindstoneInventoryTranslator()); + put(WindowType.MERCHANT, new MerchantInventoryTranslator()); + put(WindowType.SMITHING, new SmithingInventoryTranslator()); //put(WindowType.ENCHANTMENT, new EnchantmentInventoryTranslator()); //TODO InventoryTranslator furnace = new FurnaceInventoryTranslator(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java new file mode 100644 index 00000000000..37c84e28a7f --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/MerchantInventoryTranslator.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019-2020 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.connector.network.translators.inventory; + +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; +import com.nukkitx.protocol.bedrock.data.inventory.InventorySource; +import org.geysermc.connector.inventory.Inventory; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.inventory.updater.CursorInventoryUpdater; +import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; + +import java.util.List; + +public class MerchantInventoryTranslator extends BaseInventoryTranslator { + + private final InventoryUpdater updater; + + public MerchantInventoryTranslator() { + super(3); + this.updater = new CursorInventoryUpdater(); + } + + @Override + public int javaSlotToBedrock(int slot) { + switch (slot) { + case 0: + return 4; + case 1: + return 5; + case 2: + return 50; + } + return super.javaSlotToBedrock(slot); + } + + @Override + public int bedrockSlotToJava(InventoryActionData action) { + if (action.getSource().getContainerId() == ContainerId.UI) { + switch (action.getSlot()) { + case 4: + return 0; + case 5: + return 1; + case 50: + return 2; + } + } + return super.bedrockSlotToJava(action); + } + + @Override + public SlotType getSlotType(int javaSlot) { + if (javaSlot == 2) { + return SlotType.OUTPUT; + } + return SlotType.NORMAL; + } + + @Override + public void prepareInventory(GeyserSession session, Inventory inventory) { + + } + + @Override + public void openInventory(GeyserSession session, Inventory inventory) { + + } + + @Override + public void closeInventory(GeyserSession session, Inventory inventory) { + session.setLastInteractedVillagerEid(-1); + session.setVillagerTrades(null); + } + + @Override + public void updateInventory(GeyserSession session, Inventory inventory) { + updater.updateInventory(this, session, inventory); + } + + @Override + public void updateSlot(GeyserSession session, Inventory inventory, int slot) { + updater.updateSlot(this, session, inventory, slot); + } + + @Override + public void translateActions(GeyserSession session, Inventory inventory, List actions) { + for (InventoryActionData action : actions) { + if (action.getSource().getType() == InventorySource.Type.NON_IMPLEMENTED_TODO) { + return; + } + } + + super.translateActions(session, inventory, actions); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java index 055b69efd63..41489ac2afc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java @@ -28,10 +28,10 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientCreativeInventoryActionPacket; -import com.nukkitx.protocol.bedrock.data.ContainerId; -import com.nukkitx.protocol.bedrock.data.InventoryActionData; -import com.nukkitx.protocol.bedrock.data.InventorySource; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; +import com.nukkitx.protocol.bedrock.data.inventory.InventorySource; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.connector.inventory.Inventory; @@ -59,11 +59,11 @@ public void updateInventory(GeyserSession session, Inventory inventory) { ItemData[] contents = new ItemData[36]; // Inventory for (int i = 9; i < 36; i++) { - contents[i] = ItemTranslator.translateToBedrock(inventory.getItem(i)); + contents[i] = ItemTranslator.translateToBedrock(session, inventory.getItem(i)); } // Hotbar for (int i = 36; i < 45; i++) { - contents[i - 36] = ItemTranslator.translateToBedrock(inventory.getItem(i)); + contents[i - 36] = ItemTranslator.translateToBedrock(session, inventory.getItem(i)); } inventoryContentPacket.setContents(contents); session.sendUpstreamPacket(inventoryContentPacket); @@ -73,7 +73,7 @@ public void updateInventory(GeyserSession session, Inventory inventory) { armorContentPacket.setContainerId(ContainerId.ARMOR); contents = new ItemData[4]; for (int i = 5; i < 9; i++) { - contents[i - 5] = ItemTranslator.translateToBedrock(inventory.getItem(i)); + contents[i - 5] = ItemTranslator.translateToBedrock(session, inventory.getItem(i)); } armorContentPacket.setContents(contents); session.sendUpstreamPacket(armorContentPacket); @@ -81,7 +81,7 @@ public void updateInventory(GeyserSession session, Inventory inventory) { // Offhand InventoryContentPacket offhandPacket = new InventoryContentPacket(); offhandPacket.setContainerId(ContainerId.OFFHAND); - offhandPacket.setContents(new ItemData[]{ItemTranslator.translateToBedrock(inventory.getItem(45))}); + offhandPacket.setContents(new ItemData[]{ItemTranslator.translateToBedrock(session, inventory.getItem(45))}); session.sendUpstreamPacket(offhandPacket); } @@ -94,13 +94,13 @@ public static void updateCraftingGrid(GeyserSession session, Inventory inventory // Crafting grid for (int i = 1; i < 5; i++) { InventorySlotPacket slotPacket = new InventorySlotPacket(); - slotPacket.setContainerId(ContainerId.CURSOR); + slotPacket.setContainerId(ContainerId.UI); slotPacket.setSlot(i + 27); if (session.getGameMode() == GameMode.CREATIVE) { slotPacket.setItem(UNUSUABLE_CRAFTING_SPACE_BLOCK); }else{ - slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(i))); + slotPacket.setItem(ItemTranslator.translateToBedrock(session, inventory.getItem(i))); } session.sendUpstreamPacket(slotPacket); @@ -122,15 +122,15 @@ public void updateSlot(GeyserSession session, Inventory inventory, int slot) { slotPacket.setContainerId(ContainerId.ARMOR); slotPacket.setSlot(slot - 5); } else { - slotPacket.setContainerId(ContainerId.CURSOR); + slotPacket.setContainerId(ContainerId.UI); slotPacket.setSlot(slot + 27); } - slotPacket.setItem(ItemTranslator.translateToBedrock(inventory.getItem(slot))); + slotPacket.setItem(ItemTranslator.translateToBedrock(session, inventory.getItem(slot))); session.sendUpstreamPacket(slotPacket); } else if (slot == 45) { InventoryContentPacket offhandPacket = new InventoryContentPacket(); offhandPacket.setContainerId(ContainerId.OFFHAND); - offhandPacket.setContents(new ItemData[]{ItemTranslator.translateToBedrock(inventory.getItem(slot))}); + offhandPacket.setContents(new ItemData[]{ItemTranslator.translateToBedrock(session, inventory.getItem(slot))}); session.sendUpstreamPacket(offhandPacket); } } @@ -156,13 +156,13 @@ public int bedrockSlotToJava(InventoryActionData action) { break; case ContainerId.OFFHAND: return 45; - case ContainerId.CURSOR: + case ContainerId.UI: if (slotnum >= 28 && 31 >= slotnum) { return slotnum - 27; - } else if (slotnum == 50) { - return 0; } break; + case ContainerId.CRAFTING_RESULT: + return 0; } return slotnum; } @@ -184,7 +184,7 @@ public void translateActions(GeyserSession session, Inventory inventory, List= 28 && 31 >= action.getSlot())) { + if (action.getSource().getContainerId() == ContainerId.UI && (action.getSlot() >= 28 && 31 >= action.getSlot())) { updateInventory(session, inventory); InventoryUtils.updateCursor(session); return; @@ -207,7 +207,7 @@ public void translateActions(GeyserSession session, Inventory inventory, List slotBlacklist) { + private static int findTempSlot(Inventory inventory, ItemStack item, List slotBlacklist, boolean emptyOnly) { /*try and find a slot that can temporarily store the given item only look in the main inventory and hotbar only slots that are empty or contain a different type of item are valid*/ @@ -314,6 +319,9 @@ private static int findTempSlot(Inventory inventory, ItemStack item, List paramsTranslated = MessageUtils.getTranslationParams(((TranslationMessage) packet.getMessage()).getTranslationParams(), locale); + List paramsTranslated = MessageUtils.getTranslationParams(((TranslationMessage) packet.getMessage()).getWith(), locale, packet.getMessage()); textPacket.setParameters(paramsTranslated); - textPacket.setMessage(MessageUtils.insertParams(MessageUtils.getTranslatedBedrockMessage(packet.getMessage(), locale, true), paramsTranslated)); + textPacket.setMessage(MessageUtils.insertParams(MessageUtils.getTranslatedBedrockMessage(packet.getMessage(), locale, true, packet.getMessage()), paramsTranslated)); } else { textPacket.setNeedsTranslation(false); - textPacket.setMessage(MessageUtils.getTranslatedBedrockMessage(packet.getMessage(), locale, false)); + textPacket.setMessage(MessageUtils.getTranslatedBedrockMessage(packet.getMessage(), locale, false, packet.getMessage())); } session.sendUpstreamPacket(textPacket); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java index 053630d53f3..8f52433665f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareCommandsTranslator.java @@ -28,9 +28,10 @@ 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.packet.ingame.server.ServerDeclareCommandsPacket; -import com.nukkitx.protocol.bedrock.data.CommandData; -import com.nukkitx.protocol.bedrock.data.CommandEnumData; -import com.nukkitx.protocol.bedrock.data.CommandParamData; +import com.nukkitx.protocol.bedrock.data.command.CommandData; +import com.nukkitx.protocol.bedrock.data.command.CommandEnumData; +import com.nukkitx.protocol.bedrock.data.command.CommandParamData; +import com.nukkitx.protocol.bedrock.data.command.CommandParamType; import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -40,7 +41,10 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; @Translator(packet = ServerDeclareCommandsPacket.class) public class JavaDeclareCommandsTranslator extends PacketTranslator { @@ -151,41 +155,41 @@ private CommandParamData[][] getParams(CommandNode commandNode, CommandNode[] al * * @return Bedrock parameter data type */ - private CommandParamData.Type mapCommandType(CommandParser parser) { - if (parser == null) { return CommandParamData.Type.STRING; } + private CommandParamType mapCommandType(CommandParser parser) { + if (parser == null) { return CommandParamType.STRING; } switch (parser) { case FLOAT: - return CommandParamData.Type.FLOAT; + return CommandParamType.FLOAT; case INTEGER: - return CommandParamData.Type.INT; + return CommandParamType.INT; case ENTITY: case GAME_PROFILE: - return CommandParamData.Type.TARGET; + return CommandParamType.TARGET; case BLOCK_POS: - return CommandParamData.Type.BLOCK_POSITION; + return CommandParamType.BLOCK_POSITION; case COLUMN_POS: case VEC3: - return CommandParamData.Type.POSITION; + return CommandParamType.POSITION; case MESSAGE: - return CommandParamData.Type.MESSAGE; + return CommandParamType.MESSAGE; case NBT: case NBT_COMPOUND_TAG: case NBT_TAG: case NBT_PATH: - return CommandParamData.Type.JSON; + return CommandParamType.JSON; case RESOURCE_LOCATION: - return CommandParamData.Type.FILE_PATH; + return CommandParamType.FILE_PATH; case INT_RANGE: - return CommandParamData.Type.INT_RANGE; + return CommandParamType.INT_RANGE; case BOOL: case DOUBLE: @@ -217,7 +221,7 @@ private CommandParamData.Type mapCommandType(CommandParser parser) { case DIMENSION: case TIME: default: - return CommandParamData.Type.STRING; + return CommandParamType.STRING; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java index 7763a2c1dd1..15f0e496e7b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaDeclareRecipesTranslator.java @@ -31,9 +31,9 @@ import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareRecipesPacket; import com.nukkitx.nbt.tag.CompoundTag; -import com.nukkitx.protocol.bedrock.data.CraftingData; -import com.nukkitx.protocol.bedrock.data.ItemData; -import com.nukkitx.protocol.bedrock.data.PotionMixData; +import com.nukkitx.protocol.bedrock.data.inventory.CraftingData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.PotionMixData; import com.nukkitx.protocol.bedrock.packet.CraftingDataPacket; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; @@ -53,7 +53,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator { private static final Collection POTION_MIXES = Arrays.stream(new int[]{372, 331, 348, 376, 289, 437, 353, 414, 382, 375, 462, 378, 396, 377, 370, 469, 470}) - .mapToObj(ingredient -> new PotionMixData(0, ingredient, 0)) + .mapToObj(ingredient -> new PotionMixData(0, ingredient, 0, 0, 0, 0)) //TODO: Confirm this is correct behavior. .collect(Collectors.toList()); @Override @@ -64,7 +64,7 @@ public void translate(ServerDeclareRecipesPacket packet, GeyserSession session) switch (recipe.getType()) { case CRAFTING_SHAPELESS: { ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData(); - ItemData output = ItemTranslator.translateToBedrock(shapelessRecipeData.getResult()); + ItemData output = ItemTranslator.translateToBedrock(session, shapelessRecipeData.getResult()); output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); //strip NBT ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients()); for (ItemData[] inputs : inputCombinations) { @@ -76,7 +76,7 @@ public void translate(ServerDeclareRecipesPacket packet, GeyserSession session) } case CRAFTING_SHAPED: { ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData(); - ItemData output = ItemTranslator.translateToBedrock(shapedRecipeData.getResult()); + ItemData output = ItemTranslator.translateToBedrock(session, shapedRecipeData.getResult()); output = ItemData.of(output.getId(), output.getDamage(), output.getCount()); //strip NBT ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients()); for (ItemData[] inputs : inputCombinations) { @@ -103,7 +103,7 @@ private ItemData[][] combinations(GeyserSession session, Ingredient[] ingredient } Ingredient ingredient = ingredients[i]; Map> groupedByIds = Arrays.stream(ingredient.getOptions()) - .map(ItemTranslator::translateToBedrock) + .map(item -> ItemTranslator.translateToBedrock(session, item)) .collect(Collectors.groupingBy(item -> new GroupedItem(item.getId(), item.getCount(), item.getTag()))); Set optionSet = new HashSet<>(groupedByIds.size()); for (Map.Entry> entry : groupedByIds.entrySet()) { @@ -119,7 +119,7 @@ private ItemData[][] combinations(GeyserSession session, Ingredient[] ingredient if (entry.getValue().size() < idCount) { optionSet.addAll(entry.getValue()); } else { - optionSet.add(ItemData.of(groupedItem.id, (short) -1, groupedItem.count, groupedItem.tag)); + optionSet.add(ItemData.of(groupedItem.id, Short.MAX_VALUE, groupedItem.count, groupedItem.tag)); } } else { ItemData item = entry.getValue().get(0); @@ -136,7 +136,7 @@ private ItemData[][] combinations(GeyserSession session, Ingredient[] ingredient ItemData[] translatedItems = new ItemData[ingredients.length]; for (int i = 0; i < ingredients.length; i++) { if (ingredients[i].getOptions().length > 0) { - translatedItems[i] = ItemTranslator.translateToBedrock(ingredients[i].getOptions()[0]); + translatedItems[i] = ItemTranslator.translateToBedrock(session, ingredients[i].getOptions()[0]); } else { translatedItems[i] = ItemData.AIR; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java index 8d8c0affbbd..9b44cdd372f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java @@ -80,7 +80,7 @@ public void translate(ServerJoinGamePacket packet, GeyserSession session) { ClientSettingsPacket clientSettingsPacket = new ClientSettingsPacket(locale, (byte) session.getRenderDistance(), ChatVisibility.FULL, true, skinParts, Hand.MAIN_HAND); session.sendDownstreamPacket(clientSettingsPacket); - if (DimensionUtils.javaToBedrock(packet.getDimension()) != entity.getDimension()) { + if (!packet.getDimension().equals(entity.getDimension())) { DimensionUtils.switchDimension(session, packet.getDimension()); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java index 086291db72c..288389fa646 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaRespawnTranslator.java @@ -61,16 +61,16 @@ public void translate(ServerRespawnPacket packet, GeyserSession session) { session.setGameMode(packet.getGamemode()); LevelEventPacket stopRainPacket = new LevelEventPacket(); - stopRainPacket.setType(LevelEventType.STOP_RAIN); + stopRainPacket.setType(LevelEventType.STOP_RAINING); stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000); stopRainPacket.setPosition(Vector3f.ZERO); session.sendUpstreamPacket(stopRainPacket); - if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) { + if (!entity.getDimension().equals(packet.getDimension())) { DimensionUtils.switchDimension(session, packet.getDimension()); } else { if (session.isManyDimPackets()) { //reloading world - int fakeDim = entity.getDimension() == 0 ? -1 : 0; + String fakeDim = entity.getDimension().equals(DimensionUtils.OVERWORLD) ? DimensionUtils.NETHER : DimensionUtils.OVERWORLD; DimensionUtils.switchDimension(session, fakeDim); DimensionUtils.switchDimension(session, packet.getDimension()); } else { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTitleTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTitleTranslator.java index 8ecf4e30fd5..214413ab7a1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTitleTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTitleTranslator.java @@ -42,20 +42,20 @@ public void translate(ServerTitlePacket packet, GeyserSession session) { switch (packet.getAction()) { case TITLE: - titlePacket.setType(SetTitlePacket.Type.SET_TITLE); + titlePacket.setType(SetTitlePacket.Type.TITLE); titlePacket.setText(MessageUtils.getBedrockMessage(packet.getTitle())); break; case SUBTITLE: - titlePacket.setType(SetTitlePacket.Type.SET_SUBTITLE); + titlePacket.setType(SetTitlePacket.Type.SUBTITLE); titlePacket.setText(MessageUtils.getBedrockMessage(packet.getTitle())); break; case CLEAR: case RESET: - titlePacket.setType(SetTitlePacket.Type.RESET_TITLE); + titlePacket.setType(SetTitlePacket.Type.CLEAR); titlePacket.setText(""); break; case ACTION_BAR: - titlePacket.setType(SetTitlePacket.Type.SET_ACTIONBAR_MESSAGE); + titlePacket.setType(SetTitlePacket.Type.ACTIONBAR); titlePacket.setText(MessageUtils.getBedrockMessage(packet.getTitle())); break; case TIMES: diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java index 6e53df27c33..2ab499b003c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityAttachTranslator.java @@ -27,9 +27,9 @@ package org.geysermc.connector.network.translators.java.entity; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityAttachPacket; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityEventType; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; @@ -63,7 +63,7 @@ public void translate(ServerEntityAttachPacket packet, GeyserSession session) { if ((attachedToId == null || packet.getAttachedToId() == 0)) { // Is not being leashed holderId.getMetadata().getFlags().setFlag(EntityFlag.LEASHED, false); - holderId.getMetadata().put(EntityData.LEAD_HOLDER_EID, 0); + holderId.getMetadata().put(EntityData.LEASH_HOLDER_EID, 0); holderId.updateBedrockMetadata(session); EntityEventPacket eventPacket = new EntityEventPacket(); eventPacket.setRuntimeEntityId(holderId.getGeyserId()); @@ -75,7 +75,7 @@ public void translate(ServerEntityAttachPacket packet, GeyserSession session) { } holderId.getMetadata().getFlags().setFlag(EntityFlag.LEASHED, true); - holderId.getMetadata().put(EntityData.LEAD_HOLDER_EID, attachedToId.getGeyserId()); + holderId.getMetadata().put(EntityData.LEASH_HOLDER_EID, attachedToId.getGeyserId()); holderId.updateBedrockMetadata(session); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java index e977e9b0c7f..96d4c836687 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityEquipmentTranslator.java @@ -25,14 +25,14 @@ package org.geysermc.connector.network.translators.java.entity; +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Equipment; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityEquipmentPacket; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.LivingEntity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; - -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityEquipmentPacket; -import com.nukkitx.protocol.bedrock.data.ItemData; import org.geysermc.connector.network.translators.item.ItemTranslator; @Translator(packet = ServerEntityEquipmentPacket.class) @@ -55,28 +55,29 @@ public void translate(ServerEntityEquipmentPacket packet, GeyserSession session) } LivingEntity livingEntity = (LivingEntity) entity; - ItemData item = ItemTranslator.translateToBedrock(packet.getItem()); - switch (packet.getSlot()) { - case HELMET: - livingEntity.setHelmet(item); - break; - case CHESTPLATE: - livingEntity.setChestplate(item); - break; - case LEGGINGS: - livingEntity.setLeggings(item); - break; - case BOOTS: - livingEntity.setBoots(item); - break; - case MAIN_HAND: - livingEntity.setHand(item); - break; - case OFF_HAND: - livingEntity.setOffHand(item); - break; + for (Equipment equipment : packet.getEquipment()) { + ItemData item = ItemTranslator.translateToBedrock(session, equipment.getItem()); + switch (equipment.getSlot()) { + case HELMET: + livingEntity.setHelmet(item); + break; + case CHESTPLATE: + livingEntity.setChestplate(item); + break; + case LEGGINGS: + livingEntity.setLeggings(item); + break; + case BOOTS: + livingEntity.setBoots(item); + break; + case MAIN_HAND: + livingEntity.setHand(item); + break; + case OFF_HAND: + livingEntity.setOffHand(item); + break; + } } - livingEntity.updateEquipment(session); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityHeadLookTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityHeadLookTranslator.java index e26a5880fe8..115cae55e4b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityHeadLookTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityHeadLookTranslator.java @@ -25,17 +25,12 @@ package org.geysermc.connector.network.translators.java.entity; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityHeadLookPacket; import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityHeadLookPacket; -import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket; -import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; - @Translator(packet = ServerEntityHeadLookPacket.class) public class JavaEntityHeadLookTranslator extends PacketTranslator { @@ -48,21 +43,6 @@ public void translate(ServerEntityHeadLookPacket packet, GeyserSession session) if (entity == null) return; - entity.setRotation(Vector3f.from(entity.getRotation().getX(), entity.getRotation().getY(), packet.getHeadYaw())); - - if (entity.getEntityType() != EntityType.PLAYER && entity.getEntityType() != EntityType.PAINTING) { - MoveEntityAbsolutePacket moveEntityAbsolutePacket = new MoveEntityAbsolutePacket(); - moveEntityAbsolutePacket.setRuntimeEntityId(entity.getGeyserId()); - moveEntityAbsolutePacket.setPosition(entity.getPosition()); - moveEntityAbsolutePacket.setRotation(entity.getBedrockRotation()); - session.sendUpstreamPacket(moveEntityAbsolutePacket); - } else { - MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); - movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); - movePlayerPacket.setPosition(entity.getPosition()); - movePlayerPacket.setRotation(entity.getBedrockRotation()); - movePlayerPacket.setMode(MovePlayerPacket.Mode.ROTATION); - session.sendUpstreamPacket(movePlayerPacket); - } + entity.updateHeadLookRotation(session, packet.getHeadYaw()); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPositionRotationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPositionRotationTranslator.java index 477c8f261ea..c4bb799e652 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPositionRotationTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPositionRotationTranslator.java @@ -25,14 +25,12 @@ package org.geysermc.connector.network.translators.java.entity; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket; import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket; - @Translator(packet = ServerEntityPositionRotationPacket.class) public class JavaEntityPositionRotationTranslator extends PacketTranslator { @@ -43,10 +41,7 @@ public void translate(ServerEntityPositionRotationPacket packet, GeyserSession s entity = session.getPlayerEntity(); } if (entity == null) return; - if (entity.getEntityType() == EntityType.BOAT) { - entity.moveRelative(session, packet.getMoveX(), packet.getMoveY(), packet.getMoveZ(), packet.getYaw() - 90, packet.getPitch(), packet.isOnGround()); - } else { - entity.moveRelative(session, packet.getMoveX(), packet.getMoveY(), packet.getMoveZ(), packet.getYaw(), packet.getPitch(), packet.isOnGround()); - } + + entity.updatePositionAndRotation(session, packet.getMoveX(), packet.getMoveY(), packet.getMoveZ(), packet.getYaw(), packet.getPitch(), packet.isOnGround()); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java index d08bb1afbaa..744b11e9644 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityPropertiesTranslator.java @@ -25,6 +25,8 @@ package org.geysermc.connector.network.translators.java.entity; +import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPropertiesPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.network.session.GeyserSession; @@ -32,17 +34,16 @@ import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.AttributeUtils; -import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPropertiesPacket; - @Translator(packet = ServerEntityPropertiesPacket.class) public class JavaEntityPropertiesTranslator extends PacketTranslator { @Override public void translate(ServerEntityPropertiesPacket packet, GeyserSession session) { + boolean isSessionPlayer = false; Entity entity = session.getEntityCache().getEntityByJavaId(packet.getEntityId()); if (packet.getEntityId() == session.getPlayerEntity().getEntityId()) { entity = session.getPlayerEntity(); + isSessionPlayer = true; } if (entity == null) return; @@ -54,6 +55,13 @@ public void translate(ServerEntityPropertiesPacket packet, GeyserSession session case GENERIC_ATTACK_DAMAGE: entity.getAttributes().put(AttributeType.ATTACK_DAMAGE, AttributeType.ATTACK_DAMAGE.getAttribute((float) AttributeUtils.calculateValue(attribute))); break; + case GENERIC_ATTACK_SPEED: + if (isSessionPlayer) { + // Get attack speed value for use in sending the faux cooldown + double attackSpeed = AttributeUtils.calculateValue(attribute); + session.setAttackSpeed(attackSpeed); + } + break; case GENERIC_FLYING_SPEED: entity.getAttributes().put(AttributeType.FLYING_SPEED, AttributeType.FLYING_SPEED.getAttribute((float) AttributeUtils.calculateValue(attribute))); entity.getAttributes().put(AttributeType.MOVEMENT_SPEED, AttributeType.MOVEMENT_SPEED.getAttribute((float) AttributeUtils.calculateValue(attribute))); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityRotationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityRotationTranslator.java index fbeb1969253..c1d3e57879b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityRotationTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityRotationTranslator.java @@ -25,17 +25,12 @@ package org.geysermc.connector.network.translators.java.entity; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityRotationPacket; import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityRotationPacket; -import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket; -import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; - @Translator(packet = ServerEntityRotationPacket.class) public class JavaEntityRotationTranslator extends PacketTranslator { @@ -47,23 +42,6 @@ public void translate(ServerEntityRotationPacket packet, GeyserSession session) } if (entity == null) return; - // entity.moveRelative(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ(), packet.getYaw(), packet.getPitch()); - entity.setRotation(Vector3f.from(packet.getYaw(), packet.getPitch(), packet.getYaw())); - - if (entity.getEntityType() != EntityType.PLAYER) { - MoveEntityAbsolutePacket moveEntityAbsolutePacket = new MoveEntityAbsolutePacket(); - moveEntityAbsolutePacket.setRuntimeEntityId(entity.getGeyserId()); - moveEntityAbsolutePacket.setPosition(entity.getPosition()); - moveEntityAbsolutePacket.setRotation(entity.getBedrockRotation()); - session.sendUpstreamPacket(moveEntityAbsolutePacket); - } else { - MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); - movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); - movePlayerPacket.setPosition(entity.getPosition()); - movePlayerPacket.setRotation(entity.getBedrockRotation()); - movePlayerPacket.setOnGround(packet.isOnGround()); - movePlayerPacket.setMode(MovePlayerPacket.Mode.ROTATION); - session.sendUpstreamPacket(movePlayerPacket); - } + entity.updateRotation(session, packet.getYaw(), packet.getPitch(), packet.isOnGround()); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java index 912ee832528..8eab10f5a13 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java @@ -27,9 +27,9 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntitySetPassengersPacket; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityData; -import com.nukkitx.protocol.bedrock.data.EntityFlag; -import com.nukkitx.protocol.bedrock.data.EntityLink; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData; import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import org.geysermc.connector.entity.Entity; @@ -64,9 +64,9 @@ public void translate(ServerEntitySetPassengersPacket packet, GeyserSession sess continue; } - EntityLink.Type type = rider ? EntityLink.Type.RIDER : EntityLink.Type.PASSENGER; + EntityLinkData.Type type = rider ? EntityLinkData.Type.RIDER : EntityLinkData.Type.PASSENGER; SetEntityLinkPacket linkPacket = new SetEntityLinkPacket(); - linkPacket.setEntityLink(new EntityLink(entity.getGeyserId(), passenger.getGeyserId(), type, false)); + linkPacket.setEntityLink(new EntityLinkData(entity.getGeyserId(), passenger.getGeyserId(), type, false)); session.sendUpstreamPacket(linkPacket); passengers.add(passengerId); @@ -95,7 +95,7 @@ public void translate(ServerEntitySetPassengersPacket packet, GeyserSession sess } if (Arrays.stream(packet.getPassengerIds()).noneMatch(id -> id == passengerId)) { SetEntityLinkPacket linkPacket = new SetEntityLinkPacket(); - linkPacket.setEntityLink(new EntityLink(entity.getGeyserId(), passenger.getGeyserId(), EntityLink.Type.REMOVE, false)); + linkPacket.setEntityLink(new EntityLinkData(entity.getGeyserId(), passenger.getGeyserId(), EntityLinkData.Type.REMOVE, false)); session.sendUpstreamPacket(linkPacket); passengers.remove(passenger.getEntityId()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java index b8675dbfec7..98089ff277d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityStatusTranslator.java @@ -25,15 +25,14 @@ package org.geysermc.connector.network.translators.java.entity; +import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket; +import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; +import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; -import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket; -import com.nukkitx.protocol.bedrock.data.EntityEventType; -import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; - @Translator(packet = ServerEntityStatusPacket.class) public class JavaEntityStatusTranslator extends PacketTranslator { @@ -53,25 +52,25 @@ public void translate(ServerEntityStatusPacket packet, GeyserSession session) { entityEventPacket.setData(9); case LIVING_HURT: case LIVING_HURT_SWEET_BERRY_BUSH: - entityEventPacket.setType(EntityEventType.HURT_ANIMATION); + entityEventPacket.setType(EntityEventType.HURT); break; case LIVING_DEATH: - entityEventPacket.setType(EntityEventType.DEATH_ANIMATION); + entityEventPacket.setType(EntityEventType.DEATH); break; case WOLF_SHAKE_WATER: - entityEventPacket.setType(EntityEventType.SHAKE_WET); + entityEventPacket.setType(EntityEventType.SHAKE_WETNESS); break; case PLAYER_FINISH_USING_ITEM: entityEventPacket.setType(EntityEventType.USE_ITEM); break; case FISHING_HOOK_PULL_PLAYER: - entityEventPacket.setType(EntityEventType.FISH_HOOK_LURED); + entityEventPacket.setType(EntityEventType.FISH_HOOK_TEASE); //TODO: CHECK break; case TAMEABLE_TAMING_FAILED: - entityEventPacket.setType(EntityEventType.TAME_FAIL); + entityEventPacket.setType(EntityEventType.TAME_FAILED); break; case TAMEABLE_TAMING_SUCCEEDED: - entityEventPacket.setType(EntityEventType.TAME_SUCCESS); + entityEventPacket.setType(EntityEventType.TAME_SUCCEEDED); break; case ZOMBIE_VILLAGER_CURE: entityEventPacket.setType(EntityEventType.ZOMBIE_VILLAGER_CURE); @@ -80,22 +79,22 @@ public void translate(ServerEntityStatusPacket packet, GeyserSession session) { entityEventPacket.setType(EntityEventType.LOVE_PARTICLES); break; case FIREWORK_EXPLODE: - entityEventPacket.setType(EntityEventType.FIREWORK_PARTICLES); + entityEventPacket.setType(EntityEventType.FIREWORK_EXPLODE); break; case WITCH_EMIT_PARTICLES: - entityEventPacket.setType(EntityEventType.WITCH_SPELL_PARTICLES); + entityEventPacket.setType(EntityEventType.WITCH_HAT_MAGIC); //TODO: CHECK break; case TOTEM_OF_UNDYING_MAKE_SOUND: entityEventPacket.setType(EntityEventType.CONSUME_TOTEM); break; case SHEEP_GRAZE_OR_TNT_CART_EXPLODE: - entityEventPacket.setType(EntityEventType.MINECART_TNT_PRIME_FUSE); + entityEventPacket.setType(EntityEventType.PRIME_TNT_MINECART); break; case IRON_GOLEM_HOLD_POPPY: - entityEventPacket.setType(EntityEventType.IRON_GOLEM_OFFER_FLOWER); + entityEventPacket.setType(EntityEventType.GOLEM_FLOWER_OFFER); break; case IRON_GOLEM_EMPTY_HAND: - entityEventPacket.setType(EntityEventType.IRON_GOLEM_WITHDRAW_FLOWER); + entityEventPacket.setType(EntityEventType.GOLEM_FLOWER_WITHDRAW); break; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityTeleportTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityTeleportTranslator.java index 9a4686728ce..cf01d214dde 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityTeleportTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityTeleportTranslator.java @@ -44,6 +44,6 @@ public void translate(ServerEntityTeleportPacket packet, GeyserSession session) } if (entity == null) return; - entity.moveAbsolute(session, Vector3f.from(packet.getX(), packet.getY(), packet.getZ()), packet.getYaw(), packet.getPitch(), packet.isOnGround(), false); + entity.teleport(session, Vector3f.from(packet.getX(), packet.getY(), packet.getZ()), packet.getYaw(), packet.getPitch(), packet.isOnGround()); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java index 3014c6a5f23..e0e9842f4d3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerAbilitiesTranslator.java @@ -25,22 +25,21 @@ package org.geysermc.connector.network.translators.java.entity.player; -import java.util.Set; - -import com.nukkitx.protocol.bedrock.data.CommandPermission; -import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.PacketTranslator; -import org.geysermc.connector.network.translators.Translator; - import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerAbilitiesPacket; -import com.nukkitx.protocol.bedrock.data.EntityDataMap; -import com.nukkitx.protocol.bedrock.data.EntityFlag; +import com.nukkitx.protocol.bedrock.data.AdventureSetting; import com.nukkitx.protocol.bedrock.data.PlayerPermission; +import com.nukkitx.protocol.bedrock.data.command.CommandPermission; +import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; - import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; + +import java.util.Set; @Translator(packet = ServerPlayerAbilitiesPacket.class) public class JavaPlayerAbilitiesTranslator extends PacketTranslator { @@ -59,20 +58,20 @@ public void translate(ServerPlayerAbilitiesPacket packet, GeyserSession session) entityDataPacket.getMetadata().putAll(metadata); session.sendUpstreamPacket(entityDataPacket); - Set playerFlags = new ObjectOpenHashSet<>(); - playerFlags.add(AdventureSettingsPacket.Flag.AUTO_JUMP); + Set playerFlags = new ObjectOpenHashSet<>(); + playerFlags.add(AdventureSetting.AUTO_JUMP); if (packet.isCanFly()) - playerFlags.add(AdventureSettingsPacket.Flag.MAY_FLY); + playerFlags.add(AdventureSetting.MAY_FLY); if (packet.isFlying()) - playerFlags.add(AdventureSettingsPacket.Flag.FLYING); + playerFlags.add(AdventureSetting.FLYING); AdventureSettingsPacket adventureSettingsPacket = new AdventureSettingsPacket(); adventureSettingsPacket.setPlayerPermission(PlayerPermission.MEMBER); // Required or the packet simply is not sent adventureSettingsPacket.setCommandPermission(CommandPermission.NORMAL); adventureSettingsPacket.setUniqueEntityId(entity.getGeyserId()); - adventureSettingsPacket.getFlags().addAll(playerFlags); + adventureSettingsPacket.getSettings().addAll(playerFlags); session.sendUpstreamPacket(adventureSettingsPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java index b049d0be20a..9ed11a23df4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerActionAckTranslator.java @@ -50,13 +50,13 @@ public void translate(ServerPlayerActionAckPacket packet, GeyserSession session) LevelEventPacket levelEvent = new LevelEventPacket(); switch (packet.getAction()) { case FINISH_DIGGING: - double blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(session.getBreakingBlock() == null ? 0 : session.getBreakingBlock().getId()); + double blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(session.getBreakingBlock()); if (session.getGameMode() != GameMode.CREATIVE && blockHardness != 0) { - levelEvent.setType(LevelEventType.DESTROY); + levelEvent.setType(LevelEventType.PARTICLE_DESTROY_BLOCK); levelEvent.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ())); levelEvent.setData(BlockTranslator.getBedrockBlockId(session.getBreakingBlock())); session.sendUpstreamPacket(levelEvent); - session.setBreakingBlock(null); + session.setBreakingBlock(0); } ChunkUtils.updateBlock(session, packet.getNewState(), packet.getPosition()); break; @@ -64,7 +64,7 @@ public void translate(ServerPlayerActionAckPacket packet, GeyserSession session) if (session.getGameMode() == GameMode.CREATIVE) { break; } - blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(packet.getNewState().getId()); + blockHardness = BlockTranslator.JAVA_RUNTIME_ID_TO_HARDNESS.get(packet.getNewState()); levelEvent.setType(LevelEventType.BLOCK_START_BREAK); levelEvent.setPosition(Vector3f.from( packet.getPosition().getX(), @@ -79,7 +79,7 @@ public void translate(ServerPlayerActionAckPacket packet, GeyserSession session) itemEntry = ItemRegistry.getItem(item); nbtData = item.getNbt(); } - double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState().getId(), itemEntry, nbtData, session) * 20); + double breakTime = Math.ceil(BlockUtils.getBreakTime(blockHardness, packet.getNewState(), itemEntry, nbtData, session) * 20); levelEvent.setData((int) (65535 / breakTime)); session.setBreakingBlock(packet.getNewState()); session.sendUpstreamPacket(levelEvent); @@ -92,7 +92,7 @@ public void translate(ServerPlayerActionAckPacket packet, GeyserSession session) packet.getPosition().getZ() )); levelEvent.setData(0); - session.setBreakingBlock(null); + session.setBreakingBlock(0); session.sendUpstreamPacket(levelEvent); break; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java index a44b200e3d9..8b0b8201487 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java @@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.EntityEventType; +import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.RespawnPacket; @@ -80,7 +80,7 @@ public void translate(ServerPlayerPositionRotationPacket packet, GeyserSession s movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); movePlayerPacket.setPosition(pos); movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0)); - movePlayerPacket.setMode(MovePlayerPacket.Mode.RESET); + movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN); //TODO: PROBABLY RIGHT BUT STILL CHECK session.sendUpstreamPacket(movePlayerPacket); session.setSpawned(true); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnEntityTranslator.java index 920969a755a..742fa97e937 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnEntityTranslator.java @@ -31,10 +31,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnEntityPacket; import com.nukkitx.math.vector.Vector3f; -import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.entity.FallingBlockEntity; -import org.geysermc.connector.entity.FishingHookEntity; -import org.geysermc.connector.entity.ItemFrameEntity; +import org.geysermc.connector.entity.*; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -73,6 +70,10 @@ public void translate(ServerSpawnEntityPacket packet, GeyserSession session) { // Fishing bobbers need the owner for the line entity = new FishingHookEntity(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), type, position, motion, rotation, (ProjectileData) packet.getData()); + } else if (packet.getType() == EntityType.BOAT) { + // Initial rotation is incorrect + entity = new BoatEntity(packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), + type, position, motion, Vector3f.from(packet.getYaw(), 0, packet.getYaw())); } else { Constructor entityConstructor = entityClass.getConstructor(long.class, long.class, org.geysermc.connector.entity.type.EntityType.class, Vector3f.class, Vector3f.class, Vector3f.class); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java index 7360cbb2ea5..93cfa08e46b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaCloseWindowTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.java.window; import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerCloseWindowPacket; -import com.nukkitx.protocol.bedrock.packet.ContainerClosePacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -37,9 +36,7 @@ public class JavaCloseWindowTranslator extends PacketTranslator { @@ -52,10 +50,8 @@ public void translate(ServerOpenWindowPacket packet, GeyserSession session) { Inventory openInventory = session.getInventoryCache().getOpenInventory(); if (newTranslator == null) { if (openInventory != null) { - ContainerClosePacket closePacket = new ContainerClosePacket(); - closePacket.setWindowId((byte)openInventory.getId()); - session.sendUpstreamPacket(closePacket); - InventoryTranslator.INVENTORY_TRANSLATORS.get(openInventory.getWindowType()).closeInventory(session, openInventory); + InventoryUtils.closeWindow(session, openInventory.getId()); + InventoryUtils.closeInventory(session, openInventory.getId()); } ClientCloseWindowPacket closeWindowPacket = new ClientCloseWindowPacket(packet.getWindowId()); session.sendDownstreamPacket(closeWindowPacket); @@ -80,9 +76,8 @@ public void translate(ServerOpenWindowPacket packet, GeyserSession session) { if (openInventory != null) { InventoryTranslator openTranslator = InventoryTranslator.INVENTORY_TRANSLATORS.get(openInventory.getWindowType()); if (!openTranslator.getClass().equals(newTranslator.getClass())) { + InventoryUtils.closeWindow(session, openInventory.getId()); InventoryUtils.closeInventory(session, openInventory.getId()); - GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> InventoryUtils.openInventory(session, newInventory), 500, TimeUnit.MILLISECONDS); - return; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java index 5d44069fe3f..19d7db217e0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java @@ -41,8 +41,6 @@ public class JavaSetSlotTranslator extends PacketTranslator @Override public void translate(ServerSetSlotPacket packet, GeyserSession session) { if (packet.getWindowId() == 255 && packet.getSlot() == -1) { //cursor - if (Objects.equals(session.getInventory().getCursor(), packet.getItem())) - return; if (session.getCraftSlot() != 0) return; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java index 27bc34c986f..e267df20895 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockBreakAnimTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.java.world; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerBlockBreakAnimPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector3f; @@ -44,8 +43,8 @@ public class JavaBlockBreakAnimTranslator extends PacketTranslator= 2.0f ? LevelEventType.PARTICLE_HUGE_EXPLODE : LevelEventType.PARTICLE_LARGE_EXPLOSION); + levelEventPacket.setData(0); + levelEventPacket.setPosition(pos.toFloat()); + session.sendUpstreamPacket(levelEventPacket); + LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); levelSoundEventPacket.setRelativeVolumeDisabled(false); levelSoundEventPacket.setBabySound(false); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java index c8be3a56e77..2aee7bc0276 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaMapDataTranslator.java @@ -35,6 +35,7 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.BedrockMapIcon; +import org.geysermc.connector.utils.DimensionUtils; import org.geysermc.connector.utils.MapColor; @Translator(packet = ServerMapDataPacket.class) @@ -42,9 +43,10 @@ public class JavaMapDataTranslator extends PacketTranslator @Override public void translate(ServerMapDataPacket packet, GeyserSession session) { ClientboundMapItemDataPacket mapItemDataPacket = new ClientboundMapItemDataPacket(); + boolean shouldStore = false; mapItemDataPacket.setUniqueMapId(packet.getMapId()); - mapItemDataPacket.setDimensionId(session.getPlayerEntity().getDimension()); + mapItemDataPacket.setDimensionId(DimensionUtils.javaToBedrock(session.getPlayerEntity().getDimension())); mapItemDataPacket.setLocked(packet.isLocked()); mapItemDataPacket.setScale(packet.getScale()); @@ -55,6 +57,11 @@ public void translate(ServerMapDataPacket packet, GeyserSession session) { mapItemDataPacket.setWidth(data.getColumns()); mapItemDataPacket.setHeight(data.getRows()); + // We have a full map image, this usually only happens on spawn for the initial image + if (mapItemDataPacket.getWidth() == 128 && mapItemDataPacket.getHeight() == 128) { + shouldStore = true; + } + // Every int entry is an ABGR color int[] colors = new int[data.getData().length]; @@ -76,6 +83,12 @@ public void translate(ServerMapDataPacket packet, GeyserSession session) { id++; } - session.getUpstream().getSession().sendPacket(mapItemDataPacket); + // Store the map to send when the client requests it, as bedrock expects the data after a MapInfoRequestPacket + if (shouldStore) { + session.getStoredMaps().put(mapItemDataPacket.getUniqueMapId(), mapItemDataPacket); + } + + // Send anyway just in case + session.sendUpstreamPacket(mapItemDataPacket); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java index 781018b2f69..f4d1c75dab4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaNotifyClientTranslator.java @@ -31,7 +31,13 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.data.*; +import com.nukkitx.protocol.bedrock.data.AdventureSetting; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.data.PlayerPermission; +import com.nukkitx.protocol.bedrock.data.command.CommandPermission; +import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap; +import com.nukkitx.protocol.bedrock.data.entity.EntityEventType; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.geysermc.connector.entity.Entity; @@ -56,35 +62,35 @@ public void translate(ServerNotifyClientPacket packet, GeyserSession session) { switch (packet.getNotification()) { case START_RAIN: LevelEventPacket startRainPacket = new LevelEventPacket(); - startRainPacket.setType(LevelEventType.START_RAIN); + startRainPacket.setType(LevelEventType.START_RAINING); startRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000); startRainPacket.setPosition(Vector3f.ZERO); session.sendUpstreamPacket(startRainPacket); break; case STOP_RAIN: LevelEventPacket stopRainPacket = new LevelEventPacket(); - stopRainPacket.setType(LevelEventType.STOP_RAIN); + stopRainPacket.setType(LevelEventType.STOP_RAINING); stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000); stopRainPacket.setPosition(Vector3f.ZERO); session.sendUpstreamPacket(stopRainPacket); break; case CHANGE_GAMEMODE: - Set playerFlags = new ObjectOpenHashSet<>(); + Set playerFlags = new ObjectOpenHashSet<>(); GameMode gameMode = (GameMode) packet.getValue(); if (gameMode == GameMode.ADVENTURE) - playerFlags.add(AdventureSettingsPacket.Flag.IMMUTABLE_WORLD); + playerFlags.add(AdventureSetting.WORLD_IMMUTABLE); if (gameMode == GameMode.CREATIVE) - playerFlags.add(AdventureSettingsPacket.Flag.MAY_FLY); + playerFlags.add(AdventureSetting.MAY_FLY); if (gameMode == GameMode.SPECTATOR) { - playerFlags.add(AdventureSettingsPacket.Flag.MAY_FLY); - playerFlags.add(AdventureSettingsPacket.Flag.NO_CLIP); - playerFlags.add(AdventureSettingsPacket.Flag.FLYING); + playerFlags.add(AdventureSetting.MAY_FLY); + playerFlags.add(AdventureSetting.NO_CLIP); + playerFlags.add(AdventureSetting.FLYING); gameMode = GameMode.CREATIVE; // spectator doesnt exist on bedrock } - playerFlags.add(AdventureSettingsPacket.Flag.AUTO_JUMP); + playerFlags.add(AdventureSetting.AUTO_JUMP); SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); playerGameTypePacket.setGamemode(gameMode.ordinal()); @@ -97,7 +103,7 @@ public void translate(ServerNotifyClientPacket packet, GeyserSession session) { adventureSettingsPacket.setPlayerPermission(PlayerPermission.MEMBER); adventureSettingsPacket.setCommandPermission(CommandPermission.NORMAL); adventureSettingsPacket.setUniqueEntityId(entity.getGeyserId()); - adventureSettingsPacket.getFlags().addAll(playerFlags); + adventureSettingsPacket.getSettings().addAll(playerFlags); session.sendUpstreamPacket(adventureSettingsPacket); }, 50, TimeUnit.MILLISECONDS); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayBuiltinSoundTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayBuiltinSoundTranslator.java index f51e35fe6b7..d849c917935 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayBuiltinSoundTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayBuiltinSoundTranslator.java @@ -70,8 +70,9 @@ public void translate(ServerPlayBuiltinSoundPacket packet, GeyserSession session session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket + " was not a playable level sound, or has yet to be mapped to an enum in " + "NukkitX SoundEvent "); - + return; } + soundPacket.setSound(sound); soundPacket.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); soundPacket.setIdentifier(soundMapping.getIdentifier()); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java index da23adb5597..70c2749ddec 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java @@ -49,6 +49,7 @@ @Translator(packet = ServerPlayEffectPacket.class) public class JavaPlayEffectTranslator extends PacketTranslator { + // TODO: Update mappings since they're definitely all going to be wrong now @Override public void translate(ServerPlayEffectPacket packet, GeyserSession session) { LevelEventPacket effect = new LevelEventPacket(); @@ -63,13 +64,13 @@ public void translate(ServerPlayEffectPacket packet, GeyserSession session) { switch (particleEffect) { // TODO: BREAK_SPLASH_POTION has additional data case BONEMEAL_GROW: - effect.setType(LevelEventType.BONEMEAL); + effect.setType(LevelEventType.PARTICLE_CROP_GROWTH); BonemealGrowEffectData growEffectData = (BonemealGrowEffectData) packet.getData(); effect.setData(growEffectData.getParticleCount()); break; //TODO: Block break particles when under fire case BREAK_BLOCK: - effect.setType(LevelEventType.DESTROY); + effect.setType(LevelEventType.PARTICLE_DESTROY_BLOCK); // TODO: Check to make sure this is right BreakBlockEffectData breakBlockEffectData = (BreakBlockEffectData) packet.getData(); effect.setData(BlockTranslator.getBedrockBlockId(breakBlockEffectData.getBlockState())); break; @@ -77,7 +78,7 @@ public void translate(ServerPlayEffectPacket packet, GeyserSession session) { effect.setType(LevelEventType.PARTICLE_LARGE_EXPLOSION); break; case MOB_SPAWN: - effect.setType(LevelEventType.ENTITY_SPAWN); + effect.setType(LevelEventType.PARTICLE_MOB_BLOCK_SPAWN); // TODO: Check, but I don't think I really verified this ever went into effect on Java break; // Done with a dispenser case SMOKE: @@ -85,7 +86,7 @@ public void translate(ServerPlayEffectPacket packet, GeyserSession session) { effect.setType(LevelEventType.PARTICLE_SMOKE); break; case COMPOSTER: - effect.setType(LevelEventType.BONEMEAL); + effect.setType(LevelEventType.PARTICLE_CROP_GROWTH); ComposterEffectData composterEffectData = (ComposterEffectData) packet.getData(); LevelSoundEventPacket soundEvent = new LevelSoundEventPacket(); @@ -98,7 +99,7 @@ public void translate(ServerPlayEffectPacket packet, GeyserSession session) { session.sendUpstreamPacket(soundEvent); break; case BLOCK_LAVA_EXTINGUISH: - effect.setType(LevelEventType.SHOOT); + effect.setType(LevelEventType.PARTICLE_SHOOT); effect.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY() + 1, packet.getPosition().getZ())); session.sendUpstreamPacket(effect); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java index cc45e345696..323f57f07b1 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java @@ -27,7 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.world.particle.*; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.SpawnParticleEffectPacket; @@ -40,6 +40,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket; import com.nukkitx.math.vector.Vector3f; import org.geysermc.connector.network.translators.effect.EffectRegistry; +import org.geysermc.connector.utils.DimensionUtils; @Translator(packet = ServerSpawnParticlePacket.class) public class JavaSpawnParticleTranslator extends PacketTranslator { @@ -49,7 +50,7 @@ public void translate(ServerSpawnParticlePacket packet, GeyserSession session) { LevelEventPacket particle = new LevelEventPacket(); switch (packet.getParticle().getType()) { case BLOCK: - particle.setType(LevelEventType.DESTROY); + particle.setType(LevelEventType.PARTICLE_DESTROY_BLOCK); particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); particle.setData(BlockTranslator.getBedrockBlockId(((BlockParticleData) packet.getParticle().getData()).getBlockState())); session.sendUpstreamPacket(particle); @@ -64,7 +65,7 @@ public void translate(ServerSpawnParticlePacket packet, GeyserSession session) { break; case ITEM: ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack(); - ItemData bedrockItem = ItemTranslator.translateToBedrock(javaItem); + ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem); int id = bedrockItem.getId(); short damage = bedrockItem.getDamage(); particle.setType(LevelEventType.PARTICLE_ITEM_BREAK); @@ -93,7 +94,7 @@ public void translate(ServerSpawnParticlePacket packet, GeyserSession session) { if (stringParticle != null) { SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket(); stringPacket.setIdentifier(stringParticle); - stringPacket.setDimensionId(session.getPlayerEntity().getDimension()); + stringPacket.setDimensionId(DimensionUtils.javaToBedrock(session.getPlayerEntity().getDimension())); stringPacket.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); session.sendUpstreamPacket(stringPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java new file mode 100644 index 00000000000..7c80d104b58 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaTradeListTranslator.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2019-2020 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.connector.network.translators.java.world; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.window.VillagerTrade; +import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerTradeListPacket; +import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; +import com.nukkitx.protocol.bedrock.packet.UpdateTradePacket; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.item.ItemRegistry; +import org.geysermc.connector.network.translators.item.ItemTranslator; + +import java.util.ArrayList; +import java.util.List; + +@Translator(packet = ServerTradeListPacket.class) +public class JavaTradeListTranslator extends PacketTranslator { + + @Override + public void translate(ServerTradeListPacket packet, GeyserSession session) { + Entity villager = session.getPlayerEntity(); + session.setVillagerTrades(packet.getTrades()); + villager.getMetadata().put(EntityData.TRADE_TIER, packet.getVillagerLevel() - 1); + villager.getMetadata().put(EntityData.MAX_TRADE_TIER, 4); + villager.getMetadata().put(EntityData.TRADE_XP, packet.getExperience()); + villager.updateBedrockMetadata(session); + + UpdateTradePacket updateTradePacket = new UpdateTradePacket(); + updateTradePacket.setTradeTier(packet.getVillagerLevel() - 1); + updateTradePacket.setContainerId((short) packet.getWindowId()); //TODO: CHECK THIS AND THE ONE BELOW + updateTradePacket.setContainerType(ContainerType.TRADE); + String displayName; + Entity realVillager = session.getEntityCache().getEntityByGeyserId(session.getLastInteractedVillagerEid()); + if (realVillager != null && realVillager.getMetadata().containsKey(EntityData.NAMETAG) && realVillager.getMetadata().getString(EntityData.NAMETAG) != null) { + displayName = realVillager.getMetadata().getString(EntityData.NAMETAG); + } else { + displayName = packet.isRegularVillager() ? "Villager" : "Wandering Trader"; + } + updateTradePacket.setDisplayName(displayName); + //updateTradePacket.setUnknownInt(0); //TODO +// updateTradePacket.setScreen2(true); +// updateTradePacket.setWilling(true); + updateTradePacket.setPlayerUniqueEntityId(session.getPlayerEntity().getGeyserId()); + updateTradePacket.setTraderUniqueEntityId(session.getPlayerEntity().getGeyserId()); + CompoundTagBuilder builder = CompoundTagBuilder.builder(); + List tags = new ArrayList<>(); + for (VillagerTrade trade : packet.getTrades()) { + CompoundTagBuilder recipe = CompoundTagBuilder.builder(); + recipe.intTag("maxUses", trade.getMaxUses()); + recipe.intTag("traderExp", trade.getXp()); + recipe.floatTag("priceMultiplierA", trade.getPriceMultiplier()); + recipe.tag(getItemTag(session, trade.getOutput(), "sell", 0)); + recipe.floatTag("priceMultiplierB", 0.0f); + recipe.intTag("buyCountB", trade.getSecondInput() != null ? trade.getSecondInput().getAmount() : 0); + recipe.intTag("buyCountA", trade.getFirstInput().getAmount()); + recipe.intTag("demand", trade.getDemand()); + recipe.intTag("tier", packet.getVillagerLevel() - 1); + recipe.tag(getItemTag(session, trade.getFirstInput(), "buyA", trade.getSpecialPrice())); + if (trade.getSecondInput() != null) { + recipe.tag(getItemTag(session, trade.getSecondInput(), "buyB", 0)); + } + recipe.intTag("uses", trade.getNumUses()); + recipe.byteTag("rewardExp", (byte) 1); + tags.add(recipe.buildRootTag()); + } + + //Hidden trade to fix visual experience bug + if (packet.isRegularVillager() && packet.getVillagerLevel() < 5) { + tags.add(CompoundTagBuilder.builder() + .intTag("maxUses", 0) + .intTag("traderExp", 0) + .floatTag("priceMultiplierA", 0.0f) + .floatTag("priceMultiplierB", 0.0f) + .intTag("buyCountB", 0) + .intTag("buyCountA", 0) + .intTag("demand", 0) + .intTag("tier", 5) + .intTag("uses", 0) + .byteTag("rewardExp", (byte) 0) + .buildRootTag()); + } + + builder.listTag("Recipes", CompoundTag.class, tags); + List expTags = new ArrayList<>(); + expTags.add(CompoundTagBuilder.builder().intTag("0", 0).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("1", 10).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("2", 70).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("3", 150).buildRootTag()); + expTags.add(CompoundTagBuilder.builder().intTag("4", 250).buildRootTag()); + builder.listTag("TierExpRequirements", CompoundTag.class, expTags); + updateTradePacket.setOffers(builder.buildRootTag()); + session.sendUpstreamPacket(updateTradePacket); + } + + private CompoundTag getItemTag(GeyserSession session, ItemStack stack, String name, int specialPrice) { + ItemData itemData = ItemTranslator.translateToBedrock(session, stack); + ItemEntry itemEntry = ItemRegistry.getItem(stack); + CompoundTagBuilder builder = CompoundTagBuilder.builder(); + builder.byteTag("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1))); + builder.shortTag("Damage", itemData.getDamage()); + builder.shortTag("id", (short) itemEntry.getBedrockId()); + if (itemData.getTag() != null) { + CompoundTag tag = itemData.getTag().toBuilder().build("tag"); + builder.tag(tag); + } + return builder.build(name); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java index 362d67d0600..822be8c8939 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTileEntityTranslator.java @@ -47,7 +47,7 @@ public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session ChunkUtils.CACHED_BLOCK_ENTITIES.get(packet.getPosition())), packet.getPosition()); ChunkUtils.CACHED_BLOCK_ENTITIES.remove(packet.getPosition()); } else { - BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(id, packet.getNbt(), null), packet.getPosition()); + BlockEntityUtils.updateBlockEntity(session, translator.getBlockEntityTag(id, packet.getNbt(), 0), packet.getPosition()); } } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java index 4b74a67833a..d198e1a7a9c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java @@ -41,7 +41,7 @@ public void handleInteraction(GeyserSession session, Vector3f position, String i boolean powered = identifier.contains("mode=compare"); LevelEventPacket levelEventPacket = new LevelEventPacket(); levelEventPacket.setPosition(position); - levelEventPacket.setType(LevelEventType.REDSTONE_TRIGGER); + levelEventPacket.setType(LevelEventType.SOUND_CLICK); //TODO: New ID? levelEventPacket.setData(powered ? 500 : 550); session.sendUpstreamPacket(levelEventPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java index 39a07c3ac47..3b7416d6d9f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java @@ -39,7 +39,7 @@ public class DoorSoundInteractionHandler implements BlockSoundInteractionHandler @Override public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { LevelEventPacket levelEventPacket = new LevelEventPacket(); - levelEventPacket.setType(LevelEventType.SOUND_DOOR); + levelEventPacket.setType(LevelEventType.SOUND_DOOR_OPEN); levelEventPacket.setPosition(position); levelEventPacket.setData(0); session.sendUpstreamPacket(levelEventPacket); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java index fb39d4ac8d3..c3ed44b078c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java @@ -41,7 +41,7 @@ public void handleInteraction(GeyserSession session, Vector3f position, String i boolean powered = identifier.contains("powered=true"); LevelEventPacket levelEventPacket = new LevelEventPacket(); levelEventPacket.setPosition(position); - levelEventPacket.setType(LevelEventType.REDSTONE_TRIGGER); + levelEventPacket.setType(LevelEventType.SOUND_CLICK); levelEventPacket.setData(powered ? 600 : 500); session.sendUpstreamPacket(levelEventPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/CachedChunkManager.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/CachedChunkManager.java index 740e2df93ba..744a6c8238f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/CachedChunkManager.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/CachedChunkManager.java @@ -27,13 +27,12 @@ package org.geysermc.connector.network.translators.world; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import org.geysermc.connector.network.session.GeyserSession; public class CachedChunkManager extends WorldManager { @Override - public BlockState getBlockAt(GeyserSession session, int x, int y, int z) { + public int getBlockAt(GeyserSession session, int x, int y, int z) { return session.getChunkCache().getBlockAt(new Position(x, y, z)); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/WorldManager.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/WorldManager.java index d92d845437f..0b87591d7db 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/WorldManager.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/WorldManager.java @@ -27,8 +27,6 @@ package org.geysermc.connector.network.translators.world; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; - import com.nukkitx.math.vector.Vector3i; import org.geysermc.connector.network.session.GeyserSession; @@ -42,29 +40,29 @@ public abstract class WorldManager { /** - * Gets the {@link BlockState} at the specified location + * Gets the block state at the specified location * * @param session the session * @param position the position * @return the block state at the specified location */ - public BlockState getBlockAt(GeyserSession session, Position position) { + public int getBlockAt(GeyserSession session, Position position) { return this.getBlockAt(session, position.getX(), position.getY(), position.getZ()); } /** - * Gets the {@link BlockState} at the specified location + * Gets the block state at the specified location * * @param session the session * @param vector the position * @return the block state at the specified location */ - public BlockState getBlockAt(GeyserSession session, Vector3i vector) { + public int getBlockAt(GeyserSession session, Vector3i vector) { return this.getBlockAt(session, vector.getX(), vector.getY(), vector.getZ()); } /** - * Gets the {@link BlockState} at the specified location + * Gets the block state at the specified location * * @param session the session * @param x the x coordinate to get the block at @@ -72,5 +70,5 @@ public BlockState getBlockAt(GeyserSession session, Vector3i vector) { * @param z the z coordinate to get the block at * @return the block state at the specified location */ - public abstract BlockState getBlockAt(GeyserSession session, int x, int y, int z); + public abstract int getBlockAt(GeyserSession session, int x, int y, int z); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java index 070a0592c8a..73957cad9bf 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java @@ -26,16 +26,8 @@ package org.geysermc.connector.network.translators.world.block; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.nbt.tag.CompoundTag; -import it.unimi.dsi.fastutil.ints.Int2BooleanMap; -import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2ByteMap; -import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.*; import java.util.HashMap; import java.util.Map; @@ -45,24 +37,24 @@ */ public class BlockStateValues { - private static final Object2IntMap BANNER_COLORS = new Object2IntOpenHashMap<>(); - private static final Object2ByteMap BED_COLORS = new Object2ByteOpenHashMap<>(); + private static final Int2IntMap BANNER_COLORS = new Int2IntOpenHashMap(); + private static final Int2ByteMap BED_COLORS = new Int2ByteOpenHashMap(); private static final Int2ObjectMap DOUBLE_CHEST_VALUES = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap FLOWER_POT_VALUES = new Int2ObjectOpenHashMap<>(); private static final Map FLOWER_POT_BLOCKS = new HashMap<>(); - private static final Object2IntMap NOTEBLOCK_PITCHES = new Object2IntOpenHashMap<>(); + private static final Int2IntMap NOTEBLOCK_PITCHES = new Int2IntOpenHashMap(); private static final Int2BooleanMap IS_STICKY_PISTON = new Int2BooleanOpenHashMap(); private static final Int2BooleanMap PISTON_VALUES = new Int2BooleanOpenHashMap(); - private static final Object2ByteMap SKULL_VARIANTS = new Object2ByteOpenHashMap<>(); - private static final Object2ByteMap SKULL_ROTATIONS = new Object2ByteOpenHashMap<>(); - private static final Object2ByteMap SHULKERBOX_DIRECTIONS = new Object2ByteOpenHashMap<>(); + private static final Int2ByteMap SKULL_VARIANTS = new Int2ByteOpenHashMap(); + private static final Int2ByteMap SKULL_ROTATIONS = new Int2ByteOpenHashMap(); + private static final Int2ByteMap SHULKERBOX_DIRECTIONS = new Int2ByteOpenHashMap(); /** * Determines if the block state contains Bedrock block information * @param entry The String to JsonNode map used in BlockTranslator * @param javaBlockState the Java Block State of the block */ - public static void storeBlockStateValues(Map.Entry entry, BlockState javaBlockState) { + public static void storeBlockStateValues(Map.Entry entry, int javaBlockState) { JsonNode bannerColor = entry.getValue().get("banner_color"); if (bannerColor != null) { BANNER_COLORS.put(javaBlockState, (byte) bannerColor.intValue()); @@ -80,12 +72,12 @@ public static void storeBlockStateValues(Map.Entry entry, Bloc boolean isDirectionPositive = ((entry.getValue().get("x") != null && entry.getValue().get("x").asBoolean()) || (entry.getValue().get("z") != null && entry.getValue().get("z").asBoolean())); boolean isLeft = (entry.getValue().get("double_chest_position").asText().contains("left")); - DOUBLE_CHEST_VALUES.put(javaBlockState.getId(), new DoubleChestValue(isX, isDirectionPositive, isLeft)); + DOUBLE_CHEST_VALUES.put(javaBlockState, new DoubleChestValue(isX, isDirectionPositive, isLeft)); return; } if (entry.getKey().contains("potted_")) { - FLOWER_POT_VALUES.put(javaBlockState.getId(), entry.getKey().replace("potted_", "")); + FLOWER_POT_VALUES.put(javaBlockState, entry.getKey().replace("potted_", "")); return; } @@ -97,8 +89,8 @@ public static void storeBlockStateValues(Map.Entry entry, Bloc if (entry.getKey().contains("piston")) { // True if extended, false if not - PISTON_VALUES.put(javaBlockState.getId(), entry.getKey().contains("extended=true")); - IS_STICKY_PISTON.put(javaBlockState.getId(), entry.getKey().contains("sticky")); + PISTON_VALUES.put(javaBlockState, entry.getKey().contains("extended=true")); + IS_STICKY_PISTON.put(javaBlockState, entry.getKey().contains("sticky")); return; } @@ -125,9 +117,9 @@ public static void storeBlockStateValues(Map.Entry entry, Bloc * @param state BlockState of the block * @return Banner color integer or -1 if no color */ - public static int getBannerColor(BlockState state) { + public static int getBannerColor(int state) { if (BANNER_COLORS.containsKey(state)) { - return BANNER_COLORS.getInt(state); + return BANNER_COLORS.get(state); } return -1; } @@ -139,9 +131,9 @@ public static int getBannerColor(BlockState state) { * @param state BlockState of the block * @return Bed color byte or -1 if no color */ - public static byte getBedColor(BlockState state) { + public static byte getBedColor(int state) { if (BED_COLORS.containsKey(state)) { - return BED_COLORS.getByte(state); + return BED_COLORS.get(state); } return -1; } @@ -177,9 +169,9 @@ public static Map getFlowerPotBlocks() { * @param state BlockState of the block * @return note block note integer or -1 if not present */ - public static int getNoteblockPitch(BlockState state) { + public static int getNoteblockPitch(int state) { if (NOTEBLOCK_PITCHES.containsKey(state)) { - return NOTEBLOCK_PITCHES.getInt(state); + return NOTEBLOCK_PITCHES.get(state); } return -1; } @@ -192,8 +184,8 @@ public static Int2BooleanMap getPistonValues() { return PISTON_VALUES; } - public static boolean isStickyPiston(BlockState blockState) { - return IS_STICKY_PISTON.get(blockState.getId()); + public static boolean isStickyPiston(int blockState) { + return IS_STICKY_PISTON.get(blockState); } /** @@ -203,9 +195,9 @@ public static boolean isStickyPiston(BlockState blockState) { * @param state BlockState of the block * @return Skull variant byte or -1 if no variant */ - public static byte getSkullVariant(BlockState state) { + public static byte getSkullVariant(int state) { if (SKULL_VARIANTS.containsKey(state)) { - return SKULL_VARIANTS.getByte(state); + return SKULL_VARIANTS.get(state); } return -1; } @@ -217,9 +209,9 @@ public static byte getSkullVariant(BlockState state) { * @param state BlockState of the block * @return Skull rotation value or -1 if no value */ - public static byte getSkullRotation(BlockState state) { + public static byte getSkullRotation(int state) { if (SKULL_ROTATIONS.containsKey(state)) { - return SKULL_ROTATIONS.getByte(state); + return SKULL_ROTATIONS.get(state); } return -1; } @@ -232,9 +224,9 @@ public static byte getSkullRotation(BlockState state) { * @param state BlockState of the block * @return Shulker direction value or -1 if no value */ - public static byte getShulkerBoxDirection(BlockState state) { + public static byte getShulkerBoxDirection(int state) { if (SHULKERBOX_DIRECTIONS.containsKey(state)) { - return SHULKERBOX_DIRECTIONS.getByte(state); + return SHULKERBOX_DIRECTIONS.get(state); } return -1; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java index 781dc3260f9..7d95218256e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.world.block; import com.fasterxml.jackson.databind.JsonNode; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.nukkitx.nbt.CompoundTagBuilder; @@ -47,19 +46,19 @@ public class BlockTranslator { public static final ListTag BLOCKS; - public static final BlockState AIR = new BlockState(0); + public static final int AIR = 0; public static final int BEDROCK_WATER_ID; private static final Int2IntMap JAVA_TO_BEDROCK_BLOCK_MAP = new Int2IntOpenHashMap(); - private static final Int2ObjectMap BEDROCK_TO_JAVA_BLOCK_MAP = new Int2ObjectOpenHashMap<>(); - private static final BiMap JAVA_ID_BLOCK_MAP = HashBiMap.create(); + private static final Int2IntMap BEDROCK_TO_JAVA_BLOCK_MAP = new Int2IntOpenHashMap(); + private static final BiMap JAVA_ID_BLOCK_MAP = HashBiMap.create(); private static final IntSet WATERLOGGED = new IntOpenHashSet(); private static final Object2IntMap ITEM_FRAMES = new Object2IntOpenHashMap<>(); // Bedrock carpet ID, used in LlamaEntity.java for decoration public static final int CARPET = 171; - private static final Map JAVA_ID_TO_BLOCK_ENTITY_MAP = new HashMap<>(); + private static final Int2ObjectMap JAVA_ID_TO_BLOCK_ENTITY_MAP = new Int2ObjectOpenHashMap<>(); public static final Int2DoubleMap JAVA_RUNTIME_ID_TO_HARDNESS = new Int2DoubleOpenHashMap(); public static final Int2BooleanMap JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND = new Int2BooleanOpenHashMap(); @@ -72,7 +71,9 @@ public class BlockTranslator { public static final int JAVA_RUNTIME_FURNACE_ID; public static final int JAVA_RUNTIME_FURNACE_LIT_ID; - private static final int BLOCK_STATE_VERSION = 17760256; + public static final int JAVA_RUNTIME_SPAWNER_ID; + + private static final int BLOCK_STATE_VERSION = 17825806; static { /* Load block palette */ @@ -113,12 +114,12 @@ public class BlockTranslator { int cobwebRuntimeId = -1; int furnaceRuntimeId = -1; int furnaceLitRuntimeId = -1; + int spawnerRuntimeId = -1; Iterator> blocksIterator = blocks.fields(); while (blocksIterator.hasNext()) { javaRuntimeId++; Map.Entry entry = blocksIterator.next(); String javaId = entry.getKey(); - BlockState javaBlockState = new BlockState(javaRuntimeId); CompoundTag blockTag = buildBedrockState(entry.getValue()); // TODO fix this, (no block should have a null hardness) @@ -127,7 +128,11 @@ public class BlockTranslator { JAVA_RUNTIME_ID_TO_HARDNESS.put(javaRuntimeId, hardnessNode.doubleValue()); } - JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND.put(javaRuntimeId, entry.getValue().get("can_break_with_hand").booleanValue()); + try { + JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND.put(javaRuntimeId, entry.getValue().get("can_break_with_hand").booleanValue()); + } catch (Exception e) { + JAVA_RUNTIME_ID_TO_CAN_HARVEST_WITH_HAND.put(javaRuntimeId, false); + } JsonNode toolTypeNode = entry.getValue().get("tool_type"); if (toolTypeNode != null) { @@ -142,7 +147,7 @@ public class BlockTranslator { cobwebRuntimeId = javaRuntimeId; } - JAVA_ID_BLOCK_MAP.put(javaId, javaBlockState); + JAVA_ID_BLOCK_MAP.put(javaId, javaRuntimeId); // Used for adding all "special" Java block states to block state map String identifier; @@ -151,12 +156,12 @@ public class BlockTranslator { identifier = clazz.getAnnotation(BlockEntity.class).regex(); // Endswith, or else the block bedrock gets picked up for bed if (bedrock_identifer.endsWith(identifier) && !identifier.equals("")) { - JAVA_ID_TO_BLOCK_ENTITY_MAP.put(javaBlockState, clazz.getAnnotation(BlockEntity.class).name()); + JAVA_ID_TO_BLOCK_ENTITY_MAP.put(javaRuntimeId, clazz.getAnnotation(BlockEntity.class).name()); break; } } - BlockStateValues.storeBlockStateValues(entry, javaBlockState); + BlockStateValues.storeBlockStateValues(entry, javaRuntimeId); // Get the tag needed for non-empty flower pots if (entry.getValue().get("pottable") != null) { @@ -170,10 +175,10 @@ public class BlockTranslator { || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); if (waterlogged) { - BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId | 1 << 31, javaBlockState); + BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId); WATERLOGGED.add(javaRuntimeId); } else { - BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaBlockState); + BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaRuntimeId); } CompoundTag runtimeTag = blockStateMap.remove(blockTag); @@ -199,6 +204,10 @@ public class BlockTranslator { } } + if (javaId.startsWith("minecraft:spawner")) { + spawnerRuntimeId = javaRuntimeId; + } + bedrockRuntimeId++; } @@ -217,6 +226,11 @@ public class BlockTranslator { } JAVA_RUNTIME_FURNACE_LIT_ID = furnaceLitRuntimeId; + if (spawnerRuntimeId == -1) { + throw new AssertionError("Unable to find spawner in palette"); + } + JAVA_RUNTIME_SPAWNER_ID = spawnerRuntimeId; + if (waterRuntimeId == -1) { throw new AssertionError("Unable to find water in palette"); } @@ -273,15 +287,11 @@ private static CompoundTag buildBedrockState(JsonNode node) { return tagBuilder.tag(statesBuilder.build("states")).build("block"); } - public static int getBedrockBlockId(BlockState state) { - return JAVA_TO_BEDROCK_BLOCK_MAP.get(state.getId()); - } - - public static int getBedrockBlockId(int javaId) { - return JAVA_TO_BEDROCK_BLOCK_MAP.get(javaId); + public static int getBedrockBlockId(int state) { + return JAVA_TO_BEDROCK_BLOCK_MAP.get(state); } - public static BlockState getJavaBlockState(int bedrockId) { + public static int getJavaBlockState(int bedrockId) { return BEDROCK_TO_JAVA_BLOCK_MAP.get(bedrockId); } @@ -297,23 +307,23 @@ public static int getBlockStateVersion() { return BLOCK_STATE_VERSION; } - public static BlockState getJavaBlockState(String javaId) { + public static int getJavaBlockState(String javaId) { return JAVA_ID_BLOCK_MAP.get(javaId); } - public static String getBlockEntityString(BlockState javaId) { + public static String getBlockEntityString(int javaId) { return JAVA_ID_TO_BLOCK_ENTITY_MAP.get(javaId); } - public static boolean isWaterlogged(BlockState state) { - return WATERLOGGED.contains(state.getId()); + public static boolean isWaterlogged(int state) { + return WATERLOGGED.contains(state); } - public static BiMap getJavaIdBlockMap() { + public static BiMap getJavaIdBlockMap() { return JAVA_ID_BLOCK_MAP; } - public static BlockState getJavaWaterloggedState(int bedrockId) { + public static int getJavaWaterloggedState(int bedrockId) { return BEDROCK_TO_JAVA_BLOCK_MAP.get(1 << 31 | bedrockId); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java index 3e2c0a959f2..15af7a70e84 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.nukkitx.nbt.CompoundTagBuilder; @@ -42,12 +41,12 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public boolean isBlock(BlockState blockState) { + public boolean isBlock(int blockState) { return BlockStateValues.getBannerColor(blockState) != -1; } @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); int bannerColor = BlockStateValues.getBannerColor(blockState); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java index 5f0b1cc0d23..31f363888db 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.ByteTag; @@ -39,12 +38,12 @@ public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public boolean isBlock(BlockState blockState) { + public boolean isBlock(int blockState) { return BlockStateValues.getBedColor(blockState) != -1; } @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); byte bedcolor = BlockStateValues.getBedColor(blockState); // Just in case... diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedrockOnlyBlockEntity.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedrockOnlyBlockEntity.java index 5b325ebad18..9efda13c052 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedrockOnlyBlockEntity.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedrockOnlyBlockEntity.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.tag.CompoundTag; import org.geysermc.connector.network.session.GeyserSession; @@ -42,7 +41,7 @@ public interface BedrockOnlyBlockEntity { * @param blockState The Java block state. * @param position The Bedrock block position. */ - void updateBlock(GeyserSession session, BlockState blockState, Vector3i position); + void updateBlock(GeyserSession session, int blockState, Vector3i position); /** * Get the tag of the Bedrock-only block entity @@ -50,7 +49,7 @@ public interface BedrockOnlyBlockEntity { * @param blockState Java BlockState of block. * @return Bedrock tag, or null if not a Bedrock-only Block Entity */ - static CompoundTag getTag(Vector3i position, BlockState blockState) { + static CompoundTag getTag(Vector3i position, int blockState) { if (new FlowerPotBlockEntityTranslator().isBlock(blockState)) { return FlowerPotBlockEntityTranslator.getTag(blockState, position); } else if (PistonBlockEntityTranslator.isBlock(blockState)) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java index 3d663926d7b..93356e7cd83 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; @@ -46,6 +45,19 @@ public abstract class BlockEntityTranslator { public static final Map BLOCK_ENTITY_TRANSLATORS = new HashMap<>(); public static ObjectArrayList REQUIRES_BLOCK_STATE_LIST = new ObjectArrayList<>(); + /** + * Contains a list of irregular block entity name translations that can't be fit into the regex + */ + public static final Map BLOCK_ENTITY_TRANSLATIONS = new HashMap() { + { + // Bedrock/Java differences + put("minecraft:enchanting_table", "EnchantTable"); + put("minecraft:piston_head", "PistonArm"); + put("minecraft:trapped_chest", "Chest"); + // There are some legacy IDs sent but as far as I can tell they are not needed for things to work properly + } + }; + protected BlockEntityTranslator() { } @@ -75,13 +87,13 @@ public static void init() { } } - public abstract List> translateTag(CompoundTag tag, BlockState blockState); + public abstract List> translateTag(CompoundTag tag, int blockState); public abstract CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z); public abstract com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z); - public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(String id, CompoundTag tag, BlockState blockState) { + public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(String id, CompoundTag tag, int blockState) { int x = Integer.parseInt(String.valueOf(tag.getValue().get("x").getValue())); int y = Integer.parseInt(String.valueOf(tag.getValue().get("y").getValue())); int z = Integer.parseInt(String.valueOf(tag.getValue().get("z").getValue())); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java index cd31636c89a..e932d2645ea 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.nukkitx.nbt.CompoundTagBuilder; @@ -41,7 +40,7 @@ public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); ListTag items = tag.get("Items"); int i = 1; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java index f5599832d0b..d1afd19e03e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/DoubleChestBlockEntityTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.CompoundTagBuilder; @@ -48,12 +47,12 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator implements BedrockOnlyBlockEntity, RequiresBlockState { @Override - public boolean isBlock(BlockState blockState) { - return BlockStateValues.getDoubleChestValues().containsKey(blockState.getId()); + public boolean isBlock(int blockState) { + return BlockStateValues.getDoubleChestValues().containsKey(blockState); } @Override - public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { + public void updateBlock(GeyserSession session, int blockState, Vector3i position) { CompoundTag javaTag = getConstantJavaTag("chest", position.getX(), position.getY(), position.getZ()); CompoundTagBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId("chest"), position.getX(), position.getY(), position.getZ()).toBuilder(); translateTag(javaTag, blockState).forEach(tagBuilder::tag); @@ -61,10 +60,10 @@ public void updateBlock(GeyserSession session, BlockState blockState, Vector3i p } @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); - if (blockState != null && BlockStateValues.getDoubleChestValues().containsKey(blockState.getId())) { - DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState.getId()); + if (BlockStateValues.getDoubleChestValues().containsKey(blockState)) { + DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState); if (chestValues != null) { int x = (int) tag.getValue().get("x").getValue(); int z = (int) tag.getValue().get("z").getValue(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java index d10682775a0..401bb343937 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.tag.Tag; @@ -36,7 +35,7 @@ public class EmptyBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { return new ArrayList<>(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java index 4cd2eaa9ecc..17e533bc0e0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.LongTag; import com.nukkitx.nbt.CompoundTagBuilder; @@ -40,7 +39,7 @@ public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); tags.add(new IntTag("Age", (int) (long) tag.get("Age").getValue())); // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java index c4748c829c8..691a85d3202 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/FlowerPotBlockEntityTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.CompoundTag; @@ -39,30 +38,30 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, RequiresBlockState { @Override - public boolean isBlock(BlockState blockState) { - return (BlockStateValues.getFlowerPotValues().containsKey(blockState.getId())); + public boolean isBlock(int blockState) { + return (BlockStateValues.getFlowerPotValues().containsKey(blockState)); } @Override - public void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { + public void updateBlock(GeyserSession session, int blockState, Vector3i position) { BlockEntityUtils.updateBlockEntity(session, getTag(blockState, position), position); UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket(); updateBlockPacket.setDataLayer(0); updateBlockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(blockState)); updateBlockPacket.setBlockPosition(position); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NO_GRAPHIC); //TODO: Check updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); session.sendUpstreamPacket(updateBlockPacket); } /** * Get the Nukkit CompoundTag of the flower pot. - * @param blockState Java BlockState of 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 CompoundTag getTag(BlockState blockState, Vector3i position) { + public static CompoundTag getTag(int blockState, Vector3i position) { CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() .intTag("x", position.getX()) .intTag("y", position.getY()) @@ -70,7 +69,7 @@ public static CompoundTag getTag(BlockState blockState, Vector3i position) { .byteTag("isMovable", (byte) 1) .stringTag("id", "FlowerPot"); // Get the Java name of the plant inside. e.g. minecraft:oak_sapling - String name = BlockStateValues.getFlowerPotValues().get(blockState.getId()); + 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. diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java index 168015f6eb8..ca5a4f520a5 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java @@ -27,7 +27,6 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.packet.BlockEventPacket; import org.geysermc.connector.network.session.GeyserSession; @@ -40,12 +39,12 @@ public class NoteblockBlockEntityTranslator implements RequiresBlockState { @Override - public boolean isBlock(BlockState blockState) { + public boolean isBlock(int blockState) { return BlockStateValues.getNoteblockPitch(blockState) != -1; } public static void translate(GeyserSession session, Position position) { - BlockState blockState = ChunkUtils.CACHED_BLOCK_ENTITIES.get(position); + int blockState = ChunkUtils.CACHED_BLOCK_ENTITIES.getOrDefault(position, 0); BlockEventPacket blockEventPacket = new BlockEventPacket(); blockEventPacket.setBlockPosition(Vector3i.from(position.getX(), position.getY(), position.getZ())); blockEventPacket.setEventType(0); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/PistonBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/PistonBlockEntityTranslator.java index 2dffce24cc7..bf8fcb1321f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/PistonBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/PistonBlockEntityTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.CompoundTag; @@ -42,25 +41,25 @@ public class PistonBlockEntityTranslator { * @param blockState Java BlockState of block. * @return if block is a piston or not. */ - public static boolean isBlock(BlockState blockState) { - return BlockStateValues.getPistonValues().containsKey(blockState.getId()); + 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 BlockState of block. + * @param blockState Java block state of block. * @param position Bedrock position of piston. * @return Bedrock tag of piston. */ - public static CompoundTag getTag(BlockState blockState, Vector3i position) { + public static CompoundTag getTag(int blockState, Vector3i position) { CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() .intTag("x", position.getX()) .intTag("y", position.getY()) .intTag("z", position.getZ()) .byteTag("isMovable", (byte) 1) .stringTag("id", "PistonArm"); - if (BlockStateValues.getPistonValues().containsKey(blockState.getId())) { - boolean extended = BlockStateValues.getPistonValues().get(blockState.getId()); + if (BlockStateValues.getPistonValues().containsKey(blockState)) { + boolean extended = BlockStateValues.getPistonValues().get(blockState); // 1f if extended, otherwise 0f tagBuilder.floatTag("Progress", (extended) ? 1.0f : 0.0f); // 1 if sticky, 0 if not diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/RequiresBlockState.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/RequiresBlockState.java index 4df7292ad32..0db306aa514 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/RequiresBlockState.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/RequiresBlockState.java @@ -25,8 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; - /** * Implemented in block entities if their Java block state is required for additional values in Bedrock */ @@ -37,6 +35,6 @@ public interface RequiresBlockState { * @param blockState BlockState to be compared * @return true if part of the class */ - boolean isBlock(BlockState blockState); + boolean isBlock(int blockState); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java index 373b963e2ba..b92b604e08b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.ByteTag; @@ -40,7 +39,7 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); byte direction = BlockStateValues.getShulkerBoxDirection(blockState); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java index 6c170462262..d0388f335e4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java @@ -25,13 +25,11 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; -import com.github.steveice10.mc.protocol.data.message.Message; +import com.github.steveice10.mc.protocol.data.message.MessageSerializer; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.nbt.tag.Tag; -import io.netty.util.internal.StringUtil; import org.geysermc.connector.utils.MessageUtils; import java.util.ArrayList; @@ -41,14 +39,14 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); StringBuilder signText = new StringBuilder(); for(int i = 0; i < 4; i++) { int currentLine = i+1; String signLine = getOrDefault(tag.getValue().get("Text" + currentLine), ""); - signLine = MessageUtils.getBedrockMessage(Message.fromString(signLine)); + signLine = MessageUtils.getBedrockMessage(MessageSerializer.fromString(signLine)); //Java allows up to 16+ characters on certain symbols. if(signLine.length() >= 15 && (signLine.contains("-") || signLine.contains("="))) { @@ -59,7 +57,7 @@ public List> translateTag(CompoundTag tag, BlockState blockState) { signText.append("\n"); } - tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(Message.fromString(signText.toString())))); + tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(MessageSerializer.fromString(signText.toString())))); return tags; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java index 9393f7bb0c1..f868ff08895 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java @@ -25,7 +25,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.ByteTag; import com.nukkitx.nbt.tag.CompoundTag; @@ -40,12 +39,12 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @Override - public boolean isBlock(BlockState blockState) { + public boolean isBlock(int blockState) { return BlockStateValues.getSkullVariant(blockState) != -1; } @Override - public List> translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, BlockState blockState) { + public List> translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); byte skullVariant = BlockStateValues.getSkullVariant(blockState); float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java index 100dbddd6f5..548a1ec8c44 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SpawnerBlockEntityTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.*; @@ -39,7 +38,7 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, BlockState blockState) { + public List> translateTag(CompoundTag tag, int blockState) { List> tags = new ArrayList<>(); if (tag.get("MaxNearbyEntities") != null) { diff --git a/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java b/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java index ea0d67c2116..1c4d26d0b2e 100644 --- a/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java +++ b/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java @@ -29,13 +29,12 @@ import com.github.steveice10.mc.protocol.MinecraftConstants; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol; +import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.mc.protocol.data.status.handler.ServerInfoHandler; import com.github.steveice10.packetlib.Client; import com.github.steveice10.packetlib.tcp.TcpSessionFactory; -import org.geysermc.common.ping.GeyserPingInfo; -import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.GeyserLogger; import java.util.concurrent.TimeUnit; @@ -79,7 +78,7 @@ public void run() { try { this.client = new Client(connector.getConfig().getRemote().getAddress(), connector.getConfig().getRemote().getPort(), new MinecraftProtocol(SubProtocol.STATUS), new TcpSessionFactory()); this.client.getSession().setFlag(MinecraftConstants.SERVER_INFO_HANDLER_KEY, (ServerInfoHandler) (session, info) -> { - this.pingInfo = new GeyserPingInfo(info.getDescription().getFullText(), info.getPlayerInfo().getOnlinePlayers(), info.getPlayerInfo().getMaxPlayers()); + this.pingInfo = new GeyserPingInfo(((TextMessage) info.getDescription()).getText(), info.getPlayerInfo().getOnlinePlayers(), info.getPlayerInfo().getMaxPlayers()); this.client.getSession().disconnect(null); }); diff --git a/connector/src/main/java/org/geysermc/connector/ping/IGeyserPingPassthrough.java b/connector/src/main/java/org/geysermc/connector/ping/IGeyserPingPassthrough.java index 7bc842dfbbb..35c8058ef9d 100644 --- a/connector/src/main/java/org/geysermc/connector/ping/IGeyserPingPassthrough.java +++ b/connector/src/main/java/org/geysermc/connector/ping/IGeyserPingPassthrough.java @@ -26,7 +26,7 @@ package org.geysermc.connector.ping; -import org.geysermc.common.ping.GeyserPingInfo; +import org.geysermc.connector.common.ping.GeyserPingInfo; /** * Interface that retrieves ping passthrough information from the Java server diff --git a/connector/src/main/java/org/geysermc/connector/utils/AttributeUtils.java b/connector/src/main/java/org/geysermc/connector/utils/AttributeUtils.java index a69a5f19752..45cd0f9b396 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/AttributeUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/AttributeUtils.java @@ -27,6 +27,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeModifier; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOperation; +import com.nukkitx.protocol.bedrock.data.AttributeData; import org.geysermc.connector.entity.attribute.Attribute; import org.geysermc.connector.entity.attribute.AttributeType; @@ -62,15 +63,20 @@ public static com.github.steveice10.mc.protocol.data.game.entity.attribute.Attri return new com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute(type, attribute.getValue()); } - public static com.nukkitx.protocol.bedrock.data.Attribute getBedrockAttribute(Attribute attribute) { + public static AttributeData getBedrockAttribute(Attribute attribute) { AttributeType type = attribute.getType(); if (!type.isBedrockAttribute()) return null; - return new com.nukkitx.protocol.bedrock.data.Attribute(type.getBedrockIdentifier(), attribute.getMinimum(), attribute.getMaximum(), attribute.getValue(), attribute.getDefaultValue()); + return new AttributeData(type.getBedrockIdentifier(), attribute.getMinimum(), attribute.getMaximum(), attribute.getValue(), attribute.getDefaultValue()); } - //https://minecraft.gamepedia.com/Attribute#Modifiers + /** + * Retrieve the base attribute value with all modifiers applied. + * https://minecraft.gamepedia.com/Attribute#Modifiers + * @param attribute The attribute to calculate the total value. + * @return The finished attribute with all modifiers applied. + */ public static double calculateValue(com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute attribute) { double base = attribute.getValue(); for (AttributeModifier modifier : attribute.getModifiers()) { diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java index 038084c3acf..3a356e03131 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -12,29 +12,24 @@ public class BlockEntityUtils { public static String getBedrockBlockEntityId(String id) { // These are the only exceptions when it comes to block entity ids - if (id.contains("piston_head")) - return "PistonArm"; - - if (id.contains("trapped_chest")) - return "Chest"; - - if (id.contains("EnderChest")) - return "EnderChest"; - - if (id.contains("enchanting_table")) { - return "EnchantTable"; + if (BlockEntityTranslator.BLOCK_ENTITY_TRANSLATIONS.containsKey(id)) { + return BlockEntityTranslator.BLOCK_ENTITY_TRANSLATIONS.get(id); } - id = id.toLowerCase() - .replace("minecraft:", "") + id = id.replace("minecraft:", "") .replace("_", " "); - String[] words = id.split(" "); + // Split at every space or capital letter - for the latter, some legacy Java block entity tags are the correct format already + String[] words; + if (!id.toUpperCase().equals(id)) { // Otherwise we get [S, K, U, L, L] + words = id.split("(?=[A-Z])| "); // Split at every space or note or before every capital letter + } else { + words = id.split(" "); + } for (int i = 0; i < words.length; i++) { words[i] = words[i].substring(0, 1).toUpperCase() + words[i].substring(1).toLowerCase(); } - id = String.join(" ", words); - return id.replace(" ", ""); + return String.join("", words); } public static BlockEntityTranslator getBlockEntityTranslator(String name) { diff --git a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index 010a87afa92..9cab8605de5 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -28,8 +28,9 @@ import com.github.steveice10.mc.protocol.data.game.chunk.Chunk; import com.github.steveice10.mc.protocol.data.game.chunk.Column; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; 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.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.CompoundTagBuilder; @@ -52,8 +53,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; import static org.geysermc.connector.network.translators.world.block.BlockTranslator.AIR; import static org.geysermc.connector.network.translators.world.block.BlockTranslator.BEDROCK_WATER_ID; @@ -63,7 +62,7 @@ public class ChunkUtils { /** * Temporarily stores positions of BlockState values that are needed for certain block entities actively */ - public static final Map CACHED_BLOCK_ENTITIES = new HashMap<>(); + public static final Object2IntMap CACHED_BLOCK_ENTITIES = new Object2IntOpenHashMap<>(); private static final com.nukkitx.nbt.tag.CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag(); public static final byte[] EMPTY_LEVEL_CHUNK_DATA; @@ -89,7 +88,7 @@ public static ChunkData translateToBedrock(Column column) { CompoundTag[] blockEntities = column.getTileEntities(); // Temporarily stores positions of BlockState values per chunk load - Map blockEntityPositions = new HashMap<>(); + Object2IntMap blockEntityPositions = new Object2IntOpenHashMap<>(); // Temporarily stores compound tags of Bedrock-only block entities ObjectArrayList bedrockOnlyBlockEntities = new ObjectArrayList<>(); @@ -105,7 +104,7 @@ public static ChunkData translateToBedrock(Column column) { for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { - BlockState blockState = chunk.get(x, y, z); + int blockState = chunk.get(x, y, z); int id = BlockTranslator.getBedrockBlockId(blockState); // Check to see if the name is in BlockTranslator.getBlockEntityString, and therefore must be handled differently @@ -117,8 +116,8 @@ public static ChunkData translateToBedrock(Column column) { section.getBlockStorageArray()[0].setFullBlock(ChunkSection.blockPosition(x, y, z), id); // Check if block is piston or flower - only block entities in Bedrock - if (BlockStateValues.getFlowerPotValues().containsKey(blockState.getId()) || - BlockStateValues.getPistonValues().containsKey(blockState.getId())) { + if (BlockStateValues.getFlowerPotValues().containsKey(blockState) || + BlockStateValues.getPistonValues().containsKey(blockState)) { Position pos = new ChunkPosition(column.getX(), column.getZ()).getBlock(x, (chunkY << 4) + y, z); bedrockOnlyBlockEntities.add(BedrockOnlyBlockEntity.getTag(Vector3i.from(pos.getX(), pos.getY(), pos.getZ()), blockState)); } @@ -137,17 +136,29 @@ public static ChunkData translateToBedrock(Column column) { while (i < blockEntities.length) { CompoundTag tag = blockEntities[i]; String tagName; - if (!tag.contains("id")) { - GeyserConnector.getInstance().getLogger().debug("Got tag with no id: " + tag.getValue()); - tagName = "Empty"; - } else { + if (tag.contains("id")) { tagName = (String) tag.get("id").getValue(); + } else { + tagName = "Empty"; + // Sometimes legacy tags have their ID be a StringTag with empty value + for (Tag subTag : tag) { + if (subTag instanceof StringTag) { + StringTag stringTag = (StringTag) subTag; + if (stringTag.getValue().equals("")) { + tagName = stringTag.getName(); + break; + } + } + } + if (tagName.equals("Empty")) { + GeyserConnector.getInstance().getLogger().debug("Got tag with no id: " + tag.getValue()); + } } String id = BlockEntityUtils.getBedrockBlockEntityId(tagName); BlockEntityTranslator blockEntityTranslator = BlockEntityUtils.getBlockEntityTranslator(id); Position pos = new Position((int) tag.get("x").getValue(), (int) tag.get("y").getValue(), (int) tag.get("z").getValue()); - BlockState blockState = blockEntityPositions.get(pos); + int blockState = blockEntityPositions.getOrDefault(pos, 0); bedrockBlockEntities[i] = blockEntityTranslator.getBlockEntityTag(tagName, tag, blockState); i++; } @@ -174,14 +185,14 @@ public static void updateChunkPosition(GeyserSession session, Vector3i position) } } - public static void updateBlock(GeyserSession session, BlockState blockState, Position position) { + public static void updateBlock(GeyserSession session, int blockState, Position position) { Vector3i pos = Vector3i.from(position.getX(), position.getY(), position.getZ()); updateBlock(session, blockState, pos); } - public static void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { + public static void updateBlock(GeyserSession session, int blockState, Vector3i position) { // Checks for item frames so they aren't tripped up and removed - if (ItemFrameEntity.positionContainsItemFrame(session, position) && blockState.equals(AIR)) { + if (ItemFrameEntity.positionContainsItemFrame(session, position) && blockState == AIR) { ((ItemFrameEntity) session.getEntityCache().getEntityByJavaId(ItemFrameEntity.getItemFrameEntityId(session, position))).updateBlock(session); return; } else if (ItemFrameEntity.positionContainsItemFrame(session, position)) { diff --git a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java new file mode 100644 index 00000000000..446e4773219 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2019-2020 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.connector.utils; + +import com.nukkitx.protocol.bedrock.packet.SetTitlePacket; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.session.GeyserSession; + +import java.util.concurrent.TimeUnit; + +/** + * Manages the sending of a cooldown indicator to the Bedrock player as there is no cooldown indicator in Bedrock. + * Much of the work here is from the wonderful folks from ViaRewind: https://github.com/ViaVersion/ViaRewind + */ +public class CooldownUtils { + + private final static boolean SHOW_COOLDOWN; + + static { + SHOW_COOLDOWN = GeyserConnector.getInstance().getConfig().isShowCooldown(); + } + + /** + * Starts sending the fake cooldown to the Bedrock client. + * @param session GeyserSession + */ + public static void sendCooldown(GeyserSession session) { + if (!SHOW_COOLDOWN) return; + if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used + // Needs to be sent or no subtitle packet is recognized by the client + SetTitlePacket titlePacket = new SetTitlePacket(); + titlePacket.setType(SetTitlePacket.Type.TITLE); + titlePacket.setText(" "); + session.sendUpstreamPacket(titlePacket); + session.setLastHitTime(System.currentTimeMillis()); + long lastHitTime = session.getLastHitTime(); // Used later to prevent multiple scheduled cooldown threads + computeCooldown(session, lastHitTime); + } + + /** + * Keeps updating the cooldown until the bar is complete. + * @param session GeyserSession + * @param lastHitTime The time of the last hit. Used to gauge how long the cooldown is taking. + */ + private static void computeCooldown(GeyserSession session, long lastHitTime) { + if (session.isClosed()) return; // Don't run scheduled tasks if the client left + if (lastHitTime != session.getLastHitTime()) return; // Means another cooldown has started so there's no need to continue this one + SetTitlePacket titlePacket = new SetTitlePacket(); + titlePacket.setType(SetTitlePacket.Type.SUBTITLE); + titlePacket.setText(getTitle(session)); + titlePacket.setFadeInTime(0); + titlePacket.setFadeOutTime(5); + titlePacket.setStayTime(2); + session.sendUpstreamPacket(titlePacket); + if (hasCooldown(session)) { + session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50 + } else { + SetTitlePacket removeTitlePacket = new SetTitlePacket(); + removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE); + removeTitlePacket.setText(" "); + session.sendUpstreamPacket(removeTitlePacket); + } + } + + private static boolean hasCooldown(GeyserSession session) { + long time = System.currentTimeMillis() - session.getLastHitTime(); + double cooldown = restrain(((double) time) * session.getAttackSpeed() / 1000d, 1.5); + return cooldown < 1.1; + } + + + private static double restrain(double x, double max) { + if (x < 0d) + return 0d; + return Math.min(x, max); + } + + private static String getTitle(GeyserSession session) { + long time = System.currentTimeMillis() - session.getLastHitTime(); + double cooldown = restrain(((double) time) * session.getAttackSpeed() / 1000d, 1); + + int darkGrey = (int) Math.floor(10d * cooldown); + int grey = 10 - darkGrey; + StringBuilder builder = new StringBuilder("§8"); + while (darkGrey > 0) { + builder.append("˙"); + darkGrey--; + } + builder.append("§7"); + while (grey > 0) { + builder.append("˙"); + grey--; + } + return builder.toString(); + } + +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java index 6c8d9f944b5..74db16bb586 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java @@ -36,10 +36,15 @@ public class DimensionUtils { // Changes if the above-bedrock Nether building workaround is applied private static int BEDROCK_NETHER_ID = 1; - public static void switchDimension(GeyserSession session, int javaDimension) { + // Static references to all vanilla dimensions + public static final String OVERWORLD = "minecraft:overworld"; + public static final String NETHER = "minecraft:the_nether"; + public static final String THE_END = "minecraft:the_end"; + + public static void switchDimension(GeyserSession session, String javaDimension) { int bedrockDimension = javaToBedrock(javaDimension); Entity player = session.getPlayerEntity(); - if (bedrockDimension == player.getDimension()) + if (javaDimension.equals(player.getDimension())) return; session.getEntityCache().removeAllEntities(); @@ -55,7 +60,7 @@ public static void switchDimension(GeyserSession session, int javaDimension) { changeDimensionPacket.setRespawn(true); changeDimensionPacket.setPosition(pos.toFloat()); session.sendUpstreamPacket(changeDimensionPacket); - player.setDimension(bedrockDimension); + player.setDimension(javaDimension); player.setPosition(pos.toFloat()); session.setSpawned(false); session.setLastChunkPosition(null); @@ -83,14 +88,14 @@ public static void switchDimension(GeyserSession session, int javaDimension) { * @param javaDimension Dimension ID to convert * @return Converted Bedrock edition dimension ID */ - public static int javaToBedrock(int javaDimension) { + public static int javaToBedrock(String javaDimension) { switch (javaDimension) { - case -1: + case NETHER: return BEDROCK_NETHER_ID; - case 1: + case THE_END: return 2; default: - return javaDimension; + return 0; } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java index 0a5a2278c69..09c78da92c2 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java +++ b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java @@ -55,4 +55,19 @@ public static void check(GeyserBootstrap bootstrap) { } } catch (Exception e) { } // Ignore any errors, inc ip failed to fetch, process could not run or access denied } + + public static boolean checkBasic() { + try { + String OS = System.getProperty("os.name").toLowerCase(); + if (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0) { + String output = new String(Files.readAllBytes(Paths.get("/proc/1/cgroup"))); + + if (output.contains("docker")) { + return true; + } + } + } catch (Exception ignored) { } // Ignore any errors, inc ip failed to fetch, process could not run or access denied + + return false; + } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java index fd4c5e4e535..627c25dc325 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -29,10 +29,10 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.StringTag; -import com.nukkitx.protocol.bedrock.data.ContainerId; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; -import org.geysermc.common.ChatColor; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; @@ -53,12 +53,18 @@ public static void openInventory(GeyserSession session, Inventory inventory) { if (translator != null) { session.getInventoryCache().setOpenInventory(inventory); translator.prepareInventory(session, inventory); + //Ensure at least half a second passes between closing and opening a new window + //The client will not open the new window if it is still closing the old one + long delay = 500 - (System.currentTimeMillis() - session.getLastWindowCloseTime()); //TODO: find better way to handle double chest delay if (translator instanceof DoubleChestInventoryTranslator) { + delay = Math.max(delay, 200); + } + if (delay > 0) { GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> { translator.openInventory(session, inventory); translator.updateInventory(session, inventory); - }, 200, TimeUnit.MILLISECONDS); + }, delay, TimeUnit.MILLISECONDS); } else { translator.openInventory(session, inventory); translator.updateInventory(session, inventory); @@ -69,26 +75,47 @@ public static void openInventory(GeyserSession session, Inventory inventory) { public static void closeInventory(GeyserSession session, int windowId) { if (windowId != 0) { Inventory inventory = session.getInventoryCache().getInventories().get(windowId); - if (inventory != null) { + Inventory openInventory = session.getInventoryCache().getOpenInventory(); + session.getInventoryCache().uncacheInventory(windowId); + if (inventory != null && openInventory != null && inventory.getId() == openInventory.getId()) { InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType()); translator.closeInventory(session, inventory); - session.getInventoryCache().uncacheInventory(windowId); session.getInventoryCache().setOpenInventory(null); + } else { + return; } } else { Inventory inventory = session.getInventory(); InventoryTranslator translator = InventoryTranslator.INVENTORY_TRANSLATORS.get(inventory.getWindowType()); translator.updateInventory(session, inventory); } + session.setCraftSlot(0); session.getInventory().setCursor(null); + updateCursor(session); + } + + public static void closeWindow(GeyserSession session, int windowId) { + //TODO: Investigate client crash when force closing window and opening a new one + //Instead, the window will eventually close by removing the fake blocks + session.setLastWindowCloseTime(System.currentTimeMillis()); + + /* + //Spamming close window packets can bug the client + if (System.currentTimeMillis() - session.getLastWindowCloseTime() > 500) { + ContainerClosePacket closePacket = new ContainerClosePacket(); + closePacket.setId((byte) windowId); + session.sendUpstreamPacket(closePacket); + session.setLastWindowCloseTime(System.currentTimeMillis()); + } + */ } public static void updateCursor(GeyserSession session) { InventorySlotPacket cursorPacket = new InventorySlotPacket(); - cursorPacket.setContainerId(ContainerId.CURSOR); + cursorPacket.setContainerId(ContainerId.UI); //TODO: CHECK IF ACCURATE cursorPacket.setSlot(0); - cursorPacket.setItem(ItemTranslator.translateToBedrock(session.getInventory().getCursor())); + cursorPacket.setItem(ItemTranslator.translateToBedrock(session, session.getInventory().getCursor())); session.sendUpstreamPacket(cursorPacket); } diff --git a/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java index f55cb261e38..78752591359 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java @@ -28,13 +28,18 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; +import com.github.steveice10.mc.protocol.MinecraftConstants; import lombok.Getter; import org.geysermc.connector.GeyserConnector; import java.io.*; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.zip.ZipFile; public class LocaleUtils { @@ -49,7 +54,8 @@ public class LocaleUtils { static { // Create the locales folder - File localesFolder = new File("locales/"); + File localesFolder = GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("locales").toFile(); + //noinspection ResultOfMethodCallIgnored localesFolder.mkdir(); // Download the latest asset list and cache it @@ -68,7 +74,7 @@ private static void generateAssetCache() { // Get the url for the latest version of the games manifest String latestInfoURL = ""; for (Version version : versionManifest.getVersions()) { - if (version.getId().equals(versionManifest.getLatestVersion().getRelease())) { + if (version.getId().equals(MinecraftConstants.GAME_VERSION)) { latestInfoURL = version.getUrl(); break; } @@ -82,14 +88,11 @@ private static void generateAssetCache() { // Get the individual version manifest VersionInfo versionInfo = GeyserConnector.JSON_MAPPER.readValue(WebUtils.getBody(latestInfoURL), VersionInfo.class); - // Get the smallest jar for use when downloading the en_us locale, will be either the server or client - int currentSize = Integer.MAX_VALUE; - for (VersionDownload download : versionInfo.getDownloads().values()) { - if (download.getUrl().endsWith(".jar") && download.getSize() < currentSize) { - smallestURL = download.getUrl(); - currentSize = download.getSize(); - } - } + // Get the client jar for use when downloading the en_us locale + GeyserConnector.getInstance().getLogger().debug(GeyserConnector.JSON_MAPPER.writeValueAsString(versionInfo.getDownloads())); + VersionDownload download = versionInfo.getDownloads().get("client"); + GeyserConnector.getInstance().getLogger().debug(GeyserConnector.JSON_MAPPER.writeValueAsString(download)); + smallestURL = download.getUrl(); // Get the assets list JsonNode assets = GeyserConnector.JSON_MAPPER.readTree(WebUtils.getBody(versionInfo.getAssetIndex().getUrl())).get("objects"); @@ -132,7 +135,7 @@ public static void downloadAndLoadLocale(String locale) { * @param locale Locale to download */ private static void downloadLocale(String locale) { - File localeFile = new File("locales/" + locale + ".json"); + File localeFile = Paths.get(GeyserConnector.getInstance().getBootstrap().getConfigFolder().toString(),"locales",locale + ".json").toFile(); // Check if we have already downloaded the locale file if (localeFile.exists()) { @@ -149,7 +152,7 @@ private static void downloadLocale(String locale) { // Get the hash and download the locale String hash = ASSET_MAP.get("minecraft/lang/" + locale + ".json").getHash(); - WebUtils.downloadFile("http://resources.download.minecraft.net/" + hash.substring(0, 2) + "/" + hash, "locales/" + locale + ".json"); + WebUtils.downloadFile("http://resources.download.minecraft.net/" + hash.substring(0, 2) + "/" + hash, localeFile.toString()); } /** @@ -158,7 +161,7 @@ private static void downloadLocale(String locale) { * @param locale Locale to load */ private static void loadLocale(String locale) { - File localeFile = new File("locales/" + locale + ".json"); + File localeFile = GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("locales/" + locale + ".json").toFile(); // Load the locale if (localeFile.exists()) { @@ -205,29 +208,30 @@ private static void downloadEN_US(File localeFile) { GeyserConnector.getInstance().getLogger().debug("Download URL: " + smallestURL); // Download the smallest JAR (client or server) - WebUtils.downloadFile(smallestURL, "tmp_locale.jar"); + Path tmpFilePath = GeyserConnector.getInstance().getBootstrap().getConfigFolder().resolve("tmp_locale.jar"); + WebUtils.downloadFile(smallestURL, tmpFilePath.toString()); // Load in the JAR as a zip and extract the file - ZipFile localeJar = new ZipFile("tmp_locale.jar"); - InputStream inputStream = localeJar.getInputStream(localeJar.getEntry("assets/minecraft/lang/en_us.json")); - FileOutputStream outputStream = new FileOutputStream(localeFile); + ZipFile localeJar = new ZipFile(tmpFilePath.toString()); + InputStream fileStream = localeJar.getInputStream(localeJar.getEntry("assets/minecraft/lang/en_us.json")); + FileOutputStream outStream = new FileOutputStream(localeFile); // Write the file to the locale dir - int data = inputStream.read(); - while(data != -1){ - outputStream.write(data); - data = inputStream.read(); + byte[] buf = new byte[fileStream.available()]; + int length; + while ((length = fileStream.read(buf)) != -1) { + outStream.write(buf, 0, length); } // Flush all changes to disk and cleanup - outputStream.flush(); - outputStream.close(); + outStream.flush(); + outStream.close(); - inputStream.close(); + fileStream.close(); localeJar.close(); // Delete the nolonger needed client/server jar - Files.delete(Paths.get("tmp_locale.jar")); + Files.delete(tmpFilePath); } catch (Exception e) { throw new AssertionError("Unable to download and extract en_us locale!", e); } @@ -354,4 +358,4 @@ class Asset { @JsonProperty("size") private int size; -} +} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/utils/MathUtils.java b/connector/src/main/java/org/geysermc/connector/utils/MathUtils.java index f66e869db89..48702492252 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MathUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MathUtils.java @@ -27,6 +27,8 @@ public class MathUtils { + public static final double SQRT_OF_TWO = Math.sqrt(2); + /** * Round the given float to the next whole number * diff --git a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java index d79cdab8285..96775f24578 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -26,50 +26,120 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; -import com.github.steveice10.mc.protocol.data.message.*; -import com.google.gson.*; +import com.github.steveice10.mc.protocol.data.message.Message; +import com.github.steveice10.mc.protocol.data.message.MessageSerializer; +import com.github.steveice10.mc.protocol.data.message.TextMessage; +import com.github.steveice10.mc.protocol.data.message.TranslationMessage; +import com.github.steveice10.mc.protocol.data.message.style.ChatColor; +import com.github.steveice10.mc.protocol.data.message.style.ChatFormat; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import net.kyori.text.Component; import net.kyori.text.serializer.gson.GsonComponentSerializer; import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.connector.network.session.GeyserSession; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MessageUtils { - public static List getTranslationParams(Message[] messages, String locale) { + private static final Map COLORS = new HashMap<>(); + private static final Map TEAM_COLORS = new HashMap<>(); + + static { + COLORS.put(ChatColor.BLACK, 0x000000); + COLORS.put(ChatColor.DARK_BLUE, 0x0000aa); + COLORS.put(ChatColor.DARK_GREEN, 0x00aa00); + COLORS.put(ChatColor.DARK_AQUA, 0x00aaaa); + COLORS.put(ChatColor.DARK_RED, 0xaa0000); + COLORS.put(ChatColor.DARK_PURPLE, 0xaa00aa); + COLORS.put(ChatColor.GOLD, 0xffaa00); + COLORS.put(ChatColor.GRAY, 0xaaaaaa); + COLORS.put(ChatColor.DARK_GRAY, 0x555555); + COLORS.put(ChatColor.BLUE, 0x5555ff); + COLORS.put(ChatColor.GREEN, 0x55ff55); + COLORS.put(ChatColor.AQUA, 0x55ffff); + COLORS.put(ChatColor.RED, 0xff5555); + COLORS.put(ChatColor.LIGHT_PURPLE, 0xff55ff); + COLORS.put(ChatColor.YELLOW, 0xffff55); + COLORS.put(ChatColor.WHITE, 0xffffff); + + TEAM_COLORS.put(TeamColor.BLACK, getColor(ChatColor.BLACK)); + TEAM_COLORS.put(TeamColor.DARK_BLUE, getColor(ChatColor.DARK_BLUE)); + TEAM_COLORS.put(TeamColor.DARK_GREEN, getColor(ChatColor.DARK_GREEN)); + TEAM_COLORS.put(TeamColor.DARK_AQUA, getColor(ChatColor.DARK_AQUA)); + TEAM_COLORS.put(TeamColor.DARK_RED, getColor(ChatColor.DARK_RED)); + TEAM_COLORS.put(TeamColor.DARK_PURPLE, getColor(ChatColor.DARK_PURPLE)); + TEAM_COLORS.put(TeamColor.GOLD, getColor(ChatColor.GOLD)); + TEAM_COLORS.put(TeamColor.GRAY, getColor(ChatColor.GRAY)); + TEAM_COLORS.put(TeamColor.DARK_GRAY, getColor(ChatColor.DARK_GRAY)); + TEAM_COLORS.put(TeamColor.BLUE, getColor(ChatColor.BLUE)); + TEAM_COLORS.put(TeamColor.GREEN, getColor(ChatColor.GREEN)); + TEAM_COLORS.put(TeamColor.AQUA, getColor(ChatColor.AQUA)); + TEAM_COLORS.put(TeamColor.RED, getColor(ChatColor.RED)); + TEAM_COLORS.put(TeamColor.LIGHT_PURPLE, getColor(ChatColor.LIGHT_PURPLE)); + TEAM_COLORS.put(TeamColor.YELLOW, getColor(ChatColor.YELLOW)); + TEAM_COLORS.put(TeamColor.WHITE, getColor(ChatColor.WHITE)); + TEAM_COLORS.put(TeamColor.OBFUSCATED, getFormat(Collections.singletonList(ChatFormat.OBFUSCATED))); + TEAM_COLORS.put(TeamColor.BOLD, getFormat(Collections.singletonList(ChatFormat.BOLD))); + TEAM_COLORS.put(TeamColor.STRIKETHROUGH, getFormat(Collections.singletonList(ChatFormat.STRIKETHROUGH))); + TEAM_COLORS.put(TeamColor.ITALIC, getFormat(Collections.singletonList(ChatFormat.ITALIC))); + } + + /** + * Recursively parse each message from a list for usage in a {@link TranslationMessage} + * + * @param messages A {@link List} of {@link Message} to parse + * @param locale A locale loaded to get the message for + * @param parent A {@link Message} to use as the parent (can be null) + * @return + */ + public static List getTranslationParams(List messages, String locale, Message parent) { List strings = new ArrayList<>(); for (Message message : messages) { + message = fixMessageStyle(message, parent); + if (message instanceof TranslationMessage) { TranslationMessage translation = (TranslationMessage) message; if (locale == null) { - String builder = "%" + translation.getTranslationKey(); + String builder = "%" + translation.getKey(); strings.add(builder); } - if (translation.getTranslationKey().equals("commands.gamemode.success.other")) { + if (translation.getKey().equals("commands.gamemode.success.other")) { strings.add(""); } - if (translation.getTranslationKey().equals("command.context.here")) { + if (translation.getKey().equals("command.context.here")) { strings.add(" - no permission or invalid command!"); } - List furtherParams = getTranslationParams(translation.getTranslationParams(), locale); + // Collect all params and add format corrections to the end of them + List furtherParams = new ArrayList<>(); + for (String param : getTranslationParams(translation.getWith(), locale, message)) { + String newParam = param; + if (parent.getStyle().getFormats().size() != 0) { + newParam += getFormat(parent.getStyle().getFormats()); + } + if (parent.getStyle().getColor() != ChatColor.NONE) { + newParam += getColor(parent.getStyle().getColor()); + } + + furtherParams.add(newParam); + } + if (locale != null) { - strings.add(insertParams(LocaleUtils.getLocaleString(translation.getTranslationKey(), locale), furtherParams)); + strings.add(insertParams(LocaleUtils.getLocaleString(translation.getKey(), locale), furtherParams)); } else { strings.addAll(furtherParams); } } else { String builder = getFormat(message.getStyle().getFormats()) + - getColorOrParent(message.getStyle()); - builder += getTranslatedBedrockMessage(message, locale, false); + getColor(message.getStyle().getColor()); + builder += getTranslatedBedrockMessage(message, locale, false, parent); strings.add(builder); } } @@ -77,44 +147,54 @@ public static List getTranslationParams(Message[] messages, String local return strings; } - public static List getTranslationParams(Message[] messages) { - return getTranslationParams(messages, null); + public static String getTranslatedBedrockMessage(Message message, String locale) { + return getTranslatedBedrockMessage(message, locale, true); } - public static String getTranslationText(TranslationMessage message) { - return getFormat(message.getStyle().getFormats()) + getColorOrParent(message.getStyle()) - + "%" + message.getTranslationKey(); + public static String getTranslatedBedrockMessage(Message message, String locale, boolean shouldTranslate) { + return getTranslatedBedrockMessage(message, locale, shouldTranslate, null); } - public static String getTranslatedBedrockMessage(Message message, String locale, boolean shouldTranslate) { + /** + * Translate a given {@link TranslationMessage} to the given locale + * + * @param message The {@link Message} to send + * @param locale + * @param shouldTranslate + * @param parent + * @return + */ + public static String getTranslatedBedrockMessage(Message message, String locale, boolean shouldTranslate, Message parent) { JsonParser parser = new JsonParser(); - if (isMessage(message.getText())) { - JsonObject object = parser.parse(message.getText()).getAsJsonObject(); - message = Message.fromJson(formatJson(object)); + if (isMessage(message.toString())) { + JsonObject object = parser.parse(message.toString()).getAsJsonObject(); + message = MessageSerializer.fromJson(object); } - String messageText = message.getText(); + message = fixMessageStyle(message, parent); + + String messageText = (message instanceof TranslationMessage) ? ((TranslationMessage) message).getKey() : ((TextMessage) message).getText(); if (locale != null && shouldTranslate) { messageText = LocaleUtils.getLocaleString(messageText, locale); } StringBuilder builder = new StringBuilder(); builder.append(getFormat(message.getStyle().getFormats())); - builder.append(getColorOrParent(message.getStyle())); + builder.append(getColor(message.getStyle().getColor())); builder.append(messageText); for (Message msg : message.getExtra()) { builder.append(getFormat(msg.getStyle().getFormats())); - builder.append(getColorOrParent(msg.getStyle())); - if (!(msg.getText() == null)) { + builder.append(getColor(msg.getStyle().getColor())); + if (!(msg.toString() == null)) { boolean isTranslationMessage = (msg instanceof TranslationMessage); String extraText = ""; if (isTranslationMessage) { - List paramsTranslated = getTranslationParams(((TranslationMessage) msg).getTranslationParams(), locale); - extraText = insertParams(getTranslatedBedrockMessage(msg, locale, isTranslationMessage), paramsTranslated); + List paramsTranslated = getTranslationParams(((TranslationMessage) msg).getWith(), locale, message); + extraText = insertParams(getTranslatedBedrockMessage(msg, locale, isTranslationMessage, message), paramsTranslated); } else { - extraText = getTranslatedBedrockMessage(msg, locale, isTranslationMessage); + extraText = getTranslatedBedrockMessage(msg, locale, isTranslationMessage, message); } builder.append(extraText); @@ -125,15 +205,43 @@ public static String getTranslatedBedrockMessage(Message message, String locale, return builder.toString(); } - public static String getTranslatedBedrockMessage(Message message, String locale) { - return getTranslatedBedrockMessage(message, locale, true); + /** + * If the passed {@link Message} color or format are empty then copy from parent + * + * @param message {@link Message} to update + * @param parent Parent {@link Message} for style + * @return The updated {@link Message} + */ + private static Message fixMessageStyle(Message message, Message parent) { + if (parent == null) { + return message; + } + Message newMessage = message; + + // Copy color from parent + if (newMessage.getStyle().getColor() == ChatColor.NONE) { + JsonObject messageObject = MessageSerializer.toJsonObject(newMessage); + messageObject.addProperty("color", parent.getStyle().getColor()); + newMessage = MessageSerializer.fromJson(messageObject); + } + + // Copy formatting from parent + if (newMessage.getStyle().getFormats().size() == 0) { + JsonObject messageObject = MessageSerializer.toJsonObject(newMessage); + for(ChatFormat format : parent.getStyle().getFormats()) { + messageObject.addProperty(format.toString(), true); + } + newMessage = MessageSerializer.fromJson(messageObject); + } + + return newMessage; } public static String getBedrockMessage(Message message) { - if (isMessage(message.getText())) { - return getBedrockMessage(message.getText()); + if (isMessage(((TextMessage) message).getText())) { + return getBedrockMessage(((TextMessage) message).getText()); } else { - return getBedrockMessage(message.toJsonString()); + return getBedrockMessage(MessageSerializer.toJsonString(message)); } } @@ -197,90 +305,118 @@ public static String insertParams(String message, List params) { return newMessage; } - /** - * Gets the colour for the message style or fetches it from the parent (recursive) - * - * @param style The style to get the colour from - * @return Colour string to be used - */ - private static String getColorOrParent(MessageStyle style) { - ChatColor chatColor = style.getColor(); - - if (chatColor == ChatColor.NONE && style.getParent() != null) { - return getColorOrParent(style.getParent()); - } - - return getColor(chatColor); - } - /** * Convert a ChatColor into a string for inserting into messages * * @param color ChatColor to convert * @return The converted color string */ - private static String getColor(ChatColor color) { + private static String getColor(String color) { String base = "\u00a7"; switch (color) { - case BLACK: + case ChatColor.BLACK: base += "0"; break; - case DARK_BLUE: + case ChatColor.DARK_BLUE: base += "1"; break; - case DARK_GREEN: + case ChatColor.DARK_GREEN: base += "2"; break; - case DARK_AQUA: + case ChatColor.DARK_AQUA: base += "3"; break; - case DARK_RED: + case ChatColor.DARK_RED: base += "4"; break; - case DARK_PURPLE: + case ChatColor.DARK_PURPLE: base += "5"; break; - case GOLD: + case ChatColor.GOLD: base += "6"; break; - case GRAY: + case ChatColor.GRAY: base += "7"; break; - case DARK_GRAY: + case ChatColor.DARK_GRAY: base += "8"; break; - case BLUE: + case ChatColor.BLUE: base += "9"; break; - case GREEN: + case ChatColor.GREEN: base += "a"; break; - case AQUA: + case ChatColor.AQUA: base += "b"; break; - case RED: + case ChatColor.RED: base += "c"; break; - case LIGHT_PURPLE: + case ChatColor.LIGHT_PURPLE: base += "d"; break; - case YELLOW: + case ChatColor.YELLOW: base += "e"; break; - case WHITE: + case ChatColor.WHITE: base += "f"; break; - case RESET: - case NONE: + case ChatColor.RESET: + //case NONE: base += "r"; break; - default: + case "": // To stop recursion return ""; + default: + return getClosestColor(color); } return base; } + /** + * Based on https://github.com/ViaVersion/ViaBackwards/blob/master/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TranslatableRewriter1_16.java + * + * @param color A color string + * @return The closest color to that string + */ + private static String getClosestColor(String color) { + if (!color.startsWith("#")) { + return ""; + } + + int rgb = Integer.parseInt(color.substring(1), 16); + int r = (rgb >> 16) & 0xFF; + int g = (rgb >> 8) & 0xFF; + int b = rgb & 0xFF; + + String closest = null; + int smallestDiff = 0; + + for (Map.Entry testColor : COLORS.entrySet()) { + if (testColor.getValue() == rgb) { + return testColor.getKey(); + } + + int testR = (testColor.getValue() >> 16) & 0xFF; + int testG = (testColor.getValue() >> 8) & 0xFF; + int testB = testColor.getValue() & 0xFF; + + // Check by the greatest diff of the 3 values + int rDiff = Math.abs(testR - r); + int gDiff = Math.abs(testG - g); + int bDiff = Math.abs(testB - b); + int maxDiff = Math.max(Math.max(rDiff, gDiff), bDiff); + if (closest == null || maxDiff < smallestDiff) { + closest = testColor.getKey(); + smallestDiff = maxDiff; + } + } + + return getColor(closest); + } + /** * Convert a list of ChatFormats into a string for inserting into messages * @@ -328,7 +464,7 @@ public static boolean isMessage(String text) { try { JsonObject object = parser.parse(text).getAsJsonObject(); try { - Message.fromJson(formatJson(object)); + MessageSerializer.fromJson(object); } catch (Exception ex) { return false; } @@ -338,42 +474,8 @@ public static boolean isMessage(String text) { return true; } - public static JsonObject formatJson(JsonObject object) { - if (object.has("hoverEvent")) { - JsonObject sub = (JsonObject) object.get("hoverEvent"); - JsonElement element = sub.get("value"); - - if (element instanceof JsonArray) { - JsonObject newobj = new JsonObject(); - newobj.add("extra", element); - newobj.addProperty("text", ""); - sub.remove("value"); - sub.add("value", newobj); - } - } - - if (object.has("extra")) { - JsonArray a = object.getAsJsonArray("extra"); - for (int i = 0; i < a.size(); i++) { - if (!(a.get(i) instanceof JsonPrimitive)) - formatJson((JsonObject) a.get(i)); - } - } - return object; - } - public static String toChatColor(TeamColor teamColor) { - for (ChatColor color : ChatColor.values()) { - if (color.name().equals(teamColor.name())) { - return getColor(color); - } - } - for (ChatFormat format : ChatFormat.values()) { - if (format.name().equals(teamColor.name())) { - return getFormat(Collections.singletonList(format)); - } - } - return ""; + return TEAM_COLORS.getOrDefault(teamColor, ""); } /** diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java index 48e4c4c80da..ae17ed20558 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -28,14 +28,12 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.steveice10.mc.auth.data.GameProfile; -import com.nukkitx.protocol.bedrock.data.ImageData; -import com.nukkitx.protocol.bedrock.data.SerializedSkin; +import com.nukkitx.protocol.bedrock.data.skin.ImageData; +import com.nukkitx.protocol.bedrock.data.skin.SerializedSkin; import com.nukkitx.protocol.bedrock.packet.PlayerListPacket; - import lombok.AllArgsConstructor; import lombok.Getter; - -import org.geysermc.common.AuthType; +import org.geysermc.connector.common.AuthType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; diff --git a/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java b/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java index 50ab76d0b70..7a1a0215f02 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java @@ -25,11 +25,10 @@ package org.geysermc.connector.utils; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; @@ -81,4 +80,31 @@ public static void downloadFile(String reqURL, String fileLocation) { throw new AssertionError("Unable to download and save file: " + fileLocation + " (" + reqURL + ")", e); } } + + public static String post(String reqURL, String postContent) throws IOException { + URL url = null; + url = new URL(reqURL); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("POST"); + con.setRequestProperty("Content-Type", "text/plain"); + con.setDoOutput(true); + + OutputStream out = con.getOutputStream(); + out.write(postContent.getBytes(StandardCharsets.UTF_8)); + out.close(); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuffer content = new StringBuffer(); + + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + content.append("\n"); + } + + in.close(); + con.disconnect(); + + return content.toString(); + } } diff --git a/connector/src/main/resources/bedrock/biome_definitions.dat b/connector/src/main/resources/bedrock/biome_definitions.dat index b8c6df4a686..6d72cc92491 100644 Binary files a/connector/src/main/resources/bedrock/biome_definitions.dat and b/connector/src/main/resources/bedrock/biome_definitions.dat differ diff --git a/connector/src/main/resources/bedrock/creative_items.json b/connector/src/main/resources/bedrock/creative_items.json index 8045b219c29..eea92a95006 100644 --- a/connector/src/main/resources/bedrock/creative_items.json +++ b/connector/src/main/resources/bedrock/creative_items.json @@ -23,6 +23,12 @@ "id" : 5, "damage" : 5 }, + { + "id" : -242 + }, + { + "id" : -243 + }, { "id" : 139 }, @@ -78,6 +84,15 @@ "id" : 139, "damage" : 11 }, + { + "id" : -277 + }, + { + "id" : -297 + }, + { + "id" : -278 + }, { "id" : 85 }, @@ -104,6 +119,12 @@ { "id" : 113 }, + { + "id" : -256 + }, + { + "id" : -257 + }, { "id" : 107 }, @@ -122,6 +143,12 @@ { "id" : 186 }, + { + "id" : -258 + }, + { + "id" : -259 + }, { "id" : -180 }, @@ -215,6 +242,21 @@ { "id" : -4 }, + { + "id" : -254 + }, + { + "id" : -255 + }, + { + "id" : -276 + }, + { + "id" : -292 + }, + { + "id" : -275 + }, { "id" : 324 }, @@ -236,6 +278,12 @@ { "id" : 330 }, + { + "id" : 755 + }, + { + "id" : 756 + }, { "id" : 96 }, @@ -257,9 +305,18 @@ { "id" : 167 }, + { + "id" : -246 + }, + { + "id" : -247 + }, { "id" : 101 }, + { + "id" : 758 + }, { "id" : 20 }, @@ -529,9 +586,33 @@ "id" : 182, "damage" : 4 }, + { + "id" : -264 + }, + { + "id" : -265 + }, + { + "id" : -282 + }, + { + "id" : -293 + }, + { + "id" : -284 + }, { "id" : 45 }, + { + "id" : -302 + }, + { + "id" : -303 + }, + { + "id" : -304 + }, { "id" : 98 }, @@ -554,6 +635,18 @@ "id" : 168, "damage" : 2 }, + { + "id" : -274 + }, + { + "id" : -280 + }, + { + "id" : -281 + }, + { + "id" : -279 + }, { "id" : 4 }, @@ -648,18 +741,72 @@ { "id" : 170 }, + { + "id" : -239 + }, { "id" : 216 }, { "id" : 214 }, + { + "id" : -227 + }, { "id" : 112 }, { "id" : 215 }, + { + "id" : -225 + }, + { + "id" : -226 + }, + { + "id" : -240 + }, + { + "id" : -241 + }, + { + "id" : -299 + }, + { + "id" : -298 + }, + { + "id" : -300 + }, + { + "id" : -301 + }, + { + "id" : -230 + }, + { + "id" : -232 + }, + { + "id" : -233 + }, + { + "id" : -234 + }, + { + "id" : -235 + }, + { + "id" : -236 + }, + { + "id" : -270 + }, + { + "id" : -222 + }, { "id" : 35 }, @@ -1082,6 +1229,12 @@ { "id" : 153 }, + { + "id" : -288 + }, + { + "id" : -271 + }, { "id" : 13 }, @@ -1097,6 +1250,9 @@ "id" : 1, "damage" : 5 }, + { + "id" : -273 + }, { "id" : 1, "damage" : 2 @@ -1109,6 +1265,9 @@ "id" : 1, "damage" : 6 }, + { + "id" : -291 + }, { "id" : 12 }, @@ -1252,7 +1411,8 @@ "damage" : 5 }, { - "id" : -218 + "id" : -218, + "damage" : 3 }, { "id" : 295 @@ -1333,6 +1493,9 @@ "id" : 175, "damage" : 2 }, + { + "id" : 760 + }, { "id" : -131, "damage" : 3 @@ -1416,6 +1579,12 @@ { "id" : -130 }, + { + "id" : -223 + }, + { + "id" : -224 + }, { "id" : 37 }, @@ -1562,6 +1731,12 @@ { "id" : 106 }, + { + "id" : -231 + }, + { + "id" : -287 + }, { "id" : 111 }, @@ -1619,6 +1794,12 @@ { "id" : 40 }, + { + "id" : -228 + }, + { + "id" : -229 + }, { "id" : 99, "damage" : 14 @@ -1871,6 +2052,22 @@ "id" : 383, "damage" : 42 }, + { + "id" : 383, + "damage" : 125 + }, + { + "id" : 383, + "damage" : 124 + }, + { + "id" : 383, + "damage" : 123 + }, + { + "id" : 383, + "damage" : 126 + }, { "id" : 383, "damage" : 41 @@ -1922,6 +2119,9 @@ { "id" : 49 }, + { + "id" : -289 + }, { "id" : 7 }, @@ -2013,6 +2213,9 @@ { "id" : 310 }, + { + "id" : 748 + }, { "id" : 299 }, @@ -2028,6 +2231,9 @@ { "id" : 311 }, + { + "id" : 749 + }, { "id" : 300 }, @@ -2043,6 +2249,9 @@ { "id" : 312 }, + { + "id" : 750 + }, { "id" : 301 }, @@ -2058,6 +2267,9 @@ { "id" : 313 }, + { + "id" : 751 + }, { "id" : 268 }, @@ -2073,6 +2285,9 @@ { "id" : 276 }, + { + "id" : 743 + }, { "id" : 271 }, @@ -2088,6 +2303,9 @@ { "id" : 279 }, + { + "id" : 746 + }, { "id" : 270 }, @@ -2103,6 +2321,9 @@ { "id" : 278 }, + { + "id" : 745 + }, { "id" : 269 }, @@ -2118,6 +2339,9 @@ { "id" : 277 }, + { + "id" : 744 + }, { "id" : 290 }, @@ -2133,6 +2357,9 @@ { "id" : 293 }, + { + "id" : 747 + }, { "id" : 261 }, @@ -2290,6 +2517,10 @@ "id" : 262, "damage" : 42 }, + { + "id" : 262, + "damage" : 43 + }, { "id" : 513 }, @@ -2347,6 +2578,9 @@ { "id" : 398 }, + { + "id" : 757 + }, { "id" : 332 }, @@ -2572,6 +2806,10 @@ "id" : 373, "damage" : 41 }, + { + "id" : 373, + "damage" : 42 + }, { "id" : 438 }, @@ -2739,6 +2977,10 @@ "id" : 438, "damage" : 41 }, + { + "id" : 438, + "damage" : 42 + }, { "id" : 441 }, @@ -2906,6 +3148,10 @@ "id" : 441, "damage" : 41 }, + { + "id" : 441, + "damage" : 42 + }, { "id" : 280 }, @@ -2975,12 +3221,18 @@ { "id" : 50 }, + { + "id" : -268 + }, { "id" : -156 }, { "id" : -208 }, + { + "id" : -269 + }, { "id" : 58 }, @@ -2994,11 +3246,15 @@ "id" : -202 }, { - "id" : -219 + "id" : -219, + "damage" : 3 }, { "id" : 720 }, + { + "id" : 801 + }, { "id" : 61 }, @@ -3008,6 +3264,9 @@ { "id" : -198 }, + { + "id" : -272 + }, { "id" : 379 }, @@ -3163,6 +3422,9 @@ { "id" : 511 }, + { + "id" : 759 + }, { "id" : 348 }, @@ -3193,6 +3455,12 @@ { "id" : 476 }, + { + "id" : 753 + }, + { + "id" : 754 + }, { "id" : 321 }, @@ -3293,6 +3561,12 @@ { "id" : 265 }, + { + "id" : 752 + }, + { + "id" : 742 + }, { "id" : 371 }, @@ -3732,6 +4006,14 @@ "id" : 403, "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBoAAAA=" }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBwAAAA=" + }, { "id" : 403, "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB0AAAA=" @@ -3812,6 +4094,18 @@ "id" : 403, "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCMAAAA=" }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCQAAAA=" + }, { "id" : 333 }, @@ -3892,6 +4186,15 @@ { "id" : 77 }, + { + "id" : -260 + }, + { + "id" : -261 + }, + { + "id" : -296 + }, { "id" : 131 }, @@ -3913,6 +4216,12 @@ { "id" : -152 }, + { + "id" : -262 + }, + { + "id" : -263 + }, { "id" : 70 }, @@ -3922,6 +4231,9 @@ { "id" : 148 }, + { + "id" : -295 + }, { "id" : 251 }, @@ -4053,6 +4365,10 @@ "id" : 434, "damage" : 5 }, + { + "id" : 434, + "damage" : 6 + }, { "id" : 401, "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMAAAAAAAAA" diff --git a/connector/src/main/resources/bedrock/entity_identifiers.dat b/connector/src/main/resources/bedrock/entity_identifiers.dat index cb8f0481b31..c9477ba85dd 100644 Binary files a/connector/src/main/resources/bedrock/entity_identifiers.dat and b/connector/src/main/resources/bedrock/entity_identifiers.dat differ diff --git a/connector/src/main/resources/bedrock/items.json b/connector/src/main/resources/bedrock/items.json index 87f85187b5a..0614b3641be 100644 --- a/connector/src/main/resources/bedrock/items.json +++ b/connector/src/main/resources/bedrock/items.json @@ -1,2810 +1,3230 @@ [ - { - "name" : "minecraft:item.reeds", - "id" : 83 - }, - { - "name" : "minecraft:air", - "id" : -158 - }, - { - "name" : "minecraft:item.birch_door", - "id" : 194 - }, - { - "name" : "minecraft:apple", - "id" : 260 - }, - { - "name" : "minecraft:cooked_porkchop", - "id" : 320 - }, - { - "name" : "minecraft:beacon", - "id" : 138 - }, - { - "name" : "minecraft:stone_stairs", - "id" : 67 - }, - { - "name" : "minecraft:appleenchanted", - "id" : 466 - }, - { - "name" : "minecraft:tripwire", - "id" : 132 - }, - { - "name" : "minecraft:leather_leggings", - "id" : 300 - }, - { - "name" : "minecraft:bread", - "id" : 297 - }, - { - "name" : "minecraft:light_block", - "id" : -215 - }, - { - "name" : "minecraft:porkchop", - "id" : 319 - }, - { - "name" : "minecraft:spruce_fence_gate", - "id" : 183 - }, - { - "name" : "minecraft:fish", - "id" : 349 - }, - { - "name" : "minecraft:element_52", - "id" : -63 - }, - { - "name" : "minecraft:diamond_sword", - "id" : 276 - }, - { - "name" : "minecraft:element_38", - "id" : -49 - }, - { - "name" : "minecraft:sandstone_stairs", - "id" : 128 - }, - { - "name" : "minecraft:acacia_sign", - "id" : 475 - }, - { - "name" : "minecraft:rabbit_stew", - "id" : 413 - }, - { - "name" : "minecraft:birch_sign", - "id" : 473 - }, - { - "name" : "minecraft:horsearmorgold", - "id" : 418 - }, - { - "name" : "minecraft:element_74", - "id" : -85 - }, - { - "name" : "minecraft:pufferfish", - "id" : 462 - }, - { - "name" : "minecraft:redstone_block", - "id" : 152 - }, - { - "name" : "minecraft:golden_apple", - "id" : 322 - }, - { - "name" : "minecraft:item.wooden_door", - "id" : 64 - }, - { - "name" : "minecraft:emerald", - "id" : 388 - }, - { - "name" : "minecraft:element_47", - "id" : -58 - }, - { - "name" : "minecraft:mushroom_stew", - "id" : 282 - }, - { - "name" : "minecraft:stone_axe", - "id" : 275 - }, - { - "name" : "minecraft:salmon", - "id" : 460 - }, - { - "name" : "minecraft:feather", - "id" : 288 - }, - { - "name" : "minecraft:clownfish", - "id" : 461 - }, - { - "name" : "minecraft:diamond", - "id" : 264 - }, - { - "name" : "minecraft:cooked_fish", - "id" : 350 - }, - { - "name" : "minecraft:element_32", - "id" : -43 - }, - { - "name" : "minecraft:double_stone_slab4", - "id" : -166 - }, - { - "name" : "minecraft:element_5", - "id" : -16 - }, - { - "name" : "minecraft:element_25", - "id" : -36 - }, - { - "name" : "minecraft:polished_granite_stairs", - "id" : -172 - }, - { - "name" : "minecraft:bowl", - "id" : 281 - }, - { - "name" : "minecraft:red_mushroom_block", - "id" : 100 - }, - { - "name" : "minecraft:mossy_stone_brick_stairs", - "id" : -175 - }, - { - "name" : "minecraft:cooked_salmon", - "id" : 463 - }, - { - "name" : "minecraft:element_87", - "id" : -98 - }, - { - "name" : "minecraft:pumpkin_seeds", - "id" : 361 - }, - { - "name" : "minecraft:element_53", - "id" : -64 - }, - { - "name" : "minecraft:dried_kelp", - "id" : 464 - }, - { - "name" : "minecraft:brewingstandblock", - "id" : 117 - }, - { - "name" : "minecraft:wooden_pickaxe", - "id" : 270 - }, - { - "name" : "minecraft:cookie", - "id" : 357 - }, - { - "name" : "minecraft:gold_ingot", - "id" : 266 - }, - { - "name" : "minecraft:sweet_berries", - "id" : 477 - }, - { - "name" : "minecraft:melon", - "id" : 360 - }, - { - "name" : "minecraft:iron_pickaxe", - "id" : 257 - }, - { - "name" : "minecraft:glow_stick", - "id" : 166 - }, - { - "name" : "minecraft:beef", - "id" : 363 - }, - { - "name" : "minecraft:stone_hoe", - "id" : 291 - }, - { - "name" : "minecraft:cooked_beef", - "id" : 364 - }, - { - "name" : "minecraft:lime_glazed_terracotta", - "id" : 225 - }, - { - "name" : "minecraft:chicken", - "id" : 365 - }, - { - "name" : "minecraft:element_31", - "id" : -42 - }, - { - "name" : "minecraft:cooked_chicken", - "id" : 366 - }, - { - "name" : "minecraft:rotten_flesh", - "id" : 367 - }, - { - "name" : "minecraft:darkoak_sign", - "id" : 476 - }, - { - "name" : "minecraft:stone_sword", - "id" : 272 - }, - { - "name" : "minecraft:spider_eye", - "id" : 375 - }, - { - "name" : "minecraft:diamond_axe", - "id" : 279 - }, - { - "name" : "minecraft:element_105", - "id" : -116 - }, - { - "name" : "minecraft:carrot", - "id" : 391 - }, - { - "name" : "minecraft:stripped_birch_log", - "id" : -6 - }, - { - "name" : "minecraft:potato", - "id" : 392 - }, - { - "name" : "minecraft:baked_potato", - "id" : 393 - }, - { - "name" : "minecraft:element_15", - "id" : -26 - }, - { - "name" : "minecraft:carpet", - "id" : 171 - }, - { - "name" : "minecraft:poisonous_potato", - "id" : 394 - }, - { - "name" : "minecraft:beetroot_seeds", - "id" : 458 - }, - { - "name" : "minecraft:noteblock", - "id" : 25 - }, - { - "name" : "minecraft:golden_carrot", - "id" : 396 - }, - { - "name" : "minecraft:pumpkin_pie", - "id" : 400 - }, - { - "name" : "minecraft:beetroot", - "id" : 457 - }, - { - "name" : "minecraft:coral_fan_dead", - "id" : -134 - }, - { - "name" : "minecraft:iron_ingot", - "id" : 265 - }, - { - "name" : "minecraft:beetroot_soup", - "id" : 459 - }, - { - "name" : "minecraft:rabbit", - "id" : 411 - }, - { - "name" : "minecraft:cooked_rabbit", - "id" : 412 - }, - { - "name" : "minecraft:iron_helmet", - "id" : 306 - }, - { - "name" : "minecraft:wheat_seeds", - "id" : 295 - }, - { - "name" : "minecraft:melon_seeds", - "id" : 362 - }, - { - "name" : "minecraft:nether_wart", - "id" : 372 - }, - { - "name" : "minecraft:record_strad", - "id" : 508 - }, - { - "name" : "minecraft:iron_sword", - "id" : 267 - }, - { - "name" : "minecraft:iron_shovel", - "id" : 256 - }, - { - "name" : "minecraft:stone_pickaxe", - "id" : 274 - }, - { - "name" : "minecraft:leather", - "id" : 334 - }, - { - "name" : "minecraft:command_block_minecart", - "id" : 443 - }, - { - "name" : "minecraft:stone_shovel", - "id" : 273 - }, - { - "name" : "minecraft:written_book", - "id" : 387 - }, - { - "name" : "minecraft:diorite_stairs", - "id" : -170 - }, - { - "name" : "minecraft:arrow", - "id" : 262 - }, - { - "name" : "minecraft:element_97", - "id" : -108 - }, - { - "name" : "minecraft:campfire", - "id" : 720 - }, - { - "name" : "minecraft:polished_andesite_stairs", - "id" : -174 - }, - { - "name" : "minecraft:acacia_stairs", - "id" : 163 - }, - { - "name" : "minecraft:iron_axe", - "id" : 258 - }, - { - "name" : "minecraft:flint_and_steel", - "id" : 259 - }, - { - "name" : "minecraft:bow", - "id" : 261 - }, - { - "name" : "minecraft:nautilus_shell", - "id" : 465 - }, - { - "name" : "minecraft:coal", - "id" : 263 - }, - { - "name" : "minecraft:bookshelf", - "id" : 47 - }, - { - "name" : "minecraft:wooden_sword", - "id" : 268 - }, - { - "name" : "minecraft:diamond_pickaxe", - "id" : 278 - }, - { - "name" : "minecraft:deadbush", - "id" : 32 - }, - { - "name" : "minecraft:ender_chest", - "id" : 130 - }, - { - "name" : "minecraft:record_stal", - "id" : 507 - }, - { - "name" : "minecraft:wooden_shovel", - "id" : 269 - }, - { - "name" : "minecraft:dark_oak_trapdoor", - "id" : -147 - }, - { - "name" : "minecraft:record_mall", - "id" : 505 - }, - { - "name" : "minecraft:wooden_axe", - "id" : 271 - }, - { - "name" : "minecraft:powered_comparator", - "id" : 150 - }, - { - "name" : "minecraft:diamond_shovel", - "id" : 277 - }, - { - "name" : "minecraft:golden_rail", - "id" : 27 - }, - { - "name" : "minecraft:lit_furnace", - "id" : 62 - }, - { - "name" : "minecraft:stick", - "id" : 280 - }, - { - "name" : "minecraft:slime_ball", - "id" : 341 - }, - { - "name" : "minecraft:element_58", - "id" : -69 - }, - { - "name" : "minecraft:golden_sword", - "id" : 283 - }, - { - "name" : "minecraft:golden_shovel", - "id" : 284 - }, - { - "name" : "minecraft:chest", - "id" : 54 - }, - { - "name" : "minecraft:golden_pickaxe", - "id" : 285 - }, - { - "name" : "minecraft:golden_axe", - "id" : 286 - }, - { - "name" : "minecraft:element_62", - "id" : -73 - }, - { - "name" : "minecraft:string", - "id" : 287 - }, - { - "name" : "minecraft:glowstone_dust", - "id" : 348 - }, - { - "name" : "minecraft:gunpowder", - "id" : 289 - }, - { - "name" : "minecraft:spawn_egg", - "id" : 383 - }, - { - "name" : "minecraft:fence", - "id" : 85 - }, - { - "name" : "minecraft:wooden_hoe", - "id" : 290 - }, - { - "name" : "minecraft:shulker_shell", - "id" : 445 - }, - { - "name" : "minecraft:iron_hoe", - "id" : 292 - }, - { - "name" : "minecraft:diamond_hoe", - "id" : 293 - }, - { - "name" : "minecraft:golden_hoe", - "id" : 294 - }, - { - "name" : "minecraft:turtle_shell_piece", - "id" : 468 - }, - { - "name" : "minecraft:sweet_berry_bush", - "id" : -207 - }, - { - "name" : "minecraft:info_update2", - "id" : 249 - }, - { - "name" : "minecraft:muttoncooked", - "id" : 424 - }, - { - "name" : "minecraft:wheat", - "id" : 296 - }, - { - "name" : "minecraft:dark_oak_door", - "id" : 431 - }, - { - "name" : "minecraft:grindstone", - "id" : -195 - }, - { - "name" : "minecraft:element_46", - "id" : -57 - }, - { - "name" : "minecraft:potion", - "id" : 373 - }, - { - "name" : "minecraft:wither_rose", - "id" : -216 - }, - { - "name" : "minecraft:leather_helmet", - "id" : 298 - }, - { - "name" : "minecraft:element_48", - "id" : -59 - }, - { - "name" : "minecraft:leather_chestplate", - "id" : 299 - }, - { - "name" : "minecraft:leather_boots", - "id" : 301 - }, - { - "name" : "minecraft:lectern", - "id" : -194 - }, - { - "name" : "minecraft:smithing_table", - "id" : -202 - }, - { - "name" : "minecraft:bedrock", - "id" : 7 - }, - { - "name" : "minecraft:chainmail_helmet", - "id" : 302 - }, - { - "name" : "minecraft:stonebrick", - "id" : 98 - }, - { - "name" : "minecraft:stickypistonarmcollision", - "id" : -217 - }, - { - "name" : "minecraft:structure_void", - "id" : 217 - }, - { - "name" : "minecraft:chainmail_chestplate", - "id" : 303 - }, - { - "name" : "minecraft:lit_blast_furnace", - "id" : -214 - }, - { - "name" : "minecraft:element_11", - "id" : -22 - }, - { - "name" : "minecraft:chainmail_leggings", - "id" : 304 - }, - { - "name" : "minecraft:saddle", - "id" : 329 - }, - { - "name" : "minecraft:purpur_block", - "id" : 201 - }, - { - "name" : "minecraft:chainmail_boots", - "id" : 305 - }, - { - "name" : "minecraft:ladder", - "id" : 65 - }, - { - "name" : "minecraft:iron_chestplate", - "id" : 307 - }, - { - "name" : "minecraft:diamond_helmet", - "id" : 310 - }, - { - "name" : "minecraft:iron_leggings", - "id" : 308 - }, - { - "name" : "minecraft:iron_boots", - "id" : 309 - }, - { - "name" : "minecraft:element_104", - "id" : -115 - }, - { - "name" : "minecraft:chorus_fruit_popped", - "id" : 433 - }, - { - "name" : "minecraft:diamond_chestplate", - "id" : 311 - }, - { - "name" : "minecraft:diamond_leggings", - "id" : 312 - }, - { - "name" : "minecraft:element_75", - "id" : -86 - }, - { - "name" : "minecraft:diamond_boots", - "id" : 313 - }, - { - "name" : "minecraft:acacia_button", - "id" : -140 - }, - { - "name" : "minecraft:standing_banner", - "id" : 176 - }, - { - "name" : "minecraft:golden_helmet", - "id" : 314 - }, - { - "name" : "minecraft:golden_chestplate", - "id" : 315 - }, - { - "name" : "minecraft:golden_leggings", - "id" : 316 - }, - { - "name" : "minecraft:golden_boots", - "id" : 317 - }, - { - "name" : "minecraft:item.hopper", - "id" : 154 - }, - { - "name" : "minecraft:shield", - "id" : 513 - }, - { - "name" : "minecraft:flint", - "id" : 318 - }, - { - "name" : "minecraft:painting", - "id" : 321 - }, - { - "name" : "minecraft:sign", - "id" : 323 - }, - { - "name" : "minecraft:wooden_door", - "id" : 324 - }, - { - "name" : "minecraft:bucket", - "id" : 325 - }, - { - "name" : "minecraft:minecart", - "id" : 328 - }, - { - "name" : "minecraft:prismarine_stairs", - "id" : -2 - }, - { - "name" : "minecraft:iron_door", - "id" : 330 - }, - { - "name" : "minecraft:tripwire_hook", - "id" : 131 - }, - { - "name" : "minecraft:redstone", - "id" : 331 - }, - { - "name" : "minecraft:andesite_stairs", - "id" : -171 - }, - { - "name" : "minecraft:sponge", - "id" : 19 - }, - { - "name" : "minecraft:snowball", - "id" : 332 - }, - { - "name" : "minecraft:boat", - "id" : 333 - }, - { - "name" : "minecraft:item.dark_oak_door", - "id" : 197 - }, - { - "name" : "minecraft:kelp", - "id" : 335 - }, - { - "name" : "minecraft:brick", - "id" : 336 - }, - { - "name" : "minecraft:clay_ball", - "id" : 337 - }, - { - "name" : "minecraft:real_double_stone_slab", - "id" : 43 - }, - { - "name" : "minecraft:reeds", - "id" : 338 - }, - { - "name" : "minecraft:dirt", - "id" : 3 - }, - { - "name" : "minecraft:magma", - "id" : 213 - }, - { - "name" : "minecraft:red_mushroom", - "id" : 40 - }, - { - "name" : "minecraft:paper", - "id" : 339 - }, - { - "name" : "minecraft:book", - "id" : 340 - }, - { - "name" : "minecraft:chest_minecart", - "id" : 342 - }, - { - "name" : "minecraft:flowing_lava", - "id" : 10 - }, - { - "name" : "minecraft:element_86", - "id" : -97 - }, - { - "name" : "minecraft:red_glazed_terracotta", - "id" : 234 - }, - { - "name" : "minecraft:crafting_table", - "id" : 58 - }, - { - "name" : "minecraft:egg", - "id" : 344 - }, - { - "name" : "minecraft:real_double_stone_slab4", - "id" : -168 - }, - { - "name" : "minecraft:end_gateway", - "id" : 209 - }, - { - "name" : "minecraft:compass", - "id" : 345 - }, - { - "name" : "minecraft:horsearmordiamond", - "id" : 419 - }, - { - "name" : "minecraft:sapling", - "id" : 6 - }, - { - "name" : "minecraft:fishing_rod", - "id" : 346 - }, - { - "name" : "minecraft:name_tag", - "id" : 421 - }, - { - "name" : "minecraft:clock", - "id" : 347 - }, - { - "name" : "minecraft:element_96", - "id" : -107 - }, - { - "name" : "minecraft:dye", - "id" : 351 - }, - { - "name" : "minecraft:anvil", - "id" : 145 - }, - { - "name" : "minecraft:conduit", - "id" : -157 - }, - { - "name" : "minecraft:bone", - "id" : 352 - }, - { - "name" : "minecraft:soul_sand", - "id" : 88 - }, - { - "name" : "minecraft:sugar", - "id" : 353 - }, - { - "name" : "minecraft:cake", - "id" : 354 - }, - { - "name" : "minecraft:element_113", - "id" : -124 - }, - { - "name" : "minecraft:mossy_cobblestone", - "id" : 48 - }, - { - "name" : "minecraft:bed", - "id" : 355 - }, - { - "name" : "minecraft:flowing_water", - "id" : 8 - }, - { - "name" : "minecraft:item.frame", - "id" : 199 - }, - { - "name" : "minecraft:repeater", - "id" : 356 - }, - { - "name" : "minecraft:map", - "id" : 358 - }, - { - "name" : "minecraft:shears", - "id" : 359 - }, - { - "name" : "minecraft:double_stone_slab2", - "id" : 182 - }, - { - "name" : "minecraft:element_3", - "id" : -14 - }, - { - "name" : "minecraft:element_23", - "id" : -34 - }, - { - "name" : "minecraft:skull", - "id" : 397 - }, - { - "name" : "minecraft:ender_pearl", - "id" : 368 - }, - { - "name" : "minecraft:carved_pumpkin", - "id" : -155 - }, - { - "name" : "minecraft:yellow_flower", - "id" : 37 - }, - { - "name" : "minecraft:shulker_box", - "id" : 218 - }, - { - "name" : "minecraft:blaze_rod", - "id" : 369 - }, - { - "name" : "minecraft:lit_pumpkin", - "id" : 91 - }, - { - "name" : "minecraft:ghast_tear", - "id" : 370 - }, - { - "name" : "minecraft:gold_nugget", - "id" : 371 - }, - { - "name" : "minecraft:glass_bottle", - "id" : 374 - }, - { - "name" : "minecraft:emptymap", - "id" : 395 - }, - { - "name" : "minecraft:fermented_spider_eye", - "id" : 376 - }, - { - "name" : "minecraft:element_81", - "id" : -92 - }, - { - "name" : "minecraft:monster_egg", - "id" : 97 - }, - { - "name" : "minecraft:blaze_powder", - "id" : 377 - }, - { - "name" : "minecraft:armor_stand", - "id" : 425 - }, - { - "name" : "minecraft:magma_cream", - "id" : 378 - }, - { - "name" : "minecraft:brewing_stand", - "id" : 379 - }, - { - "name" : "minecraft:darkoak_standing_sign", - "id" : -192 - }, - { - "name" : "minecraft:glowingobsidian", - "id" : 246 - }, - { - "name" : "minecraft:cauldron", - "id" : 380 - }, - { - "name" : "minecraft:nether_brick", - "id" : 112 - }, - { - "name" : "minecraft:ender_eye", - "id" : 381 - }, - { - "name" : "minecraft:experience_bottle", - "id" : 384 - }, - { - "name" : "minecraft:speckled_melon", - "id" : 382 - }, - { - "name" : "minecraft:coral", - "id" : -131 - }, - { - "name" : "minecraft:fireball", - "id" : 385 - }, - { - "name" : "minecraft:writable_book", - "id" : 386 - }, - { - "name" : "minecraft:frame", - "id" : 389 - }, - { - "name" : "minecraft:smoker", - "id" : -198 - }, - { - "name" : "minecraft:flower_pot", - "id" : 390 - }, - { - "name" : "minecraft:carrotonastick", - "id" : 398 - }, - { - "name" : "minecraft:netherstar", - "id" : 399 - }, - { - "name" : "minecraft:element_16", - "id" : -27 - }, - { - "name" : "minecraft:fireworks", - "id" : 401 - }, - { - "name" : "minecraft:element_30", - "id" : -41 - }, - { - "name" : "minecraft:fireworkscharge", - "id" : 402 - }, - { - "name" : "minecraft:trident", - "id" : 455 - }, - { - "name" : "minecraft:enchanted_book", - "id" : 403 - }, - { - "name" : "minecraft:comparator", - "id" : 404 - }, - { - "name" : "minecraft:netherbrick", - "id" : 405 - }, - { - "name" : "minecraft:concrete", - "id" : 236 - }, - { - "name" : "minecraft:element_73", - "id" : -84 - }, - { - "name" : "minecraft:quartz", - "id" : 406 - }, - { - "name" : "minecraft:tnt_minecart", - "id" : 407 - }, - { - "name" : "minecraft:leaves2", - "id" : 161 - }, - { - "name" : "minecraft:element_102", - "id" : -113 - }, - { - "name" : "minecraft:coral_fan_hang2", - "id" : -136 - }, - { - "name" : "minecraft:element_67", - "id" : -78 - }, - { - "name" : "minecraft:hopper_minecart", - "id" : 408 - }, - { - "name" : "minecraft:lead", - "id" : 420 - }, - { - "name" : "minecraft:sea_pickle", - "id" : -156 - }, - { - "name" : "minecraft:hopper", - "id" : 410 - }, - { - "name" : "minecraft:rabbit_foot", - "id" : 414 - }, - { - "name" : "minecraft:rabbit_hide", - "id" : 415 - }, - { - "name" : "minecraft:acacia_standing_sign", - "id" : -190 - }, - { - "name" : "minecraft:horsearmorleather", - "id" : 416 - }, - { - "name" : "minecraft:item.wheat", - "id" : 59 - }, - { - "name" : "minecraft:horsearmoriron", - "id" : 417 - }, - { - "name" : "minecraft:record_13", - "id" : 500 - }, - { - "name" : "minecraft:stone_button", - "id" : 77 - }, - { - "name" : "minecraft:record_cat", - "id" : 501 - }, - { - "name" : "minecraft:element_89", - "id" : -100 - }, - { - "name" : "minecraft:record_blocks", - "id" : 502 - }, - { - "name" : "minecraft:bamboo", - "id" : -163 - }, - { - "name" : "minecraft:element_72", - "id" : -83 - }, - { - "name" : "minecraft:record_chirp", - "id" : 503 - }, - { - "name" : "minecraft:frosted_ice", - "id" : 207 - }, - { - "name" : "minecraft:record_far", - "id" : 504 - }, - { - "name" : "minecraft:record_wait", - "id" : 511 - }, - { - "name" : "minecraft:spruce_door", - "id" : 427 - }, - { - "name" : "minecraft:record_mellohi", - "id" : 506 - }, - { - "name" : "minecraft:vine", - "id" : 106 - }, - { - "name" : "minecraft:record_ward", - "id" : 509 - }, - { - "name" : "minecraft:jungle_stairs", - "id" : 136 - }, - { - "name" : "minecraft:ice_bomb", - "id" : 453 - }, - { - "name" : "minecraft:record_11", - "id" : 510 - }, - { - "name" : "minecraft:prismarine_crystals", - "id" : 422 - }, - { - "name" : "minecraft:banner", - "id" : 446 - }, - { - "name" : "minecraft:glass_pane", - "id" : 102 - }, - { - "name" : "minecraft:muttonraw", - "id" : 423 - }, - { - "name" : "minecraft:end_crystal", - "id" : 426 - }, - { - "name" : "minecraft:element_55", - "id" : -66 - }, - { - "name" : "minecraft:birch_door", - "id" : 428 - }, - { - "name" : "minecraft:darkoak_wall_sign", - "id" : -193 - }, - { - "name" : "minecraft:jungle_door", - "id" : 429 - }, - { - "name" : "minecraft:acacia_door", - "id" : 430 - }, - { - "name" : "minecraft:element_116", - "id" : -127 - }, - { - "name" : "minecraft:chorus_fruit", - "id" : 432 - }, - { - "name" : "minecraft:cobblestone_wall", - "id" : 139 - }, - { - "name" : "minecraft:cobblestone", - "id" : 4 - }, - { - "name" : "minecraft:dragon_breath", - "id" : 437 - }, - { - "name" : "minecraft:cactus", - "id" : 81 - }, - { - "name" : "minecraft:splash_potion", - "id" : 438 - }, - { - "name" : "minecraft:spruce_stairs", - "id" : 134 - }, - { - "name" : "minecraft:loom", - "id" : -204 - }, - { - "name" : "minecraft:powered_repeater", - "id" : 94 - }, - { - "name" : "minecraft:lingering_potion", - "id" : 441 - }, - { - "name" : "minecraft:elytra", - "id" : 444 - }, - { - "name" : "minecraft:prismarine_shard", - "id" : 409 - }, - { - "name" : "minecraft:element_112", - "id" : -123 - }, - { - "name" : "minecraft:totem", - "id" : 450 - }, - { - "name" : "minecraft:iron_nugget", - "id" : 452 - }, - { - "name" : "minecraft:pumpkin_stem", - "id" : 104 - }, - { - "name" : "minecraft:element_50", - "id" : -61 - }, - { - "name" : "minecraft:lever", - "id" : 69 - }, - { - "name" : "minecraft:heart_of_the_sea", - "id" : 467 - }, - { - "name" : "minecraft:element_92", - "id" : -103 - }, - { - "name" : "minecraft:grass", - "id" : 2 - }, - { - "name" : "minecraft:turtle_helmet", - "id" : 469 - }, - { - "name" : "minecraft:wall_banner", - "id" : 177 - }, - { - "name" : "minecraft:spruce_button", - "id" : -144 - }, - { - "name" : "minecraft:phantom_membrane", - "id" : 470 - }, - { - "name" : "minecraft:crossbow", - "id" : 471 - }, - { - "name" : "minecraft:spruce_sign", - "id" : 472 - }, - { - "name" : "minecraft:quartz_stairs", - "id" : 156 - }, - { - "name" : "minecraft:daylight_detector_inverted", - "id" : 178 - }, - { - "name" : "minecraft:jungle_sign", - "id" : 474 - }, - { - "name" : "minecraft:red_flower", - "id" : 38 - }, - { - "name" : "minecraft:tallgrass", - "id" : 31 - }, - { - "name" : "minecraft:banner_pattern", - "id" : 434 - }, - { - "name" : "minecraft:suspicious_stew", - "id" : 734 - }, - { - "name" : "minecraft:birch_fence_gate", - "id" : 184 - }, - { - "name" : "minecraft:honeycomb", - "id" : 736 - }, - { - "name" : "minecraft:element_115", - "id" : -126 - }, - { - "name" : "minecraft:honey_bottle", - "id" : 737 - }, - { - "name" : "minecraft:element_4", - "id" : -15 - }, - { - "name" : "minecraft:element_24", - "id" : -35 - }, - { - "name" : "minecraft:camera", - "id" : 498 - }, - { - "name" : "minecraft:compound", - "id" : 499 - }, - { - "name" : "minecraft:bleach", - "id" : 451 - }, - { - "name" : "minecraft:element_40", - "id" : -51 - }, - { - "name" : "minecraft:honey_block", - "id" : -220 - }, - { - "name" : "minecraft:rapid_fertilizer", - "id" : 449 - }, - { - "name" : "minecraft:balloon", - "id" : 448 - }, - { - "name" : "minecraft:redstone_ore", - "id" : 73 - }, - { - "name" : "minecraft:stonecutter_block", - "id" : -197 - }, - { - "name" : "minecraft:medicine", - "id" : 447 - }, - { - "name" : "minecraft:gold_block", - "id" : 41 - }, - { - "name" : "minecraft:stripped_oak_log", - "id" : -10 - }, - { - "name" : "minecraft:blue_ice", - "id" : -11 - }, - { - "name" : "minecraft:sparkler", - "id" : 442 - }, - { - "name" : "minecraft:stone", - "id" : 1 - }, - { - "name" : "minecraft:sand", - "id" : 12 - }, - { - "name" : "minecraft:stained_hardened_clay", - "id" : 159 - }, - { - "name" : "minecraft:wool", - "id" : 35 - }, - { - "name" : "minecraft:unpowered_comparator", - "id" : 149 - }, - { - "name" : "minecraft:log", - "id" : 17 - }, - { - "name" : "minecraft:item.kelp", - "id" : -138 - }, - { - "name" : "minecraft:coral_block", - "id" : -132 - }, - { - "name" : "minecraft:element_54", - "id" : -65 - }, - { - "name" : "minecraft:double_stone_slab", - "id" : 44 - }, - { - "name" : "minecraft:double_stone_slab3", - "id" : -162 - }, - { - "name" : "minecraft:element_2", - "id" : -13 - }, - { - "name" : "minecraft:element_22", - "id" : -33 - }, - { - "name" : "minecraft:real_double_stone_slab2", - "id" : 181 - }, - { - "name" : "minecraft:real_double_stone_slab3", - "id" : -167 - }, - { - "name" : "minecraft:coral_fan", - "id" : -133 - }, - { - "name" : "minecraft:leaves", - "id" : 18 - }, - { - "name" : "minecraft:element_10", - "id" : -21 - }, - { - "name" : "minecraft:birch_button", - "id" : -141 - }, - { - "name" : "minecraft:sandstone", - "id" : 24 - }, - { - "name" : "minecraft:red_sandstone", - "id" : 179 - }, - { - "name" : "minecraft:element_91", - "id" : -102 - }, - { - "name" : "minecraft:wooden_slab", - "id" : 158 - }, - { - "name" : "minecraft:end_stone", - "id" : 121 - }, - { - "name" : "minecraft:double_plant", - "id" : 175 - }, - { - "name" : "minecraft:waterlily", - "id" : 111 - }, - { - "name" : "minecraft:snow_layer", - "id" : 78 - }, - { - "name" : "minecraft:black_glazed_terracotta", - "id" : 235 - }, - { - "name" : "minecraft:planks", - "id" : 5 - }, - { - "name" : "minecraft:quartz_block", - "id" : 155 - }, - { - "name" : "minecraft:seagrass", - "id" : -130 - }, - { - "name" : "minecraft:brown_mushroom_block", - "id" : 99 - }, - { - "name" : "minecraft:log2", - "id" : 162 - }, - { - "name" : "minecraft:end_portal_frame", - "id" : 120 - }, - { - "name" : "minecraft:lantern", - "id" : -208 - }, - { - "name" : "minecraft:prismarine", - "id" : 168 - }, - { - "name" : "minecraft:sealantern", - "id" : 169 - }, - { - "name" : "minecraft:hard_stained_glass", - "id" : 254 - }, - { - "name" : "minecraft:concrete_powder", - "id" : 237 - }, - { - "name" : "minecraft:stained_glass", - "id" : 241 - }, - { - "name" : "minecraft:element_82", - "id" : -93 - }, - { - "name" : "minecraft:stained_glass_pane", - "id" : 160 - }, - { - "name" : "minecraft:quartz_ore", - "id" : 153 - }, - { - "name" : "minecraft:undyed_shulker_box", - "id" : 205 - }, - { - "name" : "minecraft:element_107", - "id" : -118 - }, - { - "name" : "minecraft:piston", - "id" : 33 - }, - { - "name" : "minecraft:sticky_piston", - "id" : 29 - }, - { - "name" : "minecraft:turtle_egg", - "id" : -159 - }, - { - "name" : "minecraft:acacia_fence_gate", - "id" : 187 - }, - { - "name" : "minecraft:colored_torch_bp", - "id" : 204 - }, - { - "name" : "minecraft:lava", - "id" : 11 - }, - { - "name" : "minecraft:scaffolding", - "id" : -165 - }, - { - "name" : "minecraft:blast_furnace", - "id" : -196 - }, - { - "name" : "minecraft:item.cauldron", - "id" : 118 - }, - { - "name" : "minecraft:barrel", - "id" : -203 - }, - { - "name" : "minecraft:bell", - "id" : -206 - }, - { - "name" : "minecraft:element_42", - "id" : -53 - }, - { - "name" : "minecraft:cartography_table", - "id" : -200 - }, - { - "name" : "minecraft:end_rod", - "id" : 208 - }, - { - "name" : "minecraft:fletching_table", - "id" : -201 - }, - { - "name" : "minecraft:wood", - "id" : -212 - }, - { - "name" : "minecraft:chemistry_table", - "id" : 238 - }, - { - "name" : "minecraft:element_70", - "id" : -81 - }, - { - "name" : "minecraft:tnt", - "id" : 46 - }, - { - "name" : "minecraft:hard_stained_glass_pane", - "id" : 191 - }, - { - "name" : "minecraft:colored_torch_rg", - "id" : 202 - }, - { - "name" : "minecraft:brown_mushroom", - "id" : 39 - }, - { - "name" : "minecraft:element_0", - "id" : 36 - }, - { - "name" : "minecraft:element_20", - "id" : -31 - }, - { - "name" : "minecraft:element_1", - "id" : -12 - }, - { - "name" : "minecraft:element_21", - "id" : -32 - }, - { - "name" : "minecraft:element_6", - "id" : -17 - }, - { - "name" : "minecraft:element_26", - "id" : -37 - }, - { - "name" : "minecraft:element_7", - "id" : -18 - }, - { - "name" : "minecraft:element_27", - "id" : -38 - }, - { - "name" : "minecraft:element_8", - "id" : -19 - }, - { - "name" : "minecraft:element_28", - "id" : -39 - }, - { - "name" : "minecraft:dark_oak_pressure_plate", - "id" : -152 - }, - { - "name" : "minecraft:element_9", - "id" : -20 - }, - { - "name" : "minecraft:element_29", - "id" : -40 - }, - { - "name" : "minecraft:item.spruce_door", - "id" : 193 - }, - { - "name" : "minecraft:element_12", - "id" : -23 - }, - { - "name" : "minecraft:cyan_glazed_terracotta", - "id" : 229 - }, - { - "name" : "minecraft:element_13", - "id" : -24 - }, - { - "name" : "minecraft:element_14", - "id" : -25 - }, - { - "name" : "minecraft:iron_ore", - "id" : 15 - }, - { - "name" : "minecraft:element_17", - "id" : -28 - }, - { - "name" : "minecraft:element_18", - "id" : -29 - }, - { - "name" : "minecraft:birch_pressure_plate", - "id" : -151 - }, - { - "name" : "minecraft:element_19", - "id" : -30 - }, - { - "name" : "minecraft:wooden_pressure_plate", - "id" : 72 - }, - { - "name" : "minecraft:element_33", - "id" : -44 - }, - { - "name" : "minecraft:element_34", - "id" : -45 - }, - { - "name" : "minecraft:element_35", - "id" : -46 - }, - { - "name" : "minecraft:composter", - "id" : -213 - }, - { - "name" : "minecraft:element_36", - "id" : -47 - }, - { - "name" : "minecraft:element_37", - "id" : -48 - }, - { - "name" : "minecraft:element_39", - "id" : -50 - }, - { - "name" : "minecraft:element_41", - "id" : -52 - }, - { - "name" : "minecraft:hay_block", - "id" : 170 - }, - { - "name" : "minecraft:element_43", - "id" : -54 - }, - { - "name" : "minecraft:lit_redstone_lamp", - "id" : 124 - }, - { - "name" : "minecraft:element_44", - "id" : -55 - }, - { - "name" : "minecraft:element_45", - "id" : -56 - }, - { - "name" : "minecraft:element_49", - "id" : -60 - }, - { - "name" : "minecraft:element_51", - "id" : -62 - }, - { - "name" : "minecraft:element_56", - "id" : -67 - }, - { - "name" : "minecraft:element_57", - "id" : -68 - }, - { - "name" : "minecraft:element_59", - "id" : -70 - }, - { - "name" : "minecraft:element_60", - "id" : -71 - }, - { - "name" : "minecraft:dropper", - "id" : 125 - }, - { - "name" : "minecraft:element_61", - "id" : -72 - }, - { - "name" : "minecraft:element_63", - "id" : -74 - }, - { - "name" : "minecraft:element_64", - "id" : -75 - }, - { - "name" : "minecraft:element_65", - "id" : -76 - }, - { - "name" : "minecraft:coral_fan_hang3", - "id" : -137 - }, - { - "name" : "minecraft:element_66", - "id" : -77 - }, - { - "name" : "minecraft:redstone_lamp", - "id" : 123 - }, - { - "name" : "minecraft:element_68", - "id" : -79 - }, - { - "name" : "minecraft:spruce_trapdoor", - "id" : -149 - }, - { - "name" : "minecraft:purple_glazed_terracotta", - "id" : 219 - }, - { - "name" : "minecraft:element_69", - "id" : -80 - }, - { - "name" : "minecraft:iron_block", - "id" : 42 - }, - { - "name" : "minecraft:element_71", - "id" : -82 - }, - { - "name" : "minecraft:element_76", - "id" : -87 - }, - { - "name" : "minecraft:element_77", - "id" : -88 - }, - { - "name" : "minecraft:water", - "id" : 9 - }, - { - "name" : "minecraft:element_78", - "id" : -89 - }, - { - "name" : "minecraft:element_79", - "id" : -90 - }, - { - "name" : "minecraft:element_80", - "id" : -91 - }, - { - "name" : "minecraft:netherreactor", - "id" : 247 - }, - { - "name" : "minecraft:element_83", - "id" : -94 - }, - { - "name" : "minecraft:element_84", - "id" : -95 - }, - { - "name" : "minecraft:jungle_wall_sign", - "id" : -189 - }, - { - "name" : "minecraft:end_brick_stairs", - "id" : -178 - }, - { - "name" : "minecraft:element_85", - "id" : -96 - }, - { - "name" : "minecraft:element_88", - "id" : -99 - }, - { - "name" : "minecraft:element_90", - "id" : -101 - }, - { - "name" : "minecraft:birch_standing_sign", - "id" : -186 - }, - { - "name" : "minecraft:gold_ore", - "id" : 14 - }, - { - "name" : "minecraft:element_93", - "id" : -104 - }, - { - "name" : "minecraft:element_94", - "id" : -105 - }, - { - "name" : "minecraft:element_95", - "id" : -106 - }, - { - "name" : "minecraft:glass", - "id" : 20 - }, - { - "name" : "minecraft:red_nether_brick", - "id" : 215 - }, - { - "name" : "minecraft:element_98", - "id" : -109 - }, - { - "name" : "minecraft:element_99", - "id" : -110 - }, - { - "name" : "minecraft:element_100", - "id" : -111 - }, - { - "name" : "minecraft:element_101", - "id" : -112 - }, - { - "name" : "minecraft:element_103", - "id" : -114 - }, - { - "name" : "minecraft:element_106", - "id" : -117 - }, - { - "name" : "minecraft:element_108", - "id" : -119 - }, - { - "name" : "minecraft:element_109", - "id" : -120 - }, - { - "name" : "minecraft:element_110", - "id" : -121 - }, - { - "name" : "minecraft:element_111", - "id" : -122 - }, - { - "name" : "minecraft:element_114", - "id" : -125 - }, - { - "name" : "minecraft:element_117", - "id" : -128 - }, - { - "name" : "minecraft:slime", - "id" : 165 - }, - { - "name" : "minecraft:spruce_standing_sign", - "id" : -181 - }, - { - "name" : "minecraft:element_118", - "id" : -129 - }, - { - "name" : "minecraft:gravel", - "id" : 13 - }, - { - "name" : "minecraft:detector_rail", - "id" : 28 - }, - { - "name" : "minecraft:oak_stairs", - "id" : 53 - }, - { - "name" : "minecraft:coal_ore", - "id" : 16 - }, - { - "name" : "minecraft:diamond_block", - "id" : 57 - }, - { - "name" : "minecraft:item.cake", - "id" : 92 - }, - { - "name" : "minecraft:spruce_pressure_plate", - "id" : -154 - }, - { - "name" : "minecraft:diamond_ore", - "id" : 56 - }, - { - "name" : "minecraft:furnace", - "id" : 61 - }, - { - "name" : "minecraft:underwater_torch", - "id" : 239 - }, - { - "name" : "minecraft:web", - "id" : 30 - }, - { - "name" : "minecraft:jungle_standing_sign", - "id" : -188 - }, - { - "name" : "minecraft:standing_sign", - "id" : 63 - }, - { - "name" : "minecraft:lapis_ore", - "id" : 21 - }, - { - "name" : "minecraft:beehive", - "id" : -219 - }, - { - "name" : "minecraft:item.bed", - "id" : 26 - }, - { - "name" : "minecraft:lapis_block", - "id" : 22 - }, - { - "name" : "minecraft:stripped_acacia_log", - "id" : -8 - }, - { - "name" : "minecraft:dispenser", - "id" : 23 - }, - { - "name" : "minecraft:obsidian", - "id" : 49 - }, - { - "name" : "minecraft:brick_block", - "id" : 45 - }, - { - "name" : "minecraft:dried_kelp_block", - "id" : -139 - }, - { - "name" : "minecraft:structure_block", - "id" : 252 - }, - { - "name" : "minecraft:pistonarmcollision", - "id" : 34 - }, - { - "name" : "minecraft:green_glazed_terracotta", - "id" : 233 - }, - { - "name" : "minecraft:acacia_trapdoor", - "id" : -145 - }, - { - "name" : "minecraft:carrots", - "id" : 141 - }, - { - "name" : "minecraft:rail", - "id" : 66 - }, - { - "name" : "minecraft:torch", - "id" : 50 - }, - { - "name" : "minecraft:mob_spawner", - "id" : 52 - }, - { - "name" : "minecraft:lava_cauldron", - "id" : -210 - }, - { - "name" : "minecraft:redstone_wire", - "id" : 55 - }, - { - "name" : "minecraft:farmland", - "id" : 60 - }, - { - "name" : "minecraft:wall_sign", - "id" : 68 - }, - { - "name" : "minecraft:stone_pressure_plate", - "id" : 70 - }, - { - "name" : "minecraft:red_sandstone_stairs", - "id" : 180 - }, - { - "name" : "minecraft:item.iron_door", - "id" : 71 - }, - { - "name" : "minecraft:lit_redstone_ore", - "id" : 74 - }, - { - "name" : "minecraft:stripped_jungle_log", - "id" : -7 - }, - { - "name" : "minecraft:unlit_redstone_torch", - "id" : 75 - }, - { - "name" : "minecraft:red_nether_brick_stairs", - "id" : -184 - }, - { - "name" : "minecraft:redstone_torch", - "id" : 76 - }, - { - "name" : "minecraft:ice", - "id" : 79 - }, - { - "name" : "minecraft:snow", - "id" : 80 - }, - { - "name" : "minecraft:command_block", - "id" : 137 - }, - { - "name" : "minecraft:clay", - "id" : 82 - }, - { - "name" : "minecraft:jukebox", - "id" : 84 - }, - { - "name" : "minecraft:pumpkin", - "id" : 86 - }, - { - "name" : "minecraft:item.acacia_door", - "id" : 196 - }, - { - "name" : "minecraft:nether_brick_stairs", - "id" : 114 - }, - { - "name" : "minecraft:netherrack", - "id" : 87 - }, - { - "name" : "minecraft:glowstone", - "id" : 89 - }, - { - "name" : "minecraft:hard_glass", - "id" : 253 - }, - { - "name" : "minecraft:portal", - "id" : 90 - }, - { - "name" : "minecraft:item.beetroot", - "id" : 244 - }, - { - "name" : "minecraft:unpowered_repeater", - "id" : 93 - }, - { - "name" : "minecraft:invisiblebedrock", - "id" : 95 - }, - { - "name" : "minecraft:trapdoor", - "id" : 96 - }, - { - "name" : "minecraft:item.jungle_door", - "id" : 195 - }, - { - "name" : "minecraft:iron_bars", - "id" : 101 - }, - { - "name" : "minecraft:chain_command_block", - "id" : 189 - }, - { - "name" : "minecraft:melon_block", - "id" : 103 - }, - { - "name" : "minecraft:emerald_block", - "id" : 133 - }, - { - "name" : "minecraft:chemical_heat", - "id" : 192 - }, - { - "name" : "minecraft:melon_stem", - "id" : 105 - }, - { - "name" : "minecraft:fence_gate", - "id" : 107 - }, - { - "name" : "minecraft:brick_stairs", - "id" : 108 - }, - { - "name" : "minecraft:stone_brick_stairs", - "id" : 109 - }, - { - "name" : "minecraft:mycelium", - "id" : 110 - }, - { - "name" : "minecraft:smooth_stone", - "id" : -183 - }, - { - "name" : "minecraft:nether_brick_fence", - "id" : 113 - }, - { - "name" : "minecraft:item.nether_wart", - "id" : 115 - }, - { - "name" : "minecraft:enchanting_table", - "id" : 116 - }, - { - "name" : "minecraft:end_portal", - "id" : 119 - }, - { - "name" : "minecraft:dragon_egg", - "id" : 122 - }, - { - "name" : "minecraft:granite_stairs", - "id" : -169 - }, - { - "name" : "minecraft:podzol", - "id" : 243 - }, - { - "name" : "minecraft:activator_rail", - "id" : 126 - }, - { - "name" : "minecraft:cocoa", - "id" : 127 - }, - { - "name" : "minecraft:emerald_ore", - "id" : 129 - }, - { - "name" : "minecraft:brown_glazed_terracotta", - "id" : 232 - }, - { - "name" : "minecraft:pink_glazed_terracotta", - "id" : 226 - }, - { - "name" : "minecraft:observer", - "id" : 251 - }, - { - "name" : "minecraft:info_update", - "id" : 248 - }, - { - "name" : "minecraft:birch_stairs", - "id" : 135 - }, - { - "name" : "minecraft:coral_fan_hang", - "id" : -135 - }, - { - "name" : "minecraft:packed_ice", - "id" : 174 - }, - { - "name" : "minecraft:item.flower_pot", - "id" : 140 - }, - { - "name" : "minecraft:potatoes", - "id" : 142 - }, - { - "name" : "minecraft:wooden_button", - "id" : 143 - }, - { - "name" : "minecraft:item.skull", - "id" : 144 - }, - { - "name" : "minecraft:trapped_chest", - "id" : 146 - }, - { - "name" : "minecraft:light_weighted_pressure_plate", - "id" : 147 - }, - { - "name" : "minecraft:heavy_weighted_pressure_plate", - "id" : 148 - }, - { - "name" : "minecraft:daylight_detector", - "id" : 151 - }, - { - "name" : "minecraft:smooth_sandstone_stairs", - "id" : -177 - }, - { - "name" : "minecraft:repeating_command_block", - "id" : 188 - }, - { - "name" : "minecraft:double_wooden_slab", - "id" : 157 - }, - { - "name" : "minecraft:dark_oak_stairs", - "id" : 164 - }, - { - "name" : "minecraft:iron_trapdoor", - "id" : 167 - }, - { - "name" : "minecraft:hardened_clay", - "id" : 172 - }, - { - "name" : "minecraft:coal_block", - "id" : 173 - }, - { - "name" : "minecraft:purpur_stairs", - "id" : 203 - }, - { - "name" : "minecraft:jungle_fence_gate", - "id" : 185 - }, - { - "name" : "minecraft:dark_oak_fence_gate", - "id" : 186 - }, - { - "name" : "minecraft:grass_path", - "id" : 198 - }, - { - "name" : "minecraft:bone_block", - "id" : 216 - }, - { - "name" : "minecraft:normal_stone_stairs", - "id" : -180 - }, - { - "name" : "minecraft:chorus_flower", - "id" : 200 - }, - { - "name" : "minecraft:jungle_pressure_plate", - "id" : -153 - }, - { - "name" : "minecraft:end_bricks", - "id" : 206 - }, - { - "name" : "minecraft:blue_glazed_terracotta", - "id" : 231 - }, - { - "name" : "minecraft:movingblock", - "id" : 250 - }, - { - "name" : "minecraft:light_blue_glazed_terracotta", - "id" : 223 - }, - { - "name" : "minecraft:nether_wart_block", - "id" : 214 - }, - { - "name" : "minecraft:white_glazed_terracotta", - "id" : 220 - }, - { - "name" : "minecraft:orange_glazed_terracotta", - "id" : 221 - }, - { - "name" : "minecraft:magenta_glazed_terracotta", - "id" : 222 - }, - { - "name" : "minecraft:yellow_glazed_terracotta", - "id" : 224 - }, - { - "name" : "minecraft:barrier", - "id" : -161 - }, - { - "name" : "minecraft:gray_glazed_terracotta", - "id" : 227 - }, - { - "name" : "minecraft:silver_glazed_terracotta", - "id" : 228 - }, - { - "name" : "minecraft:chorus_plant", - "id" : 240 - }, - { - "name" : "minecraft:fire", - "id" : 51 - }, - { - "name" : "minecraft:item.camera", - "id" : 242 - }, - { - "name" : "minecraft:stonecutter", - "id" : 245 - }, - { - "name" : "minecraft:reserved6", - "id" : 255 - }, - { - "name" : "minecraft:dark_prismarine_stairs", - "id" : -3 - }, - { - "name" : "minecraft:prismarine_bricks_stairs", - "id" : -4 - }, - { - "name" : "minecraft:stripped_spruce_log", - "id" : -5 - }, - { - "name" : "minecraft:stripped_dark_oak_log", - "id" : -9 - }, - { - "name" : "minecraft:hard_glass_pane", - "id" : 190 - }, - { - "name" : "minecraft:mossy_cobblestone_stairs", - "id" : -179 - }, - { - "name" : "minecraft:smooth_red_sandstone_stairs", - "id" : -176 - }, - { - "name" : "minecraft:bamboo_sapling", - "id" : -164 - }, - { - "name" : "minecraft:jungle_button", - "id" : -143 - }, - { - "name" : "minecraft:birch_wall_sign", - "id" : -187 - }, - { - "name" : "minecraft:spruce_wall_sign", - "id" : -182 - }, - { - "name" : "minecraft:jungle_trapdoor", - "id" : -148 - }, - { - "name" : "minecraft:dark_oak_button", - "id" : -142 - }, - { - "name" : "minecraft:birch_trapdoor", - "id" : -146 - }, - { - "name" : "minecraft:jigsaw", - "id" : -211 - }, - { - "name" : "minecraft:acacia_pressure_plate", - "id" : -150 - }, - { - "name" : "minecraft:bubble_column", - "id" : -160 - }, - { - "name" : "minecraft:polished_diorite_stairs", - "id" : -173 - }, - { - "name" : "minecraft:smooth_quartz_stairs", - "id" : -185 - }, - { - "name" : "minecraft:acacia_wall_sign", - "id" : -191 - }, - { - "name" : "minecraft:lit_smoker", - "id" : -199 - }, - { - "name" : "minecraft:item.campfire", - "id" : -209 - }, - { - "name" : "minecraft:bee_nest", - "id" : -218 - }, - { - "name" : "minecraft:honeycomb_block", - "id" : -221 - } + { + "name" : "minecraft:purpur_block", + "id" : 201 + }, + { + "name" : "minecraft:bow", + "id" : 261 + }, + { + "name" : "minecraft:end_bricks", + "id" : 206 + }, + { + "name" : "minecraft:air", + "id" : -158 + }, + { + "name" : "minecraft:element_94", + "id" : -105 + }, + { + "name" : "minecraft:rabbit", + "id" : 411 + }, + { + "name" : "minecraft:element_25", + "id" : -36 + }, + { + "name" : "minecraft:mushroom_stew", + "id" : 282 + }, + { + "name" : "minecraft:polished_blackstone_brick_slab", + "id" : -284 + }, + { + "name" : "minecraft:cooked_porkchop", + "id" : 320 + }, + { + "name" : "minecraft:record_ward", + "id" : 509 + }, + { + "name" : "minecraft:appleenchanted", + "id" : 466 + }, + { + "name" : "minecraft:pumpkin", + "id" : 86 + }, + { + "name" : "minecraft:slime", + "id" : 165 + }, + { + "name" : "minecraft:apple", + "id" : 260 + }, + { + "name" : "minecraft:element_50", + "id" : -61 + }, + { + "name" : "minecraft:stripped_oak_log", + "id" : -10 + }, + { + "name" : "minecraft:golden_apple", + "id" : 322 + }, + { + "name" : "minecraft:fish", + "id" : 349 + }, + { + "name" : "minecraft:item.dark_oak_door", + "id" : 197 + }, + { + "name" : "minecraft:light_block", + "id" : -215 + }, + { + "name" : "minecraft:yellow_glazed_terracotta", + "id" : 224 + }, + { + "name" : "minecraft:stone_brick_stairs", + "id" : 109 + }, + { + "name" : "minecraft:portal", + "id" : 90 + }, + { + "name" : "minecraft:gold_ingot", + "id" : 266 + }, + { + "name" : "minecraft:iron_ingot", + "id" : 265 + }, + { + "name" : "minecraft:cookie", + "id" : 357 + }, + { + "name" : "minecraft:porkchop", + "id" : 319 + }, + { + "name" : "minecraft:bread", + "id" : 297 + }, + { + "name" : "minecraft:element_7", + "id" : -18 + }, + { + "name" : "minecraft:diamond_block", + "id" : 57 + }, + { + "name" : "minecraft:iron_pickaxe", + "id" : 257 + }, + { + "name" : "minecraft:element_27", + "id" : -38 + }, + { + "name" : "minecraft:beef", + "id" : 363 + }, + { + "name" : "minecraft:salmon", + "id" : 460 + }, + { + "name" : "minecraft:melon", + "id" : 360 + }, + { + "name" : "minecraft:clownfish", + "id" : 461 + }, + { + "name" : "minecraft:element_16", + "id" : -27 + }, + { + "name" : "minecraft:tripwire", + "id" : 132 + }, + { + "name" : "minecraft:stone_axe", + "id" : 275 + }, + { + "name" : "minecraft:stained_glass_pane", + "id" : 160 + }, + { + "name" : "minecraft:trapped_chest", + "id" : 146 + }, + { + "name" : "minecraft:pufferfish", + "id" : 462 + }, + { + "name" : "minecraft:bucket", + "id" : 325 + }, + { + "name" : "minecraft:ancient_debris", + "id" : -271 + }, + { + "name" : "minecraft:anvil", + "id" : 145 + }, + { + "name" : "minecraft:stick", + "id" : 280 + }, + { + "name" : "minecraft:cooked_fish", + "id" : 350 + }, + { + "name" : "minecraft:cooked_salmon", + "id" : 463 + }, + { + "name" : "minecraft:element_61", + "id" : -72 + }, + { + "name" : "minecraft:sparkler", + "id" : 442 + }, + { + "name" : "minecraft:warped_door", + "id" : 756 + }, + { + "name" : "minecraft:dried_kelp", + "id" : 464 + }, + { + "name" : "minecraft:hay_block", + "id" : 170 + }, + { + "name" : "minecraft:wooden_shovel", + "id" : 269 + }, + { + "name" : "minecraft:nautilus_shell", + "id" : 465 + }, + { + "name" : "minecraft:element_1", + "id" : -12 + }, + { + "name" : "minecraft:stonecutter_block", + "id" : -197 + }, + { + "name" : "minecraft:cooked_beef", + "id" : 364 + }, + { + "name" : "minecraft:comparator", + "id" : 404 + }, + { + "name" : "minecraft:carrot", + "id" : 391 + }, + { + "name" : "minecraft:command_block", + "id" : 137 + }, + { + "name" : "minecraft:chicken", + "id" : 365 + }, + { + "name" : "minecraft:potion", + "id" : 373 + }, + { + "name" : "minecraft:rotten_flesh", + "id" : 367 + }, + { + "name" : "minecraft:dirt", + "id" : 3 + }, + { + "name" : "minecraft:element_62", + "id" : -73 + }, + { + "name" : "minecraft:daylight_detector", + "id" : 151 + }, + { + "name" : "minecraft:snow_layer", + "id" : 78 + }, + { + "name" : "minecraft:rabbit_foot", + "id" : 414 + }, + { + "name" : "minecraft:lingering_potion", + "id" : 441 + }, + { + "name" : "minecraft:campfire", + "id" : 720 + }, + { + "name" : "minecraft:smoker", + "id" : -198 + }, + { + "name" : "minecraft:warped_fence", + "id" : -257 + }, + { + "name" : "minecraft:cooked_chicken", + "id" : 366 + }, + { + "name" : "minecraft:light_blue_glazed_terracotta", + "id" : 223 + }, + { + "name" : "minecraft:stone_sword", + "id" : 272 + }, + { + "name" : "minecraft:record_far", + "id" : 504 + }, + { + "name" : "minecraft:spider_eye", + "id" : 375 + }, + { + "name" : "minecraft:smooth_quartz_stairs", + "id" : -185 + }, + { + "name" : "minecraft:potato", + "id" : 392 + }, + { + "name" : "minecraft:baked_potato", + "id" : 393 + }, + { + "name" : "minecraft:element_88", + "id" : -99 + }, + { + "name" : "minecraft:golden_carrot", + "id" : 396 + }, + { + "name" : "minecraft:spruce_stairs", + "id" : 134 + }, + { + "name" : "minecraft:poisonous_potato", + "id" : 394 + }, + { + "name" : "minecraft:element_13", + "id" : -24 + }, + { + "name" : "minecraft:obsidian", + "id" : 49 + }, + { + "name" : "minecraft:pumpkin_pie", + "id" : 400 + }, + { + "name" : "minecraft:diamond_pickaxe", + "id" : 278 + }, + { + "name" : "minecraft:lantern", + "id" : -208 + }, + { + "name" : "minecraft:iron_sword", + "id" : 267 + }, + { + "name" : "minecraft:smooth_stone", + "id" : -183 + }, + { + "name" : "minecraft:beetroot", + "id" : 457 + }, + { + "name" : "minecraft:element_43", + "id" : -54 + }, + { + "name" : "minecraft:beetroot_soup", + "id" : 459 + }, + { + "name" : "minecraft:red_mushroom", + "id" : 40 + }, + { + "name" : "minecraft:wooden_pickaxe", + "id" : 270 + }, + { + "name" : "minecraft:invisiblebedrock", + "id" : 95 + }, + { + "name" : "minecraft:sweet_berries", + "id" : 477 + }, + { + "name" : "minecraft:prismarine_bricks_stairs", + "id" : -4 + }, + { + "name" : "minecraft:cooked_rabbit", + "id" : 412 + }, + { + "name" : "minecraft:rabbit_stew", + "id" : 413 + }, + { + "name" : "minecraft:birch_fence_gate", + "id" : 184 + }, + { + "name" : "minecraft:wheat_seeds", + "id" : 295 + }, + { + "name" : "minecraft:chest", + "id" : 54 + }, + { + "name" : "minecraft:pumpkin_seeds", + "id" : 361 + }, + { + "name" : "minecraft:element_2", + "id" : -13 + }, + { + "name" : "minecraft:item.crimson_door", + "id" : -244 + }, + { + "name" : "minecraft:command_block_minecart", + "id" : 443 + }, + { + "name" : "minecraft:melon_seeds", + "id" : 362 + }, + { + "name" : "minecraft:iron_axe", + "id" : 258 + }, + { + "name" : "minecraft:spawn_egg", + "id" : 383 + }, + { + "name" : "minecraft:element_93", + "id" : -104 + }, + { + "name" : "minecraft:nether_wart", + "id" : 372 + }, + { + "name" : "minecraft:beetroot_seeds", + "id" : 458 + }, + { + "name" : "minecraft:element_35", + "id" : -46 + }, + { + "name" : "minecraft:iron_shovel", + "id" : 256 + }, + { + "name" : "minecraft:element_104", + "id" : -115 + }, + { + "name" : "minecraft:granite_stairs", + "id" : -169 + }, + { + "name" : "minecraft:flint_and_steel", + "id" : 259 + }, + { + "name" : "minecraft:stone_shovel", + "id" : 273 + }, + { + "name" : "minecraft:horsearmorleather", + "id" : 416 + }, + { + "name" : "minecraft:item.cauldron", + "id" : 118 + }, + { + "name" : "minecraft:melon_block", + "id" : 103 + }, + { + "name" : "minecraft:arrow", + "id" : 262 + }, + { + "name" : "minecraft:coal", + "id" : 263 + }, + { + "name" : "minecraft:real_double_stone_slab2", + "id" : 181 + }, + { + "name" : "minecraft:chorus_plant", + "id" : 240 + }, + { + "name" : "minecraft:gold_block", + "id" : 41 + }, + { + "name" : "minecraft:carrots", + "id" : 141 + }, + { + "name" : "minecraft:diamond", + "id" : 264 + }, + { + "name" : "minecraft:wooden_sword", + "id" : 268 + }, + { + "name" : "minecraft:record_strad", + "id" : 508 + }, + { + "name" : "minecraft:netherite_boots", + "id" : 751 + }, + { + "name" : "minecraft:dark_oak_stairs", + "id" : 164 + }, + { + "name" : "minecraft:farmland", + "id" : 60 + }, + { + "name" : "minecraft:wooden_axe", + "id" : 271 + }, + { + "name" : "minecraft:stone_pickaxe", + "id" : 274 + }, + { + "name" : "minecraft:planks", + "id" : 5 + }, + { + "name" : "minecraft:chainmail_helmet", + "id" : 302 + }, + { + "name" : "minecraft:diamond_shovel", + "id" : 277 + }, + { + "name" : "minecraft:diamond_sword", + "id" : 276 + }, + { + "name" : "minecraft:smithing_table", + "id" : -202 + }, + { + "name" : "minecraft:diamond_axe", + "id" : 279 + }, + { + "name" : "minecraft:bowl", + "id" : 281 + }, + { + "name" : "minecraft:flowing_water", + "id" : 8 + }, + { + "name" : "minecraft:golden_sword", + "id" : 283 + }, + { + "name" : "minecraft:honey_block", + "id" : -220 + }, + { + "name" : "minecraft:golden_shovel", + "id" : 284 + }, + { + "name" : "minecraft:golden_pickaxe", + "id" : 285 + }, + { + "name" : "minecraft:lit_redstone_lamp", + "id" : 124 + }, + { + "name" : "minecraft:elytra", + "id" : 444 + }, + { + "name" : "minecraft:golden_axe", + "id" : 286 + }, + { + "name" : "minecraft:element_52", + "id" : -63 + }, + { + "name" : "minecraft:string", + "id" : 287 + }, + { + "name" : "minecraft:real_double_stone_slab4", + "id" : -168 + }, + { + "name" : "minecraft:feather", + "id" : 288 + }, + { + "name" : "minecraft:gunpowder", + "id" : 289 + }, + { + "name" : "minecraft:acacia_stairs", + "id" : 163 + }, + { + "name" : "minecraft:wooden_hoe", + "id" : 290 + }, + { + "name" : "minecraft:stone_hoe", + "id" : 291 + }, + { + "name" : "minecraft:iron_hoe", + "id" : 292 + }, + { + "name" : "minecraft:diamond_hoe", + "id" : 293 + }, + { + "name" : "minecraft:element_86", + "id" : -97 + }, + { + "name" : "minecraft:golden_hoe", + "id" : 294 + }, + { + "name" : "minecraft:wheat", + "id" : 296 + }, + { + "name" : "minecraft:leather_helmet", + "id" : 298 + }, + { + "name" : "minecraft:leather_chestplate", + "id" : 299 + }, + { + "name" : "minecraft:leather_leggings", + "id" : 300 + }, + { + "name" : "minecraft:lodestone", + "id" : -222 + }, + { + "name" : "minecraft:brown_mushroom", + "id" : 39 + }, + { + "name" : "minecraft:leather_boots", + "id" : 301 + }, + { + "name" : "minecraft:chainmail_chestplate", + "id" : 303 + }, + { + "name" : "minecraft:end_gateway", + "id" : 209 + }, + { + "name" : "minecraft:item.beetroot", + "id" : 244 + }, + { + "name" : "minecraft:chainmail_leggings", + "id" : 304 + }, + { + "name" : "minecraft:element_101", + "id" : -112 + }, + { + "name" : "minecraft:chainmail_boots", + "id" : 305 + }, + { + "name" : "minecraft:soul_sand", + "id" : 88 + }, + { + "name" : "minecraft:iron_helmet", + "id" : 306 + }, + { + "name" : "minecraft:snowball", + "id" : 332 + }, + { + "name" : "minecraft:element_49", + "id" : -60 + }, + { + "name" : "minecraft:record_mellohi", + "id" : 506 + }, + { + "name" : "minecraft:iron_chestplate", + "id" : 307 + }, + { + "name" : "minecraft:barrel", + "id" : -203 + }, + { + "name" : "minecraft:iron_leggings", + "id" : 308 + }, + { + "name" : "minecraft:crimson_double_slab", + "id" : -266 + }, + { + "name" : "minecraft:iron_boots", + "id" : 309 + }, + { + "name" : "minecraft:real_double_stone_slab3", + "id" : -167 + }, + { + "name" : "minecraft:ender_eye", + "id" : 381 + }, + { + "name" : "minecraft:stickypistonarmcollision", + "id" : -217 + }, + { + "name" : "minecraft:iron_trapdoor", + "id" : 167 + }, + { + "name" : "minecraft:diamond_helmet", + "id" : 310 + }, + { + "name" : "minecraft:stone_pressure_plate", + "id" : 70 + }, + { + "name" : "minecraft:diamond_chestplate", + "id" : 311 + }, + { + "name" : "minecraft:sand", + "id" : 12 + }, + { + "name" : "minecraft:light_weighted_pressure_plate", + "id" : 147 + }, + { + "name" : "minecraft:piston", + "id" : 33 + }, + { + "name" : "minecraft:diamond_leggings", + "id" : 312 + }, + { + "name" : "minecraft:element_30", + "id" : -41 + }, + { + "name" : "minecraft:diamond_boots", + "id" : 313 + }, + { + "name" : "minecraft:golden_helmet", + "id" : 314 + }, + { + "name" : "minecraft:element_51", + "id" : -62 + }, + { + "name" : "minecraft:double_wooden_slab", + "id" : 157 + }, + { + "name" : "minecraft:hard_stained_glass", + "id" : 254 + }, + { + "name" : "minecraft:element_84", + "id" : -95 + }, + { + "name" : "minecraft:golden_chestplate", + "id" : 315 + }, + { + "name" : "minecraft:sealantern", + "id" : 169 + }, + { + "name" : "minecraft:bedrock", + "id" : 7 + }, + { + "name" : "minecraft:glowstone", + "id" : 89 + }, + { + "name" : "minecraft:golden_leggings", + "id" : 316 + }, + { + "name" : "minecraft:golden_boots", + "id" : 317 + }, + { + "name" : "minecraft:shield", + "id" : 513 + }, + { + "name" : "minecraft:jungle_fence_gate", + "id" : 185 + }, + { + "name" : "minecraft:carpet", + "id" : 171 + }, + { + "name" : "minecraft:flowing_lava", + "id" : 10 + }, + { + "name" : "minecraft:flint", + "id" : 318 + }, + { + "name" : "minecraft:painting", + "id" : 321 + }, + { + "name" : "minecraft:heart_of_the_sea", + "id" : 467 + }, + { + "name" : "minecraft:sign", + "id" : 323 + }, + { + "name" : "minecraft:muttonraw", + "id" : 423 + }, + { + "name" : "minecraft:element_55", + "id" : -66 + }, + { + "name" : "minecraft:wooden_door", + "id" : 324 + }, + { + "name" : "minecraft:concrete_powder", + "id" : 237 + }, + { + "name" : "minecraft:minecart", + "id" : 328 + }, + { + "name" : "minecraft:saddle", + "id" : 329 + }, + { + "name" : "minecraft:nether_wart_block", + "id" : 214 + }, + { + "name" : "minecraft:crimson_roots", + "id" : -223 + }, + { + "name" : "minecraft:element_116", + "id" : -127 + }, + { + "name" : "minecraft:iron_door", + "id" : 330 + }, + { + "name" : "minecraft:redstone", + "id" : 331 + }, + { + "name" : "minecraft:boat", + "id" : 333 + }, + { + "name" : "minecraft:written_book", + "id" : 387 + }, + { + "name" : "minecraft:iron_ore", + "id" : 15 + }, + { + "name" : "minecraft:leather", + "id" : 334 + }, + { + "name" : "minecraft:kelp", + "id" : 335 + }, + { + "name" : "minecraft:gold_nugget", + "id" : 371 + }, + { + "name" : "minecraft:brick", + "id" : 336 + }, + { + "name" : "minecraft:element_68", + "id" : -79 + }, + { + "name" : "minecraft:clay_ball", + "id" : 337 + }, + { + "name" : "minecraft:carrotonastick", + "id" : 398 + }, + { + "name" : "minecraft:reeds", + "id" : 338 + }, + { + "name" : "minecraft:paper", + "id" : 339 + }, + { + "name" : "minecraft:element_23", + "id" : -34 + }, + { + "name" : "minecraft:coral", + "id" : -131 + }, + { + "name" : "minecraft:book", + "id" : 340 + }, + { + "name" : "minecraft:end_portal", + "id" : 119 + }, + { + "name" : "minecraft:trident", + "id" : 455 + }, + { + "name" : "minecraft:slime_ball", + "id" : 341 + }, + { + "name" : "minecraft:chest_minecart", + "id" : 342 + }, + { + "name" : "minecraft:element_71", + "id" : -82 + }, + { + "name" : "minecraft:egg", + "id" : 344 + }, + { + "name" : "minecraft:netherite_sword", + "id" : 743 + }, + { + "name" : "minecraft:item.reeds", + "id" : 83 + }, + { + "name" : "minecraft:compass", + "id" : 345 + }, + { + "name" : "minecraft:crimson_stairs", + "id" : -254 + }, + { + "name" : "minecraft:fishing_rod", + "id" : 346 + }, + { + "name" : "minecraft:andesite_stairs", + "id" : -171 + }, + { + "name" : "minecraft:reserved6", + "id" : 255 + }, + { + "name" : "minecraft:clock", + "id" : 347 + }, + { + "name" : "minecraft:red_sandstone", + "id" : 179 + }, + { + "name" : "minecraft:spruce_button", + "id" : -144 + }, + { + "name" : "minecraft:glowstone_dust", + "id" : 348 + }, + { + "name" : "minecraft:blaze_rod", + "id" : 369 + }, + { + "name" : "minecraft:dye", + "id" : 351 + }, + { + "name" : "minecraft:element_74", + "id" : -85 + }, + { + "name" : "minecraft:bone", + "id" : 352 + }, + { + "name" : "minecraft:map", + "id" : 358 + }, + { + "name" : "minecraft:sugar", + "id" : 353 + }, + { + "name" : "minecraft:name_tag", + "id" : 421 + }, + { + "name" : "minecraft:cake", + "id" : 354 + }, + { + "name" : "minecraft:bed", + "id" : 355 + }, + { + "name" : "minecraft:stained_glass", + "id" : 241 + }, + { + "name" : "minecraft:repeater", + "id" : 356 + }, + { + "name" : "minecraft:beacon", + "id" : 138 + }, + { + "name" : "minecraft:netherite_chestplate", + "id" : 749 + }, + { + "name" : "minecraft:unpowered_comparator", + "id" : 149 + }, + { + "name" : "minecraft:shears", + "id" : 359 + }, + { + "name" : "minecraft:element_31", + "id" : -42 + }, + { + "name" : "minecraft:ender_pearl", + "id" : 368 + }, + { + "name" : "minecraft:red_sandstone_stairs", + "id" : 180 + }, + { + "name" : "minecraft:carved_pumpkin", + "id" : -155 + }, + { + "name" : "minecraft:ghast_tear", + "id" : 370 + }, + { + "name" : "minecraft:glass_bottle", + "id" : 374 + }, + { + "name" : "minecraft:element_44", + "id" : -55 + }, + { + "name" : "minecraft:lava", + "id" : 11 + }, + { + "name" : "minecraft:polished_blackstone_brick_stairs", + "id" : -275 + }, + { + "name" : "minecraft:jungle_pressure_plate", + "id" : -153 + }, + { + "name" : "minecraft:fermented_spider_eye", + "id" : 376 + }, + { + "name" : "minecraft:honeycomb_block", + "id" : -221 + }, + { + "name" : "minecraft:blaze_powder", + "id" : 377 + }, + { + "name" : "minecraft:magma_cream", + "id" : 378 + }, + { + "name" : "minecraft:jigsaw", + "id" : -211 + }, + { + "name" : "minecraft:brewing_stand", + "id" : 379 + }, + { + "name" : "minecraft:cauldron", + "id" : 380 + }, + { + "name" : "minecraft:element_111", + "id" : -122 + }, + { + "name" : "minecraft:rapid_fertilizer", + "id" : 449 + }, + { + "name" : "minecraft:clay", + "id" : 82 + }, + { + "name" : "minecraft:speckled_melon", + "id" : 382 + }, + { + "name" : "minecraft:experience_bottle", + "id" : 384 + }, + { + "name" : "minecraft:element_48", + "id" : -59 + }, + { + "name" : "minecraft:coal_block", + "id" : 173 + }, + { + "name" : "minecraft:fireball", + "id" : 385 + }, + { + "name" : "minecraft:writable_book", + "id" : 386 + }, + { + "name" : "minecraft:element_69", + "id" : -80 + }, + { + "name" : "minecraft:emerald", + "id" : 388 + }, + { + "name" : "minecraft:record_pigstep", + "id" : 759 + }, + { + "name" : "minecraft:element_66", + "id" : -77 + }, + { + "name" : "minecraft:frame", + "id" : 389 + }, + { + "name" : "minecraft:brewingstandblock", + "id" : 117 + }, + { + "name" : "minecraft:flower_pot", + "id" : 390 + }, + { + "name" : "minecraft:emptymap", + "id" : 395 + }, + { + "name" : "minecraft:element_110", + "id" : -121 + }, + { + "name" : "minecraft:element_75", + "id" : -86 + }, + { + "name" : "minecraft:skull", + "id" : 397 + }, + { + "name" : "minecraft:crimson_door", + "id" : 755 + }, + { + "name" : "minecraft:sponge", + "id" : 19 + }, + { + "name" : "minecraft:netherstar", + "id" : 399 + }, + { + "name" : "minecraft:fireworks", + "id" : 401 + }, + { + "name" : "minecraft:hopper_minecart", + "id" : 408 + }, + { + "name" : "minecraft:fireworkscharge", + "id" : 402 + }, + { + "name" : "minecraft:enchanted_book", + "id" : 403 + }, + { + "name" : "minecraft:netherbrick", + "id" : 405 + }, + { + "name" : "minecraft:cobblestone_wall", + "id" : 139 + }, + { + "name" : "minecraft:quartz", + "id" : 406 + }, + { + "name" : "minecraft:tnt_minecart", + "id" : 407 + }, + { + "name" : "minecraft:element_63", + "id" : -74 + }, + { + "name" : "minecraft:hopper", + "id" : 410 + }, + { + "name" : "minecraft:cobblestone", + "id" : 4 + }, + { + "name" : "minecraft:dragon_breath", + "id" : 437 + }, + { + "name" : "minecraft:rabbit_hide", + "id" : 415 + }, + { + "name" : "minecraft:horsearmoriron", + "id" : 417 + }, + { + "name" : "minecraft:horsearmorgold", + "id" : 418 + }, + { + "name" : "minecraft:colored_torch_bp", + "id" : 204 + }, + { + "name" : "minecraft:element_102", + "id" : -113 + }, + { + "name" : "minecraft:quartz_ore", + "id" : 153 + }, + { + "name" : "minecraft:netherite_shovel", + "id" : 744 + }, + { + "name" : "minecraft:horsearmordiamond", + "id" : 419 + }, + { + "name" : "minecraft:record_13", + "id" : 500 + }, + { + "name" : "minecraft:record_cat", + "id" : 501 + }, + { + "name" : "minecraft:element_3", + "id" : -14 + }, + { + "name" : "minecraft:polished_diorite_stairs", + "id" : -173 + }, + { + "name" : "minecraft:monster_egg", + "id" : 97 + }, + { + "name" : "minecraft:record_blocks", + "id" : 502 + }, + { + "name" : "minecraft:crimson_standing_sign", + "id" : -250 + }, + { + "name" : "minecraft:record_chirp", + "id" : 503 + }, + { + "name" : "minecraft:record_mall", + "id" : 505 + }, + { + "name" : "minecraft:respawn_anchor", + "id" : -272 + }, + { + "name" : "minecraft:record_stal", + "id" : 507 + }, + { + "name" : "minecraft:record_11", + "id" : 510 + }, + { + "name" : "minecraft:record_wait", + "id" : 511 + }, + { + "name" : "minecraft:info_update2", + "id" : 249 + }, + { + "name" : "minecraft:lead", + "id" : 420 + }, + { + "name" : "minecraft:prismarine_crystals", + "id" : 422 + }, + { + "name" : "minecraft:acacia_sign", + "id" : 475 + }, + { + "name" : "minecraft:muttoncooked", + "id" : 424 + }, + { + "name" : "minecraft:armor_stand", + "id" : 425 + }, + { + "name" : "minecraft:coal_ore", + "id" : 16 + }, + { + "name" : "minecraft:element_32", + "id" : -43 + }, + { + "name" : "minecraft:spruce_door", + "id" : 427 + }, + { + "name" : "minecraft:phantom_membrane", + "id" : 470 + }, + { + "name" : "minecraft:birch_door", + "id" : 428 + }, + { + "name" : "minecraft:element_85", + "id" : -96 + }, + { + "name" : "minecraft:polished_blackstone_wall", + "id" : -297 + }, + { + "name" : "minecraft:jungle_door", + "id" : 429 + }, + { + "name" : "minecraft:acacia_door", + "id" : 430 + }, + { + "name" : "minecraft:element_42", + "id" : -53 + }, + { + "name" : "minecraft:dark_oak_door", + "id" : 431 + }, + { + "name" : "minecraft:netherite_leggings", + "id" : 750 + }, + { + "name" : "minecraft:stripped_crimson_stem", + "id" : -240 + }, + { + "name" : "minecraft:chorus_fruit", + "id" : 432 + }, + { + "name" : "minecraft:camera", + "id" : 498 + }, + { + "name" : "minecraft:suspicious_stew", + "id" : 734 + }, + { + "name" : "minecraft:chorus_fruit_popped", + "id" : 433 + }, + { + "name" : "minecraft:element_98", + "id" : -109 + }, + { + "name" : "minecraft:splash_potion", + "id" : 438 + }, + { + "name" : "minecraft:element_73", + "id" : -84 + }, + { + "name" : "minecraft:prismarine_shard", + "id" : 409 + }, + { + "name" : "minecraft:seagrass", + "id" : -130 + }, + { + "name" : "minecraft:dark_oak_pressure_plate", + "id" : -152 + }, + { + "name" : "minecraft:shulker_shell", + "id" : 445 + }, + { + "name" : "minecraft:redstone_block", + "id" : 152 + }, + { + "name" : "minecraft:banner", + "id" : 446 + }, + { + "name" : "minecraft:totem", + "id" : 450 + }, + { + "name" : "minecraft:blackstone_slab", + "id" : -282 + }, + { + "name" : "minecraft:element_118", + "id" : -129 + }, + { + "name" : "minecraft:iron_nugget", + "id" : 452 + }, + { + "name" : "minecraft:netherite_pickaxe", + "id" : 745 + }, + { + "name" : "minecraft:jukebox", + "id" : 84 + }, + { + "name" : "minecraft:turtle_shell_piece", + "id" : 468 + }, + { + "name" : "minecraft:turtle_helmet", + "id" : 469 + }, + { + "name" : "minecraft:crossbow", + "id" : 471 + }, + { + "name" : "minecraft:glowingobsidian", + "id" : 246 + }, + { + "name" : "minecraft:leaves2", + "id" : 161 + }, + { + "name" : "minecraft:spruce_sign", + "id" : 472 + }, + { + "name" : "minecraft:element_38", + "id" : -49 + }, + { + "name" : "minecraft:coral_fan_hang2", + "id" : -136 + }, + { + "name" : "minecraft:birch_sign", + "id" : 473 + }, + { + "name" : "minecraft:coral_fan_dead", + "id" : -134 + }, + { + "name" : "minecraft:balloon", + "id" : 448 + }, + { + "name" : "minecraft:jungle_sign", + "id" : 474 + }, + { + "name" : "minecraft:darkoak_sign", + "id" : 476 + }, + { + "name" : "minecraft:element_24", + "id" : -35 + }, + { + "name" : "minecraft:banner_pattern", + "id" : 434 + }, + { + "name" : "minecraft:honeycomb", + "id" : 736 + }, + { + "name" : "minecraft:element_78", + "id" : -89 + }, + { + "name" : "minecraft:red_nether_brick", + "id" : 215 + }, + { + "name" : "minecraft:honey_bottle", + "id" : 737 + }, + { + "name" : "minecraft:compound", + "id" : 499 + }, + { + "name" : "minecraft:ice_bomb", + "id" : 453 + }, + { + "name" : "minecraft:brick_block", + "id" : 45 + }, + { + "name" : "minecraft:bleach", + "id" : 451 + }, + { + "name" : "minecraft:colored_torch_rg", + "id" : 202 + }, + { + "name" : "minecraft:medicine", + "id" : 447 + }, + { + "name" : "minecraft:warped_fungus", + "id" : -229 + }, + { + "name" : "minecraft:end_portal_frame", + "id" : 120 + }, + { + "name" : "minecraft:element_92", + "id" : -103 + }, + { + "name" : "minecraft:glow_stick", + "id" : 166 + }, + { + "name" : "minecraft:lodestonecompass", + "id" : 741 + }, + { + "name" : "minecraft:element_17", + "id" : -28 + }, + { + "name" : "minecraft:lit_pumpkin", + "id" : 91 + }, + { + "name" : "minecraft:netherite_ingot", + "id" : 742 + }, + { + "name" : "minecraft:chain_command_block", + "id" : 189 + }, + { + "name" : "minecraft:loom", + "id" : -204 + }, + { + "name" : "minecraft:item.warped_door", + "id" : -245 + }, + { + "name" : "minecraft:netherite_axe", + "id" : 746 + }, + { + "name" : "minecraft:netherite_hoe", + "id" : 747 + }, + { + "name" : "minecraft:dark_oak_fence_gate", + "id" : 186 + }, + { + "name" : "minecraft:element_115", + "id" : -126 + }, + { + "name" : "minecraft:netherite_helmet", + "id" : 748 + }, + { + "name" : "minecraft:element_117", + "id" : -128 + }, + { + "name" : "minecraft:netherite_scrap", + "id" : 752 + }, + { + "name" : "minecraft:crimson_sign", + "id" : 753 + }, + { + "name" : "minecraft:concrete", + "id" : 236 + }, + { + "name" : "minecraft:chiseled_nether_bricks", + "id" : -302 + }, + { + "name" : "minecraft:mob_spawner", + "id" : 52 + }, + { + "name" : "minecraft:warped_sign", + "id" : 754 + }, + { + "name" : "minecraft:chain", + "id" : 758 + }, + { + "name" : "minecraft:warped_fungus_on_a_stick", + "id" : 757 + }, + { + "name" : "minecraft:nether_sprouts", + "id" : 760 + }, + { + "name" : "minecraft:cartography_table", + "id" : -200 + }, + { + "name" : "minecraft:polished_blackstone_slab", + "id" : -293 + }, + { + "name" : "minecraft:soul_campfire", + "id" : 801 + }, + { + "name" : "minecraft:stone", + "id" : 1 + }, + { + "name" : "minecraft:wool", + "id" : 35 + }, + { + "name" : "minecraft:yellow_flower", + "id" : 37 + }, + { + "name" : "minecraft:stained_hardened_clay", + "id" : 159 + }, + { + "name" : "minecraft:log", + "id" : 17 + }, + { + "name" : "minecraft:fence", + "id" : 85 + }, + { + "name" : "minecraft:element_53", + "id" : -64 + }, + { + "name" : "minecraft:stonebrick", + "id" : 98 + }, + { + "name" : "minecraft:lit_blast_furnace", + "id" : -214 + }, + { + "name" : "minecraft:coral_block", + "id" : -132 + }, + { + "name" : "minecraft:polished_blackstone_bricks", + "id" : -274 + }, + { + "name" : "minecraft:double_stone_slab", + "id" : 44 + }, + { + "name" : "minecraft:element_100", + "id" : -111 + }, + { + "name" : "minecraft:double_stone_slab2", + "id" : 182 + }, + { + "name" : "minecraft:fence_gate", + "id" : 107 + }, + { + "name" : "minecraft:double_stone_slab3", + "id" : -162 + }, + { + "name" : "minecraft:rail", + "id" : 66 + }, + { + "name" : "minecraft:double_stone_slab4", + "id" : -166 + }, + { + "name" : "minecraft:stripped_acacia_log", + "id" : -8 + }, + { + "name" : "minecraft:real_double_stone_slab", + "id" : 43 + }, + { + "name" : "minecraft:coral_fan", + "id" : -133 + }, + { + "name" : "minecraft:sea_pickle", + "id" : -156 + }, + { + "name" : "minecraft:polished_blackstone_button", + "id" : -296 + }, + { + "name" : "minecraft:element_90", + "id" : -101 + }, + { + "name" : "minecraft:polished_blackstone_double_slab", + "id" : -294 + }, + { + "name" : "minecraft:sapling", + "id" : 6 + }, + { + "name" : "minecraft:leaves", + "id" : 18 + }, + { + "name" : "minecraft:sandstone", + "id" : 24 + }, + { + "name" : "minecraft:silver_glazed_terracotta", + "id" : 228 + }, + { + "name" : "minecraft:wooden_slab", + "id" : 158 + }, + { + "name" : "minecraft:warped_roots", + "id" : -224 + }, + { + "name" : "minecraft:element_11", + "id" : -22 + }, + { + "name" : "minecraft:red_flower", + "id" : 38 + }, + { + "name" : "minecraft:element_59", + "id" : -70 + }, + { + "name" : "minecraft:double_plant", + "id" : 175 + }, + { + "name" : "minecraft:waterlily", + "id" : 111 + }, + { + "name" : "minecraft:quartz_block", + "id" : 155 + }, + { + "name" : "minecraft:element_95", + "id" : -106 + }, + { + "name" : "minecraft:soul_soil", + "id" : -236 + }, + { + "name" : "minecraft:acacia_pressure_plate", + "id" : -150 + }, + { + "name" : "minecraft:tallgrass", + "id" : 31 + }, + { + "name" : "minecraft:brown_mushroom_block", + "id" : 99 + }, + { + "name" : "minecraft:element_103", + "id" : -114 + }, + { + "name" : "minecraft:crimson_fungus", + "id" : -228 + }, + { + "name" : "minecraft:item.frame", + "id" : 199 + }, + { + "name" : "minecraft:red_mushroom_block", + "id" : 100 + }, + { + "name" : "minecraft:log2", + "id" : 162 + }, + { + "name" : "minecraft:conduit", + "id" : -157 + }, + { + "name" : "minecraft:prismarine", + "id" : 168 + }, + { + "name" : "minecraft:magma", + "id" : 213 + }, + { + "name" : "minecraft:element_22", + "id" : -33 + }, + { + "name" : "minecraft:undyed_shulker_box", + "id" : 205 + }, + { + "name" : "minecraft:shulker_box", + "id" : 218 + }, + { + "name" : "minecraft:spruce_standing_sign", + "id" : -181 + }, + { + "name" : "minecraft:sticky_piston", + "id" : 29 + }, + { + "name" : "minecraft:element_10", + "id" : -21 + }, + { + "name" : "minecraft:turtle_egg", + "id" : -159 + }, + { + "name" : "minecraft:bamboo", + "id" : -163 + }, + { + "name" : "minecraft:observer", + "id" : 251 + }, + { + "name" : "minecraft:scaffolding", + "id" : -165 + }, + { + "name" : "minecraft:blast_furnace", + "id" : -196 + }, + { + "name" : "minecraft:grindstone", + "id" : -195 + }, + { + "name" : "minecraft:bell", + "id" : -206 + }, + { + "name" : "minecraft:end_rod", + "id" : 208 + }, + { + "name" : "minecraft:fletching_table", + "id" : -201 + }, + { + "name" : "minecraft:item.hopper", + "id" : 154 + }, + { + "name" : "minecraft:wood", + "id" : -212 + }, + { + "name" : "minecraft:chemistry_table", + "id" : 238 + }, + { + "name" : "minecraft:tnt", + "id" : 46 + }, + { + "name" : "minecraft:hard_stained_glass_pane", + "id" : 191 + }, + { + "name" : "minecraft:crimson_slab", + "id" : -264 + }, + { + "name" : "minecraft:element_87", + "id" : -98 + }, + { + "name" : "minecraft:warped_slab", + "id" : -265 + }, + { + "name" : "minecraft:element_0", + "id" : 36 + }, + { + "name" : "minecraft:element_4", + "id" : -15 + }, + { + "name" : "minecraft:ender_chest", + "id" : 130 + }, + { + "name" : "minecraft:element_5", + "id" : -16 + }, + { + "name" : "minecraft:element_6", + "id" : -17 + }, + { + "name" : "minecraft:element_8", + "id" : -19 + }, + { + "name" : "minecraft:element_9", + "id" : -20 + }, + { + "name" : "minecraft:element_12", + "id" : -23 + }, + { + "name" : "minecraft:element_14", + "id" : -25 + }, + { + "name" : "minecraft:element_15", + "id" : -26 + }, + { + "name" : "minecraft:element_18", + "id" : -29 + }, + { + "name" : "minecraft:element_19", + "id" : -30 + }, + { + "name" : "minecraft:element_20", + "id" : -31 + }, + { + "name" : "minecraft:element_21", + "id" : -32 + }, + { + "name" : "minecraft:element_26", + "id" : -37 + }, + { + "name" : "minecraft:element_28", + "id" : -39 + }, + { + "name" : "minecraft:element_29", + "id" : -40 + }, + { + "name" : "minecraft:element_33", + "id" : -44 + }, + { + "name" : "minecraft:element_34", + "id" : -45 + }, + { + "name" : "minecraft:element_36", + "id" : -47 + }, + { + "name" : "minecraft:ice", + "id" : 79 + }, + { + "name" : "minecraft:element_37", + "id" : -48 + }, + { + "name" : "minecraft:element_39", + "id" : -50 + }, + { + "name" : "minecraft:element_40", + "id" : -51 + }, + { + "name" : "minecraft:element_41", + "id" : -52 + }, + { + "name" : "minecraft:element_45", + "id" : -56 + }, + { + "name" : "minecraft:element_46", + "id" : -57 + }, + { + "name" : "minecraft:netherite_block", + "id" : -270 + }, + { + "name" : "minecraft:element_47", + "id" : -58 + }, + { + "name" : "minecraft:element_54", + "id" : -65 + }, + { + "name" : "minecraft:element_56", + "id" : -67 + }, + { + "name" : "minecraft:black_glazed_terracotta", + "id" : 235 + }, + { + "name" : "minecraft:lit_redstone_ore", + "id" : 74 + }, + { + "name" : "minecraft:crafting_table", + "id" : 58 + }, + { + "name" : "minecraft:element_57", + "id" : -68 + }, + { + "name" : "minecraft:element_58", + "id" : -69 + }, + { + "name" : "minecraft:element_60", + "id" : -71 + }, + { + "name" : "minecraft:element_64", + "id" : -75 + }, + { + "name" : "minecraft:element_65", + "id" : -76 + }, + { + "name" : "minecraft:element_67", + "id" : -78 + }, + { + "name" : "minecraft:element_70", + "id" : -81 + }, + { + "name" : "minecraft:element_72", + "id" : -83 + }, + { + "name" : "minecraft:element_76", + "id" : -87 + }, + { + "name" : "minecraft:dark_oak_button", + "id" : -142 + }, + { + "name" : "minecraft:element_77", + "id" : -88 + }, + { + "name" : "minecraft:diorite_stairs", + "id" : -170 + }, + { + "name" : "minecraft:redstone_torch", + "id" : 76 + }, + { + "name" : "minecraft:element_79", + "id" : -90 + }, + { + "name" : "minecraft:iron_bars", + "id" : 101 + }, + { + "name" : "minecraft:element_80", + "id" : -91 + }, + { + "name" : "minecraft:element_81", + "id" : -92 + }, + { + "name" : "minecraft:element_82", + "id" : -93 + }, + { + "name" : "minecraft:underwater_torch", + "id" : 239 + }, + { + "name" : "minecraft:blue_ice", + "id" : -11 + }, + { + "name" : "minecraft:element_83", + "id" : -94 + }, + { + "name" : "minecraft:element_89", + "id" : -100 + }, + { + "name" : "minecraft:element_91", + "id" : -102 + }, + { + "name" : "minecraft:element_96", + "id" : -107 + }, + { + "name" : "minecraft:element_97", + "id" : -108 + }, + { + "name" : "minecraft:cactus", + "id" : 81 + }, + { + "name" : "minecraft:element_99", + "id" : -110 + }, + { + "name" : "minecraft:element_105", + "id" : -116 + }, + { + "name" : "minecraft:element_106", + "id" : -117 + }, + { + "name" : "minecraft:cyan_glazed_terracotta", + "id" : 229 + }, + { + "name" : "minecraft:element_107", + "id" : -118 + }, + { + "name" : "minecraft:element_108", + "id" : -119 + }, + { + "name" : "minecraft:element_109", + "id" : -120 + }, + { + "name" : "minecraft:element_112", + "id" : -123 + }, + { + "name" : "minecraft:warped_button", + "id" : -261 + }, + { + "name" : "minecraft:element_113", + "id" : -124 + }, + { + "name" : "minecraft:birch_stairs", + "id" : 135 + }, + { + "name" : "minecraft:element_114", + "id" : -125 + }, + { + "name" : "minecraft:composter", + "id" : -213 + }, + { + "name" : "minecraft:crying_obsidian", + "id" : -289 + }, + { + "name" : "minecraft:end_crystal", + "id" : 426 + }, + { + "name" : "minecraft:tripwire_hook", + "id" : 131 + }, + { + "name" : "minecraft:blue_glazed_terracotta", + "id" : 231 + }, + { + "name" : "minecraft:daylight_detector_inverted", + "id" : 178 + }, + { + "name" : "minecraft:warped_trapdoor", + "id" : -247 + }, + { + "name" : "minecraft:twisting_vines", + "id" : -287 + }, + { + "name" : "minecraft:noteblock", + "id" : 25 + }, + { + "name" : "minecraft:gravel", + "id" : 13 + }, + { + "name" : "minecraft:golden_rail", + "id" : 27 + }, + { + "name" : "minecraft:warped_wall_sign", + "id" : -253 + }, + { + "name" : "minecraft:oak_stairs", + "id" : 53 + }, + { + "name" : "minecraft:grass", + "id" : 2 + }, + { + "name" : "minecraft:acacia_button", + "id" : -140 + }, + { + "name" : "minecraft:snow", + "id" : 80 + }, + { + "name" : "minecraft:detector_rail", + "id" : 28 + }, + { + "name" : "minecraft:dark_oak_trapdoor", + "id" : -147 + }, + { + "name" : "minecraft:spruce_pressure_plate", + "id" : -154 + }, + { + "name" : "minecraft:water", + "id" : 9 + }, + { + "name" : "minecraft:furnace", + "id" : 61 + }, + { + "name" : "minecraft:item.wooden_door", + "id" : 64 + }, + { + "name" : "minecraft:gold_ore", + "id" : 14 + }, + { + "name" : "minecraft:web", + "id" : 30 + }, + { + "name" : "minecraft:unlit_redstone_torch", + "id" : 75 + }, + { + "name" : "minecraft:ladder", + "id" : 65 + }, + { + "name" : "minecraft:sweet_berry_bush", + "id" : -207 + }, + { + "name" : "minecraft:standing_sign", + "id" : 63 + }, + { + "name" : "minecraft:glass", + "id" : 20 + }, + { + "name" : "minecraft:lapis_ore", + "id" : 21 + }, + { + "name" : "minecraft:bookshelf", + "id" : 47 + }, + { + "name" : "minecraft:item.bed", + "id" : 26 + }, + { + "name" : "minecraft:stripped_warped_hyphae", + "id" : -301 + }, + { + "name" : "minecraft:wither_rose", + "id" : -216 + }, + { + "name" : "minecraft:wooden_pressure_plate", + "id" : 72 + }, + { + "name" : "minecraft:powered_comparator", + "id" : 150 + }, + { + "name" : "minecraft:lapis_block", + "id" : 22 + }, + { + "name" : "minecraft:dispenser", + "id" : 23 + }, + { + "name" : "minecraft:item.wheat", + "id" : 59 + }, + { + "name" : "minecraft:item.spruce_door", + "id" : 193 + }, + { + "name" : "minecraft:diamond_ore", + "id" : 56 + }, + { + "name" : "minecraft:deadbush", + "id" : 32 + }, + { + "name" : "minecraft:pistonarmcollision", + "id" : 34 + }, + { + "name" : "minecraft:blackstone_stairs", + "id" : -276 + }, + { + "name" : "minecraft:dried_kelp_block", + "id" : -139 + }, + { + "name" : "minecraft:item.soul_campfire", + "id" : -290 + }, + { + "name" : "minecraft:green_glazed_terracotta", + "id" : 233 + }, + { + "name" : "minecraft:crimson_pressure_plate", + "id" : -262 + }, + { + "name" : "minecraft:spruce_fence_gate", + "id" : 183 + }, + { + "name" : "minecraft:iron_block", + "id" : 42 + }, + { + "name" : "minecraft:lever", + "id" : 69 + }, + { + "name" : "minecraft:mossy_cobblestone", + "id" : 48 + }, + { + "name" : "minecraft:torch", + "id" : 50 + }, + { + "name" : "minecraft:acacia_fence_gate", + "id" : 187 + }, + { + "name" : "minecraft:quartz_stairs", + "id" : 156 + }, + { + "name" : "minecraft:dragon_egg", + "id" : 122 + }, + { + "name" : "minecraft:lava_cauldron", + "id" : -210 + }, + { + "name" : "minecraft:jungle_standing_sign", + "id" : -188 + }, + { + "name" : "minecraft:redstone_wire", + "id" : 55 + }, + { + "name" : "minecraft:jungle_wall_sign", + "id" : -189 + }, + { + "name" : "minecraft:lit_furnace", + "id" : 62 + }, + { + "name" : "minecraft:beehive", + "id" : -219 + }, + { + "name" : "minecraft:crimson_wall_sign", + "id" : -252 + }, + { + "name" : "minecraft:stone_stairs", + "id" : 67 + }, + { + "name" : "minecraft:orange_glazed_terracotta", + "id" : 221 + }, + { + "name" : "minecraft:brick_stairs", + "id" : 108 + }, + { + "name" : "minecraft:wall_sign", + "id" : 68 + }, + { + "name" : "minecraft:warped_nylium", + "id" : -233 + }, + { + "name" : "minecraft:quartz_bricks", + "id" : -304 + }, + { + "name" : "minecraft:item.iron_door", + "id" : 71 + }, + { + "name" : "minecraft:redstone_ore", + "id" : 73 + }, + { + "name" : "minecraft:lectern", + "id" : -194 + }, + { + "name" : "minecraft:gilded_blackstone", + "id" : -281 + }, + { + "name" : "minecraft:red_nether_brick_stairs", + "id" : -184 + }, + { + "name" : "minecraft:basalt", + "id" : -234 + }, + { + "name" : "minecraft:stone_button", + "id" : 77 + }, + { + "name" : "minecraft:netherrack", + "id" : 87 + }, + { + "name" : "minecraft:nether_brick_stairs", + "id" : 114 + }, + { + "name" : "minecraft:item.acacia_door", + "id" : 196 + }, + { + "name" : "minecraft:item.cake", + "id" : 92 + }, + { + "name" : "minecraft:unpowered_repeater", + "id" : 93 + }, + { + "name" : "minecraft:powered_repeater", + "id" : 94 + }, + { + "name" : "minecraft:trapdoor", + "id" : 96 + }, + { + "name" : "minecraft:coral_fan_hang3", + "id" : -137 + }, + { + "name" : "minecraft:item.jungle_door", + "id" : 195 + }, + { + "name" : "minecraft:glass_pane", + "id" : 102 + }, + { + "name" : "minecraft:emerald_ore", + "id" : 129 + }, + { + "name" : "minecraft:crimson_planks", + "id" : -242 + }, + { + "name" : "minecraft:crimson_stem", + "id" : -225 + }, + { + "name" : "minecraft:weeping_vines", + "id" : -231 + }, + { + "name" : "minecraft:pumpkin_stem", + "id" : 104 + }, + { + "name" : "minecraft:emerald_block", + "id" : 133 + }, + { + "name" : "minecraft:melon_stem", + "id" : 105 + }, + { + "name" : "minecraft:chemical_heat", + "id" : 192 + }, + { + "name" : "minecraft:warped_wart_block", + "id" : -227 + }, + { + "name" : "minecraft:vine", + "id" : 106 + }, + { + "name" : "minecraft:bamboo_sapling", + "id" : -164 + }, + { + "name" : "minecraft:standing_banner", + "id" : 176 + }, + { + "name" : "minecraft:mycelium", + "id" : 110 + }, + { + "name" : "minecraft:nether_gold_ore", + "id" : -288 + }, + { + "name" : "minecraft:nether_brick", + "id" : 112 + }, + { + "name" : "minecraft:warped_double_slab", + "id" : -267 + }, + { + "name" : "minecraft:nether_brick_fence", + "id" : 113 + }, + { + "name" : "minecraft:sandstone_stairs", + "id" : 128 + }, + { + "name" : "minecraft:item.nether_wart", + "id" : 115 + }, + { + "name" : "minecraft:enchanting_table", + "id" : 116 + }, + { + "name" : "minecraft:end_stone", + "id" : 121 + }, + { + "name" : "minecraft:redstone_lamp", + "id" : 123 + }, + { + "name" : "minecraft:jungle_stairs", + "id" : 136 + }, + { + "name" : "minecraft:dropper", + "id" : 125 + }, + { + "name" : "minecraft:activator_rail", + "id" : 126 + }, + { + "name" : "minecraft:cocoa", + "id" : 127 + }, + { + "name" : "minecraft:soul_torch", + "id" : -268 + }, + { + "name" : "minecraft:info_update", + "id" : 248 + }, + { + "name" : "minecraft:packed_ice", + "id" : 174 + }, + { + "name" : "minecraft:coral_fan_hang", + "id" : -135 + }, + { + "name" : "minecraft:item.flower_pot", + "id" : 140 + }, + { + "name" : "minecraft:potatoes", + "id" : 142 + }, + { + "name" : "minecraft:wooden_button", + "id" : 143 + }, + { + "name" : "minecraft:item.skull", + "id" : 144 + }, + { + "name" : "minecraft:heavy_weighted_pressure_plate", + "id" : 148 + }, + { + "name" : "minecraft:purple_glazed_terracotta", + "id" : 219 + }, + { + "name" : "minecraft:stripped_jungle_log", + "id" : -7 + }, + { + "name" : "minecraft:hardened_clay", + "id" : 172 + }, + { + "name" : "minecraft:warped_planks", + "id" : -243 + }, + { + "name" : "minecraft:acacia_wall_sign", + "id" : -191 + }, + { + "name" : "minecraft:purpur_stairs", + "id" : 203 + }, + { + "name" : "minecraft:wall_banner", + "id" : 177 + }, + { + "name" : "minecraft:spruce_trapdoor", + "id" : -149 + }, + { + "name" : "minecraft:repeating_command_block", + "id" : 188 + }, + { + "name" : "minecraft:item.chain", + "id" : -286 + }, + { + "name" : "minecraft:item.birch_door", + "id" : 194 + }, + { + "name" : "minecraft:grass_path", + "id" : 198 + }, + { + "name" : "minecraft:blackstone", + "id" : -273 + }, + { + "name" : "minecraft:chorus_flower", + "id" : 200 + }, + { + "name" : "minecraft:normal_stone_stairs", + "id" : -180 + }, + { + "name" : "minecraft:barrier", + "id" : -161 + }, + { + "name" : "minecraft:frosted_ice", + "id" : 207 + }, + { + "name" : "minecraft:structure_block", + "id" : 252 + }, + { + "name" : "minecraft:allow", + "id" : 210 + }, + { + "name" : "minecraft:pink_glazed_terracotta", + "id" : 226 + }, + { + "name" : "minecraft:deny", + "id" : 211 + }, + { + "name" : "minecraft:border_block", + "id" : 212 + }, + { + "name" : "minecraft:movingblock", + "id" : 250 + }, + { + "name" : "minecraft:bone_block", + "id" : 216 + }, + { + "name" : "minecraft:structure_void", + "id" : 217 + }, + { + "name" : "minecraft:white_glazed_terracotta", + "id" : 220 + }, + { + "name" : "minecraft:magenta_glazed_terracotta", + "id" : 222 + }, + { + "name" : "minecraft:lime_glazed_terracotta", + "id" : 225 + }, + { + "name" : "minecraft:gray_glazed_terracotta", + "id" : 227 + }, + { + "name" : "minecraft:brown_glazed_terracotta", + "id" : 232 + }, + { + "name" : "minecraft:red_glazed_terracotta", + "id" : 234 + }, + { + "name" : "minecraft:crimson_nylium", + "id" : -232 + }, + { + "name" : "minecraft:acacia_trapdoor", + "id" : -145 + }, + { + "name" : "minecraft:smooth_sandstone_stairs", + "id" : -177 + }, + { + "name" : "minecraft:item.camera", + "id" : 242 + }, + { + "name" : "minecraft:podzol", + "id" : 243 + }, + { + "name" : "minecraft:stonecutter", + "id" : 245 + }, + { + "name" : "minecraft:netherreactor", + "id" : 247 + }, + { + "name" : "minecraft:prismarine_stairs", + "id" : -2 + }, + { + "name" : "minecraft:dark_prismarine_stairs", + "id" : -3 + }, + { + "name" : "minecraft:stripped_spruce_log", + "id" : -5 + }, + { + "name" : "minecraft:stripped_birch_log", + "id" : -6 + }, + { + "name" : "minecraft:stripped_dark_oak_log", + "id" : -9 + }, + { + "name" : "minecraft:fire", + "id" : 51 + }, + { + "name" : "minecraft:hard_glass", + "id" : 253 + }, + { + "name" : "minecraft:acacia_standing_sign", + "id" : -190 + }, + { + "name" : "minecraft:hard_glass_pane", + "id" : 190 + }, + { + "name" : "minecraft:mossy_cobblestone_stairs", + "id" : -179 + }, + { + "name" : "minecraft:crimson_fence_gate", + "id" : -258 + }, + { + "name" : "minecraft:mossy_stone_brick_stairs", + "id" : -175 + }, + { + "name" : "minecraft:item.nether_sprouts", + "id" : -238 + }, + { + "name" : "minecraft:polished_blackstone_brick_double_slab", + "id" : -285 + }, + { + "name" : "minecraft:cracked_polished_blackstone_bricks", + "id" : -280 + }, + { + "name" : "minecraft:smooth_red_sandstone_stairs", + "id" : -176 + }, + { + "name" : "minecraft:shroomlight", + "id" : -230 + }, + { + "name" : "minecraft:stripped_crimson_hyphae", + "id" : -300 + }, + { + "name" : "minecraft:crimson_button", + "id" : -260 + }, + { + "name" : "minecraft:soul_fire", + "id" : -237 + }, + { + "name" : "minecraft:polished_basalt", + "id" : -235 + }, + { + "name" : "minecraft:jungle_button", + "id" : -143 + }, + { + "name" : "minecraft:birch_pressure_plate", + "id" : -151 + }, + { + "name" : "minecraft:stripped_warped_stem", + "id" : -241 + }, + { + "name" : "minecraft:birch_wall_sign", + "id" : -187 + }, + { + "name" : "minecraft:jungle_trapdoor", + "id" : -148 + }, + { + "name" : "minecraft:item.kelp", + "id" : -138 + }, + { + "name" : "minecraft:birch_button", + "id" : -141 + }, + { + "name" : "minecraft:birch_trapdoor", + "id" : -146 + }, + { + "name" : "minecraft:bubble_column", + "id" : -160 + }, + { + "name" : "minecraft:polished_granite_stairs", + "id" : -172 + }, + { + "name" : "minecraft:polished_andesite_stairs", + "id" : -174 + }, + { + "name" : "minecraft:end_brick_stairs", + "id" : -178 + }, + { + "name" : "minecraft:spruce_wall_sign", + "id" : -182 + }, + { + "name" : "minecraft:chiseled_polished_blackstone", + "id" : -279 + }, + { + "name" : "minecraft:birch_standing_sign", + "id" : -186 + }, + { + "name" : "minecraft:darkoak_standing_sign", + "id" : -192 + }, + { + "name" : "minecraft:darkoak_wall_sign", + "id" : -193 + }, + { + "name" : "minecraft:lit_smoker", + "id" : -199 + }, + { + "name" : "minecraft:item.campfire", + "id" : -209 + }, + { + "name" : "minecraft:bee_nest", + "id" : -218 + }, + { + "name" : "minecraft:warped_fence_gate", + "id" : -259 + }, + { + "name" : "minecraft:warped_stem", + "id" : -226 + }, + { + "name" : "minecraft:blackstone_double_slab", + "id" : -283 + }, + { + "name" : "minecraft:target", + "id" : -239 + }, + { + "name" : "minecraft:crimson_trapdoor", + "id" : -246 + }, + { + "name" : "minecraft:polished_blackstone_brick_wall", + "id" : -278 + }, + { + "name" : "minecraft:warped_standing_sign", + "id" : -251 + }, + { + "name" : "minecraft:warped_stairs", + "id" : -255 + }, + { + "name" : "minecraft:crimson_fence", + "id" : -256 + }, + { + "name" : "minecraft:warped_pressure_plate", + "id" : -263 + }, + { + "name" : "minecraft:soul_lantern", + "id" : -269 + }, + { + "name" : "minecraft:blackstone_wall", + "id" : -277 + }, + { + "name" : "minecraft:polished_blackstone", + "id" : -291 + }, + { + "name" : "minecraft:polished_blackstone_stairs", + "id" : -292 + }, + { + "name" : "minecraft:polished_blackstone_pressure_plate", + "id" : -295 + }, + { + "name" : "minecraft:warped_hyphae", + "id" : -298 + }, + { + "name" : "minecraft:crimson_hyphae", + "id" : -299 + }, + { + "name" : "minecraft:cracked_nether_bricks", + "id" : -303 + } ] \ No newline at end of file diff --git a/connector/src/main/resources/bedrock/legacy_block_ids.json b/connector/src/main/resources/bedrock/legacy_block_ids.json index e5347d87ebb..275949157d4 100644 --- a/connector/src/main/resources/bedrock/legacy_block_ids.json +++ b/connector/src/main/resources/bedrock/legacy_block_ids.json @@ -1,462 +1,555 @@ { - "minecraft:air": 0, - "minecraft:stone": 1, - "minecraft:grass": 2, - "minecraft:dirt": 3, - "minecraft:cobblestone": 4, - "minecraft:planks": 5, - "minecraft:sapling": 6, - "minecraft:bedrock": 7, - "minecraft:flowing_water": 8, - "minecraft:water": 9, - "minecraft:flowing_lava": 10, - "minecraft:lava": 11, - "minecraft:sand": 12, - "minecraft:gravel": 13, - "minecraft:gold_ore": 14, - "minecraft:iron_ore": 15, - "minecraft:coal_ore": 16, - "minecraft:log": 17, - "minecraft:leaves": 18, - "minecraft:sponge": 19, - "minecraft:glass": 20, - "minecraft:lapis_ore": 21, - "minecraft:lapis_block": 22, - "minecraft:dispenser": 23, - "minecraft:sandstone": 24, - "minecraft:noteblock": 25, - "minecraft:bed": 26, - "minecraft:golden_rail": 27, - "minecraft:detector_rail": 28, - "minecraft:sticky_piston": 29, - "minecraft:web": 30, - "minecraft:tallgrass": 31, - "minecraft:deadbush": 32, - "minecraft:piston": 33, - "minecraft:pistonArmCollision": 34, - "minecraft:wool": 35, - "minecraft:element_0": 36, - "minecraft:yellow_flower": 37, - "minecraft:red_flower": 38, - "minecraft:brown_mushroom": 39, - "minecraft:red_mushroom": 40, - "minecraft:gold_block": 41, - "minecraft:iron_block": 42, - "minecraft:double_stone_slab": 43, - "minecraft:stone_slab": 44, - "minecraft:brick_block": 45, - "minecraft:tnt": 46, - "minecraft:bookshelf": 47, - "minecraft:mossy_cobblestone": 48, - "minecraft:obsidian": 49, - "minecraft:torch": 50, - "minecraft:fire": 51, - "minecraft:mob_spawner": 52, - "minecraft:oak_stairs": 53, - "minecraft:chest": 54, - "minecraft:redstone_wire": 55, - "minecraft:diamond_ore": 56, - "minecraft:diamond_block": 57, - "minecraft:crafting_table": 58, - "minecraft:wheat": 59, - "minecraft:farmland": 60, - "minecraft:furnace": 61, - "minecraft:lit_furnace": 62, - "minecraft:standing_sign": 63, - "minecraft:wooden_door": 64, - "minecraft:ladder": 65, - "minecraft:rail": 66, - "minecraft:stone_stairs": 67, - "minecraft:wall_sign": 68, - "minecraft:lever": 69, - "minecraft:stone_pressure_plate": 70, - "minecraft:iron_door": 71, - "minecraft:wooden_pressure_plate": 72, - "minecraft:redstone_ore": 73, - "minecraft:lit_redstone_ore": 74, - "minecraft:unlit_redstone_torch": 75, - "minecraft:redstone_torch": 76, - "minecraft:stone_button": 77, - "minecraft:snow_layer": 78, - "minecraft:ice": 79, - "minecraft:snow": 80, - "minecraft:cactus": 81, - "minecraft:clay": 82, - "minecraft:reeds": 83, - "minecraft:jukebox": 84, - "minecraft:fence": 85, - "minecraft:pumpkin": 86, - "minecraft:netherrack": 87, - "minecraft:soul_sand": 88, - "minecraft:glowstone": 89, - "minecraft:portal": 90, - "minecraft:lit_pumpkin": 91, - "minecraft:cake": 92, - "minecraft:unpowered_repeater": 93, - "minecraft:powered_repeater": 94, - "minecraft:invisibleBedrock": 95, - "minecraft:trapdoor": 96, - "minecraft:monster_egg": 97, - "minecraft:stonebrick": 98, - "minecraft:brown_mushroom_block": 99, - "minecraft:red_mushroom_block": 100, - "minecraft:iron_bars": 101, - "minecraft:glass_pane": 102, - "minecraft:melon_block": 103, - "minecraft:pumpkin_stem": 104, - "minecraft:melon_stem": 105, - "minecraft:vine": 106, - "minecraft:fence_gate": 107, - "minecraft:brick_stairs": 108, - "minecraft:stone_brick_stairs": 109, - "minecraft:mycelium": 110, - "minecraft:waterlily": 111, - "minecraft:nether_brick": 112, - "minecraft:nether_brick_fence": 113, - "minecraft:nether_brick_stairs": 114, - "minecraft:nether_wart": 115, - "minecraft:enchanting_table": 116, - "minecraft:brewing_stand": 117, - "minecraft:cauldron": 118, - "minecraft:end_portal": 119, - "minecraft:end_portal_frame": 120, - "minecraft:end_stone": 121, - "minecraft:dragon_egg": 122, - "minecraft:redstone_lamp": 123, - "minecraft:lit_redstone_lamp": 124, - "minecraft:dropper": 125, - "minecraft:activator_rail": 126, - "minecraft:cocoa": 127, - "minecraft:sandstone_stairs": 128, - "minecraft:emerald_ore": 129, - "minecraft:ender_chest": 130, - "minecraft:tripwire_hook": 131, - "minecraft:tripWire": 132, - "minecraft:emerald_block": 133, - "minecraft:spruce_stairs": 134, - "minecraft:birch_stairs": 135, - "minecraft:jungle_stairs": 136, - "minecraft:command_block": 137, - "minecraft:beacon": 138, - "minecraft:cobblestone_wall": 139, - "minecraft:flower_pot": 140, - "minecraft:carrots": 141, - "minecraft:potatoes": 142, - "minecraft:wooden_button": 143, - "minecraft:skull": 144, - "minecraft:anvil": 145, - "minecraft:trapped_chest": 146, - "minecraft:light_weighted_pressure_plate": 147, - "minecraft:heavy_weighted_pressure_plate": 148, - "minecraft:unpowered_comparator": 149, - "minecraft:powered_comparator": 150, - "minecraft:daylight_detector": 151, - "minecraft:redstone_block": 152, - "minecraft:quartz_ore": 153, - "minecraft:hopper": 154, - "minecraft:quartz_block": 155, - "minecraft:quartz_stairs": 156, - "minecraft:double_wooden_slab": 157, - "minecraft:wooden_slab": 158, - "minecraft:stained_hardened_clay": 159, - "minecraft:stained_glass_pane": 160, - "minecraft:leaves2": 161, - "minecraft:log2": 162, - "minecraft:acacia_stairs": 163, - "minecraft:dark_oak_stairs": 164, - "minecraft:slime": 165, - "minecraft:iron_trapdoor": 167, - "minecraft:prismarine": 168, - "minecraft:seaLantern": 169, - "minecraft:hay_block": 170, - "minecraft:carpet": 171, - "minecraft:hardened_clay": 172, - "minecraft:coal_block": 173, - "minecraft:packed_ice": 174, - "minecraft:double_plant": 175, - "minecraft:standing_banner": 176, - "minecraft:wall_banner": 177, - "minecraft:daylight_detector_inverted": 178, - "minecraft:red_sandstone": 179, - "minecraft:red_sandstone_stairs": 180, - "minecraft:double_stone_slab2": 181, - "minecraft:stone_slab2": 182, - "minecraft:spruce_fence_gate": 183, - "minecraft:birch_fence_gate": 184, - "minecraft:jungle_fence_gate": 185, - "minecraft:dark_oak_fence_gate": 186, - "minecraft:acacia_fence_gate": 187, - "minecraft:repeating_command_block": 188, - "minecraft:chain_command_block": 189, - "minecraft:hard_glass_pane": 190, - "minecraft:hard_stained_glass_pane": 191, - "minecraft:chemical_heat": 192, - "minecraft:spruce_door": 193, - "minecraft:birch_door": 194, - "minecraft:jungle_door": 195, - "minecraft:acacia_door": 196, - "minecraft:dark_oak_door": 197, - "minecraft:grass_path": 198, - "minecraft:frame": 199, - "minecraft:chorus_flower": 200, - "minecraft:purpur_block": 201, - "minecraft:colored_torch_rg": 202, - "minecraft:purpur_stairs": 203, - "minecraft:colored_torch_bp": 204, - "minecraft:undyed_shulker_box": 205, - "minecraft:end_bricks": 206, - "minecraft:frosted_ice": 207, - "minecraft:end_rod": 208, - "minecraft:end_gateway": 209, - "minecraft:magma": 213, - "minecraft:nether_wart_block": 214, - "minecraft:red_nether_brick": 215, - "minecraft:bone_block": 216, - "minecraft:shulker_box": 218, - "minecraft:purple_glazed_terracotta": 219, - "minecraft:white_glazed_terracotta": 220, - "minecraft:orange_glazed_terracotta": 221, - "minecraft:magenta_glazed_terracotta": 222, - "minecraft:light_blue_glazed_terracotta": 223, - "minecraft:yellow_glazed_terracotta": 224, - "minecraft:lime_glazed_terracotta": 225, - "minecraft:pink_glazed_terracotta": 226, - "minecraft:gray_glazed_terracotta": 227, - "minecraft:silver_glazed_terracotta": 228, - "minecraft:cyan_glazed_terracotta": 229, - "minecraft:blue_glazed_terracotta": 231, - "minecraft:brown_glazed_terracotta": 232, - "minecraft:green_glazed_terracotta": 233, - "minecraft:red_glazed_terracotta": 234, - "minecraft:black_glazed_terracotta": 235, - "minecraft:concrete": 236, - "minecraft:concretePowder": 237, - "minecraft:chemistry_table": 238, - "minecraft:underwater_torch": 239, - "minecraft:chorus_plant": 240, - "minecraft:stained_glass": 241, - "minecraft:podzol": 243, - "minecraft:beetroot": 244, - "minecraft:stonecutter": 245, - "minecraft:glowingobsidian": 246, - "minecraft:netherreactor": 247, - "minecraft:info_update": 248, - "minecraft:info_update2": 249, - "minecraft:movingBlock": 250, - "minecraft:observer": 251, - "minecraft:structure_block": 252, - "minecraft:hard_glass": 253, - "minecraft:hard_stained_glass": 254, - "minecraft:reserved6": 255, - "minecraft:prismarine_stairs": 257, - "minecraft:dark_prismarine_stairs": 258, - "minecraft:prismarine_bricks_stairs": 259, - "minecraft:stripped_spruce_log": 260, - "minecraft:stripped_birch_log": 261, - "minecraft:stripped_jungle_log": 262, - "minecraft:stripped_acacia_log": 263, - "minecraft:stripped_dark_oak_log": 264, - "minecraft:stripped_oak_log": 265, - "minecraft:blue_ice": 266, - "minecraft:element_1": 267, - "minecraft:element_2": 268, - "minecraft:element_3": 269, - "minecraft:element_4": 270, - "minecraft:element_5": 271, - "minecraft:element_6": 272, - "minecraft:element_7": 273, - "minecraft:element_8": 274, - "minecraft:element_9": 275, - "minecraft:element_10": 276, - "minecraft:element_11": 277, - "minecraft:element_12": 278, - "minecraft:element_13": 279, - "minecraft:element_14": 280, - "minecraft:element_15": 281, - "minecraft:element_16": 282, - "minecraft:element_17": 283, - "minecraft:element_18": 284, - "minecraft:element_19": 285, - "minecraft:element_20": 286, - "minecraft:element_21": 287, - "minecraft:element_22": 288, - "minecraft:element_23": 289, - "minecraft:element_24": 290, - "minecraft:element_25": 291, - "minecraft:element_26": 292, - "minecraft:element_27": 293, - "minecraft:element_28": 294, - "minecraft:element_29": 295, - "minecraft:element_30": 296, - "minecraft:element_31": 297, - "minecraft:element_32": 298, - "minecraft:element_33": 299, - "minecraft:element_34": 300, - "minecraft:element_35": 301, - "minecraft:element_36": 302, - "minecraft:element_37": 303, - "minecraft:element_38": 304, - "minecraft:element_39": 305, - "minecraft:element_40": 306, - "minecraft:element_41": 307, - "minecraft:element_42": 308, - "minecraft:element_43": 309, - "minecraft:element_44": 310, - "minecraft:element_45": 311, - "minecraft:element_46": 312, - "minecraft:element_47": 313, - "minecraft:element_48": 314, - "minecraft:element_49": 315, - "minecraft:element_50": 316, - "minecraft:element_51": 317, - "minecraft:element_52": 318, - "minecraft:element_53": 319, - "minecraft:element_54": 320, - "minecraft:element_55": 321, - "minecraft:element_56": 322, - "minecraft:element_57": 323, - "minecraft:element_58": 324, - "minecraft:element_59": 325, - "minecraft:element_60": 326, - "minecraft:element_61": 327, - "minecraft:element_62": 328, - "minecraft:element_63": 329, - "minecraft:element_64": 330, - "minecraft:element_65": 331, - "minecraft:element_66": 332, - "minecraft:element_67": 333, - "minecraft:element_68": 334, - "minecraft:element_69": 335, - "minecraft:element_70": 336, - "minecraft:element_71": 337, - "minecraft:element_72": 338, - "minecraft:element_73": 339, - "minecraft:element_74": 340, - "minecraft:element_75": 341, - "minecraft:element_76": 342, - "minecraft:element_77": 343, - "minecraft:element_78": 344, - "minecraft:element_79": 345, - "minecraft:element_80": 346, - "minecraft:element_81": 347, - "minecraft:element_82": 348, - "minecraft:element_83": 349, - "minecraft:element_84": 350, - "minecraft:element_85": 351, - "minecraft:element_86": 352, - "minecraft:element_87": 353, - "minecraft:element_88": 354, - "minecraft:element_89": 355, - "minecraft:element_90": 356, - "minecraft:element_91": 357, - "minecraft:element_92": 358, - "minecraft:element_93": 359, - "minecraft:element_94": 360, - "minecraft:element_95": 361, - "minecraft:element_96": 362, - "minecraft:element_97": 363, - "minecraft:element_98": 364, - "minecraft:element_99": 365, - "minecraft:element_100": 366, - "minecraft:element_101": 367, - "minecraft:element_102": 368, - "minecraft:element_103": 369, - "minecraft:element_104": 370, - "minecraft:element_105": 371, - "minecraft:element_106": 372, - "minecraft:element_107": 373, - "minecraft:element_108": 374, - "minecraft:element_109": 375, - "minecraft:element_110": 376, - "minecraft:element_111": 377, - "minecraft:element_112": 378, - "minecraft:element_113": 379, - "minecraft:element_114": 380, - "minecraft:element_115": 381, - "minecraft:element_116": 382, - "minecraft:element_117": 383, - "minecraft:element_118": 384, - "minecraft:seagrass": 385, - "minecraft:coral": 386, - "minecraft:coral_block": 387, - "minecraft:coral_fan": 388, - "minecraft:coral_fan_dead": 389, - "minecraft:coral_fan_hang": 390, - "minecraft:coral_fan_hang2": 391, - "minecraft:coral_fan_hang3": 392, - "minecraft:kelp": 393, - "minecraft:dried_kelp_block": 394, - "minecraft:acacia_button": 395, - "minecraft:birch_button": 396, - "minecraft:dark_oak_button": 397, - "minecraft:jungle_button": 398, - "minecraft:spruce_button": 399, - "minecraft:acacia_trapdoor": 400, - "minecraft:birch_trapdoor": 401, - "minecraft:dark_oak_trapdoor": 402, - "minecraft:jungle_trapdoor": 403, - "minecraft:spruce_trapdoor": 404, - "minecraft:acacia_pressure_plate": 405, - "minecraft:birch_pressure_plate": 406, - "minecraft:dark_oak_pressure_plate": 407, - "minecraft:jungle_pressure_plate": 408, - "minecraft:spruce_pressure_plate": 409, - "minecraft:carved_pumpkin": 410, - "minecraft:sea_pickle": 411, - "minecraft:conduit": 412, - "minecraft:turtle_egg": 414, - "minecraft:bubble_column": 415, - "minecraft:barrier": 416, - "minecraft:stone_slab3": 417, - "minecraft:bamboo": 418, - "minecraft:bamboo_sapling": 419, - "minecraft:scaffolding": 420, - "minecraft:stone_slab4": 421, - "minecraft:double_stone_slab3": 422, - "minecraft:double_stone_slab4": 423, - "minecraft:granite_stairs": 424, - "minecraft:diorite_stairs": 425, - "minecraft:andesite_stairs": 426, - "minecraft:polished_granite_stairs": 427, - "minecraft:polished_diorite_stairs": 428, - "minecraft:polished_andesite_stairs": 429, - "minecraft:mossy_stone_brick_stairs": 430, - "minecraft:smooth_red_sandstone_stairs": 431, - "minecraft:smooth_sandstone_stairs": 432, - "minecraft:end_brick_stairs": 433, - "minecraft:mossy_cobblestone_stairs": 434, - "minecraft:normal_stone_stairs": 435, - "minecraft:spruce_standing_sign": 436, - "minecraft:spruce_wall_sign": 437, - "minecraft:smooth_stone": 438, - "minecraft:red_nether_brick_stairs": 439, - "minecraft:smooth_quartz_stairs": 440, - "minecraft:birch_standing_sign": 441, - "minecraft:birch_wall_sign": 442, - "minecraft:jungle_standing_sign": 443, - "minecraft:jungle_wall_sign": 444, - "minecraft:acacia_standing_sign": 445, - "minecraft:acacia_wall_sign": 446, - "minecraft:darkoak_standing_sign": 447, - "minecraft:darkoak_wall_sign": 448, - "minecraft:lectern": 449, - "minecraft:grindstone": 450, - "minecraft:blast_furnace": 451, - "minecraft:stonecutter_block": 452, - "minecraft:smoker": 453, - "minecraft:lit_smoker": 454, - "minecraft:cartography_table": 455, - "minecraft:fletching_table": 456, - "minecraft:smithing_table": 457, - "minecraft:barrel": 458, - "minecraft:loom": 459, - "minecraft:bell": 461, - "minecraft:sweet_berry_bush": 462, - "minecraft:lantern": 463, - "minecraft:campfire": 464, - "minecraft:lava_cauldron": 465, - "minecraft:jigsaw": 466, - "minecraft:wood": 467, - "minecraft:composter": 468, - "minecraft:lit_blast_furnace": 469 + "minecraft:air" : 0, + "minecraft:stone" : 1, + "minecraft:grass" : 2, + "minecraft:dirt" : 3, + "minecraft:cobblestone" : 4, + "minecraft:planks" : 5, + "minecraft:sapling" : 6, + "minecraft:bedrock" : 7, + "minecraft:flowing_water" : 8, + "minecraft:water" : 9, + "minecraft:flowing_lava" : 10, + "minecraft:lava" : 11, + "minecraft:sand" : 12, + "minecraft:gravel" : 13, + "minecraft:gold_ore" : 14, + "minecraft:iron_ore" : 15, + "minecraft:coal_ore" : 16, + "minecraft:log" : 17, + "minecraft:leaves" : 18, + "minecraft:sponge" : 19, + "minecraft:glass" : 20, + "minecraft:lapis_ore" : 21, + "minecraft:lapis_block" : 22, + "minecraft:dispenser" : 23, + "minecraft:sandstone" : 24, + "minecraft:noteblock" : 25, + "minecraft:bed" : 26, + "minecraft:golden_rail" : 27, + "minecraft:detector_rail" : 28, + "minecraft:sticky_piston" : 29, + "minecraft:web" : 30, + "minecraft:tallgrass" : 31, + "minecraft:deadbush" : 32, + "minecraft:piston" : 33, + "minecraft:pistonArmCollision" : 34, + "minecraft:wool" : 35, + "minecraft:element_0" : 36, + "minecraft:yellow_flower" : 37, + "minecraft:red_flower" : 38, + "minecraft:brown_mushroom" : 39, + "minecraft:red_mushroom" : 40, + "minecraft:gold_block" : 41, + "minecraft:iron_block" : 42, + "minecraft:double_stone_slab" : 43, + "minecraft:stone_slab" : 44, + "minecraft:brick_block" : 45, + "minecraft:tnt" : 46, + "minecraft:bookshelf" : 47, + "minecraft:mossy_cobblestone" : 48, + "minecraft:obsidian" : 49, + "minecraft:torch" : 50, + "minecraft:fire" : 51, + "minecraft:mob_spawner" : 52, + "minecraft:oak_stairs" : 53, + "minecraft:chest" : 54, + "minecraft:redstone_wire" : 55, + "minecraft:diamond_ore" : 56, + "minecraft:diamond_block" : 57, + "minecraft:crafting_table" : 58, + "minecraft:wheat" : 59, + "minecraft:farmland" : 60, + "minecraft:furnace" : 61, + "minecraft:lit_furnace" : 62, + "minecraft:standing_sign" : 63, + "minecraft:wooden_door" : 64, + "minecraft:ladder" : 65, + "minecraft:rail" : 66, + "minecraft:stone_stairs" : 67, + "minecraft:wall_sign" : 68, + "minecraft:lever" : 69, + "minecraft:stone_pressure_plate" : 70, + "minecraft:iron_door" : 71, + "minecraft:wooden_pressure_plate" : 72, + "minecraft:redstone_ore" : 73, + "minecraft:lit_redstone_ore" : 74, + "minecraft:unlit_redstone_torch" : 75, + "minecraft:redstone_torch" : 76, + "minecraft:stone_button" : 77, + "minecraft:snow_layer" : 78, + "minecraft:ice" : 79, + "minecraft:snow" : 80, + "minecraft:cactus" : 81, + "minecraft:clay" : 82, + "minecraft:reeds" : 83, + "minecraft:jukebox" : 84, + "minecraft:fence" : 85, + "minecraft:pumpkin" : 86, + "minecraft:netherrack" : 87, + "minecraft:soul_sand" : 88, + "minecraft:glowstone" : 89, + "minecraft:portal" : 90, + "minecraft:lit_pumpkin" : 91, + "minecraft:cake" : 92, + "minecraft:unpowered_repeater" : 93, + "minecraft:powered_repeater" : 94, + "minecraft:invisibleBedrock" : 95, + "minecraft:trapdoor" : 96, + "minecraft:monster_egg" : 97, + "minecraft:stonebrick" : 98, + "minecraft:brown_mushroom_block" : 99, + "minecraft:red_mushroom_block" : 100, + "minecraft:iron_bars" : 101, + "minecraft:glass_pane" : 102, + "minecraft:melon_block" : 103, + "minecraft:pumpkin_stem" : 104, + "minecraft:melon_stem" : 105, + "minecraft:vine" : 106, + "minecraft:fence_gate" : 107, + "minecraft:brick_stairs" : 108, + "minecraft:stone_brick_stairs" : 109, + "minecraft:mycelium" : 110, + "minecraft:waterlily" : 111, + "minecraft:nether_brick" : 112, + "minecraft:nether_brick_fence" : 113, + "minecraft:nether_brick_stairs" : 114, + "minecraft:nether_wart" : 115, + "minecraft:enchanting_table" : 116, + "minecraft:brewing_stand" : 117, + "minecraft:cauldron" : 118, + "minecraft:end_portal" : 119, + "minecraft:end_portal_frame" : 120, + "minecraft:end_stone" : 121, + "minecraft:dragon_egg" : 122, + "minecraft:redstone_lamp" : 123, + "minecraft:lit_redstone_lamp" : 124, + "minecraft:dropper" : 125, + "minecraft:activator_rail" : 126, + "minecraft:cocoa" : 127, + "minecraft:sandstone_stairs" : 128, + "minecraft:emerald_ore" : 129, + "minecraft:ender_chest" : 130, + "minecraft:tripwire_hook" : 131, + "minecraft:tripWire" : 132, + "minecraft:emerald_block" : 133, + "minecraft:spruce_stairs" : 134, + "minecraft:birch_stairs" : 135, + "minecraft:jungle_stairs" : 136, + "minecraft:command_block" : 137, + "minecraft:beacon" : 138, + "minecraft:cobblestone_wall" : 139, + "minecraft:flower_pot" : 140, + "minecraft:carrots" : 141, + "minecraft:potatoes" : 142, + "minecraft:wooden_button" : 143, + "minecraft:skull" : 144, + "minecraft:anvil" : 145, + "minecraft:trapped_chest" : 146, + "minecraft:light_weighted_pressure_plate" : 147, + "minecraft:heavy_weighted_pressure_plate" : 148, + "minecraft:unpowered_comparator" : 149, + "minecraft:powered_comparator" : 150, + "minecraft:daylight_detector" : 151, + "minecraft:redstone_block" : 152, + "minecraft:quartz_ore" : 153, + "minecraft:hopper" : 154, + "minecraft:quartz_block" : 155, + "minecraft:quartz_stairs" : 156, + "minecraft:double_wooden_slab" : 157, + "minecraft:wooden_slab" : 158, + "minecraft:stained_hardened_clay" : 159, + "minecraft:stained_glass_pane" : 160, + "minecraft:leaves2" : 161, + "minecraft:log2" : 162, + "minecraft:acacia_stairs" : 163, + "minecraft:dark_oak_stairs" : 164, + "minecraft:slime" : 165, + "minecraft:iron_trapdoor" : 167, + "minecraft:prismarine" : 168, + "minecraft:seaLantern" : 169, + "minecraft:hay_block" : 170, + "minecraft:carpet" : 171, + "minecraft:hardened_clay" : 172, + "minecraft:coal_block" : 173, + "minecraft:packed_ice" : 174, + "minecraft:double_plant" : 175, + "minecraft:standing_banner" : 176, + "minecraft:wall_banner" : 177, + "minecraft:daylight_detector_inverted" : 178, + "minecraft:red_sandstone" : 179, + "minecraft:red_sandstone_stairs" : 180, + "minecraft:double_stone_slab2" : 181, + "minecraft:stone_slab2" : 182, + "minecraft:spruce_fence_gate" : 183, + "minecraft:birch_fence_gate" : 184, + "minecraft:jungle_fence_gate" : 185, + "minecraft:dark_oak_fence_gate" : 186, + "minecraft:acacia_fence_gate" : 187, + "minecraft:repeating_command_block" : 188, + "minecraft:chain_command_block" : 189, + "minecraft:hard_glass_pane" : 190, + "minecraft:hard_stained_glass_pane" : 191, + "minecraft:chemical_heat" : 192, + "minecraft:spruce_door" : 193, + "minecraft:birch_door" : 194, + "minecraft:jungle_door" : 195, + "minecraft:acacia_door" : 196, + "minecraft:dark_oak_door" : 197, + "minecraft:grass_path" : 198, + "minecraft:frame" : 199, + "minecraft:chorus_flower" : 200, + "minecraft:purpur_block" : 201, + "minecraft:colored_torch_rg" : 202, + "minecraft:purpur_stairs" : 203, + "minecraft:colored_torch_bp" : 204, + "minecraft:undyed_shulker_box" : 205, + "minecraft:end_bricks" : 206, + "minecraft:frosted_ice" : 207, + "minecraft:end_rod" : 208, + "minecraft:end_gateway" : 209, + "minecraft:allow" : 210, + "minecraft:deny" : 211, + "minecraft:border_block" : 212, + "minecraft:magma" : 213, + "minecraft:nether_wart_block" : 214, + "minecraft:red_nether_brick" : 215, + "minecraft:bone_block" : 216, + "minecraft:structure_void" : 217, + "minecraft:shulker_box" : 218, + "minecraft:purple_glazed_terracotta" : 219, + "minecraft:white_glazed_terracotta" : 220, + "minecraft:orange_glazed_terracotta" : 221, + "minecraft:magenta_glazed_terracotta" : 222, + "minecraft:light_blue_glazed_terracotta" : 223, + "minecraft:yellow_glazed_terracotta" : 224, + "minecraft:lime_glazed_terracotta" : 225, + "minecraft:pink_glazed_terracotta" : 226, + "minecraft:gray_glazed_terracotta" : 227, + "minecraft:silver_glazed_terracotta" : 228, + "minecraft:cyan_glazed_terracotta" : 229, + "minecraft:blue_glazed_terracotta" : 231, + "minecraft:brown_glazed_terracotta" : 232, + "minecraft:green_glazed_terracotta" : 233, + "minecraft:red_glazed_terracotta" : 234, + "minecraft:black_glazed_terracotta" : 235, + "minecraft:concrete" : 236, + "minecraft:concretePowder" : 237, + "minecraft:chemistry_table" : 238, + "minecraft:underwater_torch" : 239, + "minecraft:chorus_plant" : 240, + "minecraft:stained_glass" : 241, + "minecraft:camera" : 242, + "minecraft:podzol" : 243, + "minecraft:beetroot" : 244, + "minecraft:stonecutter" : 245, + "minecraft:glowingobsidian" : 246, + "minecraft:netherreactor" : 247, + "minecraft:info_update" : 248, + "minecraft:info_update2" : 249, + "minecraft:movingBlock" : 250, + "minecraft:observer" : 251, + "minecraft:structure_block" : 252, + "minecraft:hard_glass" : 253, + "minecraft:hard_stained_glass" : 254, + "minecraft:reserved6" : 255, + "minecraft:prismarine_stairs" : 257, + "minecraft:dark_prismarine_stairs" : 258, + "minecraft:prismarine_bricks_stairs" : 259, + "minecraft:stripped_spruce_log" : 260, + "minecraft:stripped_birch_log" : 261, + "minecraft:stripped_jungle_log" : 262, + "minecraft:stripped_acacia_log" : 263, + "minecraft:stripped_dark_oak_log" : 264, + "minecraft:stripped_oak_log" : 265, + "minecraft:blue_ice" : 266, + "minecraft:element_1" : 267, + "minecraft:element_2" : 268, + "minecraft:element_3" : 269, + "minecraft:element_4" : 270, + "minecraft:element_5" : 271, + "minecraft:element_6" : 272, + "minecraft:element_7" : 273, + "minecraft:element_8" : 274, + "minecraft:element_9" : 275, + "minecraft:element_10" : 276, + "minecraft:element_11" : 277, + "minecraft:element_12" : 278, + "minecraft:element_13" : 279, + "minecraft:element_14" : 280, + "minecraft:element_15" : 281, + "minecraft:element_16" : 282, + "minecraft:element_17" : 283, + "minecraft:element_18" : 284, + "minecraft:element_19" : 285, + "minecraft:element_20" : 286, + "minecraft:element_21" : 287, + "minecraft:element_22" : 288, + "minecraft:element_23" : 289, + "minecraft:element_24" : 290, + "minecraft:element_25" : 291, + "minecraft:element_26" : 292, + "minecraft:element_27" : 293, + "minecraft:element_28" : 294, + "minecraft:element_29" : 295, + "minecraft:element_30" : 296, + "minecraft:element_31" : 297, + "minecraft:element_32" : 298, + "minecraft:element_33" : 299, + "minecraft:element_34" : 300, + "minecraft:element_35" : 301, + "minecraft:element_36" : 302, + "minecraft:element_37" : 303, + "minecraft:element_38" : 304, + "minecraft:element_39" : 305, + "minecraft:element_40" : 306, + "minecraft:element_41" : 307, + "minecraft:element_42" : 308, + "minecraft:element_43" : 309, + "minecraft:element_44" : 310, + "minecraft:element_45" : 311, + "minecraft:element_46" : 312, + "minecraft:element_47" : 313, + "minecraft:element_48" : 314, + "minecraft:element_49" : 315, + "minecraft:element_50" : 316, + "minecraft:element_51" : 317, + "minecraft:element_52" : 318, + "minecraft:element_53" : 319, + "minecraft:element_54" : 320, + "minecraft:element_55" : 321, + "minecraft:element_56" : 322, + "minecraft:element_57" : 323, + "minecraft:element_58" : 324, + "minecraft:element_59" : 325, + "minecraft:element_60" : 326, + "minecraft:element_61" : 327, + "minecraft:element_62" : 328, + "minecraft:element_63" : 329, + "minecraft:element_64" : 330, + "minecraft:element_65" : 331, + "minecraft:element_66" : 332, + "minecraft:element_67" : 333, + "minecraft:element_68" : 334, + "minecraft:element_69" : 335, + "minecraft:element_70" : 336, + "minecraft:element_71" : 337, + "minecraft:element_72" : 338, + "minecraft:element_73" : 339, + "minecraft:element_74" : 340, + "minecraft:element_75" : 341, + "minecraft:element_76" : 342, + "minecraft:element_77" : 343, + "minecraft:element_78" : 344, + "minecraft:element_79" : 345, + "minecraft:element_80" : 346, + "minecraft:element_81" : 347, + "minecraft:element_82" : 348, + "minecraft:element_83" : 349, + "minecraft:element_84" : 350, + "minecraft:element_85" : 351, + "minecraft:element_86" : 352, + "minecraft:element_87" : 353, + "minecraft:element_88" : 354, + "minecraft:element_89" : 355, + "minecraft:element_90" : 356, + "minecraft:element_91" : 357, + "minecraft:element_92" : 358, + "minecraft:element_93" : 359, + "minecraft:element_94" : 360, + "minecraft:element_95" : 361, + "minecraft:element_96" : 362, + "minecraft:element_97" : 363, + "minecraft:element_98" : 364, + "minecraft:element_99" : 365, + "minecraft:element_100" : 366, + "minecraft:element_101" : 367, + "minecraft:element_102" : 368, + "minecraft:element_103" : 369, + "minecraft:element_104" : 370, + "minecraft:element_105" : 371, + "minecraft:element_106" : 372, + "minecraft:element_107" : 373, + "minecraft:element_108" : 374, + "minecraft:element_109" : 375, + "minecraft:element_110" : 376, + "minecraft:element_111" : 377, + "minecraft:element_112" : 378, + "minecraft:element_113" : 379, + "minecraft:element_114" : 380, + "minecraft:element_115" : 381, + "minecraft:element_116" : 382, + "minecraft:element_117" : 383, + "minecraft:element_118" : 384, + "minecraft:seagrass" : 385, + "minecraft:coral" : 386, + "minecraft:coral_block" : 387, + "minecraft:coral_fan" : 388, + "minecraft:coral_fan_dead" : 389, + "minecraft:coral_fan_hang" : 390, + "minecraft:coral_fan_hang2" : 391, + "minecraft:coral_fan_hang3" : 392, + "minecraft:kelp" : 393, + "minecraft:dried_kelp_block" : 394, + "minecraft:acacia_button" : 395, + "minecraft:birch_button" : 396, + "minecraft:dark_oak_button" : 397, + "minecraft:jungle_button" : 398, + "minecraft:spruce_button" : 399, + "minecraft:acacia_trapdoor" : 400, + "minecraft:birch_trapdoor" : 401, + "minecraft:dark_oak_trapdoor" : 402, + "minecraft:jungle_trapdoor" : 403, + "minecraft:spruce_trapdoor" : 404, + "minecraft:acacia_pressure_plate" : 405, + "minecraft:birch_pressure_plate" : 406, + "minecraft:dark_oak_pressure_plate" : 407, + "minecraft:jungle_pressure_plate" : 408, + "minecraft:spruce_pressure_plate" : 409, + "minecraft:carved_pumpkin" : 410, + "minecraft:sea_pickle" : 411, + "minecraft:conduit" : 412, + "minecraft:turtle_egg" : 414, + "minecraft:bubble_column" : 415, + "minecraft:barrier" : 416, + "minecraft:stone_slab3" : 417, + "minecraft:bamboo" : 418, + "minecraft:bamboo_sapling" : 419, + "minecraft:scaffolding" : 420, + "minecraft:stone_slab4" : 421, + "minecraft:double_stone_slab3" : 422, + "minecraft:double_stone_slab4" : 423, + "minecraft:granite_stairs" : 424, + "minecraft:diorite_stairs" : 425, + "minecraft:andesite_stairs" : 426, + "minecraft:polished_granite_stairs" : 427, + "minecraft:polished_diorite_stairs" : 428, + "minecraft:polished_andesite_stairs" : 429, + "minecraft:mossy_stone_brick_stairs" : 430, + "minecraft:smooth_red_sandstone_stairs" : 431, + "minecraft:smooth_sandstone_stairs" : 432, + "minecraft:end_brick_stairs" : 433, + "minecraft:mossy_cobblestone_stairs" : 434, + "minecraft:normal_stone_stairs" : 435, + "minecraft:spruce_standing_sign" : 436, + "minecraft:spruce_wall_sign" : 437, + "minecraft:smooth_stone" : 438, + "minecraft:red_nether_brick_stairs" : 439, + "minecraft:smooth_quartz_stairs" : 440, + "minecraft:birch_standing_sign" : 441, + "minecraft:birch_wall_sign" : 442, + "minecraft:jungle_standing_sign" : 443, + "minecraft:jungle_wall_sign" : 444, + "minecraft:acacia_standing_sign" : 445, + "minecraft:acacia_wall_sign" : 446, + "minecraft:darkoak_standing_sign" : 447, + "minecraft:darkoak_wall_sign" : 448, + "minecraft:lectern" : 449, + "minecraft:grindstone" : 450, + "minecraft:blast_furnace" : 451, + "minecraft:stonecutter_block" : 452, + "minecraft:smoker" : 453, + "minecraft:lit_smoker" : 454, + "minecraft:cartography_table" : 455, + "minecraft:fletching_table" : 456, + "minecraft:smithing_table" : 457, + "minecraft:barrel" : 458, + "minecraft:loom" : 459, + "minecraft:bell" : 461, + "minecraft:sweet_berry_bush" : 462, + "minecraft:lantern" : 463, + "minecraft:campfire" : 464, + "minecraft:lava_cauldron" : 465, + "minecraft:jigsaw" : 466, + "minecraft:wood" : 467, + "minecraft:composter" : 468, + "minecraft:lit_blast_furnace" : 469, + "minecraft:light_block" : 470, + "minecraft:wither_rose" : 471, + "minecraft:stickyPistonArmCollision" : 472, + "minecraft:bee_nest" : 473, + "minecraft:beehive" : 474, + "minecraft:honey_block" : 475, + "minecraft:honeycomb_block" : 476, + "minecraft:lodestone" : 477, + "minecraft:crimson_roots" : 478, + "minecraft:warped_roots" : 479, + "minecraft:crimson_stem" : 480, + "minecraft:warped_stem" : 481, + "minecraft:warped_wart_block" : 482, + "minecraft:crimson_fungus" : 483, + "minecraft:warped_fungus" : 484, + "minecraft:shroomlight" : 485, + "minecraft:weeping_vines" : 486, + "minecraft:crimson_nylium" : 487, + "minecraft:warped_nylium" : 488, + "minecraft:basalt" : 489, + "minecraft:polished_basalt" : 490, + "minecraft:soul_soil" : 491, + "minecraft:soul_fire" : 492, + "minecraft:nether_sprouts" : 493, + "minecraft:target" : 494, + "minecraft:stripped_crimson_stem" : 495, + "minecraft:stripped_warped_stem" : 496, + "minecraft:crimson_planks" : 497, + "minecraft:warped_planks" : 498, + "minecraft:crimson_door" : 499, + "minecraft:warped_door" : 500, + "minecraft:crimson_trapdoor" : 501, + "minecraft:warped_trapdoor" : 502, + "minecraft:crimson_standing_sign" : 505, + "minecraft:warped_standing_sign" : 506, + "minecraft:crimson_wall_sign" : 507, + "minecraft:warped_wall_sign" : 508, + "minecraft:crimson_stairs" : 509, + "minecraft:warped_stairs" : 510, + "minecraft:crimson_fence" : 511, + "minecraft:warped_fence" : 512, + "minecraft:crimson_fence_gate" : 513, + "minecraft:warped_fence_gate" : 514, + "minecraft:crimson_button" : 515, + "minecraft:warped_button" : 516, + "minecraft:crimson_pressure_plate" : 517, + "minecraft:warped_pressure_plate" : 518, + "minecraft:crimson_slab" : 519, + "minecraft:warped_slab" : 520, + "minecraft:crimson_double_slab" : 521, + "minecraft:warped_double_slab" : 522, + "minecraft:soul_torch" : 523, + "minecraft:soul_lantern" : 524, + "minecraft:netherite_block" : 525, + "minecraft:ancient_debris" : 526, + "minecraft:respawn_anchor" : 527, + "minecraft:blackstone" : 528, + "minecraft:polished_blackstone_bricks" : 529, + "minecraft:polished_blackstone_brick_stairs" : 530, + "minecraft:blackstone_stairs" : 531, + "minecraft:blackstone_wall" : 532, + "minecraft:polished_blackstone_brick_wall" : 533, + "minecraft:chiseled_polished_blackstone" : 534, + "minecraft:cracked_polished_blackstone_bricks" : 535, + "minecraft:gilded_blackstone" : 536, + "minecraft:blackstone_slab" : 537, + "minecraft:blackstone_double_slab" : 538, + "minecraft:polished_blackstone_brick_slab" : 539, + "minecraft:polished_blackstone_brick_double_slab" : 540, + "minecraft:chain" : 541, + "minecraft:twisting_vines" : 542, + "minecraft:nether_gold_ore" : 543, + "minecraft:crying_obsidian" : 544, + "minecraft:soul_campfire" : 545, + "minecraft:polished_blackstone" : 546, + "minecraft:polished_blackstone_stairs" : 547, + "minecraft:polished_blackstone_slab" : 548, + "minecraft:polished_blackstone_double_slab" : 549, + "minecraft:polished_blackstone_pressure_plate" : 550, + "minecraft:polished_blackstone_button" : 551, + "minecraft:polished_blackstone_wall" : 552, + "minecraft:warped_hyphae" : 553, + "minecraft:crimson_hyphae" : 554, + "minecraft:stripped_crimson_hyphae" : 555, + "minecraft:stripped_warped_hyphae" : 556, + "minecraft:chiseled_nether_bricks" : 557, + "minecraft:cracked_nether_bricks" : 558, + "minecraft:quartz_bricks" : 559 } \ No newline at end of file diff --git a/connector/src/main/resources/bedrock/legacy_item_ids.json b/connector/src/main/resources/bedrock/legacy_item_ids.json index 21989249c7c..3f22c91c399 100644 --- a/connector/src/main/resources/bedrock/legacy_item_ids.json +++ b/connector/src/main/resources/bedrock/legacy_item_ids.json @@ -1,229 +1,255 @@ { - "minecraft:iron_shovel": 256, - "minecraft:iron_pickaxe": 257, - "minecraft:iron_axe": 258, - "minecraft:flint_and_steel": 259, - "minecraft:apple": 260, - "minecraft:bow": 261, - "minecraft:arrow": 262, - "minecraft:coal": 263, - "minecraft:diamond": 264, - "minecraft:iron_ingot": 265, - "minecraft:gold_ingot": 266, - "minecraft:iron_sword": 267, - "minecraft:wooden_sword": 268, - "minecraft:wooden_shovel": 269, - "minecraft:wooden_pickaxe": 270, - "minecraft:wooden_axe": 271, - "minecraft:stone_sword": 272, - "minecraft:stone_shovel": 273, - "minecraft:stone_pickaxe": 274, - "minecraft:stone_axe": 275, - "minecraft:diamond_sword": 276, - "minecraft:diamond_shovel": 277, - "minecraft:diamond_pickaxe": 278, - "minecraft:diamond_axe": 279, - "minecraft:stick": 280, - "minecraft:bowl": 281, - "minecraft:mushroom_stew": 282, - "minecraft:golden_sword": 283, - "minecraft:golden_shovel": 284, - "minecraft:golden_pickaxe": 285, - "minecraft:golden_axe": 286, - "minecraft:string": 287, - "minecraft:feather": 288, - "minecraft:gunpowder": 289, - "minecraft:wooden_hoe": 290, - "minecraft:stone_hoe": 291, - "minecraft:iron_hoe": 292, - "minecraft:diamond_hoe": 293, - "minecraft:golden_hoe": 294, - "minecraft:wheat_seeds": 295, - "minecraft:wheat": 296, - "minecraft:bread": 297, - "minecraft:leather_helmet": 298, - "minecraft:leather_chestplate": 299, - "minecraft:leather_leggings": 300, - "minecraft:leather_boots": 301, - "minecraft:chainmail_helmet": 302, - "minecraft:chainmail_chestplate": 303, - "minecraft:chainmail_leggings": 304, - "minecraft:chainmail_boots": 305, - "minecraft:iron_helmet": 306, - "minecraft:iron_chestplate": 307, - "minecraft:iron_leggings": 308, - "minecraft:iron_boots": 309, - "minecraft:diamond_helmet": 310, - "minecraft:diamond_chestplate": 311, - "minecraft:diamond_leggings": 312, - "minecraft:diamond_boots": 313, - "minecraft:golden_helmet": 314, - "minecraft:golden_chestplate": 315, - "minecraft:golden_leggings": 316, - "minecraft:golden_boots": 317, - "minecraft:flint": 318, - "minecraft:porkchop": 319, - "minecraft:cooked_porkchop": 320, - "minecraft:painting": 321, - "minecraft:golden_apple": 322, - "minecraft:sign": 323, - "minecraft:wooden_door": 324, - "minecraft:bucket": 325, - "minecraft:minecart": 328, - "minecraft:saddle": 329, - "minecraft:iron_door": 330, - "minecraft:redstone": 331, - "minecraft:snowball": 332, - "minecraft:boat": 333, - "minecraft:leather": 334, - "minecraft:kelp": 335, - "minecraft:brick": 336, - "minecraft:clay_ball": 337, - "minecraft:reeds": 338, - "minecraft:paper": 339, - "minecraft:book": 340, - "minecraft:slime_ball": 341, - "minecraft:chest_minecart": 342, - "minecraft:egg": 344, - "minecraft:compass": 345, - "minecraft:fishing_rod": 346, - "minecraft:clock": 347, - "minecraft:glowstone_dust": 348, - "minecraft:fish": 349, - "minecraft:cooked_fish": 350, - "minecraft:dye": 351, - "minecraft:bone": 352, - "minecraft:sugar": 353, - "minecraft:cake": 354, - "minecraft:bed": 355, - "minecraft:repeater": 356, - "minecraft:cookie": 357, - "minecraft:map": 358, - "minecraft:shears": 359, - "minecraft:melon": 360, - "minecraft:pumpkin_seeds": 361, - "minecraft:melon_seeds": 362, - "minecraft:beef": 363, - "minecraft:cooked_beef": 364, - "minecraft:chicken": 365, - "minecraft:cooked_chicken": 366, - "minecraft:rotten_flesh": 367, - "minecraft:ender_pearl": 368, - "minecraft:blaze_rod": 369, - "minecraft:ghast_tear": 370, - "minecraft:gold_nugget": 371, - "minecraft:nether_wart": 372, - "minecraft:potion": 373, - "minecraft:glass_bottle": 374, - "minecraft:spider_eye": 375, - "minecraft:fermented_spider_eye": 376, - "minecraft:blaze_powder": 377, - "minecraft:magma_cream": 378, - "minecraft:brewing_stand": 379, - "minecraft:cauldron": 380, - "minecraft:composter": 381, - "minecraft:speckled_melon": 382, - "minecraft:spawn_egg": 383, - "minecraft:experience_bottle": 384, - "minecraft:fireball": 385, - "minecraft:writable_book": 386, - "minecraft:written_book": 387, - "minecraft:emerald": 388, - "minecraft:frame": 389, - "minecraft:flower_pot": 390, - "minecraft:carrot": 391, - "minecraft:potato": 392, - "minecraft:baked_potato": 393, - "minecraft:poisonous_potato": 394, - "minecraft:emptyMap": 395, - "minecraft:golden_carrot": 396, - "minecraft:skull": 397, - "minecraft:carrotOnAStick": 398, - "minecraft:netherStar": 399, - "minecraft:pumpkin_pie": 400, - "minecraft:fireworks": 401, - "minecraft:fireworksCharge": 402, - "minecraft:enchanted_book": 403, - "minecraft:comparator": 404, - "minecraft:netherbrick": 405, - "minecraft:quartz": 406, - "minecraft:tnt_minecart": 407, - "minecraft:hopper_minecart": 408, - "minecraft:prismarine_shard": 409, - "minecraft:hopper": 410, - "minecraft:rabbit": 411, - "minecraft:cooked_rabbit": 412, - "minecraft:rabbit_stew": 413, - "minecraft:rabbit_foot": 414, - "minecraft:rabbit_hide": 415, - "minecraft:horsearmorleather": 416, - "minecraft:horsearmoriron": 417, - "minecraft:horsearmorgold": 418, - "minecraft:horsearmordiamond": 419, - "minecraft:lead": 420, - "minecraft:nametag": 422, - "minecraft:muttonRaw": 423, - "minecraft:muttonCooked": 424, - "minecraft:armor_stand": 425, - "minecraft:end_crystal": 426, - "minecraft:spruce_door": 427, - "minecraft:birch_door": 428, - "minecraft:jungle_door": 429, - "minecraft:acacia_door": 430, - "minecraft:dark_oak_door": 431, - "minecraft:chorus_fruit": 432, - "minecraft:chorus_fruit_popped": 433, - "minecraft:banner_pattern": 434, - "minecraft:dragon_breath": 437, - "minecraft:splash_potion": 438, - "minecraft:lingering_potion": 441, - "minecraft:sparkler": 442, - "minecraft:command_block_minecart": 443, - "minecraft:elytra": 444, - "minecraft:shulker_shell": 445, - "minecraft:banner": 446, - "minecraft:medicine": 447, - "minecraft:balloon": 448, - "minecraft:rapid_fertilizer": 449, - "minecraft:totem": 450, - "minecraft:bleach": 451, - "minecraft:iron_nugget": 452, - "minecraft:ice_bomb": 453, - "minecraft:trident": 455, - "minecraft:beetroot": 457, - "minecraft:beetroot_seeds": 458, - "minecraft:beetroot_soup": 459, - "minecraft:salmon": 460, - "minecraft:clownfish": 461, - "minecraft:pufferfish": 462, - "minecraft:cooked_salmon": 463, - "minecraft:dried_kelp": 464, - "minecraft:nautilus_shell": 465, - "minecraft:appleEnchanted": 466, - "minecraft:heart_of_the_sea": 467, - "minecraft:turtle_shell_piece": 468, - "minecraft:turtle_helmet": 469, - "minecraft:phantom_membrane": 470, - "minecraft:crossbow": 471, - "minecraft:spruce_sign": 472, - "minecraft:birch_sign": 473, - "minecraft:jungle_sign": 474, - "minecraft:acacia_sign": 475, - "minecraft:darkoak_sign": 476, - "minecraft:sweet_berries": 477, - "minecraft:compound": 499, - "minecraft:record_13": 500, - "minecraft:record_cat": 501, - "minecraft:record_blocks": 502, - "minecraft:record_chirp": 503, - "minecraft:record_far": 504, - "minecraft:record_mall": 505, - "minecraft:record_mellohi": 506, - "minecraft:record_stal": 507, - "minecraft:record_strad": 508, - "minecraft:record_ward": 509, - "minecraft:record_11": 510, - "minecraft:record_wait": 511, - "minecraft:shield": 513, - "minecraft:campfire": 720 -} + "minecraft:iron_shovel" : 256, + "minecraft:iron_pickaxe" : 257, + "minecraft:iron_axe" : 258, + "minecraft:flint_and_steel" : 259, + "minecraft:apple" : 260, + "minecraft:bow" : 261, + "minecraft:arrow" : 262, + "minecraft:coal" : 263, + "minecraft:diamond" : 264, + "minecraft:iron_ingot" : 265, + "minecraft:gold_ingot" : 266, + "minecraft:iron_sword" : 267, + "minecraft:wooden_sword" : 268, + "minecraft:wooden_shovel" : 269, + "minecraft:wooden_pickaxe" : 270, + "minecraft:wooden_axe" : 271, + "minecraft:stone_sword" : 272, + "minecraft:stone_shovel" : 273, + "minecraft:stone_pickaxe" : 274, + "minecraft:stone_axe" : 275, + "minecraft:diamond_sword" : 276, + "minecraft:diamond_shovel" : 277, + "minecraft:diamond_pickaxe" : 278, + "minecraft:diamond_axe" : 279, + "minecraft:stick" : 280, + "minecraft:bowl" : 281, + "minecraft:mushroom_stew" : 282, + "minecraft:golden_sword" : 283, + "minecraft:golden_shovel" : 284, + "minecraft:golden_pickaxe" : 285, + "minecraft:golden_axe" : 286, + "minecraft:string" : 287, + "minecraft:feather" : 288, + "minecraft:gunpowder" : 289, + "minecraft:wooden_hoe" : 290, + "minecraft:stone_hoe" : 291, + "minecraft:iron_hoe" : 292, + "minecraft:diamond_hoe" : 293, + "minecraft:golden_hoe" : 294, + "minecraft:wheat_seeds" : 295, + "minecraft:wheat" : 296, + "minecraft:bread" : 297, + "minecraft:leather_helmet" : 298, + "minecraft:leather_chestplate" : 299, + "minecraft:leather_leggings" : 300, + "minecraft:leather_boots" : 301, + "minecraft:chainmail_helmet" : 302, + "minecraft:chainmail_chestplate" : 303, + "minecraft:chainmail_leggings" : 304, + "minecraft:chainmail_boots" : 305, + "minecraft:iron_helmet" : 306, + "minecraft:iron_chestplate" : 307, + "minecraft:iron_leggings" : 308, + "minecraft:iron_boots" : 309, + "minecraft:diamond_helmet" : 310, + "minecraft:diamond_chestplate" : 311, + "minecraft:diamond_leggings" : 312, + "minecraft:diamond_boots" : 313, + "minecraft:golden_helmet" : 314, + "minecraft:golden_chestplate" : 315, + "minecraft:golden_leggings" : 316, + "minecraft:golden_boots" : 317, + "minecraft:flint" : 318, + "minecraft:porkchop" : 319, + "minecraft:cooked_porkchop" : 320, + "minecraft:painting" : 321, + "minecraft:golden_apple" : 322, + "minecraft:sign" : 323, + "minecraft:wooden_door" : 324, + "minecraft:bucket" : 325, + "minecraft:minecart" : 328, + "minecraft:saddle" : 329, + "minecraft:iron_door" : 330, + "minecraft:redstone" : 331, + "minecraft:snowball" : 332, + "minecraft:boat" : 333, + "minecraft:leather" : 334, + "minecraft:kelp" : 335, + "minecraft:brick" : 336, + "minecraft:clay_ball" : 337, + "minecraft:reeds" : 338, + "minecraft:paper" : 339, + "minecraft:book" : 340, + "minecraft:slime_ball" : 341, + "minecraft:chest_minecart" : 342, + "minecraft:egg" : 344, + "minecraft:compass" : 345, + "minecraft:fishing_rod" : 346, + "minecraft:clock" : 347, + "minecraft:glowstone_dust" : 348, + "minecraft:fish" : 349, + "minecraft:cooked_fish" : 350, + "minecraft:dye" : 351, + "minecraft:bone" : 352, + "minecraft:sugar" : 353, + "minecraft:cake" : 354, + "minecraft:bed" : 355, + "minecraft:repeater" : 356, + "minecraft:cookie" : 357, + "minecraft:map" : 358, + "minecraft:shears" : 359, + "minecraft:melon" : 360, + "minecraft:pumpkin_seeds" : 361, + "minecraft:melon_seeds" : 362, + "minecraft:beef" : 363, + "minecraft:cooked_beef" : 364, + "minecraft:chicken" : 365, + "minecraft:cooked_chicken" : 366, + "minecraft:rotten_flesh" : 367, + "minecraft:ender_pearl" : 368, + "minecraft:blaze_rod" : 369, + "minecraft:ghast_tear" : 370, + "minecraft:gold_nugget" : 371, + "minecraft:nether_wart" : 372, + "minecraft:potion" : 373, + "minecraft:glass_bottle" : 374, + "minecraft:spider_eye" : 375, + "minecraft:fermented_spider_eye" : 376, + "minecraft:blaze_powder" : 377, + "minecraft:magma_cream" : 378, + "minecraft:brewing_stand" : 379, + "minecraft:cauldron" : 380, + "minecraft:ender_eye" : 381, + "minecraft:speckled_melon" : 382, + "minecraft:spawn_egg" : 383, + "minecraft:experience_bottle" : 384, + "minecraft:fireball" : 385, + "minecraft:writable_book" : 386, + "minecraft:written_book" : 387, + "minecraft:emerald" : 388, + "minecraft:frame" : 389, + "minecraft:flower_pot" : 390, + "minecraft:carrot" : 391, + "minecraft:potato" : 392, + "minecraft:baked_potato" : 393, + "minecraft:poisonous_potato" : 394, + "minecraft:emptymap" : 395, + "minecraft:golden_carrot" : 396, + "minecraft:skull" : 397, + "minecraft:carrotonastick" : 398, + "minecraft:netherstar" : 399, + "minecraft:pumpkin_pie" : 400, + "minecraft:fireworks" : 401, + "minecraft:fireworkscharge" : 402, + "minecraft:enchanted_book" : 403, + "minecraft:comparator" : 404, + "minecraft:netherbrick" : 405, + "minecraft:quartz" : 406, + "minecraft:tnt_minecart" : 407, + "minecraft:hopper_minecart" : 408, + "minecraft:prismarine_shard" : 409, + "minecraft:hopper" : 410, + "minecraft:rabbit" : 411, + "minecraft:cooked_rabbit" : 412, + "minecraft:rabbit_stew" : 413, + "minecraft:rabbit_foot" : 414, + "minecraft:rabbit_hide" : 415, + "minecraft:horsearmorleather" : 416, + "minecraft:horsearmoriron" : 417, + "minecraft:horsearmorgold" : 418, + "minecraft:horsearmordiamond" : 419, + "minecraft:lead" : 420, + "minecraft:name_tag" : 421, + "minecraft:prismarine_crystals" : 422, + "minecraft:muttonraw" : 423, + "minecraft:muttoncooked" : 424, + "minecraft:armor_stand" : 425, + "minecraft:end_crystal" : 426, + "minecraft:spruce_door" : 427, + "minecraft:birch_door" : 428, + "minecraft:jungle_door" : 429, + "minecraft:acacia_door" : 430, + "minecraft:dark_oak_door" : 431, + "minecraft:chorus_fruit" : 432, + "minecraft:chorus_fruit_popped" : 433, + "minecraft:banner_pattern" : 434, + "minecraft:dragon_breath" : 437, + "minecraft:splash_potion" : 438, + "minecraft:lingering_potion" : 441, + "minecraft:sparkler" : 442, + "minecraft:command_block_minecart" : 443, + "minecraft:elytra" : 444, + "minecraft:shulker_shell" : 445, + "minecraft:banner" : 446, + "minecraft:medicine" : 447, + "minecraft:balloon" : 448, + "minecraft:rapid_fertilizer" : 449, + "minecraft:totem" : 450, + "minecraft:bleach" : 451, + "minecraft:iron_nugget" : 452, + "minecraft:ice_bomb" : 453, + "minecraft:trident" : 455, + "minecraft:beetroot" : 457, + "minecraft:beetroot_seeds" : 458, + "minecraft:beetroot_soup" : 459, + "minecraft:salmon" : 460, + "minecraft:clownfish" : 461, + "minecraft:pufferfish" : 462, + "minecraft:cooked_salmon" : 463, + "minecraft:dried_kelp" : 464, + "minecraft:nautilus_shell" : 465, + "minecraft:appleenchanted" : 466, + "minecraft:heart_of_the_sea" : 467, + "minecraft:turtle_shell_piece" : 468, + "minecraft:turtle_helmet" : 469, + "minecraft:phantom_membrane" : 470, + "minecraft:crossbow" : 471, + "minecraft:spruce_sign" : 472, + "minecraft:birch_sign" : 473, + "minecraft:jungle_sign" : 474, + "minecraft:acacia_sign" : 475, + "minecraft:darkoak_sign" : 476, + "minecraft:sweet_berries" : 477, + "minecraft:camera" : 498, + "minecraft:compound" : 499, + "minecraft:record_13" : 500, + "minecraft:record_cat" : 501, + "minecraft:record_blocks" : 502, + "minecraft:record_chirp" : 503, + "minecraft:record_far" : 504, + "minecraft:record_mall" : 505, + "minecraft:record_mellohi" : 506, + "minecraft:record_stal" : 507, + "minecraft:record_strad" : 508, + "minecraft:record_ward" : 509, + "minecraft:record_11" : 510, + "minecraft:record_wait" : 511, + "minecraft:shield" : 513, + "minecraft:campfire" : 720, + "minecraft:suspicious_stew" : 734, + "minecraft:honeycomb" : 736, + "minecraft:honey_bottle" : 737, + "minecraft:lodestonecompass" : 741, + "minecraft:netherite_ingot" : 742, + "minecraft:netherite_sword" : 743, + "minecraft:netherite_shovel" : 744, + "minecraft:netherite_pickaxe" : 745, + "minecraft:netherite_axe" : 746, + "minecraft:netherite_hoe" : 747, + "minecraft:netherite_helmet" : 748, + "minecraft:netherite_chestplate" : 749, + "minecraft:netherite_leggings" : 750, + "minecraft:netherite_boots" : 751, + "minecraft:netherite_scrap" : 752, + "minecraft:crimson_sign" : 753, + "minecraft:warped_sign" : 754, + "minecraft:crimson_door" : 755, + "minecraft:warped_door" : 756, + "minecraft:warped_fungus_on_a_stick" : 757, + "minecraft:chain" : 758, + "minecraft:record_pigstep" : 759, + "minecraft:nether_sprouts" : 760, + "minecraft:soul_campfire" : 801 +} \ No newline at end of file diff --git a/connector/src/main/resources/bedrock/runtime_block_states.dat b/connector/src/main/resources/bedrock/runtime_block_states.dat index 0c79ab2fda6..feeeda664bd 100644 Binary files a/connector/src/main/resources/bedrock/runtime_block_states.dat and b/connector/src/main/resources/bedrock/runtime_block_states.dat differ diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index 931e0a8d4cc..eb4c1ddcafc 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -8,7 +8,8 @@ # -------------------------------- bedrock: - # The IP address that will listen for connections + # The IP address that will listen for connections. + # There is no reason to change this unless you want to limit what IPs can connect to your server. address: 0.0.0.0 # The port that will listen for connections port: 19132 @@ -74,6 +75,9 @@ allow-third-party-capes: true # MinecraftCapes allow-third-party-ears: false +# Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat +show-cooldown: true + # The default locale if we dont have the one the client requested default-locale: en_us @@ -81,7 +85,7 @@ default-locale: en_us # record of each block the client loads in. While this feature does allow for a few # things such as block break animations to show up in creative mode and among others, # it is HIGHLY recommended you disable this on a production environment as it can eat -# up a lot of RAM. However, when using the Bukkit version of Geyser, support for features +# up a lot of RAM. However, when using the Spigot version of Geyser, support for features # or implementations this allows is automatically enabled without the additional caching as # Geyser has direct access to the server itself. cache-chunks: false diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index a67cc940c0d..204c8f8dfdb 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit a67cc940c0d47874c833ffeb58f38e33eabfcc33 +Subproject commit 204c8f8dfdb1e39b881986c4968aa2575fbb5400 diff --git a/pom.xml b/pom.xml index a82d6217e70..3e119eb1197 100644 --- a/pom.xml +++ b/pom.xml @@ -38,14 +38,8 @@ - CodeMC-repo - https://repo.codemc.org/repository/maven-public - - true - - - true - + jitpack.io + https://jitpack.io nukkitx-release-repo