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