diff --git a/README.md b/README.md index f11b9bfb3..713e77b72 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,6 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set - [ ] Cartography Table - [ ] Stonecutter - [ ] Villager Trading -- Sounds -- Block Particles - Some Entity Flags ## Compiling diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java index 55eb137bb..2213f90bb 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitConfiguration.java @@ -28,8 +28,8 @@ package org.geysermc.platform.bukkit; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.Plugin; -import org.geysermc.common.FloodgateKeyLoader; -import org.geysermc.common.IGeyserConfiguration; +import org.geysermc.connector.FloodgateKeyLoader; +import org.geysermc.connector.GeyserConfiguration; import java.io.File; import java.nio.file.Path; @@ -37,7 +37,7 @@ import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; -public class GeyserBukkitConfiguration implements IGeyserConfiguration { +public class GeyserBukkitConfiguration implements GeyserConfiguration { private FileConfiguration config; private File dataFolder; @@ -121,6 +121,11 @@ public class GeyserBukkitConfiguration implements IGeyserConfiguration { return floodgateKey; } + @Override + public boolean isCacheChunks() { + return true; // We override this as with Bukkit, we have direct access to the server implementation + } + @Override public IMetricsInfo getMetrics() { return metricsInfo; diff --git a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java index 454ec9f6e..08822568c 100644 --- a/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/GeyserBukkitLogger.java @@ -27,13 +27,13 @@ package org.geysermc.platform.bukkit; import lombok.AllArgsConstructor; -import org.geysermc.common.logger.IGeyserLogger; +import org.geysermc.connector.GeyserLogger; import java.util.logging.Level; import java.util.logging.Logger; @AllArgsConstructor -public class GeyserBukkitLogger implements IGeyserLogger { +public class GeyserBukkitLogger implements GeyserLogger { private Logger logger; private boolean debugMode; 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 c4655bef9..d6bd31acd 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 @@ -28,19 +28,22 @@ package org.geysermc.platform.bukkit; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import org.geysermc.common.PlatformType; -import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor; import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager; +import org.geysermc.platform.bukkit.world.GeyserBukkitWorldManager; import java.util.UUID; -public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap { +public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap { private GeyserBukkitCommandManager geyserCommandManager; private GeyserBukkitConfiguration geyserConfig; private GeyserBukkitLogger geyserLogger; + private GeyserBukkitWorldManager geyserWorldManager; private GeyserConnector connector; @@ -70,6 +73,7 @@ public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap { this.connector = GeyserConnector.start(PlatformType.BUKKIT, this); this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector); + this.geyserWorldManager = new GeyserBukkitWorldManager(); this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector)); } @@ -93,4 +97,9 @@ public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap { public CommandManager getGeyserCommandManager() { return this.geyserCommandManager; } + + @Override + public WorldManager getWorldManager() { + return this.geyserWorldManager; + } } diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java similarity index 64% rename from connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java rename to bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java index c45a7c942..6172b8314 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkPosition.java +++ b/bootstrap/bukkit/src/main/java/org/geysermc/platform/bukkit/world/GeyserBukkitWorldManager.java @@ -21,33 +21,22 @@ * * @author GeyserMC * @link https://github.com/GeyserMC/Geyser + * */ -package org.geysermc.connector.world.chunk; +package org.geysermc.platform.bukkit.world; -import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; -@Getter -@Setter -@AllArgsConstructor -@EqualsAndHashCode -public class ChunkPosition { +import org.bukkit.Bukkit; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.world.WorldManager; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; - private int x; - private int z; +public class GeyserBukkitWorldManager extends WorldManager { - public Position getBlock(int x, int y, int z) { - return new Position((this.x << 4) + x, y, (this.z << 4) + z); - } - - public Position getChunkBlock(int x, int y, int z) { - int chunkX = x & 15; - int chunkY = y & 15; - int chunkZ = z & 15; - return new Position(chunkX, chunkY, chunkZ); + @Override + public BlockState getBlockAt(GeyserSession session, int x, int y, int z) { + return BlockTranslator.getJavaIdBlockMap().get(Bukkit.getPlayer(session.getName()).getWorld().getBlockAt(x, y, z).getBlockData().getAsString()); } } diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java index c94d27239..f8e401418 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeConfiguration.java @@ -27,8 +27,8 @@ package org.geysermc.platform.bungeecord; import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.config.Configuration; -import org.geysermc.common.FloodgateKeyLoader; -import org.geysermc.common.IGeyserConfiguration; +import org.geysermc.connector.FloodgateKeyLoader; +import org.geysermc.connector.GeyserConfiguration; import java.io.File; import java.nio.file.Path; @@ -36,7 +36,7 @@ import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; -public class GeyserBungeeConfiguration implements IGeyserConfiguration { +public class GeyserBungeeConfiguration implements GeyserConfiguration { private File dataFolder; private Configuration config; @@ -120,6 +120,11 @@ public class GeyserBungeeConfiguration implements IGeyserConfiguration { return floodgateKey; } + @Override + public boolean isCacheChunks() { + return config.getBoolean("cache-chunks", false); + } + @Override public BungeeMetricsInfo getMetrics() { return metricsInfo; diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java index 7aba88bcd..cd07b333d 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeLogger.java @@ -25,12 +25,12 @@ package org.geysermc.platform.bungeecord; -import org.geysermc.common.logger.IGeyserLogger; +import org.geysermc.connector.GeyserLogger; import java.util.logging.Level; import java.util.logging.Logger; -public class GeyserBungeeLogger implements IGeyserLogger { +public class GeyserBungeeLogger implements GeyserLogger { private Logger logger; private boolean debugMode; 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 4c2e25800..bfd0cf49c 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 @@ -31,8 +31,8 @@ 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.common.bootstrap.IGeyserBootstrap; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor; import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager; @@ -45,7 +45,7 @@ import java.nio.file.Files; import java.util.UUID; import java.util.logging.Level; -public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap { +public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { private GeyserBungeeCommandManager geyserCommandManager; private GeyserBungeeConfiguration geyserConfig; diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java index e60a5c3ef..e8459550e 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeConfiguration.java @@ -26,15 +26,17 @@ package org.geysermc.platform.sponge; import lombok.AllArgsConstructor; + import ninja.leaping.configurate.ConfigurationNode; -import org.geysermc.common.IGeyserConfiguration; + +import org.geysermc.connector.GeyserConfiguration; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; -public class GeyserSpongeConfiguration implements IGeyserConfiguration { +public class GeyserSpongeConfiguration implements GeyserConfiguration { private File dataFolder; private ConfigurationNode node; @@ -112,6 +114,11 @@ public class GeyserSpongeConfiguration implements IGeyserConfiguration { return Paths.get(dataFolder.toString(), node.getNode("floodgate-key-file").getString("public-key.pem")); } + @Override + public boolean isCacheChunks() { + return node.getNode("cache-chunks").getBoolean(false); + } + @Override public SpongeMetricsInfo getMetrics() { return metricsInfo; diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java index 758ac98d3..fb7cb54bb 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeLogger.java @@ -27,11 +27,11 @@ package org.geysermc.platform.sponge; import lombok.AllArgsConstructor; -import org.geysermc.common.logger.IGeyserLogger; +import org.geysermc.connector.GeyserLogger; import org.slf4j.Logger; @AllArgsConstructor -public class GeyserSpongeLogger implements IGeyserLogger { +public class GeyserSpongeLogger implements GeyserLogger { private Logger logger; private boolean debugMode; 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 cc26abb9c..01d71f1c0 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 @@ -30,8 +30,8 @@ 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.common.bootstrap.IGeyserBootstrap; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.utils.FileUtils; import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor; @@ -50,7 +50,7 @@ import java.net.InetSocketAddress; import java.util.UUID; @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Sponge", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") -public class GeyserSpongePlugin implements IGeyserBootstrap { +public class GeyserSpongePlugin implements GeyserBootstrap { @Inject private Logger logger; diff --git a/bootstrap/standalone/pom.xml b/bootstrap/standalone/pom.xml index 0a583fa7c..770ca1009 100644 --- a/bootstrap/standalone/pom.xml +++ b/bootstrap/standalone/pom.xml @@ -81,7 +81,7 @@ - org.geysermc.platform.standalone.GeyserBootstrap + org.geysermc.platform.standalone.GeyserStandaloneBootstrap @@ -119,7 +119,7 @@ - org.geysermc.platform.standalone.GeyserBootstrap + org.geysermc.platform.standalone.GeyserStandaloneBootstrap true diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java similarity index 87% rename from bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java rename to bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java index 20b7f5ea7..9d2493635 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java @@ -26,38 +26,38 @@ package org.geysermc.platform.standalone; import org.geysermc.common.PlatformType; -import org.geysermc.common.bootstrap.IGeyserBootstrap; +import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.utils.FileUtils; import org.geysermc.platform.standalone.command.GeyserCommandManager; -import org.geysermc.platform.standalone.console.GeyserLogger; import java.io.File; import java.io.IOException; import java.util.UUID; -public class GeyserBootstrap implements IGeyserBootstrap { +public class GeyserStandaloneBootstrap implements GeyserBootstrap { private GeyserCommandManager geyserCommandManager; private GeyserConfiguration geyserConfig; - private GeyserLogger geyserLogger; + private GeyserStandaloneLogger geyserLogger; private GeyserConnector connector; public static void main(String[] args) { - new GeyserBootstrap().onEnable(); + new GeyserStandaloneBootstrap().onEnable(); } @Override public void onEnable() { - geyserLogger = new GeyserLogger(); + geyserLogger = new GeyserStandaloneLogger(); LoopbackUtil.checkLoopback(geyserLogger); try { File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString())); - geyserConfig = FileUtils.loadConfig(configFile, GeyserConfiguration.class); + 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); System.exit(0); @@ -80,7 +80,7 @@ public class GeyserBootstrap implements IGeyserBootstrap { } @Override - public GeyserLogger getGeyserLogger() { + public GeyserStandaloneLogger getGeyserLogger() { return geyserLogger; } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneConfiguration.java similarity index 94% rename from bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java rename to bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneConfiguration.java index afd6179e8..8ae83d026 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserConfiguration.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneConfiguration.java @@ -29,8 +29,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; - -import org.geysermc.common.IGeyserConfiguration; +import org.geysermc.connector.GeyserConfiguration; import java.nio.file.Path; import java.nio.file.Paths; @@ -38,7 +37,7 @@ import java.util.Map; @JsonIgnoreProperties(ignoreUnknown = true) @Getter -public class GeyserConfiguration implements IGeyserConfiguration { +public class GeyserStandaloneConfiguration implements GeyserConfiguration { private BedrockConfiguration bedrock; private RemoteConfiguration remote; @@ -66,6 +65,9 @@ public class GeyserConfiguration implements IGeyserConfiguration { @JsonProperty("default-locale") private String defaultLocale; + @JsonProperty("cache-chunks") + private boolean cacheChunks; + private MetricsInfo metrics; @Override diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/console/GeyserLogger.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneLogger.java similarity index 64% rename from bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/console/GeyserLogger.java rename to bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneLogger.java index 631de9052..ffb252b2e 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/console/GeyserLogger.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneLogger.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.platform.standalone.console; +package org.geysermc.platform.standalone; import lombok.extern.log4j.Log4j2; @@ -31,12 +32,11 @@ import net.minecrell.terminalconsole.SimpleTerminalConsole; import org.apache.logging.log4j.core.config.Configurator; import org.geysermc.common.ChatColor; -import org.geysermc.common.logger.IGeyserLogger; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; @Log4j2 -public class GeyserLogger extends SimpleTerminalConsole implements IGeyserLogger, CommandSender { +public class GeyserStandaloneLogger extends SimpleTerminalConsole implements org.geysermc.connector.GeyserLogger, CommandSender { private boolean colored = true; 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 20a810726..03c49705d 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 @@ -6,14 +6,13 @@ import java.nio.file.OpenOption; import java.nio.file.Paths; import org.geysermc.common.ChatColor; -import org.geysermc.platform.standalone.console.GeyserLogger; 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'\""; private static final String startScript = "powershell -Command \"Start-Process 'cmd' -ArgumentList /c,%temp%/loopback_minecraft.bat -Verb runAs\""; - public static void checkLoopback(GeyserLogger geyserLogger) { + public static void checkLoopback(GeyserStandaloneLogger geyserLogger) { if (System.getProperty("os.name").equalsIgnoreCase("Windows 10")) { try { Process process = Runtime.getRuntime().exec(checkExemption); diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java index 33fd50fef..ff99f8ab1 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityConfiguration.java @@ -31,8 +31,8 @@ import com.velocitypowered.api.plugin.PluginContainer; import com.velocitypowered.api.proxy.ProxyServer; import lombok.Getter; import lombok.Setter; -import org.geysermc.common.FloodgateKeyLoader; -import org.geysermc.common.IGeyserConfiguration; +import org.geysermc.connector.FloodgateKeyLoader; +import org.geysermc.connector.GeyserConfiguration; import java.io.File; import java.nio.file.Path; @@ -42,7 +42,7 @@ import java.util.Optional; @JsonIgnoreProperties(ignoreUnknown = true) @Getter -public class GeyserVelocityConfiguration implements IGeyserConfiguration { +public class GeyserVelocityConfiguration implements GeyserConfiguration { private BedrockConfiguration bedrock; private RemoteConfiguration remote; @@ -70,6 +70,9 @@ public class GeyserVelocityConfiguration implements IGeyserConfiguration { @JsonProperty("default-locale") private String defaultLocale; + @JsonProperty("cache-chunks") + private boolean cacheChunks; + private MetricsInfo metrics; private Path floodgateKey; diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityLogger.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityLogger.java index 623c6481e..a935d786c 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityLogger.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityLogger.java @@ -27,11 +27,11 @@ package org.geysermc.platform.velocity; import lombok.AllArgsConstructor; -import org.geysermc.common.logger.IGeyserLogger; +import org.geysermc.connector.GeyserLogger; import org.slf4j.Logger; @AllArgsConstructor -public class GeyserVelocityLogger implements IGeyserLogger { +public class GeyserVelocityLogger implements GeyserLogger { private Logger logger; private boolean debugMode; 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 59647e1d3..bd8924133 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,8 +35,8 @@ import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.proxy.ProxyServer; import org.geysermc.common.PlatformType; -import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.utils.FileUtils; import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor; import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager; @@ -48,7 +48,7 @@ import java.net.InetSocketAddress; import java.util.UUID; @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Velocity", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") -public class GeyserVelocityPlugin implements IGeyserBootstrap { +public class GeyserVelocityPlugin implements GeyserBootstrap { @Inject private Logger logger; diff --git a/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java b/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java deleted file mode 100644 index 774e3394d..000000000 --- a/common/src/main/java/org/geysermc/common/IGeyserConfiguration.java +++ /dev/null @@ -1,87 +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.common; - -import java.nio.file.Path; -import java.util.Map; - -public interface IGeyserConfiguration { - - IBedrockConfiguration getBedrock(); - - IRemoteConfiguration getRemote(); - - Map getUserAuths(); - - boolean isPingPassthrough(); - - int getMaxPlayers(); - - boolean isDebugMode(); - - int getGeneralThreadPool(); - - boolean isAllowThirdPartyCapes(); - - String getDefaultLocale(); - - Path getFloodgateKeyFile(); - - IMetricsInfo getMetrics(); - - interface IBedrockConfiguration { - - String getAddress(); - - int getPort(); - - String getMotd1(); - - String getMotd2(); - } - - interface IRemoteConfiguration { - - String getAddress(); - - int getPort(); - - String getAuthType(); - } - - interface IUserAuthenticationInfo { - String getEmail(); - - String getPassword(); - } - - interface IMetricsInfo { - - boolean isEnabled(); - - String getUniqueId(); - } -} diff --git a/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java b/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java deleted file mode 100644 index ad571ebbb..000000000 --- a/common/src/main/java/org/geysermc/common/logger/IGeyserLogger.java +++ /dev/null @@ -1,81 +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.common.logger; - -public interface IGeyserLogger { - - /** - * Logs a severe message to console - * - * @param message the message to log - */ - void severe(String message); - - /** - * Logs a severe message and an exception to console - */ - void severe(String message, Throwable error); - - /** - * Logs an error message to console - * - * @param message the message to log - */ - void error(String message); - - /** - * Logs an error message and an exception to console - */ - void error(String message, Throwable error); - - /** - * Logs a warning message to console - * - * @param message the message to log - */ - void warning(String message); - - /** - * Logs an info message to console - * - * @param message the message to log - */ - void info(String message); - - /** - * Logs a debug message to console - * - * @param message the message to log - */ - void debug(String message); - - /** - * Sets if the logger should print debug messages - * - * @param debug if the logger should print debug messages - */ - void setDebug(boolean debug); -} diff --git a/connector/pom.xml b/connector/pom.xml index 9de533b6a..c9740ea44 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -90,6 +90,12 @@ 8.3.1 compile + + com.google.guava + guava + 29.0-jre + compile + com.github.steveice10 opennbt diff --git a/common/src/main/java/org/geysermc/common/FloodgateKeyLoader.java b/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java similarity index 90% rename from common/src/main/java/org/geysermc/common/FloodgateKeyLoader.java rename to connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java index 9eb3275f5..0b631b2d2 100644 --- a/common/src/main/java/org/geysermc/common/FloodgateKeyLoader.java +++ b/connector/src/main/java/org/geysermc/connector/FloodgateKeyLoader.java @@ -24,15 +24,13 @@ * */ -package org.geysermc.common; - -import org.geysermc.common.logger.IGeyserLogger; +package org.geysermc.connector; import java.nio.file.Files; import java.nio.file.Path; public class FloodgateKeyLoader { - public static Path getKey(IGeyserLogger logger, IGeyserConfiguration config, Path floodgateKey, Object floodgate, Path floodgateFolder) { + public static Path getKey(GeyserLogger logger, GeyserConfiguration config, Path floodgateKey, Object floodgate, Path floodgateFolder) { if (!Files.exists(floodgateKey) && config.getRemote().getAuthType().equals("floodgate")) { if (floodgate != null) { Path autoKey = floodgateFolder.resolve("public-key.pem"); diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConfiguration.java b/connector/src/main/java/org/geysermc/connector/GeyserConfiguration.java new file mode 100644 index 000000000..cbbd507a1 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/GeyserConfiguration.java @@ -0,0 +1,90 @@ +/* + * 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; + +import java.nio.file.Path; +import java.util.Map; + +public interface GeyserConfiguration { + + IBedrockConfiguration getBedrock(); + + IRemoteConfiguration getRemote(); + + Map getUserAuths(); + + boolean isPingPassthrough(); + + int getMaxPlayers(); + + boolean isDebugMode(); + + int getGeneralThreadPool(); + + boolean isAllowThirdPartyCapes(); + + String getDefaultLocale(); + + Path getFloodgateKeyFile(); + + boolean isCacheChunks(); + + IMetricsInfo getMetrics(); + + interface IBedrockConfiguration { + + String getAddress(); + + int getPort(); + + String getMotd1(); + + String getMotd2(); + } + + interface IRemoteConfiguration { + + String getAddress(); + + int getPort(); + + String getAuthType(); + } + + interface IUserAuthenticationInfo { + String getEmail(); + + String getPassword(); + } + + interface IMetricsInfo { + + boolean isEnabled(); + + String getUniqueId(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index 2679857c4..6c9e8c7db 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -32,16 +32,15 @@ import com.nukkitx.protocol.bedrock.v390.Bedrock_v390; import lombok.Getter; import org.geysermc.common.AuthType; -import org.geysermc.common.IGeyserConfiguration; import org.geysermc.common.PlatformType; -import org.geysermc.common.bootstrap.IGeyserBootstrap; -import org.geysermc.common.logger.IGeyserLogger; +import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.metrics.Metrics; import org.geysermc.connector.network.ConnectorServerEventHandler; import org.geysermc.connector.network.remote.RemoteServer; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Translators; +import org.geysermc.connector.network.translators.world.WorldManager; import org.geysermc.connector.thread.PingPassthroughThread; import org.geysermc.connector.utils.Toolbox; @@ -76,19 +75,19 @@ public class GeyserConnector { private BedrockServer bedrockServer; private PlatformType platformType; - private IGeyserBootstrap bootstrap; + private GeyserBootstrap bootstrap; private Metrics metrics; - private GeyserConnector(PlatformType platformType, IGeyserBootstrap bootstrap) { + private GeyserConnector(PlatformType platformType, GeyserBootstrap bootstrap) { long startupTime = System.currentTimeMillis(); instance = this; this.bootstrap = bootstrap; - IGeyserLogger logger = bootstrap.getGeyserLogger(); - IGeyserConfiguration config = bootstrap.getGeyserConfig(); + GeyserLogger logger = bootstrap.getGeyserLogger(); + GeyserConfiguration config = bootstrap.getGeyserConfig(); this.platformType = platformType; @@ -191,7 +190,7 @@ public class GeyserConnector { players.remove(player.getSocketAddress()); } - public static GeyserConnector start(PlatformType platformType, IGeyserBootstrap bootstrap) { + public static GeyserConnector start(PlatformType platformType, GeyserBootstrap bootstrap) { return new GeyserConnector(platformType, bootstrap); } @@ -200,16 +199,20 @@ public class GeyserConnector { bootstrap.onEnable(); } - public IGeyserLogger getLogger() { + public GeyserLogger getLogger() { return bootstrap.getGeyserLogger(); } - public IGeyserConfiguration getConfig() { + public GeyserConfiguration getConfig() { return bootstrap.getGeyserConfig(); } public CommandManager getCommandManager() { - return (CommandManager) bootstrap.getGeyserCommandManager(); + return bootstrap.getGeyserCommandManager(); + } + + public WorldManager getWorldManager() { + return bootstrap.getWorldManager(); } public static GeyserConnector getInstance() { diff --git a/connector/src/main/java/org/geysermc/connector/GeyserLogger.java b/connector/src/main/java/org/geysermc/connector/GeyserLogger.java new file mode 100644 index 000000000..4acab2227 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/GeyserLogger.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; + +public interface GeyserLogger { + + /** + * Logs a severe message to console + * + * @param message the message to log + */ + void severe(String message); + + /** + * Logs a severe message and an exception to console + */ + void severe(String message, Throwable error); + + /** + * Logs an error message to console + * + * @param message the message to log + */ + void error(String message); + + /** + * Logs an error message and an exception to console + */ + void error(String message, Throwable error); + + /** + * Logs a warning message to console + * + * @param message the message to log + */ + void warning(String message); + + /** + * Logs an info message to console + * + * @param message the message to log + */ + void info(String message); + + /** + * Logs a debug message to console + * + * @param message the message to log + */ + void debug(String message); + + /** + * Sets if the logger should print debug messages + * + * @param debug if the logger should print debug messages + */ + void setDebug(boolean debug); +} diff --git a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java new file mode 100644 index 000000000..24b338c87 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java @@ -0,0 +1,78 @@ +/* + * 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.bootstrap; + +import org.geysermc.connector.GeyserConfiguration; +import org.geysermc.connector.GeyserLogger; +import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.network.translators.world.CachedChunkManager; +import org.geysermc.connector.network.translators.world.WorldManager; + +public interface GeyserBootstrap { + + CachedChunkManager DEFAULT_CHUNK_MANAGER = new CachedChunkManager(); + + /** + * Called when the GeyserBootstrap is enabled + */ + void onEnable(); + + /** + * Called when the GeyserBootstrap is disabled + */ + void onDisable(); + + /** + * Returns the current GeyserConfiguration + * + * @return The current GeyserConfiguration + */ + GeyserConfiguration getGeyserConfig(); + + /** + * Returns the current GeyserLogger + * + * @return The current GeyserLogger + */ + GeyserLogger getGeyserLogger(); + + /** + * Returns the current CommandManager + * + * @return The current CommandManager + */ + CommandManager getGeyserCommandManager(); + + /** + * Returns the current WorldManager + * + * @return the current WorldManager + */ + default WorldManager getWorldManager() { + return DEFAULT_CHUNK_MANAGER; + } +} 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 7b1b4d69b..88b9e795d 100644 --- a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java +++ b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java @@ -26,7 +26,7 @@ package org.geysermc.connector.command; import lombok.Getter; -import org.geysermc.common.command.ICommandManager; + import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.defaults.*; @@ -34,7 +34,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -public abstract class CommandManager implements ICommandManager { +public abstract class CommandManager { @Getter private final Map commands = Collections.synchronizedMap(new HashMap<>()); @@ -87,4 +87,12 @@ public abstract class CommandManager implements ICommandManager { cmd.execute(sender, args); } + + /** + * Returns the description of the given command + * + * @param command Command to get the description for + * @return Command description + */ + public abstract String getDescription(String command); } 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 5a0cac8f4..59e1d408e 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java @@ -28,7 +28,7 @@ package org.geysermc.connector.entity; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.EntityData; import org.geysermc.connector.entity.type.EntityType; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; public class FallingBlockEntity extends Entity { 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 08831a459..d49f6e17c 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/ItemFrameEntity.java @@ -39,8 +39,8 @@ import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Translators; -import org.geysermc.connector.network.translators.block.BlockTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.utils.Toolbox; import java.util.concurrent.TimeUnit; diff --git a/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java b/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java new file mode 100644 index 000000000..629c9e51c --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/entity/TNTEntity.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + * + */ + +package org.geysermc.connector.entity; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.EntityData; +import com.nukkitx.protocol.bedrock.data.EntityFlag; +import org.geysermc.connector.entity.type.EntityType; +import org.geysermc.connector.network.session.GeyserSession; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +public class TNTEntity extends Entity { + + private int currentTick; + + public TNTEntity(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() == 7) { + currentTick = (int) entityMetadata.getValue(); + metadata.getFlags().setFlag(EntityFlag.IGNITED, true); + metadata.put(EntityData.FUSE_LENGTH, currentTick); + ScheduledFuture future = session.getConnector().getGeneralThreadPool().scheduleAtFixedRate(() -> { + if (currentTick % 5 == 0) { + metadata.put(EntityData.FUSE_LENGTH, currentTick); + } + currentTick--; + super.updateBedrockMetadata(entityMetadata, session); + }, 50, 50, TimeUnit.MILLISECONDS); // 5 ticks + session.getConnector().getGeneralThreadPool().schedule(() -> future.cancel(true), (int) entityMetadata.getValue() / 20, TimeUnit.SECONDS); + } + + super.updateBedrockMetadata(entityMetadata, session); + } +} 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 26c13a5ce..c2dad7a57 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 @@ -32,7 +32,7 @@ import com.nukkitx.protocol.bedrock.data.ItemData; import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; public class LlamaEntity extends ChestedHorseEntity { 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 a423013cb..644181ab7 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 @@ -32,7 +32,7 @@ import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.EntityFlag; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; public class EndermanEntity extends MonsterEntity { 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 263d00416..5f77fdc41 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 @@ -98,7 +98,7 @@ public enum EntityType { TRIPOD_CAMERA(Entity.class, 62, 0f), PLAYER(PlayerEntity.class, 63, 1.8f, 0.6f, 0.6f, 1.62f), ITEM(ItemEntity.class, 64, 0.25f, 0.25f), - TNT(Entity.class, 65, 0.98f, 0.98f), + TNT(TNTEntity.class, 65, 0.98f, 0.98f), FALLING_BLOCK(FallingBlockEntity.class, 66, 0.98f, 0.98f), MOVING_BLOCK(Entity.class, 67, 0f), EXPERIENCE_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f), 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 60ad28d47..8810cffb4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/ConnectorServerEventHandler.java @@ -30,7 +30,7 @@ import com.nukkitx.protocol.bedrock.BedrockPong; import com.nukkitx.protocol.bedrock.BedrockServerEventHandler; import com.nukkitx.protocol.bedrock.BedrockServerSession; -import org.geysermc.common.IGeyserConfiguration; +import org.geysermc.connector.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.MessageUtils; @@ -55,7 +55,7 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { public BedrockPong onQuery(InetSocketAddress inetSocketAddress) { connector.getLogger().debug(inetSocketAddress + " has pinged you!"); - IGeyserConfiguration config = connector.getConfig(); + GeyserConfiguration config = connector.getConfig(); ServerStatusInfo serverInfo = connector.getPassthroughThread().getInfo(); BedrockPong pong = new BedrockPong(); @@ -101,11 +101,6 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler { if (player != null) { player.disconnect(disconnectReason.name()); connector.removePlayer(player); - - player.getEntityCache().clear(); - player.getInventoryCache().getInventories().clear(); - player.getWindowCache().getWindows().clear(); - player.getScoreboardCache().removeScoreboard(); } }); bedrockServerSession.setPacketCodec(GeyserConnector.BEDROCK_PACKET_CODEC); 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 7e41fca8b..2839237e3 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -28,7 +28,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.common.IGeyserConfiguration; +import org.geysermc.connector.GeyserConfiguration; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Registry; @@ -94,7 +94,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { private boolean couldLoginUserByName(String bedrockUsername) { if (connector.getConfig().getUserAuths() != null) { - IGeyserConfiguration.IUserAuthenticationInfo info = connector.getConfig().getUserAuths().get(bedrockUsername); + GeyserConfiguration.IUserAuthenticationInfo info = connector.getConfig().getUserAuths().get(bedrockUsername); if (info != null) { connector.getLogger().info("using stored credentials for bedrock user " + session.getAuthData().getName()); 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 1ea3a1c01..623e385da 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -31,6 +31,7 @@ import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket; import com.github.steveice10.packetlib.Client; @@ -64,7 +65,7 @@ import org.geysermc.connector.network.session.auth.AuthData; import org.geysermc.connector.network.session.auth.BedrockClientData; import org.geysermc.connector.network.session.cache.*; import org.geysermc.connector.network.translators.Registry; -import org.geysermc.connector.network.translators.block.BlockTranslator; +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.Toolbox; @@ -125,12 +126,31 @@ public class GeyserSession implements CommandSender { private GameMode gameMode = GameMode.SURVIVAL; private final AtomicInteger pendingDimSwitches = new AtomicInteger(0); + + @Setter + private boolean sneaking; + @Setter private boolean sprinting; @Setter private boolean jumping; + @Setter + private BlockState breakingBlock; + + @Setter + private Vector3i lastBlockPlacePosition; + + @Setter + private String lastBlockPlacedId; + + @Setter + private boolean interacting; + + @Setter + private Vector3i lastInteractionPosition; + @Setter private boolean switchingDimension = false; private boolean manyDimPackets = false; @@ -340,10 +360,11 @@ public class GeyserSession implements CommandSender { } } - this.entityCache.getEntities().clear(); - this.scoreboardCache.removeScoreboard(); - this.inventoryCache.getInventories().clear(); - this.windowCache.getWindows().clear(); + this.chunkCache = null; + this.entityCache = null; + this.scoreboardCache = null; + this.inventoryCache = null; + this.windowCache = null; closed = true; } 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 bc88694d8..ac7ab06cf 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,34 +29,39 @@ 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.nukkitx.protocol.bedrock.packet.LevelChunkPacket; import lombok.Getter; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.Translators; -import org.geysermc.connector.network.translators.block.BlockTranslator; -import org.geysermc.connector.world.chunk.ChunkPosition; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.chunk.ChunkPosition; import java.util.HashMap; import java.util.Map; public class ChunkCache { - private GeyserSession session; + private boolean cache; + private final GeyserSession session; @Getter - private Map chunks; + private Map chunks = new HashMap<>(); public ChunkCache(GeyserSession session) { this.session = session; - this.chunks = new HashMap<>(); + this.cache = session.getConnector().getConfig().isCacheChunks(); } public void addToCache(Column chunk) { + if (!cache) { + return; + } ChunkPosition position = new ChunkPosition(chunk.getX(), chunk.getZ()); chunks.put(position, chunk); } public void updateBlock(Position position, BlockState block) { + if (!cache) { + return; + } ChunkPosition chunkPosition = new ChunkPosition(position.getX() >> 4, position.getZ() >> 4); if (!chunks.containsKey(chunkPosition)) return; @@ -70,6 +75,9 @@ public class ChunkCache { } public BlockState getBlockAt(Position position) { + if (!cache) { + return BlockTranslator.AIR; + } ChunkPosition chunkPosition = new ChunkPosition(position.getX() >> 4, position.getZ() >> 4); if (!chunks.containsKey(chunkPosition)) return BlockTranslator.AIR; @@ -85,24 +93,9 @@ public class ChunkCache { } public void removeChunk(ChunkPosition position) { - chunks.remove(position); - sendEmptyChunk(position, true); - } - - public void sendEmptyChunk(ChunkPosition position) { - sendEmptyChunk(position, false); - } - - public void sendEmptyChunk(ChunkPosition position, boolean force) { - if (!force && chunks.containsKey(position)) + if (!cache) { return; - - LevelChunkPacket levelChunkPacket = new LevelChunkPacket(); - levelChunkPacket.setChunkX(position.getX()); - levelChunkPacket.setChunkZ(position.getZ()); - levelChunkPacket.setCachingEnabled(false); - levelChunkPacket.setSubChunksLength(0); - levelChunkPacket.setData(Translators.EMPTY_LEVEL_CHUNK_DATA); - session.getUpstream().sendPacket(levelChunkPacket); + } + chunks.remove(position); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java b/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java index f7c7c28aa..03042e3a4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/Translators.java @@ -34,8 +34,8 @@ import com.github.steveice10.mc.protocol.data.game.window.WindowType; import com.nukkitx.protocol.bedrock.data.ContainerType; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.network.translators.block.BlockTranslator; -import org.geysermc.connector.network.translators.block.entity.*; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.entity.*; import org.geysermc.connector.network.translators.inventory.*; import org.geysermc.connector.network.translators.inventory.updater.ContainerInventoryUpdater; import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; @@ -121,7 +121,7 @@ public class Translators { } private static void registerBlockEntityTranslators() { - Reflections ref = new Reflections("org.geysermc.connector.network.translators.block.entity"); + Reflections ref = new Reflections("org.geysermc.connector.network.translators.world.block.entity"); for (Class clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) { 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 7ab713893..d7248aa36 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 @@ -27,6 +27,8 @@ 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; @@ -41,6 +43,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlaye import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; @Translator(packet = PlayerActionPacket.class) public class BedrockActionTranslator extends PacketTranslator { @@ -75,10 +78,12 @@ public class BedrockActionTranslator extends PacketTranslator { + + @Override + public void translate(EntityEventPacket packet, GeyserSession session) { + switch (packet.getType()) { + // Resend the packet so we get the eating sounds + case EATING_ITEM: + session.getUpstream().sendPacket(packet); + return; + } + session.getConnector().getLogger().debug("Did not translate incoming EntityEventPacket: " + packet.toString()); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockInventoryTransactionTranslator.java index 7890ead7f..ed9289599 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 @@ -25,19 +25,6 @@ package org.geysermc.connector.network.translators.bedrock; -import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket; -import org.geysermc.connector.entity.Entity; -import org.geysermc.connector.entity.ItemFrameEntity; -import org.geysermc.connector.inventory.Inventory; -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.Translators; -import org.geysermc.connector.network.translators.block.BlockTranslator; -import org.geysermc.connector.network.translators.item.ItemTranslator; -import org.geysermc.connector.utils.InventoryUtils; - -import com.nukkitx.math.vector.Vector3f; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; @@ -46,9 +33,28 @@ 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.packet.ingame.client.player.ClientPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; +import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.ItemFrameEntity; +import org.geysermc.connector.inventory.Inventory; +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.Translators; +import org.geysermc.connector.network.translators.item.ItemEntry; +import org.geysermc.connector.network.translators.item.ItemTranslator; +import org.geysermc.connector.network.translators.sound.EntitySoundInteractionHandler; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.utils.InventoryUtils; + @Translator(packet = InventoryTransactionPacket.class) public class BedrockInventoryTransactionTranslator extends PacketTranslator { @@ -90,6 +96,35 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { - /** - * Called when the GeyserBootstrap is enabled - */ - void onEnable(); - - /** - * Called when the GeyserBootstrap is disabled - */ - void onDisable(); - - /** - * Returns the current GeyserConfig - * - * @return The current GeyserConfig - */ - IGeyserConfiguration getGeyserConfig(); - - /** - * Returns the current GeyserLogger - * - * @return The current GeyserLogger - */ - IGeyserLogger getGeyserLogger(); - - /** - * Returns the current GeyserCommandManager - * - * @return The current GeyserCommandManager - */ - ICommandManager getGeyserCommandManager(); + @Override + public void translate(LevelSoundEventPacket packet, GeyserSession session) { + // lol what even :thinking: + session.getUpstream().sendPacket(packet); + } } diff --git a/common/src/main/java/org/geysermc/common/command/ICommandManager.java b/connector/src/main/java/org/geysermc/connector/network/translators/effect/Effect.java similarity index 78% rename from common/src/main/java/org/geysermc/common/command/ICommandManager.java rename to connector/src/main/java/org/geysermc/connector/network/translators/effect/Effect.java index f46dfafcd..4c58235af 100644 --- a/common/src/main/java/org/geysermc/common/command/ICommandManager.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/effect/Effect.java @@ -23,16 +23,21 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.common.command; +package org.geysermc.connector.network.translators.effect; -public interface ICommandManager { +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; - /** - * Returns the description of the given command - * - * @param command Command to get the description for - * - * @return Command description - */ - String getDescription(String command); -} +@Getter +@Setter +@AllArgsConstructor +public class Effect { + + private String javaName; + private String bedrockName; + private String type; + private int data; + private String identifier; + +} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java index 5f6274f0a..ab410ea8b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/BlockInventoryTranslator.java @@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; import com.nukkitx.protocol.bedrock.data.ContainerType; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.inventory.holder.BlockInventoryHolder; import org.geysermc.connector.network.translators.inventory.holder.InventoryHolder; import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; 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 c70a89955..720280b47 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 @@ -35,7 +35,7 @@ import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.inventory.updater.ChestInventoryUpdater; import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; @@ -112,7 +112,7 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { public void closeInventory(GeyserSession session, Inventory inventory) { Vector3i holderPos = inventory.getHolderPosition(); Position pos = new Position(holderPos.getX(), holderPos.getY(), holderPos.getZ()); - BlockState realBlock = session.getChunkCache().getBlockAt(pos); + BlockState realBlock = session.getConnector().getWorldManager().getBlockAt(session, pos.getX(), pos.getY(), pos.getZ()); UpdateBlockPacket blockPacket = new UpdateBlockPacket(); blockPacket.setDataLayer(0); blockPacket.setBlockPosition(holderPos); @@ -121,7 +121,7 @@ public class DoubleChestInventoryTranslator extends BaseInventoryTranslator { holderPos = holderPos.add(Vector3i.UNIT_X); pos = new Position(holderPos.getX(), holderPos.getY(), holderPos.getZ()); - realBlock = session.getChunkCache().getBlockAt(pos); + realBlock = session.getConnector().getWorldManager().getBlockAt(session, pos.getX(), pos.getY(), pos.getZ()); blockPacket = new UpdateBlockPacket(); blockPacket.setDataLayer(0); blockPacket.setBlockPosition(holderPos); 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 a32354453..a6e5b2dd8 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 @@ -36,7 +36,7 @@ import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import lombok.AllArgsConstructor; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.utils.LocaleUtils; @@ -82,7 +82,7 @@ public class BlockInventoryHolder extends InventoryHolder { public void closeInventory(InventoryTranslator translator, GeyserSession session, Inventory inventory) { Vector3i holderPos = inventory.getHolderPosition(); Position pos = new Position(holderPos.getX(), holderPos.getY(), holderPos.getZ()); - BlockState realBlock = session.getChunkCache().getBlockAt(pos); + BlockState realBlock = session.getConnector().getWorldManager().getBlockAt(session, pos.getX(), pos.getY(), pos.getZ()); UpdateBlockPacket blockPacket = new UpdateBlockPacket(); blockPacket.setDataLayer(0); blockPacket.setBlockPosition(holderPos); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java index e9815ba67..9c072ad15 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ItemEntry.java @@ -32,13 +32,15 @@ import lombok.Getter; @AllArgsConstructor public class ItemEntry { - public static ItemEntry AIR = new ItemEntry("minecraft:air", 0, 0, 0); + public static ItemEntry AIR = new ItemEntry("minecraft:air", 0, 0, 0, false); private final String javaIdentifier; private final int javaId; private final int bedrockId; private final int bedrockData; + private final boolean block; + @Override public boolean equals(Object obj) { return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier())); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java b/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java index 5d1ddd262..cfc05a4a9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java @@ -7,8 +7,8 @@ public class ToolItemEntry extends ItemEntry { private final String toolType; private final String toolTier; - public ToolItemEntry(String javaIdentifier, int javaId, int bedrockId, int bedrockData, String toolType, String toolTier) { - super(javaIdentifier, javaId, bedrockId, bedrockData); + public ToolItemEntry(String javaIdentifier, int javaId, int bedrockId, int bedrockData, String toolType, String toolTier, boolean isBlock) { + super(javaIdentifier, javaId, bedrockId, bedrockData, isBlock); this.toolType = toolType; this.toolTier = toolTier; } 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 80be905c0..d62017c62 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 @@ -26,6 +26,7 @@ package org.geysermc.connector.network.translators.java.entity.player; 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.server.entity.player.ServerPlayerActionAckPacket; import com.github.steveice10.opennbt.tag.builtin.*; import com.nukkitx.math.vector.Vector3f; @@ -35,7 +36,7 @@ import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translators; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.utils.BlockUtils; import org.geysermc.connector.network.translators.Translator; @@ -49,17 +50,27 @@ public class JavaPlayerActionAckTranslator extends PacketTranslator { + + @Override + public void translate(ServerStopSoundPacket packet, GeyserSession session) { + String packetSound; + if(packet.getSound() instanceof BuiltinSound) { + packetSound = ((BuiltinSound) packet.getSound()).getName(); + } else if(packet.getSound() instanceof CustomSound) { + packetSound = ((CustomSound) packet.getSound()).getName(); + } else { + session.getConnector().getLogger().debug("Unknown sound packet, we were unable to map this. " + packet.toString()); + return; + } + SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound); + session.getConnector().getLogger() + .debug("[StopSound] Sound mapping " + packetSound + " -> " + + soundMapping + (soundMapping == null ? "[not found]" : "") + + " - " + packet.toString()); + String playsound; + if(soundMapping == null || soundMapping.getPlaysound() == null) { + // no mapping + session.getConnector().getLogger() + .debug("[StopSound] Defaulting to sound server gave us."); + playsound = packetSound; + } else { + playsound = soundMapping.getPlaysound(); + } + + StopSoundPacket stopSoundPacket = new StopSoundPacket(); + stopSoundPacket.setSoundName(playsound); + // packet not mapped in the library + stopSoundPacket.setStoppingAllSound(false); + + session.getUpstream().sendPacket(stopSoundPacket); + session.getConnector().getLogger().debug("[StopSound] Packet sent - " + packet.toString() + " --> " + stopSoundPacket); + } +} 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 b79525a9d..ea1970978 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 @@ -25,9 +25,15 @@ package org.geysermc.connector.network.translators.java.world; +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.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.utils.ChunkUtils; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerBlockChangePacket; @@ -37,6 +43,66 @@ public class JavaBlockChangeTranslator extends PacketTranslator { @@ -108,7 +108,7 @@ public class JavaChunkDataTranslator extends PacketTranslator { + + @Override + public void translate(ServerExplosionPacket packet, GeyserSession session) { + for (ExplodedBlockRecord record : packet.getExploded()) { + Vector3f pos = Vector3f.from(packet.getX() + record.getX(), packet.getY() + record.getY(), packet.getZ() + record.getZ()); + // Since bedrock does not play an explosion sound and particles sound, we have to manually do so + LevelEventPacket levelEventPacket = new LevelEventPacket(); + levelEventPacket.setType(LevelEventType.PARTICLE_LARGE_EXPLOSION); + levelEventPacket.setData(0); + levelEventPacket.setPosition(pos.toFloat()); + session.getUpstream().sendPacket(levelEventPacket); + ChunkUtils.updateBlock(session, BlockTranslator.AIR, pos.toInt()); + } + LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); + levelSoundEventPacket.setRelativeVolumeDisabled(false); + levelSoundEventPacket.setBabySound(false); + levelSoundEventPacket.setExtraData(-1); + levelSoundEventPacket.setSound(SoundEvent.EXPLODE); + levelSoundEventPacket.setIdentifier(":"); + levelSoundEventPacket.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + session.getUpstream().sendPacket(levelSoundEventPacket); + } +} 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 new file mode 100644 index 000000000..aa4ade4ad --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayBuiltinSoundTranslator.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.java.world; + +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerPlayBuiltinSoundPacket; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.utils.SoundUtils; + +@Translator(packet = ServerPlayBuiltinSoundPacket.class) +public class JavaPlayBuiltinSoundTranslator extends PacketTranslator { + + @Override + public void translate(ServerPlayBuiltinSoundPacket packet, GeyserSession session) { + String packetSound = packet.getSound().getName(); + + SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound); + session.getConnector().getLogger().debug("[Builtin] Sound mapping " + packetSound + " -> " + + soundMapping + (soundMapping == null ? "[not found]" : "") + + " - " + packet.toString()); + if (soundMapping == null) { + return; + } + + if (soundMapping.isLevelEvent()) { + LevelEventPacket levelEventPacket = new LevelEventPacket(); + levelEventPacket.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + levelEventPacket.setData(0); + levelEventPacket.setType(LevelEventType.valueOf(soundMapping.getBedrock())); + session.getUpstream().sendPacket(levelEventPacket); + return; + } + LevelSoundEventPacket soundPacket = new LevelSoundEventPacket(); + SoundEvent sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); + if (sound == null) { + sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); + } + if (sound == null) { + sound = SoundUtils.toSoundEvent(packetSound); + } + if (sound == null) { + session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket + + " was not a playable level sound, or has yet to be mapped to an enum in " + + "NukkitX SoundEvent "); + + } + soundPacket.setSound(sound); + soundPacket.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + soundPacket.setIdentifier(soundMapping.getIdentifier()); + if (sound == SoundEvent.NOTE) { + // Minecraft Wiki: 2^(x/12) = Java pitch where x is -12 to 12 + // Java sends the note value as above starting with -12 and ending at 12 + // Bedrock has a number for each type of note, then proceeds up the scale by adding to that number + soundPacket.setExtraData(soundMapping.getExtraData() + (int)(Math.round((Math.log10(packet.getPitch()) / Math.log10(2)) * 12)) + 12); + } else if (sound == SoundEvent.PLACE && soundMapping.getExtraData() == -1) { + soundPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(soundMapping.getIdentifier()))); + soundPacket.setIdentifier(":"); + } else { + soundPacket.setExtraData(soundMapping.getExtraData()); + } + + + soundPacket.setBabySound(false); // might need to adjust this in the future + soundPacket.setRelativeVolumeDisabled(false); + session.getUpstream().sendPacket(soundPacket); + session.getConnector().getLogger().debug("Packet sent - " + packet.toString() + " --> " + soundPacket.toString()); + } +} 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 new file mode 100644 index 000000000..e22db97e1 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayEffectTranslator.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.java.world; + +import com.github.steveice10.mc.protocol.data.game.world.effect.ParticleEffect; +import com.github.steveice10.mc.protocol.data.game.world.effect.*; +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerPlayEffectPacket; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +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 org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.network.translators.effect.Effect; +import org.geysermc.connector.utils.EffectUtils; + +@Translator(packet = ServerPlayEffectPacket.class) +public class JavaPlayEffectTranslator extends PacketTranslator { + + @Override + public void translate(ServerPlayEffectPacket packet, GeyserSession session) { + LevelEventPacket effect = new LevelEventPacket(); + // Some things here are particles, others are not + if (packet.getEffect() instanceof ParticleEffect) { + ParticleEffect particleEffect = (ParticleEffect) packet.getEffect(); + Effect geyserEffect = EffectUtils.EFFECTS.get(particleEffect.name()); + if (geyserEffect != null) { + String name = geyserEffect.getBedrockName(); + effect.setType(LevelEventType.valueOf(name)); + } else { + switch (particleEffect) { + // TODO: BREAK_SPLASH_POTION has additional data + case BONEMEAL_GROW: + effect.setType(LevelEventType.BONEMEAL); + BonemealGrowEffectData growEffectData = (BonemealGrowEffectData) packet.getData(); + effect.setData(growEffectData.getParticleCount()); + break; + //TODO: Block break particles when under fire + case BREAK_BLOCK: + effect.setType(LevelEventType.DESTROY); + BreakBlockEffectData breakBlockEffectData = (BreakBlockEffectData) packet.getData(); + effect.setData(BlockTranslator.getBedrockBlockId(breakBlockEffectData.getBlockState())); + break; + case EXPLOSION: + effect.setType(LevelEventType.PARTICLE_LARGE_EXPLOSION); + break; + case MOB_SPAWN: + effect.setType(LevelEventType.ENTITY_SPAWN); + break; + // Done with a dispenser + case SMOKE: + // Might need to be SHOOT + effect.setType(LevelEventType.PARTICLE_SMOKE); + break; + case COMPOSTER: + effect.setType(LevelEventType.BONEMEAL); + + ComposterEffectData composterEffectData = (ComposterEffectData) packet.getData(); + LevelSoundEventPacket soundEvent = new LevelSoundEventPacket(); + soundEvent.setSound(SoundEvent.valueOf("COMPOSTER_" + composterEffectData.name())); + soundEvent.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ())); + soundEvent.setIdentifier(":"); + soundEvent.setExtraData(-1); + soundEvent.setBabySound(false); + soundEvent.setRelativeVolumeDisabled(false); + session.getUpstream().sendPacket(soundEvent); + break; + case BLOCK_LAVA_EXTINGUISH: + effect.setType(LevelEventType.SHOOT); + effect.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY() + 1, packet.getPosition().getZ())); + session.getUpstream().sendPacket(effect); + + LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); + soundEventPacket.setSound(SoundEvent.EXTINGUISH_FIRE); + soundEventPacket.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ())); + soundEventPacket.setIdentifier(":"); + soundEventPacket.setExtraData(-1); + soundEventPacket.setBabySound(false); + soundEventPacket.setRelativeVolumeDisabled(false); + session.getUpstream().sendPacket(soundEventPacket); + return; + default: + GeyserConnector.getInstance().getLogger().debug("No effect handling for particle effect: " + packet.getEffect()); + } + } + effect.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ())); + session.getUpstream().sendPacket(effect); + } else if (packet.getEffect() instanceof SoundEffect) { + SoundEffect soundEffect = (SoundEffect) packet.getEffect(); + Effect geyserEffect = EffectUtils.EFFECTS.get(soundEffect.name()); + if (geyserEffect != null) { + // Some events are LevelEventTypes, some are SoundEvents. + if (geyserEffect.getType().equals("soundLevel")) { + effect.setType(LevelEventType.valueOf(geyserEffect.getBedrockName())); + } else if (geyserEffect.getType().equals("soundEvent")) { + LevelSoundEventPacket soundEvent = new LevelSoundEventPacket(); + // Separate case since each RecordEffectData in Java is an individual track in Bedrock + if (geyserEffect.getJavaName().equals("RECORD")) { + RecordEffectData recordEffectData = (RecordEffectData) packet.getData(); + soundEvent.setSound(EffectUtils.RECORDS.get(recordEffectData.getRecordId())); + } else { + soundEvent.setSound(SoundEvent.valueOf(geyserEffect.getBedrockName())); + } + soundEvent.setExtraData(geyserEffect.getData()); + soundEvent.setIdentifier(geyserEffect.getIdentifier()); + soundEvent.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ())); + session.getUpstream().sendPacket(soundEvent); + } + } else { + GeyserConnector.getInstance().getLogger().debug("No effect handling for sound effect: " + packet.getEffect()); + } + } + if (effect.getType() != null) { + effect.setPosition(Vector3f.from(packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ())); + session.getUpstream().sendPacket(effect); + } + + } +} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayerPlaySoundTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayerPlaySoundTranslator.java new file mode 100644 index 000000000..effb71c5f --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaPlayerPlaySoundTranslator.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + * + */ + +package org.geysermc.connector.network.translators.java.world; + +import com.github.steveice10.mc.protocol.data.game.world.sound.BuiltinSound; +import com.github.steveice10.mc.protocol.data.game.world.sound.CustomSound; +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerPlaySoundPacket; +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.packet.*; +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.SoundUtils; + +@Translator(packet = ServerPlaySoundPacket.class) +public class JavaPlayerPlaySoundTranslator extends PacketTranslator { + + @Override + public void translate(ServerPlaySoundPacket packet, GeyserSession session) { + String packetSound; + if(packet.getSound() instanceof BuiltinSound) { + packetSound = ((BuiltinSound) packet.getSound()).getName(); + } else if(packet.getSound() instanceof CustomSound) { + packetSound = ((CustomSound) packet.getSound()).getName(); + } else { + session.getConnector().getLogger().debug("Unknown sound packet, we were unable to map this. " + packet.toString()); + return; + } + + SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound.replace("minecraft:", "")); + session.getConnector().getLogger() + .debug("[PlaySound] Sound mapping " + packetSound + " -> " + + soundMapping + (soundMapping == null ? "[not found]" : "") + + " - " + packet.toString()); + String playsound; + if(soundMapping == null || soundMapping.getPlaysound() == null) { + // no mapping + session.getConnector().getLogger() + .debug("[PlaySound] Defaulting to sound server gave us."); + playsound = packetSound; + } else { + playsound = soundMapping.getPlaysound(); + } + + PlaySoundPacket playSoundPacket = new PlaySoundPacket(); + playSoundPacket.setSound(playsound); + playSoundPacket.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + playSoundPacket.setVolume(packet.getVolume()); + playSoundPacket.setPitch(packet.getPitch()); + + session.getUpstream().sendPacket(playSoundPacket); + session.getConnector().getLogger().debug("[PlaySound] Packet sent - " + packet.toString() + " --> " + playSoundPacket); + } +} 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 new file mode 100644 index 000000000..1f9bcba35 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaSpawnParticleTranslator.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.network.translators.java.world; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.github.steveice10.mc.protocol.data.game.world.particle.*; +import com.nukkitx.protocol.bedrock.data.ItemData; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import com.nukkitx.protocol.bedrock.packet.SpawnParticleEffectPacket; +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.Translators; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.utils.EffectUtils; + +import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerSpawnParticlePacket; +import com.nukkitx.math.vector.Vector3f; + +@Translator(packet = ServerSpawnParticlePacket.class) +public class JavaSpawnParticleTranslator extends PacketTranslator { + + @Override + public void translate(ServerSpawnParticlePacket packet, GeyserSession session) { + LevelEventPacket particle = new LevelEventPacket(); + switch (packet.getParticle().getType()) { + case BLOCK: + particle.setType(LevelEventType.DESTROY); + particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + particle.setData(BlockTranslator.getBedrockBlockId(((BlockParticleData) packet.getParticle().getData()).getBlockState())); + session.getUpstream().sendPacket(particle); + break; + case FALLING_DUST: + //In fact, FallingDustParticle should have data like DustParticle, + //but in MCProtocol, its data is BlockState(1). + particle.setType(LevelEventType.PARTICLE_FALLING_DUST); + particle.setData(BlockTranslator.getBedrockBlockId(((FallingDustParticleData)packet.getParticle().getData()).getBlockState())); + particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + session.getUpstream().sendPacket(particle); + break; + case ITEM: + ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack(); + ItemData bedrockItem = Translators.getItemTranslator().translateToBedrock(session, javaItem); + int id = bedrockItem.getId(); + short damage = bedrockItem.getDamage(); + particle.setType(LevelEventType.PARTICLE_ITEM_BREAK); + particle.setData(id << 16 | damage); + particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + session.getUpstream().sendPacket(particle); + break; + case DUST: + DustParticleData data = (DustParticleData)packet.getParticle().getData(); + int r = (int) (data.getRed()*255); + int g = (int) (data.getGreen()*255); + int b = (int) (data.getBlue()*255); + particle.setType(LevelEventType.PARTICLE_FALLING_DUST); + particle.setData(((0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)); + particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + session.getUpstream().sendPacket(particle); + break; + default: + LevelEventType typeParticle = EffectUtils.getParticleLevelEventType(packet.getParticle().getType()); + if (typeParticle != null) { + particle.setType(typeParticle); + particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + session.getUpstream().sendPacket(particle); + } else { + String stringParticle = EffectUtils.getParticleString(packet.getParticle().getType()); + if (stringParticle != null) { + SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket(); + stringPacket.setIdentifier(stringParticle); + stringPacket.setDimensionId(session.getPlayerEntity().getDimension()); + stringPacket.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ())); + session.getUpstream().sendPacket(stringPacket); + } + } + break; + } + } + +} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUnloadChunkTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUnloadChunkTranslator.java index 02c693d87..d54d8b6a8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUnloadChunkTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUnloadChunkTranslator.java @@ -28,7 +28,7 @@ package org.geysermc.connector.network.translators.java.world; 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.world.chunk.ChunkPosition; +import org.geysermc.connector.network.translators.world.chunk.ChunkPosition; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUnloadChunkPacket; 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 b1158ef1d..5c55efed6 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 @@ -30,8 +30,8 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdate 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.block.entity.BlockEntity; -import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.world.block.entity.BlockEntity; +import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; import org.geysermc.connector.utils.BlockEntityUtils; import org.geysermc.connector.utils.ChunkUtils; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/BlockSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/BlockSoundInteractionHandler.java new file mode 100644 index 000000000..579539a1e --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/BlockSoundInteractionHandler.java @@ -0,0 +1,87 @@ +/* + * 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.sound; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.nukkitx.math.vector.Vector3f; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.Translators; + +import java.util.Map; + +/** + * Sound interaction handler for when a block is right-clicked. + */ +public interface BlockSoundInteractionHandler extends SoundInteractionHandler { + + /** + * Handles the block interaction when a player + * right-clicks a block. + * + * @param session the session interacting with the block + * @param position the position of the block + * @param identifier the identifier of the block + */ + static void handleBlockInteraction(GeyserSession session, Vector3f position, String identifier) { + for (Map.Entry> interactionEntry : SoundHandlerRegistry.INTERACTION_HANDLERS.entrySet()) { + if (!(interactionEntry.getValue() instanceof BlockSoundInteractionHandler)) { + continue; + } + if (interactionEntry.getKey().blocks().length != 0) { + boolean contains = false; + for (String blockIdentifier : interactionEntry.getKey().blocks()) { + if (identifier.contains(blockIdentifier)) { + contains = true; + break; + } + } + if (!contains) continue; + } + ItemStack itemInHand = session.getInventory().getItemInHand(); + if (interactionEntry.getKey().items().length != 0) { + if (itemInHand == null || itemInHand.getId() == 0) { + continue; + } + String handIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier(); + boolean contains = false; + for (String itemIdentifier : interactionEntry.getKey().items()) { + if (handIdentifier.contains(itemIdentifier)) { + contains = true; + break; + } + } + if (!contains) continue; + } + if (session.isSneaking() && !interactionEntry.getKey().ignoreSneakingWhileHolding()) { + if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() != 0) { + continue; + } + } + ((BlockSoundInteractionHandler) interactionEntry.getValue()).handleInteraction(session, position, identifier); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/EntitySoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/EntitySoundInteractionHandler.java new file mode 100644 index 000000000..3e0626908 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/EntitySoundInteractionHandler.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + * + */ + +package org.geysermc.connector.network.translators.sound; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; +import com.nukkitx.math.vector.Vector3f; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.Translators; + +import java.util.Map; + +/** + * Sound interaction handler for when an entity is right-clicked. + */ +public interface EntitySoundInteractionHandler extends SoundInteractionHandler { + + /** + * Handles the block interaction when a player + * right-clicks an entity. + * + * @param session the session interacting with the block + * @param position the position of the block + * @param entity the entity interacted with + */ + static void handleEntityInteraction(GeyserSession session, Vector3f position, Entity entity) { + for (Map.Entry> interactionEntry : SoundHandlerRegistry.INTERACTION_HANDLERS.entrySet()) { + if (!(interactionEntry.getValue() instanceof EntitySoundInteractionHandler)) { + continue; + } + if (interactionEntry.getKey().entities().length != 0) { + boolean contains = false; + for (String entityIdentifier : interactionEntry.getKey().entities()) { + if (entity.getEntityType().name().toLowerCase().contains(entityIdentifier)) { + contains = true; + break; + } + } + if (!contains) continue; + } + ItemStack itemInHand = session.getInventory().getItemInHand(); + if (interactionEntry.getKey().items().length != 0) { + if (itemInHand == null || itemInHand.getId() == 0) { + continue; + } + String handIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier(); + boolean contains = false; + for (String itemIdentifier : interactionEntry.getKey().items()) { + if (handIdentifier.contains(itemIdentifier)) { + contains = true; + break; + } + } + if (!contains) continue; + } + if (session.isSneaking() && !interactionEntry.getKey().ignoreSneakingWhileHolding()) { + if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() != 0) { + continue; + } + } + ((EntitySoundInteractionHandler) interactionEntry.getValue()).handleInteraction(session, position, entity); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandler.java new file mode 100644 index 000000000..52a76aa3b --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandler.java @@ -0,0 +1,78 @@ +/* + * 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.sound; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Marks if a class should be handled as a + * {@link SoundInteractionHandler}. + */ +@Retention(value = RetentionPolicy.RUNTIME) +public @interface SoundHandler { + + /** + * The identifier(s) that the placed block must contain + * one of. Leave empty to ignore. + * + * Only applies to interaction handlers that are an + * instance of {@link BlockSoundInteractionHandler}. + * + * @return the value the interacted block must contain + */ + String[] blocks() default {}; + + /** + * The identifier(s) that the player's hand item + * must contain one of. Leave empty to ignore. + * + * @return the value the item in the player's hand must contain + */ + String[] items() default {}; + + /** + * The identifier(s) that the interacted entity must have. + * Leave empty to ignore. + * + * Only applies to interaction handlers that are an + * instance of {@link BlockSoundInteractionHandler}. + * + * @return the value the item in the player's hand must contain + */ + String[] entities() default {}; + + /** + * Controls if the interaction should still be + * called even if the player is sneaking while + * holding something in their hand. + * + * @return if the interaction should continue when player + * is holding something in their hand + */ + boolean ignoreSneakingWhileHolding() default false; +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandlerRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandlerRegistry.java new file mode 100644 index 000000000..260efb416 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundHandlerRegistry.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + * + */ + +package org.geysermc.connector.network.translators.sound; + +import org.reflections.Reflections; + +import java.util.HashMap; +import java.util.Map; + +/** + * Registry that holds {@link SoundInteractionHandler}s. + */ +public class SoundHandlerRegistry { + + static final Map> INTERACTION_HANDLERS = new HashMap<>(); + + static { + Reflections ref = new Reflections("org.geysermc.connector.network.translators.sound"); + for (Class clazz : ref.getTypesAnnotatedWith(SoundHandler.class)) { + try { + SoundInteractionHandler interactionHandler = (SoundInteractionHandler) clazz.newInstance(); + SoundHandler annotation = clazz.getAnnotation(SoundHandler.class); + INTERACTION_HANDLERS.put(annotation, interactionHandler); + } catch (InstantiationException | IllegalAccessException ex) { + ex.printStackTrace(); + } + } + } + + private SoundHandlerRegistry() { + } + + public static void init() { + // no-op + } + + /** + * Returns a map of the interaction handlers + * + * @return a map of the interaction handlers + */ + public static Map> getInteractionHandlers() { + return INTERACTION_HANDLERS; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundInteractionHandler.java new file mode 100644 index 000000000..e68061ef4 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/SoundInteractionHandler.java @@ -0,0 +1,53 @@ +/* + * 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.sound; + +import com.nukkitx.math.vector.Vector3f; + +import org.geysermc.connector.network.session.GeyserSession; + +/** + * Handler for playing sounds when right-clicking + * various objects. Due to Minecraft: Bedrock Edition + * expecting interaction sounds to be played serverside + * and Minecraft: Java Edition handling them clientside, + * this had to be made to handle scenarios like that. + * + * @param the value + */ +public interface SoundInteractionHandler { + + /** + * Handles the interaction when a player + * right-clicks a block. + * + * @param session the session interacting with the block + * @param position the position of the block + * @param value the value + */ + void handleInteraction(GeyserSession session, Vector3f position, T value); +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/BucketSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/BucketSoundInteractionHandler.java new file mode 100644 index 000000000..00269cc7f --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/BucketSoundInteractionHandler.java @@ -0,0 +1,73 @@ +/* + * 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.sound.block; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.Translators; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; + +@SoundHandler(items = "bucket") +public class BucketSoundInteractionHandler implements BlockSoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { + String handItemIdentifier = Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier(); + LevelSoundEventPacket soundEventPacket = new LevelSoundEventPacket(); + soundEventPacket.setPosition(position); + soundEventPacket.setIdentifier(":"); + soundEventPacket.setRelativeVolumeDisabled(false); + soundEventPacket.setBabySound(false); + soundEventPacket.setExtraData(-1); + SoundEvent soundEvent = null; + switch (handItemIdentifier) { + case "minecraft:bucket": + if (identifier.contains("water[")) { + soundEvent = SoundEvent.BUCKET_FILL_WATER; + } else if (identifier.contains("lava[")) { + soundEvent = SoundEvent.BUCKET_FILL_LAVA; + } + break; + case "minecraft:lava_bucket": + soundEvent = SoundEvent.BUCKET_EMPTY_LAVA; + break; + case "minecraft:fish_bucket": + soundEvent = SoundEvent.BUCKET_EMPTY_FISH; + break; + case "minecraft:water_bucket": + soundEvent = SoundEvent.BUCKET_EMPTY_WATER; + break; + } + if (soundEvent != null) { + soundEventPacket.setSound(soundEvent); + session.getUpstream().sendPacket(soundEventPacket); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java new file mode 100644 index 000000000..260ad814f --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/ComparatorSoundInteractHandler.java @@ -0,0 +1,48 @@ +/* + * 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.sound.block; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; + +@SoundHandler(blocks = "comparator") +public class ComparatorSoundInteractHandler implements BlockSoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { + boolean powered = identifier.contains("mode=compare"); + LevelEventPacket levelEventPacket = new LevelEventPacket(); + levelEventPacket.setPosition(position); + levelEventPacket.setType(LevelEventType.REDSTONE_TRIGGER); + levelEventPacket.setData(powered ? 500 : 550); + session.getUpstream().sendPacket(levelEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java new file mode 100644 index 000000000..b8e2854d5 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/DoorSoundInteractionHandler.java @@ -0,0 +1,47 @@ +/* + * 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.sound.block; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; + +@SoundHandler(blocks = {"door", "fence_gate"}) +public class DoorSoundInteractionHandler implements BlockSoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { + LevelEventPacket levelEventPacket = new LevelEventPacket(); + levelEventPacket.setType(LevelEventType.SOUND_DOOR); + levelEventPacket.setPosition(position); + levelEventPacket.setData(0); + session.getUpstream().sendPacket(levelEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/FlintAndSteelInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/FlintAndSteelInteractionHandler.java new file mode 100644 index 000000000..b28133b34 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/FlintAndSteelInteractionHandler.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.network.translators.sound.block; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; + +@SoundHandler(items = "flint_and_steel", ignoreSneakingWhileHolding = true) +public class FlintAndSteelInteractionHandler implements BlockSoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { + LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); + levelSoundEventPacket.setPosition(position); + levelSoundEventPacket.setBabySound(false); + levelSoundEventPacket.setRelativeVolumeDisabled(false); + levelSoundEventPacket.setIdentifier(":"); + levelSoundEventPacket.setSound(SoundEvent.IGNITE); + levelSoundEventPacket.setExtraData(-1); + session.getUpstream().sendPacket(levelSoundEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/GrassPathInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/GrassPathInteractionHandler.java new file mode 100644 index 000000000..e29571036 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/GrassPathInteractionHandler.java @@ -0,0 +1,51 @@ +/* + * 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.sound.block; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; + +@SoundHandler(blocks = "grass_path", items = "shovel", ignoreSneakingWhileHolding = true) +public class GrassPathInteractionHandler implements BlockSoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { + LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); + levelSoundEventPacket.setPosition(position); + levelSoundEventPacket.setBabySound(false); + levelSoundEventPacket.setRelativeVolumeDisabled(false); + levelSoundEventPacket.setIdentifier(":"); + levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON); + levelSoundEventPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier))); + session.getUpstream().sendPacket(levelSoundEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/HoeInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/HoeInteractionHandler.java new file mode 100644 index 000000000..c9d4299b4 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/HoeInteractionHandler.java @@ -0,0 +1,51 @@ +/* + * 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.sound.block; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; + +@SoundHandler(blocks = "farmland", items = "hoe", ignoreSneakingWhileHolding = true) +public class HoeInteractionHandler implements BlockSoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { + LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); + levelSoundEventPacket.setPosition(position); + levelSoundEventPacket.setBabySound(false); + levelSoundEventPacket.setRelativeVolumeDisabled(false); + levelSoundEventPacket.setIdentifier(":"); + levelSoundEventPacket.setSound(SoundEvent.ITEM_USE_ON); + levelSoundEventPacket.setExtraData(BlockTranslator.getBedrockBlockId(BlockTranslator.getJavaBlockState(identifier))); + session.getUpstream().sendPacket(levelSoundEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java new file mode 100644 index 000000000..cfbe7727d --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/block/LeverSoundInteractionHandler.java @@ -0,0 +1,48 @@ +/* + * 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.sound.block; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; + +@SoundHandler(blocks = "lever") +public class LeverSoundInteractionHandler implements BlockSoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, String identifier) { + boolean powered = identifier.contains("powered=true"); + LevelEventPacket levelEventPacket = new LevelEventPacket(); + levelEventPacket.setPosition(position); + levelEventPacket.setType(LevelEventType.REDSTONE_TRIGGER); + levelEventPacket.setData(powered ? 600 : 500); + session.getUpstream().sendPacket(levelEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/sound/entity/MilkCowSoundInteractionHandler.java b/connector/src/main/java/org/geysermc/connector/network/translators/sound/entity/MilkCowSoundInteractionHandler.java new file mode 100644 index 000000000..d4046eea7 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/sound/entity/MilkCowSoundInteractionHandler.java @@ -0,0 +1,55 @@ +/* + * 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.sound.entity; + +import com.nukkitx.math.vector.Vector3f; +import com.nukkitx.protocol.bedrock.data.SoundEvent; +import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket; +import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.Translators; +import org.geysermc.connector.network.translators.sound.EntitySoundInteractionHandler; +import org.geysermc.connector.network.translators.sound.SoundHandler; + +@SoundHandler(entities = "cow", items = "bucket") +public class MilkCowSoundInteractionHandler implements EntitySoundInteractionHandler { + + @Override + public void handleInteraction(GeyserSession session, Vector3f position, Entity value) { + if (!Translators.getItemTranslator().getItem(session.getInventory().getItemInHand()).getJavaIdentifier().equals("minecraft:bucket")) { + return; + } + LevelSoundEventPacket levelSoundEventPacket = new LevelSoundEventPacket(); + levelSoundEventPacket.setPosition(position); + levelSoundEventPacket.setBabySound(false); + levelSoundEventPacket.setRelativeVolumeDisabled(false); + levelSoundEventPacket.setIdentifier(":"); + levelSoundEventPacket.setSound(SoundEvent.MILK); + levelSoundEventPacket.setExtraData(-1); + session.getUpstream().sendPacket(levelSoundEventPacket); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/CachedChunkManager.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/CachedChunkManager.java new file mode 100644 index 000000000..740e2df93 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/CachedChunkManager.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.network.translators.world; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; +import org.geysermc.connector.network.session.GeyserSession; + +public class CachedChunkManager extends WorldManager { + + @Override + public BlockState getBlockAt(GeyserSession session, int x, int y, int z) { + return session.getChunkCache().getBlockAt(new Position(x, y, z)); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/WorldManager.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/WorldManager.java new file mode 100644 index 000000000..0890aed62 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/WorldManager.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.network.translators.world; + +import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; + +import org.geysermc.connector.network.session.GeyserSession; + +/** + * Class that manages or retrieves various information + * from the world. Everything in this class should be + * safe to return null or an empty value in the event + * that chunk caching or anything of the sort is disabled + * on the standalone version of Geyser. + */ +public abstract class WorldManager { + + /** + * Gets the {@link BlockState} at the specified location + * + * @param session the session + * @param x the x coordinate to get the block at + * @param y the y coordinate to get the block at + * @param z the z coordinate to get the block at + * @return the block state at the specified location + */ + public abstract BlockState getBlockAt(GeyserSession session, int x, int y, int z); +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockStateValues.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java similarity index 99% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/BlockStateValues.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java index 87966fd1d..00d7171cf 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockStateValues.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockStateValues.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block; +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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java similarity index 96% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java index 650a494bb..2bb918cc8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/BlockTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/BlockTranslator.java @@ -23,10 +23,12 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block; +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; import com.nukkitx.nbt.NbtUtils; import com.nukkitx.nbt.stream.NBTInputStream; @@ -36,7 +38,7 @@ import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.network.translators.block.entity.BlockEntity; +import org.geysermc.connector.network.translators.world.block.entity.BlockEntity; import org.geysermc.connector.utils.Toolbox; import org.reflections.Reflections; @@ -50,7 +52,7 @@ public class BlockTranslator { 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 Map JAVA_ID_BLOCK_MAP = new HashMap<>(); + 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<>(); @@ -99,7 +101,7 @@ public class BlockTranslator { addedStatesMap.defaultReturnValue(-1); List paletteList = new ArrayList<>(); - Reflections ref = new Reflections("org.geysermc.connector.network.translators.block.entity"); + Reflections ref = new Reflections("org.geysermc.connector.network.translators.world.block.entity"); ref.getTypesAnnotatedWith(BlockEntity.class); int waterRuntimeId = -1; @@ -279,6 +281,10 @@ public class BlockTranslator { return WATERLOGGED.contains(state.getId()); } + public static BiMap getJavaIdBlockMap() { + return JAVA_ID_BLOCK_MAP; + } + public static BlockState 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/block/entity/BannerBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java similarity index 96% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java index e81191a39..2034b3d52 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BannerBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BannerBlockEntityTranslator.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +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; @@ -32,7 +32,7 @@ import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.tag.IntTag; import com.nukkitx.nbt.tag.StringTag; import com.nukkitx.nbt.tag.Tag; -import org.geysermc.connector.network.translators.block.BlockStateValues; +import org.geysermc.connector.network.translators.world.block.BlockStateValues; import java.util.ArrayList; import java.util.List; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BedBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java similarity index 94% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BedBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java index a8dae2532..543828e8e 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BedBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BedBlockEntityTranslator.java @@ -23,14 +23,14 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +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; import com.nukkitx.nbt.tag.Tag; -import org.geysermc.connector.network.translators.block.BlockStateValues; +import org.geysermc.connector.network.translators.world.block.BlockStateValues; import java.util.ArrayList; import java.util.List; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntity.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntity.java similarity index 96% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntity.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntity.java index 47cbbaf30..d08ab561c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntity.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntity.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +package org.geysermc.connector.network.translators.world.block.entity; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java similarity index 98% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java index f28257898..4545aed53 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/BlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/BlockEntityTranslator.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java similarity index 98% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java index 11b7e8649..d91e47c27 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/CampfireBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/CampfireBlockEntityTranslator.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java similarity index 96% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java index e46014008..f95cb89ec 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EmptyBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EmptyBlockEntityTranslator.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EndGatewayBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java similarity index 98% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EndGatewayBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java index de5868a4b..10de9d32d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/EndGatewayBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/NoteblockBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java similarity index 94% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/NoteblockBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java index ba9ac0de8..c538f09eb 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/NoteblockBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/NoteblockBlockEntityTranslator.java @@ -24,14 +24,14 @@ * */ -package org.geysermc.connector.network.translators.block.entity; +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; -import org.geysermc.connector.network.translators.block.BlockStateValues; +import org.geysermc.connector.network.translators.world.block.BlockStateValues; import org.geysermc.connector.utils.ChunkUtils; /** diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/RequiresBlockState.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/RequiresBlockState.java similarity index 95% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/RequiresBlockState.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/RequiresBlockState.java index ed8e6ede9..4df7292ad 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/RequiresBlockState.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/RequiresBlockState.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.mc.protocol.data.game.world.block.BlockState; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ShulkerBoxBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java similarity index 50% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ShulkerBoxBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java index 3d409a093..b0b8fa3d4 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/ShulkerBoxBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/ShulkerBoxBlockEntityTranslator.java @@ -1,36 +1,37 @@ /* * 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.connector.network.translators.block.entity; +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; import com.nukkitx.nbt.tag.Tag; -import org.geysermc.connector.network.translators.block.BlockStateValues; +import org.geysermc.connector.network.translators.world.block.BlockStateValues; import java.util.ArrayList; import java.util.List; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java similarity index 97% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java index 74dcdd13e..0dde33077 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SignBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java @@ -23,7 +23,7 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.block.entity; +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; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SkullBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java similarity index 93% rename from connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SkullBlockEntityTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java index 2380663b1..7e73c8466 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/block/entity/SkullBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java @@ -1,71 +1,71 @@ -/* - * 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.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; -import com.nukkitx.nbt.tag.FloatTag; -import com.nukkitx.nbt.tag.Tag; -import org.geysermc.connector.network.translators.block.BlockStateValues; - -import java.util.ArrayList; -import java.util.List; - -@BlockEntity(name = "Skull", delay = false, regex = "skull") -public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { - - @Override - public boolean isBlock(BlockState blockState) { - return BlockStateValues.getSkullVariant(blockState) != -1; - } - - @Override - public List> translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, BlockState blockState) { - List> tags = new ArrayList<>(); - 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)); - return tags; - } - - @Override - public com.github.steveice10.opennbt.tag.builtin.CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { - return null; - } - - @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(); - } -} +/* + * 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.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; +import com.nukkitx.nbt.tag.FloatTag; +import com.nukkitx.nbt.tag.Tag; +import org.geysermc.connector.network.translators.world.block.BlockStateValues; + +import java.util.ArrayList; +import java.util.List; + +@BlockEntity(name = "Skull", delay = false, regex = "skull") +public class SkullBlockEntityTranslator extends BlockEntityTranslator implements RequiresBlockState { + + @Override + public boolean isBlock(BlockState blockState) { + return BlockStateValues.getSkullVariant(blockState) != -1; + } + + @Override + public List> translateTag(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag, BlockState blockState) { + List> tags = new ArrayList<>(); + 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)); + return tags; + } + + @Override + public com.github.steveice10.opennbt.tag.builtin.CompoundTag getDefaultJavaTag(String javaId, int x, int y, int z) { + return null; + } + + @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(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/BlockStorage.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/BlockStorage.java similarity index 68% rename from connector/src/main/java/org/geysermc/connector/world/chunk/BlockStorage.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/BlockStorage.java index 360fdea45..5995ecf9e 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/BlockStorage.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/BlockStorage.java @@ -1,21 +1,37 @@ /* * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * - * This code in this file is derived from NukkitX and permission has - * been granted to us allowing the usage of it in Geyser. + * 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 * - * Copyright (C) 2020 The NukkitX Project - * https://github.com/NukkitX/Nukkit */ -package org.geysermc.connector.world.chunk; +package org.geysermc.connector.network.translators.world.chunk; import com.nukkitx.network.VarInts; import io.netty.buffer.ByteBuf; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; -import org.geysermc.connector.world.chunk.bitarray.BitArray; -import org.geysermc.connector.world.chunk.bitarray.BitArrayVersion; +import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArray; +import org.geysermc.connector.network.translators.world.chunk.bitarray.BitArrayVersion; import java.util.function.IntConsumer; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/ChunkPosition.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/ChunkPosition.java new file mode 100644 index 000000000..a51755d0b --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/ChunkPosition.java @@ -0,0 +1,54 @@ +/* + * 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.world.chunk; + +import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@EqualsAndHashCode +public class ChunkPosition { + + private int x; + private int z; + + public Position getBlock(int x, int y, int z) { + return new Position((this.x << 4) + x, y, (this.z << 4) + z); + } + + public Position getChunkBlock(int x, int y, int z) { + int chunkX = x & 15; + int chunkY = y & 15; + int chunkZ = z & 15; + return new Position(chunkX, chunkY, chunkZ); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkSection.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/ChunkSection.java similarity index 77% rename from connector/src/main/java/org/geysermc/connector/world/chunk/ChunkSection.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/ChunkSection.java index c160d11b3..4ede0c255 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/ChunkSection.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/ChunkSection.java @@ -1,14 +1,30 @@ /* * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * - * This code in this file is derived from NukkitX and permission has - * been granted to us allowing the usage of it in Geyser. + * 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 * - * Copyright (C) 2020 The NukkitX Project - * https://github.com/NukkitX/Nukkit */ -package org.geysermc.connector.world.chunk; +package org.geysermc.connector.network.translators.world.chunk; import com.nukkitx.network.util.Preconditions; import io.netty.buffer.ByteBuf; diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/NibbleArray.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/NibbleArray.java similarity index 62% rename from connector/src/main/java/org/geysermc/connector/world/chunk/NibbleArray.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/NibbleArray.java index 8da068f75..08303e189 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/NibbleArray.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/NibbleArray.java @@ -1,14 +1,30 @@ /* * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * - * This code in this file is derived from NukkitX and permission has - * been granted to us allowing the usage of it in Geyser. + * 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 * - * Copyright (C) 2020 The NukkitX Project - * https://github.com/NukkitX/Nukkit */ -package org.geysermc.connector.world.chunk; +package org.geysermc.connector.network.translators.world.chunk; import com.nukkitx.network.util.Preconditions; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/BitArray.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/BitArray.java new file mode 100644 index 000000000..728fe237e --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/BitArray.java @@ -0,0 +1,42 @@ +/* + * 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.world.chunk.bitarray; + +public interface BitArray { + + void set(int index, int value); + + int get(int index); + + int size(); + + int[] getWords(); + + BitArrayVersion getVersion(); + + BitArray copy(); +} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/BitArrayVersion.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/BitArrayVersion.java similarity index 60% rename from connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/BitArrayVersion.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/BitArrayVersion.java index f6e3ef5e5..be91f13d8 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/BitArrayVersion.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/BitArrayVersion.java @@ -1,14 +1,30 @@ /* * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * - * This code in this file is derived from NukkitX and permission has - * been granted to us allowing the usage of it in Geyser. + * 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 * - * Copyright (C) 2020 The NukkitX Project - * https://github.com/NukkitX/Nukkit */ -package org.geysermc.connector.world.chunk.bitarray; +package org.geysermc.connector.network.translators.world.chunk.bitarray; import org.geysermc.connector.utils.MathUtils; diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/PaddedBitArray.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/PaddedBitArray.java similarity index 65% rename from connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/PaddedBitArray.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/PaddedBitArray.java index d2f9393a3..36a97a30c 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/PaddedBitArray.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/PaddedBitArray.java @@ -1,14 +1,30 @@ /* * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * - * This code in this file is derived from NukkitX and permission has - * been granted to us allowing the usage of it in Geyser. + * 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 * - * Copyright (C) 2020 The NukkitX Project - * https://github.com/NukkitX/Nukkit */ -package org.geysermc.connector.world.chunk.bitarray; +package org.geysermc.connector.network.translators.world.chunk.bitarray; import com.nukkitx.network.util.Preconditions; import org.geysermc.connector.utils.MathUtils; diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/Pow2BitArray.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/Pow2BitArray.java similarity index 67% rename from connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/Pow2BitArray.java rename to connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/Pow2BitArray.java index bcb878a70..c9bd27646 100644 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/Pow2BitArray.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/chunk/bitarray/Pow2BitArray.java @@ -1,14 +1,30 @@ /* * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org * - * This code in this file is derived from NukkitX and permission has - * been granted to us allowing the usage of it in Geyser. + * 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 * - * Copyright (C) 2020 The NukkitX Project - * https://github.com/NukkitX/Nukkit */ -package org.geysermc.connector.world.chunk.bitarray; +package org.geysermc.connector.network.translators.world.chunk.bitarray; import com.nukkitx.network.util.Preconditions; import org.geysermc.connector.utils.MathUtils; 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 0dcd13ad9..2c04c205b 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockEntityUtils.java @@ -6,7 +6,7 @@ import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.Translators; -import org.geysermc.connector.network.translators.block.entity.BlockEntityTranslator; +import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator; public class BlockEntityUtils { diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java index 34287073e..3a9ecb867 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java @@ -28,7 +28,7 @@ package org.geysermc.connector.utils; import com.github.steveice10.mc.protocol.data.game.entity.Effect; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import org.geysermc.connector.entity.PlayerEntity; -import org.geysermc.connector.network.translators.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ToolItemEntry; 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 1347aed48..97be97324 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/ChunkUtils.java @@ -33,26 +33,24 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.packet.*; - import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; - import lombok.Getter; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.ItemFrameEntity; import org.geysermc.connector.network.session.GeyserSession; -import org.geysermc.connector.network.translators.block.entity.*; +import org.geysermc.connector.network.translators.world.block.entity.*; import org.geysermc.connector.network.translators.Translators; -import org.geysermc.connector.network.translators.block.BlockTranslator; -import org.geysermc.connector.world.chunk.ChunkPosition; -import org.geysermc.connector.world.chunk.ChunkSection; +import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.connector.network.translators.world.chunk.ChunkPosition; +import org.geysermc.connector.network.translators.world.chunk.ChunkSection; import java.util.HashMap; import java.util.Map; -import static org.geysermc.connector.network.translators.block.BlockTranslator.AIR; -import static org.geysermc.connector.network.translators.block.BlockTranslator.BEDROCK_WATER_ID; +import static org.geysermc.connector.network.translators.world.block.BlockTranslator.AIR; +import static org.geysermc.connector.network.translators.world.block.BlockTranslator.BEDROCK_WATER_ID; public class ChunkUtils { @@ -151,7 +149,6 @@ public class ChunkUtils { } public static void updateBlock(GeyserSession session, BlockState blockState, Vector3i position) { - // Checks for item frames so they aren't tripped up and removed if (ItemFrameEntity.positionContainsItemFrame(session, position) && blockState.equals(AIR)) { ((ItemFrameEntity) session.getEntityCache().getEntityByJavaId(ItemFrameEntity.getItemFrameEntityId(session, position))).updateBlock(session); @@ -193,6 +190,7 @@ public class ChunkUtils { break; //No block will be a part of two classes } } + session.getChunkCache().updateBlock(new Position(position.getX(), position.getY(), position.getZ()), blockState); } public static void sendEmptyChunks(GeyserSession session, Vector3i position, int radius, boolean forceUpdate) { diff --git a/connector/src/main/java/org/geysermc/connector/utils/EffectUtils.java b/connector/src/main/java/org/geysermc/connector/utils/EffectUtils.java new file mode 100644 index 000000000..7c1690e48 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/EffectUtils.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.utils; + +import com.fasterxml.jackson.databind.JsonNode; +import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleType; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.data.SoundEvent; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +import lombok.NonNull; + +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.translators.effect.Effect; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class EffectUtils { + + public static final Map EFFECTS = new HashMap<>(); + public static final Int2ObjectMap RECORDS = new Int2ObjectOpenHashMap<>(); + + private static Map particleTypeMap = new HashMap<>(); + private static Map particleStringMap = new HashMap<>(); + + public static void init() { + // no-op + } + + static { + /* Load particles */ + InputStream particleStream = Toolbox.getResource("mappings/particles.json"); + JsonNode particleEntries; + try { + particleEntries = Toolbox.JSON_MAPPER.readTree(particleStream); + } catch (Exception e) { + throw new AssertionError("Unable to load particle map", e); + } + + Iterator> particlesIterator = particleEntries.fields(); + while (particlesIterator.hasNext()) { + Map.Entry entry = particlesIterator.next(); + try { + setIdentifier(ParticleType.valueOf(entry.getKey().toUpperCase()), LevelEventType.valueOf(entry.getValue().asText().toUpperCase())); + } catch (IllegalArgumentException e1) { + try { + setIdentifier(ParticleType.valueOf(entry.getKey().toUpperCase()), entry.getValue().asText()); + GeyserConnector.getInstance().getLogger().debug("Force to map particle " + + entry.getKey() + + "=>" + + entry.getValue().asText() + + ", it will take effect."); + } catch (IllegalArgumentException e2){ + GeyserConnector.getInstance().getLogger().warning("Fail to map particle " + entry.getKey() + "=>" + entry.getValue().asText()); + } + } + } + + /* Load effects */ + InputStream effectsStream = Toolbox.getResource("mappings/effects.json"); + JsonNode effects; + try { + effects = Toolbox.JSON_MAPPER.readTree(effectsStream); + } catch (Exception e) { + throw new AssertionError("Unable to load effects mappings", e); + } + + Iterator> effectsIterator = effects.fields(); + while (effectsIterator.hasNext()) { + Map.Entry entry = effectsIterator.next(); + // Separate records database since they're handled differently between the two versions + if (entry.getValue().has("records")) { + JsonNode records = entry.getValue().get("records"); + Iterator> recordsIterator = records.fields(); + while (recordsIterator.hasNext()) { + Map.Entry recordEntry = recordsIterator.next(); + RECORDS.put(Integer.parseInt(recordEntry.getKey()), SoundEvent.valueOf(recordEntry.getValue().asText())); + } + } + String identifier = (entry.getValue().has("identifier")) ? entry.getValue().get("identifier").asText() : ""; + int data = (entry.getValue().has("data")) ? entry.getValue().get("data").asInt() : -1; + Effect effect = new Effect(entry.getKey(), entry.getValue().get("name").asText(), entry.getValue().get("type").asText(), data, identifier); + EFFECTS.put(entry.getKey(), effect); + } + } + + public static void setIdentifier(ParticleType type, LevelEventType identifier) { + particleTypeMap.put(type, identifier); + } + + public static void setIdentifier(ParticleType type, String identifier) { + particleStringMap.put(type, identifier); + } + + public static LevelEventType getParticleLevelEventType(@NonNull ParticleType type) { + return particleTypeMap.getOrDefault(type, null); + } + + public static String getParticleString(@NonNull ParticleType type){ + return particleStringMap.getOrDefault(type, null); + } + +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/SoundUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SoundUtils.java new file mode 100644 index 000000000..a5e58f3b1 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/utils/SoundUtils.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.utils; + +import com.fasterxml.jackson.databind.JsonNode; +import com.nukkitx.protocol.bedrock.data.SoundEvent; + +import lombok.Data; +import lombok.ToString; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class SoundUtils { + + private static final Map SOUNDS; + + public static void init() { + // no-op + } + + static { + /* Load sound mappings */ + InputStream stream = Toolbox.getResource("mappings/sounds.json"); + JsonNode soundsTree; + try { + soundsTree = Toolbox.JSON_MAPPER.readTree(stream); + } catch (IOException e) { + throw new AssertionError("Unable to load sound mappings", e); + } + + Map soundMappings = new HashMap<>(); + Iterator> soundsIterator = soundsTree.fields(); + while(soundsIterator.hasNext()) { + Map.Entry next = soundsIterator.next(); + JsonNode brMap = next.getValue(); + + soundMappings.put(next.getKey(), new SoundMapping( + next.getKey(), + brMap.has("bedrock_mapping") && brMap.get("bedrock_mapping").isTextual() ? brMap.get("bedrock_mapping").asText() : null, + brMap.has("playsound_mapping") && brMap.get("playsound_mapping").isTextual() ? brMap.get("playsound_mapping").asText() : null, + brMap.has("extra_data") && brMap.get("extra_data").isInt() ? brMap.get("extra_data").asInt() : -1, + brMap.has("identifier") && brMap.get("identifier").isTextual() ? brMap.get("identifier").asText() : null, + brMap.has("level_event") && brMap.get("level_event").isBoolean() ? brMap.get("level_event").asBoolean() : false + ) + ); + } + SOUNDS = soundMappings; + } + + /** + * Get's the sound mapping for a Java edition sound identifier + * @param java Java edition sound identifier + * @return SoundMapping object with information for bedrock, nukkit, java, etc. null if not found + */ + public static SoundMapping fromJava(String java) { + return SOUNDS.get(java); + } + + public static SoundEvent toSoundEvent(String sound) { + try { + return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_")); + } catch (Exception ex) { + return null; + } + } + + @Data + @ToString + public static class SoundMapping { + private final String java; + private final String bedrock; + private final String playsound; + private final int extraData; + private String identifier; + private boolean levelEvent; + + public SoundMapping(String java, String bedrock, String playsound, int extraData, String identifier, boolean levelEvent) { + this.java = java; + this.bedrock = bedrock == null || bedrock.equalsIgnoreCase("") ? null : bedrock; + this.playsound = playsound == null || playsound.equalsIgnoreCase("") ? null : playsound; + this.extraData = extraData; + this.identifier = identifier == null || identifier.equalsIgnoreCase("") ? ":" : identifier; + this.levelEvent = levelEvent; + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java index 09e2531c8..953b70a8a 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java +++ b/connector/src/main/java/org/geysermc/connector/utils/Toolbox.java @@ -41,6 +41,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ToolItemEntry; +import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry; import java.io.*; import java.util.*; @@ -113,20 +114,23 @@ public class Toolbox { 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("tool_tier").textValue(), + 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( entry.getKey(), itemIndex, entry.getValue().get("bedrock_id").intValue(), - entry.getValue().get("bedrock_data").intValue())); + entry.getValue().get("bedrock_data").intValue(), + entry.getValue().get("is_block").booleanValue())); } if (entry.getKey().equals("minecraft:barrier")) { BARRIER_INDEX = itemIndex; @@ -135,9 +139,16 @@ public class Toolbox { itemIndex++; } + // Load particle/effect mappings + EffectUtils.init(); + // Load sound mappings + SoundUtils.init(); // Load the locale data LocaleUtils.init(); + // Load sound handlers + SoundHandlerRegistry.init(); + /* Load creative items */ stream = getResource("bedrock/creative_items.json"); diff --git a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/BitArray.java b/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/BitArray.java deleted file mode 100644 index 944cabd3f..000000000 --- a/connector/src/main/java/org/geysermc/connector/world/chunk/bitarray/BitArray.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org - * - * This code in this file is derived from NukkitX and permission has - * been granted to us allowing the usage of it in Geyser. - * - * Copyright (C) 2020 The NukkitX Project - * https://github.com/NukkitX/Nukkit - */ - -package org.geysermc.connector.world.chunk.bitarray; - -public interface BitArray { - - void set(int index, int value); - - int get(int index); - - int size(); - - int[] getWords(); - - BitArrayVersion getVersion(); - - BitArray copy(); -} \ No newline at end of file diff --git a/connector/src/main/resources/config.yml b/connector/src/main/resources/config.yml index ae0cbed8d..b1e1e2f93 100644 --- a/connector/src/main/resources/config.yml +++ b/connector/src/main/resources/config.yml @@ -60,6 +60,15 @@ allow-third-party-capes: true # The default locale if we dont have the one the client requested 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 +# 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 +# or implementations this allows is automatically enabled without the additional caching as +# Geyser has direct access to the server itself. +cache-chunks: false + # bStats is a stat tracker that is entirely anonymous and tracks only basic information # about Geyser, such as how many people are online, how many servers are using Geyser, # what OS is being used, etc. You can learn more about bStats here: https://bstats.org/. diff --git a/connector/src/main/resources/mappings b/connector/src/main/resources/mappings index 4e80d3b8e..ddb62693f 160000 --- a/connector/src/main/resources/mappings +++ b/connector/src/main/resources/mappings @@ -1 +1 @@ -Subproject commit 4e80d3b8e489b12a93b1b98b7bbaf8fa91a7974a +Subproject commit ddb62693f878a99f106a0d6ea16a92ec7c4c7cd0