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 6d12b673..87302d4d 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 1f831d67..d9ce9f8d 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 df98b408..ffa9c7b3 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 08822568..252d6bbe 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 b6da66c1..dbc66039 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 812467be..6651adab 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 5f0e967a..b4e0158c 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 d2603f7c..b956a0d8 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 b826ab1f..2fbec156 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 05e371e5..55475a30 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 76d1564e..f17a97e3 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 fbdf2a47..4f7e54f7 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 89c90789..fee71ab1 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 e09b9248..9ff20a82 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 b4e0158c..cc054965 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 fa6f57fd..29b2fce9 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 7f941da6..aa80bf05 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 91cf6f3d..34798931 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 d5ae391c..0b7b23fe 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 644181ab..7232fb55 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 d2b87af1..24ef2faa 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 ac7ab06c..a7b0c966 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 04fe8dbf..297db702 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 d6f446f0..cbae263e 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 3e2c0a95..15af7a70 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 5f0b1cc0..31f36388 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 5b325eba..9efda13c 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 c87938dd..93356e7c 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 cd31636c..e932d264 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 f5599832..d1afd19e 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 d1068277..401bb343 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 4cd2eaa9..17e533bc 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 c4748c82..69ecefdd 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 168015f6..ca5a4f52 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 2dffce24..bf8fcb13 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 4df7292a..0db306aa 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 373b963e..b92b604e 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 6c170462..e3fb9ea0 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 9393f7bb..f868ff08 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 100dbddd..548a1ec8 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 f86173e2..9cab8605 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 49f81e3f..abff44e5 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 6ad206b3..0e9fe503 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 f301d2b5..d69f9f71 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 1962f62e..be8080d8 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 53ce6811..df340971 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 e3fb9ea0..d0388f33 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 6a323d54..e770e91a 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 d79cdab8..9e32f0a9 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 2c44e4fd..64572f36 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 fbdf2a47..55c79165 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 d69f9f71..242d4ba4 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 e770e91a..54978d5f 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 9e32f0a9..221a9917 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 a67cc940..8f78a9b2 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 3a13777b..c8e26640 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 55c79165..82f1a94f 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 34798931..0f1e6081 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 0b7b23fe..aa38441c 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 2061b895..1d692e2a 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 3acc17c3..77d7f5c9 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 24ef2faa..a1caf278 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 75a1547f..6ee70cb3 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 bdf900d8..cdb14108 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 8d8c0aff..9b44cdd3 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 5a3ebaba..2aee7bc0 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 63512047..d4c269b0 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 6c8d9f94..b78a28ff 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 221a9917..6ab71243 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 77d7f5c9..ea99c470 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 ae2ab530..fd05131a 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 c50686a0..00000000 --- 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 0f1e6081..448e2bf7 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 d201656a..338cee5f 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 fa089707..f174747b 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 79e67f34..21861589 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 a59cd08f..c067416d 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 b774af98..dda4577d 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 727df90c..4b665683 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 aa38441c..4d4d097f 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 bfd3e1ca..c830d259 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 59e1d408..54757b71 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 1db4f757..e1a8e08a 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 1b648f7c..47259e31 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 29ade193..8f0d97b0 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 3680945c..58edf29d 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 f5aa4a54..3d1a1456 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 a67c0be5..72b5ee82 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 00cfc8b5..d509b41f 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 594f139a..c567aa07 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 6be138c0..56341b3b 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 629c9e51..d2addbfb 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 7c2442b0..acc17610 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 de5fa1b5..9c3e2084 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 b90983f7..2175efcd 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 47faad36..07496093 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 2467dfe0..808eb3cb 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 26106f0a..2ee22de7 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 69afd975..b0692eab 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 537a1251..c46f00fe 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 a277f8ee..88c30cbf 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 1c5dc975..36a67dbb 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 f22815c6..7e555122 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 fd9fd999..0a7c83e7 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 6011d513..2b09ca91 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 d5503dc0..407708a5 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 6bc64bfd..0b61713a 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 e2b1b979..464377ef 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 a8866d7e..eadc3db0 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 3773011a..48586c78 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 df354357..7343f5e8 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 27f4b83c..da3ff349 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 d4d7b726..ddac4a63 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 b9505509..f0132673 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 de9bcb4e..067a360c 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 e02b3e7b..a867517a 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 2d3e0b1d..2e8ab816 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 118262dc..d0fb84a1 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 895f8cc1..a2fa1c49 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 16836976..75fec18f 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 9b5c3822..3c3a76bd 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 fedd7980..76b1ba2c 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 394be544..aa2b4e02 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 7232fb55..b1c1fa11 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 b9dc9e66..aa22d8d6 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 821faa85..aa9ce4ca 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 bca9e689..8728547f 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 301145e6..f0ad6f05 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 005d0db3..8b864525 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 2ca212ff..218a2ca0 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 91b3ebd4..c41c64c7 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 a1caf278..03d12428 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 267f3cb1..68e8519c 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 64572f36..7d8772fb 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 e5be2fec..a467e218 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 ba7f8cc7..c8e9ed18 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 5c6de0e8..1f148e02 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 174cfbc1..6e729c39 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 97594907..37621647 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 3f7636b9..37c84e28 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 28986e58..db26c469 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 b08b5084..45860dcd 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 209df074..c1ed472c 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 950e2eeb..ce02b875 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 6ec8d481..7437a26e 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 ec6175c3..51f33ac4 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 adbbdbac..26d88990 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 88157df0..57601a9e 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 65b40e61..dd9d14eb 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 be8080d8..6f11e94a 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 f4f545ff..8a1a973b 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 2fdde31d..7cb88d70 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 053630d5..16d910b8 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 b0637722..ab80cce1 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 a5814111..0d80f4af 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 8ecf4e30..214413ab 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 6e53df27..2ab499b0 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 b8675dbf..98089ff2 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 eeff588e..9ed11a23 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 ded47723..66db00ce 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 48e4c4c8..e93388c4 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 338cee5f..b584c87a 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 b1c1fa11..914b2085 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 6ee70cb3..e741ca35 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 448e2bf7..7bb00ecf 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 b584c87a..bdd7e74c 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 dd66db32..875991fa 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 6ad7a637..4564d11c 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 c9abbe3e..4a995711 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 fb06767e..78f21973 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 7bb00ecf..eaa2801e 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 dd8c336d..b304ed77 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 16d910b8..8f524336 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 47259e31..cc7d749d 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 acc17610..4a9007ab 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 d0fb84a1..aa578acb 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 4564d11c..6439eb23 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 8f78a9b2..fa672129 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 9c55217f..a10668ce 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 aa80bf05..9cb0726c 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 0d80f4af..288389fa 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 b78a28ff..74db16bb 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 fa672129..469c4415 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 00000000..9e3c14e6 --- /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 ab80cce1..c29632de 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 bdbb1033..96d4c836 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 00000000..18bb8166 --- /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 ea99c470..1db7a0e4 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 1db7a0e4..4ec3471c 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 dd9d14eb..db5bc1b3 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 a10668ce..7d952182 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 df340971..4787d698 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 6ab71243..6e995b4b 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 5d4f4368..00905f6d 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 c963f6fe..afcb321a 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 db26c469..41489ac2 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 c1ed472c..426627bf 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 66db00ce..0e5c13fc 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 8045b219..9765ff55 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 87f85187..0614b364 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 e213fe6c..78752591 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 03d12428..353d944e 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 00000000..54701116 --- /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 1cf519c0..ec267924 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 00000000..01d513fa --- /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 fd05131a..7fc49348 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 00000000..e8f0feae --- /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 c5f13b58..abf27749 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 0fca3503..c0afd884 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 00000000..906a0414 --- /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 5abf3c23..1116fb8c 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 00000000..9772a8e3 --- /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 eaa2801e..9526c840 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 8683f80c..f089350f 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 8b1d0bc7..217a9df1 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 00000000..4dbb3bb3 --- /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 576e5ed0..0e203231 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 00000000..dbcfba81 --- /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 00000000..6d4b83db --- /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 0a5a2278..09c78da9 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 50ab76d0..7a1a0215 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 b8f8749b..5cf34473 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 0090e64a..207825e8 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 9526c840..76e02e2a 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 469c4415..22f98579 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 eabbcc69..999b29ea 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 c7f8f276..ab400052 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 ec267924..ac718cba 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 dbc66039..15826d33 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 6651adab..07999d87 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 7fc49348..de2b7186 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 11b9583f..1c9605d0 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 31b6dc7f..99e8ed2f 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 abf27749..4214255e 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 91cb59b0..8f857b66 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 c0afd884..3fb561a1 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 7102d206..ae7f1871 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 03c49705..00ff14de 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 73eaddf0..b5c79cc2 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 01be949b..934c5774 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 1116fb8c..f00119ca 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 940c5224..4632f440 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 8edbc4d5..00000000 --- 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 29b2fce9..00000000 --- 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 bdd7e74c..20a77126 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 4dbb3bb3..617c9d43 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 6acb7822..a5942ee6 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 21fa4253..99845ee9 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 c38a0c23..2ddd61ed 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 2222cdef..636058a0 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 00000000..f15e3ff5 --- /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 8868b063..1397f88c 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 00000000..ee68b6d7 --- /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 75da4e6b..906bd786 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 40ef6da6..69b24ea1 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 9772a8e3..3fac2e08 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 0e203231..867de9ad 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 dbcfba81..04495b49 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 abff44e5..11ff9a02 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 0e9fe503..ba654c75 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 5a40b246..79dcf138 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 353d944e..101726f1 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 1f31367c..d05a667d 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 d70b2142..0abf8150 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 50705ae2..9e81ce59 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 54978d5f..1c4d26d0 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 7bc842df..35c8058e 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 0e5c13fc..627c25dc 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 e93388c4..ae17ed20 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 9765ff55..eea92a95 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 101726f1..b72a4f9b 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 6e729c39..4b4a1246 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 37621647..7d06aed1 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 00000000..f347ccae --- /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 22f98579..a1b44a95 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 4787d698..d222d729 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 6e995b4b..96775f24 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 76e02e2a..ddc62bf2 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 e0e0771d..eb4c1ddc 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 f51e35fe..d849c917 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 c29632de..15f0e496 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 b72a4f9b..1fe5dec8 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 74710d45..c5d1de25 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 7c80d104..d9d23f32 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 ddc62bf2..09171248 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 96775f24..3a35782d 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 ae17ed20..9e071247 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 18bb8166..abf6758a 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 00000000..10faebc7 --- /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 00000000..b60a3952 --- /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 4ec3471c..70c76038 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 abf6758a..e3ef9b50 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 10faebc7..78a420b8 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 b60a3952..4ea84211 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 70c76038..1acf579f 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 6f11e94a..aa75e149 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 09171248..b4816361 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 204c8f8d..fdc65607 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 9cab8605..5c426cb9 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 b4816361..70ad0e26 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 00000000..1ca46720 --- /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 db5bc1b3..2dbc945c 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 00000000..675d4255 --- /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 00000000..3bd54765 --- /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 404d7824..b4846f5c 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 b4846f5c..6bd9cc77 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 3d1a1456..32aa3435 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 0a7c83e7..9b9701f8 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 48586c78..e08f9adf 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 8eab10f5..ec3ca831 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 4d4d097f..6ae9c671 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 e3ef9b50..9d8a6220 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 00000000..01693170 --- /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 1acf579f..6bc1a1b0 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 2dbc945c..aebf1979 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 9d8a6220..bb4daf54 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 5cf34473..a22a7a8d 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 288389fa..6d033808 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 98089ff2..0af473ff 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 8b0b8201..fae289e1 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 c12cc513..6f858eb5 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 6f858eb5..880c1c9c 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 668156d5..b443f3d4 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 32aa3435..07a09fa1 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 c567aa07..fe4dc905 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 8fc377ab..14bc1507 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 0af473ff..98089ff2 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 fae289e1..8b0b8201 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 ec3ca831..87491fbf 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 770ca100..984a6baa 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 3fb561a1..762b09ba 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 ae7f1871..ffc322dd 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 00000000..1f4ff998 --- /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 00000000..f4586bbb --- /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 00000000..cc40ae53 --- /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 00000000..eb259cf7 --- /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 zcmce7=UY?V6YWVLgbqrR4uS##qJl`TLTFM1sZx~Qi-3fdLQ5C7{6IU+6eYPGKI=wTO><|GB5|UlFXecNvsN+ zF^ZO)nzDoRU3L5l~NMPl@eN2v4ia2Q$4k#o7v_~yu)8XFKC!uZ6w&Esp0%N zUaOr^;PXm^gy_m_a{WNd6?O1Q5Mgh`r?tHCpYwP7@8or725C}0MJ*#|r-aeMj`f#X zL*V~^KT#*t?}#WtYC%&jQ!5RMm&X4x{B4igx8xhA{odW(?!U6#uxrKMIyU`r%vikT zRCSgqY`;3t%V62J^!aVk#1-{$VZ>OGtJ0O$(Wi81>nUO*0RtL**d9AVX-= zLQ-DgCSgC($BZAS(Z@BP;)cK-b|?y_i<8z`-^~u?m<)0Za{>g8x(XKXA6=_U|G7O& zH#h#ldcQb&fgsp1W6l3?x^S2spr;^8+!jzZ_%aXW46a`g?*>wN#rJ@xs|o_6pM=t293DF;+e z4Zw|~kw$T|C*~j7+t?`kWMa4J z!m9NOo=E#T7k!J*E(a2YzW$s9m`9ai2waIa8uv9MtW!J*RzniBTE#ru(xy3Bt1&bl zf+lh@D1VL@(qqMeRRtz;TpG0O?^0~BlLKi^*QU)DX1D~FrMw2Q_7m(H_gj)K|2C)W z5`WE(5E4Pq=hUFJ<;6pN?(yUVGUm-knMnPmV<6ZKj&gG;?PsJF5|;S}G6L~--mI4& z80++fXxWj{t6w4pJoSaplmsS`S!`oD<2}TeG%Uw{Tlx_|FG&$E?(Va4P}&=Oxac=3 zzB2RZ5laW}y`b8!l{Ow_bGV#a>~()RpYGsmekgbYZYk0CsE-XzFva*rVaMsn@=wsb(Ewme6K}&DAzT zvWYxq5bqB_QEgy-lpH(7gEqwv?gEd%YI;3Ya5MMw6`F55#)CRHb);TU7bfII{mFm9R7#*+BDMPi)(^qg9gs_uMy#6bKUMWHF_0pz zfZHC>D37&{y@GdtzMU^)pl(eiaI&O+YB;z-IZIyLA!k2&?X|B%G4l!;3gi~ zkM67S+i`FIZ_Al46_z}r7Qj2Rg!3mUgvs*Fe~IDjc8vvG^NxLo{ZUct3o$98+U~<23uX@g#f8#xN11y%#P3x< ztTkwJ-LiT7d{A^XbSMfGjI`)VOrS|4k|Y5K>TOoorWnZ@0L*KyCXYsRHyJBFeL}>0 z5BpW7bFb))-%^S8ihzzWq@hAg@7FZ;{kPtk9iq=|a~Tl&CBm%gZcrI*>PMOvWIKP2 zOz2w<2TS6ir=3OGVlE=VYOZF7U(iYZcR2y@S6zq9UImSqoc3!FlCT}xy#Tjst|O#iKRsLbe-rS`@t5U|kQnkaSP&ZZuE%597I|k5R>6BJvF7 zh~3Rp`)jIv_7jxkY~!ZyaYi%V_5IlT?-s>VC?@Khe>ubo#R=a#v1ERKetBozm$iSa zxc{-~l(%UW*<>kBB7IBARPYW^c8B)QWdoiiZg~t#1Zqb=p};ZAaDI zpZvE5-^)Ksexkx$7(`z6#xwT= zrSp4VQGAy3y_iL`G?+Tre0Xa36Rl;+B?X9{|M;W$%=&)`md3LAFw}X%>>u6!$evf$ zX8-9I+LptlZIygk!2T_{MLUed1qSsbb-8>Xf}uHo3i4&JqZa2fHRujsKaT1RvewMWYns%3Tz?$`4*lo~CEDvx(Ql<)cP_zEGUJYA9*F>-jqT6N^Y z#jM?G5VAfFEhqHZT>vBRL0p+l#81W!P8j?3s?divo~CeD*(Z^YkNc%5DN4qh#DzI1 zt~T&sg}6Z5cG`CJFDuMZ5U7S9WCBlsD2}f8O^(>7;w3FY?8DX_JJOG-KeRJ;YxEED ztxXTzcyRh*YU(F?f98#N2NR4z_(25{68sgwzOMRLvliyfC3Cm!5D7(OgLiIJP%9WF z%M$PKb(%>@ICY?-%riwY^R;F4%wXwH-~W<=bQ5iXy@qoC#*{x2i`O&nWb!DoSe5zo z(qc~UaI@oG>sYB&kN!`TxQTjY5k=2ZK0OS>q@6@)uG8Uqpe5A*9^!@Xwtwy7Njn6d z2Ll9}pxwiyg(Icq$97i_Ao!J1I*DSk9yqb@X>pIYsQF33JRtJbPBwMsW4%W z+c}jE*{l1ld1kT130dOh!DQ!xzbNQjUC4WC`X$e_stz$<%9+xa|0Ol@zuPj7V64ky z{BQ$l=7gU-m!NQnw9FKlf|UublT;x*>8bqc2fd?@*8`ik4hs@V3^HEa)!>4nu83El z@l@ftVj38BN)=|x7tI$_`WyyqdaCG*eC?BEe%Do9H64k|@QlA-a6->PE$n8D(HAl; zuF@*_z}AgI8JE0GXVz!QyK8a(0gMvY`ufRJA2JVg?aEr&n}(VxOZk1AxI z$(x9t32`(WV&PXCY=8lLefIBM`m$2d(SX~rWOdwx%wZ11EfMmX7-MH5bt;+wsY9=y zndL>dy8PSFnV3}G&(L^vFSippt=oPhCPxA9QoRNryvlv>I(e=j4I3NGri0ji{$e=m?tHQWVRJ_-{#)|TK3qg z0)X@;$d#<^5l*L^ zP1Nk~BqID#WXnt;=gz={6j8Umo+Kn$OK9@aA;gDv zIP&9C04+_zbY&`WkG=&fGlO|WW%s}EY$kIcBOA0u;lvI$<2-bos%bSpEaZ6r#_LC2 zK`G4kN_+kiR*X1XHM44tonjoa%!PzF~G0yoZLv>+KAi*0v zjW77n8Bb}PpG$(XI1aK*VncK-Y*Dh;KzAikMEaZKn-mid^?S*o%qudU2FMmq@6QLW zX$d{uZ9HAvy4aa+r?Aw&U+A*F^pHtxkOAAk zdu`Z7#qtiz8MOD0O?QD3HN8Y2jK@qEBT$~1TBT76Gyjoam7mL&~o7B>|u;A3V*YRJ{8 zrc$H%=Yj!MhvJ`*BV6lCb|>;>oGJ{wRT-5we0ttGagu7y?K=WJjEf&bubzU%E@8=i z#WKStz97ELrbjYM{!V2#k|34O80y0-{@eOjO_SaT#>uMr^0k>9MA-CkzLOrPr5kS0 z|BG}k+?sZaVdHbT7o&=*9;9ns4^>~v*-_;qo-t-|GH9X+-bj%xI|{9AocxD%bLAkh zW>Fs}tH8J)@lZV?2O~5)c0a1UNG)fWJIB-F^3L(6iPBXDAMznKF={lfsHsa|iDMoW zNR=HbxYhEa*s}FP81YBM*<%{JK5Ny{%8pM-NDl|tx?)iwf7iH`}Fe3idQ@K~eS=e&a@I@Z{DF?BYil|+R( zGYttgQPr*d4^QRQMF~06FssX3NfUUK?%fr$3L|zgT;k>9m^I<19 z=i1+%oX+*W>AwSC>VKq^+~CgljGL$%%RhFYnx~1gWK-syGLeTL#Ldnxn92<{L&5M( zeUn&_*e#*68%R^U(NVSCRnR}eQJ;3xGmr939(x31r|-kFd>#!Lg^ek)FSxZ~RW99x zY$Oby5_HzjPE@mbA@_RK5TD_g{|%sh)V+TCwv$|iYDL1>$D|4&No;t(cRLM|=swex zOnPF*JacNewkly0$z4LxW8(TpTCZ3FCAnL9)9QX^k{f?ub+!NRrc|V?9w2^T0_7?` zy4t6QkQRF9_Jg#6uKN%%Cc5<;3s(Qi=H2$<*1+J!uCvtiRxXBERSGRX5Q8N96E2qYHz@F6Kg~iWtYEn~H&sJw5q||I6wiN?i=tvt;E|Oyc;9tN zOu$`(e*Qh3*ZhkEeC~4q9R2(-G5US?u&|YioS+DNOtbt#msOB&4t!)|vy9*o zOd;RT@}lfC3oa8!$$DZF&607az*u~;Tya9w{P4bCp@|2$aG0l zm_9uH!n6_XY@J5DayUIns*o;+5 zL&30W{|f0}_55o$nZkX+RZy!P-o#aiW*@qdy!(0j;sFho=oHM85KAOuOEIIZNt?L7 zR@Cq5rRbgeNZ|bd7xbO!YV;Q;wQ-PMaBIAMb3Da4@ivivnJvKGv$#NJ@RREK>h#1EY zxKO@55RD0W*UE7ZBCE~l@gR8JHa*XfHN1HO$9{#l(gu~ zC|;jSW4o!T^h@tcuaw*UsMH7<^y$gkeMnc%cV<{_Q_s@lgMF{@GN# z+r+wwJX~9$rw7h7*b!eAsMT}M@f$I8Tty#HY(%M4t3%TAIRD_<5qaav8@kj;w50)t z=FVK>j4uISKTUKHkItpp+AHD2ht8!9aAsUwZxAs8B;RnI=~LgORmz`22RUrky0&N5-=SDkKr@eI2dK68$bRn=1)@WG$6zP`XxP z)AUCTRa?CSmA?ZyhWF>*a3%VHsmXD}tL#7@?r*B*#OXEZLcSkc4L_yg{{~nJ2>NF> z9C{FO2}y#cq38zru6M29K8=sCQcJs+b+8iK#;ZXYKLh|I-#;W@nWDq59zXn{;BJ5Q z+-bZ1pj>`EvG$Ak`G+0*HIW3kL8b^x_i7)`Q+0({Y`X0k{AaDL-4)PkcagNEa^@B3 z5%}s6mI!C@%IknOi3^0ECgxu!;^V?)C8y@a+|_s!OjM?^847E0IEuR=QZCd|u%i6U zsN8d9j8zuTtSnhg!@qrotg}1JMonU~?{AUi0gipsZGnj;evGriSj}+n+tEkFy6wiJ`H$EvC{?)t|gdm2kAd1 zLuZKpYm)lM4jjU$@WV-~fDKAMlL9> zRQ%(7+N}JP;S%tOh`&{iwvZ{nnhaR4I!H&Btc;2aeHQV@T+|l{y5D_;`&E~Ck0|}P zSliaYUO=+c3jT^7oiR56cuA68SAnYiSNgAb0OX<9Sbe0SQsF>%NLO0fo8Eb0_DzTG zcVn^QKlA`$BK}#CQbz1wI@!iCU-`2+zA%JU(TC%*pXfpJCP7Ylxno5kbRJIzD-;jN zsgJ4>V|>CFDAen!4^sMRA&UM9y0VvR4W{ErYTioV>ZxlE`|8`F8Y%Ugcbrw_$^dFm>+ zO6EfMtBt_8u?}hloU0l|Hz)`B9xk6DIgxm)XPn%9rz)VJRTb#B5iLQ;Ct56#WGEr| zDjZ<>5Ji8Y#nbDpY|;5;zC;}Cu*C}tSj{S81=)nIk4#Cr7I4PWut98y_d1&&CP}>V zB9?Jwn5{l;{}b?}*C>8dB(Ozssvqx(_8>kka+I_Qvq=AUDNPU=$#9j{{Tj9|ynn>9 zUGkpD>X$iuh<0#s`DMZU)_bP?$CtIQP0k;HJ>1JzSkltXoEUIA?k#KhLg&5x^r({4 z*tciKXx!U5SsM0?V+hY3LCTur|b)5vGZPJefEa_p$pL5Krj-xQY2?aZPg*3%g z(ikHH1^RV>?^pL^jcK%fBEtXGt<#B;3+hvU8f@trLLIJAz|27#hzeLfpoSMIB zDi2oyGKEkDE>is|S2XE@31dfJzlXSRY-n0xct1Ww4KvA`^rPQ@|2S7F8gqlpN(N|Q zV^^?*Q{a})J#(3OBHw^dBc9y=?)C00^b|Jb-*9jQSUm>7LEH4iQbHbI5bzf9$u2@? zf7u&Nm37C#ekOgW;)!9>9!MdI3TcAYVHZWj+2N6hJ15ahf?YTJ31%jKQf}18b`63E z6)2_*H+e=FoPCHdQ6dOGGdnHkD-J~mmr2c*x*h$Dr5pvfYJwK}PrE4Uh%J!I#bf4t zm;sg!u3Viv+Q_%W&to!<8XJf0yujW43E11u1Vn?okuvB3my9O6EAD62o8o_HXO;H{ zSVRXNlVPuxa|3t){RH6?ts~9T5QZqtt3r1(@p~jDo8%|^ff2BQ!l_o4d*ll6ESXt8 z#bgJvS_-?oD(OwR=+~cokxhqU6>u{~%h9lls@tHSe+4SU1kM*M->A@F!R~tZlGcj% z=2F;o1d6Gh6gl%>wSF{_|CrqRoDo~R*9S|K-)~%K!hP?KotI_2wfCVRAYD>!6C{L* z#+lCt4HBiYA-6UpR}05{DfT`-*$TFk1dzMmiHDrf`zV6N-9 zHbHz9+om~>HzJ1+5XW@x=2J5diWOJpZv032NiSK;%!gxEZzt8S)y{ZoV>o>US{#fs z^f{2Tzh6G0>&+B#Tn*)swg6XD0l}zmf|Y2UycjAyWe==V!Mf|C8t zt7Q*rJJfdCVTa{I*cpi_5O76H#U=77CKVOqE3FONC&>zMo$tvJn4~y=Jd!i|G^v9p~Ugjk2UN_*= z7Vjz=y)I2(*C0^w&*ah~7&pu$QBBvJ4N@LPtvlv2F3#hwcys>@#x#|ZXki*(+w{vZ z>}`XM-6!h4h9iebk<}dFQdb9?dU}2FgSJO#B&$pSUw$F3ZqOX26S z{aUCr!cP#^)$BGgMO%=dIUP&*n>gBKctIy<56ZJD5zjzoBZerCd zwn-f@jFq^oQD|KdIgwhWG4G$oa)O(FF4M*w7EDX7&l?L!jBlz3tJ2ivJ7YB)Kc>eZ zR&54qx&P<{u#wp{;Q(CjubtMU^fsoG>i4@nT|yamB1?GDd|TXnfTW6I=3m zN_T57$SCpMS7KGy4w~jc6&+RifT|&gLk;*fW#;7bQRh+&ocS!U=vx^1&K>8TtmVw9 zRvY0lEd(1@Q!WCixNv_9G#Muov}Eq`JI^J1Z+I;v4=`nH(K2Eh7RK$?gDf%T2XHI6 z?p0bn$SUWxryqFGGMqxka%&4*LGuNPAU^&~(GR-NjZ?Y+$_}$`CqS^-`%^2mX{rh? z7E$k}_maMgJk4enwWe@;`o!Bi*58ic|&?&kr_rDbS9Y5cYB%`MrCsw`X~y?=kqMG0}-OMst_gF@%y8p{Sj>BSIreS zJSxa^kr^<(f`+E1EoCQYQA2%P)%w-cZaFU(6kYE7C^3##BFuEZc9GDO99(dZIB1Lr zw|%7tRq$Duo4x34G#tQHUMG0T|K+*$Dw$!vS5*6oM*a(l^)4&?(xh$2$dur(Q_j93 z9PzxF;TM7KGb1B^ZI)*oLp83gKU!6-%HO9uBQf&S`=mshQ-*m7ML+*aM7{U9Rs0le|XDD;}i5FS_? zvtv`4-%=8v<^MXwu@CK}Ippz~KG(rs`XoCA1zR1us8)q%qiznp zX6s4HqF`LGyt4mWlx8A1@lQ&k7^CMFJ(OPJ#23fTzbtl1`XN!Utw28*dM)iu77y~i zF#BNmGnSlotL^wC9$HnvK>nsjO;f<{8I*;oVP{U0hCOntDGkD z32!!8-*Be|>EtK>_dUEVk=l>_O()CmqQ=f^Tg0bs# zbk$C*`|RY{o)Vxl5KcTH$*5+QX;>svHdEe>_X``bS;iJK=xUUCkW#+9*b$H~-&H*K z{fI%|07lO1`xe1<$P6dcPo{)7y!#WXs)=?UV4;LJzaA0$w1XbZX=l8!v^MKpe7%Wk zDsYTnCRJ0SMy015p1QTU%fu_kFf`NZ_-6)p5!-h7ug_J}2~|kOQ7p@HT8sV%{faNDY1~_Acw*f41N;y% zW6ZS&s&kbqN)a6_7r(jBxk-h-Yl69(ab}%E{4*z2Wie0sgpBazEK}s$Pp|jb1hGb% z!ma$Q)zw87SN?J-&4F)(o2L|%w}Ds76(!98H-lRKA<&BE1bELMp>=+%emfxQ1cFH~ zo<1(INYVKj@swp$$MmrV@kKTfpOQlPTdo3=hIKT|kQgs8@VP?rVVd)Mu@_l+pefWN zcq#y-ahm()KKmqA4QJOIEpU^vT~KJ;wb)CMzqMC$tBMBDh5k9`9>|jgTDx_JaTj_{+WEWh+aKL^hE#Dea`_-K%r<&5hk1&c7L# z{b2!iNi+E8PzAJh-XYvOgNJoze!u}bnc?O;JDm#fEAxjyJgPnpJ^%BEr}b-##GRaT z(w_9N!DiBO(n%QanaSYar*@q0p@DrDS(CRUQ-L_Us}+!cdn^bW5Bw)l&&%? zK!eC|%C7=0xJ#_nL;PLiDYtzV<5qP(P;wPH0Mv?x?-gRfdjGU$KanESi=V7>6y^~` zm-1qPY#{e9U6*s=M}TxTazoA6Hh*=z&+~VzhPYXcKmIViq%Sb5#O`Vtot{i6+irXS zeqibCmcPyx@9l4YsUMv#eg3N=+PEd?f9jm|Dyh@hr7;3L%Qq~l#=nrLBKBQ>u>Zgt z@;@-9bFs9&$TFJGkrT5VzxS>nd%)Yrvyc zO7tM)E}LM0JxYNy=nImQ8AZs&uRZ{Fws>-V;h=EE8_-P-C@zi}CYttcaRHr6^&VbS zstoKq3;cqy8G|vC-`!rb!H%RPD6gd%{l`vjkA0RVDLdtm0dHsa(nU{f=q&fW1e;g7 zsk7#HF1G!Jqnqq5xh-u0dCG%gZ874&0~HAFp0bXs>)#o0siIp|(>YC3pDIUqKrSP; zd%Ay%)500P4?9?Lpnro15_la0)8D5-A=of851QDuI+-Sk4&i|Nj9CRtPN-2Vko6rQ zeK}U9n2l|DcCzJkC6?j}icIEZ|8~+wkw&G$wL)s6hcw!4x{qI-Qs}HCPhuTQ-TrRG zTg>rkBvY;`n?il}xRrsK_C&a^&G|*Us^HhZ&=hDJ^+$3_g@yW^FO+a?pj#>5>ZVAs z+^Aymilv}T)9*7U&xyy*FJSbUHPzcrdGFpN40}Kk7f#NEFwNyx5kWmOI!p+Ygpa(y*{5nolYU^{bhZ9Z)FsY2c0hgHR~;$u8ER7+RA}IlGPl@! z*6ClCmt(v)0Ru zyI}aC#uDfP&rxD}XrcusJZQ>za+E=gCqEbEV7-{YW~MzKYWDCss)h{+$tomow^4*D z?Jv>J++MTq0*5EB_YJ@K^Mma-7&mh77(x1Y>Y2U*@#Ibf=io%NE9u5|$6*5W!@u(Q z*)6X=LQ{}q|6HxH4^mE^7j1d1jpO-LvX!^+JR4+spEd)Zd=(HwGOIqg4~tUZcwuH{ zDNJ*6F;(X;%gg=|sL+$QHi0r<6-ZxKiP&|m)`?XIwY^OGa0Pj|RFkrmn?!u7I9*Xw zxUcHMA2nI4`-4n=#pcngvBxl(`=N17Y@p4qoKEH`#Y=_HbCNMyQ zmKUBRy14k^-_^tY)!Fx|p~ZnezcTGWP~={+4K(Drq6(vIfPqqwtK2;DNv)&{J_Y1AB zly9XuNxAeAA8~4Tx4#s34{y5zc!4psiAfp0{a0S8S7w5J!E$ck)T@DwNf=fK|L&?S zhYW_P6>+JvKdmQw;QoZ5sJQU%$SZF}e0n+ObC#AdM^N`poVnbfs={qhd2QofUYgB# z>v$JOxDr-;I?E!ERg(O*k}&48NC%ftc;Fc4lLR{2;gVqG(V#vYXv>Had+8-C`Or(Z17LT~XS^0<`N&2^ z5e4-foA6AkP`u0>Dt&iYRm~hO$8N)S0xFy=!UGik=|5_*oR2`Yj#>K{S7~=qT zqKk1dE1t|}%L?<|v4{c;E;$I{oAIWbS^63MG>ijjOUHpufsVs*75{SXibwXe$JAhxO~>MG$jOed66{R`1u*3o@m;wcGvw#I>>dV zbgprQqoHOuX2>6(+vL4L4TQn42uXADOqXBt{d=yrI4jP6fc1`2XZt6L;@kHolj`g) zxbrMzx=fvv@rmU!BD4|t;OoL7L=}oT#imBt#=Fd(hn=_lA*&#ZA?Z~wza=S{BO@9F zSayX3H}CX+iXEoKChzJH?afBF%~w$KL0gnvcr;sR%idLe4tfM(VxBnqL-c_2z_#>-rKh+{MynW=~+i zCd0lxOm6!$IBmXUj$%JNN7IXOKe_sibOt^^y01)n#$7g`UN=Yt7xMijdV~&*H19at zW>k`tjK8MoD)Qw9s4wSqZcM+*l_8tGw-5Oz#uUn70%oEOA7lLnl6gpn_SKMR-j8ox@@+2m^( zCqGX=2)0br@-)d)r{DhZl8`$=*i=w_`BrPYS5G+zWulR9t>LBjeAJK%6K1{zq>=n1T`gjBV6IZCwj_ z=n~Oru8@=B0@&XW)){wA7R}TMY-G6A&Y5<>_kWI=z>ygzZ)(T9ld6b?bgF{=y00b1 z#5>|57HXy1hq>sF>h(lm>~e)g$-w!PbX1nz;eG*hwAM}RRM+m(Xk zK%)ug{Pv^@=b7a{y_?um-t1?4H8qy-n{KCH2SL*OvTm@voT;2(m1T_eG!kfK3P)E|!5q>RfDlD!PqV!|ENZAIT^0Ag}MGfyc^MokKT5-H+mW zvL_*z?2g1-#XKNFomAHc?Ks;uo{n3B3{Z^VR6)33;@a*dntC?pfjHQTfgNU{4QeR9 z(?OAbs~jKfvl8!w%y_?Cv_ZRl_E-r^7q^nxi**!9XIreTJhLranwZa@Lne*6&TBQ# z?bh#UFCY9j0Fmy1&eOJDd|AI&o+8t_Grs#n_AVq}iUFEG1^Fy)Ck(IrX+Xinnz1o^3UCKkw6Bw8Gw=VESHa z{at7HIursFIFNTDiExg;ELa(pza4v2EJ%O%44hhw!V%QoN;{pt3L>CbU0Pjve0^R~OF5H;x?+0B0O=azME%a%BdyMp=t^6Iak zf(;wbkN?WPyf_(ij=a1+fK!9qw^YeyEx+gwdX9~~_9vrr#%J;9PCLq6MqL_ykox1z z`kz9k_E)&~sB+-qaJ8jhsqUpij%dUj8BVylu4Nl_c})}`U@bupsR5XYLdPxT!HK%+ zwX#RvHz&hcZ#w3XhK_wnSQiUP4Jo;}24G}1(2L)#vXcZ2-*_h{&P681d&bnre%AGQ z`yPipLxKHC{0pP<$lm=i7q$(}_UA}>;=nP{Dm#-^XI9}Sb#y2VVbS*nR9Ph0wjh!a zeMsCwxv1{FOWO!oQP*v8#E93d3$X$Uir3!XJ59v<^u zNcc8`UzL3&hOS-MA0k|HqU+{8s-y7FIq@}1Rw_WFRT+|J@q<5pGQ9NJO61S)Q~s7uL)a^Dr~A7;gA3du`O!jLf39^m6%Oh z5_n%4^1yWk!^--sLyH{>6YvIOh@8ZyxlMjI=6ZZ5MMM)>C4pTmx}&~*ufqSDgP`z2 zgSFgO3W2vVJTx0-d^b3JvC}8*D_69I)@VGDbWPL4^IFlc5bxBQZR{0A%e@|EbXUOy z2`lqQaKsy6Foe#EP&2V!>=sIu)6^Vobg_0vznnmHI+L0v81=F^WkTk2`BXC?uX*=# zhxXO3(&nYlb99f^BJjRpg%-dui8K^-XT1~}_zr2WTd0!6NEEf1V8(XG3C~}0Sjam4 z;_Q2=lpP~)Zb*%m`XJ52kT@_(h7Hy+Vg9ob=j{-_G1 zzn}}+A6Pk}a)ofrZFqqz^&5a7{WEdPL z(@isP4bN}g_WvA$wO#*aK4JWowP{Mn{b)opxBx~y=)UXwg%E1kF}5CO%X9Jtc7zUY z#YE#ZN^4C2ommE4pV#QpGWy`KJE*4Mjswuu^*r6)(qGT#Kimw3X?cLEi!Qddy8U4S zrf)I9z7Inp-SAU{dTPq;+!m0g|GffN5RnXeSR_PiC`qyNqL!0IiuBUa*_L^LP&;+F zh`^ez#ZaOVZY_^U3FM;?mpBRm-{Cc-)X#*?G1iZryfK_cGP8GOr z!4=zh7PohK>$ZAS;g-r!ApuqY`j>EIeF-1Uah1|#7W*1GWMbzmEia35wf{6~p{^qi z5cN}FZ#f*%Eq>y>fGmwZpZamFEAH*L_uS#R9!ohP%qMK&yLJ1SzF@&isK3`GNpPl>R@!Z5W}+6d?ka`EtQMw_MzhGvl}0pve9Aw{b!my}*4xtjj; z?3pD})j2eqwV3jOv~>^;ig+uOl^5WYyC5};4{HrAYTa}%GiAZGa#LXKQB8may-CVI z%1OADPBQ(WtmxGXi?0X~))1oshTt%DFtXf#wW{D+^TB{OYE*Nl`EMZUze3k8KA}6h zZhqe@wtkfC76>73n@8R5X+y_4HnqT&P72y- zqw;W6)ta<$OE}1;W#xW#cuJGfppx&+LCp-d+mg@rcU!<+aPo?4MJPr&!8m^&irK!f zd;GQ`?ZJB7ZP0?keDC2I1=d7dV`s?IXqZ~;sD@gTai6E`M<}}d2YEqOPh<_$ZHgsa zVfRkPDy>>OxHa*SLw+8+EbD;22-B=awZvqe$d#`6;ciW1S$pBT-~pd4+X1@L6VF@Z z!LU~3O9QU*N`8OW`BVE}vZ)8*wlmu2_x?GVT3l>gk7D|z{ez?eW43yz=2Wnai(K)u zmA>!SQ-}{zGJ0a8Kkd(JHqX7-BUvxor#-&vmETP;Ye#b0Y@6P_B^vNOS;3H~7O)VE zen)W2|K}r0ZJG4r^giFyi_BpGC%B<@)H}a%^-eDqOj<^H-AG#c0tMi4-E-d5v}||^ zIgIywzZ3iprED`_)LHxAsoAcb!BRwQ=Umz(*cUm2BXJ2SL8o zNx^-1lf%Vsi*x}`|Br?YvPk=MjEEjzUq77LFF5A!ORjt=nw9YBxR;C@`quV1lT}?B zO!?12Cw$zSy$}=bz-{^nqRWz+Vb0B+|7i27vt+iO4`ub$83hSUyG_H=ATLrOTY%$h zqpW-nsG^NFpFLOM1)2@qVpDHt(2<(C>h&wj>~Q>{@!r`>zX=wvxPj~~*z(sJAxVXo zRlXE%++Xh;l5G_1K46LSXi^^CghQ7!sdCw<^czQcg+EXIy-95Xx2fs74|(UDfONyO>KmmOUe^d8Kb^mU8xiy5VtZ{omMT zMlaF=rh+dt>|j4r@t881PgL{@i*T%2Dq~5hHt31WDrDNX#%(6z%L{XU`7)tF_dLXJ zUB9D~!-ZbwB*@OVK&E-3R(eZk2G#X(u@aXHx8_vIGd z6lwW_QR{D2=Eb<_)IS|7S80mbF;$;)E0Hd}d#v#A2=hxj3KCHS1>U!Wg=ZS@Xir}K zT2On(Ze}w+pvuhKi`2V_XMj61C{drQnftF~YI!0_Y(a%wxeH2;7;eS~17s6*Qey0F zk1kx@-GX~x+>?J~>B~30Ivuw{jJ?;xJ-J!uomAx1K0=CJ-hCrIdVO2=#l}ZjMX=6o z1$?<>vqVffo5$i&Ba;Gae^)bY+?{u4)}Uq~ew99xXJ;Tue_bI+P1T!C{u(^_xgb{I zqVO$|#COU1(tOcTn1q4K2f{LOZ zl52syRb)yy4!I}SC6%0>^s7#$Pt18mP%BvOoXt&nt9M12EI;M*dcU;LVm!5+I{71X zxx*w@87Yb!`N7r{yIX1yyfP%JNuz83@4S3~VPS}z4Xh0onn*+9Ie|M+ick^OQgO3t`kJT)sE zb6*|x&=zr0kYRiWE!S6Svuv~T_&d~-UaUPuQTQua@7O4~Y zh%hLWUP^P+`5Gb^e(8i^YmoJuoThreg{|}7M@;vRTe~h~Q?T7VW&NK~ zG0S(+M`!mJ{tr!O8Q1jpzyJ4wPDLrfp@67>Al;kdM-T)AL8L*tK}vE%1q@2*Mi4=z zN9Pdf?q+ny=vw^e_woPT*quFg=e&2$d7bz5x~}K>>;LN@{r0|V1w|-HQo43^9IJu; zU#wj|WWjM!ZaCqvj7Le6&5LY~>j<;n6ON;gwQBnzCsRVNvGy!EOwGlMFfc9Twq;?tqXbzi{C6Jja$a1(0ZJ%my$ zoyYd8{hVtkAMwtpE>osD4fpel=lh8J2u%9{w3H=liOE5|E^2w3*8$@ujo{EE|u%39F@j4 z4$7ZVRHk~Y&xJb9as4fBC|^j+fRCHu(p(edH)vLUd|=qTJ|>hd6I+mWn03cT&0i{! zY>{PmJ1z-y($&9poZudKUf2DI@F7dZS9>bqT-U4};}LhGeBayHX=y|9qR`~2CdbQu zeY44}mP^84PoLa5i-1@R>Ex{4b72C(`WsxJt)Tjcc-FO%E9n#j(R`$w<>RMD2qbk@ za~{+SC!F`Ih#6Pl%m?Wy4J#0Ufy>iDb7P$Fgw1gYE|Ep8n@sbGGWuGj0*Y&06-Ska zIiHrPY5L2J5t8bZe6{)yBCiBYM3*d0{1H?|(!>h0|DFX`F6B+lj-Ts}(s_-$wHe`A z4Qt^ucjD9e!i&5Dr)D=Q&pID2BaIZbUp5ra3RG1}^G7z#;Yp^!?bR&8|BwQE&l%Ex zPHigYi`Wk!tX^G0EK6p}<ooau-BD59Zw=}xH%w#Voq91d8hqG|KAej5cMa$?-w zB6?kNMAuUMB9s>&37@GkXj%rBKuUFWr53ci&-VJ)C+L#%663f}GRdnxHH z?-HT6NY|EQYaSIGZ{|juuRPa%=|w!flPBspNi+CL6o71kku2$D-WXsUlNm}`x2U>3 zk6pU()c}!eg28r!O*)mFKx_0P1`ryp;v>6L4kE-o z&Ku{Ceu)j*fuurI1g8~QpVD1p4308r_qKSFAkIgIH| zyvgRL9%>cR*6%NqH5tCqME%MG$J5TLOJMSFx4#T))nU_ zoqg1gho`JEdQ4Y87^VYyb<8h?=MGZA-W{JiDap@_V!XFEflv>2YOi(8+1S#ni9wlJ z(zX3%UwY5K$l(Vcl7p6YO{xIcprDV$cck=I14QU@&B#y)U6S~bwSHsO{07@7OWS_x zZ&!JJlE7+T4f1=x;ur8t|4F38cURxu23(i{eEEjrDWo;NGKb=AT=vvH$3mvSOVo+a zzaBv^%c8omxrl=``b~vWci6rKhv-jFpN#F38nem5(V!&huOV`!opr@l+4V=pt}eZe z?-bN;G3Aw7wG6p9#^rvKOO6xx-1}Lc`{YcTb0=prRis_3YbN=3(IMrvzB2U;R@(Kc zQE))lb0z2n^V%1d%wG`{FU;Va-O=OJGf`>f+L8QU-0ooRj*Ls%M8xcM3?P*7b$|Na zHcIPM31w4*yrdqAx;$;~oDGjExqt5_pl<0>c?e0w(V2wverFQqvp~OV$h6g}WIa65 zW#n*Y!t}HHsNZ`G?7Y=V=I|P|q&@vP#Fn2&;k;MsX|?yzH%?tX!gi|Qm_+=a`Z^WD z_Gw&hIcX%n@JgZV>UDFn>(AcBt&|4qs_P?35u9sR? zE{-M&&t+^Z#KD3_fq(wo#CIAwi6H1p95O; zJyWI2*#~jk-pI|?l?#1++Kisp;PLvtUP7Ic$|)t@3vB*fiFL<;?k_dQ1hS^lc-nCwkdZKJk1#8(@t>9l{SIlRODIH^mX@8yZnSCB?R0*Q zbWC6?9SOasesGxYbFt%KiO-iVa%P1yiSi51>2k=?Y=KJcw=BGNq@#qT{R12C=pa5b z(q(eil7n~Jt3-|8@7F$|Ncb|7P4 z?Q%3ZFdWEQ?``Q(d_%PBQfALfTOI%zPt!`k+H>4+6#C+0Ye??%>~!~eE&Y6RL7UXU!0eGBc~-jX2h3{_tL-6lErMUdnM2!e?M}uTyyfXVqok8_a3>T*p*5;5HBM zvr4?Eh$!t(ifiSvA54VXv)kT&Km0^1p~w2>SLz6I6dk58q3QP{r}W!Wvsge+X@?`8 zvy!{0l~0}*7Nk_6NsbwB{to#wms)=l8bq(8*6(pN>o%jjIOyniRkFCoc{b>A=V!Iv zcxTfigTvvEIk_Laot>meI~!_EDm@QX%qLY*MC>E<`RBUYK5(;ZTkY<|?k@qG(K_)) zTx^3C1@YoO*sL@8$vU0f??8W_lZTBH#Gh@muQ$*JM?<)ME=U9BRA=~7p1o&8%q3NW zVs-(zMjA>DJ?rlLg8~x#b%cNJeQuxL(V`NpV=K&1e*Mg@sLn23bK>plvO#HU;eFVM z?E|y!inu?er<)P!wKYjjT(^Z}q_OUipV91=cKYQO`JaFfKDuR`Tyf5qa_pp}+@WOw zta4!gb15`(BN4jwQ|=qDnBD>hViA~GKz#^O+D~tciRa?2K_+L>=Stl+wL&9XeN`0$ z?o%48tSgs4$`$QvoW$CNR|qefsA;(Z{TATA^PfYHEDT;740pP0Il1mgOg8SXRX>MA z;A59mMUG3H7q_s6yet3kIXhX6@7Rj+;X`RfjXs0CtHFV$@;jH9#!e5ca+gm4YPntn%nZn@rjZmn`1mdCu`)#*|9;e;K7ZAW(@8g;eWeoIJT{&vQ4OP6z-eNW7~qOa8D%#uM^Bx01k zEx3-`mR-2r!FE|-*@HWH7?e1yG>V=1cUm_&J!>Qz5+u`duzgN2(M5dFsCGlPRJIo& z;ZLR>l@Zq|ec^+>2F7wQ1W?G0$OC-$pO>Mt)e>|js`)VTCeZM$=SMQ5aQMNVL zk=4?=PTFrhrZ5F{lcKm*6(-uF$d4L98y2liKX6&>uF%EoyxLM|IYIY|~ub(ZX zs{+pZsVD;vfPFJ=Go`O#u^~=i3*8z}hWN*Mde8cCIjIj%Q8_bh~`O z>6Zb9ckk8OLhuDj`{YbhT*(}4U$3H%$2?6Ur58Lr;@?RO1l=h93A-J*49bZ^pV_yD z1yJJ+EMsR~i}-JN_v9-JAYS|SqP(Dd*W{qMgY*$4me-~7DgbhIlc5ql8dWy7X0vn#l6lLWQt15l*(=UwlT z8XL^N9jhA$TtL50OmHeD-|nw0^*ig}!&Rb0GPzHz;f0z6$JD!F5_B&?FyMuRQ;dFZ z>GO1Sb13;^W1S;W&p#W;n{;8?ioVhTo?{0I`%8McVcDp7ykk2*x zkIR-%VR^w@4qPMF2$0PNRN)VS=LTN!V7$?CCl%HM`w7`>&Wdxybaay@MV6e8V^R?r zrCyY}aACbE1z#xw$N`7}THoG4(PVBczeVX#d-~Q0>`|PzF9(0;{(MODR~ThhH;)gk z*-S{S9lu`PG9i7jIL5hiaXl{z-IaU1NDFsWQLf$-dAjz))drt1 z8sqmL*bS`eDF2Z+li{s`Ai0ApjFdO4RXWkuFDiI3lu|)K40DJ6ao?%zzKjW)dUQsv z>{K4lca`K@1R9>O&Lv~rAnAaqGIbZO$kmC=N@*~ZVLILJT@xMTAv_B%&)c{Slj``^ z4mLrkXYys*`pB946$~C*I2@7cnRI8Eg0yk^bWhIfYsK4C{YCO+gyM6cuIIb zE5kFuTNdz|p9NaWjU5<9CkZ73I;1w*mcf{#>IM1uRkl_azBJLl5dAg{6qVGB$(X1d z;4`D5RLg|_!*8?L1)J%kE^?N>XFRoyFP@c1q`Ob%@va#Y~JB_Ui`rdBp7yDbGldGE z{<0UaL<>uv_UAy&Fi-o(f(;a74`QG8*Sa_&V z6&nX1FE*bCCY1j5>M0;Rsx~&}*TE=q$xwds<6heR#DV-LoQ$m#15GhGq>v{h$k6!R z&gltOc9?%HIzv%uhTdRqlWi<$V^&SAI8I!5Md(Z%C}CLOXn;kVWzOSxCfeusE@{Y&)7>oJoNc@VGV zQ)$YZu>rTjU90X#-v)N`5?97e{Nyu`<*uXSZ>swQQ>0&Lv7R$|`qzhjX)>U;mQR}v z(J49Ij%$fA3p)KfC^@odZd|u!d`jy)qQWU`E-Z?tESXM>VokhH$A@V=`l-^FhBucf zBfN!gU)1j;qOv59p#T=?*JqBr>A{M#EuBnaSkIT{nW2=~oHmkoss)VI?`lc+_zNaXn1A z7j+Xl^q49jOt$e#OYz8JDzN(1ADkbs;CYz(dvvzT+AyqMK`^k05=E@r77&R#pj%rV zQ3)!;$ovzqQ@vizXrKYdJP}g^(m+fX9poA1@K?G3xr{zAv6fV( zjVN)xpvz-7GYpjoDc&oRE<#RHOOw`8q1F31Im?3Qg74FEvMUD5eFI2gj=SMu4D}MqP%j0nj1XXeuw&kx=TjCd#St&p5ONx z9Q`EnzJsi#1TBK_u<^orbsF-m!QDD!v#n!X&cvAiI+~D}MZxG0{ByK`@s~oyXI7aH z6u{HTfPF)k&dH$UxG z3Fj-B?tzLYFEbA{l-((Tefu=rp9G(Ot-s3D;b`OzP8Hmp zST5LGN~3(Hh%obs>8m5>12fv+&h%vb+n>YckR{JvuU<44p9M8#+@FwoP5F?g_cgTy z>wlCIL?IPKMe-wOIOn@%4Tqxh^NzUOG>>X|0>AV}+V=kn0@9yH^E*zp1eBr5G4n-| z=*d^a!U{kou`CE#%f9deX|Vtm(vyET1R2+mzo5ABffs*JgONp}@uRrQ5K~pRgkcft*>(X-uEBWYa-q=(=2;UiO}l6r>=b4K^7W zTQBN7G>13(x)$lzs5oS)P$fZsDrCT~DgVgz>?jAlj6X0x8$aQhi()LawLyLy@fr3d zx}bw1Ycle7dn+)wYb(7$y{DdScA!YOa9MKW;YiPR?(FDp;1YXn4X>Vu#}qojTRxvZ z25|Q0>#w#N^E<`ezzk@941^j!Oq3X+!eIyR`p%h6c)Elv2lKDCyH*!^tiM*Y4sOiV zGu?@i0r%$&)=h2g$mkE<4!xpcZeO{?4PN`shhzIMox16JlB{{*Z4?*Zl)jy~k&2RQ z5^rpZ?!AK`6z>P{(+z=96*{he;9QyTqgO_4g~wgjLUJou9bBx(s(lm#R{Fp7)%N6f zFa0C)F2=pumQCkY!Mv4KhzEZiK57G30_)z`zODJNwn?FW>mE1d{z`-hZj9V=9e)SE zfeay1>AE&G(b(l^qR40iZB#$UGXuhs_9nfX1=AC>XBJ?Xt?%y$dGne&^H+>>S!`y- zjWk_Yr$?<>`{!l5U;{L&LC?n7*j+)~C74O^JP=KAu@@Hs6| zJoL!SjO4lo^VyD;_z`kw3z_p5;)a!dzJ8bvp;wCSv zzcTRp!X_*#_%B#!aK`77?T$Z(nVxypij#sDUU!UiQdIT}R=vvIy3fe{z4N5eP4E3tBM%c5SMHkk7Kidc^$-{%2+{>z`Rc{2B=Vz;L6KaSjN)jA-nAiY(bopyoQdH{iajs8^Y^(L{r} z(GK<`bNe)dZ_CA14*SIKF!ld0 ztxoL*RIuldXS?R?F?M^HZpX9cgGfKye_=NvQc=z3*6odZ zE4T%il>omi_!+37rOAl`2qz~@$mhw(EJI#K)9xgamEiy*#>q?t#)jrN$HLhMWuAcMuTOOHw zxV+9*=n_$X!Z%JUmyyMRWfAxW`g~;N@Xe7*@T%UP|tog>ocq0H| zvf-@^FzL6Pm@_PnErY1PusWJw(ldW2| z@nJd7xaQGi8L&6k&0*X0p?E*jWkXy*j0Xjm_ zMyG~DY$3V02Ac~&Nj!keb0TC78{nu8Hw6{-cWs=ueR|Uj^J^T9I-Fp(m|IyiYkIU@ z3%1&1>{5T2*g>PAV-?z-`>4C0f>`O7IxRDBsnd;Qv-k$5)J=@p?%eBJ9o z2dxe3eA&8Xn1cVIt0QKja>kZqW_Pq$_6zl1^p;Kb)(^YwL>zuT+r$dV0Qi8M4Psj3 zbP&lhH{n*$1794;7))FqO8sxQX0raj#^YVTb<47;44HT;Ih4-MjZ>S(bIKr7-ra+5y(o_@Z_7gTKQo*hPvU4Tf*Vn=G@y#?stnvHFWI-M zS9o)<;3kyK`1Fq!7ib$@9LO+by*h6D)r6&*jCB7ub7FN)&3;4wjy8R6q7W3f840|>2&Jfdn7Ere3FBq(7mrh{=S(< zZuL5!hOu(3@qCXT`b)z^QIJi6WWb7`hVPw@(+XJ|{TpKaFd@3zoOAdSWZ$;#$_v{j znm31J;<@kq#!8eO9MH-IdNObvZ{~ZV}N@@VG`|ViigmD*Y;?1|Hx*h5sze=K8jfE`>{XSI?F3W_PZdlq}%8v|jY-`XbMSwa7Rn(ZwzXViOp<`aua zVJz1zJ&ujR+n}>ule7~}p!cufcKx|Ca!Innoe?xwG|?!vVlU;=gzY^C5j_qHZ2i-A zu*j`>v;pJp!Ex#J_-@U(bNCAx6Tkhb&4@~q$(J(kctvX@%!Ly&ur6DsZ#=#31Xfx$ z80UXvt%@Vt?O7{dOO)*X6vBjOq_h?ucK%L~y1Vn)Y^$c1Q+#G1ilzV75|WhkiHhXs zOW4R>?G19%5x_Q-RPT9^%8DgkQhD{(HxzHa*cCkOm)$0#vpqa0R&Dt3efJxSTwEF} z2cA46(Oy7^5l2~5xA{?3-G;}X+^O-}p%dQVDp;nr;at#J6GL$FH`9%X&;m3j!y9m} z*O^*mw;~7^uk0F^TF$A6{IRYH@$( zMH0e|g*O@|T{QVj`&^Fp@%33{k~|+W)$Vx!)V3xGed$VL0z)%+z_+cJ!iec6^O5KN5}^>51AO%*2IaJZdR?)|Eyn zzoO6Ndj_fdjry6g!SgIUwVprL;{}hta5N&!_CFJ9rtb2^7>#_q`HscSVZfIPbF7ty zFe5u?sSlm&_nRFAJ30y&?a7^vRre>*1phQCxOO z3@V6ir?LkMYv<)hQFXRQ-QxtwAmgsWh8ms3k84TX$Zo76>j!Dj?5zw*^p^`wA*Hr_ zk{Q11$Hi*KPDK9h=KX*?qKWg#vA^I>0aoud&1u54Puj1NRc9wKo^*P&KbV34J>W&Q zWL6Ti#U3_F>B-fm?8+*_k3aWz!fewGk`En^wG70OBOfnc#T{)IHXBq8ue>pD+diZv zCi1LSJ(+gz|JeL;S)GxL)yRO5cuU^X?t2+~H0*6XrsE_OinpUHyTr|`AsaZNv=GY>==@qMwC@ISLO zz>7H~vF>1#KWjd*v{MFh{_VQJ7M4(mKB+sHAB4osq>&D$_mA~%GT@7!#OSW?DETk9 zjxIi*xl^*WAycp=X;B@qtUzo%g|`h<_Nrzn5+hk<{OIU?Jh^1ts+IZ}2gd1x~e2z6_z@X%bhi#Qv5=9NmcYs#u` z<*#1hAF%TM_5hO4NxkslgHnsjRCgw1?(E#oxvqlH294}IRhQvkX{^I^4O5MKFp>y)N z6Z>-{UH$`aYU-ptaq!%j@N-6U|HLlH$e99@3F){h*^C#r9UrDl&2-;SI z6uMlU3^|4%`;QFy(sw;}3r;?fPj%R|6?nCA+syQ5kADdnMJYxFQKo{)lJ=4T6Q>KhMx|- z(A`U>^1t^V=&&et>kMX!`IA60>WiD^egEHY{sa{A;5pD*)i$TTMOIDIiTjmP_l!^U z<Qyj2__x^ z4EB=S`ndp$ur%pJt!Vqi7{?*#e$6ZqFbYaMQ+9`Dz9$Ihq;)QV-06roL&Cg$#X~_8 zoTfZ|*Wi~IOvhKAjedOxnCUVGcedZl;Jo)=M|H^sH#NEV3T}Tjy1NzR;8otw(_IvV z#+YTg24nYImj`~Iixw#{sZZF|3{Ic1Gcssmnq37i{N>5*qM(NH@qY#CZygz}+kr^yU-b)O$~rgf@>-^b3=l7Xv(Z@x*Tx`$;1 z+mL`FGq7qCOcs&B_w0r2yj(6h9(ful-W zu8f~PQF?Zi;^)kVIS%8+8D*F#9FP>GPdq)L`PQ$3zW(!|cRZ{tPDc|ns$;twwnZCu zms0)Re0%H3$@luel7(5rB6suw;k=L)Zl2StfDPRpKo z7*ZB98obCrDLnz`;-2&Pj%ZUlRo_kePJR|%P``tTE?Nr-geD@({WL}C2%@h|voBNO zy-gz7?rLQ6RriVwz;B-9cX$5U*r@+CQp#tPV*O-1-pPQ{HN5HZ_~YxWmXOu)L@J1% zN4gC=JJW6tDAYC*=kFIj&V*)vlXz*oo$eI|XEjmE>Eu{aE+YK%_sGnMo=IGsLA7nG zJT~G~j1>MU|CfuGm+cFzzvghgdu7$0ie4beoAlX)rr(VjZ*h!xI|RG@iq8%)I){`( zVUeBH1e#kwGGI3~_xE#}g1m@(L=w|epaJz(;em? zC~M%)6^^WnT!&sE-62)^TRPymMt5u?6ETJZLaf!H;Y~UjCZ+;Nk3+bAjA#?K}$~v_273}{S9|uX?2pCo`%?N&^q2D3R-L14n7=xY$9mJ*gLm) zw?Zjwl)?r;K`!@7^!wwq+Xx4@S#U`)cSPUm$?qny;AoDmp#3{9&a>%DwPK}!{owaPp5N=_Qm3V^D^)8>0tp(+c11X;)EGvk!6~>3*s$= z2Nf!?`i=4ah!^%iPiY(JVr`bg)dHR4USp?*ffFyAGm>``1RV;x`c%d~ebdKhGA&{6 zshE`~^m`4Lv!%V+qg!+0D%X-gOL?n`mOv)i4r>mxq3rLKi*2R{ZH%fz1D32P$1?`u z*pNZetlw`s;%Q);CbcTba6!eu5hAmiw_*?pK}pSZAxFMk zG){bt^WG1Ap7glooGN_7wQ00)N(?Yk$LdS??=Mf5a+pzSZ@e& z5cE_r39zf4+k}9Cr--AklL!rB}1PAQ(0wz8}*|sR>1nN{am8QmxEMa)lh&!2K=f| z@d3-!nJ0Ms;O*Ziu?zDlo_k{8>e8Vj2sM)f{^O2&JA;GxZc34G}lsqOi1lPB+| z|9reKL==p@9%%;nk3+v?JQ>%nyG2}c58rKWsd2v@zU$hlpZjU$Z8NMh7B6Xl>kB=$ z8D<({1nM;Q408|Y-wi#H-ym#wD6%#HADG*}_W*hF z`r6==R`K5wEq1Npo3Au6DvUPd{ih?tyep`?IS9Jvj-3W&!ivt)Nzgz*0Rj7HUL*;* zjZQyc>a++lFTSHndP(&iDGEFN@kRxJ@gYx@*07D+4i`~bSJ{#8kB^g3FUMej(nE7F z=5LWLBPLapD%Ht1l*TSR3TvN)x~*m=;}s98a%(7mbKeJM>LbUJ;OJwu6#DUdojZ0C zV%SeL#b{yq=nvdNE#(=B$%y{--{3a68+RUx(dNE;a5V?-c9AqaM2{(9(1N;O?G14_ z3K=YQmwPWoMT4cPcuj@_?T|N5%>YBSkQxhc9zWu}qN&Ywlxw}PL7Pvjhq{;j8;&P( zdInE&8FV5dI8&OF9{4J8 zOLM-NWX;@Hec* z>+X$x-<_vI+ydsJ(m?$Hio@I`9d=5I5JY{?2`acTCr-HxMT*@DcSNkix^11h$M$u9 z6*Nk2kgonTy{(C|sA+-$PcH?nHsSs(Q3wN175kT*ztbd=9vizIQ#}Q#ZV!(uj@}o2 zx=gn?D+aK&`ow3|9%_!~|Ezc%iOkp5G>j&G;W03uy2MU#t02gF=B(H2*-c&ssvuyJ zUR0G1C_u#8pm;csTtp$F3ZiQtgoCZX0c0Xk@558Kxy9Pr;iC zbH~kg`imaheUVP4O>d(H(c9)6D7r;?It1h{oDW4g(l)(V*Z~wvc(=SqRxzJ1X6%ao zB9*wLs;PebV1pVO0VB?_i=RLmZ;?WaD#b%(H|jmD5Is=TCDkR5%9~Qa@DS8lu}x68 zZLuUJ=Ek-h--9~wZs0Jh%|G$?%#>N5EyT|K#(Xq)EXT7CPZ9Sf;uDReCxIU7rOQgq z4;q1FP##U@cE(YFjV>bz$|p>4oPr0PupeLw#-g~owGx}7@9C~*NW8yeUO6RJ3oe#q zPL>Ps5vy@q8zBO_rzk-f;bp1FlC(EvtX%pMOW~E7zguV24lO4oXJ_BY$G~2unZB;) zCC(9;D2glBxMg41cS`FoG?z78nB>{hTc zIm6|Acop;V@Az0Uq?hUz=6gx3nrcdGpdDhxhAO|0;n%19rSOt9hIidZpH3B9|$BCCsKUj|;Uwtw6 zBzPE_=_(MHJaT@({bCI zZ2mLNIRY#ZGRIDR3n5M(yB!JWriuW*2Z=(4!6?(Na#J3jgSk1X9OS44dH7L2SwCnS zk=5Syx_vhAt_CT#VDWopfH@dfsTPL7rw@gz+yd?*ogmOP@dsptxX5sKA+X4t==RqE zq?$&@TS<=z*-Kk4Y^U0AsZmg9yxXU1IP)%)=ZtqrbRmLwfyapyOH9ex zpJ^8IifH2u!`%UKS%{-3JykE})qfKw*vy|`xDExuW~c{GfilqI*>I7C&^jyS{)2-J zzsLvu*SeLXoMpJg?#takv3)cIREOVCso{S#q)B0zaJii@%dhGTkcQjxKi|Mu%vbU& zYa2j^Oej|Jbz;RwyiEr%>tw2@)_<9xcV4A}3y5KNl+{Va1l|W1@3*6Fo2_jiH8kx& zZc$kO)T=-NTYysD_QPvQfb(U9Vk*V1w^j$?fSAN%Gy7;EOv43f%zUMo9z%gk0^NkA z_bQyO4O9d;m)t~>0(wxS&w^eDQE#P?fpwx7WY|;;QQE)1|LmqMdH^r38t%zCL?-Az zP(6;ufsU&ZJ(IlNp)867igEG%*Yb8$}+U42xk-jJV zJG3WlaHNCc92N5@I1`S69XUZx7Y~&H_-i{bC4VBs?lMXW#Too|(bI>HeI1@5W(bOH zf?@Wkp4q~^+eX1cV@V;uK>jZp{TlKAs=^OqR z;^`Bo0w7!XUogUHZ&Jgl9Kmytb{rVDXAsO@dx9sMGXd^6>JofX`km}hjU~CL9=c<&^p^JWcSjRwhAB>~xp9Ea4z5j?1K#^u0+TQcp zDCQvZuX56hkyG%i@Kh2zA$rkiHX9&M^dN>I%`nVdHzWB0T&sm(sHa~)HzW>G{aAvq zoi%VUL(}g_)leC0v@EgIPdMAlKhLxkn(1}5$M)oXYdk&N3n}6g8zLJ3=`p}hI>tw* zZH|$wn&+Cx;##rE>0)&fzAi-b;KN@Q^x$O{fl)iqq(*Q6#M}&}%%ges{Knh+@!llS zQ@Wg6y4s zTu3Ob&bJTEzOiD1xXJx3dJ%LE;2pZ77Hl^xoxda(6^i8kZly0aRR8$&6W{k$`cDn! z;HQ1>Re7JaWT#J}9`}q<>K@#`^MSWzj_*Mtg&ig0w)GG7`q)zzwXriMXY;2lAAc-a zmLLeboVI$>H&%R#4GXX(J^^8Rq?qV$T!ttrvqCkwZPg!(B*h|4O2%YC@*TkhtfUlw z!qu;({dQeZX2#JMpNP^_5Py!ACa=_|Bf1q;47V{_4Gg9&4SybAkxA4dj*Ug;h9@%* zDs}2dwOHRuVOAx$oxbbIm~%z^(A`%ol1>hwo~$)p2-eWO0HY>uU?8|J(Jc6*{Q)0_ zcB)k{&`<5K_U`i}u)_$5KD^s@k4|-M{1rtQ0wn`7fs6bK586^+hvim3IB)ZrkA#GW z3`g23Ukff5wQvrcgGm%Kb~k;c4WxgJ5Wj5NAOEW|LJLTR_*&d0R}C7TCO!lj=muUg zMd^k1U=L{?Ugnj#^y&)x5qSpDvn)@Q-sl-Tjw;ACS%v>5N=t;Ff3Yu`4fWe*rk=cM zFN`@#;9s&TcMg&s@Sdr1J(pz_eREoWS8^dx^M}pl3riy%j2JMrkAB=Z{Kj!#A2=jy zzOSD^&izZ>A^74Gk48zA<^xVD=DnbCk3^<|hU-?<|)Ss94Y#3pmp0FNCDz9Z4x zv@pf-KU3kmZ$Gf#0vZ78TnBcV!rb(I`(Um~AaFemYz}RQ_QQGLJMWlQ7GA(*2m=Rj zv#m4<8V!nJ5{?|3u~6qsdKQR_^&&1N7^G}s0~5h>%lQ)>HaN~Q9tTve zOj&z9FUE9S zMls=3dW-)S6W;AiUlipa6><%JbF9MAgk7)#ag6ywA}GA_mJ%4(x(m1Ka1M4m%we7L zff+@&#czJqYUz&5%;V3b`9CiJn*w~v=kz|kGFo=zO@ekm z{^z^>@_~}sJq{QkYH@yrtliMhUU8tQPy6?huze^geRdD%*yU36Qoj*b_51cmgTIiX zN`>|Oe4%cug+{-)NuA1$J7K@3)P52_{(ZBd33`|94NbiEW>a8V$+kLzm5JHJjpj6H zcT~+}VX@(m1ZID$rX1;MeiEwhWv--J)mp)DM-l7r-9Y6RDj~iNB`-4IbX*;p0LgLAY&jiW&f#MTg2@GRU)m;(5CEnWwfdQ(vO$lafAmg||;J=58hMYT%)qA>jxX{Qy+ zrNO(5OE;8ZotWh%Vs_qjZKgDw%SyZoYxDrO$BRGl`S&VRl=6J8vJvV`blz1 zg$EFA!$kvi#57OH?|$cg@+H@Oy{K_S%b>7ei}R;R?SJ9dStfM~Yt{hxD|Oib#RkA( z2T@|pzlPjDG9IWc@S*1TZg^3%GW?JAjouOe^3CIso_lY+T5ctk6u~mZ+xA_>pZ0+o z+INJTsXvlDG9ZjrrN>T{t2`u@GuLAIRi!ACM*#FjxPT=&CYXEBiJp>RdJ?K|?VnjM z?z&AJc{rNzE~|AFZ{u^%N(%~Clpe00)asy% ziL_gs>Uw|*4Zwmo{NheQDp^f{63=NR(A`7y@-6*ggaE-2gma(k8j=@A%s8F9fhaR> z(AGV)Df%bF4mdlp0@HC<0OY+$b$Z9J zGERE8u`mog)k2a|q~+Gu%vd+H&;FW5kDbCc+jC17umZVho((Zno8#|&CbLK#dW-m* z-1#`cTD?JE&@P1!C^4!w7Oed`8Q)#0p4Fe%$Tj#C>Hr8jgOZx4Ck&6QL{B$#8m>0Kwt6IV#fdz4{=gM#8l8pK8DYF1$XAtaq>R!o z9fiz0GrZ7zykXEM_^s+ZnLtU%Ay2;KfTXt1);_9w$;xbxQ;=?;s@w%fXfOtcWnuXXg!-B>)h$-1Frvn?)TmVBs zz>I;&_&+B;djVHqbFXBk!;@YUQC|$_BHY5+S~;;N<)<0Z9~ws3>AJln6%(MWB(Fbx z0B5+`jVzws#Z!Ap5xzMtKP^czq@t=Jx{+AS<#EWyE`z)%TqFB{3WW&D5kO^0t?MY+ zX?&b;ZR;@g;v+#D>)C+gsFCa41u2VS@uC5&?n@p0O$f4JRKyI?a*NXn&4N|c(ANfj zFwPTL1b=fpSD?W!fclp?1ksj1px92cEw(O_f&&Br;^L|O%3K$-ji7KGqh~ugYTzai zZqZ*_5Wopue!&5ZI==C4UvQzjwdz=*d;p0~fniD3&a6)x{MUsxGBKGK%kP+VivrNU z7(6wp=)fXkUSfiC3RK7n$pB?}CT%2nLIjLhud8-$bABCzYR?X#J)g#ZE+i>g;&D5n zs$JLX0baBN*i#plig}@+0Qkc+?zftM)B$00R$o#&=sJTubs03-3+Xg~H_Fwl8;>Bk z9-mlu?rEu4i-#7Okm0VtM=BpqNOC_LcuA}1WHM#*+xiYIj|HDkB##aFEf=^OswZ0L zIDANkb6G3MW`978#3HoDPjypv<9baVtyB?9F0AF_HT}p*Z{T`H-G<6dDx-|o%gsh~ zZzX{3+matUa_E76cSWjHJgn1?IQSab-${B`xY4%5y35|-QYXI|B}-yk@f z=RK?0!N;`TWds;ulBdj2Mvs?wVi|CwLXQqoYlFDh)+}NzM(#W~TRGq@FO@Dgq$Jp$ z5K?Y93Q_zRoXDnl{r+{+!ms*8MZG4=MRYFr2RGuAyW5{wKjA;8QjTm2)uX<%4ppp^V+qxE^M? zCD>4U8u0S*Iw<5-A0`IXA9^GZ;(JIs3{<5zh+%4nDBn9Wy{3@~?&vyX42QM(K8)zs z19~{=r6EH)mc8eVd+k$SB)rR`ASq1Bz_%#MGX-l$kj!4DMNUEv^$f_1G+#~J4UI6~ zYa&zNhU2FKrgLxedW#HjdcGYyES2cahxq9{Lh5Pubj9BSR&@lCE?_-fL%`eh$ya*= z49#vPc6S@dv`um%o+xacdwGlzRV+7kA4XJN`udI8pZy6%MWjU?cjJP@DZMt^o{QNZ zf8aNzN6Sg;e@gfzav=&kf4vt6x|j;>(;7>v4C)A$zE(yr0|}Iku1ni$QjVlOfF!l?tuaCDJ&G(+QKP$>67#2MU|UTB(Fb%M&2KAtzQ*|;p) ztBR}gg0w`i>AeA~a{#nmM`bKPk|AAJkk{ZJ-6P-)IJ}%Z`3Q_XQPi5Ku2#nXepTig z*QenCEJx-sD<>^;8HhZnSp5<2_H~+?DGNZibxx}AMpwZ_DnUS0vd3Zmqnkhk+}6~} zJLCeu&wh`Qp_hG7i0G3tBAS?eij#VL(Z%@Bwe1~ds`yfT=efD1&3~8Fiu1E!!@=X0 zKZIBHo@LpsRtLZtgnRIPdw_F!6zbF#Ecko?GV~#A%jkV??ko8$P(S72bI>QUVo;K+ zs+F}Ns&$lHvgbuMyUi2z`ol!`kt6j03Sa_+p1@Xb6#pty!|=&TM|P`nL8@Sd?7(}d zMmaJ5YUz}M-59Z?y8kBG04>=lD%s}%dCu}M;%Onk1zvkGejD<2(Rwkmg2G*W~b~~@p0{1-yv4bBKq7yMkb;@-BrXV(sl(E#%BLn~^coNx< zmrE5Q)gy=!l!bOJ@ynrPxsHIkxf$8IYL){iL5*Ov3KZ3rtDU?%EATr?Sm_}){U&NL z<(O0DGG96axk*zhc5EU*G{$a(!q6F1OOl$UU%LKzvp~J;Dtj|B4-$NWW*>q~cB&R} z;y7MN_&&8P3pq(wA*nFcncEjX!T2ItO44#Wane7O7zg35T`c0P9}s&}#%{MUO~PBo zp{r-_9Lzs7lqw0hn^2?uok70VTYwYaa7)4vXlR;v`_jDy;OHcreAZFy1b!F86}C zHVsZd1L;B**~1|S!~r0lmh>~PE{lzq;@?~M2Brx$ss-7AWsf5WpL~lMc@r%QQFkLo zK?)m)DQ{$(SmXjOMUj@`hOl7<1E5H+E^VysTGqPH7UM~{iRL%hkRtf=PB(vG)LBdL z$mHiQbK`A7{Ad+1nM980o3G3`3(vnYe=nLh0%1uW7wC}#-liPs2X)1HE3yOJLRZDgN2LEpuOafEi?^Eof?L!PbeL^!uEgjgh3N&P|Qgq$rw`b029dY(G=62oQ;sfFLyh~Pg$X9jh)lq$mG&UI0pvu{oWf{B zi1+OoEpl`3n_$7TFm^}3&7`@=EtAfFblx?3K6bG%Lhtpgum-jIjYtAI9w=PYDql#v zZfzVeuyGN&Oo8ue^1@ySqnRP^UB;@F6&_G0-4`m+rIy67OB(y%IfSs4Ja)Vwjf4`Q zl>ysHH=6S(835b7SO1J z0CZ@_Lv6($1{eeE6@8L=S`!oMzw2KNG?EWAZfJ(epo#v|?4FtoU;fk&vGV@4Q;FQv zIQ(q}9KMr9YXdt|5=z#l&hKThTZ$w5)!YeQnf7*gl1n}TzDwH2g6k9fb`nKDCXRZBb56 z;&8xyd&(fsYdv?oY^YDtT=XIaKkX=-@(%SdfDzFtPq4~9(%@!_GUmx{%63@VscC>C zsHZlOr;~H z|2^~jpj?i?29rBF5tB?>h3dW-6>C83b0#RbB8ys&graPduQnWKP;LWQVL@J+hs~E z&tGo*+~0S^rntWihhtx0nH{JWq0rWkNi>$aH##9ia_k}P?&SHB0$C0TV0>3VCT^RkS4)Ms<_nZiCWG5@5uQt4LtKmjTUGAigFPtKZjC6$|1UPxGI>5reeSvE`rGDI#dg+K+LdMoa+FG^Rh90? zKBct#d3Uq4G4p#gq2MI8sZ7hun`*#Q!Jz9qlln(76*F2R^UNh|Z#fEHgq(;c0ga zJ3s(&E%>vAoI6|Wj$3Aap^Koe4ti~3J@4Wlw6l&6_^vFJ@{UMbt!XTe}}`o`llXb0iTa z9;Wp2(f*Swh{-EJ$>)#}xnU7 z-YmtOp1N>3yq;`$Lgk8#$kN7}uwP@)#@O*W{9R9hVUF(rh!G=k5ekKHTpRy8D>PT* z1{afxcq9UI)n1ZA3+j@7WD1r&r}-tHez8ZlTCoAbwI;azD5ov_@P}shYoeXcMZll0 zEbr%D-XL!C5J7K<%@YK70Hv7I()~!@fF6G*d(T%Td2o(OgV(sc-C71@O0$gEx;F(% z2dmvBm8LX5qicKFxT&y{*u58`cHm|ifB?iWl`%&Y_|^WW`J5z_0U@;Q?@H(iz((y= zG%%2h9(24m;qwu`?w2KXq5r<877i-dvY|7B^syg8b{*G=Pww!fbhP@v_wm}<-ppt< zK$Oyz_u8C)s9qdn(-sUz0i)6(Wn1EFvmw zE5^M?I3gQ{0W+_aGT^hKU}za$jO97lMvO_-dIfNqm0@iE$yR7Jv5=1$3{J4uDRk6H za!d$s?K}5vc)uWg`=T&#&%n@=_CbFzVwKr+(JSC8@Or~l5)_6>{3gs9R=*@sAY3Zl z6e-ee{GsXH_;_+2m zZnIFcj3##$C>=(+buH;@Qhckd^lTX-x?8j~jbP`M9`E8mM%xd^22}eZNT|0j8|d)g zSQ<`>9r@(`g+7+vvFlAnXBs+@OOVQ{l7bm8jJAs{=5-Cz4PU&|Bd)!@cq-zV z&9WMFBX1cwGiQLkTM9e_D>dpV7(6O*cn7%&pno&o#{n>#{uaI`hKY+OT=GwjLIn%w z-@JRoq$@)%CNp8^3dOBb^G={^dLY=|Ne5FuC@(!HqC20oQl{mK6Ue`++4~pcHJlpt z&@cM=D?mz*T@T~^Gc#z9pJP7qQ^cp%cuc1ZEsi$fq0lrt1CqV;VPLY+;f|s4Xl9q3|18co5Wdvn_S0a^_5MektB- zwih=X8rnWW76jQewvJL21h&>NzZ31jh@QV60pi%>N8kT;1ia+8slZCC8@2p?e_HnS z-ZPly(9C}==fdSVq2CfKH8pGuYi=XSYP#VELm`NTQn+|)g8qTpw9u}JLPAMz^{97e z3*QF08)-+wcaQEXUds2&4VinS*Ph(ZJOH_>V;+Tx%{-qJws{16Ili|UtnmumuW>MV z_-u_HtsqDK{caIT$YL-P>O@s`Rn)RU5tAQlpZ_*Gc>LpFu>9E3>KEzjAqgYdzysWm zsYJik!Ol_2rC-VjfR-={wTbg$py6pW^0*(`B9eFI`U6gQY<&#~`!;nw-#A(R+>Hq@ zMbWqm!gr(f=ID1x#M;DPF!Q&&!&363V?8I+ndZCH4XuyuzJ^9QRdprYMdj##?+!mem^22ADF@4*ez>YTyZ*nqDqe;~v>%Xb9lf zT)8o6y#fs%_1Y|K&)opMO~-fBV8qZ+itgfvRonatWQy0?jiu-UTusZxE|_}fEFem% zRug`T$5ctUpd;rCCa&X4tO1OFz9@tnx%0GTF{V?J$!#@SYGIDrNwZ^70S-e9&YM%k zQC-Hy4eMXkKC8m$GBgQn`?~1%5t$!UlLd_Gj=Z!`_jd^W$)pVkxH(bFraU8AGPEc3 z5IIo6k-q#gQrYNC%*X1%xvQ1I~oMX6jyS=by2h~dqR}lIU1%nA4 z$2*UNfe7c1Lyn1tIt&I$c{;eAR14=H-rpuDo7WH3NgR8Iv#9m6lm6w@<4YEsB&r{; z*VuhJVOiK@4a6C)Q{ebPOKT}0nU|eG=$$r)nLz`aN#WXK3Do3c zrwLmT$*(MEeqOFGPE^Qdb9ESvkU|Cs|I|f;k9kP^R0UEtq7A5KVg}`dNZK-h&JD_B z$8teKmNWlz%MGZLpW{1a{(mgMJKIAF94oc*O#lx#ks!&QVHbAJjxL__b^b@7T;3nB z!#@40-k41aKh*o}_WE3{IrOn4&Ls_j%r6|&>|o(Cjtj0gY0v%*M$UPpyuL9?48l zc0b*-9<2}a=^BMP3BeF&AnANLB6E)&sMCA&t?%mHO!8K`fNDp8#)n-*<)7Bu8^bKt z7aq4jz1+pHnBe)T$|!QQ1K$ru`e9hC+&e=2d{&bKa}Vtcsc#!ZL4l6eajzQ(K%X`RyX*nECg?FAiuz~f4G zixG5B3{tr2@L#bi$OX(6zhh@2U&0d8vi-E9UPgIG1Gd!TErXSq zhsDrv*4|XlFY*&Vg69kF)9v<{mF{<*AePbWq__8%Ll}AC?PP|4*@;(@11fpz^^VHR zSmkLiB?)mH?GQ7(Fp-)u5WquGTKNBH2Pd~gjx@{hEjkcFJIs6B*tX+D&9I{Laf)pi z?>*1IFe+2jdPZNdy1pOo1?*?@v#v2DPn;32HJj}=8q+{b-wY>^lWA3(?_!uugBd5v2j|q|^f78*oH!uhy z+@eLRQobaUj!RN;qS&GIQ^^FJA-qSdoO#t0s2x}*`PZ(Ui105J9FEFh;;{PN2l3(9 z1SnztD>;5_tMtFv$B*3nXAdQ3ejC^bU)mf+I2wP(nKW=#^Ng~Wd)*G@?nHSnCDK_V z5?XZ&Bos9O-NQCY*m8pM#o;pchX?ex_a|P@0WKJn!tXS~+84|U-;Oibb3|Dd zlYw9OVd9SS4^@6;PkUCDGiVbD;Nl-+c3K#BeN^%W1wx2d6{qTx{)>IRr&krgGhypS z60%c;ht40t-x<#|m{HL%lC?WjeML*w(yFD=Y9i4bTVpv-#LxV@Rh}W6`pX7GNZ%@@ zXFsw(2x}lA;ikW=WmNSRW~RgZcM(y%@-ryw_CVml+6zimcu^eZg(xiqVHV%o)s@pXrXbDCwOlwx zY|WXEE!xo6Xpi*F>u6$OyK)*qi?OB)2vLN z4L5mF8I_{Ty0h=wWMOoN9C>c5e4tx=zb`0f&5D1Y4O?Rg_ITZJ?>^Dfx#VutKqBR=}99oIt@m^x!uQI@oA(HKXzE``di=Yc{PflO; zhkgww9t|59+uaxffJ4xsR-gX((WIe7Oci{A9-C-!&dduZ!)J@|@?(6+GNT7M(9TM2 z2!8MSX)+Xm7*@ZUe1wlm{83WK6Nm29R7)`Uel)T}jI1At^km**Y3# zu9#EN(2}(tpANl_GlLH=y#~M6E7-lcx$tzz5pJ0%y}2SO!C(ZN--Hishy6}||=i}myA>|4}E(^D{Qi6|P-A>k{`3_tdi)B$oFXL$khOK5=`zpwIak6ADM0WlEV`Lixztyd~D2iAzXdBHE{ z!!Z!=exe18G&GR#7)A3kGjeol-Knqv#u?DqtC+e?uT1u)KOA^%CJ8WW0}_X8!CxrW z!$*Hppo0RdW9=$+sgWq)!O}Rt(|#s2Sfaos!@nckX5B7eDvOR+T+$abVm&RYW*5BK1zmCAlF0*7DeP;vqn73 zP^>zxG2fkF`S?%2X*iM85+=SpdSY3DrSq= zH1(!sMn4CRq2U)|Xk~Q14ZWUFb8#OvNek%Hr`Xlx&~5%CI!ELQf4CzQ3a@A8y$xDb zC6T!$V}!~PdDQ}5y7EqQ3PChlR|C1?WXJ*Z<#eateQ~4o&|{vyFG0)nB9S}Fy(4^S z{lc)IASXotth&}P_30f(SRa!OXso$RH6$pJQJ($Roz>|6d+U#E)0QO{1gn2T2Pi6!rR~{%|QJDss!*l}W zUJfZ$okR_*xKQE&O#!90beCVjZCpd?S9P6#&g-CMBUc44ZlmQV|D90?bsu#3eJaq$ zJXO|CJ*MTi89j{=e?k59jn@FOPa?;&PtFJMA^W8x3E{KcO*FVrV`jR3VLNMD6}(DI z!nwIfE`fu?=Y{CzyCmy3j{Net$MNT9wRemN)=xomoqOliE|b^h%`ZQ|_{4XA-&pLw z{QmF3%%9KiDU2DO3^a8I7%$6_vlXF0<6aZ$R06B~Lc0*W{=kH}fq^!1vXo8`ZO{oi z#@4HL(16>kZLB<$4wj`^lJwW_v5;@v+(m#ME&&QGGmZG!hl4_ws}Dk>FIYW_lF! zY1}U!kS_+xyT{UjT$g1+)w$i>=7>j1>UNGuX`@?c-;%wZO*>3W)vbj?H@j0e9Cnjx zu5*d3Op_eSLjf~$jPyadg+a-@t)SUA9-I%IGbqpliAdU}l|gFo!kKOT^vv;vXB4=C zgmw5Jd(C5auhL;R(Tjj`cWP3=km_X|MSU+koa$>v4qtgQ10II|7Ly1582nK18?jD+ zpEvGphAU?sfS%PlljC8v`Lmg+93$GFK-wm{F*#2bcCWM!bmpuOamr1j&i)(hllMpl z6ik=8aDw#tIaXd8`hHt+2xNJuH3}A{F>Y^yL63;31nMm(XYTUwALp|&jlF%KDK+_B6K0q z?I6L|Gn~I;EX4Qz!P;$?0w&!dR-vtHru0l~5!JE)o!{{G16)k55#C=Em zvNV+pqisu1eh-Wiw~!Z!8AXSQ(#S_TI5Za-;b4(F>&6|j8=lfMcF;0fUVajcF|&r1 zV2G;clsi&|y2q@@fFp`|*dpp^34uJA0(rK?x3IVsehK5V@Wgl&$5!`)K7^W$<~YqR zKl54Rxx?L(<gXQrHzNQL0T@*A!R7xY|ZSbz(bA?hSK>WN2ZFJ?CO|K zuQ>ik55*SLC!k8=`u{)k>_8i|^RkR==$Kye4pxFsGsW$vShey#X^RU zUumXlOHN+}+k8D+;cOtD>-f^2C3YXIbU7J71QVU_kKnX~l-SHA1?4sP27Q9GWHM~w zFyPC4{V6?S7wcF4aQW7JSa7dn$Ei|Lr6ak#IAzKmQhWi0ttWe*|L^CYLUW zpC6O!_rv=6U7NyZ#l?JQRrhR3a?e>{{@(Ld->>(7FYicjEySD~VEAvgB#;`4g`R2f zqvseW9ER9ZoU5kZ)2@EFsL0nY<<6=;Err^i&|^@J!)ve3za6lp%WeD70h?8GT|1(a zId19^1ft%|>bK1b5?bLx<#dF4&yn)4ng8LDgUOloF9(4H%qbuF=IvFVs@kCF6nUnJ zD?i^eOH16GGIn_&n6kw)SaF`w4do?uyJ}!0L8bF2kRfcMb0mVarw$V$vqFxTWJL!v zap?=!OGM!T{8}#Mt8QKQ3@O-+R`&Ub^3@>esl63Je!vaLL{Dfv%zq%X)W7NK{U;RI z{bRh5DMvKhheHWg6@J)w#ZQ`_L8!{ZKbjUHGJh{4ItGPo!!HyA;A63R%jb{J$IeWj zSMZW7q|x=Fv-gKJGu@O(PRYcf20xT&5lMWYm_oLW#gSUX>*ihFT4t}In^m;ZKp*ew~}*NjL-t~0?L?k69PmZ7`+&vz*x5kYS; z@S^aH|0*Wtm1OSkt`t`-T4yjd)>{6r|6~99R!Ht0D!FRKiVh+pq>wX6{F!k!NprM< z5P+~qgtx#SnR$4>?5uGGcNV?xq@@OL32hQNP%AN>kQMU=;ZE5XlAQ#|+7HgeBImyz$WQx|;PyA2*Cw|H?vg@miY@L8d=nY3>)1vgOWt~!Ix zf6H0rn&6*Z=f0w+0r#I$&%|5;CK~XO&R?YVZdRWYx5K5~{Npl$4b597)q)`9nX6Cs zjAvE{L!_w$tt9(s*b%{nm=W&h0RPbawm0q}8qaiVZcm-t@`sN5FvW9a5&* zUkK5O4cZNr(MX%(Nejq|a@MSWf@G3&+$DiRioz9^lyMx&x3eZ|3DZ2PT1iaSV`Em%Fr3 z`7@Flk=S@+;8Rcc-D?^c)Eir)Ey~`4K{>Fb16Y_j_sh}hq6{tIfr0`&+JF&p;p0Nc z1x@-<-RFy-!Op&h^1@z9=s?7(8aBhGrt9&!+P)C3=f;?t$#&k^9S(fesP2uK(6;}z z^&Rz2pC~x8{P=GFjI7ATQY!kuNI{w5AD=83bx7?3P@XN!I)TCDHbrA~0k(ANO+LMD zS-Ne41*P1UQs75D$?BF+t7G7iK-ow`2alf}6?TYX8Q20Wq#=MkSjI&whdR!JX2)4Q>Sb?%R=tE%V1YriDPf{gdp!a`s$U11JSC@=N91-L<{1E~uQ$$|d#2*W|53+s2P>al?g&6TwQ| z`F)^n?l9jh5-?^{v-8BEy5Nd2IV7r{5qIa|zc!EjtXn#$tGHs}=NpYOWZ;vGE&S`_ zITC4=0A92@Z#&wI(TN^vk6RpU?9T)yO;(^`OEJ%)xt>b_?n^+R0D#!(SG`l(NTkq) zG-KhrZ-oT2dB)pEU2_T*CJhIv3lmFxQh(B*<_qL!$%MU9M%a;3 zTT@C4rH)q%+tNhFp+4yyep7Ia3@1ettA`SUIpARn&s!Zl-jUhH%-93GJO%X&<-3e|6UHL@5LLvD)a)%L3!}f;(uR z63sj?g~)XgM7vGuCI&CrP?OBtcbytH_fRmgjrT&udx2&oH?my34F=Ye9<^leL9&K zzIvh(y13DyOFT@RLm&Kgxk>bGt-XM+qe|qryx@DG?x2$Qh*qbQn@QrRh_zx z?jc_IJS2?^BXPCj>Qsk>8{%J^ns!`8YGG8s?tcf=h_>Co4?X(*KA6}&yk5R^u)pqW zP#tt(EPXzY5)l&bx_^~3zi;gCr%}^1hnr9Dp1op6w`6;Ou|>$xb{M_IuHDLu5wh@H z*9_HJ;v+%ysruMPWShA4=BWV!1b5ReQ&VJOBTK!L<3pE8#o!tf5m3*na_%ZP0SprK z0r>X&bDB2LtG09(D`XT?^$l4 zl9D!Up{c_{-}}+qLcwHCV7|>g?bOVokWgU#+;{Ob3N$oK)Sy8t&Qb5R%|E08hkz9$ z@@+_T*-2)O{j$EFtGUFAf^G(B^;Eu1f+ZP6R8{nkiHA{Vk&Ht$m=e*uW5k~!L}d7y z5aQ!}ed*1t`}h4Fnl`6C8oqWPmZX@nAnb@4)?Qn4jb^+gtu;2IrvABelMdA~|GtTO zuhlP!cZ>pr+Zm5~f63TqnTMKPr8BYb{KWe&xVSAT3XX5S_2+=!+xgy--B`+s%uSy_ zUDLB3^vF}75LBis*k+)t8d{u7O?_gk+?{*UXMJD!JKu9b;3TeVr%8i2`jPx?2(H17 zj{In$j&#i8xTX!*0k!`;mdhnb#mL)R6<0(g#D5*US9+onY`_z`Y%hPbS+_s?@F1#G z_J}!yJIOy7AG`J+UFf@7m$QKF=7Ryv32qxslDw9CdDh#fx65ccVnHh-E+*CBy5DT2 zgHEsP|30ziw>2F3gj;P_3O$VJL!9`+vC$^CE~tt6xuPEHABY7mCEBbvF9zkgv-W1S z$kE3rIgkMa3CrhAfEE90P1tz-!8T{$4jAuA8qH^0?aA(E15R>c+TD>Qzz~t1k@ue# zzwnwq1jua)CT7kkXpsvZDk49%$FHFhwt`(+U~E)P`?tv4fNiV_uo(DLjAqZ zMc?iKI}O!X!d`#Hj!XN4PeHl$leuWwiE5z1oJ7BP%)`m+W>mQ%WGZKK9!Jlpg_e3$ z&eZmo?{q!Z={U?)I{%U4joWR{wYYl=-%xI~ruEJs<3YvEcfq80{uK4bU+8*|A)mx} zPVz8<4M_R$tP$i4M@vGGM+C_8 zp*^Vrby>7oU?-YOZUcrt2_^@M$m`0itRY;80oc-hQNzJ(*DpsDYw%q9Mn~#~=r76<#dC7SxK~wr{Dco&>t#PXEJ#+`ns@ajzD>^?rhzE?P z<11Z5Jv2zsq>!zKbjBfgZ+dk0<=xRj{qcFUrxLGW#m!;Qd$QdC z@-M{?QcHXp8Sk!(1Mlqj9$K~PETA&lrs|-sVW5}U`cK+p{jxxd$pJ$9a z`(t=XdXaLvR9rXVGtd34g7k+c-{Knq?Fa|T^inIAW&G!roiqx<8BfrH`JZhSNF0V> zK7aln@$`g%z0;OP>fn=n!BQK6ezjXXdEMQ37FNgaYWQC!fshl$?-$bUD}al3keMO8c1Z+ehr3qTNe%571?{44_*QR> zSB2|}lTa~3@REGjx5sx=!2c+Ik-Cx20|BZjC%&qa}SN!t2s0&T%q)*w$yB=-La+BB)vbFgtx_ zo~1<8MauqC)Sp{s5#K_H$0?c#fn9E4kl;U`(_bZCKCMoVXD0RE^!?Ql|BnS=!7bIG z@GE;UF4djClwdmHTaOJNr{CitwUeE!O}Uzx9}YtzgHxySrdPeh9r7%DN#x$UVy-t=rtC=! zf)v^7=#}|bn(f=e_ZJTXmYnpT?Y$67H90pT)E>}-QE>>|KtN2~DGyQ3QbL;X{5P8< zxJQj*0z*Iu>t{RaH~=S5yk}m%=xlUYR&kB^#z)6GZNRa5W%;1kd-S7K;%|ErWWx$X z(LX(hkGyLlm`)G|TV?u-XpzB7Ys~wKDDQ&M^KMQ1=i4!R@GPYxHxZujyVb$HGyhl# z{kmCOk;gB(W!}|u2UH6e5{w4M__ut-$OdG{ULWjyr|R6uhU{Zkc%=V}AjkTSaH`-L zi306*x_mucmNQ-C#Gxf<*mBYG_Ra3ZpiD*^W$*O1D1NGJFQm-($~!{m?Qe2>v1ge+ zIvs+IQuHQPUJ|XOZ0pmq%ZdyUL3GOTy^d&K{nSfxw+F1mf;OMxVb*JLO*hS=E)5 z+Tv6*S{+icMwRH#Rr7GA%dbZ$WH_7+56{+nipof1S51S(1(J75mZUpdzU3W;;j;BW?NDmdpfMlZ5Im+u%;;J-_QwC* z@rB1IUuco-(eJFu(g<&!?;Fz7nEQS%{49;E)I;&C$XXL5D@Wt@P2jOm*x;uD&}XeO+pNW)LD_^64EOezmZXjFV6hcP?wvsa z`Wd2pw94C4*Gv#_<`H&~wjZ?<9@T#CW}?Nn=;D%HRciN1Bul|F*2aaG)R#7eM&g-d z;SN-jmcSRh-{$my0@<)cmoJ%r#1{gJXsvQBWzkkTOZ->t*as=lQr&Y~a+|_}GBS&x z-jL801R7OH=<#X|Zp%+5fX<-dPJk($;B{OMH&DUnGkg_vz~F7S$oNlXJNatKuTJuT*73;k%9@Fi3{sIp}8V>a(zb!91I zv3y1aMRE_YD(EMB>QRH&JIflAqhWEi*F2D9>I(l{YL?(%v7d_ZhnU$wwza%-&of1a zSVLIy5oWR#Mjx~KLJgLK!lQ5j_;Q!Y)chR^%>F*AesxvMR`;W==Rc?IgLQ*yr+G@E zoPeF8c*`|k$mm||HJnVIXVzetdZV9CEA#tNb=}W*j}p}Zh1grK*IQ3M$_rZHHLRK} zF+%T`CeFbDd^sn;R-w7~3ip{WH_3A#Saqvqg(v;&X8RZq?d4I%Wq$SOS`+$0PdznK zz4N9sbvf&%TI%ijj^APqNmW-$@Gu}m5Z_?M&Box~y0&+^@1d$2QH}D>z2C$hJjMM< zhNuc*XsxK#44u}C_in^K8xgn|mTmRaJuWL0p8rVol=(fh6uiTNno+#AlL{=w&TxQa zJUAQy(_W|X1aYP3`dIrsRcLN^7GSwHIK=}XMd^{&91_-9(cAjEaNhL}-+y z{-VBtHn5eKwlD#*k)_oKlcp-c#Q-qsT)dUdTWrloH!Cg(76c0(MCx)`PkFO?YE9tm zS@*Ib(F5N9B%nf;Km2?9x`175a?I1?1{Oa9gS$#NU<&QTpCzPk0m{S8;JGwg-dEn~ z-1g7cs)>1vbt1X<$_s&V)Nl2GQ{}E$^bZ0TVXCp9TK+wvaSLGOz&v$r zGxIU^Y2IPRy>$a9Q6sux`r<8uvPaADcfa%=4S!s?Kid?=y~aw6TsZEZ+#lOUf^Pn1 zb~+D@qHoV27a^H}*PLY)*Ckgwy z9@iR|@}8*x^X1fBP0WLm%HfsV1eK~7Tc7_ovalXJNfPt88yqCK2^69D254M10jZ>W z!Y2F3cXMkUc7J`H7&MU_%q>0F$hsyXZNv)>l5XGuSr>Q=^)`$x+HJlY{VHUZx;K^= z-*6~R3+wHSZ4NI~X;*TnPx~Z#X7ILhb*|ru?R$|L; zUIc5cINklba{ZW5pG@US(pRgmLONOKWH-jQ+|cFW4!yKi>5%Gfn8F>`KKk1H}v-qEe--_D1NsTd>W z{`)IN-n&XGyr#`AW&tyv=(oPp8;5cFbDg)(q?36eZoN&DB`X{kODGj!HF31`t7V$m zzrI&()V^{3wFHj8o<*fpWm5S)XCE|9U1tb7cs*)m{__?0U;W_|MaWTW&Ba`$cVJfq z_WPZ`czw&080^0SO6*l{ApxiiJl{=y_!lEOF!eM(lO4KBmCzTfDwLgQ&GjSTA{r2w zgIDTVcg(yAk=nq=o^a7_{6P=*>3vZ;@V_2c4!J}@t_R^)|767^R|x{uYB<$G4b<-^ zN}DC+JmKeD5R3msURBI7PERg zLpKA1;#P4R?zBl}n_pHO^Wq!?qF^a%m2DaaqH+g~H19h2=VUPkHKJmTW@N#`ukfu$ zT|-`D_RP{QGbv#S6RCT;SSdz^|X^@-KXmPW$hKBH{bVim6s1G{12z} zq{|+K1HXeInzZ_znISpcPi8!KeJ0mos_8n)68Vg=t#>b^56w->vzHj{Uwd_Uw14Pe z**4^Bi>l3%5?OZ&VOG6OY5Q@?tA~%YQ!q3i1_O|phPERCTSZqj)+g>!Hn;Xku2{Ff z;vpQI<~MtG%SXHD!0d~5I#b(t0ALluYLhR%Xv`&3(eO>mODTyz5KM z!O*`*Y5$BO6W4dW?dd^@vYQx+7 zE`P}UlvKRo#U75VTl(&KRkVyre1|ot`{PeClp(=Q{!h1#%Gd_^sI8Q|yLdDvSlsOt zUN~{=5bGM{8ZF#j!s?>7v8|x`=B&qKg9M#Cm10*>-NK%k;tEmiW%T!4-?LS3ouf2) zd$MjqVA4j$+{%Sh3k|WLCrzjFz{ZfNux&6hJX3x7~u!Ut;G`UYZs;`Lq$?>51T^$f2or3K2 z^?5^i^oe!l?$_Y)*ooE!Q}eCIH+H>2Hrz|w$iAaRnK``!hk%Ev-=E{Sxj5ov6foQ5 z4rQpnnm;RPodQ5OHhSZQ3r(eY;ca`ZIX5gh$pS&wpKeF#;8z(*O& zhw03DCWgUG96Y$+Zrxn|gYuq=b~h=WDnP$mt5NK;%J$tQ(e{(_V^`O}PMtg1(_xgR z6O9F^Ccb2&nj4n>j?0N2Cs zVrmLp=V)Qm_qY_$iLYdgNypv1IBOHl&s8~1$E`Z{N|w2?RRDqRj3JY$gh6Jk!10yr zZ3+;xW15`wwRh;gN@IlJP^&%|4}g@FS;dy2bX5!3u%WGx1*z6}LOBxo_f9XhM*~T2 zTSkUxZ;^~GnxhmIGZ#g1Lq8>I?2I^E8fGPvwBByKB$ItIL&v-mCOa$!#zyVr03qtQ zToxV@?EhRD=_>14xr*eUvn#tZU=?zK2wq$612LDDgt{49ecrwmfOhH5hCs zhS*JFR~fp%IVPoj@cWj`<6zgtdsu&}KT?9de%y>c;Pl^~yB`{HEdDoZfwJdRTIOt- z<{c+w5VSzg`oH!f#Jm3#Cu3Dp$qVrUfV`~!)6T%No!-skyTFY=$Tez1&Q7)CR2Cz@ z1rMD6$T-iA4J~-@}_8c7u^mI-8+-2w7&Lk zB1hud+-jZ;?>~NVdmK{?b|>uK$#?27hKbE5{ji<)C<;=6`W<)Y zRGx-}KIEGHYZHyo=ZVoMJIh%o}ZiCzF( zNNnoZKk!YoI<0Vy_R+PTLnZ^Qc-`OaCCw)$U0a$S-1X9JYE)8P9g>-GuV5SUPyVWL zULB)oH~ULy`2$-Fn{Pg{U{*KPjE_dCeKfFf(rVC@`m6u{eWvNM5}mFbe|Fl`*NY3< zTR1tsgomhhcm*xbIy|Q6Ubs>JyNQ26Aa~-lBEz=%UeWTo@-h5s2s^qQi0Jp9LUoTy zw(lP}&%7(IPkJ}ycrg2CscV*=yUT)#Q33FXpS+1MG_e0pLFL%pD(MmbuW#9DV`{ND z4b_QXO*jW@THcw?cg*LO*G?>41dd2zGhd)bN}D#4e=*)IOQWREf=6SwuHca0$7$bh zy*z404D4}%CPwi2UG)jYb;IW#0H^!pb9$B4qAB#R?!I)^e9%Xtq79$?BK#ODhs8-i z&|YzTX)@%#CRN^idS=i1AV~=-EJRl|vsV~YBeLU})Mh0dvj=;Id%20v|BPL(f(oPnR^itw43~}K zyHcO=p2WHPJ2*s$QC9%7G8&|T+I!fWg1nzjR~~57wK6g>E1^f(>a|$tJ1-75wk0cC zQA~${QdW%UizW?*B=Kk6)qcwz&lzK)PD@K68iGL?%!CZ7RSN1GA{9x)3&7z+KQrT^ z{2Cm)B~tA&^e>F!#YrLBy?Jc@Z6({ykvw5(a9|v(n7Dc26U_1^em1K*O4cr^RQ7Oh z#kp67Bf?uvaty`}_=yyN4mLA5Z(En`of}iMAKhIlRr-H7IiB+^IJlHI@%f;fSfMb{ z;_cRPQ%Rv_qtl8u3OYAMcSR5zS38#RzE04Sl{X_GSQR?-FJ&4#E-I*jfc;yRd*$}9W>$zx1_T%j9+2)uz!^oAFi6|F4p@o47VsU zjaRbMiGZd>hu-%kBv1DdHpbYFZR$}O2?~o`y#rOjZARLVl5LJsUx}}-pGCgAcwEnT ziV)}^JOa}n(fKs8YU_XfoE2t?`nCVS=NzxvYLw^CALl+&n@KgTA?hXx#uf4m?41p~ zEK_A19bk$`|M=ZS$}4o~4vAxaHIJIad53xHV*#t(A4q%agVa9&00UU5?ojLNiZh;1 z;I)pQxihDmC-pkM?{dpvX3RqhYbON94}@p(g;v_pK{K6rH`gn(Na1&Uj;_2=j2ix! zq;O>9pJV=)-X(&@{Qlappc8aryU@ zGbrg{(n{=_)=~Mo>aDHFS9QOK4Xpw_zt!fa4A1S%DTzW?TIr^Ia8`oQlH;A8-24X) zI^5b}Yg2im=j#Sg~qu z_iiXDOxx;F#;059g%at%0*K1Sm0MA4tXHqc>F13440mOnZ^zjvM-3A@TS8o2O4u>S8b`)^?_pM zZz$v^mz{{JauiSp@U}8$Yp%QL)tP$&pwtO>`u2Eqh_t!0``RvJ`Rgd-pDi1;68QDT z%%rc5L`Sbx&%%#=!)+BZWGj5TF2v_=B{eWFTs9OQh14PoS)&+O!Z>hoa+!Yjjo|J1pdV=ZvL?8zH^Y06zIIip& z{cb$86Cf+!X(Ch(%p(9k1_;$<&HBi;y?8QR`S1xCv2RTuFBJ#~hTj@XwVfB=*0~E;(`RgC4p#2|~t%S&;2?bYnIB-4QgD>Ya5O5pH`xuU~W{l7+;*8B~)*%4bdZC{H zXcUK#rFl**D(B%a;rY~Et{d9_hA}5vFpslak&Lvgy3va-(D*ki1D)37ZU#lC6b6QCor%rx5~ErezRlGUH$gq7*Ts(L~|zi)aF_L9M>@<_#R8- zsVJt~sdX9*6XrQ=*xpDXQMa22_-Y~po%~-5zVH~Ut#)$YU@c)Co^u{8WHb>g7r4T; z12e!#`Zzxr-QVs}g9lPCw4|W$rceS|CYMxjCYK(>P-W-m{eyIBAmTM;#3KG<(v##Z zqIZXMmf^!-h^m@E2f4mR`Q?vL^D->X&qf%gNWe3fDvt^nz`}H|!?pkPBr1d{0jZkt zmOcub<-#%WQQ7!lEsgwcl8jE#PU4p|PoXOjT36ly%1yHDFS3hNiEWFPCO!i}@+Cc5~;|H)PB)vCX$Ts2byK}#?dNaaH zPi7!W*K^lfAn1&^X}8u~zXbA`p( zZH(6Q*pg3oo_>%CIwTLsdVe(IZLqqYjJx*fV-W$+^Z_e3q~B)Q?N<=~V=(O`O=O|H zSBIKC19x*Iv7f*-FyHUe7kfu?+34bdL%MXhb%S9&=`(a z)r+Y95N6}!8-I7pdlHsuaZRE!E%MmmN$~n^ zV;k;EH31=SoWDk&bd97iNAWylEoP0xGL2MmIR=u!((U^mvt2x2)Yl}^KLG}lZlw4* zUN96UIe1gt8k+eAacBKeuKswod7V=18d9M~`U$2tVU~HG+Dm?SZ)Yj_81l788zHL} zPB?;k4)_vkBp|p4a7@D6l9JPZpkhmD?>WEfKChk2sIZP?K3NiqK>x;sTZtiE5r-PS znL4zJu4H*JM#U$o{P*d~ z@YoWI!h+I|#*vxD3=h;tfNMVQJu;h=nAK>10hYUGL@Mdz4t?#i$FWg z>tf>5^I3~!e)=YpGX7ne1etH10wCuL%kJLYo5@q`RCTbHP9}N+Qv0r1Y^kLl$u{){ zaOkfBPN0%wlk>>s8H3Ngd0?FrG9=vml?o&7>{)`$d9LkL+hf+9*#?zGu_qia+tvo% z_nB#Y^{eae!tBvnD`NEz6)w zYcMkf;=<{XRJ5A;@@GdJ!)XZEyC3g?&}*O~9r4j)aj5KUvRqoJDVtFjoEw6Rshda_ z-zfNAlj%XDQPM-ATVMwxZe ze@ow?i?4&B)(spKh%OL@Pp^?xnCg|OV%MHU)Xc9%FM_l3uZDK!u_#+IMS0<1P!nS@ z1Co~jNC{LQiXdRkFp%8S-V{#dloHp>99-4=giyEF{5nnujY%sv@NSJiK(IghQgu@F zSUq-xEi<+URsDfYEGk!-Yb;nEu#`L8bTo~7InqcSu}w04yta)L_622avS{BAtFg?E+0D&?Zw8_x1w~p0}4)kO*M#m#?$G zxb??9+h&-LKi^?^JB%l&yQ$CGad`Q9QVUDj(ad){n4MVqhBr(OVg9d7GA0(kN}qv# zNPOpUOo&D*(-##(4i7Le3WNu$0md*fOmaV%m69_~#WB^yiR(j3k;(~E_h8noN_UK+ z`fNlksPSBij^Q(*@4tjbDdF9~14-+@$-DxH<@%(og9t8@OOa)emDLY*FK6;L{m77i#&rFD0yItNkM((IQ*=PsvjD=cyx55osd!xinkz+$HtSm3NU3?Wa0MYhCpeJGi8sFi)0w(_T28}o~ODAz<-;ne&rv|Z7u7Bh% zT0au>YS0!AX&wsPTZ7akxaDRj2;SO|50_D>u$*5^Q5)SWn#b=}2uNQmY)3U!0e6C^ z+jRH7Z@Y-=08)X3%hujMl7nZ3@l*7w`}zh$Wl?m82BE>as+=BU;pnRPmiXULhj?8X zj#XBtXk37&YK4k6O?I14tg&?~+1Vije0eWSaTa z;4IJ^s8z~uwTxR@;Us5`9;DBD@L24|dv@lh^1o}ct_~lZ{eC_!MP}_ib3^R)qBk?n zV6F(GnoX4!Sy|50Kxs{3F(EhQeYrT#ngOegm#U}DP3XOJfv(@fX8SQXjqeu5Hmg7I zTUkh@{Rq-Js!TZ~UMcQ*?CfNpzDKGD*&UBC$mbs44{Hy3>Bl4=J z;O||Xhv|K+2!I2m(9g?iVz-sW|H-?1tHpK`ANfuBM)0pFxU=(+$!f)IcFmL!K^AiP z;GkpA@fG+Gd)|rZY`?Ipox@tuzYfKd)t?xG zdOrxTDbPp6M+MKCYjH?<9ojt_KDK3F)h_7y?ARy`p}56|1yC}lzmV-5DjzLN|NT61 z@@NUX&1siiKO{j3w99IVb>JJ03#+EuhBdW!;O&?$JikT;B185oQ?_I@F2CpEu8??K zqu!goId!$5koEaPpMX$(FD!SL`L2;BJgaW}d*~W%F)9Axh=kHOS&O0kpq`Zo3Wsu70< zguJ~`H%}MM|I1R4?tUEK?n`4o(~0im%Mn-Rtl=R9Iz72ZS3726pmD?JNKdo4WS_kp z4v=3WL8*BYxp#;t^Ut{T2+JJ(o?ik`O)vo+LP7vtjvSSMEoKs6P9^+=kOoZ8AhYJq z=Y+Qsm&x?Af%c58aj`wJ%Oz56O?}r~I)^9d^-EWgZkO84t`(vBmMI|I21J`o{)}%= z32^^el~i(INv=%grJOC67Fn~#d>Xavy|;&jp}j1)9YJLC51H&Mp8^-fo!iE&^ghXr z3w4tK#fDYG<{-Xo|<`UmNf9m1wfJgJ@xi482$#_T;7L~ z3Fw}n#f3o{JMJs4&cd&Jv+FoWVT;9AYY5ekL7`1_v5S@_w~>N9IC zFTiK46cH}SKV2LV za~LRE`6rdm=SlbG<%qOO5L!UTd^3zak0Ma~u;iqmfv;-$L+?NiCOk`J9pKk4@^;4B z&FROtN${KU(YxUoOJ`fz8Vq-`kqyR)OckF=e^< zE8xL*z;YFb>ySN@1R91Ah}ws=5T&W@s%>`lb9^Qp$^VAiWT7ZJZC+3CW5y@1xmlhU zllqW7=RUb4X6zS7$kD#q_l4c;pg$B!vc`_;MF+RDp_Ch!S4Wnp6XUUe2aqD?gNBRF z8$?%ENRQErh#vx-@5OHz==pOpnr0Nh99CP2F*yKJ0R$1|8l?yoJp%}3Fw}$w0H%)u zu(~!B#FJl(1ykwYEkXy`_)QXTJ|`2iegd5A=EwkmJ$mcf2y;iXhLa6Vq}@Qc8lh`= z(VsnU6N4tePZk*pdAABgjak5qq`q$pj;(~S6h)5AzQe#M=Jb*VW9xc!SP9h7YX29PsY=B~zH;}LNhh8-F zekobU`D7*ksbFiFd6uOosw)gsIb#!Thj;#U&Hf^f$oRIO8)p3G2mFnad@%PY+#>?V zjWi?;45``Ljzpb>1XZ}ZRds&ZTRiK1H0g2UNu(iFWSmS6`bp;wIGG1bPR$F$sSq6= z19qC@`-h*tc|2w;Txx-ZXt5zyCQ6k+5~9$&XGnoHz$PP4$paN~D@%Tx<&!Tap>=qe zly>+V4F4#H(~;Q#2S?v7swiCc#^j>pB4WGn^P59;<<29>!(bV$@qis|6>*SIUV~-{UK4^RDipqj@R08Mdclx zF0$3wji78KnbMrl8D(;Lgy~)v^ak$ZVX}KZUkEq52d3hDHIq2zwKd)I)M*UwU_Pae zE|GU>ToA$DJV8ne36^;Qx0lml;H$Yka0QLXh-WGyR!`p&Un*NM zNMYAmo}PCG94@j1dOL{Jk-q!yuLyhrgq&04=e@=1O(hy`zppp+R#PIzuv#;kZkn}u z0JHYKKX0`m<{v7quIjp#qR&CW9&+=a%*q?|ww2ahlu3v-ylbtJM0T&d^sgRp@?Z`d zx8x)nDQ{gXa#1cTG*+8`L@k|-emw@udKn651BRTdgSLhu3cApEXwGyQq0Gs__GM<+ z16VZ=R0%+X%>ZAPcv#XJ^SX%LOY(;zr7RS|!9QF-4JK`I(vHUex1P$*@``NO0 z-;rRG{yObC@SsiU-`-X_F`wd`eVD`aj=Qk_roVi0P<$Qz&Ok=tr{vr2zU(2fUB}SUab@@m`r`7Oxl%S{61DA z!tLMKJFm)M_Wn0~KJ)|90-@$w3IrM6MmF7|j^cAveR_hMQ~S!};X)UMH1bhO=aA-K z!EA>owT&&hT(;bOdS)HSeH_(a8_UIf3aXH^YpVcd?DT^r->Cf>ceN=cqT55}j! z@HhVsnoSMvAL-T6ce&O<#OQOH}S^&D>rr!-SJGEno-XK zOB@6=@mEb2x~Uy8GESEFP9^*I?B(t!%2H9L6ct(6JD+`q->wjEa#K?vtM*TVR|<06 zAirJi#}sNAvTKvP1fQeV2@|wgAG0?9v>A>dKq#)G_=R+?MFQ{m^?Zh?YH$vUn_5rFa0%^^?)Gov`R1@okj-2cP0NkzqjOT zE5qA{()UXV_T-7(x6>f8RL6@WI5|1n=@0@tAM zvR(^NXEXlWX|+OPZa<*&Gzr&V0+c59xkPI7c2_Yegc>>V$kf0X01hG)QQ%}x!_hD9rnmz;2b}`W&+***U;PvO zz8gc0W8;uZknv9D%>xcA?O^XUIe_^+g)%6$>G2rcN0PCR?j_6q+hqGBCRMyvX#Pm~ zHSy{v@%WtG^(YRmk3O%Ys0}N<_TC$67}oy$W)8CZPN>@3G*Co`<{W-CL?wb+n6{wA zFHbl9lHk)_Um3#Q?fo*6W34nPw0Y5{@y8`z(JV%SfTC106?|(>cH!Pv zgG39WndSL#QS+H{P0-%EMr4?#FY{r!vGO4|Mb*tV4-9e&Zg6=7l0SgS&Or}G-a9Xg zWE(t~dk`ZPkUfkFUx32;*+?*S!%<-Mc7`koIoY7y+NrSRUCEkZPGBv|b=M(arc| zm|ju)Z{=G}_T3S?ULdAK`gu<-2hioUC8+N2>!+ z(VC_~&YHikHYf(HyNJsk6bm7&xroUgXupJR#jAsZr5RlC=b5yLf;j-Mchk1ARS|9> z(uY*JygGJyuB4?NMWGTr?ut!iPdD7fCe4V)6X1~)jHV)yZ~{uB8qs~dXae%X8C1fk zT&30A&KWyJ)b~5fS)^!_=876}j}X(56BlvjzX`Jh@ERPS*!}mk`yU%^MM1|9S|(I7 zi`dGiBw^2&LSeIU`@hr~ISA}IQvx?1?bdYg%>@#-{)nXk3iwEH33|AJg9Cdam2{i7 zlSJBXMy7VDpX;%7cSjU$wwa(VKfc_$kmpE`=;1ggNxA8LWL(F%MrU~Yc^TpuJtZo{4n5yg)74obwytQ8AT0d}) zB3iRMOVq1E_slnBH+YK9+cfg`pt>xv4g0NY_Md`nhE5^>Sm_Z=v9-&8m zxxi=vN&#G@DR6>$Yh}Ffi25-3o{LgCh~Q|EEbh1B>8;TsKhzhNycbI75>#w;*6Thr z56b;m_?+m6cb~aO`X_>pz4|VK?S*DE;QQ;()gPt8!zcDLUTc+8F|_>f!FeeId8u{A z5!obA6bY!PXcMIk%zH=1sU){bNX!Um*A$?-JX7KaOf2b_*gfPafdrGL{RV4Sq8**| zv3C9EvJ=UjS$dLpy>C`Lk+&7}?}j@I6d>`Z)wxm!P|!y_%tPQgMKMhQFBAry{9{6Sh~!UQpppp^)@*`Y#Fah3W&Pn z=<-m8VZpqtGoi~Zp8=An25z;%ytyxBCLQIjqJFAuU2^!!>fO(fCq%w$_ylXnm|DM; zT}zkn*cnfzzKDO7jf1=fNKJlH1D-uFUILk0mkyzR0xX_|i1c@fvc{MfX^WGXSS<08>!wq8|Gvbs}$( zeb_j#&J_>c;fW)2weT@dHo-jPPI7R|`}^CR+W+n9bMY0Y;mHJ-m&&p&=d0nZJ{@Qn zckKms?^QJXjS*|qeKLUj(8w=2e@s-t#6bBoyW^W&f-l1?FX5vRsgKkbtYB;eVh@yr zg4sf=6YqTzT!L=Gan%;WWUq_hc!u**Ug@`oJNuK6a1`!Fx%0nPyV+h&R8WiGRltEmmgrIWnE~mSqd?s$Vn1F z7o3-2)IuWhHP1h}aHatUat|SMry~maY2qsR^paI6d{2RJ;&Ca*j*nRz(&Jm|D%gqK5ucb^@c8u zHm7uqevXN0rZ$5!RjW|8k}`uK$_K$SFQjAfj|(7I^Ishk2jHF|_(Zo&o*4Zn0<4mU zw`tF~mp%84u~w)3gWbl4q5P08?R zchN`~{GDRi>B$6c2})3yIc&lCxr*MIA%GwgiLEBerTV zqbAOd2_IgAcrK~n;>pk=rXN{rR`sH$vb_)7drZ{E4|}_ z@pZiNs$2G=Q2Jo;8c=X1dEx`Bwo_h#WOzU3+8KRNn5e=%HlIZm$m{-q92WODCk`2m zUV&CZtO75-HZBI8Ez>my8^C|)%82^rT|RPm=}_D(Q`-mJ0T-8RZJ%XhFnW?Hu`nBn zldJZH^d5tk@GC`rXrT&6=#l#_h$BS?I+?6rQ9Ed)m4|Y8yD{~*v3VT)thsS(lCbGE z|6vik+zW;GwCWB>*MF|98%8e7u~)!YyPo1Ld60Xsk9lVzq&w#Ir5 zZw_ILz$awW&FU1ydmT~|QO`b{aF{s8P9_p-AJhp1pXQW=aP=3J7k6#I6H=e0*QE|H zT--D5DP6UuCd`tQyeAvz`lo3S!Bn8u)uR%sOGm+o^3{|zklTa3-U2S5pPNL~S4AWB z$~K~oB3nPlC;!HSJlDn^Hx)+@3-IF6e=VG3Jg-P~6QRjA+Z}a2!(;RtHnDG;M z%J0SaP^i?DI16>NHsT#AbQbH$M+2BKWqQuvCKS5L&VPGc;t;DvL*@3u$}^hkuv4a$ zR9KvgTke_3m8T{e5u|&b6Oud7vnMI1iP%ym3vpQ|jt{Y4ue_1UJ$fiy?v*csl*@Yz zP5kD->J%O_@7cT`O@+`S6}bQHiFofYf+R{+?HO@AK%WT6H4)tn4^2GJ*t`{(7zx9< zNmoH*{$o?={LpNEb6^oi6AGE*0Z7qcs1l^o>?dRul_LOo;F?u(aED}?9}q5r=BFhb z*84jqcg(gdN5nNtSZBGxmu>K6Cb zMr!jPlQi*%B?p*~e|K&+DKBf?!VsK3Yv<$2i`e4SA8toXu07UbU#pcKCdL9wfWlWf zdHP#kLg8~tcv|=ceth;8d`Yh)9yBpJycKt**RrYh9-`JSL#f#bGS_|!9)4N%5kenp zCM)#(i;7g#w39?)g(xA;`S94#->M#m!MtUMo^BXtfkqixeB~=6Ky?GWy$JZS zq@4rR<_mLdeB_d-*AI9$BM#zkRCLF2eq9{-h&2ZwA@GKK&F$)k`~UR0EEhjh-V^NS zCF3C)6|QfZ*bM^hZVD|1H8EWavY)s6PY)r7?&HPdw9U&St#fa4_obI;smtRLd~4X7kb{46_q^Xh zu&v$cuiV_%r)7{E9j0JV&`DJI<*wb$WMb%6kb!xpk~=8KCMV79@h*Sj_(BFPR^sm<+vst>p0EDK zSlteq)1x=yf=OMN^#Y4qs9uqtJ5C>=c6tSwMeCDM!m6-NZ|Pke?eozIS(`Jef<8EA zZYJQ^F8A!zHP`b>=ut&0N%W(`WHguCCN?Y7ujqXH0&n}PYV7*a0JZS;AthQG9H_kCr{ zL2Q$I`BJzft=jMIz}0 ztsl0UrMG+96tINrb`>;mRw2=KO#Rd#4u^HLcLF=I#7>`+(baB_eaGV{w#fe0c96+A z*$9VP3!M?S9_1jZxsm_aNNZ>sO?tk~?+E$;A9l+lYn@m;(rIxZ zHHjOGUqrGyhb8ai6wTAoO}Zf(FBj-Ge##nNLLl2U06&PEJS&DhyQZr+Do?Da;s@+q=|Jj8@?6LUjOyI-sf!Y;(*W!nef6%O@y9mT+pNe zEcBY*wW)bNLwxl#Xa}DxWcQ-7h5vd@Z2>me?!hUk?DL=Bg`H*6=_uotti@`f8Zy^* zRki}z6%8i&U_co|hl?a>5)`2h(1-$n0ukt6-_MF;uiZKsoKpWYTdGqt+^*cf{~#`N zS}Kpk#~Vs%L*P^s->l746TZF!LA~=?XIl_*d0gR!i`rHyf(gTqm7te|tOm%`NPNEl z?%B@H3LLb{5po#w5O@1Wj%Htd-ZHLP#YT#aMy}yfmx&<2rIqq4eZ$XtV_`Pv{`ixF66i_#i0uc4ysL#r zw}-nbz?-|+sfGHo7B1a;9cM%G3e1uC`2$W{y@q|qPTbfcEPYXL{bb$LjgJr*MZ>Bj zCzbnF3EI2PSH{RQ`X}cT;1!z!_)t>eKZ>1~l9d8UGPzC}NGHM>s1_#s3{Xnlr^E!E z-*wy!azamM=1+8z?+$tE$R$;zFnvzC+Z#pwJ=gsOq6SX#xvd^{ls*>|j&U1Hl@36B zM!|>}dgHZN$I^gXQphgLVVd;d{RUB!%)2>A+vzb%7Mp3=eBbp@6g0gr7Xc7+l8MG< z;a}a#2644u1_lr4b94631Fh^`$`sgA|17Fg_k$rkMBjh^?+JR!Er-I>zBgA8vjUNx z;%-;^rqS$jAjJBB#Zolx?khqJ7K2n18xu{1xR-p$^ZZElFqru_ZeCigA#ut&SX*80 z(C)YeC*|ATNf`f2Y6gy>J_b+qI)@s zR#>v?Fzf;8!C?Nk7MHE#;)wK{UB>{n7YEmK6ux|^b-hkOm|1PNpFWh;k8VU|Ypn(c z1#4H{m;c6(t2i=C@K#N4Y%2M0R;i^_K@4z3hhislW1H4cps@H6(L{N&oBQ zZ1kZyv}+#$l7r-~CuD9%P`-*-dV=$O7S=lsfvMM>K=s&QImKps?H>*+L{g<1LL+IZP zS;2Jetjo6;cAy+xyFfh6))XqSrtd1d?eorGI)ug0H|LwVFF%7-!TxX^#wgwS6iJKb zaSsnx6%|1d;1d1>jeGqPqA#t4d>%tx{N<0k*9!ATr7KH2J*M}P#6l;>(q)l$yW(T6 zAgWHuW2V)Mf{<0qefpeVqtc_LK1`QJT@#%%P6i!7$`4N{TBf8IZkM}ZrCn*V*�? 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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 95741540..238a27da 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 20a77126..6cde2a2d 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 984a6baa..60b0ba81 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 426627bf..96cbd61f 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 6ae9c671..8f242dcc 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 bb4daf54..ee6815d1 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 87491fbf..094d64df 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 8f242dcc..ffe13a50 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 b443f3d4..a298041e 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 ab400052..f2166aad 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 07999d87..9658a68d 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 99e8ed2f..862c744b 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 934c5774..980c5b3e 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 69b24ea1..eff1fe49 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 11ff9a02..27b7ad8f 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 ba654c75..7b191263 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 1c4d26d0..aa9e0503 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 58edf29d..bb923a31 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 73957cad..9dcfe485 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 691a85d3..7bc19976 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 cc40ae53..f4138354 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 eb259cf7..0e336132 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 e1a8e08a..cf49dc5f 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 bb923a31..392cec24 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 1fe5dec8..93c619bf 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 880c1c9c..23a36641 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 cc9b2cd8..59f4ae8b 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 9fe62bb4..38b94039 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 1ca46720..41b6246c 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 c5d1de25..c780038a 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 a467e218..1183b21d 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 ce02b875..6dfde5d1 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 aebf1979..0979e573 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 aa75e149..6811d6bb 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 8a1a973b..304ea3fb 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 15f0e496..08022640 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 79b27f6a..23e831c0 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 70c2749d..83d6bb69 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 9dcfe485..53607317 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 7d952182..e627b845 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 15af7a70..e2a55509 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 31f36388..b84aad98 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 9efda13c..0a91cb79 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 93356e7c..557f37a3 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 e932d264..e3d2c9f5 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 d1afd19e..012d0c59 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 401bb343..6de13611 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 17e533bc..784afed5 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 7bc19976..1e7cda5f 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 bf8fcb13..a2362e81 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 b92b604e..329b3a8a 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 d0388f33..a95c853e 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 f868ff08..9547ba2f 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 548a1ec8..e911feaa 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 3a356e03..69c4a368 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 5c426cb9..06b40090 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 627c25dc..9862159d 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 b9600222..bb3cf0ed 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 a298041e..848f16c2 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 9b44cdd3..5c94d6af 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 207825e8..35887822 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 ac718cba..38d319e1 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 d1c8473b..3b051c5c 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 de2b7186..38141c52 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 b956a0d8..38187275 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 4214255e..3151e973 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 8f857b66..d37321ff 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 762b09ba..5da4c37d 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 00ff14de..8c54d141 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 f4138354..5a6b4c89 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 f00119ca..425aba18 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 4632f440..fa3aaa3c 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 3512ed83..00000000 --- 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 617ac83e..d4413d68 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 6cde2a2d..298f5bc8 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 217a9df1..eb75a2df 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 617c9d43..6566ecc1 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 a5942ee6..0407cf6e 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 99845ee9..0de73a5d 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 2ddd61ed..d8bf8583 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 906bd786..a3e99ccb 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 5ea942c1..5727a902 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 27b7ad8f..ad5cb42a 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 79dcf138..943b4568 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 93c619bf..666820cc 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 23a36641..2daa6b2f 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 59f4ae8b..1f336667 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 a11dd40a..92d2e910 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 9e3c14e6..5e4633ea 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 41489ac2..7d7673c4 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 7437a26e..e45945bc 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 0979e573..23c566d7 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 6811d6bb..7811d9c0 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 8b0b8201..49177912 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 eac2ed04..827e4c7f 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 59d9b25f..5fdda617 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 09c78da9..a6eb6c9b 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 04b6ecc4..0b7b5c5c 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 9862159d..325710c6 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 00000000..6d353adb --- /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 78752591..285846a9 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 f9a7fec2..3d4dd506 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 9e071247..22588576 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 eb4c1ddc..91f95e6e 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 00000000..08be7fdd --- /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 5a6b4c89..9be0e1c6 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 6d353adb..6172cc9e 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 875991fa..565264f0 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 87302d4d..85ede346 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 6439eb23..e05ad7f0 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 4a995711..cca3fcaa 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 60b0ba81..468042b8 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 78f21973..7c42ba33 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 0a47fbca..0df8ef4b 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 70ad0e26..b2bc1526 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 eb75a2df..afa75503 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 00000000..e29e164b --- /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 08be7fdd..c199011b 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 eff1fe49..246a3c6e 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 e29e164b..7dd59712 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 c199011b..fc8f930a 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 5c94d6af..01f6b0b9 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 aea9ba18..aa01ada8 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 6172cc9e..9dabc387 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 b2bc1526..b9bf67ce 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 822be8c8..ae4ed779 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 b9bf67ce..3fdd5f37 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 7811d9c0..fde799fe 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 776cec72..34c7f43d 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 3a35782d..bf196224 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 3c7efa18..247021f1 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 2aee7bc0..12ef1053 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 3e119eb1..acfdc3d6 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 666820cc..6b51c892 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 247021f1..11dfe46e 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 12ef1053..2aee7bc0 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 f17a97e3..4fe93d45 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 9be0e1c6..0c0ec112 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 298f5bc8..675c2b9a 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 0de73a5d..3c78c554 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 a49506b0..b1b60132 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 d8bf8583..9c24fa2b 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 cc7d749d..4d0eb202 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 ad5cb42a..6ca9063c 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 6b51c892..0aa0ceaa 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 a7b0c966..9601a298 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 7d8772fb..dfd49f2e 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