From 2dc755ca982d7c6364e2e99eabec11da0a0b2180 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Tue, 26 May 2020 10:05:25 -0400 Subject: [PATCH 001/104] Rename Geyser-Bukkit to Geyser-Spigot Despite the Bukkit suffix being correct in terms of the API, the name causes some people to download CraftBukkit instead of Spigot or Paper. All internal references to Bukkit have been renamed to Spigot. --- bootstrap/pom.xml | 2 +- bootstrap/{bukkit => spigot}/pom.xml | 10 ++--- .../spigot/GeyserSpigotConfiguration.java} | 8 ++-- .../platform/spigot/GeyserSpigotLogger.java} | 4 +- .../platform/spigot/GeyserSpigotMain.java} | 6 +-- .../spigot/GeyserSpigotPingPassthrough.java} | 6 +-- .../platform/spigot/GeyserSpigotPlugin.java} | 42 +++++++++---------- .../command/GeyserSpigotCommandExecutor.java} | 8 ++-- .../command/GeyserSpigotCommandManager.java} | 10 ++--- .../spigot/command/SpigotCommandSender.java} | 4 +- .../GeyserSpigotBlockPlaceListener.java} | 6 +-- .../world/GeyserSpigotWorldManager.java} | 6 +-- .../src/main/resources/plugin.yml | 4 +- .../java/world/JavaBlockChangeTranslator.java | 2 +- 14 files changed, 58 insertions(+), 60 deletions(-) rename bootstrap/{bukkit => spigot}/pom.xml (91%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java => spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotConfiguration.java} (96%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java => spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotLogger.java} (95%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitMain.java => spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java} (91%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPingPassthrough.java => spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java} (95%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java => spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java} (82%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandExecutor.java => spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java} (91%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/command/GeyserBukkitCommandManager.java => spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandManager.java} (88%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/command/BukkitCommandSender.java => spigot/src/main/java/org/geysermc/platform/spigot/command/SpigotCommandSender.java} (94%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitBlockPlaceListener.java => spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java} (95%) rename bootstrap/{bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java => spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotWorldManager.java} (95%) rename bootstrap/{bukkit => spigot}/src/main/resources/plugin.yml (67%) diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 6d12b6732..87302d4d8 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 91% rename from bootstrap/bukkit/pom.xml rename to bootstrap/spigot/pom.xml index 1f831d673..d9ce9f8d1 100644 --- a/bootstrap/bukkit/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -9,7 +9,7 @@ 1.0-SNAPSHOT ../ - bootstrap-bukkit + bootstrap-spigot org.geysermc @@ -31,7 +31,7 @@ - ${outputName}-Bukkit + ${outputName}-Spigot src/main/resources/ @@ -46,7 +46,7 @@ - org.geysermc.platform.bukkit.GeyserBukkitMain + org.geysermc.platform.spigot.GeyserSpigotMain @@ -65,11 +65,11 @@ 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 diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotConfiguration.java similarity index 96% rename from bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java rename to bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotConfiguration.java index df98b408d..ffa9c7b3d 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotConfiguration.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.platform.bukkit; +package org.geysermc.platform.spigot; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; @@ -37,7 +37,7 @@ import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; -public class GeyserBukkitConfiguration implements GeyserConfiguration { +public class GeyserSpigotConfiguration implements GeyserConfiguration { private FileConfiguration config; private File dataFolder; @@ -50,7 +50,7 @@ public class GeyserBukkitConfiguration implements GeyserConfiguration { private Path floodgateKey; - public GeyserBukkitConfiguration(File dataFolder, FileConfiguration config) { + public GeyserSpigotConfiguration(File dataFolder, FileConfiguration config) { this.dataFolder = dataFolder; this.config = config; @@ -66,7 +66,7 @@ public class GeyserBukkitConfiguration implements GeyserConfiguration { } } - public void loadFloodgate(GeyserBukkitPlugin plugin) { + public void loadFloodgate(GeyserSpigotPlugin 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); } 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 08822568c..252d6bbed 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.Level; 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 91% 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 b6da66c1b..dbc660391 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; -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 95% 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 812467be7..6651adab9 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,7 +24,7 @@ * */ -package org.geysermc.platform.bukkit; +package org.geysermc.platform.spigot; import lombok.AllArgsConstructor; import org.bukkit.Bukkit; @@ -39,9 +39,9 @@ import java.util.Collections; 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 82% 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 5f0e967a2..b4e0158c8 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,7 +23,7 @@ * @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; @@ -35,22 +35,22 @@ import org.geysermc.connector.command.CommandManager; 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 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 us.myles.ViaVersion.api.Via; import java.util.UUID; -public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { +public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { - private GeyserBukkitCommandManager geyserCommandManager; - private GeyserBukkitConfiguration geyserConfig; - private GeyserBukkitLogger geyserLogger; + private GeyserSpigotCommandManager geyserCommandManager; + private GeyserSpigotConfiguration geyserConfig; + private GeyserSpigotLogger geyserLogger; private IGeyserPingPassthrough geyserBukkitPingPassthrough; - private GeyserBukkitBlockPlaceListener blockPlaceListener; - private GeyserBukkitWorldManager geyserWorldManager; + private GeyserSpigotBlockPlaceListener blockPlaceListener; + private GeyserSpigotWorldManager geyserWorldManager; private GeyserConnector connector; @@ -58,7 +58,7 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { public void onEnable() { saveDefaultConfig(); - this.geyserConfig = new GeyserBukkitConfiguration(getDataFolder(), getConfig()); + this.geyserConfig = new GeyserSpigotConfiguration(getDataFolder(), getConfig()); if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) { getConfig().set("metrics.uuid", UUID.randomUUID().toString()); saveConfig(); @@ -73,20 +73,20 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { getConfig().set("remote.port", Bukkit.getPort()); saveConfig(); - this.geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode()); + this.geyserLogger = new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode()); GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); 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); } else { - this.geyserBukkitPingPassthrough = new GeyserBukkitPingPassthrough(geyserLogger); + this.geyserBukkitPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger); } - this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector); + this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector); boolean isViaVersion = false; // Used to determine if Block.getBlockData() is present. @@ -104,11 +104,11 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { } } - this.geyserWorldManager = new GeyserBukkitWorldManager(isLegacy, isViaVersion); - this.blockPlaceListener = new GeyserBukkitBlockPlaceListener(connector, isLegacy, isViaVersion); + this.geyserWorldManager = new GeyserSpigotWorldManager(isLegacy, isViaVersion); + this.blockPlaceListener = new GeyserSpigotBlockPlaceListener(connector, isLegacy, isViaVersion); Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this); - this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector)); + this.getCommand("geyser").setExecutor(new GeyserSpigotCommandExecutor(connector)); } @Override @@ -117,12 +117,12 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { } @Override - public GeyserBukkitConfiguration getGeyserConfig() { + public GeyserSpigotConfiguration getGeyserConfig() { return geyserConfig; } @Override - public GeyserBukkitLogger getGeyserLogger() { + public GeyserSpigotLogger getGeyserLogger() { return geyserLogger; } 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 d2603f7c5..b956a0d84 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.Arrays; import java.util.List; @AllArgsConstructor -public class GeyserBukkitCommandExecutor implements TabExecutor { +public class GeyserSpigotCommandExecutor implements TabExecutor { private GeyserConnector connector; @@ -51,11 +51,11 @@ public class GeyserBukkitCommandExecutor implements TabExecutor { 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 b826ab1f5..2fbec1562 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 05e371e5a..55475a303 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.bukkit.command.ConsoleCommandSender; 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 76d1564ea..f17a97e37 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.session.GeyserSession; 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 class GeyserBukkitBlockPlaceListener implements Listener { 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 95% 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 fbdf2a47b..4f7e54f76 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,21 @@ * */ -package org.geysermc.platform.bukkit.world; +package org.geysermc.platform.spigot.world; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; 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; @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. diff --git a/bootstrap/bukkit/src/main/resources/plugin.yml b/bootstrap/spigot/src/main/resources/plugin.yml similarity index 67% rename from bootstrap/bukkit/src/main/resources/plugin.yml rename to bootstrap/spigot/src/main/resources/plugin.yml index 89c90789e..fee71ab1f 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/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java index e09b9248d..9ff20a824 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java @@ -47,7 +47,7 @@ public class JavaBlockChangeTranslator extends PacketTranslator Date: Tue, 26 May 2020 10:11:28 -0400 Subject: [PATCH 002/104] Rename internal ping passthrough variable --- .../org/geysermc/platform/spigot/GeyserSpigotPlugin.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index b4e0158c8..cc0549654 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -48,7 +48,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { private GeyserSpigotCommandManager geyserCommandManager; private GeyserSpigotConfiguration geyserConfig; private GeyserSpigotLogger geyserLogger; - private IGeyserPingPassthrough geyserBukkitPingPassthrough; + private IGeyserPingPassthrough geyserSpigotPingPassthrough; private GeyserSpigotBlockPlaceListener blockPlaceListener; private GeyserSpigotWorldManager geyserWorldManager; @@ -81,9 +81,9 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { this.connector = GeyserConnector.start(PlatformType.SPIGOT, this); if (geyserConfig.isLegacyPingPassthrough()) { - this.geyserBukkitPingPassthrough = GeyserLegacyPingPassthrough.init(connector); + this.geyserSpigotPingPassthrough = GeyserLegacyPingPassthrough.init(connector); } else { - this.geyserBukkitPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger); + this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger); } this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector); @@ -133,7 +133,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { @Override public IGeyserPingPassthrough getGeyserPingPassthrough() { - return geyserBukkitPingPassthrough; + return geyserSpigotPingPassthrough; } @Override From cae888eac98f75305311bfea6873bf4d54659cde Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Tue, 26 May 2020 10:17:52 -0400 Subject: [PATCH 003/104] Include PlatformType.java --- common/src/main/java/org/geysermc/common/PlatformType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/org/geysermc/common/PlatformType.java b/common/src/main/java/org/geysermc/common/PlatformType.java index fa6f57fda..29b2fce96 100644 --- a/common/src/main/java/org/geysermc/common/PlatformType.java +++ b/common/src/main/java/org/geysermc/common/PlatformType.java @@ -7,8 +7,8 @@ import lombok.Getter; @AllArgsConstructor public enum PlatformType { - BUKKIT("Bukkit"), BUNGEECORD("BungeeCord"), + SPIGOT("Spigot"), SPONGE("Sponge"), STANDALONE("Standalone"), VELOCITY("Velocity"); From ccf9eff7ca6cc6f67b79f7da0111dab8fd68a83d Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Tue, 26 May 2020 10:47:34 -0400 Subject: [PATCH 004/104] Update workflow --- .github/workflows/pullrequest.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index 7f941da6b..aa80bf056 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -29,12 +29,12 @@ jobs: with: name: Geyser Standalone path: bootstrap/standalone/target/Geyser.jar - - name: Archive artifacts (Geyser Bukkit) + - name: Archive artifacts (Geyser Spigot) uses: actions/upload-artifact@v1 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 if: success() From d6119375b2296cb57bb80deff3d81660fcda3025 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Thu, 18 Jun 2020 21:44:50 -0400 Subject: [PATCH 005/104] (Incomplete) Update MCProtocolLib --- connector/pom.xml | 8 ++- .../org/geysermc/connector/entity/Entity.java | 3 +- .../entity/living/monster/EndermanEntity.java | 3 +- .../network/session/GeyserSession.java | 3 +- .../network/session/cache/ChunkCache.java | 5 +- ...drockBlockPickRequestPacketTranslator.java | 5 +- ...BedrockInventoryTransactionTranslator.java | 5 +- .../inventory/BlockInventoryTranslator.java | 3 +- .../DoubleChestInventoryTranslator.java | 7 +-- .../SingleChestInventoryTranslator.java | 3 +- .../holder/BlockInventoryHolder.java | 3 +- .../world/JavaBlockBreakAnimTranslator.java | 5 +- .../java/world/JavaChunkDataTranslator.java | 3 +- .../translators/world/CachedChunkManager.java | 3 +- .../translators/world/WorldManager.java | 14 ++--- .../world/block/BlockStateValues.java | 60 ++++++++----------- .../world/block/BlockTranslator.java | 42 ++++++------- .../entity/BannerBlockEntityTranslator.java | 5 +- .../entity/BedBlockEntityTranslator.java | 5 +- .../block/entity/BedrockOnlyBlockEntity.java | 5 +- .../block/entity/BlockEntityTranslator.java | 5 +- .../entity/CampfireBlockEntityTranslator.java | 3 +- .../DoubleChestBlockEntityTranslator.java | 13 ++-- .../entity/EmptyBlockEntityTranslator.java | 3 +- .../EndGatewayBlockEntityTranslator.java | 3 +- .../FlowerPotBlockEntityTranslator.java | 13 ++-- .../NoteblockBlockEntityTranslator.java | 5 +- .../entity/PistonBlockEntityTranslator.java | 13 ++-- .../block/entity/RequiresBlockState.java | 4 +- .../ShulkerBoxBlockEntityTranslator.java | 3 +- .../entity/SignBlockEntityTranslator.java | 3 +- .../entity/SkullBlockEntityTranslator.java | 5 +- .../entity/SpawnerBlockEntityTranslator.java | 3 +- .../geysermc/connector/utils/ChunkUtils.java | 21 +++---- 34 files changed, 121 insertions(+), 166 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 91cf6f3db..34798931e 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -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 @@ -99,7 +105,7 @@ com.github.steveice10 mcprotocollib - 4c315aa206 + 013e8e6dc4 compile 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 d5ae391c0..0b7b23fee 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -32,7 +32,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; 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; @@ -335,7 +334,7 @@ public class Entity { Vector3i lastInteractionPos = session.getLastInteractionPosition(); metadata.put(EntityData.BED_RESPAWN_POS, 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); 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 644181ab7..7232fb55b 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,7 +26,6 @@ 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; @@ -44,7 +43,7 @@ public class EndermanEntity extends MonsterEntity { 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.ENDERMAN_HELD_ITEM_ID, BlockTranslator.getBedrockBlockId((int) entityMetadata.getValue())); } // 'Angry' - mouth open if (entityMetadata.getId() == 16) { 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 d2b87af14..24ef2faaa 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 @@ -32,7 +32,6 @@ 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.window.VillagerTrade; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; 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; @@ -146,7 +145,7 @@ public class GeyserSession implements CommandSender { private boolean jumping; @Setter - private BlockState breakingBlock; + private int breakingBlock; @Setter private Vector3i lastBlockPlacePosition; 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 ac7ab06cf..a7b0c9665 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 @@ package org.geysermc.connector.network.session.cache; 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 class ChunkCache { 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 class ChunkCache { } } - 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/bedrock/BedrockBlockPickRequestPacketTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java index 04fe8dbf3..297db702c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java @@ -26,7 +26,6 @@ package org.geysermc.connector.network.translators.bedrock; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientMoveItemToHotbarPacket; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.packet.BlockPickRequestPacket; @@ -45,10 +44,10 @@ public class BedrockBlockPickRequestPacketTranslator extends PacketTranslator 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 class BlockStateValues { 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 class BlockStateValues { 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 class BlockStateValues { * @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 class BlockStateValues { * @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 class BlockStateValues { * @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 class BlockStateValues { 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 class BlockStateValues { * @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 class BlockStateValues { * @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 class BlockStateValues { * @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 d6f446f08..cbae263e6 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 @@ import java.util.*; 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(); @@ -121,7 +120,6 @@ public class BlockTranslator { 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) @@ -145,7 +143,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; @@ -154,12 +152,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) { @@ -173,10 +171,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); @@ -285,15 +283,11 @@ public class BlockTranslator { 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 state) { + return JAVA_TO_BEDROCK_BLOCK_MAP.get(state); } - public static int getBedrockBlockId(int javaId) { - return JAVA_TO_BEDROCK_BLOCK_MAP.get(javaId); - } - - public static BlockState getJavaBlockState(int bedrockId) { + public static int getJavaBlockState(int bedrockId) { return BEDROCK_TO_JAVA_BLOCK_MAP.get(bedrockId); } @@ -309,23 +303,23 @@ public class BlockTranslator { 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 3e2c0a959..15af7a70e 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 @@ import java.util.List; 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 5f0b1cc0d..31f363888 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 @@ import java.util.List; 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 5b325ebad..9efda13c0 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 c87938dd9..93356e7cd 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; @@ -88,13 +87,13 @@ public abstract class BlockEntityTranslator { } } - 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 cd31636c8..e932d2645 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 @@ import java.util.List; 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 f5599832d..d1afd19e0 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 @@ import java.util.List; 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 class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl } @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 d10682775..401bb3439 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 @@ import java.util.List; 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 4cd2eaa9e..17e533bc0 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 @@ import java.util.List; 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 c4748c829..69ecefdda 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,12 +38,12 @@ import org.geysermc.connector.utils.BlockEntityUtils; 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); @@ -58,11 +57,11 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R /** * 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 class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R .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 168015f6e..ca5a4f520 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 @@ import org.geysermc.connector.utils.ChunkUtils; 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 2dffce24c..bf8fcb132 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 4df7292ad..0db306aa5 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 373b963e2..b92b604e0 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 @@ import java.util.List; 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 6c1704622..e3fb9ea08 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,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.mc.protocol.data.message.Message; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.nbt.CompoundTagBuilder; @@ -41,7 +40,7 @@ import java.util.List; 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(); 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 9393f7bb0..f868ff088 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 @@ import java.util.List; 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 100dbddd6..548a1ec8c 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 @@ import java.util.List; 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/utils/ChunkUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java index f86173e24..9cab8605d 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -28,7 +28,6 @@ package org.geysermc.connector.utils; 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; @@ -54,8 +53,6 @@ import org.geysermc.connector.network.translators.world.chunk.ChunkSection; 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; @@ -65,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; @@ -91,7 +88,7 @@ public class ChunkUtils { 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<>(); @@ -107,7 +104,7 @@ public class ChunkUtils { 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 @@ -119,8 +116,8 @@ public class ChunkUtils { 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)); } @@ -161,7 +158,7 @@ public class ChunkUtils { 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++; } @@ -188,14 +185,14 @@ public class ChunkUtils { } } - 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)) { From ad4c1ff0c730ce7563d1a1c3f5f179c4967c464e Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 19 Jun 2020 11:57:34 +0100 Subject: [PATCH 006/104] Update Message system --- .../network/ConnectorServerEventHandler.java | 12 +++-- .../connector/network/QueryPacketHandler.java | 4 +- .../inventory/AnvilInventoryTranslator.java | 5 +- .../translators/item/ItemTranslator.java | 4 +- .../translators/java/JavaChatTranslator.java | 2 +- .../entity/SignBlockEntityTranslator.java | 7 ++- .../ping/GeyserLegacyPingPassthrough.java | 2 +- .../connector/utils/MessageUtils.java | 47 ++++++++++--------- 8 files changed, 45 insertions(+), 38 deletions(-) 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 49f81e3f8..abff44e58 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.configuration.GeyserConfiguration; 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 class ConnectorServerEventHandler implements BedrockServerEventHandler { 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/QueryPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java index 6ad206b33..0e9fe5035 100644 --- a/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java @@ -26,7 +26,7 @@ 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; @@ -148,7 +148,7 @@ public class QueryPacketHandler { } 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(); 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 f301d2b5d..d69f9f714 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 @@ -27,6 +27,7 @@ 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.packet.ingame.client.window.ClientRenameItemPacket; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.protocol.bedrock.data.ContainerId; @@ -129,8 +130,8 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { CompoundTag displayTag = tag.get("display"); if (displayTag != null) { String itemName = displayTag.get("Name").getValue().toString(); - Message message = Message.fromString(itemName); - rename = message.getText(); + Message message = MessageSerializer.fromString(itemName); + rename = message.toString(); } else { rename = ""; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 1962f62ec..be8080d85 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators.item; 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.opennbt.tag.builtin.*; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.CompoundTag; @@ -159,7 +159,7 @@ public abstract class ItemTranslator { // Check if its a message to translate if (MessageUtils.isMessage(name)) { // Get the translated name - name = MessageUtils.getTranslatedBedrockMessage(Message.fromString(name), session.getClientData().getLanguageCode()); + name = MessageUtils.getTranslatedBedrockMessage(MessageSerializer.fromString(name), session.getClientData().getLanguageCode()); // Build the new display tag CompoundTagBuilder displayBuilder = display.toBuilder(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java index 53ce6811f..df3409714 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java @@ -66,7 +66,7 @@ public class JavaChatTranslator extends PacketTranslator { textPacket.setType(TextPacket.Type.TRANSLATION); textPacket.setNeedsTranslation(true); - List paramsTranslated = MessageUtils.getTranslationParams(((TranslationMessage) packet.getMessage()).getTranslationParams(), locale); + List paramsTranslated = MessageUtils.getTranslationParams(((TranslationMessage) packet.getMessage()).getWith(), locale); textPacket.setParameters(paramsTranslated); textPacket.setMessage(MessageUtils.insertParams(MessageUtils.getTranslatedBedrockMessage(packet.getMessage(), locale, true), paramsTranslated)); 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 e3fb9ea08..d0388f335 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,12 +25,11 @@ package org.geysermc.connector.network.translators.world.block.entity; -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; @@ -47,7 +46,7 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { 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("="))) { @@ -58,7 +57,7 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { 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/ping/GeyserLegacyPingPassthrough.java b/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java index 6a323d549..e770e91af 100644 --- a/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java +++ b/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java @@ -77,7 +77,7 @@ public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runn 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(info.getDescription().toString(), info.getPlayerInfo().getOnlinePlayers(), info.getPlayerInfo().getMaxPlayers()); this.client.getSession().disconnect(null); }); 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 d79cdab82..9e32f0a9e 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -26,7 +26,12 @@ 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.github.steveice10.mc.protocol.data.message.Message; +import com.github.steveice10.mc.protocol.data.message.MessageSerializer; +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.github.steveice10.mc.protocol.data.message.style.MessageStyle; import com.google.gson.*; import net.kyori.text.Component; import net.kyori.text.serializer.gson.GsonComponentSerializer; @@ -41,28 +46,28 @@ import java.util.regex.Pattern; public class MessageUtils { - public static List getTranslationParams(Message[] messages, String locale) { + public static List getTranslationParams(List messages, String locale) { List strings = new ArrayList<>(); for (Message message : messages) { 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); + List furtherParams = getTranslationParams(translation.getWith(), locale); 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); } @@ -77,23 +82,23 @@ public class MessageUtils { return strings; } - public static List getTranslationParams(Message[] messages) { + public static List getTranslationParams(List messages) { return getTranslationParams(messages, null); } public static String getTranslationText(TranslationMessage message) { return getFormat(message.getStyle().getFormats()) + getColorOrParent(message.getStyle()) - + "%" + message.getTranslationKey(); + + "%" + message.getKey(); } public static String getTranslatedBedrockMessage(Message message, String locale, boolean shouldTranslate) { 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(formatJson(object)); } - String messageText = message.getText(); + String messageText = message.toString(); if (locale != null && shouldTranslate) { messageText = LocaleUtils.getLocaleString(messageText, locale); } @@ -106,12 +111,12 @@ public class MessageUtils { for (Message msg : message.getExtra()) { builder.append(getFormat(msg.getStyle().getFormats())); builder.append(getColorOrParent(msg.getStyle())); - if (!(msg.getText() == null)) { + if (!(msg.toString() == null)) { boolean isTranslationMessage = (msg instanceof TranslationMessage); String extraText = ""; if (isTranslationMessage) { - List paramsTranslated = getTranslationParams(((TranslationMessage) msg).getTranslationParams(), locale); + List paramsTranslated = getTranslationParams(((TranslationMessage) msg).getWith(), locale); extraText = insertParams(getTranslatedBedrockMessage(msg, locale, isTranslationMessage), paramsTranslated); } else { extraText = getTranslatedBedrockMessage(msg, locale, isTranslationMessage); @@ -130,10 +135,10 @@ public class MessageUtils { } public static String getBedrockMessage(Message message) { - if (isMessage(message.getText())) { - return getBedrockMessage(message.getText()); + if (isMessage(message.toString())) { + return getBedrockMessage(message.toString()); } else { - return getBedrockMessage(message.toJsonString()); + return getBedrockMessage(MessageSerializer.toJsonString(message)); } } @@ -206,9 +211,9 @@ public class MessageUtils { private static String getColorOrParent(MessageStyle style) { ChatColor chatColor = style.getColor(); - if (chatColor == ChatColor.NONE && style.getParent() != null) { + /*if (chatColor == ChatColor.NONE && style.getParent() != null) { return getColorOrParent(style.getParent()); - } + }*/ return getColor(chatColor); } @@ -328,7 +333,7 @@ public class MessageUtils { try { JsonObject object = parser.parse(text).getAsJsonObject(); try { - Message.fromJson(formatJson(object)); + MessageSerializer.fromJson(formatJson(object)); } catch (Exception ex) { return false; } From 65f61ec703b724e9f04d98e6bbc22cedb865537d Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Fri, 19 Jun 2020 09:06:29 -0400 Subject: [PATCH 007/104] Finish block state changes --- .../translators/bedrock/BedrockActionTranslator.java | 2 +- .../entity/player/JavaPlayerActionAckTranslator.java | 10 +++++----- .../java/world/JavaBlockChangeTranslator.java | 2 +- .../java/world/JavaUpdateTileEntityTranslator.java | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) 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 2c44e4fdb..64572f361 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 @@ -114,7 +114,7 @@ public class BedrockActionTranslator extends PacketTranslator Date: Fri, 19 Jun 2020 13:42:55 -0400 Subject: [PATCH 008/104] Don't forget about Bukkit --- .../bukkit/world/GeyserBukkitWorldManager.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java index fbdf2a47b..55c79165e 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java @@ -26,16 +26,12 @@ package org.geysermc.platform.bukkit.world; -import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; - 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; @@ -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,7 +55,7 @@ public class GeyserBukkitWorldManager extends WorldManager { } @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 @@ -68,7 +64,7 @@ public class GeyserBukkitWorldManager extends WorldManager { 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)); + return MappingData.blockStateMappings.getNewId(fourteenBlockId); } else { return BlockTranslator.AIR; } From 47cadc768999de15f528b1d38e82362f4bf8d248 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 19 Jun 2020 19:29:01 +0100 Subject: [PATCH 009/104] Fix json data in chat --- .../translators/inventory/AnvilInventoryTranslator.java | 6 +++--- .../connector/ping/GeyserLegacyPingPassthrough.java | 3 ++- .../java/org/geysermc/connector/utils/MessageUtils.java | 9 +++++---- 3 files changed, 10 insertions(+), 8 deletions(-) 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 d69f9f714..242d4ba4c 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,8 +26,8 @@ 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; @@ -130,8 +130,8 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { CompoundTag displayTag = tag.get("display"); if (displayTag != null) { String itemName = displayTag.get("Name").getValue().toString(); - Message message = MessageSerializer.fromString(itemName); - rename = message.toString(); + TextMessage message = (TextMessage) MessageSerializer.fromString(itemName); + rename = message.getText(); } else { rename = ""; } 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 e770e91af..54978d5f4 100644 --- a/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java +++ b/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java @@ -29,6 +29,7 @@ package org.geysermc.connector.ping; 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; @@ -77,7 +78,7 @@ public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runn 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().toString(), 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/utils/MessageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java index 9e32f0a9e..221a99176 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -28,6 +28,7 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; 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; @@ -98,7 +99,7 @@ public class MessageUtils { message = MessageSerializer.fromJson(formatJson(object)); } - String messageText = message.toString(); + String messageText = (message instanceof TranslationMessage) ? ((TranslationMessage) message).getKey() : ((TextMessage) message).getText(); if (locale != null && shouldTranslate) { messageText = LocaleUtils.getLocaleString(messageText, locale); } @@ -135,8 +136,8 @@ public class MessageUtils { } public static String getBedrockMessage(Message message) { - if (isMessage(message.toString())) { - return getBedrockMessage(message.toString()); + if (isMessage(((TextMessage) message).getText())) { + return getBedrockMessage(((TextMessage) message).getText()); } else { return getBedrockMessage(MessageSerializer.toJsonString(message)); } @@ -276,7 +277,7 @@ public class MessageUtils { base += "f"; break; case RESET: - case NONE: + //case NONE: base += "r"; break; default: From dbe1755a8e9f31fa1bf83f0d08dfbedbb39e2290 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sat, 20 Jun 2020 18:28:07 -0400 Subject: [PATCH 010/104] Update mappings repository --- connector/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index a67cc940c..8f78a9b2c 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit a67cc940c0d47874c833ffeb58f38e33eabfcc33 +Subproject commit 8f78a9b2cb514c7dce900be9c97b9b47c6f6c762 From 77873b6fbb28da2fe7242d81409106b9240708d7 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sat, 20 Jun 2020 20:35:24 -0400 Subject: [PATCH 011/104] Update ViaVersion integration --- .../geysermc/platform/bukkit/GeyserBukkitPlugin.java | 12 +----------- .../bukkit/world/GeyserBukkitWorldManager.java | 7 ++++--- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java index 3a13777b4..c8e266406 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitPlugin.java @@ -101,22 +101,12 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { this.geyserCommandManager = new GeyserBukkitCommandManager(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 GeyserBukkitWorldManager(isLegacy, isViaVersion); this.blockPlaceListener = new GeyserBukkitBlockPlaceListener(connector, isLegacy, isViaVersion); Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this); diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java index 55c79165e..82f1a94f5 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java @@ -33,7 +33,7 @@ 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 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 { @@ -60,11 +60,12 @@ public class GeyserBukkitWorldManager extends WorldManager { 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 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; } From 117cdf282d0379fffbdc10af5eda050019a4a321 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sat, 20 Jun 2020 22:24:45 -0400 Subject: [PATCH 012/104] Begin updating Geyser. Requires manual MCProtocolLib compile --- connector/pom.xml | 2 +- .../org/geysermc/connector/entity/Entity.java | 4 +- .../entity/attribute/AttributeType.java | 24 +-- .../connector/entity/type/EntityType.java | 3 +- .../network/session/GeyserSession.java | 7 +- .../BedrockAdventureSettingsTranslator.java | 2 +- .../bedrock/BedrockInteractTranslator.java | 4 +- ...BedrockInventoryTransactionTranslator.java | 12 +- .../BedrockItemFrameDropItemTranslator.java | 2 +- .../translators/item/ItemRegistry.java | 55 +++--- .../java/JavaJoinGameTranslator.java | 2 +- .../java/JavaRespawnTranslator.java | 4 +- .../java/world/JavaMapDataTranslator.java | 3 +- .../world/JavaSpawnParticleTranslator.java | 3 +- .../world/block/BlockTranslator.java | 158 ++++++++++-------- .../connector/utils/DimensionUtils.java | 25 ++- .../connector/utils/MessageUtils.java | 62 +++---- 17 files changed, 198 insertions(+), 174 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 34798931e..0f1e60819 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.steveice10 mcprotocollib - 013e8e6dc4 + 1.16-rc1-SNAPSHOT compile 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 0b7b23fee..aa38441c7 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -67,7 +67,7 @@ public class Entity { protected long entityId; protected long geyserId; - protected int dimension; + protected String dimension; protected Vector3f position; protected Vector3f motion; @@ -100,7 +100,7 @@ public class Entity { this.rotation = rotation; this.valid = false; - this.dimension = 0; + this.dimension = "minecraft:overworld"; setPosition(position); 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 2061b8953..1d692e2a7 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 @@ import lombok.Getter; 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/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index 3acc17c37..77d7f5c9e 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, 36, 1.8f, 0.6f, 0.6f, 1.62f), SLIME(SlimeEntity.class, 37, 0.51f), ENDERMAN(EndermanEntity.class, 38, 2.9f, 0.6f), SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f), @@ -150,7 +150,6 @@ public enum EntityType { COD(AbstractFishEntity.class, 112, 0.25f, 0.5f), 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), /** * Item frames are handled differently since they are a block in Bedrock. 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 24ef2faaa..a1caf2783 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 @@ -68,10 +68,7 @@ import org.geysermc.connector.network.translators.EntityIdentifierRegistry; 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.MathUtils; -import org.geysermc.connector.utils.SkinUtils; +import org.geysermc.connector.utils.*; import org.geysermc.floodgate.util.BedrockData; import org.geysermc.floodgate.util.EncryptionUtil; @@ -503,7 +500,7 @@ public class GeyserSession implements CommandSender { 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.setDifficulty(1); 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 75a1547f5..6ee70cb32 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 @@ -44,7 +44,7 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator 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: 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 bdf900d88..cdb141084 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 @@ -82,9 +82,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator> iterator = items.fields(); while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - if (entry.getValue().has("tool_type")) { - if (entry.getValue().has("tool_tier")) { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( - entry.getKey(), itemIndex, - entry.getValue().get("bedrock_id").intValue(), - entry.getValue().get("bedrock_data").intValue(), - entry.getValue().get("tool_type").textValue(), - entry.getValue().get("tool_tier").textValue(), - entry.getValue().get("is_block").booleanValue())); + try { + Map.Entry entry = iterator.next(); + if (entry.getValue().has("tool_type")) { + if (entry.getValue().has("tool_tier")) { + ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + entry.getKey(), itemIndex, + entry.getValue().get("bedrock_id").intValue(), + entry.getValue().get("bedrock_data").intValue(), + entry.getValue().get("tool_type").textValue(), + entry.getValue().get("tool_tier").textValue(), + entry.getValue().get("is_block") != null && entry.getValue().get("is_block").booleanValue())); + } else { + ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + entry.getKey(), itemIndex, + entry.getValue().get("bedrock_id").intValue(), + entry.getValue().get("bedrock_data").intValue(), + entry.getValue().get("tool_type").textValue(), + "", + entry.getValue().get("is_block").booleanValue())); + } } else { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + ITEM_ENTRIES.put(itemIndex, new ItemEntry( entry.getKey(), itemIndex, entry.getValue().get("bedrock_id").intValue(), entry.getValue().get("bedrock_data").intValue(), - entry.getValue().get("tool_type").textValue(), - "", - entry.getValue().get("is_block").booleanValue())); + entry.getValue().get("is_block") != null && entry.getValue().get("is_block").booleanValue())); + } + if (entry.getKey().equals("minecraft:barrier")) { + BARRIER_INDEX = itemIndex; } - } else { - ITEM_ENTRIES.put(itemIndex, new ItemEntry( - entry.getKey(), itemIndex, - entry.getValue().get("bedrock_id").intValue(), - entry.getValue().get("bedrock_data").intValue(), - entry.getValue().get("is_block").booleanValue())); - } - if (entry.getKey().equals("minecraft:barrier")) { - BARRIER_INDEX = itemIndex; - } - itemIndex++; + itemIndex++; + } catch (Exception e) { + System.out.println("Exception in item registry! " + e.toString()); + e.printStackTrace(); + } } /* Load creative items */ 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 8d8c0affb..9b44cdd37 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 class JavaJoinGameTranslator extends PacketTranslator 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("minecraft:overworld") ? "minecraft:nether" : "minecraft:overworld"; DimensionUtils.switchDimension(session, fakeDim); DimensionUtils.switchDimension(session, packet.getDimension()); } else { 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 5a3ebabaf..2aee7bc02 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.session.GeyserSession; 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) @@ -45,7 +46,7 @@ public class JavaMapDataTranslator extends PacketTranslator 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()); 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 63512047f..d4c269b08 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 @@ -40,6 +40,7 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator; 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 { @@ -93,7 +94,7 @@ public class JavaSpawnParticleTranslator extends PacketTranslator> blocksIterator = blocks.fields(); while (blocksIterator.hasNext()) { - javaRuntimeId++; - Map.Entry entry = blocksIterator.next(); - String javaId = entry.getKey(); - CompoundTag blockTag = buildBedrockState(entry.getValue()); + try { + javaRuntimeId++; + Map.Entry entry = blocksIterator.next(); + String javaId = entry.getKey(); + CompoundTag blockTag = buildBedrockState(entry.getValue()); - // TODO fix this, (no block should have a null hardness) - JsonNode hardnessNode = entry.getValue().get("block_hardness"); - if (hardnessNode != null) { - 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()); - - JsonNode toolTypeNode = entry.getValue().get("tool_type"); - if (toolTypeNode != null) { - JAVA_RUNTIME_ID_TO_TOOL_TYPE.put(javaRuntimeId, toolTypeNode.textValue()); - } - - if (javaId.contains("wool")) { - JAVA_RUNTIME_WOOL_IDS.add(javaRuntimeId); - } - - if (javaId.contains("cobweb")) { - cobwebRuntimeId = javaRuntimeId; - } - - JAVA_ID_BLOCK_MAP.put(javaId, javaRuntimeId); - - // Used for adding all "special" Java block states to block state map - String identifier; - String bedrock_identifer = entry.getValue().get("bedrock_identifier").asText(); - for (Class clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) { - 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(javaRuntimeId, clazz.getAnnotation(BlockEntity.class).name()); - break; + // TODO fix this, (no block should have a null hardness) + JsonNode hardnessNode = entry.getValue().get("block_hardness"); + if (hardnessNode != null) { + JAVA_RUNTIME_ID_TO_HARDNESS.put(javaRuntimeId, hardnessNode.doubleValue()); } - } - BlockStateValues.storeBlockStateValues(entry, javaRuntimeId); + 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); + } - // Get the tag needed for non-empty flower pots - if (entry.getValue().get("pottable") != null) { - BlockStateValues.getFlowerPotBlocks().put(entry.getKey().split("\\[")[0], buildBedrockState(entry.getValue())); - } + JsonNode toolTypeNode = entry.getValue().get("tool_type"); + if (toolTypeNode != null) { + JAVA_RUNTIME_ID_TO_TOOL_TYPE.put(javaRuntimeId, toolTypeNode.textValue()); + } - if ("minecraft:water[level=0]".equals(javaId)) { - waterRuntimeId = bedrockRuntimeId; - } - boolean waterlogged = entry.getKey().contains("waterlogged=true") - || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); + if (javaId.contains("wool")) { + JAVA_RUNTIME_WOOL_IDS.add(javaRuntimeId); + } - if (waterlogged) { - BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId); - WATERLOGGED.add(javaRuntimeId); - } else { - BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaRuntimeId); - } + if (javaId.contains("cobweb")) { + cobwebRuntimeId = javaRuntimeId; + } - CompoundTag runtimeTag = blockStateMap.remove(blockTag); - if (runtimeTag != null) { - addedStatesMap.put(blockTag, bedrockRuntimeId); - paletteList.add(runtimeTag); - } else { - int duplicateRuntimeId = addedStatesMap.getOrDefault(blockTag, -1); - if (duplicateRuntimeId == -1) { - GeyserConnector.getInstance().getLogger().debug("Mapping " + javaId + " was not found for bedrock edition!"); + JAVA_ID_BLOCK_MAP.put(javaId, javaRuntimeId); + + // Used for adding all "special" Java block states to block state map + String identifier; + String bedrock_identifer = entry.getValue().get("bedrock_identifier").asText(); + for (Class clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) { + 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(javaRuntimeId, clazz.getAnnotation(BlockEntity.class).name()); + break; + } + } + + BlockStateValues.storeBlockStateValues(entry, javaRuntimeId); + + // Get the tag needed for non-empty flower pots + if (entry.getValue().get("pottable") != null) { + BlockStateValues.getFlowerPotBlocks().put(entry.getKey().split("\\[")[0], buildBedrockState(entry.getValue())); + } + + if ("minecraft:water[level=0]".equals(javaId)) { + waterRuntimeId = bedrockRuntimeId; + } + boolean waterlogged = entry.getKey().contains("waterlogged=true") + || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); + + if (waterlogged) { + BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId); + WATERLOGGED.add(javaRuntimeId); } else { - JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, duplicateRuntimeId); + BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaRuntimeId); } - continue; - } - JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, bedrockRuntimeId); - if (javaId.startsWith("minecraft:furnace[facing=north")) { - if (javaId.contains("lit=true")) { - furnaceLitRuntimeId = javaRuntimeId; + CompoundTag runtimeTag = blockStateMap.remove(blockTag); + if (runtimeTag != null) { + addedStatesMap.put(blockTag, bedrockRuntimeId); + paletteList.add(runtimeTag); } else { - furnaceRuntimeId = javaRuntimeId; + int duplicateRuntimeId = addedStatesMap.getOrDefault(blockTag, -1); + if (duplicateRuntimeId == -1) { + GeyserConnector.getInstance().getLogger().debug("Mapping " + javaId + " was not found for bedrock edition!"); + } else { + JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, duplicateRuntimeId); + } + continue; } - } + JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, bedrockRuntimeId); - if (javaId.startsWith("minecraft:spawner")) { - spawnerRuntimeId = javaRuntimeId; - } + if (javaId.startsWith("minecraft:furnace[facing=north")) { + if (javaId.contains("lit=true")) { + furnaceLitRuntimeId = javaRuntimeId; + } else { + furnaceRuntimeId = javaRuntimeId; + } + } - bedrockRuntimeId++; + if (javaId.startsWith("minecraft:spawner")) { + spawnerRuntimeId = javaRuntimeId; + } + + bedrockRuntimeId++; + } catch (Exception e) { + // REMOVE AFTER 1.16 UPDATE PROBABLY + System.out.println("Block translator error! " + e.toString()); + e.printStackTrace(); + } } if (cobwebRuntimeId == -1) { 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 6c8d9f944..b78a28ffe 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,10 @@ 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) { + public static void switchDimension(GeyserSession session, String javaDimension) { int bedrockDimension = javaToBedrock(javaDimension); Entity player = session.getPlayerEntity(); - if (bedrockDimension == player.getDimension()) + if (bedrockToJava(bedrockDimension) == player.getDimension()) return; session.getEntityCache().removeAllEntities(); @@ -55,7 +55,7 @@ public class DimensionUtils { changeDimensionPacket.setRespawn(true); changeDimensionPacket.setPosition(pos.toFloat()); session.sendUpstreamPacket(changeDimensionPacket); - player.setDimension(bedrockDimension); + player.setDimension(bedrockToJava(bedrockDimension)); player.setPosition(pos.toFloat()); session.setSpawned(false); session.setLastChunkPosition(null); @@ -83,14 +83,25 @@ public class DimensionUtils { * @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 "minecraft:nether": return BEDROCK_NETHER_ID; - case 1: + case "minecraft:the_end": return 2; default: - return javaDimension; + return 0; + } + } + + public static String bedrockToJava(int bedrockDimension) { + switch (bedrockDimension) { + case 1: + return "minecraft:nether"; + case 2: + return "minecraft:the_end"; + default: + return "minecraft:overworld"; } } 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 221a99176..6ab712431 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -210,13 +210,13 @@ public class MessageUtils { * @return Colour string to be used */ private static String getColorOrParent(MessageStyle style) { - ChatColor chatColor = style.getColor(); + String color = style.getColor(); - /*if (chatColor == ChatColor.NONE && style.getParent() != null) { + /*if (color == ChatColor.NONE && style.getParent() != null) { return getColorOrParent(style.getParent()); }*/ - return getColor(chatColor); + return getColor(color); } /** @@ -225,58 +225,58 @@ public class MessageUtils { * @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 ChatColor.RESET: //case NONE: base += "r"; break; @@ -369,16 +369,16 @@ public class MessageUtils { } 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)); - } - } +// for (ChatColor color : ChatColor.) { +// 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)); +// } +// } Not dealing with this return ""; } From b9ccabb3bb0ea34f0a89783ca5e327e823ea4041 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sat, 20 Jun 2020 22:46:09 -0400 Subject: [PATCH 013/104] According to all known laws of aviation, bees exist --- .../main/java/org/geysermc/connector/entity/type/EntityType.java | 1 + 1 file changed, 1 insertion(+) 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 77d7f5c9e..ea99c4704 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 @@ -150,6 +150,7 @@ public enum EntityType { COD(AbstractFishEntity.class, 112, 0.25f, 0.5f), 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), /** * Item frames are handled differently since they are a block in Bedrock. From 56f9330a2d5f35063e9de39e27a631fd69a29aa6 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 21 Jun 2020 19:22:59 -0400 Subject: [PATCH 014/104] Remove ServerSpawnWeatherEntityPacket --- .../platform/spigot/GeyserSpigotPlugin.java | 2 +- .../JavaSpawnWeatherEntityTranslator.java | 52 ------------------- 2 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnWeatherEntityTranslator.java diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index ae2ab530e..fd05131a7 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -35,11 +35,11 @@ import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; +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 org.geysermc.connector.utils.FileUtils; import java.io.File; import java.io.IOException; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnWeatherEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnWeatherEntityTranslator.java deleted file mode 100644 index c50686a04..000000000 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/spawn/JavaSpawnWeatherEntityTranslator.java +++ /dev/null @@ -1,52 +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.connector.network.translators.java.entity.spawn; - -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.spawn.ServerSpawnWeatherEntityPacket; -import com.nukkitx.math.vector.Vector3f; - -@Translator(packet = ServerSpawnWeatherEntityPacket.class) -public class JavaSpawnWeatherEntityTranslator extends PacketTranslator { - - @Override - public void translate(ServerSpawnWeatherEntityPacket packet, GeyserSession session) { - Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ()); - - // 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); - } -} From ea1a9e54275cacec2d035e459582434a4ce8628f Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 22 Jun 2020 20:11:09 -0400 Subject: [PATCH 015/104] Bedrock 1.16 updating part 1 --- connector/pom.xml | 4 +- .../geysermc/connector/GeyserConnector.java | 6 +- .../connector/entity/AbstractArrowEntity.java | 2 +- .../entity/AreaEffectCloudEntity.java | 8 +- .../geysermc/connector/entity/BoatEntity.java | 10 +- .../entity/DefaultBlockMinecartEntity.java | 4 +- .../connector/entity/EnderCrystalEntity.java | 4 +- .../org/geysermc/connector/entity/Entity.java | 33 +- .../connector/entity/ExpOrbEntity.java | 2 +- .../connector/entity/FallingBlockEntity.java | 2 +- .../connector/entity/FireworkEntity.java | 2 +- .../connector/entity/FishingHookEntity.java | 2 +- .../entity/FurnaceMinecartEntity.java | 2 +- .../connector/entity/ItemFrameEntity.java | 6 +- .../connector/entity/LivingEntity.java | 14 +- .../connector/entity/MinecartEntity.java | 4 +- .../connector/entity/PaintingEntity.java | 2 +- .../connector/entity/PlayerEntity.java | 25 +- .../entity/SpawnerMinecartEntity.java | 2 +- .../geysermc/connector/entity/TNTEntity.java | 4 +- .../connector/entity/TridentEntity.java | 2 +- .../entity/living/AbstractFishEntity.java | 2 +- .../entity/living/AgeableEntity.java | 4 +- .../entity/living/ArmorStandEntity.java | 2 +- .../entity/living/InsentientEntity.java | 2 +- .../connector/entity/living/SlimeEntity.java | 2 +- .../connector/entity/living/WaterEntity.java | 4 +- .../entity/living/animal/BeeEntity.java | 2 +- .../entity/living/animal/FoxEntity.java | 4 +- .../entity/living/animal/OcelotEntity.java | 2 +- .../entity/living/animal/PandaEntity.java | 2 +- .../entity/living/animal/PigEntity.java | 8 +- .../entity/living/animal/PolarBearEntity.java | 2 +- .../living/animal/PufferFishEntity.java | 2 +- .../entity/living/animal/RabbitEntity.java | 4 +- .../entity/living/animal/SheepEntity.java | 4 +- .../living/animal/TropicalFishEntity.java | 2 +- .../animal/horse/AbstractHorseEntity.java | 8 +- .../animal/horse/ChestedHorseEntity.java | 2 +- .../living/animal/horse/HorseEntity.java | 4 +- .../living/animal/horse/LlamaEntity.java | 4 +- .../animal/horse/TraderLlamaEntity.java | 2 +- .../living/animal/tameable/CatEntity.java | 4 +- .../living/animal/tameable/ParrotEntity.java | 2 +- .../animal/tameable/TameableEntity.java | 4 +- .../living/animal/tameable/WolfEntity.java | 4 +- .../living/merchant/VillagerEntity.java | 2 +- .../entity/living/monster/BlazeEntity.java | 2 +- .../entity/living/monster/CreeperEntity.java | 2 +- .../living/monster/ElderGuardianEntity.java | 2 +- .../living/monster/EnderDragonEntity.java | 8 +- .../entity/living/monster/EndermanEntity.java | 4 +- .../entity/living/monster/GiantEntity.java | 2 +- .../entity/living/monster/GuardianEntity.java | 2 +- .../entity/living/monster/ShulkerEntity.java | 2 +- .../entity/living/monster/SpiderEntity.java | 2 +- .../entity/living/monster/WitherEntity.java | 2 +- .../entity/living/monster/ZombieEntity.java | 4 +- .../network/LoggingPacketHandler.java | 74 ++- .../network/session/GeyserSession.java | 15 +- .../network/session/cache/BossBar.java | 12 +- .../bedrock/BedrockActionTranslator.java | 19 +- .../BedrockContainerCloseTranslator.java | 2 +- .../bedrock/BedrockEntityEventTranslator.java | 2 +- .../bedrock/BedrockInteractTranslator.java | 6 +- ...BedrockInventoryTransactionTranslator.java | 8 +- .../BedrockMobEquipmentTranslator.java | 2 +- .../bedrock/BedrockMovePlayerTranslator.java | 2 +- .../inventory/AnvilInventoryTranslator.java | 10 +- .../inventory/BaseInventoryTranslator.java | 4 +- .../inventory/BlockInventoryTranslator.java | 2 +- .../inventory/BrewingInventoryTranslator.java | 4 +- .../inventory/ChestInventoryTranslator.java | 2 +- .../CraftingInventoryTranslator.java | 10 +- .../DoubleChestInventoryTranslator.java | 6 +- .../EnchantmentInventoryTranslator.java | 2 +- .../inventory/FurnaceInventoryTranslator.java | 2 +- .../GrindstoneInventoryTranslator.java | 4 +- .../inventory/InventoryTranslator.java | 4 +- .../MerchantInventoryTranslator.java | 8 +- .../inventory/PlayerInventoryTranslator.java | 18 +- .../SingleChestInventoryTranslator.java | 2 +- .../action/InventoryActionDataTranslator.java | 10 +- .../holder/BlockInventoryHolder.java | 6 +- .../updater/ChestInventoryUpdater.java | 2 +- .../updater/ContainerInventoryUpdater.java | 2 +- .../updater/CursorInventoryUpdater.java | 8 +- .../inventory/updater/InventoryUpdater.java | 4 +- .../translators/item/ItemRegistry.java | 2 +- .../translators/item/ItemTranslator.java | 2 +- .../item/translators/BannerTranslator.java | 2 +- .../item/translators/PotionTranslator.java | 2 +- .../java/JavaDeclareCommandsTranslator.java | 544 +++++++++--------- .../java/JavaDeclareRecipesTranslator.java | 6 +- .../java/JavaRespawnTranslator.java | 2 +- .../translators/java/JavaTitleTranslator.java | 8 +- .../entity/JavaEntityAttachTranslator.java | 10 +- .../entity/JavaEntityEquipmentTranslator.java | 2 +- .../JavaEntitySetPassengersTranslator.java | 12 +- .../entity/JavaEntityStatusTranslator.java | 29 +- .../player/JavaPlayerAbilitiesTranslator.java | 31 +- .../player/JavaPlayerActionAckTranslator.java | 2 +- .../JavaPlayerPositionRotationTranslator.java | 4 +- .../world/JavaNotifyClientTranslator.java | 28 +- .../java/world/JavaPlayEffectTranslator.java | 11 +- .../world/JavaSpawnParticleTranslator.java | 2 +- .../java/world/JavaTradeListTranslator.java | 16 +- .../block/ComparatorSoundInteractHandler.java | 2 +- .../block/DoorSoundInteractionHandler.java | 2 +- .../block/LeverSoundInteractionHandler.java | 2 +- .../connector/utils/AttributeUtils.java | 5 +- .../connector/utils/CooldownUtils.java | 6 +- .../connector/utils/InventoryUtils.java | 8 +- .../geysermc/connector/utils/SkinUtils.java | 6 +- 114 files changed, 660 insertions(+), 594 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 0f1e60819..448e2bf7e 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -32,8 +32,8 @@ com.nukkitx.protocol - bedrock-v390 - 2.5.6-SNAPSHOT + bedrock-v407 + 2.6.0-SNAPSHOT compile diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index d201656ad..338cee5ff 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -29,7 +29,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; 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 lombok.Setter; import org.geysermc.common.AuthType; @@ -70,10 +70,10 @@ 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.V392_CODEC; public static final String NAME = "Geyser"; - public static final String VERSION = "DEV"; // A fallback for running in IDEs + public static final String VERSION = "1.0-SNAPSHOT (git-feature/1.16-56f9330)"; // A fallback for running in IDEs private final Map players = new HashMap<>(); 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 fa089707c..f174747b7 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 @@ 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.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 79e67f345..218615899 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 @@ package org.geysermc.connector.entity; 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 class AreaEffectCloudEntity extends Entity { 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 a59cd08fc..c067416df 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 @@ 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.EntityData; +import com.nukkitx.protocol.bedrock.data.entity.EntityData; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -92,7 +92,7 @@ public class BoatEntity extends Entity { } 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 @@ -106,7 +106,7 @@ public class BoatEntity extends Entity { 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(() -> @@ -124,7 +124,7 @@ public class BoatEntity extends Entity { 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), @@ -136,7 +136,7 @@ public class BoatEntity extends Entity { 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 index b774af980..dda4577d2 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/DefaultBlockMinecartEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/DefaultBlockMinecartEntity.java @@ -27,7 +27,7 @@ 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.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; @@ -45,7 +45,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity { super(entityId, geyserId, entityType, position, motion, rotation); updateDefaultBlockMetadata(); - metadata.put(EntityData.HAS_DISPLAY, (byte) 1); + metadata.put(EntityData.CUSTOM_DISPLAY, (byte) 1); } @Override 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 727df90c1..4b665683e 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.EntityMetadat 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 aa38441c7..4d4d097f0 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -38,10 +38,11 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlaye 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; @@ -106,9 +107,9 @@ public class Entity { 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(); @@ -240,7 +241,7 @@ public class Entity { 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; @@ -291,7 +292,7 @@ public class Entity { } } 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); } @@ -299,9 +300,9 @@ public class Entity { 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 @@ -317,7 +318,7 @@ public class Entity { 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()); @@ -329,10 +330,10 @@ public class Entity { 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()) { int bed = session.getConnector().getWorldManager().getBlockAt(session, lastInteractionPos.getX(), lastInteractionPos.getY(), lastInteractionPos.getZ()); @@ -340,7 +341,7 @@ public class Entity { 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); @@ -348,7 +349,7 @@ public class Entity { 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 bfd3e1cae..c830d2596 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 59e1d408e..54757b71f 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 1db4f757a..e1a8e08af 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.ListTag; 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 1b648f7cf..47259e316 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 @@ package org.geysermc.connector.entity; 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; 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 29ade1935..8f0d97b09 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FurnaceMinecartEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FurnaceMinecartEntity.java @@ -27,7 +27,7 @@ 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.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; 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 3680945cb..58edf29dd 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.Vector3f; 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; @@ -150,7 +150,7 @@ public class ItemFrameEntity extends Entity { 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 class ItemFrameEntity extends Entity { 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 f5aa4a544..3d1a1456f 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 @@ 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.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 class LivingEntity extends Entity { 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 a67c0be56..72b5ee820 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 @@ 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.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; @@ -69,7 +69,7 @@ public class MinecartEntity extends Entity { // 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)); + metadata.put(EntityData.CUSTOM_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0)); } } 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 00cfc8b54..d509b41f6 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 class PaintingEntity extends Entity { 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); 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 594f139a0..c567aa078 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; @@ -99,7 +100,7 @@ public class PlayerEntity extends LivingEntity { 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; @@ -194,7 +195,7 @@ public class PlayerEntity extends LivingEntity { movePlayerPacket.setRuntimeEntityId(geyserId); movePlayerPacket.setPosition(position); movePlayerPacket.setRotation(getBedrockRotation()); - movePlayerPacket.setMode(MovePlayerPacket.Mode.ROTATION); + movePlayerPacket.setMode(MovePlayerPacket.Mode.HEAD_ROTATION); session.sendUpstreamPacket(movePlayerPacket); } @@ -212,7 +213,7 @@ public class PlayerEntity extends LivingEntity { movePlayerPacket.setPosition(position); movePlayerPacket.setRotation(getBedrockRotation()); movePlayerPacket.setOnGround(isOnGround); - movePlayerPacket.setMode(MovePlayerPacket.Mode.ROTATION); + movePlayerPacket.setMode(MovePlayerPacket.Mode.HEAD_ROTATION); session.sendUpstreamPacket(movePlayerPacket); } @@ -247,9 +248,9 @@ public class PlayerEntity extends LivingEntity { 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); } @@ -269,8 +270,8 @@ public class PlayerEntity extends LivingEntity { 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 index 6be138c07..56341b3b0 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/SpawnerMinecartEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/SpawnerMinecartEntity.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/TNTEntity.java b/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java index 629c9e51c..d2addbfba 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 @@ 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.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 7c2442b0a..acc176100 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 @@ 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.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/AbstractFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/AbstractFishEntity.java index de5fa1b5b..9c3e20840 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 b90983f78..2175efcd6 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 @@ package org.geysermc.connector.entity.living; 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 47faad367..07496093f 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,7 +28,7 @@ package org.geysermc.connector.entity.living; 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; 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 2467dfe0d..808eb3cbb 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 @@ package org.geysermc.connector.entity.living; 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 26106f0a5..2ee22de7b 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 @@ package org.geysermc.connector.entity.living; 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 69afd9754..b0692eab0 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 537a12511..c46f00fe8 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 @@ 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.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 a277f8ee1..88c30cbfa 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 @@ 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.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 1c5dc9752..36a67dbb7 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 @@ 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.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 f22815c68..7e5551226 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 @@ 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.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 fd9fd999f..0a7c83e75 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,8 +27,8 @@ 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.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.type.EntityType; @@ -67,14 +67,14 @@ public class PigEntity extends AnimalEntity { 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/PolarBearEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/PolarBearEntity.java index 6011d5130..2b09ca912 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 @@ 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.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 d5503dc06..407708a55 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 @@ 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.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 6bc64bfd0..0b61713aa 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 @@ 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.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 e2b1b9791..464377efd 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 @@ 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.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/TropicalFishEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/TropicalFishEntity.java index a8866d7ec..eadc3db0c 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 @@ 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.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 3773011a3..48586c78f 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 @@ package org.geysermc.connector.entity.living.animal.horse; 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 class AbstractHorseEntity extends AnimalEntity { 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 df3543575..7343f5e84 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 @@ package org.geysermc.connector.entity.living.animal.horse; 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 27f4b83c7..da3ff3493 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 @@ package org.geysermc.connector.entity.living.animal.horse; 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 d4d7b7262..ddac4a63f 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 @@ package org.geysermc.connector.entity.living.animal.horse; 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 b9505509f..f01326730 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 de9bcb4ec..067a360cf 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 @@ package org.geysermc.connector.entity.living.animal.tameable; 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/tameable/ParrotEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/ParrotEntity.java index e02b3e7be..a867517a8 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 @@ package org.geysermc.connector.entity.living.animal.tameable; 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 2d3e0b1d1..2e8ab816c 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 @@ package org.geysermc.connector.entity.living.animal.tameable; 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 118262dcd..d0fb84a19 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 @@ package org.geysermc.connector.entity.living.animal.tameable; 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/merchant/VillagerEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/merchant/VillagerEntity.java index 895f8cc1d..a2fa1c49a 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 @@ package org.geysermc.connector.entity.living.merchant; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData; import 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 168369767..75fec18fc 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 @@ package org.geysermc.connector.entity.living.monster; 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 9b5c38220..3c3a76bd7 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 @@ package org.geysermc.connector.entity.living.monster; 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 fedd7980e..76b1ba2cd 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 394be544b..aa2b4e026 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 @@ package org.geysermc.connector.entity.living.monster; 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 class EnderDragonEntity extends InsentientEntity { 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 7232fb55b..b1c1fa11a 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 @@ -27,8 +27,8 @@ package org.geysermc.connector.entity.living.monster; 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; import org.geysermc.connector.network.translators.world.block.BlockTranslator; 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 b9dc9e66b..aa22d8d67 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 821faa850..aa9ce4ca5 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 @@ package org.geysermc.connector.entity.living.monster; 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 bca9e6891..8728547fc 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.entity.metadata.Position; 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 301145e65..f0ad6f058 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 @@ package org.geysermc.connector.entity.living.monster; 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 005d0db3a..8b864525f 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 @@ package org.geysermc.connector.entity.living.monster; 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 2ca212ff9..218a2ca08 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 @@ package org.geysermc.connector.entity.living.monster; 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/network/LoggingPacketHandler.java b/connector/src/main/java/org/geysermc/connector/network/LoggingPacketHandler.java index 91b3ebd40..c41c64c71 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 class LoggingPacketHandler implements BedrockPacketHandler { } @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 class LoggingPacketHandler implements BedrockPacketHandler { 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/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index a1caf2783..03d124289 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 @@ -45,6 +45,7 @@ import com.nukkitx.math.vector.*; import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.*; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -225,7 +226,7 @@ public class GeyserSession implements CommandSender { upstream.sendPacket(entityPacket); InventoryContentPacket creativePacket = new InventoryContentPacket(); - creativePacket.setContainerId(ContainerId.CREATIVE); + creativePacket.setContainerId(ContainerId.CREATIVE); //TODO: Why is this deprecated? creativePacket.setContents(ItemRegistry.CREATIVE_ITEMS); upstream.sendPacket(creativePacket); @@ -235,10 +236,10 @@ public class GeyserSession implements CommandSender { UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket(); attributesPacket.setRuntimeEntityId(getPlayerEntity().getGeyserId()); - List attributes = new ArrayList<>(); + 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 Attribute("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f)); + attributes.add(new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f)); attributesPacket.setAttributes(attributes); upstream.sendPacket(attributesPacket); } @@ -495,18 +496,18 @@ public class GeyserSession implements CommandSender { 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(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); @@ -531,7 +532,7 @@ public class GeyserSession implements CommandSender { 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 267f3cb1f..68e8519c1 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 @@ package org.geysermc.connector.network.session.cache; 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 class BossBar { 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 class BossBar { 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 class BossBar { 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 class BossBar { 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/translators/bedrock/BedrockActionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java index 64572f361..7d8772fbd 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.data.game.world.block.BlockFace; 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,7 +112,7 @@ public class BedrockActionTranslator extends PacketTranslator= 32 && 42 >= slotnum) { return slotnum - 31; 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 e5be2fec3..a467e2186 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 @@ -28,7 +28,7 @@ package org.geysermc.connector.network.translators.inventory; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; 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; @@ -96,8 +96,8 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { @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); 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 ba7f8cc7a..c8e9ed186 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 5c6de0e8a..1f148e024 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 174cfbc11..6e729c39c 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,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 org.geysermc.connector.network.translators.inventory.updater.CursorInventoryUpdater; public class GrindstoneInventoryTranslator extends BlockInventoryTranslator { 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 975949070..37621647e 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; 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 index 3f7636b9e..37c84e28a 100644 --- 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 @@ -26,9 +26,9 @@ 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.InventorySource; +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; @@ -60,7 +60,7 @@ public class MerchantInventoryTranslator extends BaseInventoryTranslator { @Override public int bedrockSlotToJava(InventoryActionData action) { - if (action.getSource().getContainerId() == ContainerId.CURSOR) { + if (action.getSource().getContainerId() == ContainerId.UI) { switch (action.getSlot()) { case 4: return 0; 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 28986e58c..db26c469e 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 @@ 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.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; @@ -94,7 +94,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { // 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) { @@ -122,7 +122,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { 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(session, inventory.getItem(slot))); @@ -156,7 +156,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { break; case ContainerId.OFFHAND: return 45; - case ContainerId.CURSOR: + case ContainerId.UI: if (slotnum >= 28 && 31 >= slotnum) { return slotnum - 27; } else if (slotnum == 50) { @@ -184,7 +184,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { if (session.getGameMode() == GameMode.CREATIVE) { //crafting grid is not visible in creative mode in java edition for (InventoryActionData action : actions) { - if (action.getSource().getContainerId() == ContainerId.CURSOR && (action.getSlot() >= 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 class PlayerInventoryTranslator extends InventoryTranslator { session.sendDownstreamPacket(creativePacket); inventory.setItem(javaSlot, javaItem); break; - case ContainerId.CURSOR: + case ContainerId.UI: if (action.getSlot() == 0) { session.getInventory().setCursor(ItemTranslator.translateToJava(action.getToItem())); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/SingleChestInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/SingleChestInventoryTranslator.java index b08b50841..45860dcd3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/SingleChestInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/SingleChestInventoryTranslator.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.holder.BlockInventoryHolder; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java index 209df0748..c1ed472cc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java @@ -32,10 +32,10 @@ import com.github.steveice10.mc.protocol.data.game.window.*; import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientWindowActionPacket; -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 org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; @@ -59,7 +59,7 @@ public class InventoryActionDataTranslator { return; } else if (action.getSource().getType() == InventorySource.Type.WORLD_INTERACTION) { worldAction = action; - } else if (action.getSource().getContainerId() == ContainerId.CURSOR && action.getSlot() == 0) { + } else if (action.getSource().getContainerId() == ContainerId.UI && action.getSlot() == 0) { cursorAction = action; ItemData translatedCursor = ItemTranslator.translateToBedrock(session, session.getInventory().getCursor()); if (!translatedCursor.equals(action.getFromItem())) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java index 950e2eeb6..ce02b8751 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java @@ -28,7 +28,7 @@ package org.geysermc.connector.network.translators.inventory.holder; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; 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; @@ -70,8 +70,8 @@ public class BlockInventoryHolder extends InventoryHolder { @Override public void openInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket(); - containerOpenPacket.setWindowId((byte) inventory.getId()); - containerOpenPacket.setType((byte) containerType.id()); + containerOpenPacket.setId((byte) inventory.getId()); + containerOpenPacket.setType(containerType); containerOpenPacket.setBlockPosition(inventory.getHolderPosition()); containerOpenPacket.setUniqueEntityId(inventory.getHolderId()); session.sendUpstreamPacket(containerOpenPacket); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java index 6ec8d4810..7437a26e4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java @@ -25,7 +25,7 @@ package org.geysermc.connector.network.translators.inventory.updater; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import lombok.AllArgsConstructor; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java index ec6175c36..51f33ac43 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ContainerInventoryUpdater.java @@ -25,7 +25,7 @@ package org.geysermc.connector.network.translators.inventory.updater; -import com.nukkitx.protocol.bedrock.data.ItemData; +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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java index adbbdbacd..26d889900 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/CursorInventoryUpdater.java @@ -25,7 +25,7 @@ package org.geysermc.connector.network.translators.inventory.updater; -import com.nukkitx.protocol.bedrock.data.ContainerId; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; @@ -33,6 +33,8 @@ import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator; public class CursorInventoryUpdater extends InventoryUpdater { + + //TODO: Consider renaming this? Since the Protocol enum updated @Override public void updateInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { super.updateInventory(translator, session, inventory); @@ -42,7 +44,7 @@ public class CursorInventoryUpdater extends InventoryUpdater { if (bedrockSlot == 50) continue; InventorySlotPacket slotPacket = new InventorySlotPacket(); - slotPacket.setContainerId(ContainerId.CURSOR); + slotPacket.setContainerId(ContainerId.UI); slotPacket.setSlot(bedrockSlot); slotPacket.setItem(ItemTranslator.translateToBedrock(session, inventory.getItem(i))); session.sendUpstreamPacket(slotPacket); @@ -55,7 +57,7 @@ public class CursorInventoryUpdater extends InventoryUpdater { return true; InventorySlotPacket slotPacket = new InventorySlotPacket(); - slotPacket.setContainerId(ContainerId.CURSOR); + slotPacket.setContainerId(ContainerId.UI); slotPacket.setSlot(translator.javaSlotToBedrock(javaSlot)); slotPacket.setItem(ItemTranslator.translateToBedrock(session, inventory.getItem(javaSlot))); session.sendUpstreamPacket(slotPacket); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java index 88157df09..57601a9e0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/InventoryUpdater.java @@ -25,8 +25,8 @@ package org.geysermc.connector.network.translators.inventory.updater; -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.InventoryContentPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.connector.inventory.Inventory; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index 65b40e616..dd9d14eb2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -30,7 +30,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.nukkitx.nbt.NbtUtils; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index be8080d85..6f11e94ac 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -32,7 +32,7 @@ import com.github.steveice10.opennbt.tag.builtin.*; import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.nbt.tag.Tag; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.geysermc.connector.GeyserConnector; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java index f4f545ffe..8a1a973b0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java @@ -32,7 +32,7 @@ import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.item.ItemTranslator; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java index 2fdde31dd..7cb88d70c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java @@ -28,7 +28,7 @@ package org.geysermc.connector.network.translators.item.translators; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; -import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.item.ItemTranslator; 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 053630d53..16d910b8f 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 @@ -25,293 +25,281 @@ package org.geysermc.connector.network.translators.java; -import com.github.steveice10.mc.protocol.data.game.command.CommandNode; -import com.github.steveice10.mc.protocol.data.game.command.CommandParser; import com.github.steveice10.mc.protocol.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.packet.AvailableCommandsPacket; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import lombok.Getter; -import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; -import java.util.*; - @Translator(packet = ServerDeclareCommandsPacket.class) public class JavaDeclareCommandsTranslator extends PacketTranslator { @Override public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) { // Don't send command suggestions if they are disabled - if (!session.getConnector().getConfig().isCommandSuggestions()) { - session.getConnector().getLogger().debug("Not sending command suggestions as they are disabled."); - return; - } - List commandData = new ArrayList<>(); - Int2ObjectMap commands = new Int2ObjectOpenHashMap<>(); - Int2ObjectMap> commandArgs = new Int2ObjectOpenHashMap<>(); - - // Get the first node, it should be a root node - CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; - - // Loop through the root nodes to get all commands - for (int nodeIndex : rootNode.getChildIndices()) { - CommandNode node = packet.getNodes()[nodeIndex]; - - // Make sure we don't have duplicated commands (happens if there is more than 1 root node) - if (commands.containsKey(nodeIndex)) { continue; } - if (commands.containsValue(node.getName())) { continue; } - - // Get and update the commandArgs list with the found arguments - if (node.getChildIndices().length >= 1) { - for (int childIndex : node.getChildIndices()) { - commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); - commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); - } - } - - // Insert the command name into the list - commands.put(nodeIndex, node.getName()); - } - - // The command flags, not sure what these do apart from break things - List flags = new ArrayList<>(); - - // Loop through all the found commands - for (int commandID : commands.keySet()) { - String commandName = commands.get(commandID); - - // Create a basic alias - CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); - - // Get and parse all params - CommandParamData[][] params = getParams(packet.getNodes()[commandID], packet.getNodes()); - - // Build the completed command and add it to the final list - CommandData data = new CommandData(commandName, session.getConnector().getCommandManager().getDescription(commandName), flags, (byte) 0, aliases, params); - commandData.add(data); - } - - // Add our commands to the AvailableCommandsPacket for the bedrock client - AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); - for (CommandData data : commandData) { - availableCommandsPacket.getCommands().add(data); - } - - GeyserConnector.getInstance().getLogger().debug("Sending command packet of " + commandData.size() + " commands"); - - // Finally, send the commands to the client - session.sendUpstreamPacket(availableCommandsPacket); - } - - /** - * Build the command parameter array for the given command - * - * @param commandNode The command to build the parameters for - * @param allNodes Every command node - * - * @return An array of parameter option arrays - */ - private CommandParamData[][] getParams(CommandNode commandNode, CommandNode[] allNodes) { - // Check if the command is an alias and redirect it - if (commandNode.getRedirectIndex() != -1) { - GeyserConnector.getInstance().getLogger().debug("Redirecting command " + commandNode.getName() + " to " + allNodes[commandNode.getRedirectIndex()].getName()); - commandNode = allNodes[commandNode.getRedirectIndex()]; - } - - if (commandNode.getChildIndices().length >= 1) { - // Create the root param node and build all the children - ParamInfo rootParam = new ParamInfo(commandNode, null); - rootParam.buildChildren(allNodes); - - List treeData = rootParam.getTree(); - CommandParamData[][] params = new CommandParamData[treeData.size()][]; - - // Fill the nested params array - int i = 0; - for (CommandParamData[] tree : treeData) { - params[i] = tree; - i++; - } - - return params; - } - - return new CommandParamData[0][0]; - } - - /** - * Convert Java edition command types to Bedrock edition - * - * @param parser Command type to convert - * - * @return Bedrock parameter data type - */ - private CommandParamData.Type mapCommandType(CommandParser parser) { - if (parser == null) { return CommandParamData.Type.STRING; } - - switch (parser) { - case FLOAT: - return CommandParamData.Type.FLOAT; - - case INTEGER: - return CommandParamData.Type.INT; - - case ENTITY: - case GAME_PROFILE: - return CommandParamData.Type.TARGET; - - case BLOCK_POS: - return CommandParamData.Type.BLOCK_POSITION; - - case COLUMN_POS: - case VEC3: - return CommandParamData.Type.POSITION; - - case MESSAGE: - return CommandParamData.Type.MESSAGE; - - case NBT: - case NBT_COMPOUND_TAG: - case NBT_TAG: - case NBT_PATH: - return CommandParamData.Type.JSON; - - case RESOURCE_LOCATION: - return CommandParamData.Type.FILE_PATH; - - case INT_RANGE: - return CommandParamData.Type.INT_RANGE; - - case BOOL: - case DOUBLE: - case STRING: - case VEC2: - case BLOCK_STATE: - case BLOCK_PREDICATE: - case ITEM_STACK: - case ITEM_PREDICATE: - case COLOR: - case COMPONENT: - case OBJECTIVE: - case OBJECTIVE_CRITERIA: - case OPERATION: // Possibly OPERATOR - case PARTICLE: - case ROTATION: - case SCOREBOARD_SLOT: - case SCORE_HOLDER: - case SWIZZLE: - case TEAM: - case ITEM_SLOT: - case MOB_EFFECT: - case FUNCTION: - case ENTITY_ANCHOR: - case RANGE: - case FLOAT_RANGE: - case ITEM_ENCHANTMENT: - case ENTITY_SUMMON: - case DIMENSION: - case TIME: - default: - return CommandParamData.Type.STRING; - } - } - - @Getter - private class ParamInfo { - private CommandNode paramNode; - private CommandParamData paramData; - private List children; - - /** - * Create a new parameter info object - * - * @param paramNode CommandNode the parameter is for - * @param paramData The existing parameters for the command - */ - public ParamInfo(CommandNode paramNode, CommandParamData paramData) { - this.paramNode = paramNode; - this.paramData = paramData; - this.children = new ArrayList<>(); - } - - /** - * Build the array of all the child parameters (recursive) - * - * @param allNodes Every command node - */ - public void buildChildren(CommandNode[] allNodes) { - int enumIndex = -1; - - for (int paramID : paramNode.getChildIndices()) { - CommandNode paramNode = allNodes[paramID]; - - if (paramNode.getParser() == null) { - if (enumIndex == -1) { - enumIndex = children.size(); - - // Create the new enum command - CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); - children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); - } else { - // Get the existing enum - ParamInfo enumParamInfo = children.get(enumIndex); - - // Extend the current list of enum values - String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().length + 1); - enumOptions[enumOptions.length - 1] = paramNode.getName(); - - // Re-create the command using the updated values - CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), enumOptions, false); - children.set(enumIndex, new ParamInfo(enumParamInfo.getParamNode(), new CommandParamData(enumParamInfo.getParamData().getName(), false, enumData, enumParamInfo.getParamData().getType(), null, Collections.emptyList()))); - } - }else{ - // Put the non-enum param into the list - children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); - } - } - - // Recursively build all child options - for (ParamInfo child : children) { - child.buildChildren(allNodes); - } - } - - /** - * Get the tree of every parameter node (recursive) - * - * @return List of parameter options arrays for the command - */ - public List getTree() { - List treeParamData = new ArrayList<>(); - - for (ParamInfo child : children) { - // Get the tree from the child - List childTree = child.getTree(); - - // Un-pack the tree append the child node to it and push into the list - for (CommandParamData[] subchild : childTree) { - CommandParamData[] tmpTree = new ArrayList() { - { - add(child.getParamData()); - addAll(Arrays.asList(subchild)); - } - }.toArray(new CommandParamData[0]); - - treeParamData.add(tmpTree); - } - - // If we have no more child parameters just the child - if (childTree.size() == 0) { - treeParamData.add(new CommandParamData[] { child.getParamData() }); - } - } - - return treeParamData; - } +// if (!session.getConnector().getConfig().isCommandSuggestions()) { +// session.getConnector().getLogger().debug("Not sending command suggestions as they are disabled."); +// return; +// } +// List commandData = new ArrayList<>(); +// Int2ObjectMap commands = new Int2ObjectOpenHashMap<>(); +// Int2ObjectMap> commandArgs = new Int2ObjectOpenHashMap<>(); +// +// // Get the first node, it should be a root node +// CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; +// +// // Loop through the root nodes to get all commands +// for (int nodeIndex : rootNode.getChildIndices()) { +// CommandNode node = packet.getNodes()[nodeIndex]; +// +// // Make sure we don't have duplicated commands (happens if there is more than 1 root node) +// if (commands.containsKey(nodeIndex)) { continue; } +// if (commands.containsValue(node.getName())) { continue; } +// +// // Get and update the commandArgs list with the found arguments +// if (node.getChildIndices().length >= 1) { +// for (int childIndex : node.getChildIndices()) { +// commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); +// commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); +// } +// } +// +// // Insert the command name into the list +// commands.put(nodeIndex, node.getName()); +// } +// +// // The command flags, not sure what these do apart from break things +// List flags = new ArrayList<>(); +// +// // Loop through all the found commands +// for (int commandID : commands.keySet()) { +// String commandName = commands.get(commandID); +// +// // Create a basic alias +// CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); +// +// // Get and parse all params +// CommandParamData[][] params = getParams(packet.getNodes()[commandID], packet.getNodes()); +// +// // Build the completed command and add it to the final list +// CommandData data = new CommandData(commandName, session.getConnector().getCommandManager().getDescription(commandName), flags, (byte) 0, aliases, params); +// commandData.add(data); +// } +// +// // Add our commands to the AvailableCommandsPacket for the bedrock client +// AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); +// for (CommandData data : commandData) { +// availableCommandsPacket.getCommands().add(data); +// } +// +// GeyserConnector.getInstance().getLogger().debug("Sending command packet of " + commandData.size() + " commands"); +// +// // Finally, send the commands to the client +// session.sendUpstreamPacket(availableCommandsPacket); +// } +// +// /** +// * Build the command parameter array for the given command +// * +// * @param commandNode The command to build the parameters for +// * @param allNodes Every command node +// * +// * @return An array of parameter option arrays +// */ +// private CommandParamData[][] getParams(CommandNode commandNode, CommandNode[] allNodes) { +// // Check if the command is an alias and redirect it +// if (commandNode.getRedirectIndex() != -1) { +// GeyserConnector.getInstance().getLogger().debug("Redirecting command " + commandNode.getName() + " to " + allNodes[commandNode.getRedirectIndex()].getName()); +// commandNode = allNodes[commandNode.getRedirectIndex()]; +// } +// +// if (commandNode.getChildIndices().length >= 1) { +// // Create the root param node and build all the children +// ParamInfo rootParam = new ParamInfo(commandNode, null); +// rootParam.buildChildren(allNodes); +// +// List treeData = rootParam.getTree(); +// CommandParamData[][] params = new CommandParamData[treeData.size()][]; +// +// // Fill the nested params array +// int i = 0; +// for (CommandParamData[] tree : treeData) { +// params[i] = tree; +// i++; +// } +// +// return params; +// } +// +// return new CommandParamData[0][0]; +// } +// +// /** +// * Convert Java edition command types to Bedrock edition +// * +// * @param parser Command type to convert +// * +// * @return Bedrock parameter data type +// */ +// private CommandParamData.Type mapCommandType(CommandParser parser) { +// if (parser == null) { return CommandParamData.Type.STRING; } //TODO: this +// +// switch (parser) { +// case FLOAT: +// return CommandParamData.Type.FLOAT; +// +// case INTEGER: +// return CommandParamData.Type.INT; +// +// case ENTITY: +// case GAME_PROFILE: +// return CommandParamData.Type.TARGET; +// +// case BLOCK_POS: +// return CommandParamData.Type.BLOCK_POSITION; +// +// case COLUMN_POS: +// case VEC3: +// return CommandParamData.Type.POSITION; +// +// case MESSAGE: +// return CommandParamData.Type.MESSAGE; +// +// case NBT: +// case NBT_COMPOUND_TAG: +// case NBT_TAG: +// case NBT_PATH: +// return CommandParamData.Type.JSON; +// +// case RESOURCE_LOCATION: +// return CommandParamData.Type.FILE_PATH; +// +// case INT_RANGE: +// return CommandParamData.Type.INT_RANGE; +// +// case BOOL: +// case DOUBLE: +// case STRING: +// case VEC2: +// case BLOCK_STATE: +// case BLOCK_PREDICATE: +// case ITEM_STACK: +// case ITEM_PREDICATE: +// case COLOR: +// case COMPONENT: +// case OBJECTIVE: +// case OBJECTIVE_CRITERIA: +// case OPERATION: // Possibly OPERATOR +// case PARTICLE: +// case ROTATION: +// case SCOREBOARD_SLOT: +// case SCORE_HOLDER: +// case SWIZZLE: +// case TEAM: +// case ITEM_SLOT: +// case MOB_EFFECT: +// case FUNCTION: +// case ENTITY_ANCHOR: +// case RANGE: +// case FLOAT_RANGE: +// case ITEM_ENCHANTMENT: +// case ENTITY_SUMMON: +// case DIMENSION: +// case TIME: +// default: +// return CommandParamData.Type.STRING; +// } +// } +// +// @Getter +// private class ParamInfo { +// private CommandNode paramNode; +// private CommandParamData paramData; +// private List children; +// +// /** +// * Create a new parameter info object +// * +// * @param paramNode CommandNode the parameter is for +// * @param paramData The existing parameters for the command +// */ +// public ParamInfo(CommandNode paramNode, CommandParamData paramData) { +// this.paramNode = paramNode; +// this.paramData = paramData; +// this.children = new ArrayList<>(); +// } +// +// /** +// * Build the array of all the child parameters (recursive) +// * +// * @param allNodes Every command node +// */ +// public void buildChildren(CommandNode[] allNodes) { +// int enumIndex = -1; +// +// for (int paramID : paramNode.getChildIndices()) { +// CommandNode paramNode = allNodes[paramID]; +// +// if (paramNode.getParser() == null) { +// if (enumIndex == -1) { +// enumIndex = children.size(); +// +// // Create the new enum command +// CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); +// children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); +// } else { +// // Get the existing enum +// ParamInfo enumParamInfo = children.get(enumIndex); +// +// // Extend the current list of enum values +// String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().length + 1); +// enumOptions[enumOptions.length - 1] = paramNode.getName(); +// +// // Re-create the command using the updated values +// CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), enumOptions, false); +// children.set(enumIndex, new ParamInfo(enumParamInfo.getParamNode(), new CommandParamData(enumParamInfo.getParamData().getName(), false, enumData, enumParamInfo.getParamData().getType(), null, Collections.emptyList()))); +// } +// }else{ +// // Put the non-enum param into the list +// children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); +// } +// } +// +// // Recursively build all child options +// for (ParamInfo child : children) { +// child.buildChildren(allNodes); +// } +// } +// +// /** +// * Get the tree of every parameter node (recursive) +// * +// * @return List of parameter options arrays for the command +// */ +// public List getTree() { +// List treeParamData = new ArrayList<>(); +// +// for (ParamInfo child : children) { +// // Get the tree from the child +// List childTree = child.getTree(); +// +// // Un-pack the tree append the child node to it and push into the list +// for (CommandParamData[] subchild : childTree) { +// CommandParamData[] tmpTree = new ArrayList() { +// { +// add(child.getParamData()); +// addAll(Arrays.asList(subchild)); +// } +// }.toArray(new CommandParamData[0]); +// +// treeParamData.add(tmpTree); +// } +// +// // If we have no more child parameters just the child +// if (childTree.size() == 0) { +// treeParamData.add(new CommandParamData[] { child.getParamData() }); +// } +// } +// +// return treeParamData; +// } } } 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 b0637722b..ab80cce10 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.ShapedRecipeData; 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; 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 a58141118..0d80f4af7 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,7 +61,7 @@ public class JavaRespawnTranslator extends PacketTranslator 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); 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 8ecf4e30f..214413ab7 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 class JavaTitleTranslator extends PacketTranslator { 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 6e53df27c..2ab499b00 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 class JavaEntityAttachTranslator extends PacketTranslator 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 b8675dbfe..98089ff27 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 class JavaEntityStatusTranslator extends PacketTranslator { @@ -59,20 +58,20 @@ public class JavaPlayerAbilitiesTranslator extends PacketTranslator 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 eeff588ee..9ed11a23d 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 @@ -52,7 +52,7 @@ public class JavaPlayerActionAckTranslator extends PacketTranslator 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 class JavaNotifyClientTranslator 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 class JavaPlayEffectTranslator extends PacketTranslator 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.SET_TITLE); + titlePacket.setType(SetTitlePacket.Type.TITLE); titlePacket.setText(" "); session.sendUpstreamPacket(titlePacket); session.setLastHitTime(System.currentTimeMillis()); @@ -70,7 +70,7 @@ public class CooldownUtils { 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.SET_SUBTITLE); + titlePacket.setType(SetTitlePacket.Type.SUBTITLE); titlePacket.setText(getTitle(session)); titlePacket.setFadeInTime(0); titlePacket.setFadeOutTime(5); @@ -80,7 +80,7 @@ public class CooldownUtils { 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.SET_SUBTITLE); + removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE); removeTitlePacket.setText(" "); session.sendUpstreamPacket(removeTitlePacket); } 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 ded47723a..66db00cee 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; 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.ContainerClosePacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import org.geysermc.common.ChatColor; @@ -100,7 +100,7 @@ public class InventoryUtils { //Spamming close window packets can bug the client if (System.currentTimeMillis() - session.getLastWindowCloseTime() > 500) { ContainerClosePacket closePacket = new ContainerClosePacket(); - closePacket.setWindowId((byte) windowId); + closePacket.setId((byte) windowId); session.sendUpstreamPacket(closePacket); session.setLastWindowCloseTime(System.currentTimeMillis()); } @@ -108,7 +108,7 @@ public class InventoryUtils { 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, session.getInventory().getCursor())); session.sendUpstreamPacket(cursorPacket); 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 48e4c4c80..e93388c47 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -28,13 +28,11 @@ package org.geysermc.connector.utils; 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.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; From 0471fa89f49ad5b01f1a3863cb83a4b49ce7c113 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 22 Jun 2020 21:21:42 -0400 Subject: [PATCH 016/104] Bedrock 1.16 updating part 2 (Doesn't work) --- .../main/java/org/geysermc/connector/GeyserConnector.java | 4 ++-- .../connector/entity/living/monster/EndermanEntity.java | 2 +- .../bedrock/BedrockAdventureSettingsTranslator.java | 5 +++-- .../translators/inventory/CraftingInventoryTranslator.java | 4 ++-- .../translators/java/world/JavaSpawnParticleTranslator.java | 2 +- .../world/block/entity/FlowerPotBlockEntityTranslator.java | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 338cee5ff..b584c87af 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -70,10 +70,10 @@ 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_v407.V392_CODEC; + public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v407.V407_CODEC; // As of this time this is in a PR public static final String NAME = "Geyser"; - public static final String VERSION = "1.0-SNAPSHOT (git-feature/1.16-56f9330)"; // A fallback for running in IDEs + public static final String VERSION = "DEV"; // A fallback for running in IDEs private final Map players = new HashMap<>(); 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 b1c1fa11a..914b20859 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 @@ -43,7 +43,7 @@ public class EndermanEntity extends MonsterEntity { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { // Held block if (entityMetadata.getId() == 15) { - metadata.put(EntityData.ENDERMAN_HELD_ITEM_ID, BlockTranslator.getBedrockBlockId((int) 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/network/translators/bedrock/BedrockAdventureSettingsTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAdventureSettingsTranslator.java index 6ee70cb32..e741ca35c 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 @@ package org.geysermc.connector.network.translators.bedrock; 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,8 +41,8 @@ public class BedrockAdventureSettingsTranslator extends PacketTranslator Date: Tue, 23 Jun 2020 09:34:12 -0400 Subject: [PATCH 017/104] Update for 1.16 --- connector/pom.xml | 2 +- .../src/main/java/org/geysermc/connector/GeyserConnector.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 448e2bf7e..7bb00ecf3 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.steveice10 mcprotocollib - 1.16-rc1-SNAPSHOT + 1.16-SNAPSHOT compile diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index b584c87af..bdd7e74c7 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -70,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_v407.V407_CODEC; // As of this time this is in a PR + 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 From ca7484a5cfd6d926e330643461e8ff816db74423 Mon Sep 17 00:00:00 2001 From: endevrr Date: Wed, 24 Jun 2020 00:51:59 +0100 Subject: [PATCH 018/104] Relocate Reflections Dependency (#802) --- bootstrap/bungeecord/pom.xml | 4 ++++ bootstrap/spigot/pom.xml | 6 +++++- bootstrap/sponge/pom.xml | 4 ++++ bootstrap/velocity/pom.xml | 4 ++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml index dd66db322..875991fa0 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/spigot/pom.xml b/bootstrap/spigot/pom.xml index 6ad7a637a..4564d11ce 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -73,7 +73,11 @@ com.fasterxml.jackson - org.geysermc.platform.bukkit.shaded.jackson + org.geysermc.platform.spigot.shaded.jackson + + + org.reflections.reflections + org.geysermc.platform.spigot.shaded.reflections diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml index c9abbe3ed..4a995711a 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/velocity/pom.xml b/bootstrap/velocity/pom.xml index fb06767e0..78f219731 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 + From 78df56c7a0e99cf7b976ee1f0503cf705f460b6d Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 24 Jun 2020 11:14:11 -0400 Subject: [PATCH 019/104] Update for 1.16.1 --- connector/pom.xml | 2 +- .../translators/java/world/JavaBlockValueTranslator.java | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 7bb00ecf3..eaa2801e9 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.steveice10 mcprotocollib - 1.16-SNAPSHOT + 1.16.1-SNAPSHOT compile diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java index dd8c336d3..b304ed77f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockValueTranslator.java @@ -32,7 +32,6 @@ import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.BlockEventPacket; - import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -75,10 +74,6 @@ public class JavaBlockValueTranslator extends PacketTranslator Date: Wed, 24 Jun 2020 12:16:30 -0400 Subject: [PATCH 020/104] Uncomment JavaDeclareCommandsTranslator and update --- .../java/JavaDeclareCommandsTranslator.java | 548 +++++++++--------- 1 file changed, 282 insertions(+), 266 deletions(-) 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 16d910b8f..8f5243366 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 @@ -25,281 +25,297 @@ package org.geysermc.connector.network.translators.java; +import com.github.steveice10.mc.protocol.data.game.command.CommandNode; +import com.github.steveice10.mc.protocol.data.game.command.CommandParser; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket; +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; +import lombok.Getter; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +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 { @Override public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) { // Don't send command suggestions if they are disabled -// if (!session.getConnector().getConfig().isCommandSuggestions()) { -// session.getConnector().getLogger().debug("Not sending command suggestions as they are disabled."); -// return; -// } -// List commandData = new ArrayList<>(); -// Int2ObjectMap commands = new Int2ObjectOpenHashMap<>(); -// Int2ObjectMap> commandArgs = new Int2ObjectOpenHashMap<>(); -// -// // Get the first node, it should be a root node -// CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; -// -// // Loop through the root nodes to get all commands -// for (int nodeIndex : rootNode.getChildIndices()) { -// CommandNode node = packet.getNodes()[nodeIndex]; -// -// // Make sure we don't have duplicated commands (happens if there is more than 1 root node) -// if (commands.containsKey(nodeIndex)) { continue; } -// if (commands.containsValue(node.getName())) { continue; } -// -// // Get and update the commandArgs list with the found arguments -// if (node.getChildIndices().length >= 1) { -// for (int childIndex : node.getChildIndices()) { -// commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); -// commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); -// } -// } -// -// // Insert the command name into the list -// commands.put(nodeIndex, node.getName()); -// } -// -// // The command flags, not sure what these do apart from break things -// List flags = new ArrayList<>(); -// -// // Loop through all the found commands -// for (int commandID : commands.keySet()) { -// String commandName = commands.get(commandID); -// -// // Create a basic alias -// CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); -// -// // Get and parse all params -// CommandParamData[][] params = getParams(packet.getNodes()[commandID], packet.getNodes()); -// -// // Build the completed command and add it to the final list -// CommandData data = new CommandData(commandName, session.getConnector().getCommandManager().getDescription(commandName), flags, (byte) 0, aliases, params); -// commandData.add(data); -// } -// -// // Add our commands to the AvailableCommandsPacket for the bedrock client -// AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); -// for (CommandData data : commandData) { -// availableCommandsPacket.getCommands().add(data); -// } -// -// GeyserConnector.getInstance().getLogger().debug("Sending command packet of " + commandData.size() + " commands"); -// -// // Finally, send the commands to the client -// session.sendUpstreamPacket(availableCommandsPacket); -// } -// -// /** -// * Build the command parameter array for the given command -// * -// * @param commandNode The command to build the parameters for -// * @param allNodes Every command node -// * -// * @return An array of parameter option arrays -// */ -// private CommandParamData[][] getParams(CommandNode commandNode, CommandNode[] allNodes) { -// // Check if the command is an alias and redirect it -// if (commandNode.getRedirectIndex() != -1) { -// GeyserConnector.getInstance().getLogger().debug("Redirecting command " + commandNode.getName() + " to " + allNodes[commandNode.getRedirectIndex()].getName()); -// commandNode = allNodes[commandNode.getRedirectIndex()]; -// } -// -// if (commandNode.getChildIndices().length >= 1) { -// // Create the root param node and build all the children -// ParamInfo rootParam = new ParamInfo(commandNode, null); -// rootParam.buildChildren(allNodes); -// -// List treeData = rootParam.getTree(); -// CommandParamData[][] params = new CommandParamData[treeData.size()][]; -// -// // Fill the nested params array -// int i = 0; -// for (CommandParamData[] tree : treeData) { -// params[i] = tree; -// i++; -// } -// -// return params; -// } -// -// return new CommandParamData[0][0]; -// } -// -// /** -// * Convert Java edition command types to Bedrock edition -// * -// * @param parser Command type to convert -// * -// * @return Bedrock parameter data type -// */ -// private CommandParamData.Type mapCommandType(CommandParser parser) { -// if (parser == null) { return CommandParamData.Type.STRING; } //TODO: this -// -// switch (parser) { -// case FLOAT: -// return CommandParamData.Type.FLOAT; -// -// case INTEGER: -// return CommandParamData.Type.INT; -// -// case ENTITY: -// case GAME_PROFILE: -// return CommandParamData.Type.TARGET; -// -// case BLOCK_POS: -// return CommandParamData.Type.BLOCK_POSITION; -// -// case COLUMN_POS: -// case VEC3: -// return CommandParamData.Type.POSITION; -// -// case MESSAGE: -// return CommandParamData.Type.MESSAGE; -// -// case NBT: -// case NBT_COMPOUND_TAG: -// case NBT_TAG: -// case NBT_PATH: -// return CommandParamData.Type.JSON; -// -// case RESOURCE_LOCATION: -// return CommandParamData.Type.FILE_PATH; -// -// case INT_RANGE: -// return CommandParamData.Type.INT_RANGE; -// -// case BOOL: -// case DOUBLE: -// case STRING: -// case VEC2: -// case BLOCK_STATE: -// case BLOCK_PREDICATE: -// case ITEM_STACK: -// case ITEM_PREDICATE: -// case COLOR: -// case COMPONENT: -// case OBJECTIVE: -// case OBJECTIVE_CRITERIA: -// case OPERATION: // Possibly OPERATOR -// case PARTICLE: -// case ROTATION: -// case SCOREBOARD_SLOT: -// case SCORE_HOLDER: -// case SWIZZLE: -// case TEAM: -// case ITEM_SLOT: -// case MOB_EFFECT: -// case FUNCTION: -// case ENTITY_ANCHOR: -// case RANGE: -// case FLOAT_RANGE: -// case ITEM_ENCHANTMENT: -// case ENTITY_SUMMON: -// case DIMENSION: -// case TIME: -// default: -// return CommandParamData.Type.STRING; -// } -// } -// -// @Getter -// private class ParamInfo { -// private CommandNode paramNode; -// private CommandParamData paramData; -// private List children; -// -// /** -// * Create a new parameter info object -// * -// * @param paramNode CommandNode the parameter is for -// * @param paramData The existing parameters for the command -// */ -// public ParamInfo(CommandNode paramNode, CommandParamData paramData) { -// this.paramNode = paramNode; -// this.paramData = paramData; -// this.children = new ArrayList<>(); -// } -// -// /** -// * Build the array of all the child parameters (recursive) -// * -// * @param allNodes Every command node -// */ -// public void buildChildren(CommandNode[] allNodes) { -// int enumIndex = -1; -// -// for (int paramID : paramNode.getChildIndices()) { -// CommandNode paramNode = allNodes[paramID]; -// -// if (paramNode.getParser() == null) { -// if (enumIndex == -1) { -// enumIndex = children.size(); -// -// // Create the new enum command -// CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); -// children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); -// } else { -// // Get the existing enum -// ParamInfo enumParamInfo = children.get(enumIndex); -// -// // Extend the current list of enum values -// String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().length + 1); -// enumOptions[enumOptions.length - 1] = paramNode.getName(); -// -// // Re-create the command using the updated values -// CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), enumOptions, false); -// children.set(enumIndex, new ParamInfo(enumParamInfo.getParamNode(), new CommandParamData(enumParamInfo.getParamData().getName(), false, enumData, enumParamInfo.getParamData().getType(), null, Collections.emptyList()))); -// } -// }else{ -// // Put the non-enum param into the list -// children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); -// } -// } -// -// // Recursively build all child options -// for (ParamInfo child : children) { -// child.buildChildren(allNodes); -// } -// } -// -// /** -// * Get the tree of every parameter node (recursive) -// * -// * @return List of parameter options arrays for the command -// */ -// public List getTree() { -// List treeParamData = new ArrayList<>(); -// -// for (ParamInfo child : children) { -// // Get the tree from the child -// List childTree = child.getTree(); -// -// // Un-pack the tree append the child node to it and push into the list -// for (CommandParamData[] subchild : childTree) { -// CommandParamData[] tmpTree = new ArrayList() { -// { -// add(child.getParamData()); -// addAll(Arrays.asList(subchild)); -// } -// }.toArray(new CommandParamData[0]); -// -// treeParamData.add(tmpTree); -// } -// -// // If we have no more child parameters just the child -// if (childTree.size() == 0) { -// treeParamData.add(new CommandParamData[] { child.getParamData() }); -// } -// } -// -// return treeParamData; -// } + if (!session.getConnector().getConfig().isCommandSuggestions()) { + session.getConnector().getLogger().debug("Not sending command suggestions as they are disabled."); + return; + } + List commandData = new ArrayList<>(); + Int2ObjectMap commands = new Int2ObjectOpenHashMap<>(); + Int2ObjectMap> commandArgs = new Int2ObjectOpenHashMap<>(); + + // Get the first node, it should be a root node + CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; + + // Loop through the root nodes to get all commands + for (int nodeIndex : rootNode.getChildIndices()) { + CommandNode node = packet.getNodes()[nodeIndex]; + + // Make sure we don't have duplicated commands (happens if there is more than 1 root node) + if (commands.containsKey(nodeIndex)) { continue; } + if (commands.containsValue(node.getName())) { continue; } + + // Get and update the commandArgs list with the found arguments + if (node.getChildIndices().length >= 1) { + for (int childIndex : node.getChildIndices()) { + commandArgs.putIfAbsent(nodeIndex, new ArrayList<>()); + commandArgs.get(nodeIndex).add(packet.getNodes()[childIndex]); + } + } + + // Insert the command name into the list + commands.put(nodeIndex, node.getName()); + } + + // The command flags, not sure what these do apart from break things + List flags = new ArrayList<>(); + + // Loop through all the found commands + for (int commandID : commands.keySet()) { + String commandName = commands.get(commandID); + + // Create a basic alias + CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false); + + // Get and parse all params + CommandParamData[][] params = getParams(packet.getNodes()[commandID], packet.getNodes()); + + // Build the completed command and add it to the final list + CommandData data = new CommandData(commandName, session.getConnector().getCommandManager().getDescription(commandName), flags, (byte) 0, aliases, params); + commandData.add(data); + } + + // Add our commands to the AvailableCommandsPacket for the bedrock client + AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket(); + for (CommandData data : commandData) { + availableCommandsPacket.getCommands().add(data); + } + + GeyserConnector.getInstance().getLogger().debug("Sending command packet of " + commandData.size() + " commands"); + + // Finally, send the commands to the client + session.sendUpstreamPacket(availableCommandsPacket); + } + + /** + * Build the command parameter array for the given command + * + * @param commandNode The command to build the parameters for + * @param allNodes Every command node + * + * @return An array of parameter option arrays + */ + private CommandParamData[][] getParams(CommandNode commandNode, CommandNode[] allNodes) { + // Check if the command is an alias and redirect it + if (commandNode.getRedirectIndex() != -1) { + GeyserConnector.getInstance().getLogger().debug("Redirecting command " + commandNode.getName() + " to " + allNodes[commandNode.getRedirectIndex()].getName()); + commandNode = allNodes[commandNode.getRedirectIndex()]; + } + + if (commandNode.getChildIndices().length >= 1) { + // Create the root param node and build all the children + ParamInfo rootParam = new ParamInfo(commandNode, null); + rootParam.buildChildren(allNodes); + + List treeData = rootParam.getTree(); + CommandParamData[][] params = new CommandParamData[treeData.size()][]; + + // Fill the nested params array + int i = 0; + for (CommandParamData[] tree : treeData) { + params[i] = tree; + i++; + } + + return params; + } + + return new CommandParamData[0][0]; + } + + /** + * Convert Java edition command types to Bedrock edition + * + * @param parser Command type to convert + * + * @return Bedrock parameter data type + */ + private CommandParamType mapCommandType(CommandParser parser) { + if (parser == null) { return CommandParamType.STRING; } + + switch (parser) { + case FLOAT: + return CommandParamType.FLOAT; + + case INTEGER: + return CommandParamType.INT; + + case ENTITY: + case GAME_PROFILE: + return CommandParamType.TARGET; + + case BLOCK_POS: + return CommandParamType.BLOCK_POSITION; + + case COLUMN_POS: + case VEC3: + return CommandParamType.POSITION; + + case MESSAGE: + return CommandParamType.MESSAGE; + + case NBT: + case NBT_COMPOUND_TAG: + case NBT_TAG: + case NBT_PATH: + return CommandParamType.JSON; + + case RESOURCE_LOCATION: + return CommandParamType.FILE_PATH; + + case INT_RANGE: + return CommandParamType.INT_RANGE; + + case BOOL: + case DOUBLE: + case STRING: + case VEC2: + case BLOCK_STATE: + case BLOCK_PREDICATE: + case ITEM_STACK: + case ITEM_PREDICATE: + case COLOR: + case COMPONENT: + case OBJECTIVE: + case OBJECTIVE_CRITERIA: + case OPERATION: // Possibly OPERATOR + case PARTICLE: + case ROTATION: + case SCOREBOARD_SLOT: + case SCORE_HOLDER: + case SWIZZLE: + case TEAM: + case ITEM_SLOT: + case MOB_EFFECT: + case FUNCTION: + case ENTITY_ANCHOR: + case RANGE: + case FLOAT_RANGE: + case ITEM_ENCHANTMENT: + case ENTITY_SUMMON: + case DIMENSION: + case TIME: + default: + return CommandParamType.STRING; + } + } + + @Getter + private class ParamInfo { + private CommandNode paramNode; + private CommandParamData paramData; + private List children; + + /** + * Create a new parameter info object + * + * @param paramNode CommandNode the parameter is for + * @param paramData The existing parameters for the command + */ + public ParamInfo(CommandNode paramNode, CommandParamData paramData) { + this.paramNode = paramNode; + this.paramData = paramData; + this.children = new ArrayList<>(); + } + + /** + * Build the array of all the child parameters (recursive) + * + * @param allNodes Every command node + */ + public void buildChildren(CommandNode[] allNodes) { + int enumIndex = -1; + + for (int paramID : paramNode.getChildIndices()) { + CommandNode paramNode = allNodes[paramID]; + + if (paramNode.getParser() == null) { + if (enumIndex == -1) { + enumIndex = children.size(); + + // Create the new enum command + CommandEnumData enumData = new CommandEnumData(paramNode.getName(), new String[] { paramNode.getName() }, false); + children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, enumData, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); + } else { + // Get the existing enum + ParamInfo enumParamInfo = children.get(enumIndex); + + // Extend the current list of enum values + String[] enumOptions = Arrays.copyOf(enumParamInfo.getParamData().getEnumData().getValues(), enumParamInfo.getParamData().getEnumData().getValues().length + 1); + enumOptions[enumOptions.length - 1] = paramNode.getName(); + + // Re-create the command using the updated values + CommandEnumData enumData = new CommandEnumData(enumParamInfo.getParamData().getEnumData().getName(), enumOptions, false); + children.set(enumIndex, new ParamInfo(enumParamInfo.getParamNode(), new CommandParamData(enumParamInfo.getParamData().getName(), false, enumData, enumParamInfo.getParamData().getType(), null, Collections.emptyList()))); + } + }else{ + // Put the non-enum param into the list + children.add(new ParamInfo(paramNode, new CommandParamData(paramNode.getName(), false, null, mapCommandType(paramNode.getParser()), null, Collections.emptyList()))); + } + } + + // Recursively build all child options + for (ParamInfo child : children) { + child.buildChildren(allNodes); + } + } + + /** + * Get the tree of every parameter node (recursive) + * + * @return List of parameter options arrays for the command + */ + public List getTree() { + List treeParamData = new ArrayList<>(); + + for (ParamInfo child : children) { + // Get the tree from the child + List childTree = child.getTree(); + + // Un-pack the tree append the child node to it and push into the list + for (CommandParamData[] subchild : childTree) { + CommandParamData[] tmpTree = new ArrayList() { + { + add(child.getParamData()); + addAll(Arrays.asList(subchild)); + } + }.toArray(new CommandParamData[0]); + + treeParamData.add(tmpTree); + } + + // If we have no more child parameters just the child + if (childTree.size() == 0) { + treeParamData.add(new CommandParamData[] { child.getParamData() }); + } + } + + return treeParamData; + } } } From 60fa43c739e28dd7543292992cecf22e60c18c46 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 24 Jun 2020 14:19:57 -0400 Subject: [PATCH 021/104] Update Bedrock resources dumped by @bundabrg --- .../resources/bedrock/biome_definitions.dat | Bin 27359 -> 37626 bytes .../resources/bedrock/entity_identifiers.dat | Bin 8477 -> 8775 bytes .../resources/bedrock/legacy_block_ids.json | 1013 +++++++++-------- .../resources/bedrock/legacy_item_ids.json | 482 ++++---- .../bedrock/runtime_block_states.dat | Bin 302699 -> 1063028 bytes 5 files changed, 807 insertions(+), 688 deletions(-) diff --git a/connector/src/main/resources/bedrock/biome_definitions.dat b/connector/src/main/resources/bedrock/biome_definitions.dat index b8c6df4a686d41f62381547c6439d4e53552e616..6d72cc924919f5e018c677c9e3a2def659f07f6d 100644 GIT binary patch literal 37626 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 pOWUyvu?DWCIX@-&sX5y{7~c==i~xe#fiP# z{CNe*9L!0XDGbcaMVTpSlQ+uhPd*_RJb42Lw@^W5dQN5@lJvL9iLwS0dwC|S%iDrg zROO?o_ybYFy*Xc=pAlroQ;U!c`UO%3HX#GugddX^iW&f&smaIy0QMR~ Ang9R* delta 117 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 Date: Wed, 24 Jun 2020 16:40:42 -0400 Subject: [PATCH 022/104] Update some entity properties based on wiki.vg --- .../geysermc/connector/entity/FishingHookEntity.java | 2 ++ .../org/geysermc/connector/entity/TridentEntity.java | 2 +- .../entity/living/animal/tameable/WolfEntity.java | 11 ++++++----- 3 files changed, 9 insertions(+), 6 deletions(-) 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 47259e316..cc7d749d9 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java @@ -63,6 +63,8 @@ public class FishingHookEntity extends Entity { } } + //TODO Is ID 8 needed? + super.updateBedrockMetadata(entityMetadata, session); } } 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 acc176100..4a9007aba 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/TridentEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/TridentEntity.java @@ -39,7 +39,7 @@ public class TridentEntity extends AbstractArrowEntity { @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/living/animal/tameable/WolfEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/animal/tameable/WolfEntity.java index d0fb84a19..aa578acb2 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 @@ -40,11 +40,6 @@ public class WolfEntity extends TameableEntity { @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 class WolfEntity extends TameableEntity { } } + // "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); } } From 1490d6d06275326862f3d976ae48562db72e340a Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 24 Jun 2020 17:39:25 -0400 Subject: [PATCH 023/104] Update ViaVersion dependency --- bootstrap/spigot/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml index 4564d11ce..6439eb233 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -26,7 +26,7 @@ us.myles viaversion - 3.0.0-SNAPSHOT + 3.0.1 provided From 1572ac20f18219d55793d4ecc52180deea58d333 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 24 Jun 2020 17:53:26 -0400 Subject: [PATCH 024/104] Update mappings repository --- connector/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 8f78a9b2c..fa6721296 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 8f78a9b2cb514c7dce900be9c97b9b47c6f6c762 +Subproject commit fa6721296b8cf11c13411e55d659cafb4078591e From f0aaebc0ec2dff4bf285b1b3b8c11c74f606697f Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Wed, 24 Jun 2020 14:14:20 -0800 Subject: [PATCH 025/104] Bump block state version --- .../network/translators/world/block/BlockTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9c55217fd..a10668ced 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 @@ -73,7 +73,7 @@ public class BlockTranslator { public static final int JAVA_RUNTIME_SPAWNER_ID; - private static final int BLOCK_STATE_VERSION = 17760256; + private static final int BLOCK_STATE_VERSION = 17825806; static { /* Load block palette */ From e4d990329d138d351d1abc43f477c898227477e2 Mon Sep 17 00:00:00 2001 From: D3ATHBRINGER13 <53559772+D3ATHBRINGER13@users.noreply.github.com> Date: Thu, 25 Jun 2020 00:32:07 +0100 Subject: [PATCH 026/104] Bump action versions (#810) --- .github/workflows/pullrequest.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index aa80bf056..9cb0726ca 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 Spigot) - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 if: success() with: 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 From 71aada1df395c9ff04bbf0192a2afd71cd916b92 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 24 Jun 2020 20:27:10 -0400 Subject: [PATCH 027/104] Fix dimension switching; add static references to new Java dimensions --- .../java/JavaRespawnTranslator.java | 2 +- .../connector/utils/DimensionUtils.java | 24 +++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) 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 0d80f4af7..288389fa6 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 @@ -70,7 +70,7 @@ public class JavaRespawnTranslator extends PacketTranslator DimensionUtils.switchDimension(session, packet.getDimension()); } else { if (session.isManyDimPackets()) { //reloading world - String fakeDim = entity.getDimension().equals("minecraft:overworld") ? "minecraft:nether" : "minecraft:overworld"; + 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/utils/DimensionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java index b78a28ffe..74db16bb5 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; + // 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 (bedrockToJava(bedrockDimension) == player.getDimension()) + if (javaDimension.equals(player.getDimension())) return; session.getEntityCache().removeAllEntities(); @@ -55,7 +60,7 @@ public class DimensionUtils { changeDimensionPacket.setRespawn(true); changeDimensionPacket.setPosition(pos.toFloat()); session.sendUpstreamPacket(changeDimensionPacket); - player.setDimension(bedrockToJava(bedrockDimension)); + player.setDimension(javaDimension); player.setPosition(pos.toFloat()); session.setSpawned(false); session.setLastChunkPosition(null); @@ -85,26 +90,15 @@ public class DimensionUtils { */ public static int javaToBedrock(String javaDimension) { switch (javaDimension) { - case "minecraft:nether": + case NETHER: return BEDROCK_NETHER_ID; - case "minecraft:the_end": + case THE_END: return 2; default: return 0; } } - public static String bedrockToJava(int bedrockDimension) { - switch (bedrockDimension) { - case 1: - return "minecraft:nether"; - case 2: - return "minecraft:the_end"; - default: - return "minecraft:overworld"; - } - } - public static void changeBedrockNetherId() { // Change dimension ID to the End to allow for building above Bedrock BEDROCK_NETHER_ID = 2; From bd16925bab28e0d346934e1c273550c233599b59 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Thu, 25 Jun 2020 11:11:21 -0400 Subject: [PATCH 028/104] Update mappings repository --- connector/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index fa6721296..469c44151 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit fa6721296b8cf11c13411e55d659cafb4078591e +Subproject commit 469c44151dca60a7e87711132927544df20312af From 06fa0de793b8be75bf156d11c092064ec9db236c Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Thu, 25 Jun 2020 11:16:36 -0400 Subject: [PATCH 029/104] Add translator for PacketViolationWarningPacket --- ...drockPacketViolationWarningTranslator.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPacketViolationWarningTranslator.java 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 000000000..9e3c14e6d --- /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()); + } +} From bb630dc8678a4491caddfbcfffd4a8634fe677bb Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Thu, 25 Jun 2020 12:03:20 -0400 Subject: [PATCH 030/104] Update PotionMixData --- .../network/translators/java/JavaDeclareRecipesTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ab80cce10..c29632de7 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 @@ -53,7 +53,7 @@ import java.util.stream.Collectors; 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 From 6f2bf659a95419858418008a837fc1d18ae9170f Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Thu, 25 Jun 2020 21:53:51 -0400 Subject: [PATCH 031/104] Update JavaEntityEquipmentTranslator for Java 1.16 --- .../entity/JavaEntityEquipmentTranslator.java | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) 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 bdbb10335..96d4c8366 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.inventory.ItemData; import org.geysermc.connector.network.translators.item.ItemTranslator; @Translator(packet = ServerEntityEquipmentPacket.class) @@ -55,28 +55,29 @@ public class JavaEntityEquipmentTranslator extends PacketTranslator Date: Thu, 25 Jun 2020 22:32:04 -0400 Subject: [PATCH 032/104] Add new 1.16 entities --- .../entity/living/animal/StriderEntity.java | 50 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 4 ++ 2 files changed, 54 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/animal/StriderEntity.java 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 000000000..18bb8166e --- /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/type/EntityType.java b/connector/src/main/java/org/geysermc/connector/entity/type/EntityType.java index ea99c4704..1db7a0e4d 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 @@ -151,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. From e60f47f65dfe1e37f8e7cca61f4ae2a888ca8835 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Thu, 25 Jun 2020 22:52:48 -0400 Subject: [PATCH 033/104] Fix zombified piglins --- .../java/org/geysermc/connector/entity/type/EntityType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1db7a0e4d..4ec3471c7 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), - ZOMBIFIED_PIGLIN(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), From 54f6fada128ecf6352abc0a0c9073238a02a0f41 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Fri, 26 Jun 2020 11:15:21 -0400 Subject: [PATCH 034/104] Remove try/catch from BlockTranslator and ItemTranslator --- .../translators/item/ItemRegistry.java | 55 +++--- .../world/block/BlockTranslator.java | 186 +++++++++--------- 2 files changed, 115 insertions(+), 126 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index dd9d14eb2..db5bc1b34 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -100,42 +100,37 @@ public class ItemRegistry { int itemIndex = 0; Iterator> iterator = items.fields(); while (iterator.hasNext()) { - try { - Map.Entry entry = iterator.next(); - if (entry.getValue().has("tool_type")) { - if (entry.getValue().has("tool_tier")) { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( - entry.getKey(), itemIndex, - entry.getValue().get("bedrock_id").intValue(), - entry.getValue().get("bedrock_data").intValue(), - entry.getValue().get("tool_type").textValue(), - entry.getValue().get("tool_tier").textValue(), - entry.getValue().get("is_block") != null && entry.getValue().get("is_block").booleanValue())); - } else { - ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( - entry.getKey(), itemIndex, - entry.getValue().get("bedrock_id").intValue(), - entry.getValue().get("bedrock_data").intValue(), - entry.getValue().get("tool_type").textValue(), - "", - entry.getValue().get("is_block").booleanValue())); - } - } else { - ITEM_ENTRIES.put(itemIndex, new ItemEntry( + Map.Entry entry = iterator.next(); + if (entry.getValue().has("tool_type")) { + if (entry.getValue().has("tool_tier")) { + ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( entry.getKey(), itemIndex, entry.getValue().get("bedrock_id").intValue(), entry.getValue().get("bedrock_data").intValue(), + entry.getValue().get("tool_type").textValue(), + entry.getValue().get("tool_tier").textValue(), entry.getValue().get("is_block") != null && entry.getValue().get("is_block").booleanValue())); + } else { + ITEM_ENTRIES.put(itemIndex, new ToolItemEntry( + entry.getKey(), itemIndex, + entry.getValue().get("bedrock_id").intValue(), + entry.getValue().get("bedrock_data").intValue(), + entry.getValue().get("tool_type").textValue(), + "", + entry.getValue().get("is_block").booleanValue())); } - if (entry.getKey().equals("minecraft:barrier")) { - BARRIER_INDEX = itemIndex; - } - - itemIndex++; - } catch (Exception e) { - System.out.println("Exception in item registry! " + e.toString()); - e.printStackTrace(); + } else { + ITEM_ENTRIES.put(itemIndex, new ItemEntry( + entry.getKey(), itemIndex, + entry.getValue().get("bedrock_id").intValue(), + entry.getValue().get("bedrock_data").intValue(), + entry.getValue().get("is_block") != null && entry.getValue().get("is_block").booleanValue())); } + if (entry.getKey().equals("minecraft:barrier")) { + BARRIER_INDEX = itemIndex; + } + + itemIndex++; } /* Load creative items */ 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 a10668ced..7d9521825 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 @@ -117,104 +117,98 @@ public class BlockTranslator { int spawnerRuntimeId = -1; Iterator> blocksIterator = blocks.fields(); while (blocksIterator.hasNext()) { - try { - javaRuntimeId++; - Map.Entry entry = blocksIterator.next(); - String javaId = entry.getKey(); - CompoundTag blockTag = buildBedrockState(entry.getValue()); + javaRuntimeId++; + Map.Entry entry = blocksIterator.next(); + String javaId = entry.getKey(); + CompoundTag blockTag = buildBedrockState(entry.getValue()); - // TODO fix this, (no block should have a null hardness) - JsonNode hardnessNode = entry.getValue().get("block_hardness"); - if (hardnessNode != null) { - JAVA_RUNTIME_ID_TO_HARDNESS.put(javaRuntimeId, hardnessNode.doubleValue()); - } - - 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) { - JAVA_RUNTIME_ID_TO_TOOL_TYPE.put(javaRuntimeId, toolTypeNode.textValue()); - } - - if (javaId.contains("wool")) { - JAVA_RUNTIME_WOOL_IDS.add(javaRuntimeId); - } - - if (javaId.contains("cobweb")) { - cobwebRuntimeId = javaRuntimeId; - } - - JAVA_ID_BLOCK_MAP.put(javaId, javaRuntimeId); - - // Used for adding all "special" Java block states to block state map - String identifier; - String bedrock_identifer = entry.getValue().get("bedrock_identifier").asText(); - for (Class clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) { - 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(javaRuntimeId, clazz.getAnnotation(BlockEntity.class).name()); - break; - } - } - - BlockStateValues.storeBlockStateValues(entry, javaRuntimeId); - - // Get the tag needed for non-empty flower pots - if (entry.getValue().get("pottable") != null) { - BlockStateValues.getFlowerPotBlocks().put(entry.getKey().split("\\[")[0], buildBedrockState(entry.getValue())); - } - - if ("minecraft:water[level=0]".equals(javaId)) { - waterRuntimeId = bedrockRuntimeId; - } - boolean waterlogged = entry.getKey().contains("waterlogged=true") - || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); - - if (waterlogged) { - BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId); - WATERLOGGED.add(javaRuntimeId); - } else { - BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaRuntimeId); - } - - CompoundTag runtimeTag = blockStateMap.remove(blockTag); - if (runtimeTag != null) { - addedStatesMap.put(blockTag, bedrockRuntimeId); - paletteList.add(runtimeTag); - } else { - int duplicateRuntimeId = addedStatesMap.getOrDefault(blockTag, -1); - if (duplicateRuntimeId == -1) { - GeyserConnector.getInstance().getLogger().debug("Mapping " + javaId + " was not found for bedrock edition!"); - } else { - JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, duplicateRuntimeId); - } - continue; - } - JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, bedrockRuntimeId); - - if (javaId.startsWith("minecraft:furnace[facing=north")) { - if (javaId.contains("lit=true")) { - furnaceLitRuntimeId = javaRuntimeId; - } else { - furnaceRuntimeId = javaRuntimeId; - } - } - - if (javaId.startsWith("minecraft:spawner")) { - spawnerRuntimeId = javaRuntimeId; - } - - bedrockRuntimeId++; - } catch (Exception e) { - // REMOVE AFTER 1.16 UPDATE PROBABLY - System.out.println("Block translator error! " + e.toString()); - e.printStackTrace(); + // TODO fix this, (no block should have a null hardness) + JsonNode hardnessNode = entry.getValue().get("block_hardness"); + if (hardnessNode != null) { + JAVA_RUNTIME_ID_TO_HARDNESS.put(javaRuntimeId, hardnessNode.doubleValue()); } + + 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) { + JAVA_RUNTIME_ID_TO_TOOL_TYPE.put(javaRuntimeId, toolTypeNode.textValue()); + } + + if (javaId.contains("wool")) { + JAVA_RUNTIME_WOOL_IDS.add(javaRuntimeId); + } + + if (javaId.contains("cobweb")) { + cobwebRuntimeId = javaRuntimeId; + } + + JAVA_ID_BLOCK_MAP.put(javaId, javaRuntimeId); + + // Used for adding all "special" Java block states to block state map + String identifier; + String bedrock_identifer = entry.getValue().get("bedrock_identifier").asText(); + for (Class clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) { + 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(javaRuntimeId, clazz.getAnnotation(BlockEntity.class).name()); + break; + } + } + + BlockStateValues.storeBlockStateValues(entry, javaRuntimeId); + + // Get the tag needed for non-empty flower pots + if (entry.getValue().get("pottable") != null) { + BlockStateValues.getFlowerPotBlocks().put(entry.getKey().split("\\[")[0], buildBedrockState(entry.getValue())); + } + + if ("minecraft:water[level=0]".equals(javaId)) { + waterRuntimeId = bedrockRuntimeId; + } + boolean waterlogged = entry.getKey().contains("waterlogged=true") + || javaId.contains("minecraft:bubble_column") || javaId.contains("minecraft:kelp") || javaId.contains("seagrass"); + + if (waterlogged) { + BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId | 1 << 31, javaRuntimeId); + WATERLOGGED.add(javaRuntimeId); + } else { + BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaRuntimeId); + } + + CompoundTag runtimeTag = blockStateMap.remove(blockTag); + if (runtimeTag != null) { + addedStatesMap.put(blockTag, bedrockRuntimeId); + paletteList.add(runtimeTag); + } else { + int duplicateRuntimeId = addedStatesMap.getOrDefault(blockTag, -1); + if (duplicateRuntimeId == -1) { + GeyserConnector.getInstance().getLogger().debug("Mapping " + javaId + " was not found for bedrock edition!"); + } else { + JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, duplicateRuntimeId); + } + continue; + } + JAVA_TO_BEDROCK_BLOCK_MAP.put(javaRuntimeId, bedrockRuntimeId); + + if (javaId.startsWith("minecraft:furnace[facing=north")) { + if (javaId.contains("lit=true")) { + furnaceLitRuntimeId = javaRuntimeId; + } else { + furnaceRuntimeId = javaRuntimeId; + } + } + + if (javaId.startsWith("minecraft:spawner")) { + spawnerRuntimeId = javaRuntimeId; + } + + bedrockRuntimeId++; } if (cobwebRuntimeId == -1) { From 17a1e82ecaf74371abd69b0166e4dd4890711974 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 26 Jun 2020 23:33:38 +0100 Subject: [PATCH 035/104] Add closest color mapping for RGB chat colors --- .../translators/java/JavaChatTranslator.java | 7 +- .../connector/utils/MessageUtils.java | 70 ++++++++++++++++++- 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java index df3409714..4787d6984 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java @@ -25,15 +25,14 @@ package org.geysermc.connector.network.translators.java; +import com.github.steveice10.mc.protocol.data.message.TranslationMessage; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket; +import com.nukkitx.protocol.bedrock.packet.TextPacket; 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.MessageUtils; -import com.github.steveice10.mc.protocol.data.message.TranslationMessage; -import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket; -import com.nukkitx.protocol.bedrock.packet.TextPacket; - import java.util.List; @Translator(packet = ServerChatPacket.class) 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 6ab712431..6e995b4bb 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -40,13 +40,35 @@ 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.HashMap; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MessageUtils { + private static final Map 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); + }; + public static List getTranslationParams(List messages, String locale) { List strings = new ArrayList<>(); for (Message message : messages) { @@ -280,13 +302,57 @@ public class MessageUtils { //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 * From ba9129129c6f51bea1f57b1dc2b08fd64275d800 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Fri, 26 Jun 2020 18:51:09 -0800 Subject: [PATCH 036/104] Quick inventory fixes. WIP Temporary. The inventory system will be rewritten very soon. --- .../BedrockContainerCloseTranslator.java | 3 ++ .../bedrock/BedrockInteractTranslator.java | 18 ++++++++- .../CraftingInventoryTranslator.java | 39 +------------------ .../inventory/PlayerInventoryTranslator.java | 4 +- .../action/InventoryActionDataTranslator.java | 2 +- .../connector/utils/InventoryUtils.java | 6 +++ 6 files changed, 31 insertions(+), 41 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockContainerCloseTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockContainerCloseTranslator.java index 5d4f4368d..00905f6d9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockContainerCloseTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockContainerCloseTranslator.java @@ -54,5 +54,8 @@ public class BedrockContainerCloseTranslator 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; @@ -126,6 +134,14 @@ public class BedrockInteractTranslator extends PacketTranslator } } 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/inventory/CraftingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java index c963f6fea..afcb321a4 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 @@ -39,42 +39,9 @@ import org.geysermc.connector.utils.InventoryUtils; 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.setId((byte) inventory.getId()); - containerOpenPacket.setType(ContainerType.WORKBENCH); - 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 @@ -83,8 +50,6 @@ public class CraftingInventoryTranslator extends BaseInventoryTranslator { int slotnum = action.getSlot(); if (slotnum >= 32 && 42 >= slotnum) { return slotnum - 31; - } else if (slotnum == 50) { - return 0; } } return super.bedrockSlotToJava(action); 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 db26c469e..41489ac2a 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 @@ -159,10 +159,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator { 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; } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java index c1ed472cc..426627bfb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java @@ -55,7 +55,7 @@ public class InventoryActionDataTranslator { InventoryActionData containerAction = null; boolean refresh = false; for (InventoryActionData action : actions) { - if (action.getSource().getContainerId() == ContainerId.CRAFTING_USE_INGREDIENT || action.getSource().getContainerId() == ContainerId.CRAFTING_RESULT) { + if (action.getSource().getContainerId() == ContainerId.CRAFTING_USE_INGREDIENT) { return; } else if (action.getSource().getType() == InventorySource.Type.WORLD_INTERACTION) { worldAction = action; 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 66db00cee..0e5c13fc0 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -97,6 +97,11 @@ public class InventoryUtils { } 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(); @@ -104,6 +109,7 @@ public class InventoryUtils { session.sendUpstreamPacket(closePacket); session.setLastWindowCloseTime(System.currentTimeMillis()); } + */ } public static void updateCursor(GeyserSession session) { From d516dc5b90ead5ef29ce6e0c8d6b37513877a2fd Mon Sep 17 00:00:00 2001 From: endevrr Date: Sat, 27 Jun 2020 06:00:35 +0100 Subject: [PATCH 037/104] Update Mappings (#816) * Relocate Reflections Dependency * Update some mappings --- .../resources/bedrock/creative_items.json | 7772 +++++++++-------- .../src/main/resources/bedrock/items.json | 6036 +++++++------ 2 files changed, 7272 insertions(+), 6536 deletions(-) diff --git a/connector/src/main/resources/bedrock/creative_items.json b/connector/src/main/resources/bedrock/creative_items.json index 8045b219c..9765ff551 100644 --- a/connector/src/main/resources/bedrock/creative_items.json +++ b/connector/src/main/resources/bedrock/creative_items.json @@ -1,5 +1,273 @@ { "items" : [ + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAMAAAA=" + }, + { + "id" : 171, + "damage" : 9 + }, + { + "id" : 97, + "damage" : 1 + }, + { + "id" : 373, + "damage" : 37 + }, + { + "id" : 373, + "damage" : 36 + }, + { + "id" : 171, + "damage" : 13 + }, + { + "id" : 97 + }, + { + "id" : 52 + }, + { + "id" : 375 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAMAAAA=" + }, + { + "id" : 97, + "damage" : 2 + }, + { + "id" : 97, + "damage" : 3 + }, + { + "id" : 373, + "damage" : 35 + }, + { + "id" : 373, + "damage" : 34 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAIAAAA=" + }, + { + "id" : 373, + "damage" : 38 + }, + { + "id" : 373, + "damage" : 39 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAEAAAA=" + }, + { + "id" : 171, + "damage" : 2 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAMAAAA=" + }, + { + "id" : 171, + "damage" : 10 + }, + { + "id" : 373, + "damage" : 33 + }, + { + "id" : 171, + "damage" : 14 + }, + { + "id" : 171, + "damage" : 1 + }, + { + "id" : 373, + "damage" : 32 + }, + { + "id" : 237 + }, + { + "id" : 171, + "damage" : 6 + }, + { + "id" : 171, + "damage" : 11 + }, + { + "id" : 171, + "damage" : 3 + }, + { + "id" : 171, + "damage" : 12 + }, + { + "id" : 171, + "damage" : 15 + }, + { + "id" : 171, + "damage" : 4 + }, + { + "id" : 171, + "damage" : 5 + }, + { + "id" : 171, + "damage" : 8 + }, + { + "id" : 383, + "damage" : 122 + }, + { + "id" : 438, + "damage" : 2 + }, + { + "id" : 373, + "damage" : 29 + }, + { + "id" : 383, + "damage" : 10 + }, + { + "id" : 373, + "damage" : 28 + }, + { + "id" : 344 + }, + { + "id" : 338 + }, + { + "id" : 237, + "damage" : 12 + }, + { + "id" : 237, + "damage" : 15 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAUAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAUAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAEAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAAAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAAAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAEAAAA=" + }, + { + "id" : 438, + "damage" : 6 + }, + { + "id" : 438, + "damage" : 1 + }, + { + "id" : 373, + "damage" : 40 + }, + { + "id" : 373, + "damage" : 41 + }, + { + "id" : 438, + "damage" : 5 + }, + { + "id" : 383, + "damage" : 13 + }, + { + "id" : 97, + "damage" : 5 + }, + { + "id" : 97, + "damage" : 4 + }, + { + "id" : 383, + "damage" : 14 + }, + { + "id" : 100, + "damage" : 14 + }, + { + "id" : 99, + "damage" : 14 + }, + { + "id" : 352 + }, + { + "id" : 30 + }, { "id" : 5 }, @@ -9,20 +277,20 @@ }, { "id" : 5, - "damage" : 2 - }, - { - "id" : 5, - "damage" : 3 + "damage" : 5 }, { "id" : 5, "damage" : 4 }, { - "id" : 5, + "id" : 139, "damage" : 5 }, + { + "id" : 139, + "damage" : 4 + }, { "id" : 139 }, @@ -31,162 +299,815 @@ "damage" : 1 }, { - "id" : 139, + "id" : 39 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAcAAAA=" + }, + { + "id" : 237, + "damage" : 13 + }, + { + "id" : 237, + "damage" : 9 + }, + { + "id" : 373, + "damage" : 18 + }, + { + "id" : 373, + "damage" : 19 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAcAAAA=" + }, + { + "id" : 438, + "damage" : 8 + }, + { + "id" : 438, + "damage" : 7 + }, + { + "id" : 237, + "damage" : 4 + }, + { + "id" : 237, + "damage" : 5 + }, + { + "id" : 340 + }, + { + "id" : 208 + }, + { + "id" : 426 + }, + { + "id" : 339 + }, + { + "id" : 383, + "damage" : 30 + }, + { + "id" : 383, + "damage" : 29 + }, + { + "id" : 383, + "damage" : 18 + }, + { + "id" : 383, + "damage" : 19 + }, + { + "id" : 373, + "damage" : 17 + }, + { + "id" : 373, + "damage" : 24 + }, + { + "id" : 373, + "damage" : 25 + }, + { + "id" : 373, + "damage" : 16 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAkAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAgAAAA=" + }, + { + "id" : 171 + }, + { + "id" : 35, + "damage" : 13 + }, + { + "id" : 35, + "damage" : 4 + }, + { + "id" : 35, + "damage" : 5 + }, + { + "id" : 35, + "damage" : 6 + }, + { + "id" : 35, + "damage" : 9 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAoAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAoAAAA=" + }, + { + "id" : 237, + "damage" : 8 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAUAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAQAAAA=" + }, + { + "id" : 171, + "damage" : 7 + }, + { + "id" : 236, + "damage" : 8 + }, + { + "id" : 437 + }, + { + "id" : 373, + "damage" : 10 + }, + { + "id" : 373, + "damage" : 11 + }, + { + "id" : -222 + }, + { + "id" : 35 + }, + { + "id" : 373, + "damage" : 27 + }, + { + "id" : 373, + "damage" : 26 + }, + { + "id" : 376 + }, + { + "id" : 237, + "damage" : 7 + }, + { + "id" : 383, + "damage" : 12 + }, + { + "id" : 383, + "damage" : 11 + }, + { + "id" : 438, + "damage" : 16 + }, + { + "id" : 438, + "damage" : 15 + }, + { + "id" : 383, + "damage" : 111 + }, + { + "id" : 383, + "damage" : 27 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAAAAAA=" + }, + { + "id" : 236, + "damage" : 7 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAEAAAA=" + }, + { + "id" : 438 + }, + { + "id" : 373, + "damage" : 42 + }, + { + "id" : 5, "damage" : 2 }, + { + "id" : 5, + "damage" : 3 + }, { "id" : 139, "damage" : 3 }, { "id" : 139, - "damage" : 4 + "damage" : 2 }, { - "id" : 139, - "damage" : 5 + "id" : 438, + "damage" : 24 }, { - "id" : 139, - "damage" : 12 + "id" : 438, + "damage" : 23 }, { - "id" : 139, - "damage" : 7 - }, - { - "id" : 139, - "damage" : 8 - }, - { - "id" : 139, - "damage" : 6 - }, - { - "id" : 139, - "damage" : 9 - }, - { - "id" : 139, - "damage" : 13 - }, - { - "id" : 139, - "damage" : 10 - }, - { - "id" : 139, - "damage" : 11 - }, - { - "id" : 85 + "id" : 85, + "damage" : 2 }, { "id" : 85, "damage" : 1 }, { - "id" : 85, + "id" : 139, + "damage" : 9 + }, + { + "id" : 353 + }, + { + "id" : 367 + }, + { + "id" : 139, + "damage" : 13 + }, + { + "id" : 289 + }, + { + "id" : -228 + }, + { + "id" : -229 + }, + { + "id" : 423 + }, + { + "id" : 411 + }, + { + "id" : 80 + }, + { + "id" : 79 + }, + { + "id" : 383, + "damage" : 74 + }, + { + "id" : 111 + }, + { + "id" : -287 + }, + { + "id" : -233 + }, + { + "id" : 383, + "damage" : 113 + }, + { + "id" : 383, + "damage" : 33 + }, + { + "id" : 383, + "damage" : 121 + }, + { + "id" : -232 + }, + { + "id" : 383, + "damage" : 109 + }, + { + "id" : 383, + "damage" : 31 + }, + { + "id" : 236, + "damage" : 10 + }, + { + "id" : 236, "damage" : 2 }, { - "id" : 85, + "id" : 236, + "damage" : 9 + }, + { + "id" : 236, "damage" : 3 }, { - "id" : 85, - "damage" : 4 + "id" : 236, + "damage" : 11 }, { - "id" : 85, - "damage" : 5 + "id" : 236, + "damage" : 13 }, { - "id" : 113 + "id" : 383, + "damage" : 112 }, { - "id" : 107 + "id" : -236 }, { - "id" : 183 + "id" : 383, + "damage" : 108 }, { - "id" : 184 + "id" : -235 + }, + { + "id" : -234 + }, + { + "id" : -270 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA8AAAA=" + }, + { + "id" : 444 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAwAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAwAAAA=" + }, + { + "id" : 450 + }, + { + "id" : 384 + }, + { + "id" : 373, + "damage" : 1 + }, + { + "id" : 374 + }, + { + "id" : 409 + }, + { + "id" : 373 + }, + { + "id" : 405 + }, + { + "id" : 438, + "damage" : 17 + }, + { + "id" : 455 + }, + { + "id" : 469 + }, + { + "id" : 438, + "damage" : 33 + }, + { + "id" : 373, + "damage" : 13 + }, + { + "id" : -278 + }, + { + "id" : 85 + }, + { + "id" : 377 + }, + { + "id" : 378 + }, + { + "id" : 438, + "damage" : 18 + }, + { + "id" : 236 + }, + { + "id" : -227 + }, + { + "id" : 237, + "damage" : 6 + }, + { + "id" : 112 + }, + { + "id" : 82 + }, + { + "id" : 236, + "damage" : 6 }, { "id" : 185 }, { - "id" : 187 + "id" : 184 }, { - "id" : 186 + "id" : -259 }, { - "id" : -180 + "id" : -258 }, { - "id" : 67 + "id" : 388 }, { - "id" : -179 + "id" : 406 }, { - "id" : 53 + "id" : 414 }, { - "id" : 134 + "id" : 415 }, { - "id" : 135 + "id" : 438, + "damage" : 22 }, { - "id" : 136 + "id" : 438, + "damage" : 21 }, { - "id" : 163 + "id" : 139, + "damage" : 11 }, { - "id" : 164 + "id" : 139, + "damage" : 10 }, { - "id" : 109 + "id" : 438, + "damage" : 38 }, { - "id" : -175 + "id" : 106 }, { - "id" : 128 + "id" : 32 }, { - "id" : -177 + "id" : 438, + "damage" : 37 + }, + { + "id" : -231 + }, + { + "id" : 349 + }, + { + "id" : 438, + "damage" : 34 + }, + { + "id" : -163 + }, + { + "id" : 460 + }, + { + "id" : 383, + "damage" : 75 + }, + { + "id" : 351, + "damage" : 11 + }, + { + "id" : 351, + "damage" : 14 + }, + { + "id" : 40 + }, + { + "id" : 383, + "damage" : 40 + }, + { + "id" : 351, + "damage" : 17 + }, + { + "id" : 159, + "damage" : 13 + }, + { + "id" : 159, + "damage" : 9 + }, + { + "id" : 383, + "damage" : 28 + }, + { + "id" : 383, + "damage" : 22 + }, + { + "id" : 351, + "damage" : 1 + }, + { + "id" : 237, + "damage" : 11 + }, + { + "id" : 237, + "damage" : 3 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAkAAAA=" + }, + { + "id" : 383, + "damage" : 16 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAkAAAA=" + }, + { + "id" : 259 + }, + { + "id" : 359 + }, + { + "id" : 373, + "damage" : 15 + }, + { + "id" : 237, + "damage" : 2 + }, + { + "id" : 214 + }, + { + "id" : 216 + }, + { + "id" : 383, + "damage" : 17 + }, + { + "id" : 237, + "damage" : 10 + }, + { + "id" : 383, + "damage" : 110 + }, + { + "id" : 373, + "damage" : 14 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBIAAAA=" + }, + { + "id" : 757 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAkAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAkAAAA=" + }, + { + "id" : 332 + }, + { + "id" : 373, + "damage" : 12 + }, + { + "id" : 383, + "damage" : 45 + }, + { + "id" : 35, + "damage" : 2 + }, + { + "id" : 35, + "damage" : 11 + }, + { + "id" : 35, + "damage" : 3 + }, + { + "id" : 35, + "damage" : 10 + }, + { + "id" : -242 + }, + { + "id" : 441, + "damage" : 8 + }, + { + "id" : -243 + }, + { + "id" : 441, + "damage" : 9 + }, + { + "id" : -297 + }, + { + "id" : -277 + }, + { + "id" : 438, + "damage" : 19 + }, + { + "id" : 438, + "damage" : 20 + }, + { + "id" : 438, + "damage" : 3 }, { "id" : 180 }, { - "id" : -176 + "id" : 438, + "damage" : 4 }, { - "id" : -169 + "id" : -177 }, { - "id" : -172 + "id" : 373, + "damage" : 30 }, { - "id" : -170 + "id" : 373, + "damage" : 31 }, { - "id" : -173 + "id" : 386 }, { - "id" : -171 + "id" : 187 }, { - "id" : -174 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAAAAAA=" }, { - "id" : 108 + "id" : 186 + }, + { + "id" : 41 + }, + { + "id" : 42 + }, + { + "id" : 385 + }, + { + "id" : 159, + "damage" : 11 + }, + { + "id" : 369 + }, + { + "id" : 159, + "damage" : 3 + }, + { + "id" : 337 + }, + { + "id" : 336 + }, + { + "id" : 138 + }, + { + "id" : -206 + }, + { + "id" : 438, + "damage" : 36 + }, + { + "id" : 438, + "damage" : 35 + }, + { + "id" : 462 + }, + { + "id" : 461 }, { "id" : 114 @@ -195,10 +1116,78 @@ "id" : -184 }, { - "id" : -178 + "id" : 179, + "damage" : 3 }, { - "id" : 156 + "id" : 179, + "damage" : 2 + }, + { + "id" : 233 + }, + { + "id" : 229 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBcAAAA=" + }, + { + "id" : 441, + "damage" : 14 + }, + { + "id" : 441, + "damage" : 15 + }, + { + "id" : 325, + "damage" : 5 + }, + { + "id" : 325, + "damage" : 4 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBkAAAA=" + }, + { + "id" : 38, + "damage" : 9 + }, + { + "id" : 393 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBgAAAA=" + }, + { + "id" : 463 + }, + { + "id" : 413 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBkAAAA=" + }, + { + "id" : 297 + }, + { + "id" : 38, + "damage" : 2 + }, + { + "id" : 38, + "damage" : 3 + }, + { + "id" : 38, + "damage" : 8 }, { "id" : -185 @@ -207,49 +1196,594 @@ "id" : 203 }, { - "id" : -2 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBsAAAA=" }, { - "id" : -3 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBoAAAA=" }, { - "id" : -4 + "id" : 402, + "damage" : 7, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KXnZ3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : 324 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBUAAAA=" }, { - "id" : 427 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBYAAAA=" }, { - "id" : 428 + "id" : 402, + "damage" : 10, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Ifx4D/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : 429 + "id" : -173 }, { - "id" : 430 + "id" : -171 + }, + { + "id" : 402, + "damage" : 11, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3I92P7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 88 + }, + { + "id" : 402, + "damage" : 4, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KqRDz/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 383, + "damage" : 118 + }, + { + "id" : 383, + "damage" : 114 + }, + { + "id" : 383, + "damage" : 59 + }, + { + "id" : 7 + }, + { + "id" : 402, + "damage" : 15, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Lw8PD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 402, + "damage" : 1, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3ImLrD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 383, + "damage" : 41 + }, + { + "id" : 383, + "damage" : 43 + }, + { + "id" : 383, + "damage" : 104 + }, + { + "id" : 383, + "damage" : 115 + }, + { + "id" : 383, + "damage" : 105 + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : -169 + }, + { + "id" : -176 + }, + { + "id" : 228 + }, + { + "id" : 227 + }, + { + "id" : -197 + }, + { + "id" : -157 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZBMAAAA=" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZBMAAAA=" + }, + { + "id" : 441, + "damage" : 23 + }, + { + "id" : 441, + "damage" : 22 + }, + { + "id" : 133 + }, + { + "id" : 175, + "damage" : 4 + }, + { + "id" : 351, + "damage" : 19 + }, + { + "id" : 155, + "damage" : 2 + }, + { + "id" : 57 + }, + { + "id" : 175, + "damage" : 1 + }, + { + "id" : 351, + "damage" : 7 + }, + { + "id" : 366 + }, + { + "id" : 320 + }, + { + "id" : 155, + "damage" : 1 + }, + { + "id" : 262, + "damage" : 42 + }, + { + "id" : 262, + "damage" : 41 + }, + { + "id" : 263, + "damage" : 1 + }, + { + "id" : 264 + }, + { + "id" : 737 + }, + { + "id" : 221 + }, + { + "id" : 234 + }, + { + "id" : 389 + }, + { + "id" : 441, + "damage" : 18 + }, + { + "id" : 159, + "damage" : 2 + }, + { + "id" : 168, + "damage" : 2 + }, + { + "id" : -274 + }, + { + "id" : 159, + "damage" : 10 + }, + { + "id" : 441, + "damage" : 19 + }, + { + "id" : 441, + "damage" : 11 + }, + { + "id" : 441, + "damage" : 10 + }, + { + "id" : 742 + }, + { + "id" : 752 + }, + { + "id" : 345 + }, + { + "id" : 395 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB8AAAA=" + }, + { + "id" : 383, + "damage" : 50 + }, + { + "id" : 383, + "damage" : 49 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBIAAAA=" + }, + { + "id" : 159, + "damage" : 4 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBIAAAA=" + }, + { + "id" : 159, + "damage" : 5 + }, + { + "id" : 19, + "damage" : 1 + }, + { + "id" : 19 + }, + { + "id" : -239 + }, + { + "id" : 170 + }, + { + "id" : 164 + }, + { + "id" : 753 + }, + { + "id" : 476 + }, + { + "id" : 109 + }, + { + "id" : 262, + "damage" : 37 + }, + { + "id" : 262, + "damage" : 38 + }, + { + "id" : -131, + "damage" : 12 + }, + { + "id" : -134, + "damage" : 4 + }, + { + "id" : 335 + }, + { + "id" : 383, + "damage" : 47 + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 383, + "damage" : 36 + }, + { + "id" : -133, + "damage" : 3 + }, + { + "id" : 121 + }, + { + "id" : 372 + }, + { + "id" : -276 + }, + { + "id" : -255 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA8AAAA=" }, { "id" : 431 }, { - "id" : 330 + "id" : 430 }, { - "id" : 96 + "id" : 215 }, { - "id" : -149 + "id" : -225 }, { - "id" : -146 + "id" : 262, + "damage" : 28 }, { - "id" : -148 + "id" : 262, + "damage" : 27 }, { - "id" : -145 + "id" : -183 + }, + { + "id" : 48 + }, + { + "id" : 464 + }, + { + "id" : 354 + }, + { + "id" : 434, + "damage" : 5 + }, + { + "id" : 434, + "damage" : 4 + }, + { + "id" : 159 + }, + { + "id" : 172 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB0AAAA=" + }, + { + "id" : 67 + }, + { + "id" : -180 + }, + { + "id" : 441, + "damage" : 36 + }, + { + "id" : 441, + "damage" : 37 + }, + { + "id" : 351, + "damage" : 4 + }, + { + "id" : 351, + "damage" : 15 + }, + { + "id" : 441, + "damage" : 28 + }, + { + "id" : 441, + "damage" : 29 + }, + { + "id" : 325, + "damage" : 8 + }, + { + "id" : 397, + "damage" : 4 + }, + { + "id" : 422 + }, + { + "id" : 325, + "damage" : 10 + }, + { + "id" : 351, + "damage" : 6 + }, + { + "id" : 351, + "damage" : 12 + }, + { + "id" : 201 + }, + { + "id" : 110 + }, + { + "id" : 465 + }, + { + "id" : 397, + "damage" : 5 + }, + { + "id" : 438, + "damage" : 40 + }, + { + "id" : 1 + }, + { + "id" : 438, + "damage" : 39 + }, + { + "id" : 182, + "damage" : 2 + }, + { + "id" : 182, + "damage" : 1 + }, + { + "id" : 441, + "damage" : 5 + }, + { + "id" : 441, + "damage" : 4 + }, + { + "id" : 226 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAsAAAA=" + }, + { + "id" : 505 + }, + { + "id" : 438, + "damage" : 25 + }, + { + "id" : 438, + "damage" : 26 + }, + { + "id" : 504 + }, + { + "id" : 758 + }, + { + "id" : 101 + }, + { + "id" : 334 + }, + { + "id" : -301 + }, + { + "id" : -230 + }, + { + "id" : 333 + }, + { + "id" : 355, + "damage" : 1 + }, + { + "id" : 355, + "damage" : 7 + }, + { + "id" : 355, + "damage" : 15 + }, + { + "id" : 355, + "damage" : 4 + }, + { + "id" : -256 + }, + { + "id" : -257 + }, + { + "id" : 236, + "damage" : 5 + }, + { + "id" : 299 + }, + { + "id" : 303 + }, + { + "id" : 236, + "damage" : 4 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAoAAAA=" + }, + { + "id" : 500 + }, + { + "id" : 501 }, { "id" : -147 @@ -258,246 +1792,458 @@ "id" : 167 }, { - "id" : 101 + "id" : -299 }, { - "id" : 20 + "id" : 383, + "damage" : 39 }, { - "id" : 241 + "id" : 383, + "damage" : 38 }, { - "id" : 241, + "id" : -241 + }, + { + "id" : 373, "damage" : 8 }, { - "id" : 241, - "damage" : 7 - }, - { - "id" : 241, - "damage" : 15 - }, - { - "id" : 241, - "damage" : 12 - }, - { - "id" : 241, - "damage" : 14 - }, - { - "id" : 241, - "damage" : 1 - }, - { - "id" : 241, - "damage" : 4 - }, - { - "id" : 241, - "damage" : 5 - }, - { - "id" : 241, - "damage" : 13 - }, - { - "id" : 241, + "id" : 373, "damage" : 9 }, { - "id" : 241, + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAsAAAA=" + }, + { + "id" : 86 + }, + { + "id" : 373, + "damage" : 5 + }, + { + "id" : 373, + "damage" : 4 + }, + { + "id" : -155 + }, + { + "id" : 446, + "damage" : 4 + }, + { + "id" : 446, + "damage" : 5 + }, + { + "id" : 35, + "damage" : 7 + }, + { + "id" : -131, + "damage" : 9 + }, + { + "id" : -132, + "damage" : 9 + }, + { + "id" : -132, + "damage" : 10 + }, + { + "id" : 383, + "damage" : 37 + }, + { + "id" : 35, + "damage" : 8 + }, + { + "id" : -131, + "damage" : 11 + }, + { + "id" : -288 + }, + { + "id" : -271 + }, + { + "id" : 383, + "damage" : 46 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCQAAAA=" + }, + { + "id" : 236, + "damage" : 15 + }, + { + "id" : 236, + "damage" : 12 + }, + { + "id" : 446, + "damage" : 11 + }, + { + "id" : 446, "damage" : 3 }, + { + "id" : 438, + "damage" : 29 + }, + { + "id" : 438, + "damage" : 30 + }, + { + "id" : 85, + "damage" : 4 + }, + { + "id" : 85, + "damage" : 3 + }, + { + "id" : 370 + }, + { + "id" : 445 + }, + { + "id" : 333, + "damage" : 1 + }, + { + "id" : 1, + "damage" : 5 + }, + { + "id" : 1, + "damage" : 3 + }, + { + "id" : -302 + }, + { + "id" : -303 + }, + { + "id" : 262, + "damage" : 6 + }, + { + "id" : 262 + }, + { + "id" : 98, + "damage" : 2 + }, + { + "id" : 98, + "damage" : 1 + }, + { + "id" : 262, + "damage" : 9 + }, + { + "id" : 262, + "damage" : 10 + }, + { + "id" : 363 + }, + { + "id" : -11 + }, + { + "id" : 174 + }, + { + "id" : 319 + }, + { + "id" : 441, + "damage" : 33 + }, + { + "id" : 441, + "damage" : 32 + }, + { + "id" : 139, + "damage" : 12 + }, + { + "id" : 381 + }, + { + "id" : 399 + }, + { + "id" : 58 + }, + { + "id" : -269 + }, + { + "id" : 139, + "damage" : 7 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAYAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAcAAAA=" + }, + { + "id" : 438, + "damage" : 11 + }, + { + "id" : 438, + "damage" : 12 + }, + { + "id" : 135 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB4AAAA=" + }, + { + "id" : 473 + }, + { + "id" : 472 + }, + { + "id" : 134 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB4AAAA=" + }, + { + "id" : 165 + }, + { + "id" : 168, + "damage" : 1 + }, + { + "id" : 35, + "damage" : 14 + }, + { + "id" : 237, + "damage" : 1 + }, + { + "id" : 237, + "damage" : 14 + }, + { + "id" : -132, + "damage" : 3 + }, + { + "id" : -132, + "damage" : 2 + }, + { + "id" : 35, + "damage" : 1 + }, { "id" : 241, "damage" : 11 }, { - "id" : 241, - "damage" : 10 + "id" : 417 + }, + { + "id" : 416 + }, + { + "id" : 373, + "damage" : 22 + }, + { + "id" : 373, + "damage" : 23 }, { "id" : 241, - "damage" : 2 + "damage" : 3 }, { - "id" : 241, - "damage" : 6 + "id" : 218, + "damage" : 1 }, { - "id" : 102 - }, - { - "id" : 160 - }, - { - "id" : 160, - "damage" : 8 - }, - { - "id" : 160, - "damage" : 7 - }, - { - "id" : 160, - "damage" : 15 - }, - { - "id" : 160, - "damage" : 12 - }, - { - "id" : 160, + "id" : 218, "damage" : 14 }, { - "id" : 160, - "damage" : 1 + "id" : 324 }, { - "id" : 160, - "damage" : 4 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBEAAAA=" }, { - "id" : 160, - "damage" : 5 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBAAAAA=" }, { - "id" : 160, - "damage" : 13 + "id" : 383, + "damage" : 125 }, { - "id" : 160, + "id" : 383, + "damage" : 124 + }, + { + "id" : 427 + }, + { + "id" : -218, + "damage" : 3 + }, + { + "id" : 295 + }, + { + "id" : 37 + }, + { + "id" : -224 + }, + { + "id" : 351, "damage" : 9 }, { - "id" : 160, - "damage" : 3 + "id" : 351, + "damage" : 13 }, { - "id" : 160, - "damage" : 11 + "id" : 383, + "damage" : 23 }, { - "id" : 160, - "damage" : 10 + "id" : 383, + "damage" : 24 }, { - "id" : 160, + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 17, "damage" : 2 }, { - "id" : 160, - "damage" : 6 + "id" : 749 }, { - "id" : 65 + "id" : -6 }, { - "id" : -165 + "id" : 311 }, { - "id" : 44 - }, - { - "id" : -166, + "id" : 24, "damage" : 2 }, { - "id" : 44, + "id" : 273 + }, + { + "id" : 24, "damage" : 3 }, { - "id" : 182, - "damage" : 5 + "id" : 269 }, { - "id" : 158 + "id" : 152 }, { - "id" : 158, + "id" : 331 + }, + { + "id" : 159, + "damage" : 12 + }, + { + "id" : 159, + "damage" : 15 + }, + { + "id" : 262, + "damage" : 24 + }, + { + "id" : 23, + "damage" : 3 + }, + { + "id" : 125, + "damage" : 3 + }, + { + "id" : 262, + "damage" : 23 + }, + { + "id" : 3, "damage" : 1 }, { - "id" : 158, - "damage" : 2 + "id" : 287 }, { - "id" : 158, - "damage" : 3 + "id" : 2 }, { - "id" : 158, - "damage" : 4 + "id" : 99 }, { - "id" : 158, - "damage" : 5 + "id" : 99, + "damage" : 15 }, { - "id" : 44, - "damage" : 5 + "id" : 470 }, { - "id" : -166 + "id" : 441 }, { - "id" : 44, + "id" : 441, "damage" : 1 }, - { - "id" : -166, - "damage" : 3 - }, - { - "id" : 182, - "damage" : 6 - }, - { - "id" : 182 - }, - { - "id" : -166, - "damage" : 4 - }, - { - "id" : -162, - "damage" : 1 - }, - { - "id" : -162, - "damage" : 6 - }, - { - "id" : -162, - "damage" : 7 - }, - { - "id" : -162, - "damage" : 4 - }, - { - "id" : -162, - "damage" : 5 - }, - { - "id" : -162, - "damage" : 3 - }, - { - "id" : -162, - "damage" : 2 - }, - { - "id" : 44, - "damage" : 4 - }, - { - "id" : 44, - "damage" : 7 - }, { "id" : 182, "damage" : 7 @@ -506,728 +2252,78 @@ "id" : -162 }, { - "id" : 44, + "id" : 160, "damage" : 6 }, { - "id" : -166, + "id" : 161, "damage" : 1 }, - { - "id" : 182, - "damage" : 1 - }, - { - "id" : 182, - "damage" : 2 - }, - { - "id" : 182, - "damage" : 3 - }, - { - "id" : 182, - "damage" : 4 - }, - { - "id" : 45 - }, - { - "id" : 98 - }, - { - "id" : 98, - "damage" : 1 - }, - { - "id" : 98, - "damage" : 2 - }, - { - "id" : 98, - "damage" : 3 - }, - { - "id" : 206 - }, - { - "id" : 168, - "damage" : 2 - }, - { - "id" : 4 - }, - { - "id" : 48 - }, - { - "id" : -183 - }, - { - "id" : 24 - }, - { - "id" : 24, - "damage" : 1 - }, - { - "id" : 24, - "damage" : 2 - }, - { - "id" : 24, - "damage" : 3 - }, - { - "id" : 179 - }, - { - "id" : 179, - "damage" : 1 - }, - { - "id" : 179, - "damage" : 2 - }, - { - "id" : 179, - "damage" : 3 - }, - { - "id" : 173 - }, - { - "id" : -139 - }, - { - "id" : 41 - }, - { - "id" : 42 - }, - { - "id" : 133 - }, - { - "id" : 57 - }, - { - "id" : 22 - }, - { - "id" : 155 - }, - { - "id" : 155, - "damage" : 2 - }, - { - "id" : 155, - "damage" : 1 - }, - { - "id" : 155, - "damage" : 3 - }, - { - "id" : 168 - }, - { - "id" : 168, - "damage" : 1 - }, - { - "id" : 165 - }, - { - "id" : -220 - }, - { - "id" : -221 - }, - { - "id" : 170 - }, - { - "id" : 216 - }, - { - "id" : 214 - }, - { - "id" : 112 - }, - { - "id" : 215 - }, - { - "id" : 35 - }, - { - "id" : 35, - "damage" : 8 - }, - { - "id" : 35, - "damage" : 7 - }, - { - "id" : 35, - "damage" : 15 - }, - { - "id" : 35, - "damage" : 12 - }, - { - "id" : 35, - "damage" : 14 - }, - { - "id" : 35, - "damage" : 1 - }, - { - "id" : 35, - "damage" : 4 - }, - { - "id" : 35, - "damage" : 5 - }, - { - "id" : 35, - "damage" : 13 - }, - { - "id" : 35, - "damage" : 9 - }, - { - "id" : 35, - "damage" : 3 - }, - { - "id" : 35, - "damage" : 11 - }, - { - "id" : 35, - "damage" : 10 - }, - { - "id" : 35, - "damage" : 2 - }, - { - "id" : 35, - "damage" : 6 - }, - { - "id" : 171 - }, - { - "id" : 171, - "damage" : 8 - }, - { - "id" : 171, - "damage" : 7 - }, - { - "id" : 171, - "damage" : 15 - }, - { - "id" : 171, - "damage" : 12 - }, - { - "id" : 171, - "damage" : 14 - }, - { - "id" : 171, - "damage" : 1 - }, - { - "id" : 171, - "damage" : 4 - }, - { - "id" : 171, - "damage" : 5 - }, - { - "id" : 171, - "damage" : 13 - }, - { - "id" : 171, - "damage" : 9 - }, - { - "id" : 171, - "damage" : 3 - }, - { - "id" : 171, - "damage" : 11 - }, - { - "id" : 171, - "damage" : 10 - }, - { - "id" : 171, - "damage" : 2 - }, - { - "id" : 171, - "damage" : 6 - }, - { - "id" : 237 - }, - { - "id" : 237, - "damage" : 8 - }, - { - "id" : 237, - "damage" : 7 - }, - { - "id" : 237, - "damage" : 15 - }, - { - "id" : 237, - "damage" : 12 - }, - { - "id" : 237, - "damage" : 14 - }, - { - "id" : 237, - "damage" : 1 - }, - { - "id" : 237, - "damage" : 4 - }, - { - "id" : 237, - "damage" : 5 - }, - { - "id" : 237, - "damage" : 13 - }, - { - "id" : 237, - "damage" : 9 - }, - { - "id" : 237, - "damage" : 3 - }, - { - "id" : 237, - "damage" : 11 - }, - { - "id" : 237, - "damage" : 10 - }, - { - "id" : 237, - "damage" : 2 - }, - { - "id" : 237, - "damage" : 6 - }, - { - "id" : 236 - }, - { - "id" : 236, - "damage" : 8 - }, - { - "id" : 236, - "damage" : 7 - }, - { - "id" : 236, - "damage" : 15 - }, - { - "id" : 236, - "damage" : 12 - }, - { - "id" : 236, - "damage" : 14 - }, - { - "id" : 236, - "damage" : 1 - }, - { - "id" : 236, - "damage" : 4 - }, - { - "id" : 236, - "damage" : 5 - }, - { - "id" : 236, - "damage" : 13 - }, - { - "id" : 236, - "damage" : 9 - }, - { - "id" : 236, - "damage" : 3 - }, - { - "id" : 236, - "damage" : 11 - }, - { - "id" : 236, - "damage" : 10 - }, - { - "id" : 236, - "damage" : 2 - }, - { - "id" : 236, - "damage" : 6 - }, - { - "id" : 82 - }, - { - "id" : 172 - }, - { - "id" : 159 - }, - { - "id" : 159, - "damage" : 8 - }, - { - "id" : 159, - "damage" : 7 - }, - { - "id" : 159, - "damage" : 15 - }, - { - "id" : 159, - "damage" : 12 - }, - { - "id" : 159, - "damage" : 14 - }, - { - "id" : 159, - "damage" : 1 - }, - { - "id" : 159, - "damage" : 4 - }, - { - "id" : 159, - "damage" : 5 - }, - { - "id" : 159, - "damage" : 13 - }, - { - "id" : 159, - "damage" : 9 - }, - { - "id" : 159, - "damage" : 3 - }, - { - "id" : 159, - "damage" : 11 - }, - { - "id" : 159, - "damage" : 10 - }, - { - "id" : 159, - "damage" : 2 - }, - { - "id" : 159, - "damage" : 6 - }, - { - "id" : 220 - }, - { - "id" : 228 - }, - { - "id" : 227 - }, - { - "id" : 235 - }, - { - "id" : 232 - }, - { - "id" : 234 - }, - { - "id" : 221 - }, - { - "id" : 224 - }, - { - "id" : 225 - }, - { - "id" : 233 - }, - { - "id" : 229 - }, - { - "id" : 223 - }, - { - "id" : 231 - }, - { - "id" : 219 - }, - { - "id" : 222 - }, - { - "id" : 226 - }, - { - "id" : 201 - }, - { - "id" : 201, - "damage" : 2 - }, - { - "id" : 3 - }, - { - "id" : 3, - "damage" : 1 - }, - { - "id" : 2 - }, - { - "id" : 198 - }, - { - "id" : 243 - }, - { - "id" : 110 - }, - { - "id" : 1 - }, - { - "id" : 15 - }, - { - "id" : 14 - }, - { - "id" : 56 - }, - { - "id" : 21 - }, - { - "id" : 73 - }, - { - "id" : 16 - }, - { - "id" : 129 - }, - { - "id" : 153 - }, - { - "id" : 13 - }, - { - "id" : 1, - "damage" : 1 - }, - { - "id" : 1, - "damage" : 3 - }, - { - "id" : 1, - "damage" : 5 - }, - { - "id" : 1, - "damage" : 2 - }, - { - "id" : 1, - "damage" : 4 - }, - { - "id" : 1, - "damage" : 6 - }, - { - "id" : 12 - }, - { - "id" : 12, - "damage" : 1 - }, - { - "id" : 81 - }, - { - "id" : 17 - }, - { - "id" : -10 - }, - { - "id" : 17, - "damage" : 1 - }, - { - "id" : -5 - }, - { - "id" : 17, - "damage" : 2 - }, - { - "id" : -6 - }, - { - "id" : 17, - "damage" : 3 - }, - { - "id" : -7 - }, - { - "id" : 162 - }, - { - "id" : -8 - }, - { - "id" : 162, - "damage" : 1 - }, - { - "id" : -9 - }, - { - "id" : -212 - }, - { - "id" : -212, - "damage" : 8 - }, - { - "id" : -212, - "damage" : 1 - }, - { - "id" : -212, - "damage" : 9 - }, - { - "id" : -212, - "damage" : 2 - }, - { - "id" : -212, - "damage" : 10 - }, - { - "id" : -212, - "damage" : 3 - }, - { - "id" : -212, - "damage" : 11 - }, - { - "id" : -212, - "damage" : 4 - }, - { - "id" : -212, - "damage" : 12 - }, - { - "id" : -212, - "damage" : 5 - }, - { - "id" : -212, - "damage" : 13 - }, - { - "id" : 18 - }, - { - "id" : 18, - "damage" : 1 - }, - { - "id" : 18, - "damage" : 2 - }, - { - "id" : 18, - "damage" : 3 - }, { "id" : 161 }, { - "id" : 161, + "id" : 160, + "damage" : 2 + }, + { + "id" : 257 + }, + { + "id" : 70 + }, + { + "id" : -263 + }, + { + "id" : 285 + }, + { + "id" : 160, + "damage" : 10 + }, + { + "id" : 160, + "damage" : 11 + }, + { + "id" : -165 + }, + { + "id" : 65 + }, + { + "id" : 18, + "damage" : 3 + }, + { + "id" : 18, + "damage" : 2 + }, + { + "id" : 160, + "damage" : 9 + }, + { + "id" : 6, + "damage" : 3 + }, + { + "id" : 18, "damage" : 1 }, + { + "id" : 146 + }, + { + "id" : 18 + }, + { + "id" : -203 + }, + { + "id" : 130 + }, { "id" : 6 }, @@ -1241,2696 +2337,60 @@ }, { "id" : 6, - "damage" : 3 + "damage" : 5 }, { "id" : 6, "damage" : 4 }, - { - "id" : 6, - "damage" : 5 - }, - { - "id" : -218 - }, - { - "id" : 295 - }, - { - "id" : 361 - }, - { - "id" : 362 - }, - { - "id" : 458 - }, - { - "id" : 296 - }, - { - "id" : 457 - }, - { - "id" : 392 - }, - { - "id" : 394 - }, - { - "id" : 391 - }, - { - "id" : 396 - }, - { - "id" : 260 - }, - { - "id" : 322 - }, - { - "id" : 466 - }, - { - "id" : 103 - }, - { - "id" : 360 - }, - { - "id" : 382 - }, - { - "id" : 477 - }, - { - "id" : 86 - }, - { - "id" : -155 - }, - { - "id" : 91 - }, - { - "id" : 736 - }, - { - "id" : 31, - "damage" : 2 - }, - { - "id" : 175, - "damage" : 3 - }, - { - "id" : 31, - "damage" : 1 - }, - { - "id" : 175, - "damage" : 2 - }, - { - "id" : -131, - "damage" : 3 - }, - { - "id" : -131, - "damage" : 1 - }, - { - "id" : -131, - "damage" : 2 - }, - { - "id" : -131 - }, - { - "id" : -131, - "damage" : 4 - }, - { - "id" : -131, - "damage" : 11 - }, - { - "id" : -131, - "damage" : 9 - }, - { - "id" : -131, - "damage" : 10 - }, - { - "id" : -131, - "damage" : 8 - }, - { - "id" : -131, - "damage" : 12 - }, - { - "id" : -133, - "damage" : 3 - }, - { - "id" : -133, - "damage" : 1 - }, - { - "id" : -133, - "damage" : 2 - }, - { - "id" : -133 - }, - { - "id" : -133, - "damage" : 4 - }, - { - "id" : -134, - "damage" : 3 - }, - { - "id" : -134, - "damage" : 1 - }, - { - "id" : -134, - "damage" : 2 - }, - { - "id" : -134 - }, - { - "id" : -134, - "damage" : 4 - }, - { - "id" : 335 - }, - { - "id" : -130 - }, - { - "id" : 37 - }, - { - "id" : 38 - }, - { - "id" : 38, - "damage" : 1 - }, - { - "id" : 38, - "damage" : 2 - }, - { - "id" : 38, - "damage" : 3 - }, - { - "id" : 38, - "damage" : 4 - }, - { - "id" : 38, - "damage" : 5 - }, - { - "id" : 38, - "damage" : 6 - }, - { - "id" : 38, - "damage" : 7 - }, - { - "id" : 38, - "damage" : 8 - }, - { - "id" : 38, - "damage" : 9 - }, - { - "id" : 38, - "damage" : 10 - }, - { - "id" : 175 - }, - { - "id" : 175, - "damage" : 1 - }, - { - "id" : 175, - "damage" : 4 - }, - { - "id" : 175, - "damage" : 5 - }, - { - "id" : -216 - }, - { - "id" : 351, - "damage" : 19 - }, - { - "id" : 351, - "damage" : 7 - }, - { - "id" : 351, - "damage" : 8 - }, - { - "id" : 351, - "damage" : 16 - }, - { - "id" : 351, - "damage" : 17 - }, - { - "id" : 351, - "damage" : 1 - }, - { - "id" : 351, - "damage" : 14 - }, - { - "id" : 351, - "damage" : 11 - }, - { - "id" : 351, - "damage" : 10 - }, - { - "id" : 351, - "damage" : 2 - }, - { - "id" : 351, - "damage" : 6 - }, - { - "id" : 351, - "damage" : 12 - }, - { - "id" : 351, - "damage" : 18 - }, - { - "id" : 351, - "damage" : 5 - }, - { - "id" : 351, - "damage" : 13 - }, - { - "id" : 351, - "damage" : 9 - }, - { - "id" : 351 - }, - { - "id" : 351, - "damage" : 3 - }, - { - "id" : 351, - "damage" : 4 - }, - { - "id" : 351, - "damage" : 15 - }, - { - "id" : 106 - }, - { - "id" : 111 - }, - { - "id" : 32 - }, - { - "id" : -163 - }, - { - "id" : 80 - }, - { - "id" : 79 - }, - { - "id" : 174 - }, - { - "id" : -11 - }, - { - "id" : 78 - }, - { - "id" : 365 - }, - { - "id" : 319 - }, - { - "id" : 363 - }, - { - "id" : 423 - }, - { - "id" : 411 - }, - { - "id" : 349 - }, - { - "id" : 460 - }, - { - "id" : 461 - }, - { - "id" : 462 - }, - { - "id" : 39 - }, - { - "id" : 40 - }, - { - "id" : 99, - "damage" : 14 - }, - { - "id" : 100, - "damage" : 14 - }, - { - "id" : 99, - "damage" : 15 - }, - { - "id" : 99 - }, - { - "id" : 344 - }, - { - "id" : 338 - }, - { - "id" : 353 - }, - { - "id" : 367 - }, - { - "id" : 352 - }, - { - "id" : 30 - }, - { - "id" : 375 - }, - { - "id" : 52 - }, - { - "id" : 97 - }, - { - "id" : 97, - "damage" : 1 - }, - { - "id" : 97, - "damage" : 2 - }, - { - "id" : 97, - "damage" : 3 - }, - { - "id" : 97, - "damage" : 4 - }, - { - "id" : 97, - "damage" : 5 - }, - { - "id" : 122 - }, - { - "id" : -159 - }, - { - "id" : 383, - "damage" : 10 - }, - { - "id" : 383, - "damage" : 122 - }, - { - "id" : 383, - "damage" : 11 - }, - { - "id" : 383, - "damage" : 12 - }, - { - "id" : 383, - "damage" : 13 - }, - { - "id" : 383, - "damage" : 14 - }, - { - "id" : 383, - "damage" : 28 - }, - { - "id" : 383, - "damage" : 22 - }, - { - "id" : 383, - "damage" : 75 - }, - { - "id" : 383, - "damage" : 16 - }, - { - "id" : 383, - "damage" : 19 - }, - { - "id" : 383, - "damage" : 30 - }, - { - "id" : 383, - "damage" : 18 - }, - { - "id" : 383, - "damage" : 29 - }, - { - "id" : 383, - "damage" : 23 - }, - { - "id" : 383, - "damage" : 24 - }, - { - "id" : 383, - "damage" : 25 - }, - { - "id" : 383, - "damage" : 26 - }, - { - "id" : 383, - "damage" : 27 - }, - { - "id" : 383, - "damage" : 111 - }, - { - "id" : 383, - "damage" : 112 - }, - { - "id" : 383, - "damage" : 108 - }, - { - "id" : 383, - "damage" : 109 - }, - { - "id" : 383, - "damage" : 31 - }, - { - "id" : 383, - "damage" : 74 - }, - { - "id" : 383, - "damage" : 113 - }, - { - "id" : 383, - "damage" : 121 - }, - { - "id" : 383, - "damage" : 33 - }, - { - "id" : 383, - "damage" : 38 - }, - { - "id" : 383, - "damage" : 39 - }, - { - "id" : 383, - "damage" : 34 - }, - { - "id" : 383, - "damage" : 48 - }, - { - "id" : 383, - "damage" : 46 - }, - { - "id" : 383, - "damage" : 37 - }, - { - "id" : 383, - "damage" : 35 - }, - { - "id" : 383, - "damage" : 32 - }, - { - "id" : 383, - "damage" : 36 - }, - { - "id" : 383, - "damage" : 47 - }, - { - "id" : 383, - "damage" : 110 - }, - { - "id" : 383, - "damage" : 17 - }, - { - "id" : 383, - "damage" : 40 - }, - { - "id" : 383, - "damage" : 45 - }, - { - "id" : 383, - "damage" : 49 - }, - { - "id" : 383, - "damage" : 50 - }, - { - "id" : 383, - "damage" : 55 - }, - { - "id" : 383, - "damage" : 42 - }, - { - "id" : 383, - "damage" : 41 - }, - { - "id" : 383, - "damage" : 43 - }, - { - "id" : 383, - "damage" : 54 - }, - { - "id" : 383, - "damage" : 57 - }, - { - "id" : 383, - "damage" : 104 - }, - { - "id" : 383, - "damage" : 105 - }, - { - "id" : 383, - "damage" : 115 - }, - { - "id" : 383, - "damage" : 118 - }, - { - "id" : 383, - "damage" : 116 - }, - { - "id" : 383, - "damage" : 58 - }, - { - "id" : 383, - "damage" : 114 - }, - { - "id" : 383, - "damage" : 59 - }, - { - "id" : 49 - }, - { - "id" : 7 - }, - { - "id" : 88 - }, - { - "id" : 87 - }, - { - "id" : 213 - }, - { - "id" : 372 - }, - { - "id" : 121 - }, - { - "id" : 200 - }, - { - "id" : 240 - }, - { - "id" : 432 - }, - { - "id" : 433 - }, - { - "id" : 19 - }, - { - "id" : 19, - "damage" : 1 - }, - { - "id" : -132 - }, - { - "id" : -132, - "damage" : 1 - }, - { - "id" : -132, - "damage" : 2 - }, - { - "id" : -132, - "damage" : 3 - }, - { - "id" : -132, - "damage" : 4 - }, - { - "id" : -132, - "damage" : 8 - }, - { - "id" : -132, - "damage" : 9 - }, - { - "id" : -132, - "damage" : 10 - }, - { - "id" : -132, - "damage" : 11 - }, - { - "id" : -132, - "damage" : 12 - }, - { - "id" : 298 - }, - { - "id" : 302 - }, - { - "id" : 306 - }, - { - "id" : 314 - }, - { - "id" : 310 - }, - { - "id" : 299 - }, - { - "id" : 303 - }, - { - "id" : 307 - }, - { - "id" : 315 - }, - { - "id" : 311 - }, - { - "id" : 300 - }, - { - "id" : 304 - }, - { - "id" : 308 - }, - { - "id" : 316 - }, - { - "id" : 312 - }, - { - "id" : 301 - }, - { - "id" : 305 - }, - { - "id" : 309 - }, - { - "id" : 317 - }, - { - "id" : 313 - }, - { - "id" : 268 - }, - { - "id" : 272 - }, - { - "id" : 267 - }, - { - "id" : 283 - }, - { - "id" : 276 - }, - { - "id" : 271 - }, - { - "id" : 275 - }, - { - "id" : 258 - }, - { - "id" : 286 - }, - { - "id" : 279 - }, - { - "id" : 270 - }, - { - "id" : 274 - }, - { - "id" : 257 - }, - { - "id" : 285 - }, - { - "id" : 278 - }, - { - "id" : 269 - }, - { - "id" : 273 - }, - { - "id" : 256 - }, - { - "id" : 284 - }, - { - "id" : 277 - }, - { - "id" : 290 - }, - { - "id" : 291 - }, - { - "id" : 292 - }, - { - "id" : 294 - }, - { - "id" : 293 - }, - { - "id" : 261 - }, - { - "id" : 471 - }, - { - "id" : 262 - }, - { - "id" : 262, - "damage" : 6 - }, - { - "id" : 262, - "damage" : 7 - }, - { - "id" : 262, - "damage" : 8 - }, - { - "id" : 262, - "damage" : 9 - }, - { - "id" : 262, - "damage" : 10 - }, - { - "id" : 262, - "damage" : 11 - }, - { - "id" : 262, - "damage" : 12 - }, - { - "id" : 262, - "damage" : 13 - }, - { - "id" : 262, - "damage" : 14 - }, - { - "id" : 262, - "damage" : 15 - }, - { - "id" : 262, - "damage" : 16 - }, - { - "id" : 262, - "damage" : 17 - }, - { - "id" : 262, - "damage" : 18 - }, - { - "id" : 262, - "damage" : 19 - }, - { - "id" : 262, - "damage" : 20 - }, - { - "id" : 262, - "damage" : 21 - }, - { - "id" : 262, - "damage" : 22 - }, - { - "id" : 262, - "damage" : 23 - }, - { - "id" : 262, - "damage" : 24 - }, - { - "id" : 262, - "damage" : 25 - }, - { - "id" : 262, - "damage" : 26 - }, - { - "id" : 262, - "damage" : 27 - }, - { - "id" : 262, - "damage" : 28 - }, - { - "id" : 262, - "damage" : 29 - }, - { - "id" : 262, - "damage" : 30 - }, - { - "id" : 262, - "damage" : 31 - }, - { - "id" : 262, - "damage" : 32 - }, - { - "id" : 262, - "damage" : 33 - }, - { - "id" : 262, - "damage" : 34 - }, - { - "id" : 262, - "damage" : 35 - }, - { - "id" : 262, - "damage" : 36 - }, - { - "id" : 262, - "damage" : 37 - }, - { - "id" : 262, - "damage" : 38 - }, - { - "id" : 262, - "damage" : 39 - }, - { - "id" : 262, - "damage" : 40 - }, - { - "id" : 262, - "damage" : 41 - }, - { - "id" : 262, - "damage" : 42 - }, - { - "id" : 513 - }, - { - "id" : 366 - }, - { - "id" : 320 - }, - { - "id" : 364 - }, - { - "id" : 424 - }, - { - "id" : 412 - }, - { - "id" : 350 - }, - { - "id" : 463 - }, - { - "id" : 297 - }, - { - "id" : 282 - }, - { - "id" : 459 - }, - { - "id" : 413 - }, - { - "id" : 393 - }, - { - "id" : 357 - }, - { - "id" : 400 - }, - { - "id" : 354 - }, - { - "id" : 464 - }, - { - "id" : 346 - }, - { - "id" : 398 - }, - { - "id" : 332 - }, - { - "id" : 359 - }, - { - "id" : 259 - }, - { - "id" : 420 - }, - { - "id" : 347 - }, - { - "id" : 345 - }, - { - "id" : 395 - }, - { - "id" : 395, - "damage" : 2 - }, - { - "id" : 329 - }, - { - "id" : 416 - }, - { - "id" : 417 - }, - { - "id" : 418 - }, - { - "id" : 419 - }, - { - "id" : 455 - }, - { - "id" : 469 - }, - { - "id" : 444 - }, - { - "id" : 450 - }, - { - "id" : 374 - }, - { - "id" : 384 - }, - { - "id" : 373 - }, - { - "id" : 373, - "damage" : 1 - }, - { - "id" : 373, - "damage" : 2 - }, - { - "id" : 373, - "damage" : 3 - }, - { - "id" : 373, - "damage" : 4 - }, - { - "id" : 373, - "damage" : 5 - }, - { - "id" : 373, - "damage" : 6 - }, - { - "id" : 373, - "damage" : 7 - }, - { - "id" : 373, - "damage" : 8 - }, - { - "id" : 373, - "damage" : 9 - }, - { - "id" : 373, - "damage" : 10 - }, - { - "id" : 373, - "damage" : 11 - }, - { - "id" : 373, - "damage" : 12 - }, - { - "id" : 373, - "damage" : 13 - }, - { - "id" : 373, - "damage" : 14 - }, - { - "id" : 373, - "damage" : 15 - }, - { - "id" : 373, - "damage" : 16 - }, - { - "id" : 373, - "damage" : 17 - }, - { - "id" : 373, - "damage" : 18 - }, - { - "id" : 373, - "damage" : 19 - }, - { - "id" : 373, - "damage" : 20 - }, - { - "id" : 373, - "damage" : 21 - }, - { - "id" : 373, - "damage" : 22 - }, - { - "id" : 373, - "damage" : 23 - }, - { - "id" : 373, - "damage" : 24 - }, - { - "id" : 373, - "damage" : 25 - }, - { - "id" : 373, - "damage" : 26 - }, - { - "id" : 373, - "damage" : 27 - }, - { - "id" : 373, - "damage" : 28 - }, - { - "id" : 373, - "damage" : 29 - }, - { - "id" : 373, - "damage" : 30 - }, - { - "id" : 373, - "damage" : 31 - }, - { - "id" : 373, - "damage" : 32 - }, - { - "id" : 373, - "damage" : 33 - }, - { - "id" : 373, - "damage" : 34 - }, - { - "id" : 373, - "damage" : 35 - }, - { - "id" : 373, - "damage" : 36 - }, - { - "id" : 373, - "damage" : 37 - }, - { - "id" : 373, - "damage" : 38 - }, - { - "id" : 373, - "damage" : 39 - }, - { - "id" : 373, - "damage" : 40 - }, - { - "id" : 373, - "damage" : 41 - }, - { - "id" : 438 - }, - { - "id" : 438, - "damage" : 1 - }, - { - "id" : 438, - "damage" : 2 - }, - { - "id" : 438, - "damage" : 3 - }, - { - "id" : 438, - "damage" : 4 - }, - { - "id" : 438, - "damage" : 5 - }, - { - "id" : 438, - "damage" : 6 - }, - { - "id" : 438, - "damage" : 7 - }, - { - "id" : 438, - "damage" : 8 - }, - { - "id" : 438, - "damage" : 9 - }, - { - "id" : 438, - "damage" : 10 - }, - { - "id" : 438, - "damage" : 11 - }, - { - "id" : 438, - "damage" : 12 - }, - { - "id" : 438, - "damage" : 13 - }, - { - "id" : 438, - "damage" : 14 - }, - { - "id" : 438, - "damage" : 15 - }, - { - "id" : 438, - "damage" : 16 - }, - { - "id" : 438, - "damage" : 17 - }, - { - "id" : 438, - "damage" : 18 - }, - { - "id" : 438, - "damage" : 19 - }, - { - "id" : 438, - "damage" : 20 - }, - { - "id" : 438, - "damage" : 21 - }, - { - "id" : 438, - "damage" : 22 - }, - { - "id" : 438, - "damage" : 23 - }, - { - "id" : 438, - "damage" : 24 - }, - { - "id" : 438, - "damage" : 25 - }, - { - "id" : 438, - "damage" : 26 - }, - { - "id" : 438, - "damage" : 27 - }, - { - "id" : 438, - "damage" : 28 - }, - { - "id" : 438, - "damage" : 29 - }, - { - "id" : 438, - "damage" : 30 - }, - { - "id" : 438, - "damage" : 31 - }, - { - "id" : 438, - "damage" : 32 - }, - { - "id" : 438, - "damage" : 33 - }, - { - "id" : 438, - "damage" : 34 - }, - { - "id" : 438, - "damage" : 35 - }, - { - "id" : 438, - "damage" : 36 - }, - { - "id" : 438, - "damage" : 37 - }, - { - "id" : 438, - "damage" : 38 - }, - { - "id" : 438, - "damage" : 39 - }, - { - "id" : 438, - "damage" : 40 - }, - { - "id" : 438, - "damage" : 41 - }, - { - "id" : 441 - }, - { - "id" : 441, - "damage" : 1 - }, - { - "id" : 441, - "damage" : 2 - }, - { - "id" : 441, - "damage" : 3 - }, - { - "id" : 441, - "damage" : 4 - }, - { - "id" : 441, - "damage" : 5 - }, - { - "id" : 441, - "damage" : 6 - }, - { - "id" : 441, - "damage" : 7 - }, - { - "id" : 441, - "damage" : 8 - }, - { - "id" : 441, - "damage" : 9 - }, - { - "id" : 441, - "damage" : 10 - }, - { - "id" : 441, - "damage" : 11 - }, - { - "id" : 441, - "damage" : 12 - }, - { - "id" : 441, - "damage" : 13 - }, - { - "id" : 441, - "damage" : 14 - }, - { - "id" : 441, - "damage" : 15 - }, - { - "id" : 441, - "damage" : 16 - }, - { - "id" : 441, - "damage" : 17 - }, - { - "id" : 441, - "damage" : 18 - }, - { - "id" : 441, - "damage" : 19 - }, - { - "id" : 441, - "damage" : 20 - }, - { - "id" : 441, - "damage" : 21 - }, - { - "id" : 441, - "damage" : 22 - }, - { - "id" : 441, - "damage" : 23 - }, - { - "id" : 441, - "damage" : 24 - }, - { - "id" : 441, - "damage" : 25 - }, - { - "id" : 441, - "damage" : 26 - }, - { - "id" : 441, - "damage" : 27 - }, - { - "id" : 441, - "damage" : 28 - }, - { - "id" : 441, - "damage" : 29 - }, - { - "id" : 441, - "damage" : 30 - }, - { - "id" : 441, - "damage" : 31 - }, - { - "id" : 441, - "damage" : 32 - }, - { - "id" : 441, - "damage" : 33 - }, - { - "id" : 441, - "damage" : 34 - }, - { - "id" : 441, - "damage" : 35 - }, - { - "id" : 441, - "damage" : 36 - }, - { - "id" : 441, - "damage" : 37 - }, - { - "id" : 441, - "damage" : 38 - }, - { - "id" : 441, - "damage" : 39 - }, - { - "id" : 441, - "damage" : 40 - }, - { - "id" : 441, - "damage" : 41 - }, - { - "id" : 280 - }, - { - "id" : 355 - }, - { - "id" : 355, - "damage" : 8 - }, - { - "id" : 355, - "damage" : 7 - }, - { - "id" : 355, - "damage" : 15 - }, - { - "id" : 355, - "damage" : 12 - }, - { - "id" : 355, - "damage" : 14 - }, - { - "id" : 355, - "damage" : 1 - }, - { - "id" : 355, - "damage" : 4 - }, - { - "id" : 355, - "damage" : 5 - }, - { - "id" : 355, - "damage" : 13 - }, - { - "id" : 355, - "damage" : 9 - }, - { - "id" : 355, - "damage" : 3 - }, - { - "id" : 355, - "damage" : 11 - }, - { - "id" : 355, - "damage" : 10 - }, - { - "id" : 355, - "damage" : 2 - }, - { - "id" : 355, - "damage" : 6 - }, - { - "id" : 50 - }, - { - "id" : -156 - }, - { - "id" : -208 - }, - { - "id" : 58 - }, - { - "id" : -200 - }, - { - "id" : -201 - }, - { - "id" : -202 - }, - { - "id" : -219 - }, - { - "id" : 720 - }, - { - "id" : 61 - }, - { - "id" : -196 - }, - { - "id" : -198 - }, - { - "id" : 379 - }, - { - "id" : 145 - }, - { - "id" : 145, - "damage" : 4 - }, - { - "id" : 145, - "damage" : 8 - }, - { - "id" : -195 - }, - { - "id" : 116 - }, - { - "id" : 47 - }, - { - "id" : -194 - }, - { - "id" : 380 - }, - { - "id" : -213 - }, { "id" : 54 }, { - "id" : 146 + "id" : -213 }, { - "id" : 130 + "id" : 380 }, { - "id" : -203 + "id" : -194 }, { - "id" : 205 + "id" : 116 }, { - "id" : 218 + "id" : 145, + "damage" : 4 }, { - "id" : 218, + "id" : 379 + }, + { + "id" : -198 + }, + { + "id" : -272 + }, + { + "id" : 145 + }, + { + "id" : -195 + }, + { + "id" : 145, "damage" : 8 }, { - "id" : 218, - "damage" : 7 + "id" : 47 }, { - "id" : 218, - "damage" : 15 + "id" : 158 }, { - "id" : 218, - "damage" : 12 - }, - { - "id" : 218, - "damage" : 14 - }, - { - "id" : 218, + "id" : 158, "damage" : 1 }, - { - "id" : 218, - "damage" : 4 - }, - { - "id" : 218, - "damage" : 5 - }, - { - "id" : 218, - "damage" : 13 - }, - { - "id" : 218, - "damage" : 9 - }, - { - "id" : 218, - "damage" : 3 - }, - { - "id" : 218, - "damage" : 11 - }, - { - "id" : 218, - "damage" : 10 - }, - { - "id" : 218, - "damage" : 2 - }, - { - "id" : 218, - "damage" : 6 - }, - { - "id" : 425 - }, - { - "id" : 25 - }, - { - "id" : 84 - }, - { - "id" : 500 - }, - { - "id" : 501 - }, - { - "id" : 502 - }, - { - "id" : 503 - }, - { - "id" : 504 - }, - { - "id" : 505 - }, - { - "id" : 506 - }, - { - "id" : 507 - }, - { - "id" : 508 - }, - { - "id" : 509 - }, - { - "id" : 510 - }, - { - "id" : 511 - }, - { - "id" : 348 - }, - { - "id" : 89 - }, - { - "id" : 123 - }, - { - "id" : 169 - }, - { - "id" : 323 - }, - { - "id" : 472 - }, - { - "id" : 473 - }, - { - "id" : 474 - }, - { - "id" : 475 - }, - { - "id" : 476 - }, - { - "id" : 321 - }, - { - "id" : 389 - }, - { - "id" : 737 - }, - { - "id" : 390 - }, - { - "id" : 281 - }, - { - "id" : 325 - }, - { - "id" : 325, - "damage" : 1 - }, - { - "id" : 325, - "damage" : 8 - }, - { - "id" : 325, - "damage" : 10 - }, - { - "id" : 325, - "damage" : 2 - }, - { - "id" : 325, - "damage" : 3 - }, - { - "id" : 325, - "damage" : 4 - }, - { - "id" : 325, - "damage" : 5 - }, - { - "id" : 397, - "damage" : 3 - }, - { - "id" : 397, - "damage" : 2 - }, - { - "id" : 397, - "damage" : 4 - }, - { - "id" : 397, - "damage" : 5 - }, - { - "id" : 397 - }, - { - "id" : 397, - "damage" : 1 - }, - { - "id" : 138 - }, - { - "id" : -206 - }, - { - "id" : -157 - }, - { - "id" : -197 - }, - { - "id" : 120 - }, - { - "id" : 263 - }, - { - "id" : 263, - "damage" : 1 - }, - { - "id" : 264 - }, - { - "id" : 452 - }, - { - "id" : 265 - }, - { - "id" : 371 - }, - { - "id" : 266 - }, - { - "id" : 388 - }, - { - "id" : 406 - }, - { - "id" : 337 - }, - { - "id" : 336 - }, - { - "id" : 405 - }, - { - "id" : 409 - }, - { - "id" : 422 - }, - { - "id" : 465 - }, - { - "id" : 467 - }, - { - "id" : 468 - }, - { - "id" : 470 - }, - { - "id" : 287 - }, - { - "id" : 288 - }, - { - "id" : 318 - }, - { - "id" : 289 - }, - { - "id" : 334 - }, - { - "id" : 415 - }, - { - "id" : 414 - }, - { - "id" : 385 - }, - { - "id" : 369 - }, - { - "id" : 377 - }, - { - "id" : 378 - }, - { - "id" : 376 - }, - { - "id" : 437 - }, - { - "id" : 445 - }, - { - "id" : 370 - }, - { - "id" : 341 - }, - { - "id" : 368 - }, - { - "id" : 381 - }, - { - "id" : 399 - }, - { - "id" : 208 - }, - { - "id" : 426 - }, - { - "id" : 339 - }, - { - "id" : 340 - }, - { - "id" : 386 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAYAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAYAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAYAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAcAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAcAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAcAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAgAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAoAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAoAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAoAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAoAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAoAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAwAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAwAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZA8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZA8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBYAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBcAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBcAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBcAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBgAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBgAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBgAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBoAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZB0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZB0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZCIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCMAAAA=" - }, - { - "id" : 333 - }, - { - "id" : 333, - "damage" : 1 - }, - { - "id" : 333, - "damage" : 2 - }, - { - "id" : 333, - "damage" : 3 - }, - { - "id" : 333, - "damage" : 4 - }, - { - "id" : 333, - "damage" : 5 - }, - { - "id" : 66 - }, - { - "id" : 27 - }, - { - "id" : 28 - }, - { - "id" : 126 - }, - { - "id" : 328 - }, - { - "id" : 342 - }, - { - "id" : 408 - }, - { - "id" : 407 - }, - { - "id" : 331 - }, - { - "id" : 152 - }, - { - "id" : 76 - }, - { - "id" : 69 - }, - { - "id" : 143 - }, - { - "id" : -144 - }, - { - "id" : -141 - }, - { - "id" : -143 - }, - { - "id" : -140 - }, - { - "id" : -142 - }, - { - "id" : 77 - }, - { - "id" : 131 - }, - { - "id" : 72 - }, - { - "id" : -154 - }, - { - "id" : -151 - }, - { - "id" : -153 - }, - { - "id" : -150 - }, - { - "id" : -152 - }, - { - "id" : 70 - }, - { - "id" : 147 - }, - { - "id" : 148 - }, - { - "id" : 251 - }, - { - "id" : 151 - }, - { - "id" : 356 - }, { "id" : 404 }, @@ -3938,52 +2398,330 @@ "id" : 410 }, { - "id" : 125, + "id" : 276 + }, + { + "id" : 743 + }, + { + "id" : -212, "damage" : 3 }, { - "id" : 23, - "damage" : 3 + "id" : -212, + "damage" : 11 }, { - "id" : 33, - "damage" : 1 + "id" : -212, + "damage" : 5 + }, + { + "id" : -212, + "damage" : 13 }, { "id" : 29, "damage" : 1 }, { - "id" : 46 + "id" : 160, + "damage" : 1 }, { - "id" : 421 + "id" : 160, + "damage" : 4 }, { - "id" : -204 + "id" : 33, + "damage" : 1 + }, + { + "id" : 44 + }, + { + "id" : 160, + "damage" : 3 + }, + { + "id" : 158, + "damage" : 4 + }, + { + "id" : 251 + }, + { + "id" : -295 + }, + { + "id" : -150 + }, + { + "id" : -153 + }, + { + "id" : -166, + "damage" : 2 + }, + { + "id" : 131 + }, + { + "id" : 158, + "damage" : 5 + }, + { + "id" : 272 + }, + { + "id" : 268 + }, + { + "id" : 286 + }, + { + "id" : 258 + }, + { + "id" : 290 + }, + { + "id" : 291 + }, + { + "id" : 293 + }, + { + "id" : 747 + }, + { + "id" : 256 + }, + { + "id" : 284 + }, + { + "id" : 270 + }, + { + "id" : 274 + }, + { + "id" : 745 + }, + { + "id" : 278 + }, + { + "id" : -260 + }, + { + "id" : -143 + }, + { + "id" : -141 + }, + { + "id" : 72 + }, + { + "id" : 77 + }, + { + "id" : 261 }, { "id" : 446 }, { - "id" : 446, + "id" : -204 + }, + { + "id" : 471 + }, + { + "id" : 102 + }, + { + "id" : 317 + }, + { + "id" : 241, + "damage" : 6 + }, + { + "id" : 309 + }, + { + "id" : 313 + }, + { + "id" : 751 + }, + { + "id" : -166, + "damage" : 3 + }, + { + "id" : 182 + }, + { + "id" : 182, + "damage" : 6 + }, + { + "id" : 44, + "damage" : 1 + }, + { + "id" : 421 + }, + { + "id" : 46 + }, + { + "id" : 160 + }, + { + "id" : 160, "damage" : 8 }, { - "id" : 446, - "damage" : 7 + "id" : 162 }, { - "id" : 446, - "damage" : 15 + "id" : 218, + "damage" : 3 }, { - "id" : 446, + "id" : 218, "damage" : 12 }, { - "id" : 446, - "damage" : 14 + "id" : -9 + }, + { + "id" : -8 + }, + { + "id" : 162, + "damage" : 1 + }, + { + "id" : 458 + }, + { + "id" : 218, + "damage" : 15 + }, + { + "id" : 322 + }, + { + "id" : 801 + }, + { + "id" : -212, + "damage" : 10 + }, + { + "id" : 720 + }, + { + "id" : -219, + "damage" : 3 + }, + { + "id" : 296 + }, + { + "id" : -202 + }, + { + "id" : -208 + }, + { + "id" : 241, + "damage" : 13 + }, + { + "id" : 241, + "damage" : 9 + }, + { + "id" : 218, + "damage" : 11 + }, + { + "id" : -156 + }, + { + "id" : 50 + }, + { + "id" : -268 + }, + { + "id" : 218, + "damage" : 9 + }, + { + "id" : 218, + "damage" : 13 + }, + { + "id" : 218, + "damage" : 7 + }, + { + "id" : 218, + "damage" : 8 + }, + { + "id" : 392 + }, + { + "id" : 457 + }, + { + "id" : 466 + }, + { + "id" : 360 + }, + { + "id" : 103 + }, + { + "id" : 744 + }, + { + "id" : 277 + }, + { + "id" : 342 + }, + { + "id" : 328 + }, + { + "id" : 262, + "damage" : 12 + }, + { + "id" : 262, + "damage" : 11 + }, + { + "id" : 356 + }, + { + "id" : 275 + }, + { + "id" : 151 + }, + { + "id" : 271 }, { "id" : 446, @@ -3991,44 +2729,111 @@ }, { "id" : 446, - "damage" : 4 + "damage" : 14 }, { - "id" : 446, - "damage" : 5 - }, - { - "id" : 446, - "damage" : 13 - }, - { - "id" : 446, - "damage" : 9 - }, - { - "id" : 446, + "id" : 158, "damage" : 3 }, { - "id" : 446, - "damage" : 11 - }, - { - "id" : 446, - "damage" : 10 - }, - { - "id" : 446, + "id" : 158, "damage" : 2 }, { - "id" : 446, + "id" : -10 + }, + { + "id" : 17 + }, + { + "id" : 316 + }, + { + "id" : -212, + "damage" : 2 + }, + { + "id" : 308 + }, + { + "id" : 160, + "damage" : 13 + }, + { + "id" : 160, + "damage" : 5 + }, + { + "id" : -262 + }, + { + "id" : -152 + }, + { + "id" : -162, + "damage" : 2 + }, + { + "id" : -162, + "damage" : 3 + }, + { + "id" : -261 + }, + { + "id" : -296 + }, + { + "id" : 143 + }, + { + "id" : -144 + }, + { + "id" : 333, + "damage" : 5 + }, + { + "id" : 31, + "damage" : 1 + }, + { + "id" : 175, + "damage" : 2 + }, + { + "id" : 333, + "damage" : 4 + }, + { + "id" : -291 + }, + { + "id" : 12 + }, + { + "id" : 1, + "damage" : 4 + }, + { + "id" : 1, "damage" : 6 }, { - "id" : 446, - "damage" : 15, - "nbt_b64" : "CgAAAwQAVHlwZQEAAAAA" + "id" : 262, + "damage" : 19 + }, + { + "id" : 333, + "damage" : 3 + }, + { + "id" : 333, + "damage" : 2 + }, + { + "id" : 262, + "damage" : 20 }, { "id" : 434 @@ -4038,56 +2843,278 @@ "damage" : 1 }, { - "id" : 434, - "damage" : 2 + "id" : 306 }, { "id" : 434, "damage" : 3 }, + { + "id" : 446, + "damage" : 15, + "nbt_b64" : "CgAAAwQAVHlwZQEAAAAA" + }, + { + "id" : 509 + }, + { + "id" : 314 + }, + { + "id" : 310 + }, + { + "id" : 748 + }, + { + "id" : 446, + "damage" : 6 + }, { "id" : 434, + "damage" : 2 + }, + { + "id" : 508 + }, + { + "id" : 355, + "damage" : 8 + }, + { + "id" : 355 + }, + { + "id" : 241, + "damage" : 8 + }, + { + "id" : 302 + }, + { + "id" : 298 + }, + { + "id" : -131, + "damage" : 1 + }, + { + "id" : 241, + "damage" : 15 + }, + { + "id" : 241, + "damage" : 7 + }, + { + "id" : -131, + "damage" : 2 + }, + { + "id" : 355, + "damage" : 3 + }, + { + "id" : 241, + "damage" : 12 + }, + { + "id" : -145 + }, + { + "id" : -148 + }, + { + "id" : 760 + }, + { + "id" : -131, + "damage" : 3 + }, + { + "id" : 175, + "damage" : 3 + }, + { + "id" : 31, + "damage" : 2 + }, + { + "id" : -162, "damage" : 4 }, { - "id" : 434, + "id" : -162, "damage" : 5 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMAAAAAAAAA" + "id" : 241, + "damage" : 4 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 241, + "damage" : 5 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZCIAAAA=" }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCIAAAA=" }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 355, + "damage" : 2 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 355, + "damage" : 6 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 218, + "damage" : 2 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 218, + "damage" : 10 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 441, + "damage" : 38 + }, + { + "id" : 84 + }, + { + "id" : 25 + }, + { + "id" : 123 + }, + { + "id" : 355, + "damage" : 9 + }, + { + "id" : 262, + "damage" : 29 + }, + { + "id" : 262, + "damage" : 30 + }, + { + "id" : 750 + }, + { + "id" : 312 + }, + { + "id" : 511 + }, + { + "id" : 510 + }, + { + "id" : 280 + }, + { + "id" : 441, + "damage" : 42 + }, + { + "id" : 441, + "damage" : 39 + }, + { + "id" : 89 + }, + { + "id" : 446, + "damage" : 12 + }, + { + "id" : 16 + }, + { + "id" : 73 + }, + { + "id" : 446, + "damage" : 15 + }, + { + "id" : 81 + }, + { + "id" : 12, + "damage" : 1 + }, + { + "id" : -166, + "damage" : 4 + }, + { + "id" : -162, + "damage" : 1 + }, + { + "id" : 262, + "damage" : 17 + }, + { + "id" : 262, + "damage" : 18 + }, + { + "id" : 126 + }, + { + "id" : 28 + }, + { + "id" : 262, + "damage" : 14 + }, + { + "id" : 262, + "damage" : 13 + }, + { + "id" : 182, + "damage" : 4 + }, + { + "id" : -282 + }, + { + "id" : -293 + }, + { + "id" : 182, + "damage" : 3 + }, + { + "id" : 394 + }, + { + "id" : 391 + }, + { + "id" : -133, + "damage" : 4 + }, + { + "id" : -133 + }, + { + "id" : -134, + "damage" : 3 + }, + { + "id" : -134, + "damage" : 1 }, { "id" : 401, @@ -4098,8 +3125,60 @@ "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCEAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCAAAAA=" + }, + { + "id" : 446, + "damage" : 7 + }, + { + "id" : 446, + "damage" : 8 + }, + { + "id" : 301 + }, + { + "id" : 262, + "damage" : 34 + }, + { + "id" : 262, + "damage" : 33 + }, + { + "id" : -212, + "damage" : 1 + }, + { + "id" : -212, + "damage" : 9 + }, + { + "id" : -212, + "damage" : 8 + }, + { + "id" : -212 + }, + { + "id" : 200 + }, + { + "id" : 240 + }, + { + "id" : 160, + "damage" : 15 + }, + { + "id" : 160, + "damage" : 7 }, { "id" : 401, @@ -4107,43 +3186,275 @@ }, { "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 433 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 432 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 396 }, { - "id" : 402, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IhHR3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : 260 }, { - "id" : 402, - "damage" : 8, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3JST0f/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : -196 }, { - "id" : 402, - "damage" : 7, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KXnZ3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : 61 }, { - "id" : 402, - "damage" : 15, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Lw8PD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : -149 }, { - "id" : 402, - "damage" : 12, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Laszr/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : -146 + }, + { + "id" : 96 + }, + { + "id" : 756 + }, + { + "id" : 425 + }, + { + "id" : 218, + "damage" : 6 + }, + { + "id" : 441, + "damage" : 25 + }, + { + "id" : 441, + "damage" : 24 + }, + { + "id" : 205 + }, + { + "id" : 218 + }, + { + "id" : 390 + }, + { + "id" : 281 + }, + { + "id" : 355, + "damage" : 10 + }, + { + "id" : 355, + "damage" : 11 + }, + { + "id" : 241, + "damage" : 1 + }, + { + "id" : 241, + "damage" : 14 + }, + { + "id" : 44, + "damage" : 3 + }, + { + "id" : 182, + "damage" : 5 + }, + { + "id" : 160, + "damage" : 14 + }, + { + "id" : 160, + "damage" : 12 + }, + { + "id" : 424 + }, + { + "id" : 262, + "damage" : 32 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCIAAAA=" + }, + { + "id" : 364 + }, + { + "id" : 348 + }, + { + "id" : 759 + }, + { + "id" : 441, + "damage" : 41 + }, + { + "id" : 441, + "damage" : 40 + }, + { + "id" : 294 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCIAAAA=" + }, + { + "id" : 148 + }, + { + "id" : 262, + "damage" : 15 + }, + { + "id" : 746 + }, + { + "id" : 147 + }, + { + "id" : 305 + }, + { + "id" : 262, + "damage" : 31 + }, + { + "id" : 27 + }, + { + "id" : 66 + }, + { + "id" : -280 + }, + { + "id" : 279 + }, + { + "id" : 262, + "damage" : 16 + }, + { + "id" : -281 + }, + { + "id" : -142 + }, + { + "id" : 231 + }, + { + "id" : 223 + }, + { + "id" : 21 + }, + { + "id" : -162, + "damage" : 6 + }, + { + "id" : -162, + "damage" : 7 + }, + { + "id" : 56 + }, + { + "id" : -140 + }, + { + "id" : -264 + }, + { + "id" : -265 + }, + { + "id" : 292 + }, + { + "id" : 383, + "damage" : 58 + }, + { + "id" : 383, + "damage" : 116 + }, + { + "id" : 282 + }, + { + "id" : 459 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBgAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBgAAAA=" + }, + { + "id" : 397, + "damage" : 2 + }, + { + "id" : 397, + "damage" : 3 + }, + { + "id" : 441, + "damage" : 17 + }, + { + "id" : 441, + "damage" : 16 + }, + { + "id" : -174 + }, + { + "id" : -139 + }, + { + "id" : 179, + "damage" : 1 + }, + { + "id" : 179 + }, + { + "id" : 173 + }, + { + "id" : 38, + "damage" : 5 + }, + { + "id" : 38, + "damage" : 4 + }, + { + "id" : 38, + "damage" : 7 + }, + { + "id" : 38, + "damage" : 6 }, { "id" : 402, @@ -4152,13 +3463,69 @@ }, { "id" : 402, - "damage" : 1, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3ImLrD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "damage" : 12, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Laszr/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 400 + }, + { + "id" : 357 + }, + { + "id" : 350 + }, + { + "id" : 412 + }, + { + "id" : 49 + }, + { + "id" : -289 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBcAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBcAAAA=" + }, + { + "id" : -178 + }, + { + "id" : 108 + }, + { + "id" : -2 + }, + { + "id" : 156 }, { "id" : 402, - "damage" : 4, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KqRDz/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "damage" : 6, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KcnBb/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : -3 + }, + { + "id" : 402, + "damage" : 2, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IWfF7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 402, + "damage" : 3, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IyVIP/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 402, + "damage" : 9, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Kqi/P/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { "id" : 402, @@ -4171,34 +3538,983 @@ "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3K9Tsf/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : 402, - "damage" : 9, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Kqi/P/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : 383, + "damage" : 57 + }, + { + "id" : 3 + }, + { + "id" : 201, + "damage" : 2 + }, + { + "id" : 383, + "damage" : 54 + }, + { + "id" : 213 + }, + { + "id" : 87 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB0AAAA=" + }, + { + "id" : -254 + }, + { + "id" : -4 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBwAAAA=" + }, + { + "id" : 325, + "damage" : 1 + }, + { + "id" : 325 + }, + { + "id" : 441, + "damage" : 27 + }, + { + "id" : -279 + }, + { + "id" : 4 + }, + { + "id" : 346 + }, + { + "id" : 398 + }, + { + "id" : 441, + "damage" : 26 + }, + { + "id" : -223 + }, + { + "id" : 24, + "damage" : 1 + }, + { + "id" : 38, + "damage" : 1 + }, + { + "id" : 38 + }, + { + "id" : -130 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZB0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZB0AAAA=" + }, + { + "id" : 222 + }, + { + "id" : 219 + }, + { + "id" : 243 + }, + { + "id" : 198 + }, + { + "id" : 397 + }, + { + "id" : 397, + "damage" : 1 + }, + { + "id" : 24 + }, + { + "id" : 325, + "damage" : 2 + }, + { + "id" : 325, + "damage" : 3 + }, + { + "id" : 441, + "damage" : 7 + }, + { + "id" : 441, + "damage" : 2 + }, + { + "id" : 441, + "damage" : 6 + }, + { + "id" : 441, + "damage" : 3 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBEAAAA=" + }, + { + "id" : -220 + }, + { + "id" : -221 + }, + { + "id" : 206 + }, + { + "id" : 98, + "damage" : 3 + }, + { + "id" : 15 + }, + { + "id" : 14 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBEAAAA=" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 351, + "damage" : 2 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB8AAAA=" + }, + { + "id" : 441, + "damage" : 31 + }, + { + "id" : 351, + "damage" : 10 + }, + { + "id" : -132 + }, + { + "id" : -132, + "damage" : 1 + }, + { + "id" : 321 + }, + { + "id" : -134 + }, + { + "id" : 754 + }, + { + "id" : 441, + "damage" : 30 + }, + { + "id" : 262, + "damage" : 35 + }, + { + "id" : 53 + }, + { + "id" : -179 + }, + { + "id" : 262, + "damage" : 36 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB4AAAA=" + }, + { + "id" : -292 + }, + { + "id" : -275 + }, + { + "id" : -175 + }, + { + "id" : 128 + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : -134, + "damage" : 2 + }, + { + "id" : -133, + "damage" : 2 + }, + { + "id" : -133, + "damage" : 1 + }, + { + "id" : 347 + }, + { + "id" : 418 + }, + { + "id" : 419 + }, + { + "id" : 420 + }, + { + "id" : 383, + "damage" : 55 + }, + { + "id" : 383, + "damage" : 42 + }, + { + "id" : 330 + }, + { + "id" : 755 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCMAAAA=" + }, + { + "id" : 22 + }, + { + "id" : 155 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBQAAAA=" + }, + { + "id" : 383, + "damage" : 32 + }, + { + "id" : 383, + "damage" : 35 + }, + { + "id" : 159, + "damage" : 6 + }, + { + "id" : -170 + }, + { + "id" : -172 + }, + { + "id" : -132, + "damage" : 12 + }, + { + "id" : -132, + "damage" : 11 + }, + { + "id" : 323 + }, + { + "id" : 169 + }, + { + "id" : 513 + }, + { + "id" : 262, + "damage" : 43 + }, + { + "id" : 351, + "damage" : 8 + }, + { + "id" : 351, + "damage" : 16 + }, + { + "id" : 38, + "damage" : 10 + }, + { + "id" : 175 + }, + { + "id" : 441, + "damage" : 13 + }, + { + "id" : 441, + "damage" : 12 + }, + { + "id" : 441, + "damage" : 21 + }, + { + "id" : 1, + "damage" : 2 + }, + { + "id" : 441, + "damage" : 20 + }, + { + "id" : 153 + }, + { + "id" : -273 + }, + { + "id" : 266 + }, + { + "id" : 263 + }, + { + "id" : 129 + }, + { + "id" : 225 + }, + { + "id" : 220 + }, + { + "id" : 120 + }, + { + "id" : 224 + }, + { + "id" : 438, + "damage" : 32 + }, + { + "id" : 438, + "damage" : 31 + }, + { + "id" : 45 + }, + { + "id" : -284 + }, + { + "id" : 371 + }, + { + "id" : 288 + }, + { + "id" : 318 + }, + { + "id" : 355, + "damage" : 14 + }, + { + "id" : 355, + "damage" : 12 + }, + { + "id" : 85, + "damage" : 5 + }, + { + "id" : 241 + }, + { + "id" : 20 + }, + { + "id" : 262, + "damage" : 21 + }, + { + "id" : 262, + "damage" : 22 + }, + { + "id" : 507 + }, + { + "id" : 506 + }, + { + "id" : 503 + }, + { + "id" : 502 + }, + { + "id" : 113 + }, + { + "id" : 107 + }, + { + "id" : 183 + }, + { + "id" : 446, + "damage" : 2 + }, + { + "id" : 446, + "damage" : 10 + }, + { + "id" : 315 + }, + { + "id" : 307 + }, + { + "id" : 355, + "damage" : 5 + }, + { + "id" : 355, + "damage" : 13 + }, + { + "id" : -300 + }, + { + "id" : -247 + }, + { + "id" : -131, + "damage" : 4 + }, + { + "id" : -131 + }, + { + "id" : -298 + }, + { + "id" : 383, + "damage" : 34 + }, + { + "id" : 383, + "damage" : 48 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAoAAAA=" + }, + { + "id" : -246 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAoAAAA=" + }, + { + "id" : 91 + }, + { + "id" : 736 + }, + { + "id" : 373, + "damage" : 7 + }, + { + "id" : 373, + "damage" : 6 + }, + { + "id" : 373, + "damage" : 2 + }, + { + "id" : 373, + "damage" : 3 + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMAAAAAAAAA" + }, + { + "id" : 383, + "damage" : 25 + }, + { + "id" : 383, + "damage" : 26 + }, + { + "id" : 434, + "damage" : 6 + }, + { + "id" : 159, + "damage" : 8 + }, + { + "id" : 159, + "damage" : 7 + }, + { + "id" : -240 + }, + { + "id" : 351, + "damage" : 3 + }, + { + "id" : 351 + }, + { + "id" : -226 + }, + { + "id" : -7 + }, + { + "id" : 17, + "damage" : 3 + }, + { + "id" : -5 + }, + { + "id" : 17, + "damage" : 1 + }, + { + "id" : 300 + }, + { + "id" : 304 + }, + { + "id" : 438, + "damage" : 13 + }, + { + "id" : 438, + "damage" : 14 + }, + { + "id" : 467 + }, + { + "id" : 44, + "damage" : 4 + }, + { + "id" : 468 + }, + { + "id" : 159, + "damage" : 14 + }, + { + "id" : 159, + "damage" : 1 + }, + { + "id" : 262, + "damage" : 26 + }, + { + "id" : 262, + "damage" : 25 + }, + { + "id" : 351, + "damage" : 5 + }, + { + "id" : 351, + "damage" : 18 + }, + { + "id" : 69 + }, + { + "id" : 408 + }, + { + "id" : 76 + }, + { + "id" : 407 + }, + { + "id" : 438, + "damage" : 42 + }, + { + "id" : 44, + "damage" : 7 + }, + { + "id" : -166, + "damage" : 1 + }, + { + "id" : 44, + "damage" : 6 + }, + { + "id" : 218, + "damage" : 5 + }, + { + "id" : 438, + "damage" : 41 + }, + { + "id" : 438, + "damage" : 9 + }, + { + "id" : 218, + "damage" : 4 + }, + { + "id" : 163 + }, + { + "id" : 136 + }, + { + "id" : -201 + }, + { + "id" : 438, + "damage" : 10 + }, + { + "id" : 373, + "damage" : 20 + }, + { + "id" : -200 + }, + { + "id" : 139, + "damage" : 8 + }, + { + "id" : 139, + "damage" : 6 + }, + { + "id" : 373, + "damage" : 21 + }, + { + "id" : 441, + "damage" : 34 + }, + { + "id" : 441, + "damage" : 35 + }, + { + "id" : 241, + "damage" : 2 + }, + { + "id" : 241, + "damage" : 10 + }, + { + "id" : 475 + }, + { + "id" : 262, + "damage" : 39 + }, + { + "id" : 474 + }, + { + "id" : 262, + "damage" : 40 + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZA8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZA8AAAA=" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAYAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAYAAAA=" + }, + { + "id" : 361 + }, + { + "id" : 395, + "damage" : 2 + }, + { + "id" : 362 + }, + { + "id" : 35, + "damage" : 15 + }, + { + "id" : 35, + "damage" : 12 + }, + { + "id" : 329 + }, + { + "id" : 428 + }, + { + "id" : 383, + "damage" : 123 + }, + { + "id" : 429 + }, + { + "id" : 477 + }, + { + "id" : 383, + "damage" : 126 + }, + { + "id" : 382 + }, + { + "id" : -216 + }, + { + "id" : 175, + "damage" : 5 + }, + { + "id" : -212, + "damage" : 4 }, { "id" : 402, - "damage" : 3, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IyVIP/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "damage" : 8, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3JST0f/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { "id" : 402, - "damage" : 11, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3I92P7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IhHR3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : 402, - "damage" : 10, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Ifx4D/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : -212, + "damage" : 12 }, { - "id" : 402, - "damage" : 2, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IWfF7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : -131, + "damage" : 10 }, { - "id" : 402, - "damage" : 6, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KcnBb/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "id" : -131, + "damage" : 8 + }, + { + "id" : 13 + }, + { + "id" : 1, + "damage" : 1 + }, + { + "id" : 446, + "damage" : 13 + }, + { + "id" : 446, + "damage" : 9 + }, + { + "id" : -132, + "damage" : 4 + }, + { + "id" : -132, + "damage" : 8 + }, + { + "id" : 122 + }, + { + "id" : -159 + }, + { + "id" : 236, + "damage" : 1 + }, + { + "id" : 236, + "damage" : 14 + }, + { + "id" : 168 + }, + { + "id" : 155, + "damage" : 3 + }, + { + "id" : 262, + "damage" : 7 + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCQAAAA=" + }, + { + "id" : -304 + }, + { + "id" : 262, + "damage" : 8 + }, + { + "id" : 98 + }, + { + "id" : 368 + }, + { + "id" : 341 + }, + { + "id" : 267 + }, + { + "id" : 283 + }, + { + "id" : 44, + "damage" : 5 + }, + { + "id" : -166 + }, + { + "id" : 265 + }, + { + "id" : 452 + }, + { + "id" : 438, + "damage" : 28 + }, + { + "id" : 438, + "damage" : 27 + }, + { + "id" : 235 + }, + { + "id" : 232 + }, + { + "id" : 365 + }, + { + "id" : 78 + }, + { + "id" : -151 + }, + { + "id" : -154 } ] } \ No newline at end of file diff --git a/connector/src/main/resources/bedrock/items.json b/connector/src/main/resources/bedrock/items.json index 87f85187b..0614b3641 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 From 5b147f8dd1775d948ec85aaf77d26fdea00a58d6 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 27 Jun 2020 06:58:52 +0100 Subject: [PATCH 038/104] Fix en_us locale downloading (#809) Fixes occasional inventories not working because of being unable to read the locale. --- .../geysermc/connector/utils/LocaleUtils.java | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) 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 e213fe6cc..787525913 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java @@ -28,6 +28,7 @@ package org.geysermc.connector.utils; 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; @@ -35,7 +36,10 @@ 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 { @@ -70,7 +74,7 @@ public class LocaleUtils { // 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; } @@ -84,14 +88,11 @@ public class LocaleUtils { // 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"); @@ -160,7 +161,7 @@ public class LocaleUtils { * @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()) { @@ -212,21 +213,21 @@ public class LocaleUtils { // Load in the JAR as a zip and extract the file ZipFile localeJar = new ZipFile(tmpFilePath.toString()); - InputStream inputStream = localeJar.getInputStream(localeJar.getEntry("assets/minecraft/lang/en_us.json")); - FileOutputStream outputStream = new FileOutputStream(localeFile); + 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 @@ -357,4 +358,4 @@ class Asset { @JsonProperty("size") private int size; -} +} \ No newline at end of file From 75f470cb333997c0ec1a6975df80daf25f31e101 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sat, 27 Jun 2020 11:35:02 -0400 Subject: [PATCH 039/104] Fix creative items --- .../geysermc/connector/network/session/GeyserSession.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 03d124289..353d944e6 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 @@ -225,9 +225,10 @@ public class GeyserSession implements CommandSender { entityPacket.setTag(EntityIdentifierRegistry.ENTITY_IDENTIFIERS); upstream.sendPacket(entityPacket); - InventoryContentPacket creativePacket = new InventoryContentPacket(); - creativePacket.setContainerId(ContainerId.CREATIVE); //TODO: Why is this deprecated? - creativePacket.setContents(ItemRegistry.CREATIVE_ITEMS); + CreativeContentPacket creativePacket = new CreativeContentPacket(); + for (int i = 0; i < ItemRegistry.CREATIVE_ITEMS.length; i++) { + creativePacket.getEntries().put(i, ItemRegistry.CREATIVE_ITEMS[i]); + } upstream.sendPacket(creativePacket); PlayStatusPacket playStatusPacket = new PlayStatusPacket(); From 7743f6d71854dfcb73808c3b2f8d95aa9937cff1 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sat, 27 Jun 2020 16:36:48 +0100 Subject: [PATCH 040/104] Add dump command (#808) * Add dump command Adds a command to collect and dump infomation about the Geyser install and bootstrap and submit it to a dumps site. * Finalize URL; misc. fixes; add 'architecture' param Co-authored-by: DoctorMacc --- .../bungeecord/GeyserBungeeDumpInfo.java | 63 +++++++++ .../bungeecord/GeyserBungeePlugin.java | 6 + .../platform/spigot/GeyserSpigotDumpInfo.java | 62 +++++++++ .../platform/spigot/GeyserSpigotPlugin.java | 5 + .../platform/sponge/GeyserSpongeDumpInfo.java | 63 +++++++++ .../platform/sponge/GeyserSpongePlugin.java | 6 + .../standalone/GeyserStandaloneBootstrap.java | 6 + .../velocity/GeyserVelocityDumpInfo.java | 63 +++++++++ .../velocity/GeyserVelocityPlugin.java | 6 + .../common/serializer/AsteriskSerializer.java | 76 +++++++++++ connector/pom.xml | 5 + .../connector/bootstrap/GeyserBootstrap.java | 8 ++ .../connector/command/CommandManager.java | 1 + .../command/defaults/DumpCommand.java | 93 +++++++++++++ .../GeyserJacksonConfiguration.java | 7 +- .../connector/dump/BootstrapDumpInfo.java | 63 +++++++++ .../org/geysermc/connector/dump/DumpInfo.java | 125 ++++++++++++++++++ .../geysermc/connector/utils/DockerCheck.java | 15 +++ .../geysermc/connector/utils/WebUtils.java | 32 ++++- 19 files changed, 699 insertions(+), 6 deletions(-) create mode 100644 bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeDumpInfo.java create mode 100644 bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotDumpInfo.java create mode 100644 bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeDumpInfo.java create mode 100644 bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityDumpInfo.java create mode 100644 common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java create mode 100644 connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java create mode 100644 connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java create mode 100644 connector/src/main/java/org/geysermc/connector/dump/DumpInfo.java 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 000000000..547011162 --- /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/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java index 1cf519c0e..ec267924f 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 @@ -35,6 +35,7 @@ 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; @@ -140,4 +141,9 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { public Path getConfigFolder() { return getDataFolder().toPath(); } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserBungeeDumpInfo(getProxy()); + } } 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 000000000..01d513fa8 --- /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/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index fd05131a7..7fc493487 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -32,6 +32,7 @@ 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; @@ -192,4 +193,8 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { return temp; } + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserSpigotDumpInfo(); + } } 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 000000000..e8f0feaef --- /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/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java index c5f13b581..abf27749c 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 @@ -34,6 +34,7 @@ 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; @@ -162,4 +163,9 @@ public class GeyserSpongePlugin implements GeyserBootstrap { public void onServerStop(GameStoppedEvent event) { onDisable(); } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserSpongeDumpInfo(); + } } 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 0fca35038..c0afd8840 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 @@ -30,6 +30,7 @@ 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; @@ -108,4 +109,9 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { // Return the current working directory return Paths.get(System.getProperty("user.dir")); } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new BootstrapDumpInfo(); + } } 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 000000000..906a04142 --- /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/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java index 5abf3c230..1116fb8c8 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 @@ -39,6 +39,7 @@ import org.geysermc.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; @@ -153,4 +154,9 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { public void onShutdown(ProxyShutdownEvent event) { onDisable(); } + + @Override + public BootstrapDumpInfo getDumpInfo() { + return new GeyserVelocityDumpInfo(proxyServer); + } } diff --git a/common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java b/common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java new file mode 100644 index 000000000..9772a8e31 --- /dev/null +++ b/common/src/main/java/org/geysermc/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.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/pom.xml b/connector/pom.xml index eaa2801e9..9526c840d 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -170,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/bootstrap/GeyserBootstrap.java b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java index 8683f80cd..f089350fb 100644 --- a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java +++ b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java @@ -26,6 +26,7 @@ package org.geysermc.connector.bootstrap; +import org.geysermc.connector.dump.BootstrapDumpInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserLogger; @@ -92,4 +93,11 @@ public interface GeyserBootstrap { * @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 8b1d0bc78..217a9df1f 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 abstract class CommandManager { 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) { 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 000000000..4dbb3bb37 --- /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.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/configuration/GeyserJacksonConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java index 576e5ed0d..0e203231a 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java @@ -30,6 +30,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; +import org.geysermc.common.serializer.AsteriskSerializer; import java.nio.file.Path; import java.util.Map; @@ -111,16 +112,16 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration @Setter private int port; - private String motd1; - private String motd2; - @JsonProperty("auth-type") private String authType; } @Getter public static class UserAuthenticationInfo implements IUserAuthenticationInfo { + @AsteriskSerializer.Asterisk() private String email; + + @AsteriskSerializer.Asterisk() private String password; } 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 000000000..dbcfba819 --- /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.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 000000000..6d4b83db8 --- /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/utils/DockerCheck.java b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java index 0a5a2278c..09c78da92 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 class DockerCheck { } } 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/WebUtils.java b/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java index 50ab76d0b..7a1a0215f 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 class WebUtils { 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(); + } } From 3cd85ed76f819aebec3aad9daf8083ffcf4249d5 Mon Sep 17 00:00:00 2001 From: toinouH <64892431+toinouH@users.noreply.github.com> Date: Sat, 27 Jun 2020 18:06:57 +0200 Subject: [PATCH 041/104] Update README.md (#811) Versions of Java and Bedrock Edition supported updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b8f8749b8..5cf34473d 100644 --- a/README.md +++ b/README.md @@ -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. From dd1747cae9257854e5a93d7a88524750a7a36cb5 Mon Sep 17 00:00:00 2001 From: Tim203 Date: Sat, 27 Jun 2020 23:47:52 +0200 Subject: [PATCH 042/104] Updated the mappings and fixed building --- .gitmodules | 1 + connector/pom.xml | 10 +++++----- connector/src/main/resources/mappings | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitmodules b/.gitmodules index 0090e64ab..207825e83 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/connector/pom.xml b/connector/pom.xml index 9526c840d..76e02e2aa 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -31,9 +31,9 @@ compile - com.nukkitx.protocol + com.github.bundabrg.Protocol bedrock-v407 - 2.6.0-SNAPSHOT + feature~1.16-protocol-SNAPSHOT compile @@ -103,9 +103,9 @@ compile - com.github.steveice10 - mcprotocollib - 1.16.1-SNAPSHOT + com.github.GeyserMC + MCProtocolLib + feature~1.16-SNAPSHOT compile diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 469c44151..22f98579c 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 469c44151dca60a7e87711132927544df20312af +Subproject commit 22f98579c0ef0ed6f8d768393e4af478a76db40e From 8f763dfc5f114b794fce4b2c84992222c00e75b2 Mon Sep 17 00:00:00 2001 From: Tim203 Date: Sun, 28 Jun 2020 00:27:00 +0200 Subject: [PATCH 043/104] Move common stuff used only by connector and bootstrap to connector --- .../platform/bungeecord/GeyserBungeeMain.java | 2 +- .../GeyserBungeePingPassthrough.java | 2 +- .../bungeecord/GeyserBungeePlugin.java | 2 +- .../platform/spigot/GeyserSpigotMain.java | 2 +- .../spigot/GeyserSpigotPingPassthrough.java | 2 +- .../platform/spigot/GeyserSpigotPlugin.java | 2 +- .../platform/sponge/GeyserSpongeMain.java | 2 +- .../sponge/GeyserSpongePingPassthrough.java | 2 +- .../platform/sponge/GeyserSpongePlugin.java | 2 +- .../command/GeyserSpongeCommandExecutor.java | 2 +- .../standalone/GeyserStandaloneBootstrap.java | 2 +- .../standalone/GeyserStandaloneLogger.java | 2 +- .../platform/standalone/LoopbackUtil.java | 2 +- .../platform/velocity/GeyserVelocityMain.java | 2 +- .../GeyserVelocityPingPassthrough.java | 3 +- .../velocity/GeyserVelocityPlugin.java | 2 +- .../GeyserVelocityCommandExecutor.java | 2 +- .../java/org/geysermc/common/AuthType.java | 33 ----------- .../org/geysermc/common/PlatformType.java | 17 ------ .../geysermc/connector/GeyserConnector.java | 4 +- .../command/defaults/DumpCommand.java | 2 +- .../command/defaults/HelpCommand.java | 2 +- .../command/defaults/ListCommand.java | 2 +- .../command/defaults/ReloadCommand.java | 4 +- .../command/defaults/StopCommand.java | 2 +- .../geysermc/connector/common/AuthType.java | 59 +++++++++++++++++++ .../geysermc/connector}/common/ChatColor.java | 37 ++++++------ .../connector/common/PlatformType.java | 43 ++++++++++++++ .../connector}/common/main/IGeyserMain.java | 2 +- .../common/ping/GeyserPingInfo.java | 2 +- .../common/serializer/AsteriskSerializer.java | 2 +- .../GeyserJacksonConfiguration.java | 2 +- .../connector/dump/BootstrapDumpInfo.java | 2 +- .../network/ConnectorServerEventHandler.java | 2 +- .../connector/network/QueryPacketHandler.java | 2 +- .../network/UpstreamPacketHandler.java | 2 +- .../network/session/GeyserSession.java | 3 +- .../BedrockCommandRequestTranslator.java | 2 +- .../bedrock/BedrockMovePlayerTranslator.java | 2 +- .../java/world/JavaBlockChangeTranslator.java | 2 +- .../ping/GeyserLegacyPingPassthrough.java | 2 +- .../ping/IGeyserPingPassthrough.java | 2 +- .../connector/utils/InventoryUtils.java | 3 +- .../geysermc/connector/utils/SkinUtils.java | 2 +- 44 files changed, 162 insertions(+), 112 deletions(-) delete mode 100644 common/src/main/java/org/geysermc/common/AuthType.java delete mode 100644 common/src/main/java/org/geysermc/common/PlatformType.java create mode 100644 connector/src/main/java/org/geysermc/connector/common/AuthType.java rename {common/src/main/java/org/geysermc => connector/src/main/java/org/geysermc/connector}/common/ChatColor.java (75%) create mode 100644 connector/src/main/java/org/geysermc/connector/common/PlatformType.java rename {common/src/main/java/org/geysermc => connector/src/main/java/org/geysermc/connector}/common/main/IGeyserMain.java (98%) rename {common/src/main/java/org/geysermc => connector/src/main/java/org/geysermc/connector}/common/ping/GeyserPingInfo.java (97%) rename {common/src/main/java/org/geysermc => connector/src/main/java/org/geysermc/connector}/common/serializer/AsteriskSerializer.java (98%) 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 eabbcc698..999b29eaf 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 c7f8f2762..ab4000520 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.connection.PendingConnection; 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 ec267924f..ac718cbae 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,7 +30,7 @@ import net.md_5.bungee.api.plugin.Plugin; 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.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java index dbc660391..15826d334 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotMain.java @@ -26,7 +26,7 @@ package org.geysermc.platform.spigot; -import org.geysermc.common.main.IGeyserMain; +import org.geysermc.connector.common.main.IGeyserMain; public class GeyserSpigotMain extends IGeyserMain { diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java index 6651adab9..07999d876 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java @@ -31,7 +31,7 @@ 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; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index 7fc493487..de2b7186c 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -27,7 +27,7 @@ package org.geysermc.platform.spigot; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; 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 11b9583f9..1c9605d0a 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 31b6dc7fb..99e8ed2f2 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 abf27749c..4214255e8 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,7 +29,7 @@ import com.google.inject.Inject; 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.common.PlatformType; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; 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 91cb59b0f..8f857b665 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 @@ package org.geysermc.platform.sponge.command; 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 c0afd8840..3fb561a1d 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,7 +25,7 @@ package org.geysermc.platform.standalone; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.configuration.GeyserConfiguration; 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 7102d206e..ae7f18718 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 lombok.extern.log4j.Log4j2; 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; 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 03c49705d..00ff14de7 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.Files; 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/src/main/java/org/geysermc/platform/velocity/GeyserVelocityMain.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityMain.java index 73eaddf09..b5c79cc2b 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 01be949b8..934c57740 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.InboundConnection; 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 1116fb8c8..f00119ca9 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 @@ -35,7 +35,7 @@ import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.proxy.ProxyServer; import lombok.Getter; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; 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 940c52244..4632f4404 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 lombok.AllArgsConstructor; 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 8edbc4d55..000000000 --- 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 29b2fce96..000000000 --- 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 { - - BUNGEECORD("BungeeCord"), - SPIGOT("Spigot"), - SPONGE("Sponge"), - STANDALONE("Standalone"), - VELOCITY("Velocity"); - - private String platformName; -} diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index bdd7e74c7..20a771266 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -32,8 +32,8 @@ import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.v407.Bedrock_v407; import lombok.Getter; import lombok.Setter; -import org.geysermc.common.AuthType; -import org.geysermc.common.PlatformType; +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; 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 index 4dbb3bb37..617c9d436 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java @@ -29,7 +29,7 @@ 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.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/HelpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java index 6acb7822b..a5942ee6b 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 21fa42535..99845ee94 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 c38a0c23d..2ddd61ed8 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 2222cdef5..636058a02 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 000000000..f15e3ff58 --- /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 8868b063c..1397f88cf 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 000000000..ee68b6d7b --- /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 75da4e6b9..906bd7865 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 40ef6da62..69b24ea1e 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/common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java b/connector/src/main/java/org/geysermc/connector/common/serializer/AsteriskSerializer.java similarity index 98% rename from common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java rename to connector/src/main/java/org/geysermc/connector/common/serializer/AsteriskSerializer.java index 9772a8e31..3fac2e08a 100644 --- a/common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java +++ b/connector/src/main/java/org/geysermc/connector/common/serializer/AsteriskSerializer.java @@ -24,7 +24,7 @@ * */ -package org.geysermc.common.serializer; +package org.geysermc.connector.common.serializer; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.core.JsonGenerator; diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java index 0e203231a..867de9adf 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java @@ -30,7 +30,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; -import org.geysermc.common.serializer.AsteriskSerializer; +import org.geysermc.connector.common.serializer.AsteriskSerializer; import java.nio.file.Path; import java.util.Map; diff --git a/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java b/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java index dbcfba819..04495b49e 100644 --- a/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java +++ b/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java @@ -28,7 +28,7 @@ package org.geysermc.connector.dump; import lombok.AllArgsConstructor; import lombok.Getter; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import java.util.List; 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 abff44e58..11ff9a029 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -31,7 +31,7 @@ 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.common.ping.GeyserPingInfo; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.network.session.GeyserSession; 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 0e9fe5035..ba654c75b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java @@ -29,7 +29,7 @@ package org.geysermc.connector.network; 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; 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 5a40b2467..79dcf1385 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -27,7 +27,7 @@ package org.geysermc.connector.network; import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.packet.*; -import org.geysermc.common.AuthType; +import org.geysermc.connector.common.AuthType; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; 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 353d944e6..101726f17 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 @@ -45,7 +45,6 @@ import com.nukkitx.math.vector.*; import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.*; -import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -53,7 +52,7 @@ 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.connector.common.AuthType; import org.geysermc.common.window.FormWindow; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java index 1f31367c3..d05a667d0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java @@ -25,7 +25,7 @@ package org.geysermc.connector.network.translators.bedrock; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.network.session.GeyserSession; 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 d70b21423..0abf81505 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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java index 50705ae22..9e81ce59d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaBlockChangeTranslator.java @@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.data.SoundEvent; import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; -import org.geysermc.common.PlatformType; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; 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 54978d5f4..1c4d26d0b 100644 --- a/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java +++ b/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java @@ -33,7 +33,7 @@ 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.common.ping.GeyserPingInfo; import org.geysermc.connector.GeyserConnector; import java.util.concurrent.TimeUnit; 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 7bc842dfb..35c8058ef 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/InventoryUtils.java b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java index 0e5c13fc0..627c25dc3 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -31,9 +31,8 @@ import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; -import com.nukkitx.protocol.bedrock.packet.ContainerClosePacket; 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; 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 e93388c47..ae17ed205 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -33,7 +33,7 @@ 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; From 2e0eb6dfb7126115b80d778569b28c4f47c21738 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 27 Jun 2020 15:26:16 -0800 Subject: [PATCH 044/104] Fix creative item list --- .../resources/bedrock/creative_items.json | 7762 ++++++++--------- 1 file changed, 3881 insertions(+), 3881 deletions(-) diff --git a/connector/src/main/resources/bedrock/creative_items.json b/connector/src/main/resources/bedrock/creative_items.json index 9765ff551..eea92a950 100644 --- a/connector/src/main/resources/bedrock/creative_items.json +++ b/connector/src/main/resources/bedrock/creative_items.json @@ -1,273 +1,5 @@ { "items" : [ - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAMAAAA=" - }, - { - "id" : 171, - "damage" : 9 - }, - { - "id" : 97, - "damage" : 1 - }, - { - "id" : 373, - "damage" : 37 - }, - { - "id" : 373, - "damage" : 36 - }, - { - "id" : 171, - "damage" : 13 - }, - { - "id" : 97 - }, - { - "id" : 52 - }, - { - "id" : 375 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAMAAAA=" - }, - { - "id" : 97, - "damage" : 2 - }, - { - "id" : 97, - "damage" : 3 - }, - { - "id" : 373, - "damage" : 35 - }, - { - "id" : 373, - "damage" : 34 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAIAAAA=" - }, - { - "id" : 373, - "damage" : 38 - }, - { - "id" : 373, - "damage" : 39 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAEAAAA=" - }, - { - "id" : 171, - "damage" : 2 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAMAAAA=" - }, - { - "id" : 171, - "damage" : 10 - }, - { - "id" : 373, - "damage" : 33 - }, - { - "id" : 171, - "damage" : 14 - }, - { - "id" : 171, - "damage" : 1 - }, - { - "id" : 373, - "damage" : 32 - }, - { - "id" : 237 - }, - { - "id" : 171, - "damage" : 6 - }, - { - "id" : 171, - "damage" : 11 - }, - { - "id" : 171, - "damage" : 3 - }, - { - "id" : 171, - "damage" : 12 - }, - { - "id" : 171, - "damage" : 15 - }, - { - "id" : 171, - "damage" : 4 - }, - { - "id" : 171, - "damage" : 5 - }, - { - "id" : 171, - "damage" : 8 - }, - { - "id" : 383, - "damage" : 122 - }, - { - "id" : 438, - "damage" : 2 - }, - { - "id" : 373, - "damage" : 29 - }, - { - "id" : 383, - "damage" : 10 - }, - { - "id" : 373, - "damage" : 28 - }, - { - "id" : 344 - }, - { - "id" : 338 - }, - { - "id" : 237, - "damage" : 12 - }, - { - "id" : 237, - "damage" : 15 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAAAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAEAAAA=" - }, - { - "id" : 438, - "damage" : 6 - }, - { - "id" : 438, - "damage" : 1 - }, - { - "id" : 373, - "damage" : 40 - }, - { - "id" : 373, - "damage" : 41 - }, - { - "id" : 438, - "damage" : 5 - }, - { - "id" : 383, - "damage" : 13 - }, - { - "id" : 97, - "damage" : 5 - }, - { - "id" : 97, - "damage" : 4 - }, - { - "id" : 383, - "damage" : 14 - }, - { - "id" : 100, - "damage" : 14 - }, - { - "id" : 99, - "damage" : 14 - }, - { - "id" : 352 - }, - { - "id" : 30 - }, { "id" : 5 }, @@ -277,19 +9,25 @@ }, { "id" : 5, - "damage" : 5 + "damage" : 2 + }, + { + "id" : 5, + "damage" : 3 }, { "id" : 5, "damage" : 4 }, { - "id" : 139, + "id" : 5, "damage" : 5 }, { - "id" : 139, - "damage" : 4 + "id" : -242 + }, + { + "id" : -243 }, { "id" : 139 @@ -299,447 +37,58 @@ "damage" : 1 }, { - "id" : 39 + "id" : 139, + "damage" : 2 }, { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAcAAAA=" + "id" : 139, + "damage" : 3 }, { - "id" : 237, - "damage" : 13 - }, - { - "id" : 237, - "damage" : 9 - }, - { - "id" : 373, - "damage" : 18 - }, - { - "id" : 373, - "damage" : 19 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAcAAAA=" - }, - { - "id" : 438, - "damage" : 8 - }, - { - "id" : 438, - "damage" : 7 - }, - { - "id" : 237, + "id" : 139, "damage" : 4 }, { - "id" : 237, + "id" : 139, "damage" : 5 }, { - "id" : 340 - }, - { - "id" : 208 - }, - { - "id" : 426 - }, - { - "id" : 339 - }, - { - "id" : 383, - "damage" : 30 - }, - { - "id" : 383, - "damage" : 29 - }, - { - "id" : 383, - "damage" : 18 - }, - { - "id" : 383, - "damage" : 19 - }, - { - "id" : 373, - "damage" : 17 - }, - { - "id" : 373, - "damage" : 24 - }, - { - "id" : 373, - "damage" : 25 - }, - { - "id" : 373, - "damage" : 16 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAgAAAA=" - }, - { - "id" : 171 - }, - { - "id" : 35, - "damage" : 13 - }, - { - "id" : 35, - "damage" : 4 - }, - { - "id" : 35, - "damage" : 5 - }, - { - "id" : 35, - "damage" : 6 - }, - { - "id" : 35, - "damage" : 9 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAoAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAoAAAA=" - }, - { - "id" : 237, - "damage" : 8 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAQAAAA=" - }, - { - "id" : 171, - "damage" : 7 - }, - { - "id" : 236, - "damage" : 8 - }, - { - "id" : 437 - }, - { - "id" : 373, - "damage" : 10 - }, - { - "id" : 373, - "damage" : 11 - }, - { - "id" : -222 - }, - { - "id" : 35 - }, - { - "id" : 373, - "damage" : 27 - }, - { - "id" : 373, - "damage" : 26 - }, - { - "id" : 376 - }, - { - "id" : 237, - "damage" : 7 - }, - { - "id" : 383, + "id" : 139, "damage" : 12 }, { - "id" : 383, - "damage" : 11 - }, - { - "id" : 438, - "damage" : 16 - }, - { - "id" : 438, - "damage" : 15 - }, - { - "id" : 383, - "damage" : 111 - }, - { - "id" : 383, - "damage" : 27 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAAAAAA=" - }, - { - "id" : 236, + "id" : 139, "damage" : 7 }, { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAEAAAA=" - }, - { - "id" : 438 - }, - { - "id" : 373, - "damage" : 42 - }, - { - "id" : 5, - "damage" : 2 - }, - { - "id" : 5, - "damage" : 3 + "id" : 139, + "damage" : 8 }, { "id" : 139, - "damage" : 3 - }, - { - "id" : 139, - "damage" : 2 - }, - { - "id" : 438, - "damage" : 24 - }, - { - "id" : 438, - "damage" : 23 - }, - { - "id" : 85, - "damage" : 2 - }, - { - "id" : 85, - "damage" : 1 + "damage" : 6 }, { "id" : 139, "damage" : 9 }, - { - "id" : 353 - }, - { - "id" : 367 - }, { "id" : 139, "damage" : 13 }, { - "id" : 289 - }, - { - "id" : -228 - }, - { - "id" : -229 - }, - { - "id" : 423 - }, - { - "id" : 411 - }, - { - "id" : 80 - }, - { - "id" : 79 - }, - { - "id" : 383, - "damage" : 74 - }, - { - "id" : 111 - }, - { - "id" : -287 - }, - { - "id" : -233 - }, - { - "id" : 383, - "damage" : 113 - }, - { - "id" : 383, - "damage" : 33 - }, - { - "id" : 383, - "damage" : 121 - }, - { - "id" : -232 - }, - { - "id" : 383, - "damage" : 109 - }, - { - "id" : 383, - "damage" : 31 - }, - { - "id" : 236, + "id" : 139, "damage" : 10 }, { - "id" : 236, - "damage" : 2 - }, - { - "id" : 236, - "damage" : 9 - }, - { - "id" : 236, - "damage" : 3 - }, - { - "id" : 236, + "id" : 139, "damage" : 11 }, { - "id" : 236, - "damage" : 13 + "id" : -277 }, { - "id" : 383, - "damage" : 112 - }, - { - "id" : -236 - }, - { - "id" : 383, - "damage" : 108 - }, - { - "id" : -235 - }, - { - "id" : -234 - }, - { - "id" : -270 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA8AAAA=" - }, - { - "id" : 444 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA4AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAwAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAwAAAA=" - }, - { - "id" : 450 - }, - { - "id" : 384 - }, - { - "id" : 373, - "damage" : 1 - }, - { - "id" : 374 - }, - { - "id" : 409 - }, - { - "id" : 373 - }, - { - "id" : 405 - }, - { - "id" : 438, - "damage" : 17 - }, - { - "id" : 455 - }, - { - "id" : 469 - }, - { - "id" : 438, - "damage" : 33 - }, - { - "id" : 373, - "damage" : 13 + "id" : -297 }, { "id" : -278 @@ -748,1008 +97,27 @@ "id" : 85 }, { - "id" : 377 - }, - { - "id" : 378 - }, - { - "id" : 438, - "damage" : 18 - }, - { - "id" : 236 - }, - { - "id" : -227 - }, - { - "id" : 237, - "damage" : 6 - }, - { - "id" : 112 - }, - { - "id" : 82 - }, - { - "id" : 236, - "damage" : 6 - }, - { - "id" : 185 - }, - { - "id" : 184 - }, - { - "id" : -259 - }, - { - "id" : -258 - }, - { - "id" : 388 - }, - { - "id" : 406 - }, - { - "id" : 414 - }, - { - "id" : 415 - }, - { - "id" : 438, - "damage" : 22 - }, - { - "id" : 438, - "damage" : 21 - }, - { - "id" : 139, - "damage" : 11 - }, - { - "id" : 139, - "damage" : 10 - }, - { - "id" : 438, - "damage" : 38 - }, - { - "id" : 106 - }, - { - "id" : 32 - }, - { - "id" : 438, - "damage" : 37 - }, - { - "id" : -231 - }, - { - "id" : 349 - }, - { - "id" : 438, - "damage" : 34 - }, - { - "id" : -163 - }, - { - "id" : 460 - }, - { - "id" : 383, - "damage" : 75 - }, - { - "id" : 351, - "damage" : 11 - }, - { - "id" : 351, - "damage" : 14 - }, - { - "id" : 40 - }, - { - "id" : 383, - "damage" : 40 - }, - { - "id" : 351, - "damage" : 17 - }, - { - "id" : 159, - "damage" : 13 - }, - { - "id" : 159, - "damage" : 9 - }, - { - "id" : 383, - "damage" : 28 - }, - { - "id" : 383, - "damage" : 22 - }, - { - "id" : 351, + "id" : 85, "damage" : 1 }, { - "id" : 237, - "damage" : 11 - }, - { - "id" : 237, - "damage" : 3 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAkAAAA=" - }, - { - "id" : 383, - "damage" : 16 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAkAAAA=" - }, - { - "id" : 259 - }, - { - "id" : 359 - }, - { - "id" : 373, - "damage" : 15 - }, - { - "id" : 237, + "id" : 85, "damage" : 2 }, { - "id" : 214 - }, - { - "id" : 216 - }, - { - "id" : 383, - "damage" : 17 - }, - { - "id" : 237, - "damage" : 10 - }, - { - "id" : 383, - "damage" : 110 - }, - { - "id" : 373, - "damage" : 14 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBIAAAA=" - }, - { - "id" : 757 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAkAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAkAAAA=" - }, - { - "id" : 332 - }, - { - "id" : 373, - "damage" : 12 - }, - { - "id" : 383, - "damage" : 45 - }, - { - "id" : 35, - "damage" : 2 - }, - { - "id" : 35, - "damage" : 11 - }, - { - "id" : 35, + "id" : 85, "damage" : 3 }, { - "id" : 35, - "damage" : 10 - }, - { - "id" : -242 - }, - { - "id" : 441, - "damage" : 8 - }, - { - "id" : -243 - }, - { - "id" : 441, - "damage" : 9 - }, - { - "id" : -297 - }, - { - "id" : -277 - }, - { - "id" : 438, - "damage" : 19 - }, - { - "id" : 438, - "damage" : 20 - }, - { - "id" : 438, - "damage" : 3 - }, - { - "id" : 180 - }, - { - "id" : 438, + "id" : 85, "damage" : 4 }, { - "id" : -177 - }, - { - "id" : 373, - "damage" : 30 - }, - { - "id" : 373, - "damage" : 31 - }, - { - "id" : 386 - }, - { - "id" : 187 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAAAAAA=" - }, - { - "id" : 186 - }, - { - "id" : 41 - }, - { - "id" : 42 - }, - { - "id" : 385 - }, - { - "id" : 159, - "damage" : 11 - }, - { - "id" : 369 - }, - { - "id" : 159, - "damage" : 3 - }, - { - "id" : 337 - }, - { - "id" : 336 - }, - { - "id" : 138 - }, - { - "id" : -206 - }, - { - "id" : 438, - "damage" : 36 - }, - { - "id" : 438, - "damage" : 35 - }, - { - "id" : 462 - }, - { - "id" : 461 - }, - { - "id" : 114 - }, - { - "id" : -184 - }, - { - "id" : 179, - "damage" : 3 - }, - { - "id" : 179, - "damage" : 2 - }, - { - "id" : 233 - }, - { - "id" : 229 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBcAAAA=" - }, - { - "id" : 441, - "damage" : 14 - }, - { - "id" : 441, - "damage" : 15 - }, - { - "id" : 325, + "id" : 85, "damage" : 5 }, { - "id" : 325, - "damage" : 4 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBkAAAA=" - }, - { - "id" : 38, - "damage" : 9 - }, - { - "id" : 393 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBgAAAA=" - }, - { - "id" : 463 - }, - { - "id" : 413 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBkAAAA=" - }, - { - "id" : 297 - }, - { - "id" : 38, - "damage" : 2 - }, - { - "id" : 38, - "damage" : 3 - }, - { - "id" : 38, - "damage" : 8 - }, - { - "id" : -185 - }, - { - "id" : 203 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBoAAAA=" - }, - { - "id" : 402, - "damage" : 7, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KXnZ3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBUAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBYAAAA=" - }, - { - "id" : 402, - "damage" : 10, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Ifx4D/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : -173 - }, - { - "id" : -171 - }, - { - "id" : 402, - "damage" : 11, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3I92P7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 88 - }, - { - "id" : 402, - "damage" : 4, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KqRDz/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 383, - "damage" : 118 - }, - { - "id" : 383, - "damage" : 114 - }, - { - "id" : 383, - "damage" : 59 - }, - { - "id" : 7 - }, - { - "id" : 402, - "damage" : 15, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Lw8PD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 402, - "damage" : 1, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3ImLrD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 383, - "damage" : 41 - }, - { - "id" : 383, - "damage" : 43 - }, - { - "id" : 383, - "damage" : 104 - }, - { - "id" : 383, - "damage" : 115 - }, - { - "id" : 383, - "damage" : 105 - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : -169 - }, - { - "id" : -176 - }, - { - "id" : 228 - }, - { - "id" : 227 - }, - { - "id" : -197 - }, - { - "id" : -157 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZBMAAAA=" - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZBMAAAA=" - }, - { - "id" : 441, - "damage" : 23 - }, - { - "id" : 441, - "damage" : 22 - }, - { - "id" : 133 - }, - { - "id" : 175, - "damage" : 4 - }, - { - "id" : 351, - "damage" : 19 - }, - { - "id" : 155, - "damage" : 2 - }, - { - "id" : 57 - }, - { - "id" : 175, - "damage" : 1 - }, - { - "id" : 351, - "damage" : 7 - }, - { - "id" : 366 - }, - { - "id" : 320 - }, - { - "id" : 155, - "damage" : 1 - }, - { - "id" : 262, - "damage" : 42 - }, - { - "id" : 262, - "damage" : 41 - }, - { - "id" : 263, - "damage" : 1 - }, - { - "id" : 264 - }, - { - "id" : 737 - }, - { - "id" : 221 - }, - { - "id" : 234 - }, - { - "id" : 389 - }, - { - "id" : 441, - "damage" : 18 - }, - { - "id" : 159, - "damage" : 2 - }, - { - "id" : 168, - "damage" : 2 - }, - { - "id" : -274 - }, - { - "id" : 159, - "damage" : 10 - }, - { - "id" : 441, - "damage" : 19 - }, - { - "id" : 441, - "damage" : 11 - }, - { - "id" : 441, - "damage" : 10 - }, - { - "id" : 742 - }, - { - "id" : 752 - }, - { - "id" : 345 - }, - { - "id" : 395 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB8AAAA=" - }, - { - "id" : 383, - "damage" : 50 - }, - { - "id" : 383, - "damage" : 49 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBIAAAA=" - }, - { - "id" : 159, - "damage" : 4 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBIAAAA=" - }, - { - "id" : 159, - "damage" : 5 - }, - { - "id" : 19, - "damage" : 1 - }, - { - "id" : 19 - }, - { - "id" : -239 - }, - { - "id" : 170 - }, - { - "id" : 164 - }, - { - "id" : 753 - }, - { - "id" : 476 - }, - { - "id" : 109 - }, - { - "id" : 262, - "damage" : 37 - }, - { - "id" : 262, - "damage" : 38 - }, - { - "id" : -131, - "damage" : 12 - }, - { - "id" : -134, - "damage" : 4 - }, - { - "id" : 335 - }, - { - "id" : 383, - "damage" : 47 - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 383, - "damage" : 36 - }, - { - "id" : -133, - "damage" : 3 - }, - { - "id" : 121 - }, - { - "id" : 372 - }, - { - "id" : -276 - }, - { - "id" : -255 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA8AAAA=" - }, - { - "id" : 431 - }, - { - "id" : 430 - }, - { - "id" : 215 - }, - { - "id" : -225 - }, - { - "id" : 262, - "damage" : 28 - }, - { - "id" : 262, - "damage" : 27 - }, - { - "id" : -183 - }, - { - "id" : 48 - }, - { - "id" : 464 - }, - { - "id" : 354 - }, - { - "id" : 434, - "damage" : 5 - }, - { - "id" : 434, - "damage" : 4 - }, - { - "id" : 159 - }, - { - "id" : 172 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB0AAAA=" - }, - { - "id" : 67 - }, - { - "id" : -180 - }, - { - "id" : 441, - "damage" : 36 - }, - { - "id" : 441, - "damage" : 37 - }, - { - "id" : 351, - "damage" : 4 - }, - { - "id" : 351, - "damage" : 15 - }, - { - "id" : 441, - "damage" : 28 - }, - { - "id" : 441, - "damage" : 29 - }, - { - "id" : 325, - "damage" : 8 - }, - { - "id" : 397, - "damage" : 4 - }, - { - "id" : 422 - }, - { - "id" : 325, - "damage" : 10 - }, - { - "id" : 351, - "damage" : 6 - }, - { - "id" : 351, - "damage" : 12 - }, - { - "id" : 201 - }, - { - "id" : 110 - }, - { - "id" : 465 - }, - { - "id" : 397, - "damage" : 5 - }, - { - "id" : 438, - "damage" : 40 - }, - { - "id" : 1 - }, - { - "id" : 438, - "damage" : 39 - }, - { - "id" : 182, - "damage" : 2 - }, - { - "id" : 182, - "damage" : 1 - }, - { - "id" : 441, - "damage" : 5 - }, - { - "id" : 441, - "damage" : 4 - }, - { - "id" : 226 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAsAAAA=" - }, - { - "id" : 505 - }, - { - "id" : 438, - "damage" : 25 - }, - { - "id" : 438, - "damage" : 26 - }, - { - "id" : 504 - }, - { - "id" : 758 - }, - { - "id" : 101 - }, - { - "id" : 334 - }, - { - "id" : -301 - }, - { - "id" : -230 - }, - { - "id" : 333 - }, - { - "id" : 355, - "damage" : 1 - }, - { - "id" : 355, - "damage" : 7 - }, - { - "id" : 355, - "damage" : 15 - }, - { - "id" : 355, - "damage" : 4 + "id" : 113 }, { "id" : -256 @@ -1758,32 +126,178 @@ "id" : -257 }, { - "id" : 236, - "damage" : 5 + "id" : 107 }, { - "id" : 299 + "id" : 183 }, { - "id" : 303 + "id" : 184 }, { - "id" : 236, - "damage" : 4 + "id" : 185 }, { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAsAAAA=" + "id" : 187 }, { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAoAAAA=" + "id" : 186 }, { - "id" : 500 + "id" : -258 }, { - "id" : 501 + "id" : -259 + }, + { + "id" : -180 + }, + { + "id" : 67 + }, + { + "id" : -179 + }, + { + "id" : 53 + }, + { + "id" : 134 + }, + { + "id" : 135 + }, + { + "id" : 136 + }, + { + "id" : 163 + }, + { + "id" : 164 + }, + { + "id" : 109 + }, + { + "id" : -175 + }, + { + "id" : 128 + }, + { + "id" : -177 + }, + { + "id" : 180 + }, + { + "id" : -176 + }, + { + "id" : -169 + }, + { + "id" : -172 + }, + { + "id" : -170 + }, + { + "id" : -173 + }, + { + "id" : -171 + }, + { + "id" : -174 + }, + { + "id" : 108 + }, + { + "id" : 114 + }, + { + "id" : -184 + }, + { + "id" : -178 + }, + { + "id" : 156 + }, + { + "id" : -185 + }, + { + "id" : 203 + }, + { + "id" : -2 + }, + { + "id" : -3 + }, + { + "id" : -4 + }, + { + "id" : -254 + }, + { + "id" : -255 + }, + { + "id" : -276 + }, + { + "id" : -292 + }, + { + "id" : -275 + }, + { + "id" : 324 + }, + { + "id" : 427 + }, + { + "id" : 428 + }, + { + "id" : 429 + }, + { + "id" : 430 + }, + { + "id" : 431 + }, + { + "id" : 330 + }, + { + "id" : 755 + }, + { + "id" : 756 + }, + { + "id" : 96 + }, + { + "id" : -149 + }, + { + "id" : -146 + }, + { + "id" : -148 + }, + { + "id" : -145 }, { "id" : -147 @@ -1792,458 +306,255 @@ "id" : 167 }, { - "id" : -299 + "id" : -246 }, { - "id" : 383, - "damage" : 39 + "id" : -247 }, { - "id" : 383, - "damage" : 38 + "id" : 101 }, { - "id" : -241 + "id" : 758 }, { - "id" : 373, + "id" : 20 + }, + { + "id" : 241 + }, + { + "id" : 241, "damage" : 8 }, { - "id" : 373, - "damage" : 9 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAsAAAA=" - }, - { - "id" : 86 - }, - { - "id" : 373, - "damage" : 5 - }, - { - "id" : 373, - "damage" : 4 - }, - { - "id" : -155 - }, - { - "id" : 446, - "damage" : 4 - }, - { - "id" : 446, - "damage" : 5 - }, - { - "id" : 35, + "id" : 241, "damage" : 7 }, { - "id" : -131, - "damage" : 9 - }, - { - "id" : -132, - "damage" : 9 - }, - { - "id" : -132, - "damage" : 10 - }, - { - "id" : 383, - "damage" : 37 - }, - { - "id" : 35, - "damage" : 8 - }, - { - "id" : -131, - "damage" : 11 - }, - { - "id" : -288 - }, - { - "id" : -271 - }, - { - "id" : 383, - "damage" : 46 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCQAAAA=" - }, - { - "id" : 236, + "id" : 241, "damage" : 15 }, { - "id" : 236, + "id" : 241, "damage" : 12 }, { - "id" : 446, - "damage" : 11 + "id" : 241, + "damage" : 14 }, { - "id" : 446, - "damage" : 3 + "id" : 241, + "damage" : 1 }, { - "id" : 438, - "damage" : 29 - }, - { - "id" : 438, - "damage" : 30 - }, - { - "id" : 85, + "id" : 241, "damage" : 4 }, { - "id" : 85, - "damage" : 3 - }, - { - "id" : 370 - }, - { - "id" : 445 - }, - { - "id" : 333, - "damage" : 1 - }, - { - "id" : 1, + "id" : 241, "damage" : 5 }, - { - "id" : 1, - "damage" : 3 - }, - { - "id" : -302 - }, - { - "id" : -303 - }, - { - "id" : 262, - "damage" : 6 - }, - { - "id" : 262 - }, - { - "id" : 98, - "damage" : 2 - }, - { - "id" : 98, - "damage" : 1 - }, - { - "id" : 262, - "damage" : 9 - }, - { - "id" : 262, - "damage" : 10 - }, - { - "id" : 363 - }, - { - "id" : -11 - }, - { - "id" : 174 - }, - { - "id" : 319 - }, - { - "id" : 441, - "damage" : 33 - }, - { - "id" : 441, - "damage" : 32 - }, - { - "id" : 139, - "damage" : 12 - }, - { - "id" : 381 - }, - { - "id" : 399 - }, - { - "id" : 58 - }, - { - "id" : -269 - }, - { - "id" : 139, - "damage" : 7 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAYAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAcAAAA=" - }, - { - "id" : 438, - "damage" : 11 - }, - { - "id" : 438, - "damage" : 12 - }, - { - "id" : 135 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB4AAAA=" - }, - { - "id" : 473 - }, - { - "id" : 472 - }, - { - "id" : 134 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB4AAAA=" - }, - { - "id" : 165 - }, - { - "id" : 168, - "damage" : 1 - }, - { - "id" : 35, - "damage" : 14 - }, - { - "id" : 237, - "damage" : 1 - }, - { - "id" : 237, - "damage" : 14 - }, - { - "id" : -132, - "damage" : 3 - }, - { - "id" : -132, - "damage" : 2 - }, - { - "id" : 35, - "damage" : 1 - }, { "id" : 241, - "damage" : 11 - }, - { - "id" : 417 - }, - { - "id" : 416 - }, - { - "id" : 373, - "damage" : 22 - }, - { - "id" : 373, - "damage" : 23 - }, - { - "id" : 241, - "damage" : 3 - }, - { - "id" : 218, - "damage" : 1 - }, - { - "id" : 218, - "damage" : 14 - }, - { - "id" : 324 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBAAAAA=" - }, - { - "id" : 383, - "damage" : 125 - }, - { - "id" : 383, - "damage" : 124 - }, - { - "id" : 427 - }, - { - "id" : -218, - "damage" : 3 - }, - { - "id" : 295 - }, - { - "id" : 37 - }, - { - "id" : -224 - }, - { - "id" : 351, - "damage" : 9 - }, - { - "id" : 351, "damage" : 13 }, { - "id" : 383, - "damage" : 23 + "id" : 241, + "damage" : 9 }, { - "id" : 383, - "damage" : 24 - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 17, - "damage" : 2 - }, - { - "id" : 749 - }, - { - "id" : -6 - }, - { - "id" : 311 - }, - { - "id" : 24, - "damage" : 2 - }, - { - "id" : 273 - }, - { - "id" : 24, + "id" : 241, "damage" : 3 }, { - "id" : 269 + "id" : 241, + "damage" : 11 }, { - "id" : 152 + "id" : 241, + "damage" : 10 }, { - "id" : 331 + "id" : 241, + "damage" : 2 }, { - "id" : 159, + "id" : 241, + "damage" : 6 + }, + { + "id" : 102 + }, + { + "id" : 160 + }, + { + "id" : 160, + "damage" : 8 + }, + { + "id" : 160, + "damage" : 7 + }, + { + "id" : 160, + "damage" : 15 + }, + { + "id" : 160, "damage" : 12 }, { - "id" : 159, - "damage" : 15 + "id" : 160, + "damage" : 14 }, { - "id" : 262, - "damage" : 24 - }, - { - "id" : 23, - "damage" : 3 - }, - { - "id" : 125, - "damage" : 3 - }, - { - "id" : 262, - "damage" : 23 - }, - { - "id" : 3, + "id" : 160, "damage" : 1 }, { - "id" : 287 + "id" : 160, + "damage" : 4 }, { - "id" : 2 + "id" : 160, + "damage" : 5 }, { - "id" : 99 + "id" : 160, + "damage" : 13 }, { - "id" : 99, - "damage" : 15 + "id" : 160, + "damage" : 9 }, { - "id" : 470 + "id" : 160, + "damage" : 3 }, { - "id" : 441 + "id" : 160, + "damage" : 11 }, { - "id" : 441, + "id" : 160, + "damage" : 10 + }, + { + "id" : 160, + "damage" : 2 + }, + { + "id" : 160, + "damage" : 6 + }, + { + "id" : 65 + }, + { + "id" : -165 + }, + { + "id" : 44 + }, + { + "id" : -166, + "damage" : 2 + }, + { + "id" : 44, + "damage" : 3 + }, + { + "id" : 182, + "damage" : 5 + }, + { + "id" : 158 + }, + { + "id" : 158, "damage" : 1 }, + { + "id" : 158, + "damage" : 2 + }, + { + "id" : 158, + "damage" : 3 + }, + { + "id" : 158, + "damage" : 4 + }, + { + "id" : 158, + "damage" : 5 + }, + { + "id" : 44, + "damage" : 5 + }, + { + "id" : -166 + }, + { + "id" : 44, + "damage" : 1 + }, + { + "id" : -166, + "damage" : 3 + }, + { + "id" : 182, + "damage" : 6 + }, + { + "id" : 182 + }, + { + "id" : -166, + "damage" : 4 + }, + { + "id" : -162, + "damage" : 1 + }, + { + "id" : -162, + "damage" : 6 + }, + { + "id" : -162, + "damage" : 7 + }, + { + "id" : -162, + "damage" : 4 + }, + { + "id" : -162, + "damage" : 5 + }, + { + "id" : -162, + "damage" : 3 + }, + { + "id" : -162, + "damage" : 2 + }, + { + "id" : 44, + "damage" : 4 + }, + { + "id" : 44, + "damage" : 7 + }, { "id" : 182, "damage" : 7 @@ -2252,77 +563,829 @@ "id" : -162 }, { - "id" : 160, + "id" : 44, "damage" : 6 }, { - "id" : 161, + "id" : -166, "damage" : 1 }, { - "id" : 161 + "id" : 182, + "damage" : 1 }, { - "id" : 160, + "id" : 182, "damage" : 2 }, { - "id" : 257 - }, - { - "id" : 70 - }, - { - "id" : -263 - }, - { - "id" : 285 - }, - { - "id" : 160, - "damage" : 10 - }, - { - "id" : 160, - "damage" : 11 - }, - { - "id" : -165 - }, - { - "id" : 65 - }, - { - "id" : 18, + "id" : 182, "damage" : 3 }, { - "id" : 18, + "id" : 182, + "damage" : 4 + }, + { + "id" : -264 + }, + { + "id" : -265 + }, + { + "id" : -282 + }, + { + "id" : -293 + }, + { + "id" : -284 + }, + { + "id" : 45 + }, + { + "id" : -302 + }, + { + "id" : -303 + }, + { + "id" : -304 + }, + { + "id" : 98 + }, + { + "id" : 98, + "damage" : 1 + }, + { + "id" : 98, "damage" : 2 }, { - "id" : 160, + "id" : 98, + "damage" : 3 + }, + { + "id" : 206 + }, + { + "id" : 168, + "damage" : 2 + }, + { + "id" : -274 + }, + { + "id" : -280 + }, + { + "id" : -281 + }, + { + "id" : -279 + }, + { + "id" : 4 + }, + { + "id" : 48 + }, + { + "id" : -183 + }, + { + "id" : 24 + }, + { + "id" : 24, + "damage" : 1 + }, + { + "id" : 24, + "damage" : 2 + }, + { + "id" : 24, + "damage" : 3 + }, + { + "id" : 179 + }, + { + "id" : 179, + "damage" : 1 + }, + { + "id" : 179, + "damage" : 2 + }, + { + "id" : 179, + "damage" : 3 + }, + { + "id" : 173 + }, + { + "id" : -139 + }, + { + "id" : 41 + }, + { + "id" : 42 + }, + { + "id" : 133 + }, + { + "id" : 57 + }, + { + "id" : 22 + }, + { + "id" : 155 + }, + { + "id" : 155, + "damage" : 2 + }, + { + "id" : 155, + "damage" : 1 + }, + { + "id" : 155, + "damage" : 3 + }, + { + "id" : 168 + }, + { + "id" : 168, + "damage" : 1 + }, + { + "id" : 165 + }, + { + "id" : -220 + }, + { + "id" : -221 + }, + { + "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 + }, + { + "id" : 35, + "damage" : 8 + }, + { + "id" : 35, + "damage" : 7 + }, + { + "id" : 35, + "damage" : 15 + }, + { + "id" : 35, + "damage" : 12 + }, + { + "id" : 35, + "damage" : 14 + }, + { + "id" : 35, + "damage" : 1 + }, + { + "id" : 35, + "damage" : 4 + }, + { + "id" : 35, + "damage" : 5 + }, + { + "id" : 35, + "damage" : 13 + }, + { + "id" : 35, "damage" : 9 }, { - "id" : 6, + "id" : 35, "damage" : 3 }, { - "id" : 18, + "id" : 35, + "damage" : 11 + }, + { + "id" : 35, + "damage" : 10 + }, + { + "id" : 35, + "damage" : 2 + }, + { + "id" : 35, + "damage" : 6 + }, + { + "id" : 171 + }, + { + "id" : 171, + "damage" : 8 + }, + { + "id" : 171, + "damage" : 7 + }, + { + "id" : 171, + "damage" : 15 + }, + { + "id" : 171, + "damage" : 12 + }, + { + "id" : 171, + "damage" : 14 + }, + { + "id" : 171, "damage" : 1 }, { - "id" : 146 + "id" : 171, + "damage" : 4 + }, + { + "id" : 171, + "damage" : 5 + }, + { + "id" : 171, + "damage" : 13 + }, + { + "id" : 171, + "damage" : 9 + }, + { + "id" : 171, + "damage" : 3 + }, + { + "id" : 171, + "damage" : 11 + }, + { + "id" : 171, + "damage" : 10 + }, + { + "id" : 171, + "damage" : 2 + }, + { + "id" : 171, + "damage" : 6 + }, + { + "id" : 237 + }, + { + "id" : 237, + "damage" : 8 + }, + { + "id" : 237, + "damage" : 7 + }, + { + "id" : 237, + "damage" : 15 + }, + { + "id" : 237, + "damage" : 12 + }, + { + "id" : 237, + "damage" : 14 + }, + { + "id" : 237, + "damage" : 1 + }, + { + "id" : 237, + "damage" : 4 + }, + { + "id" : 237, + "damage" : 5 + }, + { + "id" : 237, + "damage" : 13 + }, + { + "id" : 237, + "damage" : 9 + }, + { + "id" : 237, + "damage" : 3 + }, + { + "id" : 237, + "damage" : 11 + }, + { + "id" : 237, + "damage" : 10 + }, + { + "id" : 237, + "damage" : 2 + }, + { + "id" : 237, + "damage" : 6 + }, + { + "id" : 236 + }, + { + "id" : 236, + "damage" : 8 + }, + { + "id" : 236, + "damage" : 7 + }, + { + "id" : 236, + "damage" : 15 + }, + { + "id" : 236, + "damage" : 12 + }, + { + "id" : 236, + "damage" : 14 + }, + { + "id" : 236, + "damage" : 1 + }, + { + "id" : 236, + "damage" : 4 + }, + { + "id" : 236, + "damage" : 5 + }, + { + "id" : 236, + "damage" : 13 + }, + { + "id" : 236, + "damage" : 9 + }, + { + "id" : 236, + "damage" : 3 + }, + { + "id" : 236, + "damage" : 11 + }, + { + "id" : 236, + "damage" : 10 + }, + { + "id" : 236, + "damage" : 2 + }, + { + "id" : 236, + "damage" : 6 + }, + { + "id" : 82 + }, + { + "id" : 172 + }, + { + "id" : 159 + }, + { + "id" : 159, + "damage" : 8 + }, + { + "id" : 159, + "damage" : 7 + }, + { + "id" : 159, + "damage" : 15 + }, + { + "id" : 159, + "damage" : 12 + }, + { + "id" : 159, + "damage" : 14 + }, + { + "id" : 159, + "damage" : 1 + }, + { + "id" : 159, + "damage" : 4 + }, + { + "id" : 159, + "damage" : 5 + }, + { + "id" : 159, + "damage" : 13 + }, + { + "id" : 159, + "damage" : 9 + }, + { + "id" : 159, + "damage" : 3 + }, + { + "id" : 159, + "damage" : 11 + }, + { + "id" : 159, + "damage" : 10 + }, + { + "id" : 159, + "damage" : 2 + }, + { + "id" : 159, + "damage" : 6 + }, + { + "id" : 220 + }, + { + "id" : 228 + }, + { + "id" : 227 + }, + { + "id" : 235 + }, + { + "id" : 232 + }, + { + "id" : 234 + }, + { + "id" : 221 + }, + { + "id" : 224 + }, + { + "id" : 225 + }, + { + "id" : 233 + }, + { + "id" : 229 + }, + { + "id" : 223 + }, + { + "id" : 231 + }, + { + "id" : 219 + }, + { + "id" : 222 + }, + { + "id" : 226 + }, + { + "id" : 201 + }, + { + "id" : 201, + "damage" : 2 + }, + { + "id" : 3 + }, + { + "id" : 3, + "damage" : 1 + }, + { + "id" : 2 + }, + { + "id" : 198 + }, + { + "id" : 243 + }, + { + "id" : 110 + }, + { + "id" : 1 + }, + { + "id" : 15 + }, + { + "id" : 14 + }, + { + "id" : 56 + }, + { + "id" : 21 + }, + { + "id" : 73 + }, + { + "id" : 16 + }, + { + "id" : 129 + }, + { + "id" : 153 + }, + { + "id" : -288 + }, + { + "id" : -271 + }, + { + "id" : 13 + }, + { + "id" : 1, + "damage" : 1 + }, + { + "id" : 1, + "damage" : 3 + }, + { + "id" : 1, + "damage" : 5 + }, + { + "id" : -273 + }, + { + "id" : 1, + "damage" : 2 + }, + { + "id" : 1, + "damage" : 4 + }, + { + "id" : 1, + "damage" : 6 + }, + { + "id" : -291 + }, + { + "id" : 12 + }, + { + "id" : 12, + "damage" : 1 + }, + { + "id" : 81 + }, + { + "id" : 17 + }, + { + "id" : -10 + }, + { + "id" : 17, + "damage" : 1 + }, + { + "id" : -5 + }, + { + "id" : 17, + "damage" : 2 + }, + { + "id" : -6 + }, + { + "id" : 17, + "damage" : 3 + }, + { + "id" : -7 + }, + { + "id" : 162 + }, + { + "id" : -8 + }, + { + "id" : 162, + "damage" : 1 + }, + { + "id" : -9 + }, + { + "id" : -212 + }, + { + "id" : -212, + "damage" : 8 + }, + { + "id" : -212, + "damage" : 1 + }, + { + "id" : -212, + "damage" : 9 + }, + { + "id" : -212, + "damage" : 2 + }, + { + "id" : -212, + "damage" : 10 + }, + { + "id" : -212, + "damage" : 3 + }, + { + "id" : -212, + "damage" : 11 + }, + { + "id" : -212, + "damage" : 4 + }, + { + "id" : -212, + "damage" : 12 + }, + { + "id" : -212, + "damage" : 5 + }, + { + "id" : -212, + "damage" : 13 }, { "id" : 18 }, { - "id" : -203 + "id" : 18, + "damage" : 1 }, { - "id" : 130 + "id" : 18, + "damage" : 2 + }, + { + "id" : 18, + "damage" : 3 + }, + { + "id" : 161 + }, + { + "id" : 161, + "damage" : 1 }, { "id" : 6 @@ -2337,462 +1400,91 @@ }, { "id" : 6, - "damage" : 5 + "damage" : 3 }, { "id" : 6, "damage" : 4 }, { - "id" : 54 - }, - { - "id" : -213 - }, - { - "id" : 380 - }, - { - "id" : -194 - }, - { - "id" : 116 - }, - { - "id" : 145, - "damage" : 4 - }, - { - "id" : 379 - }, - { - "id" : -198 - }, - { - "id" : -272 - }, - { - "id" : 145 - }, - { - "id" : -195 - }, - { - "id" : 145, - "damage" : 8 - }, - { - "id" : 47 - }, - { - "id" : 158 - }, - { - "id" : 158, - "damage" : 1 - }, - { - "id" : 404 - }, - { - "id" : 410 - }, - { - "id" : 276 - }, - { - "id" : 743 - }, - { - "id" : -212, - "damage" : 3 - }, - { - "id" : -212, - "damage" : 11 - }, - { - "id" : -212, + "id" : 6, "damage" : 5 }, { - "id" : -212, - "damage" : 13 - }, - { - "id" : 29, - "damage" : 1 - }, - { - "id" : 160, - "damage" : 1 - }, - { - "id" : 160, - "damage" : 4 - }, - { - "id" : 33, - "damage" : 1 - }, - { - "id" : 44 - }, - { - "id" : 160, + "id" : -218, "damage" : 3 }, { - "id" : 158, - "damage" : 4 + "id" : 295 }, { - "id" : 251 + "id" : 361 }, { - "id" : -295 - }, - { - "id" : -150 - }, - { - "id" : -153 - }, - { - "id" : -166, - "damage" : 2 - }, - { - "id" : 131 - }, - { - "id" : 158, - "damage" : 5 - }, - { - "id" : 272 - }, - { - "id" : 268 - }, - { - "id" : 286 - }, - { - "id" : 258 - }, - { - "id" : 290 - }, - { - "id" : 291 - }, - { - "id" : 293 - }, - { - "id" : 747 - }, - { - "id" : 256 - }, - { - "id" : 284 - }, - { - "id" : 270 - }, - { - "id" : 274 - }, - { - "id" : 745 - }, - { - "id" : 278 - }, - { - "id" : -260 - }, - { - "id" : -143 - }, - { - "id" : -141 - }, - { - "id" : 72 - }, - { - "id" : 77 - }, - { - "id" : 261 - }, - { - "id" : 446 - }, - { - "id" : -204 - }, - { - "id" : 471 - }, - { - "id" : 102 - }, - { - "id" : 317 - }, - { - "id" : 241, - "damage" : 6 - }, - { - "id" : 309 - }, - { - "id" : 313 - }, - { - "id" : 751 - }, - { - "id" : -166, - "damage" : 3 - }, - { - "id" : 182 - }, - { - "id" : 182, - "damage" : 6 - }, - { - "id" : 44, - "damage" : 1 - }, - { - "id" : 421 - }, - { - "id" : 46 - }, - { - "id" : 160 - }, - { - "id" : 160, - "damage" : 8 - }, - { - "id" : 162 - }, - { - "id" : 218, - "damage" : 3 - }, - { - "id" : 218, - "damage" : 12 - }, - { - "id" : -9 - }, - { - "id" : -8 - }, - { - "id" : 162, - "damage" : 1 + "id" : 362 }, { "id" : 458 }, - { - "id" : 218, - "damage" : 15 - }, - { - "id" : 322 - }, - { - "id" : 801 - }, - { - "id" : -212, - "damage" : 10 - }, - { - "id" : 720 - }, - { - "id" : -219, - "damage" : 3 - }, { "id" : 296 }, - { - "id" : -202 - }, - { - "id" : -208 - }, - { - "id" : 241, - "damage" : 13 - }, - { - "id" : 241, - "damage" : 9 - }, - { - "id" : 218, - "damage" : 11 - }, - { - "id" : -156 - }, - { - "id" : 50 - }, - { - "id" : -268 - }, - { - "id" : 218, - "damage" : 9 - }, - { - "id" : 218, - "damage" : 13 - }, - { - "id" : 218, - "damage" : 7 - }, - { - "id" : 218, - "damage" : 8 - }, - { - "id" : 392 - }, { "id" : 457 }, { - "id" : 466 + "id" : 392 }, { - "id" : 360 + "id" : 394 + }, + { + "id" : 391 + }, + { + "id" : 396 + }, + { + "id" : 260 + }, + { + "id" : 322 + }, + { + "id" : 466 }, { "id" : 103 }, { - "id" : 744 + "id" : 360 }, { - "id" : 277 + "id" : 382 }, { - "id" : 342 + "id" : 477 }, { - "id" : 328 + "id" : 86 }, { - "id" : 262, - "damage" : 12 + "id" : -155 }, { - "id" : 262, - "damage" : 11 + "id" : 91 }, { - "id" : 356 + "id" : 736 }, { - "id" : 275 + "id" : 31, + "damage" : 2 }, { - "id" : 151 - }, - { - "id" : 271 - }, - { - "id" : 446, - "damage" : 1 - }, - { - "id" : 446, - "damage" : 14 - }, - { - "id" : 158, + "id" : 175, "damage" : 3 }, - { - "id" : 158, - "damage" : 2 - }, - { - "id" : -10 - }, - { - "id" : 17 - }, - { - "id" : 316 - }, - { - "id" : -212, - "damage" : 2 - }, - { - "id" : 308 - }, - { - "id" : 160, - "damage" : 13 - }, - { - "id" : 160, - "damage" : 5 - }, - { - "id" : -262 - }, - { - "id" : -152 - }, - { - "id" : -162, - "damage" : 2 - }, - { - "id" : -162, - "damage" : 3 - }, - { - "id" : -261 - }, - { - "id" : -296 - }, - { - "id" : 143 - }, - { - "id" : -144 - }, - { - "id" : 333, - "damage" : 5 - }, { "id" : 31, "damage" : 1 @@ -2802,60 +1494,718 @@ "damage" : 2 }, { - "id" : 333, - "damage" : 4 + "id" : 760 }, { - "id" : -291 - }, - { - "id" : 12 - }, - { - "id" : 1, - "damage" : 4 - }, - { - "id" : 1, - "damage" : 6 - }, - { - "id" : 262, - "damage" : 19 - }, - { - "id" : 333, + "id" : -131, "damage" : 3 }, { - "id" : 333, - "damage" : 2 - }, - { - "id" : 262, - "damage" : 20 - }, - { - "id" : 434 - }, - { - "id" : 434, + "id" : -131, "damage" : 1 }, { - "id" : 306 + "id" : -131, + "damage" : 2 }, { - "id" : 434, + "id" : -131 + }, + { + "id" : -131, + "damage" : 4 + }, + { + "id" : -131, + "damage" : 11 + }, + { + "id" : -131, + "damage" : 9 + }, + { + "id" : -131, + "damage" : 10 + }, + { + "id" : -131, + "damage" : 8 + }, + { + "id" : -131, + "damage" : 12 + }, + { + "id" : -133, "damage" : 3 }, { - "id" : 446, - "damage" : 15, - "nbt_b64" : "CgAAAwQAVHlwZQEAAAAA" + "id" : -133, + "damage" : 1 }, { - "id" : 509 + "id" : -133, + "damage" : 2 + }, + { + "id" : -133 + }, + { + "id" : -133, + "damage" : 4 + }, + { + "id" : -134, + "damage" : 3 + }, + { + "id" : -134, + "damage" : 1 + }, + { + "id" : -134, + "damage" : 2 + }, + { + "id" : -134 + }, + { + "id" : -134, + "damage" : 4 + }, + { + "id" : 335 + }, + { + "id" : -130 + }, + { + "id" : -223 + }, + { + "id" : -224 + }, + { + "id" : 37 + }, + { + "id" : 38 + }, + { + "id" : 38, + "damage" : 1 + }, + { + "id" : 38, + "damage" : 2 + }, + { + "id" : 38, + "damage" : 3 + }, + { + "id" : 38, + "damage" : 4 + }, + { + "id" : 38, + "damage" : 5 + }, + { + "id" : 38, + "damage" : 6 + }, + { + "id" : 38, + "damage" : 7 + }, + { + "id" : 38, + "damage" : 8 + }, + { + "id" : 38, + "damage" : 9 + }, + { + "id" : 38, + "damage" : 10 + }, + { + "id" : 175 + }, + { + "id" : 175, + "damage" : 1 + }, + { + "id" : 175, + "damage" : 4 + }, + { + "id" : 175, + "damage" : 5 + }, + { + "id" : -216 + }, + { + "id" : 351, + "damage" : 19 + }, + { + "id" : 351, + "damage" : 7 + }, + { + "id" : 351, + "damage" : 8 + }, + { + "id" : 351, + "damage" : 16 + }, + { + "id" : 351, + "damage" : 17 + }, + { + "id" : 351, + "damage" : 1 + }, + { + "id" : 351, + "damage" : 14 + }, + { + "id" : 351, + "damage" : 11 + }, + { + "id" : 351, + "damage" : 10 + }, + { + "id" : 351, + "damage" : 2 + }, + { + "id" : 351, + "damage" : 6 + }, + { + "id" : 351, + "damage" : 12 + }, + { + "id" : 351, + "damage" : 18 + }, + { + "id" : 351, + "damage" : 5 + }, + { + "id" : 351, + "damage" : 13 + }, + { + "id" : 351, + "damage" : 9 + }, + { + "id" : 351 + }, + { + "id" : 351, + "damage" : 3 + }, + { + "id" : 351, + "damage" : 4 + }, + { + "id" : 351, + "damage" : 15 + }, + { + "id" : 106 + }, + { + "id" : -231 + }, + { + "id" : -287 + }, + { + "id" : 111 + }, + { + "id" : 32 + }, + { + "id" : -163 + }, + { + "id" : 80 + }, + { + "id" : 79 + }, + { + "id" : 174 + }, + { + "id" : -11 + }, + { + "id" : 78 + }, + { + "id" : 365 + }, + { + "id" : 319 + }, + { + "id" : 363 + }, + { + "id" : 423 + }, + { + "id" : 411 + }, + { + "id" : 349 + }, + { + "id" : 460 + }, + { + "id" : 461 + }, + { + "id" : 462 + }, + { + "id" : 39 + }, + { + "id" : 40 + }, + { + "id" : -228 + }, + { + "id" : -229 + }, + { + "id" : 99, + "damage" : 14 + }, + { + "id" : 100, + "damage" : 14 + }, + { + "id" : 99, + "damage" : 15 + }, + { + "id" : 99 + }, + { + "id" : 344 + }, + { + "id" : 338 + }, + { + "id" : 353 + }, + { + "id" : 367 + }, + { + "id" : 352 + }, + { + "id" : 30 + }, + { + "id" : 375 + }, + { + "id" : 52 + }, + { + "id" : 97 + }, + { + "id" : 97, + "damage" : 1 + }, + { + "id" : 97, + "damage" : 2 + }, + { + "id" : 97, + "damage" : 3 + }, + { + "id" : 97, + "damage" : 4 + }, + { + "id" : 97, + "damage" : 5 + }, + { + "id" : 122 + }, + { + "id" : -159 + }, + { + "id" : 383, + "damage" : 10 + }, + { + "id" : 383, + "damage" : 122 + }, + { + "id" : 383, + "damage" : 11 + }, + { + "id" : 383, + "damage" : 12 + }, + { + "id" : 383, + "damage" : 13 + }, + { + "id" : 383, + "damage" : 14 + }, + { + "id" : 383, + "damage" : 28 + }, + { + "id" : 383, + "damage" : 22 + }, + { + "id" : 383, + "damage" : 75 + }, + { + "id" : 383, + "damage" : 16 + }, + { + "id" : 383, + "damage" : 19 + }, + { + "id" : 383, + "damage" : 30 + }, + { + "id" : 383, + "damage" : 18 + }, + { + "id" : 383, + "damage" : 29 + }, + { + "id" : 383, + "damage" : 23 + }, + { + "id" : 383, + "damage" : 24 + }, + { + "id" : 383, + "damage" : 25 + }, + { + "id" : 383, + "damage" : 26 + }, + { + "id" : 383, + "damage" : 27 + }, + { + "id" : 383, + "damage" : 111 + }, + { + "id" : 383, + "damage" : 112 + }, + { + "id" : 383, + "damage" : 108 + }, + { + "id" : 383, + "damage" : 109 + }, + { + "id" : 383, + "damage" : 31 + }, + { + "id" : 383, + "damage" : 74 + }, + { + "id" : 383, + "damage" : 113 + }, + { + "id" : 383, + "damage" : 121 + }, + { + "id" : 383, + "damage" : 33 + }, + { + "id" : 383, + "damage" : 38 + }, + { + "id" : 383, + "damage" : 39 + }, + { + "id" : 383, + "damage" : 34 + }, + { + "id" : 383, + "damage" : 48 + }, + { + "id" : 383, + "damage" : 46 + }, + { + "id" : 383, + "damage" : 37 + }, + { + "id" : 383, + "damage" : 35 + }, + { + "id" : 383, + "damage" : 32 + }, + { + "id" : 383, + "damage" : 36 + }, + { + "id" : 383, + "damage" : 47 + }, + { + "id" : 383, + "damage" : 110 + }, + { + "id" : 383, + "damage" : 17 + }, + { + "id" : 383, + "damage" : 40 + }, + { + "id" : 383, + "damage" : 45 + }, + { + "id" : 383, + "damage" : 49 + }, + { + "id" : 383, + "damage" : 50 + }, + { + "id" : 383, + "damage" : 55 + }, + { + "id" : 383, + "damage" : 42 + }, + { + "id" : 383, + "damage" : 125 + }, + { + "id" : 383, + "damage" : 124 + }, + { + "id" : 383, + "damage" : 123 + }, + { + "id" : 383, + "damage" : 126 + }, + { + "id" : 383, + "damage" : 41 + }, + { + "id" : 383, + "damage" : 43 + }, + { + "id" : 383, + "damage" : 54 + }, + { + "id" : 383, + "damage" : 57 + }, + { + "id" : 383, + "damage" : 104 + }, + { + "id" : 383, + "damage" : 105 + }, + { + "id" : 383, + "damage" : 115 + }, + { + "id" : 383, + "damage" : 118 + }, + { + "id" : 383, + "damage" : 116 + }, + { + "id" : 383, + "damage" : 58 + }, + { + "id" : 383, + "damage" : 114 + }, + { + "id" : 383, + "damage" : 59 + }, + { + "id" : 49 + }, + { + "id" : -289 + }, + { + "id" : 7 + }, + { + "id" : 88 + }, + { + "id" : 87 + }, + { + "id" : 213 + }, + { + "id" : 372 + }, + { + "id" : 121 + }, + { + "id" : 200 + }, + { + "id" : 240 + }, + { + "id" : 432 + }, + { + "id" : 433 + }, + { + "id" : 19 + }, + { + "id" : 19, + "damage" : 1 + }, + { + "id" : -132 + }, + { + "id" : -132, + "damage" : 1 + }, + { + "id" : -132, + "damage" : 2 + }, + { + "id" : -132, + "damage" : 3 + }, + { + "id" : -132, + "damage" : 4 + }, + { + "id" : -132, + "damage" : 8 + }, + { + "id" : -132, + "damage" : 9 + }, + { + "id" : -132, + "damage" : 10 + }, + { + "id" : -132, + "damage" : 11 + }, + { + "id" : -132, + "damage" : 12 + }, + { + "id" : 298 + }, + { + "id" : 302 + }, + { + "id" : 306 }, { "id" : 314 @@ -2867,197 +2217,201 @@ "id" : 748 }, { - "id" : 446, - "damage" : 6 + "id" : 299 }, { - "id" : 434, - "damage" : 2 + "id" : 303 }, { - "id" : 508 + "id" : 307 }, { - "id" : 355, - "damage" : 8 + "id" : 315 }, { - "id" : 355 + "id" : 311 }, { - "id" : 241, - "damage" : 8 + "id" : 749 }, { - "id" : 302 + "id" : 300 }, { - "id" : 298 + "id" : 304 }, { - "id" : -131, - "damage" : 1 + "id" : 308 }, { - "id" : 241, - "damage" : 15 - }, - { - "id" : 241, - "damage" : 7 - }, - { - "id" : -131, - "damage" : 2 - }, - { - "id" : 355, - "damage" : 3 - }, - { - "id" : 241, - "damage" : 12 - }, - { - "id" : -145 - }, - { - "id" : -148 - }, - { - "id" : 760 - }, - { - "id" : -131, - "damage" : 3 - }, - { - "id" : 175, - "damage" : 3 - }, - { - "id" : 31, - "damage" : 2 - }, - { - "id" : -162, - "damage" : 4 - }, - { - "id" : -162, - "damage" : 5 - }, - { - "id" : 241, - "damage" : 4 - }, - { - "id" : 241, - "damage" : 5 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZCIAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCIAAAA=" - }, - { - "id" : 355, - "damage" : 2 - }, - { - "id" : 355, - "damage" : 6 - }, - { - "id" : 218, - "damage" : 2 - }, - { - "id" : 218, - "damage" : 10 - }, - { - "id" : 441, - "damage" : 38 - }, - { - "id" : 84 - }, - { - "id" : 25 - }, - { - "id" : 123 - }, - { - "id" : 355, - "damage" : 9 - }, - { - "id" : 262, - "damage" : 29 - }, - { - "id" : 262, - "damage" : 30 - }, - { - "id" : 750 + "id" : 316 }, { "id" : 312 }, { - "id" : 511 + "id" : 750 }, { - "id" : 510 + "id" : 301 }, { - "id" : 280 + "id" : 305 }, { - "id" : 441, - "damage" : 42 + "id" : 309 }, { - "id" : 441, - "damage" : 39 + "id" : 317 }, { - "id" : 89 + "id" : 313 }, { - "id" : 446, + "id" : 751 + }, + { + "id" : 268 + }, + { + "id" : 272 + }, + { + "id" : 267 + }, + { + "id" : 283 + }, + { + "id" : 276 + }, + { + "id" : 743 + }, + { + "id" : 271 + }, + { + "id" : 275 + }, + { + "id" : 258 + }, + { + "id" : 286 + }, + { + "id" : 279 + }, + { + "id" : 746 + }, + { + "id" : 270 + }, + { + "id" : 274 + }, + { + "id" : 257 + }, + { + "id" : 285 + }, + { + "id" : 278 + }, + { + "id" : 745 + }, + { + "id" : 269 + }, + { + "id" : 273 + }, + { + "id" : 256 + }, + { + "id" : 284 + }, + { + "id" : 277 + }, + { + "id" : 744 + }, + { + "id" : 290 + }, + { + "id" : 291 + }, + { + "id" : 292 + }, + { + "id" : 294 + }, + { + "id" : 293 + }, + { + "id" : 747 + }, + { + "id" : 261 + }, + { + "id" : 471 + }, + { + "id" : 262 + }, + { + "id" : 262, + "damage" : 6 + }, + { + "id" : 262, + "damage" : 7 + }, + { + "id" : 262, + "damage" : 8 + }, + { + "id" : 262, + "damage" : 9 + }, + { + "id" : 262, + "damage" : 10 + }, + { + "id" : 262, + "damage" : 11 + }, + { + "id" : 262, "damage" : 12 }, { - "id" : 16 + "id" : 262, + "damage" : 13 }, { - "id" : 73 + "id" : 262, + "damage" : 14 }, { - "id" : 446, + "id" : 262, "damage" : 15 }, { - "id" : 81 - }, - { - "id" : 12, - "damage" : 1 - }, - { - "id" : -166, - "damage" : 4 - }, - { - "id" : -162, - "damage" : 1 + "id" : 262, + "damage" : 16 }, { "id" : 262, @@ -3068,80 +2422,64 @@ "damage" : 18 }, { - "id" : 126 - }, - { - "id" : 28 + "id" : 262, + "damage" : 19 }, { "id" : 262, - "damage" : 14 + "damage" : 20 }, { "id" : 262, - "damage" : 13 + "damage" : 21 }, { - "id" : 182, - "damage" : 4 + "id" : 262, + "damage" : 22 }, { - "id" : -282 + "id" : 262, + "damage" : 23 }, { - "id" : -293 + "id" : 262, + "damage" : 24 }, { - "id" : 182, - "damage" : 3 + "id" : 262, + "damage" : 25 }, { - "id" : 394 + "id" : 262, + "damage" : 26 }, { - "id" : 391 + "id" : 262, + "damage" : 27 }, { - "id" : -133, - "damage" : 4 + "id" : 262, + "damage" : 28 }, { - "id" : -133 + "id" : 262, + "damage" : 29 }, { - "id" : -134, - "damage" : 3 + "id" : 262, + "damage" : 30 }, { - "id" : -134, - "damage" : 1 + "id" : 262, + "damage" : 31 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 262, + "damage" : 32 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCEAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCAAAAA=" - }, - { - "id" : 446, - "damage" : 7 - }, - { - "id" : 446, - "damage" : 8 - }, - { - "id" : 301 + "id" : 262, + "damage" : 33 }, { "id" : 262, @@ -3149,89 +2487,829 @@ }, { "id" : 262, - "damage" : 33 + "damage" : 35 }, { - "id" : -212, + "id" : 262, + "damage" : 36 + }, + { + "id" : 262, + "damage" : 37 + }, + { + "id" : 262, + "damage" : 38 + }, + { + "id" : 262, + "damage" : 39 + }, + { + "id" : 262, + "damage" : 40 + }, + { + "id" : 262, + "damage" : 41 + }, + { + "id" : 262, + "damage" : 42 + }, + { + "id" : 262, + "damage" : 43 + }, + { + "id" : 513 + }, + { + "id" : 366 + }, + { + "id" : 320 + }, + { + "id" : 364 + }, + { + "id" : 424 + }, + { + "id" : 412 + }, + { + "id" : 350 + }, + { + "id" : 463 + }, + { + "id" : 297 + }, + { + "id" : 282 + }, + { + "id" : 459 + }, + { + "id" : 413 + }, + { + "id" : 393 + }, + { + "id" : 357 + }, + { + "id" : 400 + }, + { + "id" : 354 + }, + { + "id" : 464 + }, + { + "id" : 346 + }, + { + "id" : 398 + }, + { + "id" : 757 + }, + { + "id" : 332 + }, + { + "id" : 359 + }, + { + "id" : 259 + }, + { + "id" : 420 + }, + { + "id" : 347 + }, + { + "id" : 345 + }, + { + "id" : 395 + }, + { + "id" : 395, + "damage" : 2 + }, + { + "id" : 329 + }, + { + "id" : 416 + }, + { + "id" : 417 + }, + { + "id" : 418 + }, + { + "id" : 419 + }, + { + "id" : 455 + }, + { + "id" : 469 + }, + { + "id" : 444 + }, + { + "id" : 450 + }, + { + "id" : 374 + }, + { + "id" : 384 + }, + { + "id" : 373 + }, + { + "id" : 373, "damage" : 1 }, { - "id" : -212, - "damage" : 9 + "id" : 373, + "damage" : 2 }, { - "id" : -212, - "damage" : 8 + "id" : 373, + "damage" : 3 }, { - "id" : -212 + "id" : 373, + "damage" : 4 }, { - "id" : 200 + "id" : 373, + "damage" : 5 }, { - "id" : 240 + "id" : 373, + "damage" : 6 }, { - "id" : 160, - "damage" : 15 - }, - { - "id" : 160, + "id" : 373, "damage" : 7 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 373, + "damage" : 8 }, { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + "id" : 373, + "damage" : 9 }, { - "id" : 433 + "id" : 373, + "damage" : 10 }, { - "id" : 432 + "id" : 373, + "damage" : 11 }, { - "id" : 396 + "id" : 373, + "damage" : 12 }, { - "id" : 260 + "id" : 373, + "damage" : 13 }, { - "id" : -196 + "id" : 373, + "damage" : 14 }, { - "id" : 61 + "id" : 373, + "damage" : 15 }, { - "id" : -149 + "id" : 373, + "damage" : 16 }, { - "id" : -146 + "id" : 373, + "damage" : 17 }, { - "id" : 96 + "id" : 373, + "damage" : 18 }, { - "id" : 756 + "id" : 373, + "damage" : 19 }, { - "id" : 425 + "id" : 373, + "damage" : 20 }, { - "id" : 218, + "id" : 373, + "damage" : 21 + }, + { + "id" : 373, + "damage" : 22 + }, + { + "id" : 373, + "damage" : 23 + }, + { + "id" : 373, + "damage" : 24 + }, + { + "id" : 373, + "damage" : 25 + }, + { + "id" : 373, + "damage" : 26 + }, + { + "id" : 373, + "damage" : 27 + }, + { + "id" : 373, + "damage" : 28 + }, + { + "id" : 373, + "damage" : 29 + }, + { + "id" : 373, + "damage" : 30 + }, + { + "id" : 373, + "damage" : 31 + }, + { + "id" : 373, + "damage" : 32 + }, + { + "id" : 373, + "damage" : 33 + }, + { + "id" : 373, + "damage" : 34 + }, + { + "id" : 373, + "damage" : 35 + }, + { + "id" : 373, + "damage" : 36 + }, + { + "id" : 373, + "damage" : 37 + }, + { + "id" : 373, + "damage" : 38 + }, + { + "id" : 373, + "damage" : 39 + }, + { + "id" : 373, + "damage" : 40 + }, + { + "id" : 373, + "damage" : 41 + }, + { + "id" : 373, + "damage" : 42 + }, + { + "id" : 438 + }, + { + "id" : 438, + "damage" : 1 + }, + { + "id" : 438, + "damage" : 2 + }, + { + "id" : 438, + "damage" : 3 + }, + { + "id" : 438, + "damage" : 4 + }, + { + "id" : 438, + "damage" : 5 + }, + { + "id" : 438, "damage" : 6 }, + { + "id" : 438, + "damage" : 7 + }, + { + "id" : 438, + "damage" : 8 + }, + { + "id" : 438, + "damage" : 9 + }, + { + "id" : 438, + "damage" : 10 + }, + { + "id" : 438, + "damage" : 11 + }, + { + "id" : 438, + "damage" : 12 + }, + { + "id" : 438, + "damage" : 13 + }, + { + "id" : 438, + "damage" : 14 + }, + { + "id" : 438, + "damage" : 15 + }, + { + "id" : 438, + "damage" : 16 + }, + { + "id" : 438, + "damage" : 17 + }, + { + "id" : 438, + "damage" : 18 + }, + { + "id" : 438, + "damage" : 19 + }, + { + "id" : 438, + "damage" : 20 + }, + { + "id" : 438, + "damage" : 21 + }, + { + "id" : 438, + "damage" : 22 + }, + { + "id" : 438, + "damage" : 23 + }, + { + "id" : 438, + "damage" : 24 + }, + { + "id" : 438, + "damage" : 25 + }, + { + "id" : 438, + "damage" : 26 + }, + { + "id" : 438, + "damage" : 27 + }, + { + "id" : 438, + "damage" : 28 + }, + { + "id" : 438, + "damage" : 29 + }, + { + "id" : 438, + "damage" : 30 + }, + { + "id" : 438, + "damage" : 31 + }, + { + "id" : 438, + "damage" : 32 + }, + { + "id" : 438, + "damage" : 33 + }, + { + "id" : 438, + "damage" : 34 + }, + { + "id" : 438, + "damage" : 35 + }, + { + "id" : 438, + "damage" : 36 + }, + { + "id" : 438, + "damage" : 37 + }, + { + "id" : 438, + "damage" : 38 + }, + { + "id" : 438, + "damage" : 39 + }, + { + "id" : 438, + "damage" : 40 + }, + { + "id" : 438, + "damage" : 41 + }, + { + "id" : 438, + "damage" : 42 + }, + { + "id" : 441 + }, + { + "id" : 441, + "damage" : 1 + }, + { + "id" : 441, + "damage" : 2 + }, + { + "id" : 441, + "damage" : 3 + }, + { + "id" : 441, + "damage" : 4 + }, + { + "id" : 441, + "damage" : 5 + }, + { + "id" : 441, + "damage" : 6 + }, + { + "id" : 441, + "damage" : 7 + }, + { + "id" : 441, + "damage" : 8 + }, + { + "id" : 441, + "damage" : 9 + }, + { + "id" : 441, + "damage" : 10 + }, + { + "id" : 441, + "damage" : 11 + }, + { + "id" : 441, + "damage" : 12 + }, + { + "id" : 441, + "damage" : 13 + }, + { + "id" : 441, + "damage" : 14 + }, + { + "id" : 441, + "damage" : 15 + }, + { + "id" : 441, + "damage" : 16 + }, + { + "id" : 441, + "damage" : 17 + }, + { + "id" : 441, + "damage" : 18 + }, + { + "id" : 441, + "damage" : 19 + }, + { + "id" : 441, + "damage" : 20 + }, + { + "id" : 441, + "damage" : 21 + }, + { + "id" : 441, + "damage" : 22 + }, + { + "id" : 441, + "damage" : 23 + }, + { + "id" : 441, + "damage" : 24 + }, { "id" : 441, "damage" : 25 }, { "id" : 441, - "damage" : 24 + "damage" : 26 + }, + { + "id" : 441, + "damage" : 27 + }, + { + "id" : 441, + "damage" : 28 + }, + { + "id" : 441, + "damage" : 29 + }, + { + "id" : 441, + "damage" : 30 + }, + { + "id" : 441, + "damage" : 31 + }, + { + "id" : 441, + "damage" : 32 + }, + { + "id" : 441, + "damage" : 33 + }, + { + "id" : 441, + "damage" : 34 + }, + { + "id" : 441, + "damage" : 35 + }, + { + "id" : 441, + "damage" : 36 + }, + { + "id" : 441, + "damage" : 37 + }, + { + "id" : 441, + "damage" : 38 + }, + { + "id" : 441, + "damage" : 39 + }, + { + "id" : 441, + "damage" : 40 + }, + { + "id" : 441, + "damage" : 41 + }, + { + "id" : 441, + "damage" : 42 + }, + { + "id" : 280 + }, + { + "id" : 355 + }, + { + "id" : 355, + "damage" : 8 + }, + { + "id" : 355, + "damage" : 7 + }, + { + "id" : 355, + "damage" : 15 + }, + { + "id" : 355, + "damage" : 12 + }, + { + "id" : 355, + "damage" : 14 + }, + { + "id" : 355, + "damage" : 1 + }, + { + "id" : 355, + "damage" : 4 + }, + { + "id" : 355, + "damage" : 5 + }, + { + "id" : 355, + "damage" : 13 + }, + { + "id" : 355, + "damage" : 9 + }, + { + "id" : 355, + "damage" : 3 + }, + { + "id" : 355, + "damage" : 11 + }, + { + "id" : 355, + "damage" : 10 + }, + { + "id" : 355, + "damage" : 2 + }, + { + "id" : 355, + "damage" : 6 + }, + { + "id" : 50 + }, + { + "id" : -268 + }, + { + "id" : -156 + }, + { + "id" : -208 + }, + { + "id" : -269 + }, + { + "id" : 58 + }, + { + "id" : -200 + }, + { + "id" : -201 + }, + { + "id" : -202 + }, + { + "id" : -219, + "damage" : 3 + }, + { + "id" : 720 + }, + { + "id" : 801 + }, + { + "id" : 61 + }, + { + "id" : -196 + }, + { + "id" : -198 + }, + { + "id" : -272 + }, + { + "id" : 379 + }, + { + "id" : 145 + }, + { + "id" : 145, + "damage" : 4 + }, + { + "id" : 145, + "damage" : 8 + }, + { + "id" : -195 + }, + { + "id" : 116 + }, + { + "id" : 47 + }, + { + "id" : -194 + }, + { + "id" : 380 + }, + { + "id" : -213 + }, + { + "id" : 54 + }, + { + "id" : 146 + }, + { + "id" : 130 + }, + { + "id" : -203 }, { "id" : 205 @@ -3239,6 +3317,159 @@ { "id" : 218 }, + { + "id" : 218, + "damage" : 8 + }, + { + "id" : 218, + "damage" : 7 + }, + { + "id" : 218, + "damage" : 15 + }, + { + "id" : 218, + "damage" : 12 + }, + { + "id" : 218, + "damage" : 14 + }, + { + "id" : 218, + "damage" : 1 + }, + { + "id" : 218, + "damage" : 4 + }, + { + "id" : 218, + "damage" : 5 + }, + { + "id" : 218, + "damage" : 13 + }, + { + "id" : 218, + "damage" : 9 + }, + { + "id" : 218, + "damage" : 3 + }, + { + "id" : 218, + "damage" : 11 + }, + { + "id" : 218, + "damage" : 10 + }, + { + "id" : 218, + "damage" : 2 + }, + { + "id" : 218, + "damage" : 6 + }, + { + "id" : 425 + }, + { + "id" : 25 + }, + { + "id" : 84 + }, + { + "id" : 500 + }, + { + "id" : 501 + }, + { + "id" : 502 + }, + { + "id" : 503 + }, + { + "id" : 504 + }, + { + "id" : 505 + }, + { + "id" : 506 + }, + { + "id" : 507 + }, + { + "id" : 508 + }, + { + "id" : 509 + }, + { + "id" : 510 + }, + { + "id" : 511 + }, + { + "id" : 759 + }, + { + "id" : 348 + }, + { + "id" : 89 + }, + { + "id" : 123 + }, + { + "id" : 169 + }, + { + "id" : 323 + }, + { + "id" : 472 + }, + { + "id" : 473 + }, + { + "id" : 474 + }, + { + "id" : 475 + }, + { + "id" : 476 + }, + { + "id" : 753 + }, + { + "id" : 754 + }, + { + "id" : 321 + }, + { + "id" : 389 + }, + { + "id" : 737 + }, { "id" : 390 }, @@ -3246,159 +3477,514 @@ "id" : 281 }, { - "id" : 355, - "damage" : 10 + "id" : 325 }, { - "id" : 355, - "damage" : 11 - }, - { - "id" : 241, + "id" : 325, "damage" : 1 }, { - "id" : 241, - "damage" : 14 + "id" : 325, + "damage" : 8 }, { - "id" : 44, + "id" : 325, + "damage" : 10 + }, + { + "id" : 325, + "damage" : 2 + }, + { + "id" : 325, "damage" : 3 }, { - "id" : 182, + "id" : 325, + "damage" : 4 + }, + { + "id" : 325, "damage" : 5 }, { - "id" : 160, - "damage" : 14 + "id" : 397, + "damage" : 3 }, { - "id" : 160, - "damage" : 12 + "id" : 397, + "damage" : 2 }, { - "id" : 424 + "id" : 397, + "damage" : 4 }, { - "id" : 262, - "damage" : 32 + "id" : 397, + "damage" : 5 + }, + { + "id" : 397 + }, + { + "id" : 397, + "damage" : 1 + }, + { + "id" : 138 + }, + { + "id" : -206 + }, + { + "id" : -157 + }, + { + "id" : -197 + }, + { + "id" : 120 + }, + { + "id" : 263 + }, + { + "id" : 263, + "damage" : 1 + }, + { + "id" : 264 + }, + { + "id" : 452 + }, + { + "id" : 265 + }, + { + "id" : 752 + }, + { + "id" : 742 + }, + { + "id" : 371 + }, + { + "id" : 266 + }, + { + "id" : 388 + }, + { + "id" : 406 + }, + { + "id" : 337 + }, + { + "id" : 336 + }, + { + "id" : 405 + }, + { + "id" : 409 + }, + { + "id" : 422 + }, + { + "id" : 465 + }, + { + "id" : 467 + }, + { + "id" : 468 + }, + { + "id" : 470 + }, + { + "id" : 287 + }, + { + "id" : 288 + }, + { + "id" : 318 + }, + { + "id" : 289 + }, + { + "id" : 334 + }, + { + "id" : 415 + }, + { + "id" : 414 + }, + { + "id" : 385 + }, + { + "id" : 369 + }, + { + "id" : 377 + }, + { + "id" : 378 + }, + { + "id" : 376 + }, + { + "id" : 437 + }, + { + "id" : 445 + }, + { + "id" : 370 + }, + { + "id" : 341 + }, + { + "id" : 368 + }, + { + "id" : 381 + }, + { + "id" : 399 + }, + { + "id" : 208 + }, + { + "id" : 426 + }, + { + "id" : 339 + }, + { + "id" : 340 + }, + { + "id" : 386 }, { "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCIAAAA=" - }, - { - "id" : 364 - }, - { - "id" : 348 - }, - { - "id" : 759 - }, - { - "id" : 441, - "damage" : 41 - }, - { - "id" : 441, - "damage" : 40 - }, - { - "id" : 294 + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAAAAAA=" }, { "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCIAAAA=" + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAAAAAA=" }, { - "id" : 148 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAAAAAA=" }, { - "id" : 262, - "damage" : 15 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAAAAAA=" }, { - "id" : 746 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAEAAAA=" }, { - "id" : 147 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAEAAAA=" }, { - "id" : 305 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAEAAAA=" }, { - "id" : 262, - "damage" : 31 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAEAAAA=" }, { - "id" : 27 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAIAAAA=" }, { - "id" : 66 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAIAAAA=" }, { - "id" : -280 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAIAAAA=" }, { - "id" : 279 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAIAAAA=" }, { - "id" : 262, - "damage" : 16 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAMAAAA=" }, { - "id" : -281 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAMAAAA=" }, { - "id" : -142 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAMAAAA=" }, { - "id" : 231 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAMAAAA=" }, { - "id" : 223 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAQAAAA=" }, { - "id" : 21 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAQAAAA=" }, { - "id" : -162, - "damage" : 6 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAQAAAA=" }, { - "id" : -162, - "damage" : 7 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAQAAAA=" }, { - "id" : 56 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAUAAAA=" }, { - "id" : -140 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAUAAAA=" }, { - "id" : -264 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAUAAAA=" }, { - "id" : -265 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAYAAAA=" }, { - "id" : 292 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAYAAAA=" }, { - "id" : 383, - "damage" : 58 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAYAAAA=" }, { - "id" : 383, - "damage" : 116 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAcAAAA=" }, { - "id" : 282 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAcAAAA=" }, { - "id" : 459 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAcAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAgAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAkAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAkAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAkAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAkAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAkAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAoAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAoAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAoAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAoAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAoAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZAsAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAwAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAwAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZA8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZA8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZA8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZA8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZA8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBAAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBEAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBEAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBEAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZBMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBUAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBYAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBcAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBcAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBcAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBgAAAA=" }, { "id" : 403, @@ -3409,53 +3995,472 @@ "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBgAAAA=" }, { - "id" : 397, - "damage" : 2 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBkAAAA=" }, { - "id" : 397, - "damage" : 3 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBkAAAA=" }, { - "id" : 441, - "damage" : 17 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBoAAAA=" }, { - "id" : 441, - "damage" : 16 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBsAAAA=" }, { - "id" : -174 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBwAAAA=" }, { - "id" : -139 + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB0AAAA=" }, { - "id" : 179, + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZB0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZB0AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB4AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZB8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB8AAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCAAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCEAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZCIAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCMAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCQAAAA=" + }, + { + "id" : 403, + "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCQAAAA=" + }, + { + "id" : 333 + }, + { + "id" : 333, "damage" : 1 }, { - "id" : 179 + "id" : 333, + "damage" : 2 }, { - "id" : 173 + "id" : 333, + "damage" : 3 }, { - "id" : 38, - "damage" : 5 - }, - { - "id" : 38, + "id" : 333, "damage" : 4 }, { - "id" : 38, + "id" : 333, + "damage" : 5 + }, + { + "id" : 66 + }, + { + "id" : 27 + }, + { + "id" : 28 + }, + { + "id" : 126 + }, + { + "id" : 328 + }, + { + "id" : 342 + }, + { + "id" : 408 + }, + { + "id" : 407 + }, + { + "id" : 331 + }, + { + "id" : 152 + }, + { + "id" : 76 + }, + { + "id" : 69 + }, + { + "id" : 143 + }, + { + "id" : -144 + }, + { + "id" : -141 + }, + { + "id" : -143 + }, + { + "id" : -140 + }, + { + "id" : -142 + }, + { + "id" : 77 + }, + { + "id" : -260 + }, + { + "id" : -261 + }, + { + "id" : -296 + }, + { + "id" : 131 + }, + { + "id" : 72 + }, + { + "id" : -154 + }, + { + "id" : -151 + }, + { + "id" : -153 + }, + { + "id" : -150 + }, + { + "id" : -152 + }, + { + "id" : -262 + }, + { + "id" : -263 + }, + { + "id" : 70 + }, + { + "id" : 147 + }, + { + "id" : 148 + }, + { + "id" : -295 + }, + { + "id" : 251 + }, + { + "id" : 151 + }, + { + "id" : 356 + }, + { + "id" : 404 + }, + { + "id" : 410 + }, + { + "id" : 125, + "damage" : 3 + }, + { + "id" : 23, + "damage" : 3 + }, + { + "id" : 33, + "damage" : 1 + }, + { + "id" : 29, + "damage" : 1 + }, + { + "id" : 46 + }, + { + "id" : 421 + }, + { + "id" : -204 + }, + { + "id" : 446 + }, + { + "id" : 446, + "damage" : 8 + }, + { + "id" : 446, "damage" : 7 }, { - "id" : 38, + "id" : 446, + "damage" : 15 + }, + { + "id" : 446, + "damage" : 12 + }, + { + "id" : 446, + "damage" : 14 + }, + { + "id" : 446, + "damage" : 1 + }, + { + "id" : 446, + "damage" : 4 + }, + { + "id" : 446, + "damage" : 5 + }, + { + "id" : 446, + "damage" : 13 + }, + { + "id" : 446, + "damage" : 9 + }, + { + "id" : 446, + "damage" : 3 + }, + { + "id" : 446, + "damage" : 11 + }, + { + "id" : 446, + "damage" : 10 + }, + { + "id" : 446, + "damage" : 2 + }, + { + "id" : 446, "damage" : 6 }, + { + "id" : 446, + "damage" : 15, + "nbt_b64" : "CgAAAwQAVHlwZQEAAAAA" + }, + { + "id" : 434 + }, + { + "id" : 434, + "damage" : 1 + }, + { + "id" : 434, + "damage" : 2 + }, + { + "id" : 434, + "damage" : 3 + }, + { + "id" : 434, + "damage" : 4 + }, + { + "id" : 434, + "damage" : 5 + }, + { + "id" : 434, + "damage" : 6 + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMAAAAAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 401, + "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" + }, + { + "id" : 402, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IhHR3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 402, + "damage" : 8, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3JST0f/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 402, + "damage" : 7, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KXnZ3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 402, + "damage" : 15, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Lw8PD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, + { + "id" : 402, + "damage" : 12, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Laszr/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + }, { "id" : 402, "damage" : 14, @@ -3463,69 +4468,13 @@ }, { "id" : 402, - "damage" : 12, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Laszr/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 400 - }, - { - "id" : 357 - }, - { - "id" : 350 - }, - { - "id" : 412 - }, - { - "id" : 49 - }, - { - "id" : -289 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBcAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBcAAAA=" - }, - { - "id" : -178 - }, - { - "id" : 108 - }, - { - "id" : -2 - }, - { - "id" : 156 + "damage" : 1, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3ImLrD/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { "id" : 402, - "damage" : 6, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KcnBb/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : -3 - }, - { - "id" : 402, - "damage" : 2, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IWfF7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 402, - "damage" : 3, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IyVIP/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" - }, - { - "id" : 402, - "damage" : 9, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Kqi/P/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "damage" : 4, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KqRDz/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { "id" : 402, @@ -3538,983 +4487,34 @@ "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3K9Tsf/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAADQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : 383, - "damage" : 57 - }, - { - "id" : 3 - }, - { - "id" : 201, - "damage" : 2 - }, - { - "id" : 383, - "damage" : 54 - }, - { - "id" : 213 - }, - { - "id" : 87 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB0AAAA=" - }, - { - "id" : -254 - }, - { - "id" : -4 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBwAAAA=" - }, - { - "id" : 325, - "damage" : 1 - }, - { - "id" : 325 - }, - { - "id" : 441, - "damage" : 27 - }, - { - "id" : -279 - }, - { - "id" : 4 - }, - { - "id" : 346 - }, - { - "id" : 398 - }, - { - "id" : 441, - "damage" : 26 - }, - { - "id" : -223 - }, - { - "id" : 24, - "damage" : 1 - }, - { - "id" : 38, - "damage" : 1 - }, - { - "id" : 38 - }, - { - "id" : -130 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZB0AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZB0AAAA=" - }, - { - "id" : 222 - }, - { - "id" : 219 - }, - { - "id" : 243 - }, - { - "id" : 198 - }, - { - "id" : 397 - }, - { - "id" : 397, - "damage" : 1 - }, - { - "id" : 24 - }, - { - "id" : 325, - "damage" : 2 - }, - { - "id" : 325, - "damage" : 3 - }, - { - "id" : 441, - "damage" : 7 - }, - { - "id" : 441, - "damage" : 2 - }, - { - "id" : 441, - "damage" : 6 - }, - { - "id" : 441, - "damage" : 3 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBEAAAA=" - }, - { - "id" : -220 - }, - { - "id" : -221 - }, - { - "id" : 206 - }, - { - "id" : 98, - "damage" : 3 - }, - { - "id" : 15 - }, - { - "id" : 14 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZBEAAAA=" - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAAAQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 351, - "damage" : 2 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZB8AAAA=" - }, - { - "id" : 441, - "damage" : 31 - }, - { - "id" : 351, - "damage" : 10 - }, - { - "id" : -132 - }, - { - "id" : -132, - "damage" : 1 - }, - { - "id" : 321 - }, - { - "id" : -134 - }, - { - "id" : 754 - }, - { - "id" : 441, - "damage" : 30 - }, - { - "id" : 262, - "damage" : 35 - }, - { - "id" : 53 - }, - { - "id" : -179 - }, - { - "id" : 262, - "damage" : 36 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZB4AAAA=" - }, - { - "id" : -292 - }, - { - "id" : -275 - }, - { - "id" : -175 - }, - { - "id" : 128 - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : -134, - "damage" : 2 - }, - { - "id" : -133, - "damage" : 2 - }, - { - "id" : -133, - "damage" : 1 - }, - { - "id" : 347 - }, - { - "id" : 418 - }, - { - "id" : 419 - }, - { - "id" : 420 - }, - { - "id" : 383, - "damage" : 55 - }, - { - "id" : 383, - "damage" : 42 - }, - { - "id" : 330 - }, - { - "id" : 755 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCMAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZCMAAAA=" - }, - { - "id" : 22 - }, - { - "id" : 155 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZBQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZBQAAAA=" - }, - { - "id" : 383, - "damage" : 32 - }, - { - "id" : 383, - "damage" : 35 - }, - { - "id" : 159, - "damage" : 6 - }, - { - "id" : -170 - }, - { - "id" : -172 - }, - { - "id" : -132, - "damage" : 12 - }, - { - "id" : -132, - "damage" : 11 - }, - { - "id" : 323 - }, - { - "id" : 169 - }, - { - "id" : 513 - }, - { - "id" : 262, - "damage" : 43 - }, - { - "id" : 351, - "damage" : 8 - }, - { - "id" : 351, - "damage" : 16 - }, - { - "id" : 38, - "damage" : 10 - }, - { - "id" : 175 - }, - { - "id" : 441, - "damage" : 13 - }, - { - "id" : 441, - "damage" : 12 - }, - { - "id" : 441, - "damage" : 21 - }, - { - "id" : 1, - "damage" : 2 - }, - { - "id" : 441, - "damage" : 20 - }, - { - "id" : 153 - }, - { - "id" : -273 - }, - { - "id" : 266 - }, - { - "id" : 263 - }, - { - "id" : 129 - }, - { - "id" : 225 - }, - { - "id" : 220 - }, - { - "id" : 120 - }, - { - "id" : 224 - }, - { - "id" : 438, - "damage" : 32 - }, - { - "id" : 438, - "damage" : 31 - }, - { - "id" : 45 - }, - { - "id" : -284 - }, - { - "id" : 371 - }, - { - "id" : 288 - }, - { - "id" : 318 - }, - { - "id" : 355, - "damage" : 14 - }, - { - "id" : 355, - "damage" : 12 - }, - { - "id" : 85, - "damage" : 5 - }, - { - "id" : 241 - }, - { - "id" : 20 - }, - { - "id" : 262, - "damage" : 21 - }, - { - "id" : 262, - "damage" : 22 - }, - { - "id" : 507 - }, - { - "id" : 506 - }, - { - "id" : 503 - }, - { - "id" : 502 - }, - { - "id" : 113 - }, - { - "id" : 107 - }, - { - "id" : 183 - }, - { - "id" : 446, - "damage" : 2 - }, - { - "id" : 446, - "damage" : 10 - }, - { - "id" : 315 - }, - { - "id" : 307 - }, - { - "id" : 355, - "damage" : 5 - }, - { - "id" : 355, - "damage" : 13 - }, - { - "id" : -300 - }, - { - "id" : -247 - }, - { - "id" : -131, - "damage" : 4 - }, - { - "id" : -131 - }, - { - "id" : -298 - }, - { - "id" : 383, - "damage" : 34 - }, - { - "id" : 383, - "damage" : 48 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAsAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZAoAAAA=" - }, - { - "id" : -246 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZAoAAAA=" - }, - { - "id" : 91 - }, - { - "id" : 736 - }, - { - "id" : 373, - "damage" : 7 - }, - { - "id" : 373, - "damage" : 6 - }, - { - "id" : 373, - "damage" : 2 - }, - { - "id" : 373, - "damage" : 3 - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMAAAAAAAAA" - }, - { - "id" : 383, - "damage" : 25 - }, - { - "id" : 383, - "damage" : 26 - }, - { - "id" : 434, - "damage" : 6 - }, - { - "id" : 159, - "damage" : 8 - }, - { - "id" : 159, - "damage" : 7 - }, - { - "id" : -240 - }, - { - "id" : 351, - "damage" : 3 - }, - { - "id" : 351 - }, - { - "id" : -226 - }, - { - "id" : -7 - }, - { - "id" : 17, - "damage" : 3 - }, - { - "id" : -5 - }, - { - "id" : 17, - "damage" : 1 - }, - { - "id" : 300 - }, - { - "id" : 304 - }, - { - "id" : 438, - "damage" : 13 - }, - { - "id" : 438, - "damage" : 14 - }, - { - "id" : 467 - }, - { - "id" : 44, - "damage" : 4 - }, - { - "id" : 468 - }, - { - "id" : 159, - "damage" : 14 - }, - { - "id" : 159, - "damage" : 1 - }, - { - "id" : 262, - "damage" : 26 - }, - { - "id" : 262, - "damage" : 25 - }, - { - "id" : 351, - "damage" : 5 - }, - { - "id" : 351, - "damage" : 18 - }, - { - "id" : 69 - }, - { - "id" : 408 - }, - { - "id" : 76 - }, - { - "id" : 407 - }, - { - "id" : 438, - "damage" : 42 - }, - { - "id" : 44, - "damage" : 7 - }, - { - "id" : -166, - "damage" : 1 - }, - { - "id" : 44, - "damage" : 6 - }, - { - "id" : 218, - "damage" : 5 - }, - { - "id" : 438, - "damage" : 41 - }, - { - "id" : 438, - "damage" : 9 - }, - { - "id" : 218, - "damage" : 4 - }, - { - "id" : 163 - }, - { - "id" : 136 - }, - { - "id" : -201 - }, - { - "id" : 438, - "damage" : 10 - }, - { - "id" : 373, - "damage" : 20 - }, - { - "id" : -200 - }, - { - "id" : 139, - "damage" : 8 - }, - { - "id" : 139, - "damage" : 6 - }, - { - "id" : 373, - "damage" : 21 - }, - { - "id" : 441, - "damage" : 34 - }, - { - "id" : 441, - "damage" : 35 - }, - { - "id" : 241, - "damage" : 2 - }, - { - "id" : 241, - "damage" : 10 - }, - { - "id" : 475 - }, - { - "id" : 262, - "damage" : 39 - }, - { - "id" : 474 - }, - { - "id" : 262, - "damage" : 40 - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAABwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBAACAgBpZA8AAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsBQACAgBpZA8AAAA=" - }, - { - "id" : 401, - "nbt_b64" : "CgAACgkARmlyZXdvcmtzAQYARmxpZ2h0AQkKAEV4cGxvc2lvbnMKAQAAAAcNAEZpcmV3b3JrQ29sb3IBAAAADwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAAA" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAQACAgBpZAYAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZAYAAAA=" - }, - { - "id" : 361 - }, - { - "id" : 395, - "damage" : 2 - }, - { - "id" : 362 - }, - { - "id" : 35, - "damage" : 15 - }, - { - "id" : 35, - "damage" : 12 - }, - { - "id" : 329 - }, - { - "id" : 428 - }, - { - "id" : 383, - "damage" : 123 - }, - { - "id" : 429 - }, - { - "id" : 477 - }, - { - "id" : 383, - "damage" : 126 - }, - { - "id" : 382 - }, - { - "id" : -216 - }, - { - "id" : 175, - "damage" : 5 - }, - { - "id" : -212, - "damage" : 4 + "id" : 402, + "damage" : 9, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Kqi/P/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACQEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { "id" : 402, - "damage" : 8, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3JST0f/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "damage" : 3, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IyVIP/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { "id" : 402, - "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IhHR3/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAAEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" + "damage" : 11, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3I92P7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACwEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : -212, - "damage" : 12 + "id" : 402, + "damage" : 10, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3Ifx4D/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAACgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : -131, - "damage" : 10 + "id" : 402, + "damage" : 2, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3IWfF7/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAAAgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" }, { - "id" : -131, - "damage" : 8 - }, - { - "id" : 13 - }, - { - "id" : 1, - "damage" : 1 - }, - { - "id" : 446, - "damage" : 13 - }, - { - "id" : 446, - "damage" : 9 - }, - { - "id" : -132, - "damage" : 4 - }, - { - "id" : -132, - "damage" : 8 - }, - { - "id" : 122 - }, - { - "id" : -159 - }, - { - "id" : 236, - "damage" : 1 - }, - { - "id" : 236, - "damage" : 14 - }, - { - "id" : 168 - }, - { - "id" : 155, - "damage" : 3 - }, - { - "id" : 262, - "damage" : 7 - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAwACAgBpZCQAAAA=" - }, - { - "id" : 403, - "nbt_b64" : "CgAACQQAZW5jaAoBAAAAAgMAbHZsAgACAgBpZCQAAAA=" - }, - { - "id" : -304 - }, - { - "id" : 262, - "damage" : 8 - }, - { - "id" : 98 - }, - { - "id" : 368 - }, - { - "id" : 341 - }, - { - "id" : 267 - }, - { - "id" : 283 - }, - { - "id" : 44, - "damage" : 5 - }, - { - "id" : -166 - }, - { - "id" : 265 - }, - { - "id" : 452 - }, - { - "id" : 438, - "damage" : 28 - }, - { - "id" : 438, - "damage" : 27 - }, - { - "id" : 235 - }, - { - "id" : 232 - }, - { - "id" : 365 - }, - { - "id" : 78 - }, - { - "id" : -151 - }, - { - "id" : -154 + "id" : 402, + "damage" : 6, + "nbt_b64" : "CgAAAwsAY3VzdG9tQ29sb3KcnBb/Cg0ARmlyZXdvcmtzSXRlbQcNAEZpcmV3b3JrQ29sb3IBAAAABgEMAEZpcmV3b3JrVHlwZQAHDABGaXJld29ya0ZhZGUAAAAAAQ0ARmlyZXdvcmtUcmFpbAABDwBGaXJld29ya0ZsaWNrZXIAAAA=" } ] } \ No newline at end of file From e3e8bb27997b2fb20ba6beaea3d975a7a09ad0fd Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 27 Jun 2020 20:47:10 -0800 Subject: [PATCH 045/104] Fix first item of creative inventory not showing --- .../org/geysermc/connector/network/session/GeyserSession.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 101726f17..b72a4f9b5 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 @@ -226,7 +226,7 @@ public class GeyserSession implements CommandSender { CreativeContentPacket creativePacket = new CreativeContentPacket(); for (int i = 0; i < ItemRegistry.CREATIVE_ITEMS.length; i++) { - creativePacket.getEntries().put(i, ItemRegistry.CREATIVE_ITEMS[i]); + creativePacket.getEntries().put(i + 1, ItemRegistry.CREATIVE_ITEMS[i]); } upstream.sendPacket(creativePacket); From 6e94428f6013c621324cc9f751e2e42d14f301ac Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 28 Jun 2020 01:53:35 -0400 Subject: [PATCH 046/104] Non-working smithing table inventory support --- .../GrindstoneInventoryTranslator.java | 3 +- .../inventory/InventoryTranslator.java | 1 + .../SmithingInventoryTranslator.java | 70 +++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/inventory/SmithingInventoryTranslator.java 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 6e729c39c..4b4a12465 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,6 +25,7 @@ package org.geysermc.connector.network.translators.inventory; +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; @@ -38,7 +39,7 @@ public class GrindstoneInventoryTranslator extends BlockInventoryTranslator { @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 37621647e..7d06aed14 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 @@ -55,6 +55,7 @@ public abstract class InventoryTranslator { 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/SmithingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/SmithingInventoryTranslator.java new file mode 100644 index 000000000..f347ccae1 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/SmithingInventoryTranslator.java @@ -0,0 +1,70 @@ +/* + * 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.ContainerType; +import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; +import org.geysermc.connector.network.translators.inventory.updater.CursorInventoryUpdater; + +public class SmithingInventoryTranslator extends BlockInventoryTranslator { + + public SmithingInventoryTranslator() { + super(3, "minecraft:smithing_table", ContainerType.SMITHING_TABLE, new CursorInventoryUpdater()); + } + + @Override + public int bedrockSlotToJava(InventoryActionData action) { + final int slot = super.bedrockSlotToJava(action); + if (action.getSource().getContainerId() == ContainerId.UI) { + switch (slot) { + case 51: + return 0; + case 52: + return 1; + case 50: + return 2; + default: + return slot; + } + } return slot; + } + + @Override + public int javaSlotToBedrock(int slot) { + switch (slot) { + case 0: + return 51; + case 1: + return 52; + case 2: + return 50; + } + return super.javaSlotToBedrock(slot); + } + +} From 1410b67189ef01d676d5db04fe20b01e631b8c1f Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sat, 27 Jun 2020 22:36:41 -0800 Subject: [PATCH 047/104] Update mappings submodule Fixes shulker boxes --- connector/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 22f98579c..a1b44a958 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 22f98579c0ef0ed6f8d768393e4af478a76db40e +Subproject commit a1b44a958ab42fdc2416bfbacc0fbf155ed58d46 From 9569416124b355592c541046f30ea646f7e74599 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 28 Jun 2020 14:57:41 +0100 Subject: [PATCH 048/104] Fix chat formatting and team colors --- .../translators/java/JavaChatTranslator.java | 6 +- .../connector/utils/MessageUtils.java | 186 ++++++++++-------- 2 files changed, 111 insertions(+), 81 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java index 4787d6984..d222d729b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java @@ -65,14 +65,14 @@ public class JavaChatTranslator extends PacketTranslator { textPacket.setType(TextPacket.Type.TRANSLATION); textPacket.setNeedsTranslation(true); - List paramsTranslated = MessageUtils.getTranslationParams(((TranslationMessage) packet.getMessage()).getWith(), 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/utils/MessageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java index 6e995b4bb..96775f245 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -32,23 +32,21 @@ 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.github.steveice10.mc.protocol.data.message.style.MessageStyle; -import com.google.gson.*; +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.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MessageUtils { private static final Map COLORS = new HashMap<>(); + private static final Map TEAM_COLORS = new HashMap<>(); static { COLORS.put(ChatColor.BLACK, 0x000000); @@ -67,11 +65,42 @@ public class MessageUtils { COLORS.put(ChatColor.LIGHT_PURPLE, 0xff55ff); COLORS.put(ChatColor.YELLOW, 0xffff55); COLORS.put(ChatColor.WHITE, 0xffffff); - }; - public static List getTranslationParams(List messages, String locale) { + 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; @@ -88,7 +117,20 @@ public class MessageUtils { strings.add(" - no permission or invalid command!"); } - List furtherParams = getTranslationParams(translation.getWith(), 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.getKey(), locale), furtherParams)); } else { @@ -96,8 +138,8 @@ public class MessageUtils { } } 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); } } @@ -105,22 +147,32 @@ public class MessageUtils { return strings; } - public static List getTranslationParams(List messages) { - return getTranslationParams(messages, null); - } - - public static String getTranslationText(TranslationMessage message) { - return getFormat(message.getStyle().getFormats()) + getColorOrParent(message.getStyle()) - + "%" + message.getKey(); + public static String getTranslatedBedrockMessage(Message message, String locale) { + return getTranslatedBedrockMessage(message, locale, true); } public static String getTranslatedBedrockMessage(Message message, String locale, boolean shouldTranslate) { + return getTranslatedBedrockMessage(message, locale, shouldTranslate, null); + } + + /** + * 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.toString())) { JsonObject object = parser.parse(message.toString()).getAsJsonObject(); - message = MessageSerializer.fromJson(formatJson(object)); + message = MessageSerializer.fromJson(object); } + message = fixMessageStyle(message, parent); + String messageText = (message instanceof TranslationMessage) ? ((TranslationMessage) message).getKey() : ((TextMessage) message).getText(); if (locale != null && shouldTranslate) { messageText = LocaleUtils.getLocaleString(messageText, locale); @@ -128,21 +180,21 @@ public class MessageUtils { 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())); + builder.append(getColor(msg.getStyle().getColor())); if (!(msg.toString() == null)) { boolean isTranslationMessage = (msg instanceof TranslationMessage); String extraText = ""; if (isTranslationMessage) { - List paramsTranslated = getTranslationParams(((TranslationMessage) msg).getWith(), 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); @@ -153,8 +205,36 @@ public class MessageUtils { 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) { @@ -225,22 +305,6 @@ public class MessageUtils { 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) { - String color = style.getColor(); - - /*if (color == ChatColor.NONE && style.getParent() != null) { - return getColorOrParent(style.getParent()); - }*/ - - return getColor(color); - } - /** * Convert a ChatColor into a string for inserting into messages * @@ -400,7 +464,7 @@ public class MessageUtils { try { JsonObject object = parser.parse(text).getAsJsonObject(); try { - MessageSerializer.fromJson(formatJson(object)); + MessageSerializer.fromJson(object); } catch (Exception ex) { return false; } @@ -410,42 +474,8 @@ public class MessageUtils { 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.) { -// 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)); -// } -// } Not dealing with this - return ""; + return TEAM_COLORS.getOrDefault(teamColor, ""); } /** From 2df3d4cbca52c3b28ddb77ce006299ed8ce4db31 Mon Sep 17 00:00:00 2001 From: Tim203 Date: Sun, 28 Jun 2020 16:44:57 +0200 Subject: [PATCH 049/104] Update to the latest MCProtocolLib commit --- connector/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/pom.xml b/connector/pom.xml index 76e02e2aa..ddc62bf2a 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.GeyserMC MCProtocolLib - feature~1.16-SNAPSHOT + feature~1.16-1.12.1-1-g74ee57a-310 compile From 980e82a2d9f37a5949e0c79a64f5a9dab45aee04 Mon Sep 17 00:00:00 2001 From: D3ATHBRINGER13 <53559772+D3ATHBRINGER13@users.noreply.github.com> Date: Sun, 28 Jun 2020 16:52:53 +0100 Subject: [PATCH 050/104] Replace Bukkit with Spigot (#831) --- connector/src/main/resources/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index e0e0771da..eb4c1ddca 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -85,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 From 8e8bc2817a4e18cb4c475d47d7db3e0af985f327 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 28 Jun 2020 12:34:57 -0500 Subject: [PATCH 051/104] Return if sound is null and update mappings --- .../translators/java/world/JavaPlayBuiltinSoundTranslator.java | 3 ++- connector/src/main/resources/mappings | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) 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 f51e35fe6..d849c9179 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 class JavaPlayBuiltinSoundTranslator extends PacketTranslator Date: Sun, 28 Jun 2020 13:33:38 -0800 Subject: [PATCH 052/104] Fix some recipes with multiple ingredient options --- .../network/translators/java/JavaDeclareRecipesTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c29632de7..15f0e496e 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 @@ -119,7 +119,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator Date: Sun, 28 Jun 2020 23:38:27 +0100 Subject: [PATCH 053/104] Fix disconnect message formatting --- .../geysermc/connector/network/session/GeyserSession.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 b72a4f9b5..1fe5dec8b 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 @@ -32,6 +32,7 @@ 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.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; @@ -52,10 +53,10 @@ import it.unimi.dsi.fastutil.objects.Object2LongMap; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import lombok.Getter; import lombok.Setter; -import org.geysermc.connector.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; @@ -366,7 +367,8 @@ public class GeyserSession implements CommandSender { if (event.getCause() != null) { event.getCause().printStackTrace(); } - upstream.disconnect(event.getReason()); + + upstream.disconnect(MessageUtils.getBedrockMessage(MessageSerializer.fromString(event.getReason()))); } @Override From 12d5982c57159cc21de6988adcc536eea95d7c31 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Sun, 28 Jun 2020 16:14:57 -0800 Subject: [PATCH 054/104] Anvil fixes --- .../inventory/AnvilInventoryTranslator.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) 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 74710d45a..c5d1de252 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 @@ -30,15 +30,13 @@ 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.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.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() { @@ -57,6 +55,9 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { return 2; } } + if (action.getSource().getContainerId() == ContainerId.ANVIL_RESULT) { + return 2; + } return super.bedrockSlotToJava(action); } @@ -112,7 +113,13 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { session.sendDownstreamPacket(renameItemPacket); } if (anvilResult != null) { - //client will send another packet to grab anvil output + //Strip unnecessary actions + 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; } @@ -121,7 +128,7 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { @Override public void updateSlot(GeyserSession session, Inventory inventory, int slot) { - if (slot >= 0 && slot <= 2) { + if (slot == 0) { ItemStack item = inventory.getItem(slot); if (item != null) { String rename; From f2f59e4e3775dff8a24e01dbedca59634027e188 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 28 Jun 2020 23:44:38 -0400 Subject: [PATCH 055/104] Fill in renamed villager trading values (villager trading UI now opens) --- .../translators/java/world/JavaTradeListTranslator.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 index 7c80d104b..d9d23f323 100644 --- 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 @@ -70,9 +70,9 @@ public class JavaTradeListTranslator extends PacketTranslator Date: Mon, 29 Jun 2020 13:50:16 +0100 Subject: [PATCH 056/104] Clean chat code and fix skins --- connector/pom.xml | 2 +- .../connector/utils/MessageUtils.java | 19 +++++++------------ .../geysermc/connector/utils/SkinUtils.java | 1 + 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index ddc62bf2a..09171248a 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.GeyserMC MCProtocolLib - feature~1.16-1.12.1-1-g74ee57a-310 + feature~1.16-1.12.1-1-ge4798a3-318 compile 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 96775f245..3a35782d4 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -32,6 +32,7 @@ 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.github.steveice10.mc.protocol.data.message.style.MessageStyle; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import net.kyori.text.Component; @@ -216,25 +217,19 @@ public class MessageUtils { if (parent == null) { return message; } - Message newMessage = message; + MessageStyle.Builder styleBuilder = message.getStyle().toBuilder(); // 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); + if (message.getStyle().getColor() == ChatColor.NONE) { + styleBuilder.color(parent.getStyle().getColor()); } // 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); + if (message.getStyle().getFormats().size() == 0) { + styleBuilder.formats(parent.getStyle().getFormats()); } - return newMessage; + return message.toBuilder().style(styleBuilder.build()).build(); } public static String getBedrockMessage(Message message) { 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 ae17ed205..9e0712477 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -96,6 +96,7 @@ public class SkinUtils { entry.setXuid(""); entry.setPlatformChatId(""); entry.setTeacher(false); + entry.setTrustedSkin(true); return entry; } From 91c33242c6f91122a915f67ac6f5ee5a06052b11 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 29 Jun 2020 14:40:06 +0100 Subject: [PATCH 057/104] Fix baby states and collisions of 1.16 mobs --- .../entity/living/animal/StriderEntity.java | 1 - .../entity/living/monster/HoglinEntity.java | 52 +++++++++++++++++++ .../entity/living/monster/ZoglinEntity.java | 36 +++++++++++++ .../connector/entity/type/EntityType.java | 10 ++-- 4 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java 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 index 18bb8166e..abf6758a2 100644 --- 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 @@ -40,7 +40,6 @@ public class StriderEntity extends AnimalEntity { @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 18) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java new file mode 100644 index 000000000..10faebc78 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java @@ -0,0 +1,52 @@ +/* + * 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.monster; + +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 com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +public class HoglinEntity extends MonsterEntity { + + public HoglinEntity(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() == 15) { + boolean isBaby = (boolean) entityMetadata.getValue(); + if (isBaby) { + metadata.put(EntityData.SCALE, .55f); + metadata.getFlags().setFlag(EntityFlag.BABY, true); + } + } + super.updateBedrockMetadata(entityMetadata, session); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java new file mode 100644 index 000000000..b60a39521 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java @@ -0,0 +1,36 @@ +/* + * 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.monster; + +import com.nukkitx.math.vector.Vector3f; +import org.geysermc.connector.entity.type.EntityType; + +public class ZoglinEntity extends HoglinEntity { + + public ZoglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + } +} 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 4ec3471c7..70c76038d 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), - ZOMBIFIED_PIGLIN(MonsterEntity.class, 0, 1.8f, 0.6f, 0.6f, 1.62f, "minecraft:zombie_pigman"), + ZOMBIFIED_PIGLIN(ZombieEntity.class, 36, 1.95f, 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), @@ -151,10 +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 + STRIDER(StriderEntity.class, 125, 1.7f, 0.9f, 0f, 0f, "minecraft:strider"), //TODO - update entity metadata + HOGLIN(HoglinEntity.class, 124, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:hoglin"), //TODO + ZOGLIN(ZoglinEntity.class, 126, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:zoglin"), //TODO + PIGLIN(ZombieEntity.class, 123, 1.95f, 0.6f, 0.6f, 0f, "minecraft:piglin"), //TODO /** * Item frames are handled differently since they are a block in Bedrock. From d394cc6280ca0a3c7e4e9cc9feee6d968a765554 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 29 Jun 2020 15:37:54 +0100 Subject: [PATCH 058/104] Update entity metadata --- .../entity/living/animal/StriderEntity.java | 3 +++ .../{HoglinEntity.java => PiglinEntity.java} | 11 +++++++++-- .../entity/living/monster/ZoglinEntity.java | 18 +++++++++++++++++- .../connector/entity/type/EntityType.java | 4 ++-- 4 files changed, 31 insertions(+), 5 deletions(-) rename connector/src/main/java/org/geysermc/connector/entity/living/monster/{HoglinEntity.java => PiglinEntity.java} (84%) 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 index abf6758a2..e3ef9b501 100644 --- 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 @@ -40,6 +40,9 @@ public class StriderEntity extends AnimalEntity { @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { + if (entityMetadata.getId() == 17) { + metadata.getFlags().setFlag(EntityFlag.ALWAYS_SHOW_NAME, (boolean) entityMetadata.getValue()); + } if (entityMetadata.getId() == 18) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java similarity index 84% rename from connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java rename to connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java index 10faebc78..78a420b8c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/HoglinEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/PiglinEntity.java @@ -32,9 +32,9 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -public class HoglinEntity extends MonsterEntity { +public class PiglinEntity extends MonsterEntity { - public HoglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + public PiglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } @@ -47,6 +47,13 @@ public class HoglinEntity extends MonsterEntity { metadata.getFlags().setFlag(EntityFlag.BABY, true); } } + if (entityMetadata.getId() == 17) { + metadata.getFlags().setFlag(EntityFlag.CHARGING, (boolean) entityMetadata.getValue()); + } + if (entityMetadata.getId() == 18) { + metadata.getFlags().setFlag(EntityFlag.DANCING, (boolean) entityMetadata.getValue()); + } + super.updateBedrockMetadata(entityMetadata, session); } } diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java index b60a39521..4ea842110 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZoglinEntity.java @@ -25,12 +25,28 @@ package org.geysermc.connector.entity.living.monster; +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 com.nukkitx.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; -public class ZoglinEntity extends HoglinEntity { +public class ZoglinEntity extends MonsterEntity { public ZoglinEntity(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() == 15) { + boolean isBaby = (boolean) entityMetadata.getValue(); + if (isBaby) { + metadata.put(EntityData.SCALE, .55f); + metadata.getFlags().setFlag(EntityFlag.BABY, true); + } + } + super.updateBedrockMetadata(entityMetadata, session); + } } 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 70c76038d..1acf579f1 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 @@ -152,9 +152,9 @@ public enum EntityType { FOX(FoxEntity.class, 121, 0.5f, 1.25f), BEE(BeeEntity.class, 122, 0.6f, 0.6f), STRIDER(StriderEntity.class, 125, 1.7f, 0.9f, 0f, 0f, "minecraft:strider"), //TODO - update entity metadata - HOGLIN(HoglinEntity.class, 124, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:hoglin"), //TODO + HOGLIN(AnimalEntity.class, 124, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:hoglin"), //TODO ZOGLIN(ZoglinEntity.class, 126, 1.4f, 1.3965f, 1.3965f, 0f, "minecraft:zoglin"), //TODO - PIGLIN(ZombieEntity.class, 123, 1.95f, 0.6f, 0.6f, 0f, "minecraft:piglin"), //TODO + PIGLIN(PiglinEntity.class, 123, 1.95f, 0.6f, 0.6f, 0f, "minecraft:piglin"), //TODO /** * Item frames are handled differently since they are a block in Bedrock. From e77f2b5dbbbcbedcff3c96e416acaa07c000a5ca Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Jun 2020 10:59:51 -0800 Subject: [PATCH 059/104] Drop long array nbt tag when translating to bedrock --- .../connector/network/translators/item/ItemTranslator.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 6f11e94ac..aa75e1499 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -253,8 +253,10 @@ public abstract class ItemTranslator { } if (tag instanceof LongArrayTag) { - LongArrayTag longArrayTag = (LongArrayTag) tag; - return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue()); + //Long array tag does not exist in BE + //LongArrayTag longArrayTag = (LongArrayTag) tag; + //return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue()); + return null; } if (tag instanceof LongTag) { From ebc1f13e9b775bc103e36279d6d0e777c4f8e7ca Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 16:03:54 -0400 Subject: [PATCH 060/104] Update dependencies ('item marked as non-null' error is fixed') --- connector/pom.xml | 2 +- connector/src/main/resources/mappings | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 09171248a..b4816361f 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -105,7 +105,7 @@ com.github.GeyserMC MCProtocolLib - feature~1.16-1.12.1-1-ge4798a3-318 + feature~1.16-1.12.1-1-g10bb8e2-319 compile diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 204c8f8df..fdc656079 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 204c8f8dfdb1e39b881986c4968aa2575fbb5400 +Subproject commit fdc65607994b924261f43170f4d4d563b14167d7 From fc4a87a9c902e7c63d4539930060788f1fbfcc74 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 16:46:29 -0400 Subject: [PATCH 061/104] Fix blocks not updating --- .../src/main/java/org/geysermc/connector/utils/ChunkUtils.java | 1 + 1 file changed, 1 insertion(+) 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 9cab8605d..5c426cb9b 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -211,6 +211,7 @@ public class ChunkUtils { updateBlockPacket.setBlockPosition(position); updateBlockPacket.setRuntimeId(blockId); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); session.sendUpstreamPacket(updateBlockPacket); UpdateBlockPacket waterPacket = new UpdateBlockPacket(); From 4c89a8e30319631e2f3d0024b2b7739adc7886d2 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 17:52:59 -0400 Subject: [PATCH 062/104] Return to using Protocol develop branch --- connector/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index b4816361f..70ad0e26d 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -31,9 +31,9 @@ compile - com.github.bundabrg.Protocol + com.nukkitx.protocol bedrock-v407 - feature~1.16-protocol-SNAPSHOT + 2.6.0-SNAPSHOT compile From 7710261b70d864429edcb887254f20be60ffc4ff Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 30 Jun 2020 00:52:32 +0100 Subject: [PATCH 063/104] Add Loadstone Compass tracking --- ...tionTrackingDBClientRequestTranslator.java | 82 ++++++++++++ .../translators/item/ItemRegistry.java | 3 + .../item/translators/CompassTranslator.java | 121 ++++++++++++++++++ .../connector/utils/LoadstoneTracker.java | 84 ++++++++++++ 4 files changed, 290 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java new file mode 100644 index 000000000..1ca467206 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java @@ -0,0 +1,82 @@ +/* + * 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.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.tag.IntTag; +import com.nukkitx.protocol.bedrock.packet.PositionTrackingDBClientRequestPacket; +import com.nukkitx.protocol.bedrock.packet.PositionTrackingDBServerBroadcastPacket; +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.DimensionUtils; +import org.geysermc.connector.utils.LoadstoneTracker; + +import java.util.ArrayList; +import java.util.List; + +@Translator(packet = PositionTrackingDBClientRequestPacket.class) +public class BedrockPositionTrackingDBClientRequestTranslator extends PacketTranslator { + + @Override + public void translate(PositionTrackingDBClientRequestPacket packet, GeyserSession session) { + PositionTrackingDBServerBroadcastPacket broadcastPacket = new PositionTrackingDBServerBroadcastPacket(); + broadcastPacket.setTrackingId(packet.getTrackingId()); + + // Fetch the stored Loadstone + LoadstoneTracker.LoadstonePos pos = LoadstoneTracker.getPos(packet.getTrackingId()); + + // If we don't have data for that ID tell the client its not found + if (pos == null) { + broadcastPacket.setAction(PositionTrackingDBServerBroadcastPacket.Action.NOT_FOUND); + session.sendUpstreamPacket(broadcastPacket); + return; + } + + broadcastPacket.setAction(PositionTrackingDBServerBroadcastPacket.Action.UPDATE); + + // Build the nbt data for the update + CompoundTagBuilder builder = CompoundTagBuilder.builder(); + builder.intTag("dim", DimensionUtils.javaToBedrock(pos.getDimension())); + builder.stringTag("id", String.format("%08X", packet.getTrackingId())); + + builder.byteTag("version", (byte) 1); // Not sure what this is for + builder.byteTag("status", (byte) 0); // Not sure what this is for + + // Build the position for the update + List posList = new ArrayList<>(); + posList.add(new IntTag("", pos.getX())); + posList.add(new IntTag("", pos.getY())); + posList.add(new IntTag("", pos.getZ())); + + builder.listTag("pos", IntTag.class, posList); + + broadcastPacket.setTag(builder.buildRootTag()); + + session.sendUpstreamPacket(broadcastPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index db5bc1b34..2dbc945c3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -133,6 +133,9 @@ public class ItemRegistry { itemIndex++; } + // Add the loadstonecompass since it doesn't exist on java but we need it for item conversion + ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestonecompass", itemIndex, 741, 0, false)); + /* Load creative items */ stream = FileUtils.getResource("bedrock/creative_items.json"); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.java new file mode 100644 index 000000000..675d42555 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/CompassTranslator.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.network.translators.item.translators; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.opennbt.tag.builtin.*; +import com.nukkitx.protocol.bedrock.data.inventory.ItemData; +import org.geysermc.connector.network.translators.ItemRemapper; +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 org.geysermc.connector.utils.LoadstoneTracker; + +import java.util.List; +import java.util.stream.Collectors; + +@ItemRemapper +public class CompassTranslator extends ItemTranslator { + + private List appliedItems; + + public CompassTranslator() { + appliedItems = ItemRegistry.ITEM_ENTRIES.values().stream().filter(entry -> entry.getJavaIdentifier().endsWith("compass")).collect(Collectors.toList()); + } + + @Override + public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) { + if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry); + + Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked"); + if (lodestoneTag instanceof ByteTag) { + // Get the fake lodestonecompass entry + itemEntry = ItemRegistry.getItemEntry("minecraft:lodestonecompass"); + + // Get the loadstone pos + CompoundTag loadstonePos = itemStack.getNbt().get("LodestonePos"); + if (loadstonePos != null) { + // Get all info needed for tracking + int x = ((IntTag) loadstonePos.get("X")).getValue(); + int y = ((IntTag) loadstonePos.get("Y")).getValue(); + int z = ((IntTag) loadstonePos.get("Z")).getValue(); + String dim = ((StringTag) itemStack.getNbt().get("LodestoneDimension")).getValue(); + + // Store the info + int trackID = LoadstoneTracker.store(x, y, z, dim); + + // Set the bedrock tracking id + itemStack.getNbt().put(new IntTag("trackingHandle", trackID)); + } else { + // The loadstone was removed just set the tracking id to 0 + itemStack.getNbt().put(new IntTag("trackingHandle", 0)); + } + } + + ItemData itemData = super.translateToBedrock(itemStack, itemEntry); + + return itemData; + } + + @Override + public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) { + boolean isLoadstone = false; + if (itemEntry.getJavaIdentifier().equals("minecraft:lodestonecompass")) { + // Revert the entry back to the compass + itemEntry = ItemRegistry.getItemEntry("minecraft:compass"); + + isLoadstone = true; + } + + ItemStack itemStack = super.translateToJava(itemData, itemEntry); + + if (isLoadstone) { + // Get the tracking id + int trackingID = ((IntTag) itemStack.getNbt().get("trackingHandle")).getValue(); + + // Fetch the tracking info from the id + LoadstoneTracker.LoadstonePos pos = LoadstoneTracker.getPos(trackingID); + if (pos != null) { + // Build the new NBT data for the fetched tracking info + itemStack.getNbt().put(new StringTag("LodestoneDimension", pos.getDimension())); + + CompoundTag posTag = new CompoundTag("LodestonePos"); + posTag.put(new IntTag("X", pos.getX())); + posTag.put(new IntTag("Y", pos.getY())); + posTag.put(new IntTag("Z", pos.getZ())); + + itemStack.getNbt().put(posTag); + } + } + + return itemStack; + } + + @Override + public List getAppliedItems() { + return appliedItems; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java b/connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java new file mode 100644 index 000000000..3bd547654 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/LoadstoneTracker.java @@ -0,0 +1,84 @@ +/* + * 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 it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +public class LoadstoneTracker { + + private static final Int2ObjectMap LOADSTONES = new Int2ObjectOpenHashMap<>(); + + /** + * Store the given coordinates and dimensions + * + * @param x The X position of the Loadstone + * @param y The Y position of the Loadstone + * @param z The Z position of the Loadstone + * @param dim The dimension containing of the Loadstone + * @return The id in the Map + */ + public static int store(int x, int y, int z, String dim) { + LoadstonePos pos = new LoadstonePos(x, y, z, dim); + + if (!LOADSTONES.containsValue(pos)) { + // Start at 1 as 0 seems to not work + LOADSTONES.put(LOADSTONES.size() + 1, pos); + } + + for (Int2ObjectMap.Entry loadstone : LOADSTONES.int2ObjectEntrySet()) { + if (loadstone.getValue().equals(pos)) { + return loadstone.getIntKey(); + } + } + + return 0; + } + + /** + * Get the loadstone data + * + * @param id The ID to get the data for + * @return The stored data + */ + public static LoadstonePos getPos(int id) { + return LOADSTONES.get(id); + } + + @Getter + @AllArgsConstructor + @EqualsAndHashCode + public static class LoadstonePos { + int x; + int y; + int z; + String dimension; + } +} \ No newline at end of file From 95144266d268e50e4cc80a06b14702d3a156394b Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Jun 2020 16:34:07 -0800 Subject: [PATCH 064/104] Handle int tag for enchantment level --- .../item/translators/nbt/EnchantmentTranslator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java index 404d7824c..b4846f5c6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java @@ -122,7 +122,7 @@ public class EnchantmentTranslator extends NbtItemStackTranslator { private CompoundTag remapEnchantment(CompoundTag tag) { Tag javaEnchLvl = tag.get("lvl"); - if (!(javaEnchLvl instanceof ShortTag)) + if (!(javaEnchLvl instanceof ShortTag || javaEnchLvl instanceof IntTag)) return null; Tag javaEnchId = tag.get("id"); @@ -137,7 +137,7 @@ public class EnchantmentTranslator extends NbtItemStackTranslator { CompoundTag bedrockTag = new CompoundTag(""); bedrockTag.put(new ShortTag("id", (short) enchantment.ordinal())); - bedrockTag.put(new ShortTag("lvl", ((ShortTag) javaEnchLvl).getValue())); + bedrockTag.put(new ShortTag("lvl", ((Number) javaEnchLvl.getValue()).shortValue())); return bedrockTag; } From eb3bde15a76ea25414419593732d0896b41e56d4 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 29 Jun 2020 16:54:19 -0800 Subject: [PATCH 065/104] Fix stored enchantments accidentally being dropped --- .../translators/item/translators/nbt/EnchantmentTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java index b4846f5c6..6bd9cc77e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/EnchantmentTranslator.java @@ -114,7 +114,7 @@ public class EnchantmentTranslator extends NbtItemStackTranslator { itemTag.put(new ListTag("Enchantments", enchantments)); } if (!storedEnchantments.isEmpty()) { - itemTag.put(new ListTag("StoredEnchantments", enchantments)); + itemTag.put(new ListTag("StoredEnchantments", storedEnchantments)); } itemTag.remove("ench"); } From ba6adc988be440639d2d717517c884404bdf274e Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 29 Jun 2020 21:33:42 -0400 Subject: [PATCH 066/104] Strider mounting fixes; update mappings This commit refactors health visual logic to make it a global system for each living entity. --- .../connector/entity/LivingEntity.java | 38 +++++++++++++++++++ .../entity/living/animal/PigEntity.java | 35 +---------------- .../animal/horse/AbstractHorseEntity.java | 37 ------------------ .../JavaEntitySetPassengersTranslator.java | 6 +++ connector/src/main/resources/mappings | 2 +- 5 files changed, 47 insertions(+), 71 deletions(-) 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 3d1a1456f..32aa34358 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,23 @@ 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.AttributeData; 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 com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket; import lombok.Getter; import lombok.Setter; +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; @Getter @Setter @@ -98,4 +106,34 @@ public class LivingEntity extends Entity { session.sendUpstreamPacket(handPacket); session.sendUpstreamPacket(offHandPacket); } + + @Override + public void updateBedrockAttributes(GeyserSession session) { + if (!valid) return; + + float maxHealth = this.attributes.containsKey(AttributeType.MAX_HEALTH) ? this.attributes.get(AttributeType.MAX_HEALTH).getValue() : getDefaultMaxHealth(); + + List attributes = new ArrayList<>(); + for (Map.Entry entry : this.attributes.entrySet()) { + if (!entry.getValue().getType().isBedrockAttribute()) + continue; + + attributes.add(AttributeUtils.getBedrockAttribute(entry.getValue())); + } + // Add health attribute to properly show hearts when mounting + attributes.add(new AttributeData("minecraft:health", 0.0f, maxHealth, metadata.getFloat(EntityData.HEALTH, 20f), maxHealth)); + + UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); + updateAttributesPacket.setRuntimeEntityId(geyserId); + updateAttributesPacket.setAttributes(attributes); + session.sendUpstreamPacket(updateAttributesPacket); + } + + /** + * Used for the health visual when mounting an entity. + * @return the default maximum health for the entity. + */ + protected float getDefaultMaxHealth() { + return 20f; + } } 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 0a7c83e75..9b9701f8a 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,33 +27,18 @@ 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.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()); @@ -62,23 +47,7 @@ public class PigEntity extends AnimalEntity { } @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); + protected float getDefaultMaxHealth() { + return 10f; } } 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 48586c78f..e08f9adf0 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,24 +27,13 @@ package org.geysermc.connector.entity.living.animal.horse; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; -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; 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 AbstractHorseEntity extends AnimalEntity { - // For updating the horse visual easier - private float health = 20f; - public AbstractHorseEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); } @@ -52,11 +41,6 @@ public class AbstractHorseEntity extends AnimalEntity { @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { - if (entityMetadata.getId() == 8) { - health = (float) entityMetadata.getValue(); - updateBedrockAttributes(session); - } - if (entityMetadata.getId() == 16) { byte xd = (byte) entityMetadata.getValue(); metadata.getFlags().setFlag(EntityFlag.TAMED, (xd & 0x02) == 0x02); @@ -71,25 +55,4 @@ public class AbstractHorseEntity extends AnimalEntity { 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/network/translators/java/entity/JavaEntitySetPassengersTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntitySetPassengersTranslator.java index 8eab10f5a..ec3ca8318 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 @@ -140,8 +140,14 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator Date: Tue, 30 Jun 2020 13:20:03 +0100 Subject: [PATCH 067/104] Fix Zombified Piglin fire flicker --- .../org/geysermc/connector/entity/Entity.java | 2 +- .../entity/living/animal/StriderEntity.java | 2 + .../living/monster/ZombifiedPiglinEntity.java | 39 +++++++++++++++++++ .../connector/entity/type/EntityType.java | 2 +- .../translators/item/ItemRegistry.java | 5 ++- 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java 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 4d4d097f0..6ae9c6717 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -260,7 +260,7 @@ public class Entity { case 0: if (entityMetadata.getType() == MetadataType.BYTE) { byte xd = (byte) entityMetadata.getValue(); - metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01); + metadata.getFlags().setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !metadata.getFlags().getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire 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().getFlag(EntityFlag.SPRINTING)); // Otherwise swimming is enabled on older servers 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 index e3ef9b501..9d8a6220b 100644 --- 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 @@ -36,6 +36,8 @@ 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); + + metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true); } @Override diff --git a/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java new file mode 100644 index 000000000..01693170a --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/living/monster/ZombifiedPiglinEntity.java @@ -0,0 +1,39 @@ +/* + * 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.monster; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.entity.EntityFlag; +import org.geysermc.connector.entity.type.EntityType; + +public class ZombifiedPiglinEntity extends ZombieEntity { + + public ZombifiedPiglinEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { + super(entityId, geyserId, entityType, position, motion, rotation); + + metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true); + } +} 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 1acf579f1..6bc1a1b0b 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), - ZOMBIFIED_PIGLIN(ZombieEntity.class, 36, 1.95f, 0.6f, 0.6f, 1.62f, "minecraft:zombie_pigman"), + ZOMBIFIED_PIGLIN(ZombifiedPiglinEntity.class, 36, 1.95f, 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), diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index 2dbc945c3..aebf19797 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -198,7 +198,10 @@ public class ItemRegistry { } } - GeyserConnector.getInstance().getLogger().debug("Missing mapping for bedrock item " + data.getId() + ":" + data.getDamage()); + // This will hide the message when the player clicks with an empty hand + if (data.getId() != 0 && data.getDamage() != 0) { + GeyserConnector.getInstance().getLogger().debug("Missing mapping for bedrock item " + data.getId() + ":" + data.getDamage()); + } return ItemEntry.AIR; } From e7fae53552127521870856dd7096e4eb2374be03 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 30 Jun 2020 13:51:44 +0100 Subject: [PATCH 068/104] Fix Strider shaking --- .../connector/entity/living/animal/StriderEntity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 index 9d8a6220b..bb4daf545 100644 --- 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 @@ -38,12 +38,14 @@ public class StriderEntity extends AnimalEntity { super(entityId, geyserId, entityType, position, motion, rotation); metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true); + metadata.getFlags().setFlag(EntityFlag.BREATHING, true); } @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 17) { - metadata.getFlags().setFlag(EntityFlag.ALWAYS_SHOW_NAME, (boolean) entityMetadata.getValue()); + metadata.getFlags().setFlag(EntityFlag.BREATHING, !(boolean) entityMetadata.getValue()); + metadata.getFlags().setFlag(EntityFlag.SHAKING, (boolean) entityMetadata.getValue()); } if (entityMetadata.getId() == 18) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); From 4c2a8789afae978b79af3fa5a1e3324aab751029 Mon Sep 17 00:00:00 2001 From: D3ATHBRINGER13 <53559772+D3ATHBRINGER13@users.noreply.github.com> Date: Tue, 30 Jun 2020 16:22:39 +0100 Subject: [PATCH 069/104] Update Bedrock Version (#868) * Update Bedrock Version * Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5cf34473d..a22a7a8d0 100644 --- a/README.md +++ b/README.md @@ -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.16.0 and Minecraft Java v1.16.1. +### Currently supporting Minecraft Bedrock v1.16.0/1 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. From c804a6edfb4ccc1348ec18868dfdba9d135961a2 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Tue, 30 Jun 2020 17:08:22 +0100 Subject: [PATCH 070/104] Fix respawning and death not being registered on the client --- .../translators/java/JavaRespawnTranslator.java | 5 ++--- .../java/entity/JavaEntityStatusTranslator.java | 14 ++++++++++++++ .../JavaPlayerPositionRotationTranslator.java | 12 ++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) 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 288389fa6..6d0338082 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 @@ -25,9 +25,11 @@ package org.geysermc.connector.network.translators.java; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.network.session.GeyserSession; @@ -35,9 +37,6 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.DimensionUtils; -import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; -import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; - import java.util.concurrent.ThreadLocalRandom; @Translator(packet = ServerRespawnPacket.class) 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 98089ff27..0af473ff7 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 @@ -28,11 +28,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.GeyserConnector; 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.concurrent.TimeUnit; + @Translator(packet = ServerEntityStatusPacket.class) public class JavaEntityStatusTranslator extends PacketTranslator { @@ -99,5 +102,16 @@ public class JavaEntityStatusTranslator extends PacketTranslator { + EntityEventPacket eventPacket2 = new EntityEventPacket(); + eventPacket2.setRuntimeEntityId(entityEventPacket.getRuntimeEntityId()); + eventPacket2.setType(entityEventPacket.getType()); + eventPacket2.setData(entityEventPacket.getData()); + session.sendUpstreamPacket(eventPacket2); + }, 1, TimeUnit.MILLISECONDS); + } } } 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 8b0b82014..fae289e12 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 @@ -34,6 +34,7 @@ import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.RespawnPacket; import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; +import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -42,6 +43,8 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.ChunkUtils; +import java.util.concurrent.TimeUnit; + @Translator(packet = ServerPlayerPositionRotationPacket.class) public class JavaPlayerPositionRotationTranslator extends PacketTranslator { @@ -71,6 +74,15 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator { + EntityEventPacket eventPacket2 = new EntityEventPacket(); + eventPacket2.setRuntimeEntityId(entity.getGeyserId()); + eventPacket2.setType(EntityEventType.RESPAWN); + eventPacket2.setData(0); + session.sendUpstreamPacket(eventPacket2); + }, 1, TimeUnit.MILLISECONDS); + SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.getMetadata().putAll(entity.getMetadata()); From 81651cfac5daa77f7377e6e9b3f7de36fa24b43e Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Tue, 30 Jun 2020 20:39:21 -0400 Subject: [PATCH 071/104] Add support for 3D biomes; fix Nether biome display --- .../network/translators/BiomeTranslator.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java index c12cc5136..6f858eb50 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java @@ -70,24 +70,27 @@ public class BiomeTranslator { return bedrockData; } - for (int z = 0; z < 16; z += 4) { - for (int x = 0; x < 16; x += 4) { - byte biomeId = biomeID(biomeData, x, z); - fillArray(z, x, bedrockData, biomeId); - fillArray(z + 1, x, bedrockData, biomeId); - fillArray(z + 2, x, bedrockData, biomeId); - fillArray(z + 3, x, bedrockData, biomeId); + for (int y = 0; y < 16; y += 4) { + for (int z = 0; z < 16; z += 4) { + for (int x = 0; x < 16; x += 4) { + byte biomeId = biomeID(biomeData, x, y, z); + int offset = ((z + (y / 4)) << 4) | x; + Arrays.fill(bedrockData, offset, offset + 4, biomeId); + } } } return bedrockData; } - private static void fillArray(int z, int x, byte[] legacyBiomeData, int biomeId) { - int offset = (z << 4) | x; - Arrays.fill(legacyBiomeData, offset, offset + 4, (byte) biomeId); - } - - private static byte biomeID(int[] biomeData, int x, int z) { - return (byte) biomeData[((z >> 2) & 3) << 2 | ((x >> 2) & 3)]; + private static byte biomeID(int[] biomeData, int x, int y, int z) { + int biomeId = biomeData[((y >> 2) & 63) << 4 | ((z >> 2) & 3) << 2 | ((x >> 2) & 3)]; + if (biomeId == 0) { + biomeId = 42; // Ocean + } else if (biomeId >= 40 && biomeId <= 43) { // Java has multiple End dimensions that Bedrock doesn't recognize + biomeId = 9; + } else if (biomeId >= 170) { // Nether biomes. Dunno why it's like this :microjang: + biomeId = biomeId + 8; + } + return (byte) biomeId; } } From 51dfda1c917baba9fde170df5e0ce30307ebadba Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 1 Jul 2020 08:22:21 -0400 Subject: [PATCH 072/104] Clean up formatting --- .../connector/network/translators/BiomeTranslator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java index 6f858eb50..880c1c9cd 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java @@ -55,7 +55,7 @@ public class BiomeTranslator { CompoundTag biomesTag; - try (NBTInputStream biomenbtInputStream = NbtUtils.createNetworkReader(stream)){ + try (NBTInputStream biomenbtInputStream = NbtUtils.createNetworkReader(stream)) { biomesTag = (CompoundTag) biomenbtInputStream.readTag(); BIOMES = biomesTag; } catch (Exception ex) { @@ -89,7 +89,7 @@ public class BiomeTranslator { } else if (biomeId >= 40 && biomeId <= 43) { // Java has multiple End dimensions that Bedrock doesn't recognize biomeId = 9; } else if (biomeId >= 170) { // Nether biomes. Dunno why it's like this :microjang: - biomeId = biomeId + 8; + biomeId += 8; } return (byte) biomeId; } From 0f342c1e809222d3bbee3873f0d577f6f835a397 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Wed, 1 Jul 2020 14:26:00 +0100 Subject: [PATCH 073/104] Update mappings to fix fences and plant stems --- connector/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 668156d55..b443f3d43 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 668156d559be2c0e081950194342da7fb68f1543 +Subproject commit b443f3d43ff2da104816490e3190a3194ee610b2 From c17f21eedc258e148a097435c6824e7c7846a471 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 1 Jul 2020 12:28:03 -0400 Subject: [PATCH 074/104] Fix respawn bugs - hopefully for good Thanks to @bundabrg for spotting this one. --- .../connector/entity/LivingEntity.java | 8 +++++-- .../connector/entity/PlayerEntity.java | 22 +++++++++++++++++++ .../bedrock/BedrockRespawnTranslator.java | 7 +++--- .../entity/JavaEntityStatusTranslator.java | 14 ------------ .../JavaPlayerPositionRotationTranslator.java | 12 ---------- 5 files changed, 31 insertions(+), 32 deletions(-) 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 32aa34358..07a09fa1f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/LivingEntity.java @@ -117,11 +117,15 @@ public class LivingEntity extends Entity { for (Map.Entry entry : this.attributes.entrySet()) { if (!entry.getValue().getType().isBedrockAttribute()) continue; + if (entry.getValue().getType() == AttributeType.HEALTH) { + // Add health attribute to properly show hearts when mounting + // TODO: Not a perfect system, since it led to respawn bugs + attributes.add(new AttributeData("minecraft:health", 0.0f, maxHealth, metadata.getFloat(EntityData.HEALTH, 20f), maxHealth)); + continue; + } attributes.add(AttributeUtils.getBedrockAttribute(entry.getValue())); } - // Add health attribute to properly show hearts when mounting - attributes.add(new AttributeData("minecraft:health", 0.0f, maxHealth, metadata.getFloat(EntityData.HEALTH, 20f), maxHealth)); UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); updateAttributesPacket.setRuntimeEntityId(geyserId); 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 c567aa078..fe4dc905c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/PlayerEntity.java @@ -39,15 +39,19 @@ import com.nukkitx.protocol.bedrock.packet.*; import lombok.Getter; import lombok.Setter; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.entity.attribute.Attribute; +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.network.session.cache.EntityEffectCache; import org.geysermc.connector.scoreboard.Team; +import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.SkinUtils; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -293,4 +297,22 @@ public class PlayerEntity extends LivingEntity { } } } + + @Override + public void updateBedrockAttributes(GeyserSession session) { // TODO: Don't use duplicated code + if (!valid) return; + + List attributes = new ArrayList<>(); + for (Map.Entry entry : this.attributes.entrySet()) { + if (!entry.getValue().getType().isBedrockAttribute()) + continue; + + attributes.add(AttributeUtils.getBedrockAttribute(entry.getValue())); + } + + UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket(); + updateAttributesPacket.setRuntimeEntityId(geyserId); + updateAttributesPacket.setAttributes(attributes); + session.sendUpstreamPacket(updateAttributesPacket); + } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java index 8fc377ab5..14bc1507e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java @@ -25,14 +25,13 @@ package org.geysermc.connector.network.translators.bedrock; -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.ClientRequest; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.packet.RespawnPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; @Translator(packet = RespawnPacket.class) public class BedrockRespawnTranslator extends PacketTranslator { 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 0af473ff7..98089ff27 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 @@ -28,14 +28,11 @@ 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.GeyserConnector; 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.concurrent.TimeUnit; - @Translator(packet = ServerEntityStatusPacket.class) public class JavaEntityStatusTranslator extends PacketTranslator { @@ -102,16 +99,5 @@ public class JavaEntityStatusTranslator extends PacketTranslator { - EntityEventPacket eventPacket2 = new EntityEventPacket(); - eventPacket2.setRuntimeEntityId(entityEventPacket.getRuntimeEntityId()); - eventPacket2.setType(entityEventPacket.getType()); - eventPacket2.setData(entityEventPacket.getData()); - session.sendUpstreamPacket(eventPacket2); - }, 1, TimeUnit.MILLISECONDS); - } } } 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 fae289e12..8b0b82014 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 @@ -34,7 +34,6 @@ import com.nukkitx.protocol.bedrock.packet.EntityEventPacket; import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; import com.nukkitx.protocol.bedrock.packet.RespawnPacket; import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; -import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -43,8 +42,6 @@ import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.ChunkUtils; -import java.util.concurrent.TimeUnit; - @Translator(packet = ServerPlayerPositionRotationPacket.class) public class JavaPlayerPositionRotationTranslator extends PacketTranslator { @@ -74,15 +71,6 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator { - EntityEventPacket eventPacket2 = new EntityEventPacket(); - eventPacket2.setRuntimeEntityId(entity.getGeyserId()); - eventPacket2.setType(EntityEventType.RESPAWN); - eventPacket2.setData(0); - session.sendUpstreamPacket(eventPacket2); - }, 1, TimeUnit.MILLISECONDS); - SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.getMetadata().putAll(entity.getMetadata()); From 699ae0b88ed45deefbdf60ddd7d86c81e86df495 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Wed, 1 Jul 2020 20:27:39 -0400 Subject: [PATCH 075/104] Set strider entity offset properly if not a player entity --- .../java/entity/JavaEntitySetPassengersTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ec3ca8318..87491fbf3 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 @@ -141,7 +141,7 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator Date: Thu, 2 Jul 2020 20:10:43 -0400 Subject: [PATCH 076/104] Add GUI to standalone --- bootstrap/standalone/pom.xml | 2 +- .../standalone/GeyserStandaloneBootstrap.java | 56 ++- .../standalone/GeyserStandaloneLogger.java | 11 +- .../platform/standalone/gui/ANSIColor.java | 79 ++++ .../platform/standalone/gui/ColorPane.java | 118 ++++++ .../standalone/gui/GeyserStandaloneGUI.java | 336 ++++++++++++++++++ .../platform/standalone/gui/GraphPanel.java | 188 ++++++++++ .../standalone/src/main/resources/icon.png | Bin 0 -> 115461 bytes .../standalone/src/main/resources/log4j2.xml | 6 +- .../geysermc/connector/GeyserConnector.java | 21 +- 10 files changed, 807 insertions(+), 10 deletions(-) create mode 100644 bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ANSIColor.java create mode 100644 bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ColorPane.java create mode 100644 bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java create mode 100644 bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java create mode 100644 bootstrap/standalone/src/main/resources/icon.png diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml index 770ca1009..984a6baad 100644 --- a/bootstrap/standalone/pom.xml +++ b/bootstrap/standalone/pom.xml @@ -20,7 +20,7 @@ net.minecrell terminalconsoleappender - 1.1.1 + 1.2.0 org.apache.logging.log4j 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 3fb561a1d..762b09ba5 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,16 +25,23 @@ package org.geysermc.platform.standalone; -import org.geysermc.connector.common.PlatformType; +import lombok.Getter; +import net.minecrell.terminalconsole.TerminalConsoleAppender; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Logger; +import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; -import org.geysermc.connector.configuration.GeyserConfiguration; +import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.dump.BootstrapDumpInfo; -import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; +import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.utils.FileUtils; import org.geysermc.platform.standalone.command.GeyserCommandManager; +import org.geysermc.platform.standalone.gui.GeyserStandaloneGUI; import java.io.File; import java.io.IOException; @@ -49,14 +56,49 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { private GeyserStandaloneLogger geyserLogger; private IGeyserPingPassthrough geyserPingPassthrough; + private GeyserStandaloneGUI gui; + + @Getter + private boolean useGui = System.console() == null; + private GeyserConnector connector; public static void main(String[] args) { + for (String arg : args) { + // By default, standalone Geyser will check if it should open the GUI based on if the GUI is null + // Optionally, you can force the use of a GUI or no GUI by specifying args + if (arg.equals("gui")) { + new GeyserStandaloneBootstrap().onEnable(true); + return; + } else if (arg.equals("nogui")) { + new GeyserStandaloneBootstrap().onEnable(false); + return; + } + } new GeyserStandaloneBootstrap().onEnable(); } + public void onEnable(boolean useGui) { + this.useGui = useGui; + this.onEnable(); + } + @Override public void onEnable() { + Logger logger = (Logger) LogManager.getRootLogger(); + for (Appender appender : logger.getAppenders().values()) { + // Remove the appender that is not in use + // Prevents multiple appenders/double logging and removes harmless errors + if ((useGui && appender instanceof TerminalConsoleAppender) || (!useGui && appender instanceof ConsoleAppender)) { + logger.removeAppender(appender); + } + } + if (useGui && gui == null) { + gui = new GeyserStandaloneGUI(); + gui.redirectSystemStreams(); + gui.startUpdateThread(); + } + geyserLogger = new GeyserStandaloneLogger(); LoopbackUtil.checkLoopback(geyserLogger); @@ -73,9 +115,15 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { connector = GeyserConnector.start(PlatformType.STANDALONE, this); geyserCommandManager = new GeyserCommandManager(connector); + if (gui != null) { + gui.setupInterface(geyserLogger, geyserCommandManager); + } + geyserPingPassthrough = GeyserLegacyPingPassthrough.init(connector); - geyserLogger.start(); + if (!useGui) { + geyserLogger.start(); // Throws an error otherwise + } } @Override 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 ae7f18718..ffc322dd5 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 @@ -30,6 +30,7 @@ import lombok.extern.log4j.Log4j2; import net.minecrell.terminalconsole.SimpleTerminalConsole; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configurator; import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; @@ -96,7 +97,15 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements org @Override public void setDebug(boolean debug) { - Configurator.setLevel(log.getName(), debug ? org.apache.logging.log4j.Level.DEBUG : log.getLevel()); + Configurator.setLevel(log.getName(), debug ? Level.DEBUG : Level.INFO); + } + + /** + * Used for setting debug mode in GUI mode + * @return if debug is enabled + */ + public boolean isDebug() { + return log.isDebugEnabled(); } @Override diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ANSIColor.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ANSIColor.java new file mode 100644 index 000000000..1f4ff998a --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ANSIColor.java @@ -0,0 +1,79 @@ +/* + * 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.standalone.gui; + +import lombok.Getter; + +import java.awt.*; +import java.util.regex.Pattern; + +public enum ANSIColor { + // Normal colors + BLACK("(0;)?30(0;)?m", Color.getHSBColor(0.000f, 0.000f, 0.000f)), + RED("(0;)?31(0;)?m", Color.getHSBColor(0.000f, 1.000f, 0.502f)), + GREEN("(0;)?32(0;)?m", Color.getHSBColor(0.333f, 1.000f, 0.502f)), + YELLOW("(0;)?33(0;)?m", Color.getHSBColor(0.167f, 1.000f, 0.502f)), + BLUE("(0;)?34(0;)?m", Color.getHSBColor(0.667f, 1.000f, 0.502f)), + MAGENTA("(0;)?35(0;)?m", Color.getHSBColor(0.833f, 1.000f, 0.502f)), + CYAN("(0;)?36(0;)?m", Color.getHSBColor(0.500f, 1.000f, 0.502f)), + WHITE("(0;)?37(0;)?m", Color.getHSBColor(0.000f, 0.000f, 0.753f)), + + // Bold colors + B_BLACK("(1;30|30;1)m", Color.getHSBColor(0.000f, 0.000f, 0.502f)), + B_RED("(1;31|31;1)m", Color.getHSBColor(0.000f, 1.000f, 1.000f)), + B_GREEN("(1;32|32;1)m", Color.getHSBColor(0.333f, 1.000f, 1.000f)), + B_YELLOW("(1;33|33;1)m", Color.getHSBColor(0.167f, 1.000f, 1.000f)), + B_BLUE("(1;34|34;1)m", Color.getHSBColor(0.667f, 1.000f, 1.000f)), + B_MAGENTA("(1;35|35;1)m", Color.getHSBColor(0.833f, 1.000f, 1.000f)), + B_CYAN("(1;36|36;1)m", Color.getHSBColor(0.500f, 1.000f, 1.000f)), + B_WHITE("(1;37|37;1)m", Color.getHSBColor(0.000f, 0.000f, 1.000f)), + + RESET("0m", Color.getHSBColor(0.000f, 0.000f, 1.000f)); + + private static final ANSIColor[] VALUES = values(); + private static final String PREFIX = Pattern.quote("\u001B["); + + private final String ANSICode; + + @Getter + private final Color color; + + ANSIColor(String ANSICode, Color color) { + this.ANSICode = ANSICode; + this.color = color; + } + + public static ANSIColor fromANSI(String code) { + for (ANSIColor value : VALUES) { + if (code.matches(PREFIX + value.ANSICode)) { + return value; + } + } + + return B_WHITE; + } +} diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ColorPane.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ColorPane.java new file mode 100644 index 000000000..f4586bbb1 --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/ColorPane.java @@ -0,0 +1,118 @@ +/* + * 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.standalone.gui; + +import javax.swing.*; +import javax.swing.text.*; +import java.awt.*; + +/** + * This class was based on this code: https://stackoverflow.com/a/6899478/5299903 + */ +public class ColorPane extends JTextPane { + private static Color colorCurrent = ANSIColor.RESET.getColor(); + private String remaining = ""; + + /** + * Append the given string in the given color to the text pane + * @param c The color + * @param s The text + */ + private void append(Color c, String s) { + StyleContext sc = StyleContext.getDefaultStyleContext(); + AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c); + int len = getDocument().getLength(); + + try { + getDocument().insertString(len, s, aset); + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + + /** + * Extract the ANSI color codes from the string and add each part to the text pane + * + * @param s The text to parse + */ + public void appendANSI(String s) { // convert ANSI color codes first + int aPos = 0; // current char position in addString + int aIndex = 0; // index of next Escape sequence + int mIndex = 0; // index of "m" terminating Escape sequence + String tmpString = ""; + boolean stillSearching = true; // true until no more Escape sequences + String addString = remaining + s; + remaining = ""; + + if (addString.length() > 0) { + aIndex = addString.indexOf("\u001B"); // find first escape + if (aIndex == -1) { // no escape/color change in this string, so just send it with current color + append(colorCurrent, addString); + return; + } + // otherwise There is an escape character in the string, so we must process it + + if (aIndex > 0) { // Escape is not first char, so send text up to first escape + tmpString = addString.substring(0, aIndex); + append(colorCurrent, tmpString); + aPos = aIndex; // aPos is now at the beginning of the first escape sequence + } + + + // while there's text in the input buffer + stillSearching = true; + while (stillSearching) { + mIndex = addString.indexOf("m", aPos); // find the end of the escape sequence + if (mIndex < 0) { // the buffer ends halfway through the ansi string! + remaining = addString.substring(aPos, addString.length()); + stillSearching = false; + continue; + } else { + tmpString = addString.substring(aPos, mIndex+1); + colorCurrent = ANSIColor.fromANSI(tmpString).getColor(); + } + aPos = mIndex + 1; + // now we have the color, send text that is in that color (up to next escape) + + aIndex = addString.indexOf("\u001B", aPos); + + if (aIndex == -1) { // if that was the last sequence of the input, send remaining text + tmpString = addString.substring(aPos, addString.length()); + append(colorCurrent, tmpString); + stillSearching = false; + continue; // jump out of loop early, as the whole string has been sent now + } + + // there is another escape sequence, so send part of the string and prepare for the next + tmpString = addString.substring(aPos, aIndex); + aPos = aIndex; + append(colorCurrent, tmpString); + + } + } + } +} diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java new file mode 100644 index 000000000..cc40ae537 --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java @@ -0,0 +1,336 @@ +/* + * 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.standalone.gui; + +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.platform.standalone.GeyserStandaloneLogger; +import org.geysermc.platform.standalone.command.GeyserCommandManager; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import javax.swing.text.Document; +import java.awt.*; +import java.awt.event.*; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.InetSocketAddress; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class GeyserStandaloneGUI { + + private static final String[] playerTableHeadings = new String[] {"IP", "Username"}; + private static final List ramValues = new ArrayList<>(); + + private static final ColorPane consolePane = new ColorPane(); + private static final GraphPanel ramGraph = new GraphPanel(); + private static final JTable playerTable = new JTable(new String[][] { }, playerTableHeadings); + private static final int originalFontSize = consolePane.getFont().getSize(); + + private static final long MEGABYTE = 1024L * 1024L; + + private final JMenu commandsMenu; + private final JMenu optionsMenu; + + public GeyserStandaloneGUI() { + // Create the frame and setup basic settings + JFrame frame = new JFrame("Geyser Standalone"); + frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + frame.setSize(800, 400); + frame.setMinimumSize(frame.getSize()); + + // Remove Java UI look + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception ignored) { } + + // Show a confirm dialog on close + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent we) + { + String[] buttons = {"Yes", "No"}; + int result = JOptionPane.showOptionDialog(frame, "Are you sure you want to exit?", frame.getTitle(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttons, buttons[1]); + if (result == JOptionPane.YES_OPTION) { + System.exit(0); + } + } + }); + + Container cp = frame.getContentPane(); + + // Fetch and set the icon for the frame + URL image = getClass().getClassLoader().getResource("icon.png"); + if (image != null) { + ImageIcon icon = new ImageIcon(image); + frame.setIconImage(icon.getImage()); + } + + // Setup the split pane and event listeners + JSplitPane splitPane = new JSplitPane(); + splitPane.setDividerLocation(600); + splitPane.addPropertyChangeListener("dividerLocation", e -> splitPaneLimit((JSplitPane)e.getSource())); + splitPane.addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + splitPaneLimit((JSplitPane)e.getSource()); + } + }); + + cp.add(splitPane, BorderLayout.CENTER); + + // Set the background and disable input for the text pane + consolePane.setBackground(Color.BLACK); + consolePane.setEditable(false); + + // Wrap the text pane in a scroll pane and add it to the form + JScrollPane consoleScrollPane = new JScrollPane(consolePane); + //cp.add(consoleScrollPane, BorderLayout.CENTER); + splitPane.setLeftComponent(consoleScrollPane); + + // Create a new menu bar for the top of the frame + JMenuBar menuBar = new JMenuBar(); + + // Create 'File' + JMenu fileMenu = new JMenu("File"); + fileMenu.setMnemonic(KeyEvent.VK_F); + menuBar.add(fileMenu); + + // 'Open Geyser folder' button + JMenuItem openButton = new JMenuItem("Open Geyser folder", KeyEvent.VK_O); + openButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK)); + openButton.addActionListener(e -> { + try { + Desktop.getDesktop().open(new File("./")); + } catch (IOException ignored) { } + }); + fileMenu.add(openButton); + + fileMenu.addSeparator(); + + // 'Exit' button + JMenuItem exitButton = new JMenuItem("Exit", KeyEvent.VK_X); + exitButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_MASK)); + exitButton.addActionListener(e -> System.exit(0)); + fileMenu.add(exitButton); + + // Create 'Commands' + commandsMenu = new JMenu("Commands"); + commandsMenu.setMnemonic(KeyEvent.VK_C); + menuBar.add(commandsMenu); + + // Create 'View' + JMenu viewMenu = new JMenu("View"); + viewMenu.setMnemonic(KeyEvent.VK_V); + menuBar.add(viewMenu); + + // 'Zoom in' button + JMenuItem zoomInButton = new JMenuItem("Zoom In"); + zoomInButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK)); + zoomInButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() + 1))); + viewMenu.add(zoomInButton); + + // 'Zoom in' button + JMenuItem zoomOutButton = new JMenuItem("Zoom Out"); + zoomOutButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK)); + zoomOutButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() - 1))); + viewMenu.add(zoomOutButton); + + // 'Reset Zoom' button + JMenuItem resetZoomButton = new JMenuItem("Reset Zoom"); + resetZoomButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), originalFontSize))); + viewMenu.add(resetZoomButton); + + // create 'Options' + optionsMenu = new JMenu("Options"); + viewMenu.setMnemonic(KeyEvent.VK_O); + menuBar.add(optionsMenu); + + // Set the frames menu bar + frame.setJMenuBar(menuBar); + + JPanel rightPane = new JPanel(); + rightPane.setLayout(new CardLayout(5, 5)); + //cp.add(rightPane, BorderLayout.EAST); + splitPane.setRightComponent(rightPane); + + JPanel rightContentPane = new JPanel(); + rightContentPane.setLayout(new GridLayout(2, 1, 5, 5)); + rightPane.add(rightContentPane); + + // Set the ram graph to 0 + for (int i = 0; i < 10; i++) { + ramValues.add(0); + } + ramGraph.setValues(ramValues); + ramGraph.setXLabel("Loading..."); + rightContentPane.add(ramGraph); + + JScrollPane playerScrollPane = new JScrollPane(playerTable); + rightContentPane.add(playerScrollPane); + + // This has to be done last + frame.setVisible(true); + } + + /** + * Queue up an update to the text pane so we don't block the main thread + * + * @param text The text to append + */ + private void updateTextPane(final String text) { + SwingUtilities.invokeLater(() -> { + consolePane.appendANSI(text); + Document doc = consolePane.getDocument(); + consolePane.setCaretPosition(doc.getLength()); + }); + } + + /** + * Redirect the default io streams to the text pane + */ + public void redirectSystemStreams() { + // Setup a new output stream to forward it to the text pane + OutputStream out = new OutputStream() { + @Override + public void write(final int b) { + updateTextPane(String.valueOf((char) b)); + } + + @Override + public void write(byte[] b, int off, int len) { + updateTextPane(new String(b, off, len)); + } + + @Override + public void write(byte[] b) { + write(b, 0, b.length); + } + }; + + // Override the system output streams + System.setOut(new PrintStream(out, true)); + System.setErr(new PrintStream(out, true)); + + } + + /** + * Add all the Geyser commands to the commands menu, and setup the debug mode toggle + * + * @param geyserStandaloneLogger The current logger + * @param geyserCommandManager The commands manager + */ + public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, GeyserCommandManager geyserCommandManager) { + commandsMenu.removeAll(); + + for (Map.Entry command : geyserCommandManager.getCommands().entrySet()) { + // Remove the offhand command and any alias commands to prevent duplicates in the list + if ("offhand".equals(command.getValue().getName()) || command.getValue().getAliases().contains(command.getKey())) { + continue; + } + + // Create the button that runs the command + JMenuItem commandButton = new JMenuItem(command.getValue().getName()); + commandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription()); + commandButton.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{ })); + commandsMenu.add(commandButton); + } + + // 'Debug Mode' toggle + JCheckBoxMenuItem debugMode = new JCheckBoxMenuItem("Debug Mode"); + debugMode.setSelected(geyserStandaloneLogger.isDebug()); + debugMode.addActionListener(e -> geyserStandaloneLogger.setDebug(!geyserStandaloneLogger.isDebug())); + optionsMenu.add(debugMode); + } + + /** + * Start the thread to update the form information every 1s + */ + public void startUpdateThread() { + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + + Runnable periodicTask = () -> { + if (GeyserConnector.getInstance() != null) { + // Update player table + String[][] playerNames = new String[GeyserConnector.getInstance().getPlayers().size()][2]; + int i = 0; + for (Map.Entry player : GeyserConnector.getInstance().getPlayers().entrySet()) { + playerNames[i][0] = player.getKey().getHostName(); + playerNames[i][1] = player.getValue().getPlayerEntity().getUsername(); + + i++; + } + + DefaultTableModel model = new DefaultTableModel(playerNames, playerTableHeadings); + playerTable.setModel(model); + model.fireTableDataChanged(); + } + + // Update ram graph + final long freeMemory = Runtime.getRuntime().freeMemory(); + final long totalMemory = Runtime.getRuntime().totalMemory(); + final int freePercent = (int)(freeMemory * 100.0 / totalMemory + 0.5); + ramValues.add(100 - freePercent); + + ramGraph.setXLabel("Usage: " + String.format("%,d", (totalMemory - freeMemory) / MEGABYTE) + "mb (" + freePercent + "% free)"); + + // Trim the list + int k = ramValues.size(); + if ( k > 10 ) + ramValues.subList(0, k - 10).clear(); + + // Update the graph + ramGraph.setValues(ramValues); + }; + + // SwingUtilities.invokeLater is called so we don't run into threading issues with the GUI + executor.scheduleAtFixedRate(() -> SwingUtilities.invokeLater(periodicTask), 0, 1, TimeUnit.SECONDS); + } + + /** + * Make sure the JSplitPane divider is within a set of bounds + * + * @param splitPane The JSplitPane to check + */ + private void splitPaneLimit(JSplitPane splitPane) { + JRootPane frame = splitPane.getRootPane(); + int location = splitPane.getDividerLocation(); + if (location < frame.getWidth() - frame.getWidth() * 0.4f) { + splitPane.setDividerLocation(Math.round(frame.getWidth() - frame.getWidth() * 0.4f)); + } else if (location > frame.getWidth() - 200) { + splitPane.setDividerLocation(frame.getWidth() - 200); + } + } +} diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java new file mode 100644 index 000000000..eb259cf77 --- /dev/null +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java @@ -0,0 +1,188 @@ +/* + * 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.standalone.gui; + +import lombok.Setter; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * This has been modified to fit Geyser more but is based on + * https://gist.github.com/roooodcastro/6325153#gistcomment-3107524 + */ +public final class GraphPanel extends JPanel { + private final static int padding = 10; + private final static int labelPadding = 25; + private final static int pointWidth = 4; + private final static int numberYDivisions = 10; + private final static Color lineColor = new Color(44, 102, 230, 180); + private final static Color pointColor = new Color(100, 100, 100, 180); + private final static Color gridColor = new Color(200, 200, 200, 200); + private static final Stroke graphStroke = new BasicStroke(2f); + private List values = new ArrayList<>(10); + + @Setter + private String xLabel = ""; + + public GraphPanel() { + setPreferredSize(new Dimension(200 - (padding * 2), 150 - (padding * 2))); + } + + public void setValues(Collection newValues) { + values.clear(); + addValues(newValues); + } + + public void addValues(Collection newValues) { + values.addAll(newValues); + updateUI(); + } + + @Override + protected void paintComponent(Graphics graphics) { + super.paintComponent(graphics); + if (!(graphics instanceof Graphics2D)) { + graphics.drawString("Graphics is not Graphics2D, unable to render", 0, 0); + return; + } + final Graphics2D g = (Graphics2D) graphics; + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + final int length = values.size(); + final int width = getWidth(); + final int height = getHeight(); + final int maxScore = getMaxScore(); + final int minScore = getMinScore(); + final int scoreRange = maxScore - minScore; + + // draw white background + g.setColor(Color.WHITE); + g.fillRect( + padding + labelPadding, + padding, + width - (2 * padding) - labelPadding, + height - 2 * padding - labelPadding); + g.setColor(Color.BLACK); + + final FontMetrics fontMetrics = g.getFontMetrics(); + final int fontHeight = fontMetrics.getHeight(); + + // create hatch marks and grid lines for y axis. + for (int i = 0; i < numberYDivisions + 1; i++) { + final int x1 = padding + labelPadding; + final int x2 = pointWidth + padding + labelPadding; + final int y = height - ((i * (height - padding * 2 - labelPadding)) / numberYDivisions + padding + labelPadding); + if (length > 0) { + g.setColor(gridColor); + g.drawLine(padding + labelPadding + 1 + pointWidth, y, width - padding, y); + + g.setColor(Color.BLACK); + final int tickValue = (int) (minScore + ((scoreRange * i) / numberYDivisions)); + final String yLabel = tickValue + ""; + final int labelWidth = fontMetrics.stringWidth(yLabel); + g.drawString(yLabel, x1 - labelWidth - 5, y + (fontHeight / 2) - 3); + } + g.drawLine(x1, y, x2, y); + } + + // and for x axis + if (length > 1) { + for (int i = 0; i < length; i++) { + final int x = i * (width - padding * 2 - labelPadding) / (length - 1) + padding + labelPadding; + final int y1 = height - padding - labelPadding; + final int y2 = y1 - pointWidth; + if ((i % ((int) ((length / 20.0)) + 1)) == 0) { + g.setColor(gridColor); + g.drawLine(x, height - padding - labelPadding - 1 - pointWidth, x, padding); + + g.setColor(Color.BLACK); + + /*g.setColor(Color.BLACK); + final String xLabel = i + ""; + final int labelWidth = fontMetrics.stringWidth(xLabel); + g.drawString(xLabel, x - labelWidth / 2, y1 + fontHeight + 3);*/ + } + g.drawLine(x, y1, x, y2); + } + } + + // create x and y axes + g.drawLine(padding + labelPadding, height - padding - labelPadding, padding + labelPadding, padding); + g.drawLine(padding + labelPadding, height - padding - labelPadding, width - padding, height - padding - labelPadding); + + g.setColor(Color.BLACK); + final int labelWidth = fontMetrics.stringWidth(xLabel); + final int labelX = ((padding + labelPadding) + (width - padding)) / 2; + final int labelY = height - padding - labelPadding; + g.drawString(xLabel, labelX - labelWidth / 2, labelY + fontHeight + 3); + + final Stroke oldStroke = g.getStroke(); + g.setColor(lineColor); + g.setStroke(graphStroke); + + final double xScale = ((double) width - (2 * padding) - labelPadding) / (length - 1); + final double yScale = ((double) height - 2 * padding - labelPadding) / scoreRange; + + final List graphPoints = new ArrayList<>(length); + for (int i = 0; i < length; i++) { + final int x1 = (int) (i * xScale + padding + labelPadding); + final int y1 = (int) ((maxScore - values.get(i)) * yScale + padding); + graphPoints.add(new Point(x1, y1)); + } + + for (int i = 0; i < graphPoints.size() - 1; i++) { + final int x1 = graphPoints.get(i).x; + final int y1 = graphPoints.get(i).y; + final int x2 = graphPoints.get(i + 1).x; + final int y2 = graphPoints.get(i + 1).y; + g.drawLine(x1, y1, x2, y2); + } + + boolean drawDots = width > (length * pointWidth); + if (drawDots) { + g.setStroke(oldStroke); + g.setColor(pointColor); + for (Point graphPoint : graphPoints) { + final int x = graphPoint.x - pointWidth / 2; + final int y = graphPoint.y - pointWidth / 2; + g.fillOval(x, y, pointWidth, pointWidth); + } + } + } + + private int getMinScore() { + return 0; + } + + private int getMaxScore() { + return 100; + } +} diff --git a/bootstrap/standalone/src/main/resources/icon.png b/bootstrap/standalone/src/main/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4e6a38a787f0ed02a93b2580b5be0e838ffefea3 GIT binary patch literal 115461 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�? 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 literal 0 HcmV?d00001 diff --git a/bootstrap/standalone/src/main/resources/log4j2.xml b/bootstrap/standalone/src/main/resources/log4j2.xml index 957415405..238a27da5 100644 --- a/bootstrap/standalone/src/main/resources/log4j2.xml +++ b/bootstrap/standalone/src/main/resources/log4j2.xml @@ -1,9 +1,12 @@ - + + + + @@ -14,6 +17,7 @@ + diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 20a771266..6cde2a2db 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -44,17 +44,17 @@ import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.BiomeTranslator; import org.geysermc.connector.network.translators.EntityIdentifierRegistry; import org.geysermc.connector.network.translators.PacketTranslatorRegistry; +import org.geysermc.connector.network.translators.effect.EffectRegistry; import org.geysermc.connector.network.translators.item.ItemRegistry; import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry; +import org.geysermc.connector.network.translators.sound.SoundRegistry; import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.network.translators.world.block.BlockTranslator; -import org.geysermc.connector.network.translators.effect.EffectRegistry; import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; import org.geysermc.connector.utils.DimensionUtils; import org.geysermc.connector.utils.DockerCheck; import org.geysermc.connector.utils.LocaleUtils; -import org.geysermc.connector.network.translators.sound.SoundRegistry; import java.net.InetSocketAddress; import java.text.DecimalFormat; @@ -158,8 +158,23 @@ public class GeyserConnector { metrics.addCustomChart(new Metrics.SimplePie("platform", platformType::getPlatformName)); } + boolean isGui = false; + // This will check if we are in standalone and get the 'useGui' variable from there + if (platformType == PlatformType.STANDALONE) { + try { + Class cls = Class.forName("org.geysermc.platform.standalone.GeyserStandaloneBootstrap"); + isGui = (boolean) cls.getMethod("isUseGui").invoke(cls.cast(bootstrap)); + } catch (Exception e) { e.printStackTrace(); } + } + double completeTime = (System.currentTimeMillis() - startupTime) / 1000D; - logger.info(String.format("Done (%ss)! Run /geyser help for help!", new DecimalFormat("#.###").format(completeTime))); + String message = String.format("Done (%ss)!", new DecimalFormat("#.###").format(completeTime)); + if (isGui) { + message += " Run Commands -> help for help!"; + } else { + message += " Run /geyser help for help!"; + } + logger.info(message); } public void shutdown() { From 0daa4451ec08961b18296a9575737ce3ae4a0ea7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2020 19:18:44 -0500 Subject: [PATCH 077/104] Bump log4j-core from 2.13.1 to 2.13.2 in /bootstrap/standalone (#886) Bumps log4j-core from 2.13.1 to 2.13.2. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bootstrap/standalone/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml index 984a6baad..60b0ba81f 100644 --- a/bootstrap/standalone/pom.xml +++ b/bootstrap/standalone/pom.xml @@ -63,7 +63,7 @@ org.apache.logging.log4j log4j-core - 2.13.1 + 2.13.2 org.apache.logging.log4j From ab71bf0727ea425998056a4ae09c664b2f8e463a Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Fri, 3 Jul 2020 12:18:35 -0800 Subject: [PATCH 078/104] Fix bug when dropping items from an open inventory --- .../inventory/action/InventoryActionDataTranslator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java index 426627bfb..96cbd61fb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/action/InventoryActionDataTranslator.java @@ -120,9 +120,9 @@ public class InventoryActionDataTranslator { session.sendDownstreamPacket(dropPacket); } } - ItemStack item = session.getInventory().getItem(javaSlot); + ItemStack item = inventory.getItem(javaSlot); if (item != null) { - session.getInventory().setItem(javaSlot, new ItemStack(item.getId(), item.getAmount() - dropAmount, item.getNbt())); + inventory.setItem(javaSlot, new ItemStack(item.getId(), item.getAmount() - dropAmount, item.getNbt())); } return; } else { //clicking outside of inventory From da96a5b19c92fe6440bb066a5fba17fb6bbad46b Mon Sep 17 00:00:00 2001 From: rtm516 Date: Fri, 3 Jul 2020 22:55:54 +0100 Subject: [PATCH 079/104] Fix Strider cold state when riding and removing of the RIDING flag when a parent is killed --- .../org/geysermc/connector/entity/Entity.java | 6 ++++ .../entity/living/animal/StriderEntity.java | 34 +++++++++++++++++-- .../JavaEntitySetPassengersTranslator.java | 3 ++ 3 files changed, 41 insertions(+), 2 deletions(-) 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 6ae9c6717..8f242dcc6 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -146,6 +146,12 @@ public class Entity { public boolean despawnEntity(GeyserSession session) { if (!valid) return true; + for (long passenger : passengers) { + Entity entity = session.getEntityCache().getEntityByJavaId(passenger); + entity.getMetadata().getFlags().setFlag(EntityFlag.RIDING, false); + entity.updateBedrockMetadata(session); + } + RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket(); removeEntityPacket.setUniqueEntityId(geyserId); session.sendUpstreamPacket(removeEntityPacket); 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 index bb4daf545..ee6815d15 100644 --- 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 @@ -29,11 +29,14 @@ 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.Entity; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; public class StriderEntity extends AnimalEntity { + private boolean shaking = false; + public StriderEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { super(entityId, geyserId, entityType, position, motion, rotation); @@ -44,8 +47,7 @@ public class StriderEntity extends AnimalEntity { @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 17) { - metadata.getFlags().setFlag(EntityFlag.BREATHING, !(boolean) entityMetadata.getValue()); - metadata.getFlags().setFlag(EntityFlag.SHAKING, (boolean) entityMetadata.getValue()); + shaking = (boolean) entityMetadata.getValue(); } if (entityMetadata.getId() == 18) { metadata.getFlags().setFlag(EntityFlag.SADDLED, (boolean) entityMetadata.getValue()); @@ -53,4 +55,32 @@ public class StriderEntity extends AnimalEntity { super.updateBedrockMetadata(entityMetadata, session); } + + @Override + public void updateBedrockMetadata(GeyserSession session) { + // Make sure they are not shaking when riding another entity + // Needs to copy the parent state + if (metadata.getFlags().getFlag(EntityFlag.RIDING)) { + boolean parentShaking = false; + for (Entity ent : session.getEntityCache().getEntities().values()) { + if (ent.getPassengers().contains(entityId) && ent instanceof StriderEntity) { + parentShaking = ent.getMetadata().getFlags().getFlag(EntityFlag.SHAKING); + break; + } + } + + metadata.getFlags().setFlag(EntityFlag.BREATHING, !parentShaking); + metadata.getFlags().setFlag(EntityFlag.SHAKING, parentShaking); + } else { + metadata.getFlags().setFlag(EntityFlag.BREATHING, !shaking); + metadata.getFlags().setFlag(EntityFlag.SHAKING, shaking); + } + + // Update the passengers if we have any + for (long passenger : passengers) { + session.getEntityCache().getEntityByJavaId(passenger).updateBedrockMetadata(session); + } + + super.updateBedrockMetadata(session); + } } 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 87491fbf3..094d64df7 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 @@ -101,6 +101,9 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator 1)); } + + // Force an update to the passenger metadata + passenger.updateBedrockMetadata(session); } if (entity.getEntityType() == EntityType.HORSE) { From a7fbe995f826f427dfa589b535e255629519d24e Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sat, 4 Jul 2020 10:26:32 -0400 Subject: [PATCH 080/104] Add comment and check for null when removing passengers --- .../src/main/java/org/geysermc/connector/entity/Entity.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 8f242dcc6..ffe13a50d 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/Entity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/Entity.java @@ -146,9 +146,10 @@ public class Entity { public boolean despawnEntity(GeyserSession session) { if (!valid) return true; - for (long passenger : passengers) { + for (long passenger : passengers) { // Make sure all passengers on the despawned entity are updated Entity entity = session.getEntityCache().getEntityByJavaId(passenger); - entity.getMetadata().getFlags().setFlag(EntityFlag.RIDING, false); + if (entity == null) continue; + entity.getMetadata().getOrCreateFlags().setFlag(EntityFlag.RIDING, false); entity.updateBedrockMetadata(session); } From cc2bbc675f1db05878a3015eca7407ed015923cf Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sat, 4 Jul 2020 13:08:36 -0500 Subject: [PATCH 081/104] Update mappings submodule --- connector/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index b443f3d43..a298041e0 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit b443f3d43ff2da104816490e3190a3194ee610b2 +Subproject commit a298041e008d83e38b15248ebee5a38be2bc613f From 8ac5d6e13d92e3c8919a410c34d94850491a0861 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sat, 4 Jul 2020 16:35:48 -0500 Subject: [PATCH 082/104] Fix memory leak in legacy ping passthrough (Fixes #674, #813) --- .../GeyserBungeePingPassthrough.java | 9 +-- .../spigot/GeyserSpigotPingPassthrough.java | 12 ++-- .../sponge/GeyserSpongePingPassthrough.java | 19 +++-- .../GeyserVelocityPingPassthrough.java | 16 +++-- .../connector/common/ping/GeyserPingInfo.java | 61 +++++++++++++--- .../network/ConnectorServerEventHandler.java | 8 +-- .../connector/network/QueryPacketHandler.java | 8 +-- .../ping/GeyserLegacyPingPassthrough.java | 72 ++++++++++++++----- 8 files changed, 152 insertions(+), 53 deletions(-) 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 ab4000520..f2166aad7 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 @@ -60,14 +60,15 @@ public class GeyserBungeePingPassthrough implements IGeyserPingPassthrough, List else future.complete(event); })); ProxyPingEvent event = future.join(); + ServerPing response = event.getResponse(); GeyserPingInfo geyserPingInfo = new GeyserPingInfo( - event.getResponse().getDescription(), - event.getResponse().getPlayers().getOnline(), - event.getResponse().getPlayers().getMax() + response.getDescriptionComponent().toLegacyText(), + new GeyserPingInfo.Players(response.getPlayers().getMax(), response.getPlayers().getOnline()), + new GeyserPingInfo.Version(response.getVersion().getName(), response.getVersion().getProtocol()) ); if (event.getResponse().getPlayers().getSample() != null) { Arrays.stream(event.getResponse().getPlayers().getSample()).forEach(proxiedPlayer -> { - geyserPingInfo.addPlayer(proxiedPlayer.getName()); + geyserPingInfo.getPlayerList().add(proxiedPlayer.getName()); }); } return geyserPingInfo; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java index 07999d876..9658a68da 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPingPassthrough.java @@ -26,6 +26,7 @@ package org.geysermc.platform.spigot; +import com.github.steveice10.mc.protocol.MinecraftConstants; import lombok.AllArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -48,14 +49,15 @@ public class GeyserSpigotPingPassthrough implements IGeyserPingPassthrough { try { ServerListPingEvent event = new GeyserPingEvent(InetAddress.getLocalHost(), Bukkit.getMotd(), Bukkit.getOnlinePlayers().size(), Bukkit.getMaxPlayers()); Bukkit.getPluginManager().callEvent(event); - GeyserPingInfo geyserPingInfo = new GeyserPingInfo(event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()); - Bukkit.getOnlinePlayers().forEach(player -> { - geyserPingInfo.addPlayer(player.getName()); - }); + GeyserPingInfo geyserPingInfo = new GeyserPingInfo(event.getMotd(), + new GeyserPingInfo.Players(event.getMaxPlayers(), event.getNumPlayers()), + new GeyserPingInfo.Version(Bukkit.getVersion(), MinecraftConstants.PROTOCOL_VERSION) // thanks Spigot for not exposing this, just default to latest + ); + Bukkit.getOnlinePlayers().stream().map(Player::getName).forEach(geyserPingInfo.getPlayerList()::add); return geyserPingInfo; } catch (Exception e) { logger.debug("Error while getting Bukkit ping passthrough: " + e.toString()); - return new GeyserPingInfo(null, 0, 0); + return new GeyserPingInfo(null, null, null); } } 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 99e8ed2f2..862c744bb 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,6 +26,7 @@ package org.geysermc.platform.sponge; +import com.github.steveice10.mc.protocol.MinecraftConstants; import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.spongepowered.api.MinecraftVersion; @@ -35,6 +36,7 @@ import org.spongepowered.api.event.cause.Cause; import org.spongepowered.api.event.cause.EventContext; import org.spongepowered.api.event.server.ClientPingServerEvent; import org.spongepowered.api.network.status.StatusClient; +import org.spongepowered.api.profile.GameProfile; import java.lang.reflect.Method; import java.net.Inet4Address; @@ -68,11 +70,18 @@ public class GeyserSpongePingPassthrough implements IGeyserPingPassthrough { Sponge.getEventManager().post(event); GeyserPingInfo geyserPingInfo = new GeyserPingInfo( event.getResponse().getDescription().toPlain(), - event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getOnline(), - event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getMax()); - event.getResponse().getPlayers().get().getProfiles().forEach(player -> { - geyserPingInfo.addPlayer(player.getName().orElseThrow(IllegalStateException::new)); - }); + new GeyserPingInfo.Players( + event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getMax(), + event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getOnline() + ), + new GeyserPingInfo.Version( + event.getResponse().getVersion().getName(), + MinecraftConstants.PROTOCOL_VERSION) // thanks for also not exposing this sponge + ); + event.getResponse().getPlayers().get().getProfiles().stream() + .map(GameProfile::getName) + .map(op -> op.orElseThrow(IllegalStateException::new)) + .forEach(geyserPingInfo.getPlayerList()::add); return geyserPingInfo; } 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 934c57740..980c5b3ee 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 @@ -59,13 +59,17 @@ public class GeyserVelocityPingPassthrough implements IGeyserPingPassthrough { throw new RuntimeException(e); } GeyserPingInfo geyserPingInfo = new GeyserPingInfo( - LegacyComponentSerializer.INSTANCE.serialize(event.getPing().getDescription(), '§'), - event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getOnline(), - event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getMax() + LegacyComponentSerializer.legacy().serialize(event.getPing().getDescription(), '§'), + new GeyserPingInfo.Players( + event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getMax(), + event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getOnline() + ), + new GeyserPingInfo.Version( + event.getPing().getVersion().getName(), + event.getPing().getVersion().getProtocol() + ) ); - event.getPing().getPlayers().get().getSample().forEach(player -> { - geyserPingInfo.addPlayer(player.getName()); - }); + event.getPing().getPlayers().get().getSample().stream().map(ServerPing.SamplePlayer::getName).forEach(geyserPingInfo.getPlayerList()::add); return geyserPingInfo; } diff --git a/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java b/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java index 69b24ea1e..eff1fe49d 100644 --- a/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java +++ b/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java @@ -26,8 +26,11 @@ package org.geysermc.connector.common.ping; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.JsonNode; import lombok.Data; -import lombok.Getter; import java.util.ArrayList; import java.util.Collection; @@ -35,14 +38,56 @@ import java.util.Collection; @Data public class GeyserPingInfo { - public final String motd; - public final int currentPlayerCount; - public final int maxPlayerCount; + private String description; - @Getter - private Collection players = new ArrayList<>(); + private Players players; + private Version version; - public void addPlayer(String username) { - players.add(username); + @JsonIgnore + private Collection playerList = new ArrayList<>(); + + public GeyserPingInfo() { + } + + public GeyserPingInfo(String description, Players players, Version version) { + this.description = description; + this.players = players; + this.version = version; + } + + @JsonSetter("description") + void setDescription(JsonNode description) { + this.description = description.toString(); + } + + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Players { + + private int max; + private int online; + + public Players() { + } + + public Players(int max, int online) { + this.max = max; + this.online = online; + } + } + + @Data + public static class Version { + + private String name; + private int protocol; + + public Version() { + } + + public Version(String name, int protocol) { + this.name = name; + this.protocol = protocol; + } } } 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 11ff9a029..27b7ad8fe 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -74,8 +74,8 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { pong.setVersion(null); // Server tries to connect either way and it looks better pong.setIpv4Port(config.getBedrock().getPort()); - if (config.isPassthroughMotd() && pingInfo != null && pingInfo.motd != null) { - String[] motd = MessageUtils.getBedrockMessage(MessageSerializer.fromString(pingInfo.motd)).split("\n"); + if (config.isPassthroughMotd() && pingInfo != null && pingInfo.getDescription() != null) { + String[] motd = MessageUtils.getBedrockMessage(MessageSerializer.fromString(pingInfo.getDescription())).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. @@ -87,8 +87,8 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { } if (config.isPassthroughPlayerCounts() && pingInfo != null) { - pong.setPlayerCount(pingInfo.currentPlayerCount); - pong.setMaximumPlayerCount(pingInfo.maxPlayerCount); + pong.setPlayerCount(pingInfo.getPlayers().getOnline()); + pong.setMaximumPlayerCount(pingInfo.getPlayers().getMax()); } else { pong.setPlayerCount(connector.getPlayers().size()); pong.setMaximumPlayerCount(config.getMaxPlayers()); 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 ba654c75b..7b1912639 100644 --- a/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/QueryPacketHandler.java @@ -148,7 +148,7 @@ public class QueryPacketHandler { } if (connector.getConfig().isPassthroughMotd() && pingInfo != null) { - String[] javaMotd = MessageUtils.getBedrockMessage(MessageSerializer.fromString(pingInfo.motd)).split("\n"); + String[] javaMotd = MessageUtils.getBedrockMessage(MessageSerializer.fromString(pingInfo.getDescription())).split("\n"); motd = javaMotd[0].trim(); // First line of the motd. } else { motd = connector.getConfig().getBedrock().getMotd1(); @@ -156,8 +156,8 @@ public class QueryPacketHandler { // If passthrough player counts is enabled lets get players from the server if (connector.getConfig().isPassthroughPlayerCounts() && pingInfo != null) { - currentPlayerCount = String.valueOf(pingInfo.currentPlayerCount); - maxPlayerCount = String.valueOf(pingInfo.maxPlayerCount); + currentPlayerCount = String.valueOf(pingInfo.getPlayers().getOnline()); + maxPlayerCount = String.valueOf(pingInfo.getPlayers().getMax()); } else { currentPlayerCount = String.valueOf(connector.getPlayers().size()); maxPlayerCount = String.valueOf(connector.getConfig().getMaxPlayers()); @@ -220,7 +220,7 @@ public class QueryPacketHandler { // Fill player names if(pingInfo != null) { - for (String username : pingInfo.getPlayers()) { + for (String username : pingInfo.getPlayerList()) { query.write(username.getBytes()); query.write((byte) 0x00); } 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 1c4d26d0b..aa9e0503d 100644 --- a/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java +++ b/connector/src/main/java/org/geysermc/connector/ping/GeyserLegacyPingPassthrough.java @@ -26,16 +26,21 @@ package org.geysermc.connector.ping; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; 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 com.nukkitx.nbt.util.VarInts; import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.GeyserConnector; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.ConnectException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit; public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runnable { @@ -44,13 +49,10 @@ public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runn public GeyserLegacyPingPassthrough(GeyserConnector connector) { this.connector = connector; - this.pingInfo = new GeyserPingInfo(null, 0, 0); } private GeyserPingInfo pingInfo; - private Client client; - /** * Start legacy ping passthrough thread * @param connector GeyserConnector @@ -76,15 +78,51 @@ public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runn @Override 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(((TextMessage) info.getDescription()).getText(), info.getPlayerInfo().getOnlinePlayers(), info.getPlayerInfo().getMaxPlayers()); - this.client.getSession().disconnect(null); - }); + Socket socket = new Socket(); + socket.connect(new InetSocketAddress(connector.getConfig().getRemote().getAddress(), connector.getConfig().getRemote().getPort()), 5000); - client.getSession().connect(); - } catch (Exception ex) { - ex.printStackTrace(); + ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream(); + DataOutputStream handshake = new DataOutputStream(byteArrayStream); + handshake.write(0x0); + VarInts.writeUnsignedInt(handshake, MinecraftConstants.PROTOCOL_VERSION); + VarInts.writeUnsignedInt(handshake, socket.getInetAddress().getHostAddress().length()); + handshake.writeBytes(socket.getInetAddress().getHostAddress()); + handshake.writeShort(socket.getPort()); + VarInts.writeUnsignedInt(handshake, 1); + + DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); + VarInts.writeUnsignedInt(dataOutputStream, byteArrayStream.size()); + dataOutputStream.write(byteArrayStream.toByteArray()); + dataOutputStream.writeByte(0x01); + dataOutputStream.writeByte(0x00); + + DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); + VarInts.readUnsignedInt(dataInputStream); + VarInts.readUnsignedInt(dataInputStream); + int length = VarInts.readUnsignedInt(dataInputStream); + byte[] buffer = new byte[length]; + dataInputStream.readFully(buffer); + dataOutputStream.writeByte(0x09); + dataOutputStream.writeByte(0x01); + dataOutputStream.writeLong(System.currentTimeMillis()); + + VarInts.readUnsignedInt(dataInputStream); + String json = new String(buffer); + + this.pingInfo = GeyserConnector.JSON_MAPPER.readValue(json, GeyserPingInfo.class); + + byteArrayStream.close(); + handshake.close(); + dataOutputStream.close(); + dataInputStream.close(); + socket.close(); + } catch (SocketTimeoutException | ConnectException ex) { + this.pingInfo = null; + this.connector.getLogger().debug("Connection timeout for ping passthrough."); + } catch (JsonParseException | JsonMappingException ex) { + this.connector.getLogger().error("Failed to parse json when pinging server!", ex); + } catch (IOException e) { + e.printStackTrace(); } } } From 4062f1ee550597bedf10232c0d9108f57b62404d Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 5 Jul 2020 00:03:51 -0400 Subject: [PATCH 083/104] Fix flower pots and item frames --- .../java/org/geysermc/connector/entity/ItemFrameEntity.java | 4 ++-- .../network/translators/world/block/BlockStateValues.java | 2 +- .../world/block/entity/FlowerPotBlockEntityTranslator.java | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) 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 58edf29dd..bb923a313 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -150,7 +150,7 @@ public class ItemFrameEntity extends Entity { updateBlockPacket.setBlockPosition(bedrockPosition); updateBlockPacket.setRuntimeId(0); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NO_GRAPHIC); //TODO: Used to be NONE + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); session.sendUpstreamPacket(updateBlockPacket); session.getItemFrameCache().remove(position, entityId); @@ -178,7 +178,7 @@ public class ItemFrameEntity extends Entity { updateBlockPacket.setBlockPosition(bedrockPosition); updateBlockPacket.setRuntimeId(bedrockRuntimeId); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NO_GRAPHIC); //TODO Same + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); session.sendUpstreamPacket(updateBlockPacket); 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 73957cad9..9dcfe485a 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 @@ -76,7 +76,7 @@ public class BlockStateValues { return; } - if (entry.getKey().contains("potted_")) { + if (entry.getKey().contains("potted_") || entry.getKey().contains("flower_pot")) { FLOWER_POT_VALUES.put(javaBlockState, entry.getKey().replace("potted_", "")); return; } 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 691a85d32..7bc199768 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 @@ -49,10 +49,11 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R updateBlockPacket.setDataLayer(0); updateBlockPacket.setRuntimeId(BlockTranslator.getBedrockBlockId(blockState)); updateBlockPacket.setBlockPosition(position); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); - updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NO_GRAPHIC); //TODO: Check updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK); + updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY); session.sendUpstreamPacket(updateBlockPacket); + BlockEntityUtils.updateBlockEntity(session, getTag(blockState, position), position); } /** From 5958b5d0baacc7dfd6ced2a5d752e7703aef37dc Mon Sep 17 00:00:00 2001 From: rtm516 Date: Sun, 5 Jul 2020 21:07:49 +0100 Subject: [PATCH 084/104] Fix ram graph causing memory leak and add cleanup of options menu on reload --- .../platform/standalone/gui/GeyserStandaloneGUI.java | 1 + .../org/geysermc/platform/standalone/gui/GraphPanel.java | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java index cc40ae537..f4138354d 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java @@ -254,6 +254,7 @@ public class GeyserStandaloneGUI { */ public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, GeyserCommandManager geyserCommandManager) { commandsMenu.removeAll(); + optionsMenu.removeAll(); for (Map.Entry command : geyserCommandManager.getCommands().entrySet()) { // Remove the offhand command and any alias commands to prevent duplicates in the list diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java index eb259cf77..0e3361327 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GraphPanel.java @@ -43,9 +43,9 @@ public final class GraphPanel extends JPanel { private final static int labelPadding = 25; private final static int pointWidth = 4; private final static int numberYDivisions = 10; - private final static Color lineColor = new Color(44, 102, 230, 180); - private final static Color pointColor = new Color(100, 100, 100, 180); - private final static Color gridColor = new Color(200, 200, 200, 200); + private final static Color lineColor = new Color(44, 102, 230, 255); + private final static Color pointColor = new Color(100, 100, 100, 255); + private final static Color gridColor = new Color(200, 200, 200, 255); private static final Stroke graphStroke = new BasicStroke(2f); private List values = new ArrayList<>(10); From da1674c8d671c50874ae73b989b82f81a79bf25b Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 5 Jul 2020 15:58:43 -0500 Subject: [PATCH 085/104] Update to Cloudburst NBT 2.0 --- .../connector/entity/FireworkEntity.java | 29 +-- .../connector/entity/ItemFrameEntity.java | 70 +++---- .../network/session/GeyserSession.java | 4 +- .../network/translators/BiomeTranslator.java | 10 +- .../translators/EntityIdentifierRegistry.java | 8 +- .../BedrockBlockEntityDataTranslator.java | 80 ++++---- ...tionTrackingDBClientRequestTranslator.java | 34 ++-- .../inventory/AnvilInventoryTranslator.java | 3 +- .../DoubleChestInventoryTranslator.java | 34 ++-- .../holder/BlockInventoryHolder.java | 12 +- .../translators/item/ItemRegistry.java | 3 +- .../translators/item/ItemTranslator.java | 178 +++++++++--------- .../item/translators/BannerTranslator.java | 45 ++--- .../java/JavaDeclareRecipesTranslator.java | 4 +- .../java/world/JavaBlockValueTranslator.java | 26 +-- .../java/world/JavaChunkDataTranslator.java | 10 +- .../java/world/JavaExplosionTranslator.java | 2 +- .../java/world/JavaPlayEffectTranslator.java | 2 +- .../java/world/JavaTradeListTranslator.java | 97 +++++----- .../world/block/BlockStateValues.java | 6 +- .../world/block/BlockTranslator.java | 56 +++--- .../entity/BannerBlockEntityTranslator.java | 27 ++- .../entity/BedBlockEntityTranslator.java | 22 +-- .../block/entity/BedrockOnlyBlockEntity.java | 4 +- .../block/entity/BlockEntityTranslator.java | 32 ++-- .../entity/CampfireBlockEntityTranslator.java | 36 ++-- .../DoubleChestBlockEntityTranslator.java | 28 ++- .../entity/EmptyBlockEntityTranslator.java | 12 +- .../EndGatewayBlockEntityTranslator.java | 45 +++-- .../FlowerPotBlockEntityTranslator.java | 24 +-- .../entity/PistonBlockEntityTranslator.java | 24 +-- .../ShulkerBoxBlockEntityTranslator.java | 23 +-- .../entity/SignBlockEntityTranslator.java | 22 +-- .../entity/SkullBlockEntityTranslator.java | 28 ++- .../entity/SpawnerBlockEntityTranslator.java | 48 +++-- .../connector/utils/BlockEntityUtils.java | 5 +- .../geysermc/connector/utils/ChunkUtils.java | 18 +- .../connector/utils/InventoryUtils.java | 17 +- .../geysermc/connector/utils/ItemUtils.java | 6 - 39 files changed, 550 insertions(+), 584 deletions(-) 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 e1a8e08af..cf49dc5fa 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FireworkEntity.java @@ -31,7 +31,9 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; import com.nukkitx.protocol.bedrock.data.entity.EntityData; import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket; import org.geysermc.connector.entity.type.EntityType; @@ -49,7 +51,6 @@ public class FireworkEntity extends Entity { super(entityId, geyserId, entityType, position, motion, rotation); } - @Override public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { if (entityMetadata.getId() == 7) { @@ -62,19 +63,19 @@ public class FireworkEntity extends Entity { CompoundTag fireworks = tag.get("Fireworks"); - CompoundTagBuilder fireworksBuilder = CompoundTagBuilder.builder(); + NbtMapBuilder fireworksBuilder = NbtMap.builder(); if (fireworks.get("Flight") != null) { - fireworksBuilder.byteTag("Flight", MathUtils.convertByte(fireworks.get("Flight").getValue())); + fireworksBuilder.putByte("Flight", MathUtils.convertByte(fireworks.get("Flight").getValue())); } - List explosions = new ArrayList<>(); + List explosions = new ArrayList<>(); if (fireworks.get("Explosions") != null) { for (Tag effect : ((ListTag) fireworks.get("Explosions")).getValue()) { CompoundTag effectData = (CompoundTag) effect; - CompoundTagBuilder effectBuilder = CompoundTagBuilder.builder(); + NbtMapBuilder effectBuilder = NbtMap.builder(); if (effectData.get("Type") != null) { - effectBuilder.byteTag("FireworkType", MathUtils.convertByte(effectData.get("Type").getValue())); + effectBuilder.putByte("FireworkType", MathUtils.convertByte(effectData.get("Type").getValue())); } if (effectData.get("Colors") != null) { @@ -86,7 +87,7 @@ public class FireworkEntity extends Entity { colors[i++] = FireworkColor.fromJavaID(color).getBedrockID(); } - effectBuilder.byteArrayTag("FireworkColor", colors); + effectBuilder.putByteArray("FireworkColor", colors); } if (effectData.get("FadeColors") != null) { @@ -98,24 +99,24 @@ public class FireworkEntity extends Entity { colors[i++] = FireworkColor.fromJavaID(color).getBedrockID(); } - effectBuilder.byteArrayTag("FireworkFade", colors); + effectBuilder.putByteArray("FireworkFade", colors); } if (effectData.get("Trail") != null) { - effectBuilder.byteTag("FireworkTrail", MathUtils.convertByte(effectData.get("Trail").getValue())); + effectBuilder.putByte("FireworkTrail", MathUtils.convertByte(effectData.get("Trail").getValue())); } if (effectData.get("Flicker") != null) { - effectBuilder.byteTag("FireworkFlicker", MathUtils.convertByte(effectData.get("Flicker").getValue())); + effectBuilder.putByte("FireworkFlicker", MathUtils.convertByte(effectData.get("Flicker").getValue())); } - explosions.add(effectBuilder.buildRootTag()); + explosions.add(effectBuilder.build()); } } - fireworksBuilder.tag(new com.nukkitx.nbt.tag.ListTag<>("Explosions", com.nukkitx.nbt.tag.CompoundTag.class, explosions)); + fireworksBuilder.putList("Explosions", NbtType.COMPOUND, explosions); - metadata.put(EntityData.DISPLAY_ITEM, CompoundTagBuilder.builder().tag(fireworksBuilder.build("Fireworks")).buildRootTag()); + metadata.put(EntityData.DISPLAY_ITEM, NbtMap.builder().put("Fireworks", fireworksBuilder.build())); } else if (entityMetadata.getId() == 8 && !entityMetadata.getValue().equals(OptionalInt.empty()) && ((OptionalInt) entityMetadata.getValue()).getAsInt() == session.getPlayerEntity().getEntityId()) { //Checks if the firework has an entity ID (used when a player is gliding) and checks to make sure the player that is gliding is the one getting sent the packet or else every player near the gliding player will boost too. PlayerEntity entity = session.getPlayerEntity(); 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 bb923a313..392cec24c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -30,8 +30,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; @@ -66,21 +66,21 @@ public class ItemFrameEntity extends Entity { /** * Cached item frame's Bedrock compound tag. */ - private CompoundTag cachedTag; + private NbtMap cachedTag; public ItemFrameEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, HangingDirection direction) { super(entityId, geyserId, entityType, position, motion, rotation); - CompoundTagBuilder builder = CompoundTag.builder(); - builder.tag(CompoundTag.builder() - .stringTag("name", "minecraft:frame") - .intTag("version", BlockTranslator.getBlockStateVersion()) - .tag(CompoundTag.builder() - .intTag("facing_direction", direction.ordinal()) - .byteTag("item_frame_map_bit", (byte) 0) - .build("states")) - .build("block")); - builder.shortTag("id", (short) 199); - bedrockRuntimeId = BlockTranslator.getItemFrame(builder.buildRootTag()); + NbtMapBuilder builder = NbtMap.builder(); + NbtMapBuilder blockBuilder = NbtMap.builder() + .putString("name", "minecraft:frame") + .putInt("version", BlockTranslator.getBlockStateVersion()); + blockBuilder.put("states", NbtMap.builder() + .putInt("facing_direction", direction.ordinal()) + .putByte("item_frame_map_bit", (byte) 0) + .build()); + builder.put("block", blockBuilder.build()); + builder.putShort("id", (short) 199); + bedrockRuntimeId = BlockTranslator.getItemFrame(builder.build()); bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ()); } @@ -100,7 +100,7 @@ public class ItemFrameEntity extends Entity { if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) { ItemData itemData = ItemTranslator.translateToBedrock(session, (ItemStack) entityMetadata.getValue()); ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue()); - CompoundTagBuilder builder = CompoundTag.builder(); + NbtMapBuilder builder = NbtMap.builder(); String blockName = ""; for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) { @@ -110,17 +110,17 @@ public class ItemFrameEntity extends Entity { } } - builder.byteTag("Count", (byte) itemData.getCount()); + builder.putByte("Count", (byte) itemData.getCount()); if (itemData.getTag() != null) { - builder.tag(itemData.getTag().toBuilder().build("tag")); + builder.put("tag", itemData.getTag().toBuilder().build()); } - builder.shortTag("Damage", itemData.getDamage()); - builder.stringTag("Name", blockName); - CompoundTagBuilder tag = getDefaultTag().toBuilder(); - tag.tag(builder.build("Item")); - tag.floatTag("ItemDropChance", 1.0f); - tag.floatTag("ItemRotation", rotation); - cachedTag = tag.buildRootTag(); + builder.putShort("Damage", itemData.getDamage()); + builder.putString("Name", blockName); + NbtMapBuilder tag = getDefaultTag().toBuilder(); + tag.put("Item", builder.build()); + tag.putFloat("ItemDropChance", 1.0f); + tag.putFloat("ItemRotation", rotation); + cachedTag = tag.build(); updateBlock(session); } else if (entityMetadata.getId() == 7 && entityMetadata.getValue() == null && cachedTag != null) { @@ -133,9 +133,9 @@ public class ItemFrameEntity extends Entity { updateBlock(session); return; } - CompoundTagBuilder builder = cachedTag.toBuilder(); - builder.floatTag("ItemRotation", rotation); - cachedTag = builder.buildRootTag(); + NbtMapBuilder builder = cachedTag.toBuilder(); + builder.putFloat("ItemRotation", rotation); + cachedTag = builder.build(); updateBlock(session); } else { @@ -158,14 +158,14 @@ public class ItemFrameEntity extends Entity { return true; } - private CompoundTag getDefaultTag() { - CompoundTagBuilder builder = CompoundTag.builder(); - builder.intTag("x", bedrockPosition.getX()); - builder.intTag("y", bedrockPosition.getY()); - builder.intTag("z", bedrockPosition.getZ()); - builder.byteTag("isMovable", (byte) 1); - builder.stringTag("id", "ItemFrame"); - return builder.buildRootTag(); + private NbtMap getDefaultTag() { + NbtMapBuilder builder = NbtMap.builder(); + builder.putInt("x", bedrockPosition.getX()); + builder.putInt("y", bedrockPosition.getY()); + builder.putInt("z", bedrockPosition.getZ()); + builder.putByte("isMovable", (byte) 1); + builder.putString("id", "ItemFrame"); + return builder.build(); } /** 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 1fe5dec8b..93c619bfc 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 @@ -218,11 +218,11 @@ public class GeyserSession implements CommandSender { ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket(); - biomeDefinitionListPacket.setTag(BiomeTranslator.BIOMES); + biomeDefinitionListPacket.setDefinitions(BiomeTranslator.BIOMES); upstream.sendPacket(biomeDefinitionListPacket); AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket(); - entityPacket.setTag(EntityIdentifierRegistry.ENTITY_IDENTIFIERS); + entityPacket.setIdentifiers(EntityIdentifierRegistry.ENTITY_IDENTIFIERS); upstream.sendPacket(entityPacket); CreativeContentPacket creativePacket = new CreativeContentPacket(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java index 880c1c9cd..23a36641e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java @@ -26,9 +26,9 @@ package org.geysermc.connector.network.translators; +import com.nukkitx.nbt.NBTInputStream; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtUtils; -import com.nukkitx.nbt.stream.NBTInputStream; -import com.nukkitx.nbt.tag.CompoundTag; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.utils.FileUtils; @@ -40,7 +40,7 @@ import java.util.Arrays; // Array index formula by https://wiki.vg/Chunk_Format public class BiomeTranslator { - public static final CompoundTag BIOMES; + public static final NbtMap BIOMES; private BiomeTranslator() { } @@ -53,10 +53,10 @@ public class BiomeTranslator { /* Load biomes */ InputStream stream = FileUtils.getResource("bedrock/biome_definitions.dat"); - CompoundTag biomesTag; + NbtMap biomesTag; try (NBTInputStream biomenbtInputStream = NbtUtils.createNetworkReader(stream)) { - biomesTag = (CompoundTag) biomenbtInputStream.readTag(); + biomesTag = (NbtMap) biomenbtInputStream.readTag(); BIOMES = biomesTag; } catch (Exception ex) { GeyserConnector.getInstance().getLogger().warning("Failed to get biomes from biome definitions, is there something wrong with the file?"); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java index cc9b2cd89..59f4ae8ba 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java @@ -26,9 +26,9 @@ package org.geysermc.connector.network.translators; +import com.nukkitx.nbt.NBTInputStream; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtUtils; -import com.nukkitx.nbt.stream.NBTInputStream; -import com.nukkitx.nbt.tag.CompoundTag; import org.geysermc.connector.utils.FileUtils; import java.io.InputStream; @@ -38,7 +38,7 @@ import java.io.InputStream; */ public class EntityIdentifierRegistry { - public static CompoundTag ENTITY_IDENTIFIERS; + public static NbtMap ENTITY_IDENTIFIERS; private EntityIdentifierRegistry() { } @@ -52,7 +52,7 @@ public class EntityIdentifierRegistry { InputStream stream = FileUtils.getResource("bedrock/entity_identifiers.dat"); try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) { - ENTITY_IDENTIFIERS = (CompoundTag) nbtInputStream.readTag(); + ENTITY_IDENTIFIERS = (NbtMap) nbtInputStream.readTag(); } catch (Exception e) { throw new AssertionError("Unable to get entities from entity identifiers", e); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java index 9fe62bb44..38b940399 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockEntityDataTranslator.java @@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators.bedrock; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientUpdateSignPacket; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -45,47 +45,45 @@ public class BedrockBlockEntityDataTranslator extends PacketTranslator lines.length - 1) { - break; - } - newMessage = new StringBuilder(); - } else newMessage.append(character); - } - // Put the final line on since it isn't done in the for loop - if (iterator < lines.length) lines[iterator] = newMessage.toString(); - ClientUpdateSignPacket clientUpdateSignPacket = new ClientUpdateSignPacket(pos, lines); - session.sendDownstreamPacket(clientUpdateSignPacket); - //TODO (potentially): originally I was going to update the sign blocks so Bedrock and Java users would match visually - // However Java can still store a lot per-line and visuals are still messed up so that doesn't work - - // We remove the sign position from map to indicate there is no work-in-progress sign - lastMessages.remove(pos); + NbtMap tag = packet.getData(); + if (tag.getString("id").equals("Sign")) { + // This is the reason why this all works - Bedrock sends packets every time you update the sign, Java only wants the final packet + // But Bedrock sends one final packet when you're done editing the sign, which should be equal to the last message since there's no edits + // So if the latest update does not match the last cached update then it's still being edited + Position pos = new Position(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")); + if (!tag.getString("Text").equals(lastMessages.get(pos))) { + lastMessages.put(pos, tag.getString("Text")); + return; } + // Otherwise the two messages are identical and we can get to work deconstructing + StringBuilder newMessage = new StringBuilder(); + // While Bedrock's sign lines are one string, Java's is an array of each line + // (Initialized all with empty strings because it complains about null) + String[] lines = new String[] {"", "", "", ""}; + int iterator = 0; + // This converts the message into the array'd message Java wants + for (char character : tag.getString("Text").toCharArray()) { + // If we get a return in Bedrock, that signals to use the next line. + if (character == '\n') { + lines[iterator] = newMessage.toString(); + iterator++; + // Bedrock, for whatever reason, can hold a message out of bounds + // We don't care about that so we discard that + if (iterator > lines.length - 1) { + break; + } + newMessage = new StringBuilder(); + } else newMessage.append(character); + } + // Put the final line on since it isn't done in the for loop + if (iterator < lines.length) lines[iterator] = newMessage.toString(); + ClientUpdateSignPacket clientUpdateSignPacket = new ClientUpdateSignPacket(pos, lines); + session.sendDownstreamPacket(clientUpdateSignPacket); + //TODO (potentially): originally I was going to update the sign blocks so Bedrock and Java users would match visually + // However Java can still store a lot per-line and visuals are still messed up so that doesn't work + + // We remove the sign position from map to indicate there is no work-in-progress sign + lastMessages.remove(pos); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java index 1ca467206..41b6246c9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockPositionTrackingDBClientRequestTranslator.java @@ -26,19 +26,19 @@ package org.geysermc.connector.network.translators.bedrock; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.IntTag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; import com.nukkitx.protocol.bedrock.packet.PositionTrackingDBClientRequestPacket; import com.nukkitx.protocol.bedrock.packet.PositionTrackingDBServerBroadcastPacket; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; 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.DimensionUtils; import org.geysermc.connector.utils.LoadstoneTracker; -import java.util.ArrayList; -import java.util.List; - @Translator(packet = PositionTrackingDBClientRequestPacket.class) public class BedrockPositionTrackingDBClientRequestTranslator extends PacketTranslator { @@ -60,22 +60,20 @@ public class BedrockPositionTrackingDBClientRequestTranslator extends PacketTran broadcastPacket.setAction(PositionTrackingDBServerBroadcastPacket.Action.UPDATE); // Build the nbt data for the update - CompoundTagBuilder builder = CompoundTagBuilder.builder(); - builder.intTag("dim", DimensionUtils.javaToBedrock(pos.getDimension())); - builder.stringTag("id", String.format("%08X", packet.getTrackingId())); + NbtMapBuilder builder = NbtMap.builder(); + builder.putInt("dim", DimensionUtils.javaToBedrock(pos.getDimension())); + builder.putString("id", String.format("%08X", packet.getTrackingId())); - builder.byteTag("version", (byte) 1); // Not sure what this is for - builder.byteTag("status", (byte) 0); // Not sure what this is for + builder.putByte("version", (byte) 1); // Not sure what this is for + builder.putByte("status", (byte) 0); // Not sure what this is for // Build the position for the update - List posList = new ArrayList<>(); - posList.add(new IntTag("", pos.getX())); - posList.add(new IntTag("", pos.getY())); - posList.add(new IntTag("", pos.getZ())); - - builder.listTag("pos", IntTag.class, posList); - - broadcastPacket.setTag(builder.buildRootTag()); + IntList posList = new IntArrayList(); + posList.add(pos.getX()); + posList.add(pos.getY()); + posList.add(pos.getZ()); + builder.putList("pos", NbtType.INT, posList); + broadcastPacket.setTag(builder.build()); session.sendUpstreamPacket(broadcastPacket); } 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 c5d1de252..c780038a0 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 @@ -30,6 +30,7 @@ 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.nbt.NbtMap; import com.nukkitx.protocol.bedrock.data.inventory.*; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; @@ -103,7 +104,7 @@ public class AnvilInventoryTranslator extends BlockInventoryTranslator { } if (itemName != null) { String rename; - com.nukkitx.nbt.tag.CompoundTag tag = itemName.getTag(); + NbtMap tag = itemName.getTag(); if (tag != null) { rename = tag.getCompound("display").getString("Name"); } else { 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 a467e2186..1183b21da 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 @@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators.inventory; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; @@ -57,14 +57,14 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); session.sendUpstreamPacket(blockPacket); - CompoundTag tag = CompoundTag.builder() - .stringTag("id", "Chest") - .intTag("x", position.getX()) - .intTag("y", position.getY()) - .intTag("z", position.getZ()) - .intTag("pairx", pairPosition.getX()) - .intTag("pairz", pairPosition.getZ()) - .stringTag("CustomName", inventory.getTitle()).buildRootTag(); + NbtMap tag = NbtMap.builder() + .putString("id", "Chest") + .putInt("x", position.getX()) + .putInt("y", position.getY()) + .putInt("z", position.getZ()) + .putInt("pairx", pairPosition.getX()) + .putInt("pairz", pairPosition.getZ()) + .putString("CustomName", inventory.getTitle()).build(); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag); dataPacket.setBlockPosition(position); @@ -77,14 +77,14 @@ public class DoubleChestInventoryTranslator extends ChestInventoryTranslator { blockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); session.sendUpstreamPacket(blockPacket); - tag = CompoundTag.builder() - .stringTag("id", "Chest") - .intTag("x", pairPosition.getX()) - .intTag("y", pairPosition.getY()) - .intTag("z", pairPosition.getZ()) - .intTag("pairx", position.getX()) - .intTag("pairz", position.getZ()) - .stringTag("CustomName", inventory.getTitle()).buildRootTag(); + tag = NbtMap.builder() + .putString("id", "Chest") + .putInt("x", pairPosition.getX()) + .putInt("y", pairPosition.getY()) + .putInt("z", pairPosition.getZ()) + .putInt("pairx", position.getX()) + .putInt("pairz", position.getZ()) + .putString("CustomName", inventory.getTitle()).build(); dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag); dataPacket.setBlockPosition(pairPosition); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java index ce02b8751..6dfde5d1c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/holder/BlockInventoryHolder.java @@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators.inventory.holder; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; @@ -56,11 +56,11 @@ public class BlockInventoryHolder extends InventoryHolder { session.sendUpstreamPacket(blockPacket); inventory.setHolderPosition(position); - CompoundTag tag = CompoundTag.builder() - .intTag("x", position.getX()) - .intTag("y", position.getY()) - .intTag("z", position.getZ()) - .stringTag("CustomName", LocaleUtils.getLocaleString(inventory.getTitle(), session.getClientData().getLanguageCode())).buildRootTag(); + NbtMap tag = NbtMap.builder() + .putInt("x", position.getX()) + .putInt("y", position.getY()) + .putInt("z", position.getZ()) + .putString("CustomName", LocaleUtils.getLocaleString(inventory.getTitle(), session.getClientData().getLanguageCode())).build(); BlockEntityDataPacket dataPacket = new BlockEntityDataPacket(); dataPacket.setData(tag); dataPacket.setBlockPosition(position); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index aebf19797..0979e5731 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -29,6 +29,7 @@ package org.geysermc.connector.network.translators.item; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtUtils; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.StartGamePacket; @@ -156,7 +157,7 @@ public class ItemRegistry { byte[] bytes = Base64.getDecoder().decode(itemNode.get("nbt_b64").asText()); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); try { - com.nukkitx.nbt.tag.CompoundTag tag = (com.nukkitx.nbt.tag.CompoundTag) NbtUtils.createReaderLE(bais).readTag(); + NbtMap tag = (NbtMap) NbtUtils.createReaderLE(bais).readTag(); creativeItems.add(ItemData.of(itemNode.get("id").asInt(), damage, 1, tag)); } catch (IOException e) { e.printStackTrace(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index aa75e1499..6811d6bb6 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -28,10 +28,21 @@ package org.geysermc.connector.network.translators.item; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.message.MessageSerializer; -import com.github.steveice10.opennbt.tag.builtin.*; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.CompoundTag; -import com.nukkitx.nbt.tag.Tag; +import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; +import com.github.steveice10.opennbt.tag.builtin.ByteTag; +import com.github.steveice10.opennbt.tag.builtin.DoubleTag; +import com.github.steveice10.opennbt.tag.builtin.FloatTag; +import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.github.steveice10.opennbt.tag.builtin.LongArrayTag; +import com.github.steveice10.opennbt.tag.builtin.LongTag; +import com.github.steveice10.opennbt.tag.builtin.ShortTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.nukkitx.nbt.NbtList; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -150,9 +161,9 @@ public abstract class ItemTranslator { // Get the display name of the item - CompoundTag tag = itemData.getTag(); + NbtMap tag = itemData.getTag(); if (tag != null) { - CompoundTag display = tag.getCompound("display"); + NbtMap display = tag.getCompound("display"); if (display != null) { String name = display.getString("Name"); @@ -162,15 +173,15 @@ public abstract class ItemTranslator { name = MessageUtils.getTranslatedBedrockMessage(MessageSerializer.fromString(name), session.getClientData().getLanguageCode()); // Build the new display tag - CompoundTagBuilder displayBuilder = display.toBuilder(); - displayBuilder.stringTag("Name", name); + NbtMapBuilder displayBuilder = display.toBuilder(); + displayBuilder.putString("Name", name); // Build the new root tag - CompoundTagBuilder builder = tag.toBuilder(); - builder.tag(displayBuilder.build("display")); + NbtMapBuilder builder = tag.toBuilder(); + builder.put("display", displayBuilder.build()); // Create a new item with the original data + updated name - itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.buildRootTag()); + itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build()); } } } @@ -200,56 +211,51 @@ public abstract class ItemTranslator { if (itemData.getTag() == null) { return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), new com.github.steveice10.opennbt.tag.builtin.CompoundTag("")); } - return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), this.translateToJavaNBT(itemData.getTag())); + return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), this.translateToJavaNBT("", itemData.getTag())); } public abstract List getAppliedItems(); - public CompoundTag translateNbtToBedrock(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag) { - Map> javaValue = new HashMap<>(); + public NbtMap translateNbtToBedrock(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag) { + Map javaValue = new HashMap<>(); if (tag.getValue() != null && !tag.getValue().isEmpty()) { for (String str : tag.getValue().keySet()) { com.github.steveice10.opennbt.tag.builtin.Tag javaTag = tag.get(str); - com.nukkitx.nbt.tag.Tag translatedTag = translateToBedrockNBT(javaTag); + Object translatedTag = translateToBedrockNBT(javaTag); if (translatedTag == null) continue; - javaValue.put(translatedTag.getName(), translatedTag); + javaValue.put(javaTag.getName(), translatedTag); } } - - return new CompoundTag(tag.getName(), javaValue); + NbtMapBuilder builder = NbtMap.builder(); + javaValue.forEach(builder::put); + return builder.build(); } - private Tag translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.Tag tag) { + private Object translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.Tag tag) { if (tag instanceof ByteArrayTag) { - ByteArrayTag byteArrayTag = (ByteArrayTag) tag; - return new com.nukkitx.nbt.tag.ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue()); + return ((ByteArrayTag) tag).getValue(); } if (tag instanceof ByteTag) { - ByteTag byteTag = (ByteTag) tag; - return new com.nukkitx.nbt.tag.ByteTag(byteTag.getName(), byteTag.getValue()); + return ((ByteTag) tag).getValue(); } if (tag instanceof DoubleTag) { - DoubleTag doubleTag = (DoubleTag) tag; - return new com.nukkitx.nbt.tag.DoubleTag(doubleTag.getName(), doubleTag.getValue()); + return ((DoubleTag) tag).getValue(); } if (tag instanceof FloatTag) { - FloatTag floatTag = (FloatTag) tag; - return new com.nukkitx.nbt.tag.FloatTag(floatTag.getName(), floatTag.getValue()); + return ((FloatTag) tag).getValue(); } if (tag instanceof IntArrayTag) { - IntArrayTag intArrayTag = (IntArrayTag) tag; - return new com.nukkitx.nbt.tag.IntArrayTag(intArrayTag.getName(), intArrayTag.getValue()); + return ((IntArrayTag) tag).getValue(); } if (tag instanceof IntTag) { - IntTag intTag = (IntTag) tag; - return new com.nukkitx.nbt.tag.IntTag(intTag.getName(), intTag.getValue()); + return ((IntTag) tag).getValue(); } if (tag instanceof LongArrayTag) { @@ -260,50 +266,46 @@ public abstract class ItemTranslator { } if (tag instanceof LongTag) { - LongTag longTag = (LongTag) tag; - return new com.nukkitx.nbt.tag.LongTag(longTag.getName(), longTag.getValue()); + return ((LongTag) tag).getValue(); } if (tag instanceof ShortTag) { - ShortTag shortTag = (ShortTag) tag; - return new com.nukkitx.nbt.tag.ShortTag(shortTag.getName(), shortTag.getValue()); + return ((ShortTag) tag).getValue(); } if (tag instanceof StringTag) { - StringTag stringTag = (StringTag) tag; - return new com.nukkitx.nbt.tag.StringTag(stringTag.getName(), stringTag.getValue()); + return ((StringTag) tag).getValue(); } if (tag instanceof ListTag) { ListTag listTag = (ListTag) tag; - List> tagList = new ArrayList<>(); + List tagList = new ArrayList<>(); for (com.github.steveice10.opennbt.tag.builtin.Tag value : listTag) { tagList.add(translateToBedrockNBT(value)); } - Class clazz = CompoundTag.class; + NbtType type = NbtType.COMPOUND; if (!tagList.isEmpty()) { - clazz = tagList.get(0).getClass(); + type = NbtType.byClass(tagList.get(0).getClass()); } - return new com.nukkitx.nbt.tag.ListTag(listTag.getName(), clazz, tagList); + return new NbtList(type, tagList); } if (tag instanceof com.github.steveice10.opennbt.tag.builtin.CompoundTag) { com.github.steveice10.opennbt.tag.builtin.CompoundTag compoundTag = (com.github.steveice10.opennbt.tag.builtin.CompoundTag) tag; - return translateNbtToBedrock(compoundTag); } return null; } - public com.github.steveice10.opennbt.tag.builtin.CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) { - com.github.steveice10.opennbt.tag.builtin.CompoundTag javaTag = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(tag.getName()); + public com.github.steveice10.opennbt.tag.builtin.CompoundTag translateToJavaNBT(String name, NbtMap tag) { + com.github.steveice10.opennbt.tag.builtin.CompoundTag javaTag = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(name); Map javaValue = javaTag.getValue(); - if (tag.getValue() != null && !tag.getValue().isEmpty()) { - for (String str : tag.getValue().keySet()) { - Tag bedrockTag = tag.get(str); - com.github.steveice10.opennbt.tag.builtin.Tag translatedTag = translateToJavaNBT(bedrockTag); + if (tag != null && !tag.isEmpty()) { + for (String str : tag.keySet()) { + Object bedrockTag = tag.get(str); + com.github.steveice10.opennbt.tag.builtin.Tag translatedTag = translateToJavaNBT(name, bedrockTag); if (translatedTag == null) continue; @@ -315,77 +317,65 @@ public abstract class ItemTranslator { return javaTag; } - private com.github.steveice10.opennbt.tag.builtin.Tag translateToJavaNBT(com.nukkitx.nbt.tag.Tag tag) { - if (tag instanceof com.nukkitx.nbt.tag.ByteArrayTag) { - com.nukkitx.nbt.tag.ByteArrayTag byteArrayTag = (com.nukkitx.nbt.tag.ByteArrayTag) tag; - return new ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue()); + private com.github.steveice10.opennbt.tag.builtin.Tag translateToJavaNBT(String name, Object object) { + if (object instanceof int[]) { + return new IntArrayTag(name, (int[]) object); } - if (tag instanceof com.nukkitx.nbt.tag.ByteTag) { - com.nukkitx.nbt.tag.ByteTag byteTag = (com.nukkitx.nbt.tag.ByteTag) tag; - return new ByteTag(byteTag.getName(), byteTag.getValue()); + if (object instanceof byte[]) { + return new ByteArrayTag(name, (byte[]) object); + } + + if (object instanceof Byte) { + return new ByteTag(name, (byte) object); } - if (tag instanceof com.nukkitx.nbt.tag.DoubleTag) { - com.nukkitx.nbt.tag.DoubleTag doubleTag = (com.nukkitx.nbt.tag.DoubleTag) tag; - return new DoubleTag(doubleTag.getName(), doubleTag.getValue()); + if (object instanceof Float) { + return new FloatTag(name, (float) object); } - if (tag instanceof com.nukkitx.nbt.tag.FloatTag) { - com.nukkitx.nbt.tag.FloatTag floatTag = (com.nukkitx.nbt.tag.FloatTag) tag; - return new FloatTag(floatTag.getName(), floatTag.getValue()); + if (object instanceof Double) { + return new DoubleTag(name, (double) object); } - if (tag instanceof com.nukkitx.nbt.tag.IntArrayTag) { - com.nukkitx.nbt.tag.IntArrayTag intArrayTag = (com.nukkitx.nbt.tag.IntArrayTag) tag; - return new IntArrayTag(intArrayTag.getName(), intArrayTag.getValue()); + if (object instanceof Integer) { + return new IntTag(name, (int) object); } - if (tag instanceof com.nukkitx.nbt.tag.IntTag) { - com.nukkitx.nbt.tag.IntTag intTag = (com.nukkitx.nbt.tag.IntTag) tag; - return new IntTag(intTag.getName(), intTag.getValue()); + if (object instanceof long[]) { + return new LongArrayTag(name, (long[]) object); } - if (tag instanceof com.nukkitx.nbt.tag.LongArrayTag) { - com.nukkitx.nbt.tag.LongArrayTag longArrayTag = (com.nukkitx.nbt.tag.LongArrayTag) tag; - return new LongArrayTag(longArrayTag.getName(), longArrayTag.getValue()); + if (object instanceof Long) { + return new LongTag(name, (long) object); } - if (tag instanceof com.nukkitx.nbt.tag.LongTag) { - com.nukkitx.nbt.tag.LongTag longTag = (com.nukkitx.nbt.tag.LongTag) tag; - return new LongTag(longTag.getName(), longTag.getValue()); + if (object instanceof Short) { + return new ShortTag(name, (short) object); } - if (tag instanceof com.nukkitx.nbt.tag.ShortTag) { - com.nukkitx.nbt.tag.ShortTag shortTag = (com.nukkitx.nbt.tag.ShortTag) tag; - return new ShortTag(shortTag.getName(), shortTag.getValue()); + if (object instanceof String) { + return new StringTag(name, (String) object); } - if (tag instanceof com.nukkitx.nbt.tag.StringTag) { - com.nukkitx.nbt.tag.StringTag stringTag = (com.nukkitx.nbt.tag.StringTag) tag; - return new StringTag(stringTag.getName(), stringTag.getValue()); - } - - if (tag instanceof com.nukkitx.nbt.tag.ListTag) { - com.nukkitx.nbt.tag.ListTag listTag = (com.nukkitx.nbt.tag.ListTag) tag; - + if (object instanceof List) { List tags = new ArrayList<>(); - for (Object value : listTag.getValue()) { - if (!(value instanceof com.nukkitx.nbt.tag.Tag)) - continue; - - com.nukkitx.nbt.tag.Tag tagValue = (com.nukkitx.nbt.tag.Tag) value; - com.github.steveice10.opennbt.tag.builtin.Tag javaTag = translateToJavaNBT(tagValue); + for (Object value : (List) object) { + com.github.steveice10.opennbt.tag.builtin.Tag javaTag = translateToJavaNBT("", value); if (javaTag != null) tags.add(javaTag); } - return new ListTag(listTag.getName(), tags); + return new ListTag(name, tags); } - if (tag instanceof com.nukkitx.nbt.tag.CompoundTag) { - com.nukkitx.nbt.tag.CompoundTag compoundTag = (com.nukkitx.nbt.tag.CompoundTag) tag; - return translateToJavaNBT(compoundTag); + if (object instanceof NbtMap) { + NbtMap map = (NbtMap) object; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().equals(map.get(name))) { + return translateToJavaNBT(entry.getKey(), map.getCompound(name)); + } + } } return null; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java index 8a1a973b0..304ea3fb2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java @@ -31,7 +31,10 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; -import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.NbtList; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.network.translators.item.ItemRegistry; @@ -63,10 +66,10 @@ public class BannerTranslator extends ItemTranslator { if (blockEntityTag.contains("Patterns")) { ListTag patterns = blockEntityTag.get("Patterns"); - CompoundTagBuilder builder = itemData.getTag().toBuilder(); - builder.tag(convertBannerPattern(patterns)); + NbtMapBuilder builder = itemData.getTag().toBuilder(); + builder.put("Patterns", convertBannerPattern(patterns)); - itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.buildRootTag()); + itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build()); } return itemData; @@ -78,9 +81,9 @@ public class BannerTranslator extends ItemTranslator { ItemStack itemStack = super.translateToJava(itemData, itemEntry); - com.nukkitx.nbt.tag.CompoundTag nbtTag = itemData.getTag(); - if (nbtTag.contains("Patterns")) { - com.nukkitx.nbt.tag.ListTag patterns = nbtTag.get("Patterns"); + NbtMap nbtTag = itemData.getTag(); + if (nbtTag.containsKey("Patterns", NbtType.COMPOUND)) { + List patterns = nbtTag.getList("Patterns", NbtType.COMPOUND); CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag"); blockEntityTag.put(convertBannerPattern(patterns)); @@ -102,16 +105,16 @@ public class BannerTranslator extends ItemTranslator { * @param patterns The patterns to convert * @return The new converted patterns */ - public static com.nukkitx.nbt.tag.ListTag convertBannerPattern(ListTag patterns) { - List tagsList = new ArrayList<>(); + public static NbtList convertBannerPattern(ListTag patterns) { + List tagsList = new ArrayList<>(); for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) { - com.nukkitx.nbt.tag.CompoundTag newPatternTag = getBedrockBannerPattern((CompoundTag) patternTag); + NbtMap newPatternTag = getBedrockBannerPattern((CompoundTag) patternTag); if (newPatternTag != null) { tagsList.add(newPatternTag); } } - return new com.nukkitx.nbt.tag.ListTag<>("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, tagsList); + return new NbtList<>(NbtType.COMPOUND, tagsList); } /** @@ -120,7 +123,7 @@ public class BannerTranslator extends ItemTranslator { * @param pattern Java edition pattern nbt * @return The Bedrock edition format pattern nbt */ - public static com.nukkitx.nbt.tag.CompoundTag getBedrockBannerPattern(CompoundTag pattern) { + public static NbtMap getBedrockBannerPattern(CompoundTag pattern) { String patternName = (String) pattern.get("Pattern").getValue(); // Return null if its the globe pattern as it doesn't exist on bedrock @@ -128,11 +131,11 @@ public class BannerTranslator extends ItemTranslator { return null; } - return CompoundTagBuilder.builder() - .intTag("Color", 15 - (int) pattern.get("Color").getValue()) - .stringTag("Pattern", (String) pattern.get("Pattern").getValue()) - .stringTag("Pattern", patternName) - .buildRootTag(); + return NbtMap.builder() + .putInt("Color", 15 - (int) pattern.get("Color").getValue()) + .putString("Pattern", (String) pattern.get("Pattern").getValue()) + .putString("Pattern", patternName) + .build(); } /** @@ -141,10 +144,10 @@ public class BannerTranslator extends ItemTranslator { * @param patterns The patterns to convert * @return The new converted patterns */ - public static ListTag convertBannerPattern(com.nukkitx.nbt.tag.ListTag patterns) { + public static ListTag convertBannerPattern(List patterns) { List tagsList = new ArrayList<>(); - for (Object patternTag : patterns.getValue()) { - CompoundTag newPatternTag = getJavaBannerPattern((com.nukkitx.nbt.tag.CompoundTag) patternTag); + for (Object patternTag : patterns) { + CompoundTag newPatternTag = getJavaBannerPattern((NbtMap) patternTag); tagsList.add(newPatternTag); } @@ -157,7 +160,7 @@ public class BannerTranslator extends ItemTranslator { * @param pattern Bedorck edition pattern nbt * @return The Java edition format pattern nbt */ - public static CompoundTag getJavaBannerPattern(com.nukkitx.nbt.tag.CompoundTag pattern) { + public static CompoundTag getJavaBannerPattern(NbtMap pattern) { Map tags = new HashMap<>(); tags.put("Color", new IntTag("Color", 15 - pattern.getInt("Color"))); tags.put("Pattern", new StringTag("Pattern", pattern.getString("Pattern"))); 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 15f0e496e..08022640f 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 @@ -30,7 +30,7 @@ import com.github.steveice10.mc.protocol.data.game.recipe.Recipe; import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapedRecipeData; import com.github.steveice10.mc.protocol.data.game.recipe.data.ShapelessRecipeData; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareRecipesPacket; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.protocol.bedrock.data.inventory.CraftingData; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.data.inventory.PotionMixData; @@ -169,6 +169,6 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator blockEntityEntry : chunkData.getLoadBlockEntitiesLater().object2IntEntrySet()) { + for (Object2IntMap.Entry blockEntityEntry : chunkData.getLoadBlockEntitiesLater().object2IntEntrySet()) { int x = blockEntityEntry.getKey().getInt("x"); int y = blockEntityEntry.getKey().getInt("y"); int z = blockEntityEntry.getKey().getInt("z"); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaExplosionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaExplosionTranslator.java index 79b27f6a5..23e831c02 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaExplosionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaExplosionTranslator.java @@ -52,7 +52,7 @@ public class JavaExplosionTranslator extends PacketTranslator= 2.0f ? LevelEventType.PARTICLE_HUGE_EXPLODE : LevelEventType.PARTICLE_LARGE_EXPLOSION); + levelEventPacket.setType(packet.getRadius() >= 2.0f ? LevelEventType.PARTICLE_HUGE_EXPLODE : LevelEventType.PARTICLE_EXPLOSION); levelEventPacket.setData(0); levelEventPacket.setPosition(pos.toFloat()); session.sendUpstreamPacket(levelEventPacket); 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 70c2749dd..83d6bb69f 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 @@ -75,7 +75,7 @@ public class JavaPlayEffectTranslator extends PacketTranslator tags = new ArrayList<>(); + NbtMapBuilder builder = NbtMap.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())); + NbtMapBuilder recipe = NbtMap.builder(); + recipe.putInt("maxUses", trade.getMaxUses()); + recipe.putInt("traderExp", trade.getXp()); + recipe.putFloat("priceMultiplierA", trade.getPriceMultiplier()); + recipe.put("sell", getItemTag(session, trade.getOutput(), 0)); + recipe.putFloat("priceMultiplierB", 0.0f); + recipe.putInt("buyCountB", trade.getSecondInput() != null ? trade.getSecondInput().getAmount() : 0); + recipe.putInt("buyCountA", trade.getFirstInput().getAmount()); + recipe.putInt("demand", trade.getDemand()); + recipe.putInt("tier", packet.getVillagerLevel() - 1); + recipe.put("buyA", getItemTag(session, trade.getFirstInput(), trade.getSpecialPrice())); if (trade.getSecondInput() != null) { - recipe.tag(getItemTag(session, trade.getSecondInput(), "buyB", 0)); + recipe.put("buyB", getItemTag(session, trade.getSecondInput(), 0)); } - recipe.intTag("uses", trade.getNumUses()); - recipe.byteTag("rewardExp", (byte) 1); - tags.add(recipe.buildRootTag()); + recipe.putInt("uses", trade.getNumUses()); + recipe.putByte("rewardExp", (byte) 1); + tags.add(recipe.build()); } //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()); + tags.add(NbtMap.builder() + .putInt("maxUses", 0) + .putInt("traderExp", 0) + .putFloat("priceMultiplierA", 0.0f) + .putFloat("priceMultiplierB", 0.0f) + .putInt("buyCountB", 0) + .putInt("buyCountA", 0) + .putInt("demand", 0) + .putInt("tier", 5) + .putInt("uses", 0) + .putByte("rewardExp", (byte) 0) + .build()); } - 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()); + builder.putList("Recipes", NbtType.COMPOUND, tags); + List expTags = new ArrayList<>(); + expTags.add(NbtMap.builder().putInt("0", 0).build()); + expTags.add(NbtMap.builder().putInt("1", 10).build()); + expTags.add(NbtMap.builder().putInt("2", 70).build()); + expTags.add(NbtMap.builder().putInt("3", 150).build()); + expTags.add(NbtMap.builder().putInt("4", 250).build()); + builder.putList("TierExpRequirements", NbtType.COMPOUND, expTags); + updateTradePacket.setOffers(builder.build()); session.sendUpstreamPacket(updateTradePacket); } - private CompoundTag getItemTag(GeyserSession session, ItemStack stack, String name, int specialPrice) { + private NbtMap getItemTag(GeyserSession session, ItemStack stack, 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()); + NbtMapBuilder builder = NbtMap.builder(); + builder.putByte("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1))); + builder.putShort("Damage", itemData.getDamage()); + builder.putShort("id", (short) itemEntry.getBedrockId()); if (itemData.getTag() != null) { - CompoundTag tag = itemData.getTag().toBuilder().build("tag"); - builder.tag(tag); + NbtMap tag = itemData.getTag().toBuilder().build(); + builder.put("tag", tag); } - return builder.build(name); + return builder.build(); } } 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 9dcfe485a..53607317a 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,7 +26,7 @@ package org.geysermc.connector.network.translators.world.block; import com.fasterxml.jackson.databind.JsonNode; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; import it.unimi.dsi.fastutil.ints.*; import java.util.HashMap; @@ -41,7 +41,7 @@ public class BlockStateValues { 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 Map FLOWER_POT_BLOCKS = new HashMap<>(); 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(); @@ -159,7 +159,7 @@ public class BlockStateValues { * Get the map of contained flower pot plants to Bedrock CompoundTag * @return Map of flower pot blocks. */ - public static Map getFlowerPotBlocks() { + public static Map getFlowerPotBlocks() { return FLOWER_POT_BLOCKS; } 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 7d9521825..e627b8454 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 @@ -28,11 +28,12 @@ package org.geysermc.connector.network.translators.world.block; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import com.nukkitx.nbt.CompoundTagBuilder; +import com.nukkitx.nbt.NBTInputStream; +import com.nukkitx.nbt.NbtList; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; import com.nukkitx.nbt.NbtUtils; -import com.nukkitx.nbt.stream.NBTInputStream; -import com.nukkitx.nbt.tag.CompoundTag; -import com.nukkitx.nbt.tag.ListTag; import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -45,7 +46,7 @@ import java.io.InputStream; import java.util.*; public class BlockTranslator { - public static final ListTag BLOCKS; + public static final NbtList BLOCKS; public static final int AIR = 0; public static final int BEDROCK_WATER_ID; @@ -53,7 +54,7 @@ public class BlockTranslator { 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<>(); + private static final Object2IntMap ITEM_FRAMES = new Object2IntOpenHashMap<>(); // Bedrock carpet ID, used in LlamaEntity.java for decoration public static final int CARPET = 171; @@ -79,16 +80,16 @@ public class BlockTranslator { /* Load block palette */ InputStream stream = FileUtils.getResource("bedrock/runtime_block_states.dat"); - ListTag blocksTag; + NbtList blocksTag; try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) { - blocksTag = (ListTag) nbtInputStream.readTag(); + blocksTag = (NbtList) nbtInputStream.readTag(); } catch (Exception e) { throw new AssertionError("Unable to get blocks from runtime block states", e); } - Map blockStateMap = new HashMap<>(); + Map blockStateMap = new HashMap<>(); - for (CompoundTag tag : blocksTag.getValue()) { + for (NbtMap tag : blocksTag) { if (blockStateMap.putIfAbsent(tag.getCompound("block"), tag) != null) { throw new AssertionError("Duplicate block states in Bedrock palette"); } @@ -101,9 +102,9 @@ public class BlockTranslator { } catch (Exception e) { throw new AssertionError("Unable to load Java block mappings", e); } - Object2IntMap addedStatesMap = new Object2IntOpenHashMap<>(); + Object2IntMap addedStatesMap = new Object2IntOpenHashMap<>(); addedStatesMap.defaultReturnValue(-1); - List paletteList = new ArrayList<>(); + List paletteList = new ArrayList<>(); Reflections ref = new Reflections("org.geysermc.connector.network.translators.world.block.entity"); ref.getTypesAnnotatedWith(BlockEntity.class); @@ -120,7 +121,7 @@ public class BlockTranslator { javaRuntimeId++; Map.Entry entry = blocksIterator.next(); String javaId = entry.getKey(); - CompoundTag blockTag = buildBedrockState(entry.getValue()); + NbtMap blockTag = buildBedrockState(entry.getValue()); // TODO fix this, (no block should have a null hardness) JsonNode hardnessNode = entry.getValue().get("block_hardness"); @@ -181,7 +182,7 @@ public class BlockTranslator { BEDROCK_TO_JAVA_BLOCK_MAP.putIfAbsent(bedrockRuntimeId, javaRuntimeId); } - CompoundTag runtimeTag = blockStateMap.remove(blockTag); + NbtMap runtimeTag = blockStateMap.remove(blockTag); if (runtimeTag != null) { addedStatesMap.put(blockTag, bedrockRuntimeId); paletteList.add(runtimeTag); @@ -240,15 +241,15 @@ public class BlockTranslator { // Loop around again to find all item frame runtime IDs int frameRuntimeId = 0; - for (CompoundTag tag : paletteList) { - CompoundTag blockTag = tag.getCompound("block"); + for (NbtMap tag : paletteList) { + NbtMap blockTag = tag.getCompound("block"); if (blockTag.getString("name").equals("minecraft:frame")) { ITEM_FRAMES.put(tag, frameRuntimeId); } frameRuntimeId++; } - BLOCKS = new ListTag<>("", CompoundTag.class, paletteList); + BLOCKS = new NbtList<>(NbtType.COMPOUND, paletteList); } private BlockTranslator() { @@ -258,12 +259,12 @@ public class BlockTranslator { // no-op } - private static CompoundTag buildBedrockState(JsonNode node) { - CompoundTagBuilder tagBuilder = CompoundTag.builder(); - tagBuilder.stringTag("name", node.get("bedrock_identifier").textValue()) - .intTag("version", BlockTranslator.BLOCK_STATE_VERSION); + private static NbtMap buildBedrockState(JsonNode node) { + NbtMapBuilder tagBuilder = NbtMap.builder(); + tagBuilder.putString("name", node.get("bedrock_identifier").textValue()) + .putInt("version", BlockTranslator.BLOCK_STATE_VERSION); - CompoundTagBuilder statesBuilder = CompoundTag.builder(); + NbtMapBuilder statesBuilder = NbtMap.builder(); // check for states if (node.has("bedrock_states")) { @@ -274,17 +275,18 @@ public class BlockTranslator { JsonNode stateValue = stateEntry.getValue(); switch (stateValue.getNodeType()) { case BOOLEAN: - statesBuilder.booleanTag(stateEntry.getKey(), stateValue.booleanValue()); + statesBuilder.putBoolean(stateEntry.getKey(), stateValue.booleanValue()); continue; case STRING: - statesBuilder.stringTag(stateEntry.getKey(), stateValue.textValue()); + statesBuilder.putString(stateEntry.getKey(), stateValue.textValue()); continue; case NUMBER: - statesBuilder.intTag(stateEntry.getKey(), stateValue.intValue()); + statesBuilder.putInt(stateEntry.getKey(), stateValue.intValue()); } } } - return tagBuilder.tag(statesBuilder.build("states")).build("block"); + tagBuilder.put("states", statesBuilder.build()); + return tagBuilder.build(); } public static int getBedrockBlockId(int state) { @@ -295,7 +297,7 @@ public class BlockTranslator { return BEDROCK_TO_JAVA_BLOCK_MAP.get(bedrockId); } - public static int getItemFrame(CompoundTag tag) { + public static int getItemFrame(NbtMap tag) { return ITEM_FRAMES.getOrDefault(tag, -1); } 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 15af7a70e..e2a555090 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 @@ -27,15 +27,14 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.IntTag; -import com.nukkitx.nbt.tag.StringTag; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtType; import org.geysermc.connector.network.translators.item.translators.BannerTranslator; import org.geysermc.connector.network.translators.world.block.BlockStateValues; import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @BlockEntity(name = "Banner", regex = "banner") public class BannerBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @@ -46,21 +45,21 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement } @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); int bannerColor = BlockStateValues.getBannerColor(blockState); if (bannerColor != -1) { - tags.add(new IntTag("Base", 15 - bannerColor)); + tags.put("Base", 15 - bannerColor); } if (tag.contains("Patterns")) { ListTag patterns = tag.get("Patterns"); - tags.add(BannerTranslator.convertBannerPattern(patterns)); + tags.put("", BannerTranslator.convertBannerPattern(patterns)); } if (tag.contains("CustomName")) { - tags.add(new StringTag("CustomName", (String) tag.get("CustomName").getValue())); + tags.put("CustomName", tag.get("CustomName").getValue()); } return tags; @@ -74,9 +73,9 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.listTag("Patterns", com.nukkitx.nbt.tag.CompoundTag.class, new ArrayList<>()); - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z).toBuilder() + .putList("Patterns", NbtType.COMPOUND, new ArrayList<>()) + .build(); } } 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 31f363888..b84aad984 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 @@ -26,13 +26,11 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.ByteTag; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; import org.geysermc.connector.network.translators.world.block.BlockStateValues; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @BlockEntity(name = "Bed", regex = "bed") public class BedBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @@ -43,12 +41,12 @@ public class BedBlockEntityTranslator extends BlockEntityTranslator implements R } @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); byte bedcolor = BlockStateValues.getBedColor(blockState); // Just in case... if (bedcolor == -1) bedcolor = 0; - tags.add(new ByteTag("color", bedcolor)); + tags.put("color", bedcolor); return tags; } @@ -58,9 +56,9 @@ public class BedBlockEntityTranslator extends BlockEntityTranslator implements R } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.byteTag("color", (byte) 0); - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z).toBuilder() + .putByte("color", (byte) 0) + .build(); } } 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 9efda13c0..0a91cb790 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 @@ -27,7 +27,7 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; import org.geysermc.connector.network.session.GeyserSession; /** @@ -49,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, int blockState) { + static NbtMap 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 93356e7cd..557f37a33 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 @@ -28,8 +28,8 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.geysermc.connector.GeyserConnector; @@ -37,7 +37,6 @@ import org.geysermc.connector.utils.BlockEntityUtils; import org.reflections.Reflections; import java.util.HashMap; -import java.util.List; import java.util.Map; public abstract class BlockEntityTranslator { @@ -87,20 +86,21 @@ public abstract class BlockEntityTranslator { } } - public abstract List> translateTag(CompoundTag tag, int blockState); + public abstract Map 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 abstract NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z); - public com.nukkitx.nbt.tag.CompoundTag getBlockEntityTag(String id, CompoundTag tag, int blockState) { + public NbtMap 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())); - CompoundTagBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(id), x, y, z).toBuilder(); - translateTag(tag, blockState).forEach(tagBuilder::tag); - return tagBuilder.buildRootTag(); + NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId(id), x, y, z).toBuilder(); + Map translatedTags = translateTag(tag, blockState); + translatedTags.forEach(tagBuilder::put); + return tagBuilder.build(); } protected CompoundTag getConstantJavaTag(String javaId, int x, int y, int z) { @@ -112,13 +112,13 @@ public abstract class BlockEntityTranslator { return tag; } - protected com.nukkitx.nbt.tag.CompoundTag getConstantBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() - .intTag("x", x) - .intTag("y", y) - .intTag("z", z) - .stringTag("id", bedrockId); - return tagBuilder.buildRootTag(); + protected NbtMap getConstantBedrockTag(String bedrockId, int x, int y, int z) { + return NbtMap.builder() + .putInt("x", x) + .putInt("y", y) + .putInt("z", z) + .putString("id", bedrockId) + .build(); } @SuppressWarnings("unchecked") 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 e932d2645..e3d2c9f5e 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 @@ -27,25 +27,24 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemRegistry; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; +import java.util.Map; @BlockEntity(name = "Campfire", regex = "campfire") public class CampfireBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); ListTag items = tag.get("Items"); int i = 1; for (com.github.steveice10.opennbt.tag.builtin.Tag itemTag : items.getValue()) { - tags.add(getItem((CompoundTag) itemTag).toBuilder().build("Item" + i)); + tags.put("Item" + i, getItem((CompoundTag) itemTag)); i++; } return tags; @@ -59,22 +58,17 @@ public class CampfireBlockEntityTranslator extends BlockEntityTranslator { } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item1", new HashMap<>())); - tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item2", new HashMap<>())); - tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item3", new HashMap<>())); - tagBuilder.tag(new com.nukkitx.nbt.tag.CompoundTag("Item4", new HashMap<>())); - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z); } - protected com.nukkitx.nbt.tag.CompoundTag getItem(CompoundTag tag) { + protected NbtMap getItem(CompoundTag tag) { ItemEntry entry = ItemRegistry.getItemEntry((String) tag.get("id").getValue()); - CompoundTagBuilder tagBuilder = CompoundTagBuilder.builder() - .shortTag("id", (short) entry.getBedrockId()) - .byteTag("Count", (byte) tag.get("Count").getValue()) - .shortTag("Damage", (short) entry.getBedrockData()) - .tag(CompoundTagBuilder.builder().build("tag")); - return tagBuilder.buildRootTag(); + NbtMapBuilder tagBuilder = NbtMap.builder() + .putShort("id", (short) entry.getBedrockId()) + .putByte("Count", (byte) tag.get("Count").getValue()) + .putShort("Damage", (short) entry.getBedrockData()); + tagBuilder.put("tag", NbtMap.builder().build()); + return tagBuilder.build(); } } 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 d1afd19e0..012d0c595 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 @@ -28,17 +28,15 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.ByteTag; -import com.nukkitx.nbt.tag.IntTag; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockStateValues; import org.geysermc.connector.network.translators.world.block.DoubleChestValue; import org.geysermc.connector.utils.BlockEntityUtils; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; /** * Chests have more block entity properties in Bedrock, which is solved by implementing the BedrockOnlyBlockEntity @@ -54,14 +52,14 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl @Override 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); - BlockEntityUtils.updateBlockEntity(session, tagBuilder.buildRootTag(), position); + NbtMapBuilder tagBuilder = getConstantBedrockTag(BlockEntityUtils.getBedrockBlockEntityId("chest"), position.getX(), position.getY(), position.getZ()).toBuilder(); + translateTag(javaTag, blockState).forEach(tagBuilder::put); + BlockEntityUtils.updateBlockEntity(session, tagBuilder.build(), position); } @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); if (BlockStateValues.getDoubleChestValues().containsKey(blockState)) { DoubleChestValue chestValues = BlockStateValues.getDoubleChestValues().get(blockState); if (chestValues != null) { @@ -85,10 +83,10 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl x = x + (chestValues.isLeft ? 1 : -1); } } - tags.add(new IntTag("pairx", x)); - tags.add(new IntTag("pairz", z)); + tags.put("pairx", x); + tags.put("pairz", z); if (!chestValues.isLeft) { - tags.add(new ByteTag("pairlead", (byte) 1)); + tags.put("pairlead", (byte) 1); } } } @@ -101,7 +99,7 @@ public class DoubleChestBlockEntityTranslator extends BlockEntityTranslator impl } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { return null; } } 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 401bb3439..6de136119 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 @@ -26,17 +26,17 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @BlockEntity(name = "Empty", regex = "") public class EmptyBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, int blockState) { - return new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + return new HashMap<>(); } @Override @@ -45,7 +45,7 @@ public class EmptyBlockEntityTranslator extends BlockEntityTranslator { } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { return getConstantBedrockTag(bedrockId, x, y, z); } } 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 17e533bc0..784afed5b 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 @@ -27,31 +27,32 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.LongTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.IntTag; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtList; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtType; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; -import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; +import java.util.Map; @BlockEntity(name = "EndGateway", regex = "end_gateway") public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); - tags.add(new IntTag("Age", (int) (long) tag.get("Age").getValue())); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); + tags.put("Age", (int) ((long) tag.get("Age").getValue())); // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist // Linked coordinates - List tagsList = new ArrayList<>(); + IntList tagsList = new IntArrayList(); // Yes, the axis letters are capitalized - tagsList.add(new IntTag("", getExitPortalCoordinate(tag, "X"))); - tagsList.add(new IntTag("", getExitPortalCoordinate(tag, "Y"))); - tagsList.add(new IntTag("", getExitPortalCoordinate(tag, "Z"))); - com.nukkitx.nbt.tag.ListTag exitPortal = - new com.nukkitx.nbt.tag.ListTag<>("ExitPortal", IntTag.class, tagsList); - tags.add(exitPortal); + tagsList.add(getExitPortalCoordinate(tag, "X")); + tagsList.add(getExitPortalCoordinate(tag, "Y")); + tagsList.add(getExitPortalCoordinate(tag, "Z")); + tags.put("ExitPortal", new NbtList<>(NbtType.INT, tagsList)); return tags; } @@ -63,20 +64,16 @@ public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - List tagsList = new ArrayList<>(); - tagsList.add(new IntTag("", 0)); - tagsList.add(new IntTag("", 0)); - tagsList.add(new IntTag("", 0)); - tagBuilder.listTag("ExitPortal", IntTag.class, tagsList); - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z).toBuilder() + .putList("ExitPortal", NbtType.INT, Arrays.asList(0, 0, 0)) + .build(); } private int getExitPortalCoordinate(CompoundTag tag, String axis) { // Return 0 if it doesn't exist, otherwise give proper value if (tag.get("ExitPortal") != null) { - LinkedHashMap compoundTag = (LinkedHashMap) tag.get("ExitPortal").getValue(); + LinkedHashMap compoundTag = (LinkedHashMap) tag.get("ExitPortal").getValue(); com.github.steveice10.opennbt.tag.builtin.IntTag intTag = (com.github.steveice10.opennbt.tag.builtin.IntTag) compoundTag.get(axis); return intTag.getValue(); } return 0; 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 7bc199768..1e7cda5ff 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 @@ -27,8 +27,8 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockStateValues; @@ -62,23 +62,23 @@ public class FlowerPotBlockEntityTranslator implements BedrockOnlyBlockEntity, R * @param position Bedrock position of flower pot. * @return Bedrock tag of flower pot. */ - 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", "FlowerPot"); + public static NbtMap getTag(int blockState, Vector3i position) { + NbtMapBuilder tagBuilder = NbtMap.builder() + .putInt("x", position.getX()) + .putInt("y", position.getY()) + .putInt("z", position.getZ()) + .putByte("isMovable", (byte) 1) + .putString("id", "FlowerPot"); // Get the Java name of the plant inside. e.g. minecraft:oak_sapling String name = BlockStateValues.getFlowerPotValues().get(blockState); if (name != null) { // Get the Bedrock CompoundTag of the block. // This is where we need to store the *Java* name because Bedrock has six minecraft:sapling blocks with different block states. - CompoundTag plant = BlockStateValues.getFlowerPotBlocks().get(name); + NbtMap plant = BlockStateValues.getFlowerPotBlocks().get(name); if (plant != null) { - tagBuilder.tag(plant.toBuilder().build("PlantBlock")); + tagBuilder.put("PlantBlock", plant.toBuilder().build()); } } - return tagBuilder.buildRootTag(); + return tagBuilder.build(); } } 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 bf8fcb132..a2362e811 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 @@ -27,8 +27,8 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.CompoundTag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; import org.geysermc.connector.network.translators.world.block.BlockStateValues; /** @@ -51,21 +51,21 @@ public class PistonBlockEntityTranslator { * @param position Bedrock position of piston. * @return Bedrock tag of piston. */ - 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"); + public static NbtMap getTag(int blockState, Vector3i position) { + NbtMapBuilder tagBuilder = NbtMap.builder() + .putInt("x", position.getX()) + .putInt("y", position.getY()) + .putInt("z", position.getZ()) + .putByte("isMovable", (byte) 1) + .putString("id", "PistonArm"); if (BlockStateValues.getPistonValues().containsKey(blockState)) { boolean extended = BlockStateValues.getPistonValues().get(blockState); // 1f if extended, otherwise 0f - tagBuilder.floatTag("Progress", (extended) ? 1.0f : 0.0f); + tagBuilder.putFloat("Progress", (extended) ? 1.0f : 0.0f); // 1 if sticky, 0 if not - tagBuilder.byteTag("Sticky", (byte)((BlockStateValues.isStickyPiston(blockState)) ? 1 : 0)); + tagBuilder.putByte("Sticky", (byte)((BlockStateValues.isStickyPiston(blockState)) ? 1 : 0)); } - return tagBuilder.buildRootTag(); + return tagBuilder.build(); } } 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 b92b604e0..329b3a8ae 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 @@ -27,26 +27,23 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.ByteTag; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; import org.geysermc.connector.network.translators.world.block.BlockStateValues; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @BlockEntity(name = "ShulkerBox", regex = "shulker_box") public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); byte direction = BlockStateValues.getShulkerBoxDirection(blockState); // Just in case... if (direction == -1) direction = 1; - tags.add(new ByteTag("facing", direction)); - + tags.put("facing", direction); return tags; } @@ -56,9 +53,9 @@ public class ShulkerBoxBlockEntityTranslator extends BlockEntityTranslator { } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.byteTag("facing", (byte)1); - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z).toBuilder() + .putByte("facing", (byte) 1) + .build(); } } 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 d0388f335..a95c853e7 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 @@ -27,20 +27,18 @@ package org.geysermc.connector.network.translators.world.block.entity; 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 com.nukkitx.nbt.NbtMap; import org.geysermc.connector.utils.MessageUtils; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @BlockEntity(name = "Sign", regex = "sign") public class SignBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); StringBuilder signText = new StringBuilder(); for(int i = 0; i < 4; i++) { @@ -57,7 +55,7 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { signText.append("\n"); } - tags.add(new StringTag("Text", MessageUtils.getBedrockMessage(MessageSerializer.fromString(signText.toString())))); + tags.put("Text", MessageUtils.getBedrockMessage(MessageSerializer.fromString(signText.toString()))); return tags; } @@ -72,9 +70,9 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.stringTag("Text", ""); - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z).toBuilder() + .putString("Text", "") + .build(); } } 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 f868ff088..9547ba2ff 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,15 +25,11 @@ package org.geysermc.connector.network.translators.world.block.entity; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.ByteTag; -import com.nukkitx.nbt.tag.CompoundTag; -import com.nukkitx.nbt.tag.FloatTag; -import com.nukkitx.nbt.tag.Tag; +import com.nukkitx.nbt.NbtMap; import org.geysermc.connector.network.translators.world.block.BlockStateValues; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @BlockEntity(name = "Skull", regex = "skull") public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { @@ -44,14 +40,14 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } @Override - public List> translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); byte skullVariant = BlockStateValues.getSkullVariant(blockState); float rotation = BlockStateValues.getSkullRotation(blockState) * 22.5f; // Just in case... if (skullVariant == -1) skullVariant = 0; - tags.add(new FloatTag("Rotation", rotation)); - tags.add(new ByteTag("SkullType", skullVariant)); + tags.put("Rotation", rotation); + tags.put("SkullType", skullVariant); return tags; } @@ -61,10 +57,10 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements } @Override - public CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.floatTag("Rotation", 0); - tagBuilder.byteTag("SkullType", (byte) 0); - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z).toBuilder() + .putFloat("Rotation", 0f) + .putByte("SkullType", (byte) 0) + .build(); } } 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 548a1ec8c..e911feaa2 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 @@ -27,63 +27,62 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.*; +import com.nukkitx.nbt.NbtMap; import org.geysermc.connector.entity.type.EntityType; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; @BlockEntity(name = "MobSpawner", regex = "mob_spawner") public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { @Override - public List> translateTag(CompoundTag tag, int blockState) { - List> tags = new ArrayList<>(); + public Map translateTag(CompoundTag tag, int blockState) { + Map tags = new HashMap<>(); if (tag.get("MaxNearbyEntities") != null) { - tags.add(new ShortTag("MaxNearbyEntities", (short) tag.get("MaxNearbyEntities").getValue())); + tags.put("MaxNearbyEntities", (short) tag.get("MaxNearbyEntities").getValue()); } if (tag.get("RequiredPlayerRange") != null) { - tags.add(new ShortTag("RequiredPlayerRange", (short) tag.get("RequiredPlayerRange").getValue())); + tags.put("RequiredPlayerRange", (short) tag.get("RequiredPlayerRange").getValue()); } if (tag.get("SpawnCount") != null) { - tags.add(new ShortTag("SpawnCount", (short) tag.get("SpawnCount").getValue())); + tags.put("SpawnCount", (short) tag.get("SpawnCount").getValue()); } if (tag.get("MaxSpawnDelay") != null) { - tags.add(new ShortTag("MaxSpawnDelay", (short) tag.get("MaxSpawnDelay").getValue())); + tags.put("MaxSpawnDelay", (short) tag.get("MaxSpawnDelay").getValue()); } if (tag.get("Delay") != null) { - tags.add(new ShortTag("Delay", (short) tag.get("Delay").getValue())); + tags.put("Delay", (short) tag.get("Delay").getValue()); } if (tag.get("SpawnRange") != null) { - tags.add(new ShortTag("SpawnRange", (short) tag.get("SpawnRange").getValue())); + tags.put("SpawnRange", (short) tag.get("SpawnRange").getValue()); } if (tag.get("MinSpawnDelay") != null) { - tags.add(new ShortTag("MinSpawnDelay", (short) tag.get("MinSpawnDelay").getValue())); + tags.put("MinSpawnDelay", (short) tag.get("MinSpawnDelay").getValue()); } if (tag.get("SpawnData") != null) { CompoundTag spawnData = tag.get("SpawnData"); String entityID = (String) spawnData.get("id").getValue(); - tags.add(new StringTag("EntityIdentifier", entityID)); + tags.put("EntityIdentifier", entityID); EntityType type = EntityType.getFromIdentifier(entityID); if (type != null) { - tags.add(new FloatTag("DisplayEntityWidth", type.getWidth())); - tags.add(new FloatTag("DisplayEntityHeight", type.getHeight())); - tags.add(new FloatTag("DisplayEntityScale", 1.0f)); + tags.put("DisplayEntityWidth", type.getWidth()); + tags.put("DisplayEntityHeight", type.getHeight()); + tags.put("DisplayEntityScale", 1.0f); } } - tags.add(new StringTag("id", "MobSpawner")); - tags.add(new ByteTag("isMovable", (byte) 1)); + tags.put("id", "MobSpawner"); + tags.put("isMovable", (byte) 1); return tags; } @@ -94,11 +93,10 @@ public class SpawnerBlockEntityTranslator extends BlockEntityTranslator { } @Override - public com.nukkitx.nbt.tag.CompoundTag getDefaultBedrockTag(String bedrockId, int x, int y, int z) { - CompoundTagBuilder tagBuilder = getConstantBedrockTag(bedrockId, x, y, z).toBuilder(); - tagBuilder.byteTag("isMovable", (byte) 1) - .stringTag("id", "MobSpawner"); - - return tagBuilder.buildRootTag(); + public NbtMap getDefaultBedrockTag(String bedrockId, int x, int y, int z) { + return getConstantBedrockTag(bedrockId, x, y, z).toBuilder() + .putByte("isMovable", (byte) 1) + .putString("id", "MobSpawner") + .build(); } } 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 3a356e031..69c4a3682 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -2,6 +2,7 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; @@ -41,11 +42,11 @@ public class BlockEntityUtils { return blockEntityTranslator; } - public static void updateBlockEntity(GeyserSession session, com.nukkitx.nbt.tag.CompoundTag blockEntity, Position position) { + public static void updateBlockEntity(GeyserSession session, NbtMap blockEntity, Position position) { updateBlockEntity(session, blockEntity, Vector3i.from(position.getX(), position.getY(), position.getZ())); } - public static void updateBlockEntity(GeyserSession session, com.nukkitx.nbt.tag.CompoundTag blockEntity, Vector3i position) { + public static void updateBlockEntity(GeyserSession session, NbtMap blockEntity, Vector3i position) { BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket(); blockEntityPacket.setBlockPosition(position); blockEntityPacket.setData(blockEntity); 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 5c426cb9b..06b400908 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -33,9 +33,9 @@ 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; +import com.nukkitx.nbt.NBTOutputStream; +import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtUtils; -import com.nukkitx.nbt.stream.NBTOutputStream; import com.nukkitx.protocol.bedrock.packet.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -64,7 +64,7 @@ public class ChunkUtils { */ public static final Object2IntMap CACHED_BLOCK_ENTITIES = new Object2IntOpenHashMap<>(); - private static final com.nukkitx.nbt.tag.CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag(); + private static final NbtMap EMPTY_TAG = NbtMap.builder().build(); public static final byte[] EMPTY_LEVEL_CHUNK_DATA; static { @@ -72,7 +72,7 @@ public class ChunkUtils { outputStream.write(new byte[258]); // Biomes + Border Size + Extra Data Size try (NBTOutputStream stream = NbtUtils.createNetworkWriter(outputStream)) { - stream.write(EMPTY_TAG); + stream.writeTag(EMPTY_TAG); } EMPTY_LEVEL_CHUNK_DATA = outputStream.toByteArray(); @@ -91,7 +91,7 @@ public class ChunkUtils { Object2IntMap blockEntityPositions = new Object2IntOpenHashMap<>(); // Temporarily stores compound tags of Bedrock-only block entities - ObjectArrayList bedrockOnlyBlockEntities = new ObjectArrayList<>(); + ObjectArrayList bedrockOnlyBlockEntities = new ObjectArrayList<>(); for (int chunkY = 0; chunkY < chunks.length; chunkY++) { chunkData.sections[chunkY] = new ChunkSection(); @@ -131,7 +131,7 @@ public class ChunkUtils { } - com.nukkitx.nbt.tag.CompoundTag[] bedrockBlockEntities = new com.nukkitx.nbt.tag.CompoundTag[blockEntities.length + bedrockOnlyBlockEntities.size()]; + NbtMap[] bedrockBlockEntities = new NbtMap[blockEntities.length + bedrockOnlyBlockEntities.size()]; int i = 0; while (i < blockEntities.length) { CompoundTag tag = blockEntities[i]; @@ -162,7 +162,7 @@ public class ChunkUtils { bedrockBlockEntities[i] = blockEntityTranslator.getBlockEntityTag(tagName, tag, blockState); i++; } - for (com.nukkitx.nbt.tag.CompoundTag tag : bedrockOnlyBlockEntities) { + for (NbtMap tag : bedrockOnlyBlockEntities) { bedrockBlockEntities[i] = tag; i++; } @@ -270,8 +270,8 @@ public class ChunkUtils { public ChunkSection[] sections; @Getter - private com.nukkitx.nbt.tag.CompoundTag[] blockEntities = new com.nukkitx.nbt.tag.CompoundTag[0]; + private NbtMap[] blockEntities = new NbtMap[0]; @Getter - private Object2IntMap loadBlockEntitiesLater = new Object2IntOpenHashMap<>(); + private Object2IntMap loadBlockEntitiesLater = new Object2IntOpenHashMap<>(); } } 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 627c25dc3..9862159dc 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -27,8 +27,9 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; -import com.nukkitx.nbt.CompoundTagBuilder; -import com.nukkitx.nbt.tag.StringTag; +import com.nukkitx.nbt.NbtMap; +import com.nukkitx.nbt.NbtMapBuilder; +import com.nukkitx.nbt.NbtType; import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; @@ -136,13 +137,13 @@ public class InventoryUtils { * part of the inventory is unusable. */ public static ItemData createUnusableSpaceBlock(String description) { - CompoundTagBuilder root = CompoundTagBuilder.builder(); - CompoundTagBuilder display = CompoundTagBuilder.builder(); + NbtMapBuilder root = NbtMap.builder(); + NbtMapBuilder display = NbtMap.builder(); - display.stringTag("Name", ChatColor.RESET + "Unusable inventory space"); - display.listTag("Lore", StringTag.class, Collections.singletonList(new StringTag("", ChatColor.RESET + ChatColor.DARK_PURPLE + description))); + display.putString("Name", ChatColor.RESET + "Unusable inventory space"); + display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description)); - root.tag(display.build("display")); - return ItemData.of(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.buildRootTag()); + root.put("display", display.build()); + return ItemData.of(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.build()); } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java b/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java index b96002224..bb3cf0ed0 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ItemUtils.java @@ -26,12 +26,6 @@ package org.geysermc.connector.utils; import com.github.steveice10.opennbt.tag.builtin.*; -import com.nukkitx.nbt.CompoundTagBuilder; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; public class ItemUtils { From 69d7db4493d058ebd6648d2963ff46e353c5b8ee Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 5 Jul 2020 17:18:33 -0500 Subject: [PATCH 086/104] Update mappings submodule --- connector/src/main/resources/mappings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index a298041e0..848f16c2d 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit a298041e008d83e38b15248ebee5a38be2bc613f +Subproject commit 848f16c2d5441dfa2bd0768e5b75f903e623d2d9 From d1e5960d695c8c064efefc4cdb11cb2e10a1740e Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Sun, 5 Jul 2020 18:33:05 -0500 Subject: [PATCH 087/104] Send a dimension change upon join game packet now sent by bungeecord on 1.16 --- .../network/translators/java/JavaJoinGameTranslator.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 9b44cdd37..5c94d6afb 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 @@ -52,6 +52,13 @@ public class JavaJoinGameTranslator extends PacketTranslator Date: Mon, 6 Jul 2020 00:35:51 +0100 Subject: [PATCH 088/104] Add Translation support (#504) Adds full multi-language support to any Bedrock-supported language. Co-authored-by: DoctorMacc --- .gitmodules | 5 +- .../bungeecord/GeyserBungeePlugin.java | 5 +- .../command/GeyserBungeeCommandExecutor.java | 11 +- .../platform/spigot/GeyserSpigotPlugin.java | 9 +- .../command/GeyserSpigotCommandExecutor.java | 12 +- .../platform/sponge/GeyserSpongePlugin.java | 5 +- .../command/GeyserSpongeCommandExecutor.java | 7 +- .../standalone/GeyserStandaloneBootstrap.java | 3 +- .../platform/standalone/LoopbackUtil.java | 9 +- .../standalone/gui/GeyserStandaloneGUI.java | 35 +-- .../velocity/GeyserVelocityPlugin.java | 5 +- .../GeyserVelocityCommandExecutor.java | 4 +- common/src/main/resources/help.txt | 18 -- .../connector/FloodgateKeyLoader.java | 7 +- .../geysermc/connector/GeyserConnector.java | 23 +- .../connector/command/CommandManager.java | 17 +- .../command/defaults/DumpCommand.java | 19 +- .../command/defaults/HelpCommand.java | 14 +- .../command/defaults/ListCommand.java | 11 +- .../command/defaults/ReloadCommand.java | 15 +- .../connector/common/main/IGeyserMain.java | 49 ++++- .../configuration/GeyserConfiguration.java | 6 +- .../network/ConnectorServerEventHandler.java | 7 +- .../network/UpstreamPacketHandler.java | 13 +- .../network/session/GeyserSession.java | 32 +-- .../network/translators/BiomeTranslator.java | 3 +- .../translators/EntityIdentifierRegistry.java | 3 +- .../translators/PacketTranslatorRegistry.java | 7 +- ...drockPacketViolationWarningTranslator.java | 1 + .../translators/effect/EffectRegistry.java | 3 +- .../inventory/PlayerInventoryTranslator.java | 4 +- .../updater/ChestInventoryUpdater.java | 4 +- .../translators/item/ItemRegistry.java | 14 +- .../translators/item/ItemTranslator.java | 6 +- .../JavaPlayerPositionRotationTranslator.java | 3 +- .../spawn/JavaSpawnEntityTranslator.java | 3 +- .../JavaSpawnLivingEntityTranslator.java | 3 +- .../spawn/JavaSpawnPlayerTranslator.java | 3 +- .../java/scoreboard/JavaTeamTranslator.java | 17 +- .../scoreboard/JavaUpdateScoreTranslator.java | 3 +- .../block/entity/BlockEntityTranslator.java | 5 +- .../connector/scoreboard/Scoreboard.java | 3 +- .../geysermc/connector/utils/DockerCheck.java | 4 +- .../geysermc/connector/utils/FileUtils.java | 2 +- .../connector/utils/InventoryUtils.java | 3 +- .../connector/utils/LanguageUtils.java | 207 ++++++++++++++++++ .../geysermc/connector/utils/LocaleUtils.java | 22 +- .../connector/utils/LoginEncryptionUtils.java | 20 +- .../geysermc/connector/utils/SkinUtils.java | 6 +- connector/src/main/resources/config.yml | 4 +- connector/src/main/resources/languages | 1 + 51 files changed, 504 insertions(+), 191 deletions(-) delete mode 100644 common/src/main/resources/help.txt create mode 100644 connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java create mode 160000 connector/src/main/resources/languages diff --git a/.gitmodules b/.gitmodules index 207825e83..35887822e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,7 @@ [submodule "connector/src/main/resources/mappings"] path = connector/src/main/resources/mappings url = https://github.com/GeyserMC/mappings.git - branch = feature/1.16 + branch = feature/1.16 +[submodule "connector/src/main/resources/languages"] + path = connector/src/main/resources/languages + url = https://github.com/GeyserMC/languages.git 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 ac718cbae..38d319e15 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 @@ -39,6 +39,7 @@ 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.connector.utils.LanguageUtils; import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor; import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager; @@ -71,7 +72,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class); configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "config.yml")); } 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); + getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); } @@ -93,7 +94,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); if (geyserConfig.getRemote().getAuthType().equals("floodgate") && getProxy().getPluginManager().getPlugin("floodgate-bungee") == null) { - geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling..."); + geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); return; } diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java index d1c8473bd..3b051c5c3 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java @@ -33,6 +33,8 @@ import net.md_5.bungee.api.plugin.TabExecutor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import java.util.ArrayList; import java.util.Arrays; @@ -52,7 +54,14 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor if (args.length > 0) { if (getCommand(args[0]) != null) { if (!sender.hasPermission(getCommand(args[0]).getPermission())) { - sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + "You do not have permission to execute this command!")); + String message = ""; + if (sender instanceof GeyserSession) { + message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode()); + } else { + message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail"); + } + + sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + message)); return; } getCommand(args[0]).execute(new BungeeCommandSender(sender), args); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index de2b7186c..38141c520 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -37,6 +37,7 @@ import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.utils.FileUtils; +import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor; import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager; import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener; @@ -68,15 +69,15 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { 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..."); + getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copy_bukkit_config")); Files.copy(bukkitConfig.toPath(), new File(getDataFolder().toString() + "/config.yml").toPath()); - getLogger().log(Level.INFO, "Copied!"); + getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copied_bukkit_config")); } } 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); + getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); } @@ -92,7 +93,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { 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..."); + geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); this.getPluginLoader().disablePlugin(this); return; } diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java index b956a0d84..381872752 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java @@ -26,13 +26,14 @@ package org.geysermc.platform.spigot.command; import lombok.AllArgsConstructor; - import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import java.util.ArrayList; import java.util.Arrays; @@ -48,7 +49,14 @@ public class GeyserSpigotCommandExecutor implements TabExecutor { if (args.length > 0) { if (getCommand(args[0]) != null) { if (!sender.hasPermission(getCommand(args[0]).getPermission())) { - sender.sendMessage(ChatColor.RED + "You do not have permission to execute this command!"); + String message = ""; + if (sender instanceof GeyserSession) { + message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode()); + } else { + message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail"); + } + + sender.sendMessage(ChatColor.RED + message); return true; } getCommand(args[0]).execute(new SpigotCommandSender(sender), args); 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 4214255e8..3151e973c 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 @@ -38,6 +38,7 @@ 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.connector.utils.LanguageUtils; import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor; import org.geysermc.platform.sponge.command.GeyserSpongeCommandManager; import org.slf4j.Logger; @@ -80,7 +81,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap { try { configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString())); } catch (IOException ex) { - logger.warn("Failed to copy config.yml from jar path!"); + logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed")); ex.printStackTrace(); } @@ -90,7 +91,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap { config = loader.load(); this.geyserConfig = new GeyserSpongeConfiguration(configDir, config); } catch (IOException ex) { - logger.warn("Failed to load config.yml!"); + logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed")); ex.printStackTrace(); return; } 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 8f857b665..d37321ffe 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 @@ -26,10 +26,10 @@ package org.geysermc.platform.sponge.command; import lombok.AllArgsConstructor; - -import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.utils.LanguageUtils; import org.spongepowered.api.command.CommandCallable; import org.spongepowered.api.command.CommandException; import org.spongepowered.api.command.CommandResult; @@ -55,7 +55,8 @@ public class GeyserSpongeCommandExecutor implements CommandCallable { if (args.length > 0) { if (getCommand(args[0]) != null) { if (!source.hasPermission(getCommand(args[0]).getPermission())) { - source.sendMessage(Text.of(ChatColor.RED + "You do not have permission to execute this command!")); + // Not ideal to use log here but we dont get a session + source.sendMessage(Text.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail"))); return CommandResult.success(); } getCommand(args[0]).execute(new SpongeCommandSender(source), args); 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 762b09ba5..5da4c37d9 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 @@ -40,6 +40,7 @@ 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.connector.utils.LanguageUtils; import org.geysermc.platform.standalone.command.GeyserCommandManager; import org.geysermc.platform.standalone.gui.GeyserStandaloneGUI; @@ -107,7 +108,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class); } catch (IOException ex) { - geyserLogger.severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex); + geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex); System.exit(0); } GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); 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 00ff14de7..8c54d141b 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 @@ -1,12 +1,13 @@ package org.geysermc.platform.standalone; +import org.geysermc.connector.common.ChatColor; +import org.geysermc.connector.utils.LanguageUtils; + import java.io.InputStream; import java.nio.file.Files; import java.nio.file.OpenOption; import java.nio.file.Paths; -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. private static final String loopbackCommand = "powershell -Command \"CheckNetIsolation LoopbackExempt -a -n='Microsoft.MinecraftUWP_8wekyb3d8bbwe'\""; @@ -31,12 +32,12 @@ public class LoopbackUtil { Files.write(Paths.get(System.getenv("temp") + "/loopback_minecraft.bat"), loopbackCommand.getBytes(), new OpenOption[0]); process = Runtime.getRuntime().exec(startScript); - geyserLogger.info(ChatColor.AQUA + "Added loopback exemption to Windows!"); + geyserLogger.info(ChatColor.AQUA + LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.added")); } } catch (Exception e) { e.printStackTrace(); - geyserLogger.error("Couldn't auto add loopback exemption to Windows!"); + geyserLogger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.failed")); } } } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java index f4138354d..5a6b4c89d 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java @@ -29,6 +29,7 @@ package org.geysermc.platform.standalone.gui; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.platform.standalone.GeyserStandaloneLogger; import org.geysermc.platform.standalone.command.GeyserCommandManager; @@ -52,7 +53,9 @@ import java.util.concurrent.TimeUnit; public class GeyserStandaloneGUI { - private static final String[] playerTableHeadings = new String[] {"IP", "Username"}; + private static final String[] playerTableHeadings = new String[] { + LanguageUtils.getLocaleStringLog("geyser.gui.table.ip"), + LanguageUtils.getLocaleStringLog("geyser.gui.table.username")}; private static final List ramValues = new ArrayList<>(); private static final ColorPane consolePane = new ColorPane(); @@ -67,7 +70,7 @@ public class GeyserStandaloneGUI { public GeyserStandaloneGUI() { // Create the frame and setup basic settings - JFrame frame = new JFrame("Geyser Standalone"); + JFrame frame = new JFrame(LanguageUtils.getLocaleStringLog("geyser.gui.title")); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.setSize(800, 400); frame.setMinimumSize(frame.getSize()); @@ -82,8 +85,8 @@ public class GeyserStandaloneGUI { @Override public void windowClosing(WindowEvent we) { - String[] buttons = {"Yes", "No"}; - int result = JOptionPane.showOptionDialog(frame, "Are you sure you want to exit?", frame.getTitle(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttons, buttons[1]); + String[] buttons = {LanguageUtils.getLocaleStringLog("geyser.gui.exit.confirm"), LanguageUtils.getLocaleStringLog("geyser.gui.exit.deny")}; + int result = JOptionPane.showOptionDialog(frame, LanguageUtils.getLocaleStringLog("geyser.gui.exit.message"), frame.getTitle(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttons, buttons[1]); if (result == JOptionPane.YES_OPTION) { System.exit(0); } @@ -124,12 +127,12 @@ public class GeyserStandaloneGUI { JMenuBar menuBar = new JMenuBar(); // Create 'File' - JMenu fileMenu = new JMenu("File"); + JMenu fileMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file")); fileMenu.setMnemonic(KeyEvent.VK_F); menuBar.add(fileMenu); // 'Open Geyser folder' button - JMenuItem openButton = new JMenuItem("Open Geyser folder", KeyEvent.VK_O); + JMenuItem openButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.open_folder"), KeyEvent.VK_O); openButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK)); openButton.addActionListener(e -> { try { @@ -141,40 +144,40 @@ public class GeyserStandaloneGUI { fileMenu.addSeparator(); // 'Exit' button - JMenuItem exitButton = new JMenuItem("Exit", KeyEvent.VK_X); + JMenuItem exitButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.exit"), KeyEvent.VK_X); exitButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_MASK)); exitButton.addActionListener(e -> System.exit(0)); fileMenu.add(exitButton); // Create 'Commands' - commandsMenu = new JMenu("Commands"); + commandsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.commands")); commandsMenu.setMnemonic(KeyEvent.VK_C); menuBar.add(commandsMenu); // Create 'View' - JMenu viewMenu = new JMenu("View"); + JMenu viewMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view")); viewMenu.setMnemonic(KeyEvent.VK_V); menuBar.add(viewMenu); // 'Zoom in' button - JMenuItem zoomInButton = new JMenuItem("Zoom In"); + JMenuItem zoomInButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_in")); zoomInButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK)); zoomInButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() + 1))); viewMenu.add(zoomInButton); // 'Zoom in' button - JMenuItem zoomOutButton = new JMenuItem("Zoom Out"); + JMenuItem zoomOutButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_out")); zoomOutButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK)); zoomOutButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() - 1))); viewMenu.add(zoomOutButton); // 'Reset Zoom' button - JMenuItem resetZoomButton = new JMenuItem("Reset Zoom"); + JMenuItem resetZoomButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.reset_zoom")); resetZoomButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), originalFontSize))); viewMenu.add(resetZoomButton); // create 'Options' - optionsMenu = new JMenu("Options"); + optionsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options")); viewMenu.setMnemonic(KeyEvent.VK_O); menuBar.add(optionsMenu); @@ -195,7 +198,7 @@ public class GeyserStandaloneGUI { ramValues.add(0); } ramGraph.setValues(ramValues); - ramGraph.setXLabel("Loading..."); + ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.loading")); rightContentPane.add(ramGraph); JScrollPane playerScrollPane = new JScrollPane(playerTable); @@ -270,7 +273,7 @@ public class GeyserStandaloneGUI { } // 'Debug Mode' toggle - JCheckBoxMenuItem debugMode = new JCheckBoxMenuItem("Debug Mode"); + JCheckBoxMenuItem debugMode = new JCheckBoxMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options.toggle_debug_mode")); debugMode.setSelected(geyserStandaloneLogger.isDebug()); debugMode.addActionListener(e -> geyserStandaloneLogger.setDebug(!geyserStandaloneLogger.isDebug())); optionsMenu.add(debugMode); @@ -305,7 +308,7 @@ public class GeyserStandaloneGUI { final int freePercent = (int)(freeMemory * 100.0 / totalMemory + 0.5); ramValues.add(100 - freePercent); - ramGraph.setXLabel("Usage: " + String.format("%,d", (totalMemory - freeMemory) / MEGABYTE) + "mb (" + freePercent + "% free)"); + ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.usage", String.format("%,d", (totalMemory - freeMemory) / MEGABYTE), freePercent)); // Trim the list int k = ramValues.size(); 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 f00119ca9..425aba183 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 @@ -43,6 +43,7 @@ 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.connector.utils.LanguageUtils; import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor; import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager; import org.slf4j.Logger; @@ -85,7 +86,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { 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); + logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex); ex.printStackTrace(); } @@ -103,7 +104,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger); if (geyserConfig.getRemote().getAuthType().equals("floodgate") && !proxyServer.getPluginManager().getPlugin("floodgate").isPresent()) { - geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling..."); + geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); return; } 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 4632f4404..fa3aaa3c3 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 @@ -35,6 +35,7 @@ import net.kyori.text.TextComponent; import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.utils.LanguageUtils; @AllArgsConstructor public class GeyserVelocityCommandExecutor implements Command { @@ -46,7 +47,8 @@ public class GeyserVelocityCommandExecutor implements Command { if (args.length > 0) { if (getCommand(args[0]) != null) { if (!source.hasPermission(getCommand(args[0]).getPermission())) { - source.sendMessage(TextComponent.of(ChatColor.RED + "You do not have permission to execute this command!")); + // Not ideal to use log here but we dont get a session + source.sendMessage(TextComponent.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail"))); return; } getCommand(args[0]).execute(new VelocityCommandSender(source), args); diff --git a/common/src/main/resources/help.txt b/common/src/main/resources/help.txt deleted file mode 100644 index 3512ed839..000000000 --- a/common/src/main/resources/help.txt +++ /dev/null @@ -1,18 +0,0 @@ - --------------------------------------------------------------------------------- - - Oops! You attempted to run a plugin version of Geyser directly! - - This jar file is a plugin for ${plugin_type}. You can run this file as a - plugin by dropping the jar file into the "${plugin_folder}" directory. - - There is also a standalone version available that doesn't need to - be installed as a plugin, you can find it on our build server: - - http://ci.geysermc.org/ - - If you need more help, you should check out our discord: - - http://discord.geysermc.org/ - --------------------------------------------------------------------------------- \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java b/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java index 617ac83eb..d4413d68b 100644 --- a/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java +++ b/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java @@ -26,6 +26,7 @@ package org.geysermc.connector; +import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.configuration.GeyserConfiguration; import java.nio.file.Files; @@ -37,13 +38,13 @@ public class FloodgateKeyLoader { if (floodgate != null) { Path autoKey = floodgateFolder.resolve("public-key.pem"); if (Files.exists(autoKey)) { - logger.info("Auto-loaded floodgate key"); + logger.info(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.auto_loaded")); floodgateKey = autoKey; } else { - logger.error("Auth-type set to floodgate and the public key is missing!"); + logger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.missing_key")); } } else { - logger.error("Auth-type set to floodgate but floodgate is not installed!"); + logger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed")); } } diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 6cde2a2db..298f5bc82 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -50,6 +50,7 @@ import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry; import org.geysermc.connector.network.translators.sound.SoundRegistry; import org.geysermc.connector.network.translators.world.WorldManager; +import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; import org.geysermc.connector.utils.DimensionUtils; @@ -107,7 +108,7 @@ public class GeyserConnector { logger.info("******************************************"); logger.info(""); - logger.info("Loading " + NAME + " version " + VERSION); + logger.info(LanguageUtils.getLocaleStringLog("geyser.core.load", NAME, VERSION)); logger.info(""); logger.info("******************************************"); @@ -143,9 +144,9 @@ public class GeyserConnector { bedrockServer.setHandler(new ConnectorServerEventHandler(this)); bedrockServer.bind().whenComplete((avoid, throwable) -> { if (throwable == null) { - logger.info("Started Geyser on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort()); + logger.info(LanguageUtils.getLocaleStringLog("geyser.core.start", config.getBedrock().getAddress(), String.valueOf(config.getBedrock().getPort()))); } else { - logger.severe("Failed to start Geyser on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort()); + logger.severe(LanguageUtils.getLocaleStringLog("geyser.core.fail", config.getBedrock().getAddress(), config.getBedrock().getPort())); throwable.printStackTrace(); } }).join(); @@ -168,24 +169,24 @@ public class GeyserConnector { } double completeTime = (System.currentTimeMillis() - startupTime) / 1000D; - String message = String.format("Done (%ss)!", new DecimalFormat("#.###").format(completeTime)); + String message = LanguageUtils.getLocaleStringLog("geyser.core.finish.done", new DecimalFormat("#.###").format(completeTime)) + " "; if (isGui) { - message += " Run Commands -> help for help!"; + message += LanguageUtils.getLocaleStringLog("geyser.core.finish.gui"); } else { - message += " Run /geyser help for help!"; + message += LanguageUtils.getLocaleStringLog("geyser.core.finish.console"); } logger.info(message); } public void shutdown() { - bootstrap.getGeyserLogger().info("Shutting down Geyser."); + bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown")); shuttingDown = true; if (players.size() >= 1) { - bootstrap.getGeyserLogger().info("Kicking " + players.size() + " player(s)"); + bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.kick.log", players.size())); for (GeyserSession playerSession : players.values()) { - playerSession.disconnect("Geyser Proxy shutting down."); + playerSession.disconnect(LanguageUtils.getPlayerLocaleString("geyser.core.shutdown.kick.message", playerSession.getClientData().getLanguageCode())); } CompletableFuture future = CompletableFuture.runAsync(new Runnable() { @@ -209,7 +210,7 @@ public class GeyserConnector { // Block and wait for the future to complete try { future.get(); - bootstrap.getGeyserLogger().info("Kicked all players"); + bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.kick.done")); } catch (Exception e) { // Quietly fail } @@ -222,7 +223,7 @@ public class GeyserConnector { authType = null; this.getCommandManager().getCommands().clear(); - bootstrap.getGeyserLogger().info("Geyser shutdown successfully."); + bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.done")); } public void addPlayer(GeyserSession player) { 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 217a9df1f..eb75a2df4 100644 --- a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java +++ b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java @@ -29,6 +29,7 @@ import lombok.Getter; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.defaults.*; +import org.geysermc.connector.utils.LanguageUtils; import java.util.Collections; import java.util.HashMap; @@ -44,17 +45,17 @@ public abstract class CommandManager { public CommandManager(GeyserConnector connector) { this.connector = connector; - registerCommand(new HelpCommand(connector, "help", "Shows help for all registered commands.", "geyser.command.help")); - registerCommand(new ListCommand(connector, "list", "List all players connected through Geyser.", "geyser.command.list")); - 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")); + registerCommand(new HelpCommand(connector, "help", LanguageUtils.getLocaleStringLog("geyser.commands.help.desc"), "geyser.command.help")); + registerCommand(new ListCommand(connector, "list", LanguageUtils.getLocaleStringLog("geyser.commands.list.desc"), "geyser.command.list")); + registerCommand(new ReloadCommand(connector, "reload", LanguageUtils.getLocaleStringLog("geyser.commands.reload.desc"), "geyser.command.reload")); + registerCommand(new StopCommand(connector, "stop", LanguageUtils.getLocaleStringLog("geyser.commands.stop.desc"), "geyser.command.stop")); + registerCommand(new OffhandCommand(connector, "offhand", LanguageUtils.getLocaleStringLog("geyser.commands.offhand.desc"), "geyser.command.offhand")); + registerCommand(new DumpCommand(connector, "dump", LanguageUtils.getLocaleStringLog("geyser.commands.dump.desc"), "geyser.command.dump")); } public void registerCommand(GeyserCommand command) { commands.put(command.getName(), command); - connector.getLogger().debug("Registered command " + command.getName()); + connector.getLogger().debug(LanguageUtils.getLocaleStringLog("geyser.commands.registered", command.getName())); if (command.getAliases().isEmpty()) return; @@ -82,7 +83,7 @@ public abstract class CommandManager { GeyserCommand cmd = commands.get(label); if (cmd == null) { - connector.getLogger().error("Invalid Command! Try /geyser help for a list of commands."); + connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.invalid")); return; } 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 index 617c9d436..6566ecc1c 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java @@ -34,6 +34,7 @@ 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.LanguageUtils; import org.geysermc.connector.utils.WebUtils; import java.io.IOException; @@ -57,37 +58,37 @@ public class DumpCommand extends GeyserCommand { @Override public void execute(CommandSender sender, String[] args) { - sender.sendMessage("Collecting dump info"); + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collecting")); 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); + sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error")); + connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error_short"), e); return; } - sender.sendMessage("Uploading dump"); + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.uploading")); 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); + sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error")); + connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short"), e); return; } if (!responseNode.has("key")) { - sender.sendMessage(ChatColor.RED + "Failed to upload dump: " + (responseNode.has("message") ? responseNode.get("message").asText() : response)); + sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short") + ": " + (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); + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.message") + " " + ChatColor.DARK_AQUA + uploadedDumpUrl); if (!sender.isConsole()) { - connector.getLogger().info(sender.getName() + " created a GeyserDump at " + uploadedDumpUrl); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.commands.dump.created", sender.getName(), 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 a5942ee6b..0407cf6ef 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 @@ -29,6 +29,8 @@ 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.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import java.util.Collections; import java.util.List; @@ -48,7 +50,17 @@ public class HelpCommand extends GeyserCommand { @Override public void execute(CommandSender sender, String[] args) { - sender.sendMessage("---- Showing Help For: Geyser (Page 1/1) ----"); + int page = 1; + int maxPage = 1; + String header = ""; + + if (sender instanceof GeyserSession) { + header = LanguageUtils.getPlayerLocaleString("geyser.commands.help.header", ((GeyserSession) sender).getClientData().getLanguageCode(), page, maxPage); + } else { + header = LanguageUtils.getLocaleStringLog("geyser.commands.help.header", page, maxPage); + } + + sender.sendMessage(header); Map cmds = connector.getCommandManager().getCommands(); List commands = connector.getCommandManager().getCommands().keySet().stream().sorted().collect(Collectors.toList()); commands.forEach(cmd -> sender.sendMessage(ChatColor.YELLOW + "/geyser " + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription())); 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 99845ee94..0de73a5d1 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,11 +25,11 @@ package org.geysermc.connector.command.defaults; -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.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import java.util.stream.Collectors; @@ -45,6 +45,13 @@ public class ListCommand extends GeyserCommand { @Override public void execute(CommandSender sender, String[] args) { - sender.sendMessage(ChatColor.YELLOW + "Online Players (" + connector.getPlayers().size() + "): " + ChatColor.WHITE + connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" "))); + String message = ""; + if (sender instanceof GeyserSession) { + message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", ((GeyserSession) sender).getClientData().getLanguageCode(), connector.getPlayers().size(), connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" "))); + } else { + message = LanguageUtils.getLocaleStringLog("geyser.commands.list.message", connector.getPlayers().size(), connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" "))); + } + + sender.sendMessage(message); } } 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 2ddd61ed8..d8bf8583b 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,12 +25,12 @@ package org.geysermc.connector.command.defaults; -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; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; public class ReloadCommand extends GeyserCommand { @@ -46,9 +46,18 @@ public class ReloadCommand extends GeyserCommand { if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) { return; } - sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked."); + + String message = ""; + if (sender instanceof GeyserSession) { + message = LanguageUtils.getPlayerLocaleString("geyser.commands.reload.message", ((GeyserSession) sender).getClientData().getLanguageCode()); + } else { + message = LanguageUtils.getLocaleStringLog("geyser.commands.reload.message"); + } + + sender.sendMessage(message); + for (GeyserSession session : connector.getPlayers().values()) { - session.disconnect("Geyser has been reloaded... sorry for the inconvenience!"); + session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.commands.reload.kick", session.getClientData().getLanguageCode())); } connector.reload(); } diff --git a/connector/src/main/java/org/geysermc/connector/common/main/IGeyserMain.java b/connector/src/main/java/org/geysermc/connector/common/main/IGeyserMain.java index 906bd7865..a3e99ccb3 100644 --- a/connector/src/main/java/org/geysermc/connector/common/main/IGeyserMain.java +++ b/connector/src/main/java/org/geysermc/connector/common/main/IGeyserMain.java @@ -28,24 +28,39 @@ package org.geysermc.connector.common.main; import javax.swing.*; import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.Locale; import java.util.Scanner; public class IGeyserMain { + /** + * Displays the run help message in the console and a message box if running with a gui + */ public void displayMessage() { String message = createMessage(); - if (System.console() == null) { + if (System.console() == null && !isHeadless()) { JOptionPane.showMessageDialog(null, message, "GeyserMC Plugin: " + this.getPluginType(), JOptionPane.ERROR_MESSAGE); } printMessage(message); } + /** + * Load and format the run help text + * + * @return The formatted message + */ private String createMessage() { String message = ""; - InputStream helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("help.txt"); + InputStream helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("languages/run-help/" + Locale.getDefault().toString() + ".txt"); + + if (helpStream == null) { + helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("languages/run-help/en_US.txt"); + } + Scanner help = new Scanner(helpStream).useDelimiter("\\Z"); String line = ""; while (help.hasNext()) { @@ -60,14 +75,44 @@ public class IGeyserMain { return message; } + /** + * Check if we are in a headless environment + * + * @return Are we in a headless environment? + */ + private boolean isHeadless() { + try { + Class graphicsEnvironment = Class.forName("java.awt.GraphicsEnvironment"); + Method isHeadless = graphicsEnvironment.getDeclaredMethod("isHeadless"); + return (Boolean)isHeadless.invoke(null); + } catch (Exception ex) { } + + return true; + } + + /** + * Simply print a message to console + * + * @param message The message to print + */ private void printMessage(String message) { System.out.print(message); } + /** + * Get the platform the plugin is for + * + * @return The string representation of the plugin platforms name + */ public String getPluginType() { return "unknown"; } + /** + * Get the folder name the plugin should go into + * + * @return The string representation of the folder + */ public String getPluginFolder() { return "unknown"; } diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java index 5ea942c1a..5727a902f 100644 --- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java +++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserConfiguration.java @@ -28,6 +28,8 @@ package org.geysermc.connector.configuration; import org.geysermc.connector.GeyserLogger; +import org.geysermc.connector.utils.LanguageUtils; + import java.nio.file.Path; import java.util.Map; @@ -111,9 +113,9 @@ public interface GeyserConfiguration { static void checkGeyserConfiguration(GeyserConfiguration geyserConfig, GeyserLogger geyserLogger) { if (geyserConfig.getConfigVersion() < CURRENT_CONFIG_VERSION) { - geyserLogger.warning("Your Geyser config is out of date! Please regenerate your config when possible."); + geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.outdated")); } else if (geyserConfig.getConfigVersion() > CURRENT_CONFIG_VERSION) { - geyserLogger.warning("Your Geyser config is too new! Errors may occur."); + geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.too_new")); } } } 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 27b7ad8fe..ad5cb42aa 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -37,6 +37,7 @@ 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 org.geysermc.connector.utils.LanguageUtils; import java.net.InetSocketAddress; @@ -50,13 +51,13 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { @Override public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) { - connector.getLogger().info(inetSocketAddress + " tried to connect!"); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.attempt_connect", inetSocketAddress)); return true; } @Override public BedrockPong onQuery(InetSocketAddress inetSocketAddress) { - connector.getLogger().debug(inetSocketAddress + " has pinged you!"); + connector.getLogger().debug(LanguageUtils.getLocaleStringLog("geyser.network.pinged", inetSocketAddress)); GeyserConfiguration config = connector.getConfig(); @@ -108,7 +109,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { bedrockServerSession.setLogging(true); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession))); bedrockServerSession.addDisconnectHandler(disconnectReason -> { - connector.getLogger().info("Bedrock user with ip: " + bedrockServerSession.getAddress().getAddress() + " has disconnected for reason " + disconnectReason); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.disconnect", bedrockServerSession.getAddress().getAddress(), disconnectReason)); GeyserSession player = connector.getPlayers().get(bedrockServerSession.getAddress()); if (player != null) { 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 79dcf1385..943b4568c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -33,6 +33,7 @@ import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslatorRegistry; import org.geysermc.connector.utils.LoginEncryptionUtils; +import org.geysermc.connector.utils.LanguageUtils; public class UpstreamPacketHandler extends LoggingPacketHandler { @@ -47,10 +48,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { @Override public boolean handle(LoginPacket loginPacket) { if (loginPacket.getProtocolVersion() > GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) { - session.disconnect("Outdated Geyser proxy! I'm still on " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); + session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.outdated.server", session.getClientData().getLanguageCode(), GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion())); return true; } else if (loginPacket.getProtocolVersion() < GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) { - session.disconnect("Outdated Bedrock client! Please use " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()); + session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.outdated.client", session.getClientData().getLanguageCode(), GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion())); return true; } @@ -70,7 +71,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { switch (packet.getStatus()) { case COMPLETED: session.connect(connector.getRemoteServer()); - connector.getLogger().info("Player connected with username " + session.getAuthData().getName()); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.connect", session.getAuthData().getName())); break; case HAVE_ALL_PACKS: ResourcePackStackPacket stack = new ResourcePackStackPacket(); @@ -97,7 +98,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { GeyserConfiguration.IUserAuthenticationInfo info = connector.getConfig().getUserAuths().get(bedrockUsername); if (info != null) { - connector.getLogger().info("using stored credentials for bedrock user " + session.getAuthData().getName()); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.stored_credentials", session.getAuthData().getName())); session.authenticate(info.getEmail(), info.getPassword()); // TODO send a message to bedrock user telling them they are connected (if nothing like a motd @@ -111,6 +112,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { @Override public boolean handle(SetLocalPlayerAsInitializedPacket packet) { + LanguageUtils.loadGeyserLocale(session.getClientData().getLanguageCode()); + if (!session.isLoggedIn() && !session.isLoggingIn() && session.getConnector().getAuthType() == AuthType.ONLINE) { // TODO it is safer to key authentication on something that won't change (UUID, not username) if (!couldLoginUserByName(session.getAuthData().getName())) { @@ -124,7 +127,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { @Override public boolean handle(MovePlayerPacket packet) { if (session.isLoggingIn()) { - session.sendMessage("Please wait until you are logged in..."); + session.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.auth.login.wait", session.getClientData().getLanguageCode())); } return translateAndDefault(packet); 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 93c619bfc..666820cc2 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 @@ -258,12 +258,11 @@ public class GeyserSession implements CommandSender { public void login() { if (connector.getAuthType() != AuthType.ONLINE) { - connector.getLogger().info( - "Attempting to login using " + connector.getAuthType().name().toLowerCase() + " mode... " + - (connector.getAuthType() == AuthType.OFFLINE ? - "authentication is disabled." : "authentication will be encrypted" - ) - ); + if (connector.getAuthType() == AuthType.OFFLINE) { + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.offline")); + } else { + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.floodgate")); + } authenticate(authData.getName()); } } @@ -274,7 +273,7 @@ public class GeyserSession implements CommandSender { public void authenticate(String username, String password) { if (loggedIn) { - connector.getLogger().severe(username + " is already logged in!"); + connector.getLogger().severe(LanguageUtils.getLocaleStringLog("geyser.auth.already_loggedin", username)); return; } @@ -299,13 +298,13 @@ public class GeyserSession implements CommandSender { PublicKey.class ); } catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException e) { - connector.getLogger().error("Error while reading Floodgate key file", e); + connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.auth.floodgate.bad_key"), e); } publicKey = key; } else publicKey = null; if (publicKey != null) { - connector.getLogger().info("Loaded Floodgate key!"); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.floodgate.loaded_key")); } downstream = new Client(remoteServer.getAddress(), remoteServer.getPort(), protocol, new TcpSessionFactory()); @@ -326,7 +325,7 @@ public class GeyserSession implements CommandSender { upstream.getSession().getAddress().getAddress().getHostAddress() )); } catch (Exception e) { - connector.getLogger().error("Failed to encrypt message", e); + connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.auth.floodgate.encrypt_fail"), e); } HandshakePacket handshakePacket = event.getPacket(); @@ -343,7 +342,7 @@ public class GeyserSession implements CommandSender { public void connected(ConnectedEvent event) { loggingIn = false; loggedIn = true; - connector.getLogger().info(authData.getName() + " (logged in as: " + protocol.getProfile().getName() + ")" + " has connected to remote java server on address " + remoteServer.getAddress()); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.connect", authData.getName(), protocol.getProfile().getName(), remoteServer.getAddress())); playerEntity.setUuid(protocol.getProfile().getId()); playerEntity.setUsername(protocol.getProfile().getName()); @@ -352,6 +351,7 @@ public class GeyserSession implements CommandSender { // Let the user know there locale may take some time to download // as it has to be extracted from a JAR if (locale.toLowerCase().equals("en_us") && !LocaleUtils.LOCALE_MAPPINGS.containsKey("en_us")) { + // This should probably be left hardcoded as it will only show for en_us clients sendMessage("Downloading your locale (en_us) this may take some time"); } @@ -363,7 +363,7 @@ public class GeyserSession implements CommandSender { public void disconnected(DisconnectedEvent event) { loggingIn = false; loggedIn = false; - connector.getLogger().info(authData.getName() + " has disconnected from remote java server on address " + remoteServer.getAddress() + " because of " + event.getReason()); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.remote.disconnect", authData.getName(), remoteServer.getAddress(), event.getReason())); if (event.getCause() != null) { event.getCause().printStackTrace(); } @@ -402,7 +402,7 @@ public class GeyserSession implements CommandSender { @Override public void packetError(PacketErrorEvent event) { - connector.getLogger().warning("Downstream packet error! " + event.getCause().getMessage()); + connector.getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.network.downstream_error", event.getCause().getMessage())); if (connector.getConfig().isDebugMode()) event.getCause().printStackTrace(); event.setSuppress(true); @@ -412,8 +412,8 @@ public class GeyserSession implements CommandSender { downstream.getSession().connect(); connector.addPlayer(this); } catch (InvalidCredentialsException | IllegalArgumentException e) { - connector.getLogger().info("User '" + username + "' entered invalid login info, kicking."); - disconnect("Invalid/incorrect login info"); + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.auth.login.invalid", username)); + disconnect(LanguageUtils.getPlayerLocaleString("geyser.auth.login.invalid.kick", getClientData().getLanguageCode())); } catch (RequestException ex) { ex.printStackTrace(); } @@ -442,7 +442,7 @@ public class GeyserSession implements CommandSender { } public void close() { - disconnect("Server closed."); + disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.close", getClientData().getLanguageCode())); } public void setAuthenticationData(AuthData authData) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java index 23a36641e..2daa6b2f4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java @@ -31,6 +31,7 @@ import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtUtils; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.utils.FileUtils; +import org.geysermc.connector.utils.LanguageUtils; import java.io.InputStream; import java.util.Arrays; @@ -59,7 +60,7 @@ public class BiomeTranslator { biomesTag = (NbtMap) biomenbtInputStream.readTag(); BIOMES = biomesTag; } catch (Exception ex) { - GeyserConnector.getInstance().getLogger().warning("Failed to get biomes from biome definitions, is there something wrong with the file?"); + GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.biome_read")); throw new AssertionError(ex); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java index 59f4ae8ba..1f3366678 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/EntityIdentifierRegistry.java @@ -30,6 +30,7 @@ import com.nukkitx.nbt.NBTInputStream; import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtUtils; import org.geysermc.connector.utils.FileUtils; +import org.geysermc.connector.utils.LanguageUtils; import java.io.InputStream; @@ -54,7 +55,7 @@ public class EntityIdentifierRegistry { try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) { ENTITY_IDENTIFIERS = (NbtMap) nbtInputStream.readTag(); } catch (Exception e) { - throw new AssertionError("Unable to get entities from entity identifiers", e); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.entity"), e); } } } 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 a11dd40af..92d2e9102 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 @@ -33,6 +33,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacket; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import org.reflections.Reflections; import java.util.HashMap; @@ -66,10 +67,10 @@ public class PacketTranslatorRegistry { BEDROCK_TRANSLATOR.translators.put(targetPacket, translator); } else { - GeyserConnector.getInstance().getLogger().error("Class " + clazz.getCanonicalName() + " is annotated as a translator but has an invalid target packet."); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.invalid_target", clazz.getCanonicalName())); } } catch (InstantiationException | IllegalAccessException e) { - GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated translator " + clazz.getCanonicalName() + "."); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.failed", clazz.getCanonicalName())); } } @@ -97,7 +98,7 @@ public class PacketTranslatorRegistry { GeyserConnector.getInstance().getLogger().debug("Could not find packet for " + (packet.toString().length() > 25 ? packet.getClass().getSimpleName() : packet)); } } catch (Throwable ex) { - GeyserConnector.getInstance().getLogger().error("Could not translate packet " + packet.getClass().getSimpleName(), ex); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex); ex.printStackTrace(); } } 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 index 9e3c14e6d..5e4633ea5 100644 --- 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 @@ -36,6 +36,7 @@ public class BedrockPacketViolationWarningTranslator extends PacketTranslator" + entry.getValue().asText()); + GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.particle.failed_map", entry.getKey(), entry.getValue().asText())); } } } 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 41489ac2a..7d7673c4e 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 @@ -39,12 +39,12 @@ import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.utils.InventoryUtils; +import org.geysermc.connector.utils.LanguageUtils; import java.util.List; public class PlayerInventoryTranslator extends InventoryTranslator { - private static final ItemData UNUSUABLE_CRAFTING_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock( - "The creative crafting grid is\nunavailable in Java Edition"); + private static final ItemData UNUSUABLE_CRAFTING_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock(LanguageUtils.getLocaleStringLog("geyser.inventory.unusable_item.creative")); public PlayerInventoryTranslator() { super(46); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java index 7437a26e4..e45945bc3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java @@ -34,11 +34,11 @@ import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.utils.InventoryUtils; +import org.geysermc.connector.utils.LanguageUtils; @AllArgsConstructor public class ChestInventoryUpdater extends InventoryUpdater { - private static final ItemData UNUSUABLE_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock( - "This slot does not exist in the inventory\non Java Edition, as there is less\nrows than possible in Bedrock"); + private static final ItemData UNUSUABLE_SPACE_BLOCK = InventoryUtils.createUnusableSpaceBlock(LanguageUtils.getLocaleStringLog("geyser.inventory.unusable_item.slot")); private final int paddedSize; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java index 0979e5731..23c566d7c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemRegistry.java @@ -37,16 +37,12 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.utils.FileUtils; +import org.geysermc.connector.utils.LanguageUtils; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Base64; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Registry for anything item related. @@ -82,7 +78,7 @@ public class ItemRegistry { try { itemEntries = GeyserConnector.JSON_MAPPER.readValue(stream, itemEntriesType); } catch (Exception e) { - throw new AssertionError("Unable to load Bedrock runtime item IDs", e); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_bedrock"), e); } for (JsonNode entry : itemEntries) { @@ -95,7 +91,7 @@ public class ItemRegistry { try { items = GeyserConnector.JSON_MAPPER.readTree(stream); } catch (Exception e) { - throw new AssertionError("Unable to load Java runtime item IDs", e); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e); } int itemIndex = 0; @@ -144,7 +140,7 @@ public class ItemRegistry { try { creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items"); } catch (Exception e) { - throw new AssertionError("Unable to load creative items", e); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e); } List creativeItems = new ArrayList<>(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 6811d6bb6..7811d9c0a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -50,6 +50,7 @@ import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; import org.geysermc.connector.utils.MessageUtils; +import org.geysermc.connector.utils.LanguageUtils; import org.reflections.Reflections; import java.util.*; @@ -88,14 +89,13 @@ public abstract class ItemTranslator { for (ItemEntry item : appliedItems) { ItemTranslator registered = ITEM_STACK_TRANSLATORS.get(item.getJavaId()); if (registered != null) { - GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + "." + - " Item translator " + registered.getClass().getCanonicalName() + " is already registered for the item " + item.getJavaIdentifier()); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.item.already_registered", clazz.getCanonicalName(), registered.getClass().getCanonicalName(), item.getJavaIdentifier())); continue; } ITEM_STACK_TRANSLATORS.put(item.getJavaId(), itemStackTranslator); } } catch (InstantiationException | IllegalAccessException e) { - GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated item translator " + clazz.getCanonicalName() + "."); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.item.failed", clazz.getCanonicalName())); } } 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 8b0b82014..491779121 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 @@ -41,6 +41,7 @@ import org.geysermc.connector.network.session.cache.TeleportCache; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.ChunkUtils; +import org.geysermc.connector.utils.LanguageUtils; @Translator(packet = ServerPlayerPositionRotationPacket.class) public class JavaPlayerPositionRotationTranslator extends PacketTranslator { @@ -90,7 +91,7 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator { @@ -66,21 +65,21 @@ public class JavaTeamTranslator extends PacketTranslator { .setSuffix(MessageUtils.getBedrockMessage(packet.getSuffix())) .setUpdateType(UpdateType.UPDATE); } else { - GeyserConnector.getInstance().getLogger().error("Error while translating Team Packet " + packet.getAction() + "! Scoreboard Team " + packet.getTeamName() + " is not registered."); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_not_registered", packet.getAction(), packet.getTeamName())); } break; case ADD_PLAYER: if(team != null){ team.addEntities(packet.getPlayers()); } else { - GeyserConnector.getInstance().getLogger().error("Error while translating Team Packet " + packet.getAction() + "! Scoreboard Team " + packet.getTeamName() + " is not registered."); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_not_registered", packet.getAction(), packet.getTeamName())); } break; case REMOVE_PLAYER: if(team != null){ team.removeEntities(packet.getPlayers()); } else { - GeyserConnector.getInstance().getLogger().error("Error while translating Team Packet " + packet.getAction() + "! Scoreboard Team " + packet.getTeamName() + " is not registered."); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_not_registered", packet.getAction(), packet.getTeamName())); } break; case REMOVE: diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java index eac2ed049..827e4c7f4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/scoreboard/JavaUpdateScoreTranslator.java @@ -34,6 +34,7 @@ import org.geysermc.connector.scoreboard.Scoreboard; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardAction; import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerUpdateScorePacket; +import org.geysermc.connector.utils.LanguageUtils; @Translator(packet = ServerUpdateScorePacket.class) public class JavaUpdateScoreTranslator extends PacketTranslator { @@ -45,7 +46,7 @@ public class JavaUpdateScoreTranslator extends PacketTranslator clazz : ref.getSubTypesOf(RequiresBlockState.class)) { @@ -81,7 +82,7 @@ public abstract class BlockEntityTranslator { try { REQUIRES_BLOCK_STATE_LIST.add((RequiresBlockState) clazz.newInstance()); } catch (InstantiationException | IllegalAccessException e) { - GeyserConnector.getInstance().getLogger().error("Could not instantiate required block state " + clazz.getCanonicalName() + "."); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.block_state.failed", clazz.getCanonicalName())); } } } diff --git a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java index 59d9b25f6..5fdda617f 100644 --- a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java +++ b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java @@ -34,6 +34,7 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.Getter; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.utils.LanguageUtils; import java.util.*; import java.util.concurrent.atomic.AtomicLong; @@ -78,7 +79,7 @@ public class Scoreboard { public Team registerNewTeam(String teamName, Set players) { if (teams.containsKey(teamName)) { - session.getConnector().getLogger().info("Ignoring team " + teamName + ". It overrides without removing old team."); + session.getConnector().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.translator.team.failed_overrides", teamName)); return getTeam(teamName); } 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 09c78da92..a6eb6c9ba 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java +++ b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java @@ -49,8 +49,8 @@ public class DockerCheck { String output = new String(Files.readAllBytes(Paths.get("/proc/1/cgroup"))); if (output.contains("docker")) { - bootstrap.getGeyserLogger().warning("You are most likely in a Docker container, this may cause connection issues from Geyser to the Java server"); - bootstrap.getGeyserLogger().warning("We recommended using the following IP as the remote address: " + ipAddress); + bootstrap.getGeyserLogger().warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.docker_warn.line1")); + bootstrap.getGeyserLogger().warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.docker_warn.line2", ipAddress)); } } } catch (Exception e) { } // Ignore any errors, inc ip failed to fetch, process could not run or access denied diff --git a/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java b/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java index 04b6ecc4d..0b7b5c5cf 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/FileUtils.java @@ -135,7 +135,7 @@ public class FileUtils { public static InputStream getResource(String resource) { InputStream stream = FileUtils.class.getClassLoader().getResourceAsStream(resource); if (stream == null) { - throw new AssertionError("Unable to find resource: " + resource); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.resource", resource)); } return stream; } 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 9862159dc..325710c6d 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -140,7 +140,8 @@ public class InventoryUtils { NbtMapBuilder root = NbtMap.builder(); NbtMapBuilder display = NbtMap.builder(); - display.putString("Name", ChatColor.RESET + "Unusable inventory space"); + // Not ideal to use log here but we dont get a session + display.putString("Name", ChatColor.RESET + LanguageUtils.getLocaleStringLog("geyser.inventory.unusable_item.name")); display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description)); root.put("display", display.build()); diff --git a/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java new file mode 100644 index 000000000..6d353adbe --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java @@ -0,0 +1,207 @@ +/* + * 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 org.geysermc.connector.GeyserConnector; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; + +public class LanguageUtils { + + /** + * If we determine the locale that the user wishes to use, use that locale + */ + private static String CACHED_LOCALE; + + private static final Map LOCALE_MAPPINGS = new HashMap<>(); + + static { + // Load it as a backup in case something goes really wrong + if (!"en_US".equals(formatLocale(getDefaultLocale()))) { // getDefaultLocale() loads the locale automatically + loadGeyserLocale("en_US"); + } + } + + /** + * Loads a Geyser locale from resources, if the file doesn't exist it just logs a warning + * + * @param locale Locale to load + */ + public static void loadGeyserLocale(String locale) { + locale = formatLocale(locale); + + InputStream localeStream = GeyserConnector.class.getClassLoader().getResourceAsStream("languages/texts/" + locale + ".properties"); + + // Load the locale + if (localeStream != null) { + Properties localeProp = new Properties(); + try { + localeProp.load(new InputStreamReader(localeStream, StandardCharsets.UTF_8)); + } catch (Exception e) { + throw new AssertionError(getLocaleStringLog("geyser.language.load_failed", locale), e); + } + + // Insert the locale into the mappings + LOCALE_MAPPINGS.put(locale, localeProp); + } else { + if (!locale.toLowerCase().equals(getDefaultLocale().toLowerCase())) { // The default locale was invalid fallback to en_us + GeyserConnector.getInstance().getLogger().warning(getLocaleStringLog("geyser.language.missing_file", locale)); + } + } + } + + /** + * Get a formatted language string with the default locale for Geyser + * + * @param key Language string to translate + * @param values Values to put into the string + * @return Translated string or the original message if it was not found in the given locale + */ + public static String getLocaleStringLog(String key, Object... values) { + return getPlayerLocaleString(key, getDefaultLocale(), values); + } + + /** + * Get a formatted language string with the given locale for Geyser + * + * @param key Language string to translate + * @param locale Locale to translate to + * @param values Values to put into the string + * @return Translated string or the original message if it was not found in the given locale + */ + public static String getPlayerLocaleString(String key, String locale, Object... values) { + locale = formatLocale(locale); + + Properties properties = LOCALE_MAPPINGS.get(locale); + String formatString = properties.getProperty(key); + + // Try and get the key from the default locale + if (formatString == null) { + properties = LOCALE_MAPPINGS.get(formatLocale(getDefaultLocale())); + formatString = properties.getProperty(key); + } + + // Try and get the key from en_US (this should only ever happen in development) + if (formatString == null) { + properties = LOCALE_MAPPINGS.get("en_US"); + formatString = properties.getProperty(key); + } + + // Final fallback + if (formatString == null) { + formatString = key; + } + + return MessageFormat.format(formatString.replace("&", "\u00a7"), values); + } + + /** + * Cleans up and formats a locale string + * + * @param locale The locale to format + * @return The formatted locale + */ + private static String formatLocale(String locale) { + try { + String[] parts = locale.toLowerCase().split("_"); + String newLocale = parts[0] + "_" + parts[1].toUpperCase(); + switch (newLocale) { // Fallback to the closest language if we don't support it but Bedrock does. + case "es_MX": + return "es_ES"; + case "pt_BR": + return "pt_PT"; + case "fr_CA": + return "fr_FR"; + default: + return newLocale; + } + } catch (Exception e) { + return locale; + } + } + + /** + * Get the default locale that Geyser should use + * @return the current default locale + */ + public static String getDefaultLocale() { + if (CACHED_LOCALE != null) return CACHED_LOCALE; // We definitely know the locale the user is using + String locale; + boolean isValid = true; + if (GeyserConnector.getInstance() != null && + GeyserConnector.getInstance().getConfig() != null && + GeyserConnector.getInstance().getConfig().getDefaultLocale() != null) { // If the config option for getDefaultLocale does not equal null, use that + locale = formatLocale(GeyserConnector.getInstance().getConfig().getDefaultLocale()); + if (isValidLanguage(locale)) { + CACHED_LOCALE = locale; + return locale; + } else { + isValid = false; + } + } + locale = formatLocale(Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry()); + if (!isValidLanguage(locale)) { // Bedrock does not support this language + locale = "en_US"; + } + if (GeyserConnector.getInstance() != null && + GeyserConnector.getInstance().getConfig() != null && (GeyserConnector.getInstance().getConfig().getDefaultLocale() == null || !isValid)) { // Means we should use the system locale for sure + CACHED_LOCALE = locale; + } + return locale; + } + + /** + * Ensures that the given locale is supported by Bedrock + * @param locale the locale to validate + * @return true if the given locale is supported by Bedrock and by extension Geyser + */ + private static boolean isValidLanguage(String locale) { + boolean result = true; + if (FileUtils.class.getResource("/languages/texts/" + locale + ".properties") == null) { + result = false; + if (GeyserConnector.getInstance() != null && GeyserConnector.getInstance().getLogger() != null) { // Could be too early for these to be initialized + GeyserConnector.getInstance().getLogger().warning(locale + " is not a valid Bedrock language."); // We can't translate this since we just loaded an invalid language + } + } else { + if (!LOCALE_MAPPINGS.containsKey(locale)) { + loadGeyserLocale(locale); + } + } + return result; + } + + public static void init() { + // no-op + } +} 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 787525913..285846a97 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LocaleUtils.java @@ -48,8 +48,6 @@ public class LocaleUtils { private static final Map ASSET_MAP = new HashMap<>(); - private static final String DEFAULT_LOCALE = (GeyserConnector.getInstance().getConfig().getDefaultLocale() != null ? GeyserConnector.getInstance().getConfig().getDefaultLocale() : "en_us"); - private static String smallestURL = ""; static { @@ -60,7 +58,7 @@ public class LocaleUtils { // Download the latest asset list and cache it generateAssetCache(); - downloadAndLoadLocale(DEFAULT_LOCALE); + downloadAndLoadLocale(LanguageUtils.getDefaultLocale()); } /** @@ -82,7 +80,7 @@ public class LocaleUtils { // Make sure we definitely got a version if (latestInfoURL.isEmpty()) { - throw new Exception("Unable to get latest Minecraft version"); + throw new Exception(LanguageUtils.getLocaleStringLog("geyser.locale.fail.latest_version")); } // Get the individual version manifest @@ -105,7 +103,7 @@ public class LocaleUtils { ASSET_MAP.put(entry.getKey(), asset); } } catch (Exception e) { - GeyserConnector.getInstance().getLogger().info("Failed to load locale asset cache: " + (!e.getMessage().isEmpty() ? e.getMessage() : e.getStackTrace())); + GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.locale.fail.asset_cache", (!e.getMessage().isEmpty() ? e.getMessage() : e.getStackTrace()))); } } @@ -119,7 +117,7 @@ public class LocaleUtils { // Check the locale isn't already loaded if (!ASSET_MAP.containsKey("minecraft/lang/" + locale + ".json") && !locale.equals("en_us")) { - GeyserConnector.getInstance().getLogger().warning("Invalid locale requested to download and load: " + locale); + GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.locale.fail.invalid", locale)); return; } @@ -170,7 +168,7 @@ public class LocaleUtils { try { localeStream = new FileInputStream(localeFile); } catch (FileNotFoundException e) { - throw new AssertionError("Unable to load locale: " + locale + " (" + e.getMessage() + ")"); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.locale.fail.file", locale, e.getMessage())); } // Parse the file as json @@ -178,7 +176,7 @@ public class LocaleUtils { try { localeObj = GeyserConnector.JSON_MAPPER.readTree(localeStream); } catch (Exception e) { - throw new AssertionError("Unable to load Java edition lang map for " + locale, e); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.locale.fail.json", locale), e); } // Parse all the locale fields @@ -192,7 +190,7 @@ public class LocaleUtils { // Insert the locale into the mappings LOCALE_MAPPINGS.put(locale.toLowerCase(), langMap); } else { - GeyserConnector.getInstance().getLogger().warning("Missing locale file: " + locale); + GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.locale.fail.missing", locale)); } } @@ -204,7 +202,7 @@ public class LocaleUtils { private static void downloadEN_US(File localeFile) { try { // Let the user know we are downloading the JAR - GeyserConnector.getInstance().getLogger().info("Downloading Minecraft JAR to extract en_us locale, please wait... (this may take some time depending on the speed of your internet connection)"); + GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.locale.download.en_us")); GeyserConnector.getInstance().getLogger().debug("Download URL: " + smallestURL); // Download the smallest JAR (client or server) @@ -233,7 +231,7 @@ public class LocaleUtils { // Delete the nolonger needed client/server jar Files.delete(tmpFilePath); } catch (Exception e) { - throw new AssertionError("Unable to download and extract en_us locale!", e); + throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.locale.fail.en_us"), e); } } @@ -247,7 +245,7 @@ public class LocaleUtils { public static String getLocaleString(String messageText, String locale) { Map localeStrings = LocaleUtils.LOCALE_MAPPINGS.get(locale.toLowerCase()); if (localeStrings == null) - localeStrings = LocaleUtils.LOCALE_MAPPINGS.get(DEFAULT_LOCALE); + localeStrings = LocaleUtils.LOCALE_MAPPINGS.get(LanguageUtils.getDefaultLocale()); return localeStrings.getOrDefault(messageText, messageText); } diff --git a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java index f9a7fec26..3d4dd506a 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java @@ -156,18 +156,20 @@ public class LoginEncryptionUtils { private static int AUTH_DETAILS_FORM_ID = 1337; public static void showLoginWindow(GeyserSession session) { - SimpleFormWindow window = new SimpleFormWindow("Login", "You need a Java Edition account to play on this server."); - window.getButtons().add(new FormButton("Login with Minecraft")); - window.getButtons().add(new FormButton("Disconnect")); + String userLanguage = session.getClientData().getLanguageCode(); + SimpleFormWindow window = new SimpleFormWindow(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.title", userLanguage), LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.desc", userLanguage)); + window.getButtons().add(new FormButton(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.btn_login", userLanguage))); + window.getButtons().add(new FormButton(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.notice.btn_disconnect", userLanguage))); session.sendForm(window, AUTH_FORM_ID); } public static void showLoginDetailsWindow(GeyserSession session) { - CustomFormWindow window = new CustomFormBuilder("Login Details") - .addComponent(new LabelComponent("Enter the credentials for your Minecraft: Java Edition account below.")) - .addComponent(new InputComponent("Email/Username", "account@geysermc.org", "")) - .addComponent(new InputComponent("Password", "123456", "")) + String userLanguage = session.getClientData().getLanguageCode(); + CustomFormWindow window = new CustomFormBuilder(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.title", userLanguage)) + .addComponent(new LabelComponent(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.desc", userLanguage))) + .addComponent(new InputComponent(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.email", userLanguage), "account@geysermc.org", "")) + .addComponent(new InputComponent(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.details.pass", userLanguage), "123456", "")) .build(); session.sendForm(window, AUTH_DETAILS_FORM_ID); @@ -203,8 +205,8 @@ public class LoginEncryptionUtils { if (response != null) { if (response.getClickedButtonId() == 0) { showLoginDetailsWindow(session); - } else if (response.getClickedButtonId() == 1) { - session.disconnect("Login is required"); + } else if(response.getClickedButtonId() == 1) { + session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.auth.login.form.disconnect", session.getClientData().getLanguageCode())); } } else { showLoginWindow(session); 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 9e0712477..225885769 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java @@ -246,7 +246,7 @@ public class SkinUtils { } } } catch (Exception e) { - GeyserConnector.getInstance().getLogger().error("Failed getting skin for " + entity.getUuid(), e); + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.skin.fail", entity.getUuid()), e); } if (skinAndCapeConsumer != null) skinAndCapeConsumer.accept(skinAndCape); @@ -257,7 +257,7 @@ public class SkinUtils { public static void handleBedrockSkin(PlayerEntity playerEntity, BedrockClientData clientData) { GameProfileData data = GameProfileData.from(playerEntity.getProfile()); - GeyserConnector.getInstance().getLogger().info("Registering bedrock skin for " + playerEntity.getUsername() + " (" + playerEntity.getUuid() + ")"); + GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.skin.bedrock.register", playerEntity.getUsername(), playerEntity.getUuid())); try { byte[] skinBytes = com.github.steveice10.mc.auth.util.Base64.decode(clientData.getSkinData().getBytes("UTF-8")); @@ -270,7 +270,7 @@ public class SkinUtils { SkinProvider.storeBedrockSkin(playerEntity.getUuid(), data.getSkinUrl(), skinBytes); SkinProvider.storeBedrockGeometry(playerEntity.getUuid(), geometryNameBytes, geometryBytes); } else { - GeyserConnector.getInstance().getLogger().info("Unable to load bedrock skin for '" + playerEntity.getUsername() + "' as they are likely using a customised skin"); + GeyserConnector.getInstance().getLogger().info(LanguageUtils.getLocaleStringLog("geyser.skin.bedrock.fail", playerEntity.getUsername())); GeyserConnector.getInstance().getLogger().debug("The size of '" + playerEntity.getUsername() + "' skin is: " + clientData.getSkinImageWidth() + "x" + clientData.getSkinImageHeight()); } diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index eb4c1ddca..91f95e6ed 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -78,8 +78,8 @@ 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 +# The default locale if we dont have the one the client requested. Uncomment to not use the default system language. +# default-locale: en_us # Configures if chunk caching should be enabled or not. This keeps an individual # record of each block the client loads in. While this feature does allow for a few diff --git a/connector/src/main/resources/languages b/connector/src/main/resources/languages new file mode 160000 index 000000000..08be7fdd7 --- /dev/null +++ b/connector/src/main/resources/languages @@ -0,0 +1 @@ +Subproject commit 08be7fdd7bd3c1ade46fa8968c04d3d67bb0d378 From 6cdf1eaf439b4936bbf0fe490cd08daf934d340b Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 6 Jul 2020 00:46:51 +0100 Subject: [PATCH 089/104] Fix player table throwing errors on interaction --- .../standalone/gui/GeyserStandaloneGUI.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java index 5a6b4c89d..9be0e1c6a 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java @@ -47,20 +47,19 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Vector; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class GeyserStandaloneGUI { - private static final String[] playerTableHeadings = new String[] { - LanguageUtils.getLocaleStringLog("geyser.gui.table.ip"), - LanguageUtils.getLocaleStringLog("geyser.gui.table.username")}; + private static final DefaultTableModel playerTableModel = new DefaultTableModel(); private static final List ramValues = new ArrayList<>(); private static final ColorPane consolePane = new ColorPane(); private static final GraphPanel ramGraph = new GraphPanel(); - private static final JTable playerTable = new JTable(new String[][] { }, playerTableHeadings); + private static final JTable playerTable = new JTable(playerTableModel); private static final int originalFontSize = consolePane.getFont().getSize(); private static final long MEGABYTE = 1024L * 1024L; @@ -201,6 +200,9 @@ public class GeyserStandaloneGUI { ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.loading")); rightContentPane.add(ramGraph); + playerTableModel.addColumn(LanguageUtils.getLocaleStringLog("geyser.gui.table.ip")); + playerTableModel.addColumn(LanguageUtils.getLocaleStringLog("geyser.gui.table.username")); + JScrollPane playerScrollPane = new JScrollPane(playerTable); rightContentPane.add(playerScrollPane); @@ -288,18 +290,17 @@ public class GeyserStandaloneGUI { Runnable periodicTask = () -> { if (GeyserConnector.getInstance() != null) { // Update player table - String[][] playerNames = new String[GeyserConnector.getInstance().getPlayers().size()][2]; - int i = 0; - for (Map.Entry player : GeyserConnector.getInstance().getPlayers().entrySet()) { - playerNames[i][0] = player.getKey().getHostName(); - playerNames[i][1] = player.getValue().getPlayerEntity().getUsername(); + playerTableModel.getDataVector().removeAllElements(); - i++; + for (Map.Entry player : GeyserConnector.getInstance().getPlayers().entrySet()) { + Vector row = new Vector(); + row.add(player.getKey().getHostName()); + row.add(player.getValue().getPlayerEntity().getUsername()); + + playerTableModel.addRow(row); } - DefaultTableModel model = new DefaultTableModel(playerNames, playerTableHeadings); - playerTable.setModel(model); - model.fireTableDataChanged(); + playerTableModel.fireTableDataChanged(); } // Update ram graph From ca4d827d2868f8075d4375dd76acbae5cfa2ea87 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 5 Jul 2020 21:13:28 -0400 Subject: [PATCH 090/104] Don't cause a recursion error if Geyser can't find the locale --- .../main/java/org/geysermc/connector/utils/LanguageUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java index 6d353adbe..6172cc9e8 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java @@ -75,8 +75,8 @@ public class LanguageUtils { // Insert the locale into the mappings LOCALE_MAPPINGS.put(locale, localeProp); } else { - if (!locale.toLowerCase().equals(getDefaultLocale().toLowerCase())) { // The default locale was invalid fallback to en_us - GeyserConnector.getInstance().getLogger().warning(getLocaleStringLog("geyser.language.missing_file", locale)); + if (GeyserConnector.getInstance() != null && GeyserConnector.getInstance().getLogger() != null) { + GeyserConnector.getInstance().getLogger().warning("Missing locale: " + locale); } } } From afcf1e3acdad3801d08b121408819f0719030791 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Sun, 5 Jul 2020 21:38:24 -0400 Subject: [PATCH 091/104] Change versioning to match supported Bedrock version; add versioning command (#730) * Change versioning to match supported Bedrock version Line up Geyser's versioning to match with the highest/currently supported Bedrock version for future tracking of older Geyser versions. * Add version command * Fix DEV check for version command * Remove SNAPSHOT * Update languages submodule Co-authored-by: rtm516 --- bootstrap/bungeecord/pom.xml | 4 +- bootstrap/pom.xml | 2 +- bootstrap/spigot/pom.xml | 4 +- bootstrap/sponge/pom.xml | 4 +- bootstrap/standalone/pom.xml | 4 +- bootstrap/velocity/pom.xml | 4 +- common/pom.xml | 2 +- connector/pom.xml | 4 +- .../connector/command/CommandManager.java | 1 + .../command/defaults/VersionCommand.java | 76 +++++++++++++++++++ connector/src/main/resources/languages | 2 +- 11 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml index 875991fa0..565264f0f 100644 --- a/bootstrap/bungeecord/pom.xml +++ b/bootstrap/bungeecord/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.0-SNAPSHOT + 1.0.0 ../ bootstrap-bungeecord @@ -14,7 +14,7 @@ org.geysermc connector - 1.0-SNAPSHOT + 1.0.0 compile diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index 87302d4d8..85ede3466 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -10,7 +10,7 @@ ../ bootstrap-parent - 1.0-SNAPSHOT + 1.0.0 pom diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml index 6439eb233..e05ad7f03 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.0-SNAPSHOT + 1.0.0 ../ bootstrap-spigot @@ -14,7 +14,7 @@ org.geysermc connector - 1.0-SNAPSHOT + 1.0.0 compile diff --git a/bootstrap/sponge/pom.xml b/bootstrap/sponge/pom.xml index 4a995711a..cca3fcaae 100644 --- a/bootstrap/sponge/pom.xml +++ b/bootstrap/sponge/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.0-SNAPSHOT + 1.0.0 ../ bootstrap-sponge @@ -14,7 +14,7 @@ org.geysermc connector - 1.0-SNAPSHOT + 1.0.0 compile diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml index 60b0ba81f..468042b8f 100644 --- a/bootstrap/standalone/pom.xml +++ b/bootstrap/standalone/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.0-SNAPSHOT + 1.0.0 ../ bootstrap-standalone @@ -14,7 +14,7 @@ org.geysermc connector - 1.0-SNAPSHOT + 1.0.0 compile diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml index 78f219731..7c42ba336 100644 --- a/bootstrap/velocity/pom.xml +++ b/bootstrap/velocity/pom.xml @@ -6,7 +6,7 @@ org.geysermc bootstrap-parent - 1.0-SNAPSHOT + 1.0.0 ../ bootstrap-velocity @@ -14,7 +14,7 @@ org.geysermc connector - 1.0-SNAPSHOT + 1.0.0 compile diff --git a/common/pom.xml b/common/pom.xml index 0a47fbcaa..0df8ef4bf 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -10,7 +10,7 @@ ../ common - 1.0-SNAPSHOT + 1.0.0 com.google.code.gson diff --git a/connector/pom.xml b/connector/pom.xml index 70ad0e26d..b2bc15263 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -10,12 +10,12 @@ ../ connector - 1.0-SNAPSHOT + 1.0.0 org.geysermc common - 1.0-SNAPSHOT + 1.0.0 compile 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 eb75a2df4..afa75503e 100644 --- a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java +++ b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java @@ -51,6 +51,7 @@ public abstract class CommandManager { registerCommand(new StopCommand(connector, "stop", LanguageUtils.getLocaleStringLog("geyser.commands.stop.desc"), "geyser.command.stop")); registerCommand(new OffhandCommand(connector, "offhand", LanguageUtils.getLocaleStringLog("geyser.commands.offhand.desc"), "geyser.command.offhand")); registerCommand(new DumpCommand(connector, "dump", LanguageUtils.getLocaleStringLog("geyser.commands.dump.desc"), "geyser.command.dump")); + registerCommand(new VersionCommand(connector, "version", LanguageUtils.getLocaleStringLog("geyser.commands.version.desc"), "geyser.command.version")); } public void registerCommand(GeyserCommand command) { diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java new file mode 100644 index 000000000..e29e164b3 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.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.command.defaults; + +import com.github.steveice10.mc.protocol.MinecraftConstants; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; +import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.utils.FileUtils; +import org.geysermc.connector.utils.LanguageUtils; +import org.geysermc.connector.utils.WebUtils; + +import java.util.Properties; + +public class VersionCommand extends GeyserCommand { + + public GeyserConnector connector; + + public VersionCommand(GeyserConnector connector, String name, String description, String permission) { + super(name, description, permission); + this.connector = connector; + } + + @Override + public void execute(CommandSender sender, String[] args) { + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.version", GeyserConnector.NAME, GeyserConnector.VERSION, MinecraftConstants.GAME_VERSION, GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion())); + + // Disable update checking in dev mode + //noinspection ConstantConditions - changes in production + if (!GeyserConnector.VERSION.equals("DEV")) { + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.checking")); + try { + Properties gitProp = new Properties(); + gitProp.load(FileUtils.getResource("git.properties")); + + String buildXML = WebUtils.getBody("https://ci.nukkitx.com/job/GeyserMC/job/Geyser/job/" + gitProp.getProperty("git.branch") + "/lastSuccessfulBuild/api/xml?xpath=//master/buildNumber"); + if (buildXML.startsWith("")) { + int latestBuildNum = Integer.parseInt(buildXML.replaceAll("<(\\\\)?buildNumber>", "")); + int buildNum = Integer.parseInt(gitProp.getProperty("git.build.number")); + if (latestBuildNum != buildNum) { + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.no_updates")); + } else { + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.outdated", (latestBuildNum - buildNum), "http://ci.geysermc.org/")); + } + } else { + throw new AssertionError(); + } + } catch (Exception e) { + sender.sendMessage("Failed to check for updates"); + } + } + } +} diff --git a/connector/src/main/resources/languages b/connector/src/main/resources/languages index 08be7fdd7..c199011b6 160000 --- a/connector/src/main/resources/languages +++ b/connector/src/main/resources/languages @@ -1 +1 @@ -Subproject commit 08be7fdd7bd3c1ade46fa8968c04d3d67bb0d378 +Subproject commit c199011b6c131b195e94d4785abbc3dd73ca19cd From ad751ecb5b55e2a43f5e77c36f272354f3e3aac7 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 6 Jul 2020 11:18:17 +0100 Subject: [PATCH 092/104] Fix ping passthrough throwing errors on unknown properties (Fixes #903) --- .../java/org/geysermc/connector/common/ping/GeyserPingInfo.java | 1 + 1 file changed, 1 insertion(+) diff --git a/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java b/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java index eff1fe49d..246a3c6e3 100644 --- a/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java +++ b/connector/src/main/java/org/geysermc/connector/common/ping/GeyserPingInfo.java @@ -36,6 +36,7 @@ import java.util.ArrayList; import java.util.Collection; @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class GeyserPingInfo { private String description; From b0e291edc4c62e303cba7002ea47ffde8550d4a1 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 6 Jul 2020 12:18:14 +0100 Subject: [PATCH 093/104] Fix version checking and add failed language string --- .../connector/command/defaults/VersionCommand.java | 14 +++++++++----- connector/src/main/resources/languages | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java index e29e164b3..7dd59712a 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java @@ -33,6 +33,9 @@ import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.WebUtils; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Properties; public class VersionCommand extends GeyserCommand { @@ -56,9 +59,9 @@ public class VersionCommand extends GeyserCommand { Properties gitProp = new Properties(); gitProp.load(FileUtils.getResource("git.properties")); - String buildXML = WebUtils.getBody("https://ci.nukkitx.com/job/GeyserMC/job/Geyser/job/" + gitProp.getProperty("git.branch") + "/lastSuccessfulBuild/api/xml?xpath=//master/buildNumber"); + String buildXML = WebUtils.getBody("https://ci.nukkitx.com/job/GeyserMC/job/Geyser/job/" + URLEncoder.encode(gitProp.getProperty("git.branch"), StandardCharsets.UTF_8.toString()) + "/lastSuccessfulBuild/api/xml?xpath=//buildNumber"); if (buildXML.startsWith("")) { - int latestBuildNum = Integer.parseInt(buildXML.replaceAll("<(\\\\)?buildNumber>", "")); + int latestBuildNum = Integer.parseInt(buildXML.replaceAll("<(\\\\)?(/)?buildNumber>", "").trim()); int buildNum = Integer.parseInt(gitProp.getProperty("git.build.number")); if (latestBuildNum != buildNum) { sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.no_updates")); @@ -66,10 +69,11 @@ public class VersionCommand extends GeyserCommand { sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.outdated", (latestBuildNum - buildNum), "http://ci.geysermc.org/")); } } else { - throw new AssertionError(); + throw new AssertionError("buildNumber missing"); } - } catch (Exception e) { - sender.sendMessage("Failed to check for updates"); + } catch (IOException | AssertionError | NumberFormatException e) { + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.version.failed"), e); + sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.failed")); } } } diff --git a/connector/src/main/resources/languages b/connector/src/main/resources/languages index c199011b6..fc8f930a2 160000 --- a/connector/src/main/resources/languages +++ b/connector/src/main/resources/languages @@ -1 +1 @@ -Subproject commit c199011b6c131b195e94d4785abbc3dd73ca19cd +Subproject commit fc8f930a238a375c7e3be6e5c7ea1720b61d0cca From 66570a623d2d61674724e0e7e72fef9ce0fbe02f Mon Sep 17 00:00:00 2001 From: theminecoder Date: Mon, 6 Jul 2020 23:10:36 +1000 Subject: [PATCH 094/104] Fix scoreboards bleeding into other servers (#902) --- .../network/translators/java/JavaJoinGameTranslator.java | 3 +++ 1 file changed, 3 insertions(+) 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 5c94d6afb..01f6b0b92 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 @@ -31,6 +31,7 @@ import com.github.steveice10.mc.protocol.data.game.setting.SkinPart; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientSettingsPacket; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.session.cache.ScoreboardCache; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.DimensionUtils; @@ -58,6 +59,8 @@ public class JavaJoinGameTranslator extends PacketTranslator Date: Mon, 6 Jul 2020 14:26:00 +0100 Subject: [PATCH 095/104] Update MinecraftCapes endpoints (#907) Updates the mccapes endpoints with the new domain. --- .../main/java/org/geysermc/connector/utils/SkinProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java index aea9ba189..aa01ada81 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java +++ b/connector/src/main/java/org/geysermc/connector/utils/SkinProvider.java @@ -537,7 +537,7 @@ public class SkinProvider { OPTIFINE("http://s.optifine.net/capes/%s.png", CapeUrlType.USERNAME), LABYMOD("https://www.labymod.net/page/php/getCapeTexture.php?uuid=%s", CapeUrlType.UUID_DASHED), FIVEZIG("https://textures.5zigreborn.eu/profile/%s", CapeUrlType.UUID_DASHED), - MINECRAFTCAPES("https://www.minecraftcapes.co.uk/getCape/%s", CapeUrlType.UUID); + MINECRAFTCAPES("https://minecraftcapes.net/profile/%s/cape", CapeUrlType.UUID); public static final CapeProvider[] VALUES = Arrays.copyOfRange(values(), 1, 5); private String url; @@ -573,7 +573,7 @@ public class SkinProvider { @NoArgsConstructor @Getter public enum EarsProvider { - MINECRAFTCAPES("https://www.minecraftcapes.co.uk/getEars/%s", CapeUrlType.UUID); + MINECRAFTCAPES("https://minecraftcapes.net/profile/%s/ears", CapeUrlType.UUID); public static final EarsProvider[] VALUES = values(); private String url; From 7e51040a8e0081854d852ceda709e91169fd82b6 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 6 Jul 2020 14:41:55 +0100 Subject: [PATCH 096/104] Fix fallback locale not loading --- .../main/java/org/geysermc/connector/utils/LanguageUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java b/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java index 6172cc9e8..9dabc3871 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/LanguageUtils.java @@ -173,6 +173,7 @@ public class LanguageUtils { locale = formatLocale(Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry()); if (!isValidLanguage(locale)) { // Bedrock does not support this language locale = "en_US"; + loadGeyserLocale(locale); } if (GeyserConnector.getInstance() != null && GeyserConnector.getInstance().getConfig() != null && (GeyserConnector.getInstance().getConfig().getDefaultLocale() == null || !isValid)) { // Means we should use the system locale for sure From 82c6276794b3f3b26e9cbc3b5e5f9688ed097d13 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 6 Jul 2020 15:19:48 -0400 Subject: [PATCH 097/104] Move back to using the main repository for MCProtocolLib --- connector/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index b2bc15263..b9bf67cef 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -103,9 +103,9 @@ compile - com.github.GeyserMC - MCProtocolLib - feature~1.16-1.12.1-1-g10bb8e2-319 + com.github.steveice10 + mcprotocollib + 7545884a2d compile From 545dfa38f0db781fc6199ee9a8efcccb1815b1f4 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 6 Jul 2020 16:22:07 -0400 Subject: [PATCH 098/104] JavaUpdateTileEntityTranslator improvements - Remove the use of deprecated functions - Check for empty NBT (fixes errors on CubeCraft) --- .../java/world/JavaUpdateTileEntityTranslator.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) 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 822be8c89..ae4ed7792 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 @@ -40,12 +40,17 @@ public class JavaUpdateTileEntityTranslator extends PacketTranslator Date: Mon, 6 Jul 2020 23:36:04 +0100 Subject: [PATCH 099/104] Fix RGB colors on signs causing chunk issues, fix items names not being displayed correctly --- connector/pom.xml | 12 +++++----- .../translators/item/ItemTranslator.java | 23 +++++++++---------- .../translators/nbt/BasicItemTranslator.java | 12 +++++----- .../connector/utils/MessageUtils.java | 10 ++++---- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index b9bf67cef..3fdd5f37a 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -127,20 +127,20 @@ net.kyori - text-api - 3.0.3 + adventure-api + 4.0.0-SNAPSHOT compile net.kyori - text-serializer-gson - 3.0.3 + adventure-text-serializer-gson + 4.0.0-SNAPSHOT compile net.kyori - text-serializer-legacy - 3.0.3 + adventure-text-serializer-legacy + 4.0.0-SNAPSHOT compile diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java index 7811d9c0a..fde799fe4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemTranslator.java @@ -28,17 +28,7 @@ package org.geysermc.connector.network.translators.item; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.message.MessageSerializer; -import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag; -import com.github.steveice10.opennbt.tag.builtin.ByteTag; -import com.github.steveice10.opennbt.tag.builtin.DoubleTag; -import com.github.steveice10.opennbt.tag.builtin.FloatTag; -import com.github.steveice10.opennbt.tag.builtin.IntArrayTag; -import com.github.steveice10.opennbt.tag.builtin.IntTag; -import com.github.steveice10.opennbt.tag.builtin.ListTag; -import com.github.steveice10.opennbt.tag.builtin.LongArrayTag; -import com.github.steveice10.opennbt.tag.builtin.LongTag; -import com.github.steveice10.opennbt.tag.builtin.ShortTag; -import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.github.steveice10.opennbt.tag.builtin.*; import com.nukkitx.nbt.NbtList; import com.nukkitx.nbt.NbtMap; import com.nukkitx.nbt.NbtMapBuilder; @@ -46,11 +36,14 @@ import com.nukkitx.nbt.NbtType; import com.nukkitx.protocol.bedrock.data.inventory.ItemData; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.ItemRemapper; -import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.LanguageUtils; +import org.geysermc.connector.utils.MessageUtils; import org.reflections.Reflections; import java.util.*; @@ -167,6 +160,12 @@ public abstract class ItemTranslator { if (display != null) { String name = display.getString("Name"); + // If its not a message convert it + if (!MessageUtils.isMessage(name)) { + TextComponent component = LegacyComponentSerializer.legacy().deserialize(name); + name = GsonComponentSerializer.gson().serialize(component); + } + // Check if its a message to translate if (MessageUtils.isMessage(name)) { // Get the translated name diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java index 776cec729..34c7f43dc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/translators/nbt/BasicItemTranslator.java @@ -29,13 +29,13 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; -import net.kyori.text.Component; -import net.kyori.text.TextComponent; -import net.kyori.text.serializer.gson.GsonComponentSerializer; -import net.kyori.text.serializer.legacy.LegacyComponentSerializer; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.connector.network.translators.ItemRemapper; -import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.item.NbtItemStackTranslator; import org.geysermc.connector.utils.MessageUtils; import java.util.ArrayList; @@ -101,7 +101,7 @@ public class BasicItemTranslator extends NbtItemStackTranslator { message = message.replaceFirst("§r", ""); } Component component = TextComponent.of(message); - return GsonComponentSerializer.INSTANCE.serialize(component); + return GsonComponentSerializer.gson().serialize(component); } private String toBedrockMessage(StringTag tag) { 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 3a35782d4..bf1962246 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/MessageUtils.java @@ -35,9 +35,9 @@ import com.github.steveice10.mc.protocol.data.message.style.ChatFormat; import com.github.steveice10.mc.protocol.data.message.style.MessageStyle; 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 net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.connector.network.session.GeyserSession; import java.util.*; @@ -263,12 +263,12 @@ public class MessageUtils { } public static Component phraseJavaMessage(String message) { - return GsonComponentSerializer.INSTANCE.deserialize(message); + return GsonComponentSerializer.gson().deserialize(message); } public static String getJavaMessage(String message) { Component component = LegacyComponentSerializer.legacy().deserialize(message); - return GsonComponentSerializer.INSTANCE.serialize(component); + return GsonComponentSerializer.gson().serialize(component); } /** From c454e443df0fc2829732d8b44d425619be79e44a Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 6 Jul 2020 23:36:31 +0100 Subject: [PATCH 100/104] Fix maps with negative IDs causing out of bounds errors --- .../bedrock/BedrockMapInfoRequestTranslator.java | 8 ++++++-- .../translators/java/world/JavaMapDataTranslator.java | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java index 3c7efa18b..247021f10 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java @@ -39,12 +39,16 @@ public class BedrockMapInfoRequestTranslator extends PacketTranslator { - session.sendUpstreamPacket(session.getStoredMaps().get(mapID)); - session.getStoredMaps().remove(mapID); + session.sendUpstreamPacket(session.getStoredMaps().get(finalMapID)); + session.getStoredMaps().remove(finalMapID); }, 100, TimeUnit.MILLISECONDS); } } 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 2aee7bc02..12ef1053b 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 @@ -85,7 +85,11 @@ public class JavaMapDataTranslator extends PacketTranslator // 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); + long uniqueMapId = mapItemDataPacket.getUniqueMapId(); + if (uniqueMapId <= -1l) { + uniqueMapId = 0l; + } + session.getStoredMaps().put(uniqueMapId, mapItemDataPacket); } // Send anyway just in case From 02905c2a355d53df805d7b8d52b2f0b92dd08912 Mon Sep 17 00:00:00 2001 From: rtm516 Date: Mon, 6 Jul 2020 23:41:54 +0100 Subject: [PATCH 101/104] Add the adventure-api maven repo --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 3e119eb11..acfdc3d63 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,10 @@ viaversion-repo https://repo.viaversion.com + + sonatype + https://oss.sonatype.org/content/repositories/snapshots/ + From 699402e635919fdd1680cf7361cd4042264c382c Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Mon, 6 Jul 2020 15:52:38 -0800 Subject: [PATCH 102/104] Fix bug with maps --- .../connector/network/session/GeyserSession.java | 3 ++- .../bedrock/BedrockMapInfoRequestTranslator.java | 11 +++++------ .../translators/java/world/JavaMapDataTranslator.java | 6 +----- 3 files changed, 8 insertions(+), 12 deletions(-) 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 666820cc2..6b51c8921 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 @@ -48,6 +48,7 @@ import com.nukkitx.protocol.bedrock.BedrockServerSession; 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.Long2ObjectMaps; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2LongMap; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; @@ -107,7 +108,7 @@ public class GeyserSession implements CommandSender { private TeleportCache teleportCache; @Getter - private final Long2ObjectMap storedMaps = new Long2ObjectOpenHashMap<>(); + private final Long2ObjectMap storedMaps = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>()); /** * A map of Vector3i positions to Java entity IDs. diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java index 247021f10..11dfe46e0 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockMapInfoRequestTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.connector.network.translators.bedrock; +import com.nukkitx.protocol.bedrock.packet.ClientboundMapItemDataPacket; import com.nukkitx.protocol.bedrock.packet.MapInfoRequestPacket; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; @@ -39,16 +40,14 @@ public class BedrockMapInfoRequestTranslator extends PacketTranslator { - session.sendUpstreamPacket(session.getStoredMaps().get(finalMapID)); - session.getStoredMaps().remove(finalMapID); + ClientboundMapItemDataPacket mapPacket = session.getStoredMaps().remove(mapID); + if (mapPacket != null) { + session.sendUpstreamPacket(mapPacket); + } }, 100, TimeUnit.MILLISECONDS); } } 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 12ef1053b..2aee7bc02 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 @@ -85,11 +85,7 @@ public class JavaMapDataTranslator extends PacketTranslator // Store the map to send when the client requests it, as bedrock expects the data after a MapInfoRequestPacket if (shouldStore) { - long uniqueMapId = mapItemDataPacket.getUniqueMapId(); - if (uniqueMapId <= -1l) { - uniqueMapId = 0l; - } - session.getStoredMaps().put(uniqueMapId, mapItemDataPacket); + session.getStoredMaps().put(mapItemDataPacket.getUniqueMapId(), mapItemDataPacket); } // Send anyway just in case From 24f9651cc6e6279e3a2b709c0cf6766c2032fb4a Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Mon, 6 Jul 2020 20:11:34 -0500 Subject: [PATCH 103/104] Convert map of players to list (may address #833) --- .../spigot/world/GeyserSpigotBlockPlaceListener.java | 2 +- .../platform/standalone/gui/GeyserStandaloneGUI.java | 7 +++---- .../java/org/geysermc/connector/GeyserConnector.java | 12 ++++++------ .../connector/command/defaults/ListCommand.java | 4 ++-- .../connector/command/defaults/OffhandCommand.java | 2 +- .../connector/command/defaults/ReloadCommand.java | 2 +- .../geysermc/connector/entity/FishingHookEntity.java | 2 +- .../network/ConnectorServerEventHandler.java | 9 --------- .../connector/network/session/GeyserSession.java | 9 ++++++++- 9 files changed, 23 insertions(+), 26 deletions(-) diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java index f17a97e37..4fe93d459 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/GeyserSpigotBlockPlaceListener.java @@ -47,7 +47,7 @@ public class GeyserSpigotBlockPlaceListener implements Listener { @EventHandler public void place(final BlockPlaceEvent event) { - for (GeyserSession session : connector.getPlayers().values()) { + for (GeyserSession session : connector.getPlayers()) { if (event.getPlayer() == Bukkit.getPlayer(session.getPlayerEntity().getUsername())) { LevelSoundEventPacket placeBlockSoundPacket = new LevelSoundEventPacket(); placeBlockSoundPacket.setSound(SoundEvent.PLACE); diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java index 9be0e1c6a..0c0ec1127 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java @@ -42,7 +42,6 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import java.net.InetSocketAddress; import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -292,10 +291,10 @@ public class GeyserStandaloneGUI { // Update player table playerTableModel.getDataVector().removeAllElements(); - for (Map.Entry player : GeyserConnector.getInstance().getPlayers().entrySet()) { + for (GeyserSession player : GeyserConnector.getInstance().getPlayers()) { Vector row = new Vector(); - row.add(player.getKey().getHostName()); - row.add(player.getValue().getPlayerEntity().getUsername()); + row.add(player.getSocketAddress().getHostName()); + row.add(player.getPlayerEntity().getUsername()); playerTableModel.addRow(row); } diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 298f5bc82..675c2b9a2 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -59,8 +59,8 @@ import org.geysermc.connector.utils.LocaleUtils; import java.net.InetSocketAddress; import java.text.DecimalFormat; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -76,7 +76,7 @@ public class GeyserConnector { public static final String NAME = "Geyser"; public static final String VERSION = "DEV"; // A fallback for running in IDEs - private final Map players = new HashMap<>(); + private final List players = new ArrayList<>(); private static GeyserConnector instance; @@ -185,7 +185,7 @@ public class GeyserConnector { if (players.size() >= 1) { bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.kick.log", players.size())); - for (GeyserSession playerSession : players.values()) { + for (GeyserSession playerSession : players) { playerSession.disconnect(LanguageUtils.getPlayerLocaleString("geyser.core.shutdown.kick.message", playerSession.getClientData().getLanguageCode())); } @@ -227,11 +227,11 @@ public class GeyserConnector { } public void addPlayer(GeyserSession player) { - players.put(player.getSocketAddress(), player); + players.add(player); } public void removePlayer(GeyserSession player) { - players.remove(player.getSocketAddress()); + players.remove(player); } public static GeyserConnector start(PlatformType platformType, GeyserBootstrap bootstrap) { 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 0de73a5d1..3c78c5540 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 @@ -47,9 +47,9 @@ public class ListCommand extends GeyserCommand { public void execute(CommandSender sender, String[] args) { String message = ""; if (sender instanceof GeyserSession) { - message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", ((GeyserSession) sender).getClientData().getLanguageCode(), connector.getPlayers().size(), connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" "))); + message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", ((GeyserSession) sender).getClientData().getLanguageCode(), connector.getPlayers().size(), connector.getPlayers().stream().map(GeyserSession::getName).collect(Collectors.joining(" "))); } else { - message = LanguageUtils.getLocaleStringLog("geyser.commands.list.message", connector.getPlayers().size(), connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" "))); + message = LanguageUtils.getLocaleStringLog("geyser.commands.list.message", connector.getPlayers().size(), connector.getPlayers().stream().map(GeyserSession::getName).collect(Collectors.joining(" "))); } sender.sendMessage(message); diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java index a49506b0f..b1b601328 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java @@ -59,7 +59,7 @@ public class OffhandCommand extends GeyserCommand { return; } // Needed for Bukkit - sender is not an instance of GeyserSession - for (GeyserSession session : connector.getPlayers().values()) { + for (GeyserSession session : connector.getPlayers()) { if (sender.getName().equals(session.getPlayerEntity().getUsername())) { ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0), BlockFace.DOWN); 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 d8bf8583b..9c24fa2be 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 @@ -56,7 +56,7 @@ public class ReloadCommand extends GeyserCommand { sender.sendMessage(message); - for (GeyserSession session : connector.getPlayers().values()) { + for (GeyserSession session : connector.getPlayers()) { session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.commands.reload.kick", session.getClientData().getLanguageCode())); } connector.reload(); 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 cc7d749d9..4d0eb202f 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FishingHookEntity.java @@ -37,7 +37,7 @@ public class FishingHookEntity extends Entity { public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, ProjectileData data) { super(entityId, geyserId, entityType, position, motion, rotation); - for (GeyserSession session : GeyserConnector.getInstance().getPlayers().values()) { + for (GeyserSession session : GeyserConnector.getInstance().getPlayers()) { Entity entity = session.getEntityCache().getEntityByJavaId(data.getOwnerId()); if (entity == null && session.getPlayerEntity().getEntityId() == data.getOwnerId()) { entity = session.getPlayerEntity(); 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 ad5cb42aa..6ca9063c2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -108,15 +108,6 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { public void onSessionCreation(BedrockServerSession bedrockServerSession) { bedrockServerSession.setLogging(true); bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(connector, new GeyserSession(connector, bedrockServerSession))); - bedrockServerSession.addDisconnectHandler(disconnectReason -> { - connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.disconnect", bedrockServerSession.getAddress().getAddress(), disconnectReason)); - - GeyserSession player = connector.getPlayers().get(bedrockServerSession.getAddress()); - if (player != null) { - player.disconnect(disconnectReason.name()); - connector.removePlayer(player); - } - }); bedrockServerSession.setPacketCodec(GeyserConnector.BEDROCK_PACKET_CODEC); } 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 6b51c8921..0aa0ceaae 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 @@ -210,6 +210,13 @@ public class GeyserSession implements CommandSender { this.loggedIn = false; this.inventoryCache.getInventories().put(0, inventory); + + bedrockServerSession.addDisconnectHandler(disconnectReason -> { + connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.network.disconnect", bedrockServerSession.getAddress().getAddress(), disconnectReason)); + + disconnect(disconnectReason.name()); + connector.removePlayer(this); + }); } public void connect(RemoteServer remoteServer) { @@ -428,7 +435,7 @@ public class GeyserSession implements CommandSender { downstream.getSession().disconnect(reason); } if (upstream != null && !upstream.isClosed()) { - connector.getPlayers().remove(this.upstream.getAddress()); + connector.getPlayers().remove(this); upstream.disconnect(reason); } } From f68632f43349816528efc8719e01817ff4d518fc Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 6 Jul 2020 21:38:10 -0400 Subject: [PATCH 104/104] Block-related updates - Fix block breaking animation - Fix block breaking particles - Don't initialize Geyser's chunk cache if using Spigot --- .../connector/network/session/cache/ChunkCache.java | 11 +++++++---- .../translators/bedrock/BedrockActionTranslator.java | 2 +- .../BedrockInventoryTransactionTranslator.java | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) 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 a7b0c9665..9601a2981 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 @@ -29,6 +29,7 @@ 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 lombok.Getter; +import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.world.chunk.ChunkPosition; @@ -38,15 +39,17 @@ import java.util.Map; public class ChunkCache { - private boolean cache; - private final GeyserSession session; + private final boolean cache; @Getter private Map chunks = new HashMap<>(); public ChunkCache(GeyserSession session) { - this.session = session; - this.cache = session.getConnector().getConfig().isCacheChunks(); + if (session.getConnector().getWorldManager().getClass() == GeyserBootstrap.DEFAULT_CHUNK_MANAGER.getClass()) { + this.cache = session.getConnector().getConfig().isCacheChunks(); + } else { + this.cache = false; // To prevent Spigot from initializing + } } public void addToCache(Column chunk) { 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 7d8772fbd..dfd49f2ee 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 @@ -112,7 +112,7 @@ public class BedrockActionTranslator extends PacketTranslator