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 09b737bcb..4ba593a75 100644
--- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java
+++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java
@@ -25,9 +25,6 @@
 
 package org.geysermc.connector.network;
 
-import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
-import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
-import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerSwingArmPacket;
 import com.nimbusds.jose.JWSObject;
 import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler;
 import com.nukkitx.protocol.bedrock.packet.*;
@@ -45,6 +42,7 @@ import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.network.session.GeyserSession;
 import org.geysermc.connector.network.session.auth.BedrockAuthData;
 import org.geysermc.connector.network.session.cache.WindowCache;
+import org.geysermc.connector.network.translators.Registry;
 
 import java.util.UUID;
 
@@ -125,11 +123,7 @@ public class UpstreamPacketHandler implements BedrockPacketHandler {
     @Override
     public boolean handle(AnimatePacket packet) {
         connector.getLogger().debug("Handled packet: " + packet.getClass().getSimpleName());
-        switch (packet.getAction()) {
-            case SWING_ARM:
-                ClientPlayerSwingArmPacket swingArmPacket = new ClientPlayerSwingArmPacket(Hand.MAIN_HAND);
-                session.getDownstream().getSession().send(swingArmPacket);
-        }
+        Registry.BEDROCK.translate(packet.getClass(), packet, session);
         return true;
     }
 
@@ -184,15 +178,7 @@ public class UpstreamPacketHandler implements BedrockPacketHandler {
     @Override
     public boolean handle(CommandRequestPacket packet) {
         connector.getLogger().debug("Handled packet: " + packet.getClass().getSimpleName());
-
-        String command = packet.getCommand().replace("/", "");
-        if (connector.getCommandMap().getCommands().containsKey(command)) {
-            connector.getCommandMap().runCommand(session, command);
-        } else {
-            ClientChatPacket chatPacket = new ClientChatPacket(packet.getCommand());
-            session.getDownstream().getSession().send(chatPacket);
-        }
-
+        Registry.BEDROCK.translate(packet.getClass(), packet, session);
         return true;
     }
 
@@ -455,16 +441,7 @@ public class UpstreamPacketHandler implements BedrockPacketHandler {
     @Override
     public boolean handle(TextPacket packet) {
         connector.getLogger().debug("Handled packet: " + packet.getClass().getSimpleName());
-
-        if (packet.getMessage().charAt(0) == '.') {
-            ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage().replace(".", "/"));
-            session.getDownstream().getSession().send(chatPacket);
-            return true;
-        }
-
-        ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage());
-        session.getDownstream().getSession().send(chatPacket);
-
+        Registry.BEDROCK.translate(packet.getClass(), packet, session);
         return true;
     }
 
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 8cf5ced5d..c21252efa 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
@@ -67,8 +67,6 @@ public class GeyserSession implements PlayerSession, Player {
     @Getter
     private Client downstream;
 
-    private final GeyserSession THIS = this;
-
     @Getter
     private AuthData authenticationData;
 
@@ -136,7 +134,7 @@ public class GeyserSession implements PlayerSession, Player {
 
                 @Override
                 public void packetReceived(PacketReceivedEvent event) {
-                    Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), THIS);
+                    Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this);
                 }
             });
 
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslator.java
new file mode 100644
index 000000000..412af6e7c
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslator.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 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;
+
+import org.geysermc.connector.network.session.GeyserSession;
+
+public abstract class PacketTranslator<T> {
+
+    public abstract void translate(T packet, GeyserSession session);
+
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java b/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java
index ad0e8c21a..987fc4f27 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/Registry.java
@@ -26,28 +26,33 @@
 package org.geysermc.connector.network.translators;
 
 import com.github.steveice10.packetlib.packet.Packet;
+import com.nukkitx.protocol.bedrock.BedrockPacket;
 import org.geysermc.connector.console.GeyserLogger;
 import org.geysermc.connector.network.session.GeyserSession;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.function.BiConsumer;
 
 public class Registry<T> {
 
-    private final Map<Class<? extends T>, BiConsumer<? extends T, GeyserSession>> MAP = new HashMap<>();
+    private final Map<Class<? extends T>, PacketTranslator<? extends T>> MAP = new HashMap<>();
 
     public static final Registry<Packet> JAVA = new Registry<>();
+    public static final Registry<BedrockPacket> BEDROCK = new Registry<>();
 
-    public static <T extends Packet> void add(Class<T> clazz, BiConsumer<T, GeyserSession> translator) {
+    public static <T extends Packet> void registerJava(Class<T> clazz, PacketTranslator<T> translator) {
         JAVA.MAP.put(clazz, translator);
     }
 
-    public <P extends T> void translate(Class<P> clazz, P p, GeyserSession s) {
+    public static <T extends BedrockPacket> void registerBedrock(Class<T> clazz, PacketTranslator<T> translator) {
+        BEDROCK.MAP.put(clazz, translator);
+    }
+
+    public <P extends T> void translate(Class<? extends P> clazz, P packet, GeyserSession session) {
         try {
-            ((BiConsumer<P, GeyserSession>) JAVA.MAP.get(clazz)).accept(p, s);
-        } catch (NullPointerException e) {
-            GeyserLogger.DEFAULT.debug("could not translate packet " + p.getClass().getSimpleName());
+            ((PacketTranslator<P>) MAP.get(clazz)).translate(packet, session);
+        } catch (NullPointerException ex) {
+            GeyserLogger.DEFAULT.debug("Could not translate packet " + packet.getClass().getSimpleName());
         }
     }
 }
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java
index 2794d2bf4..d1b629d21 100644
--- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java
@@ -25,8 +25,6 @@
 
 package org.geysermc.connector.network.translators;
 
-import com.flowpowered.math.vector.Vector3f;
-import com.github.steveice10.mc.protocol.data.message.TranslationMessage;
 import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket;
 import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
 import com.github.steveice10.mc.protocol.packet.ingame.server.ServerTitlePacket;
@@ -40,17 +38,29 @@ import com.nukkitx.nbt.CompoundTagBuilder;
 import com.nukkitx.nbt.NbtUtils;
 import com.nukkitx.nbt.stream.NBTOutputStream;
 import com.nukkitx.nbt.tag.CompoundTag;
-import com.nukkitx.protocol.bedrock.packet.*;
-import org.geysermc.connector.utils.MessageUtils;
+import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
+import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
+import com.nukkitx.protocol.bedrock.packet.TextPacket;
+import org.geysermc.connector.network.translators.bedrock.BedrockAnimateTranslator;
+import org.geysermc.connector.network.translators.bedrock.BedrockCommandRequestTranslator;
+import org.geysermc.connector.network.translators.bedrock.BedrockTextTranslator;
+import org.geysermc.connector.network.translators.java.JavaChatTranslator;
+import org.geysermc.connector.network.translators.java.JavaEntityPositionRotationTranslator;
+import org.geysermc.connector.network.translators.java.JavaEntityPositionTranslator;
+import org.geysermc.connector.network.translators.java.JavaEntityTeleportTranslator;
+import org.geysermc.connector.network.translators.java.JavaEntityVelocityTranslator;
+import org.geysermc.connector.network.translators.java.JavaJoinGameTranslator;
+import org.geysermc.connector.network.translators.java.JavaNotifyClientTranslator;
+import org.geysermc.connector.network.translators.java.JavaTitleTranslator;
+import org.geysermc.connector.network.translators.java.JavaUpdateTimeTranslator;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.concurrent.ThreadLocalRandom;
 
 public class TranslatorsInit {
 
     private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag();
-    private static final byte[] EMPTY_LEVEL_CHUNK_DATA;
+    public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
 
     static {
         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
@@ -67,182 +77,18 @@ public class TranslatorsInit {
     }
 
     public static void start() {
-        addLoginPackets();
-        addChatPackets();
-        addTitlePackets();
-        addTimePackets();
-        addEntityPackets();
-        addNotifyPackets();
-    }
+        Registry.registerJava(ServerJoinGamePacket.class, new JavaJoinGameTranslator());
+        Registry.registerJava(ServerChatPacket.class, new JavaChatTranslator());
+        Registry.registerJava(ServerTitlePacket.class, new JavaTitleTranslator());
+        Registry.registerJava(ServerUpdateTimePacket.class, new JavaUpdateTimeTranslator());
+        Registry.registerJava(ServerEntityPositionPacket.class, new JavaEntityPositionTranslator());
+        Registry.registerJava(ServerEntityPositionRotationPacket.class, new JavaEntityPositionRotationTranslator());
+        Registry.registerJava(ServerEntityTeleportPacket.class, new JavaEntityTeleportTranslator());
+        Registry.registerJava(ServerEntityVelocityPacket.class, new JavaEntityVelocityTranslator());
+        Registry.registerJava(ServerNotifyClientPacket.class, new JavaNotifyClientTranslator());
 
-    private static void addLoginPackets() {
-        Registry.add(ServerJoinGamePacket.class, (packet, session) -> {
-            AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
-            bedrockPacket.setUniqueEntityId(packet.getEntityId());
-            session.getUpstream().sendPacketImmediately(bedrockPacket);
-
-            Vector3f pos = new Vector3f(0, 0, 0);
-            int chunkX = pos.getFloorX() >> 4;
-            int chunkZ = pos.getFloorZ() >> 4;
-            for (int x = -3; x < 3; x++) {
-                for (int z = -3; z < 3; z++) {
-                    LevelChunkPacket data = new LevelChunkPacket();
-                    data.setChunkX(chunkX + x);
-                    data.setChunkZ(chunkZ + z);
-                    data.setSubChunksLength(0);
-
-                    data.setData(EMPTY_LEVEL_CHUNK_DATA);
-
-                    session.getUpstream().sendPacketImmediately(data);
-
-                }
-            }
-        });
-    }
-
-    private static void addChatPackets() {
-        Registry.add(ServerChatPacket.class, (packet, session) -> {
-            TextPacket textPacket = new TextPacket();
-            textPacket.setPlatformChatId("");
-            textPacket.setSourceName("");
-            textPacket.setXuid(session.getAuthenticationData().getXboxUUID());
-            switch (packet.getType()) {
-                case CHAT:
-                    textPacket.setType(TextPacket.Type.CHAT);
-                case SYSTEM:
-                    textPacket.setType(TextPacket.Type.SYSTEM);
-                case NOTIFICATION:
-                    textPacket.setType(TextPacket.Type.TIP);
-                default:
-                    textPacket.setType(TextPacket.Type.RAW);
-            }
-
-            if (packet.getMessage() instanceof TranslationMessage) {
-                textPacket.setType(TextPacket.Type.TRANSLATION);
-                textPacket.setNeedsTranslation(true);
-                textPacket.setParameters(MessageUtils.getTranslationParams(((TranslationMessage) packet.getMessage()).getTranslationParams()));
-                textPacket.setMessage(MessageUtils.getBedrockMessage(packet.getMessage()));
-            } else {
-                textPacket.setNeedsTranslation(false);
-                textPacket.setMessage(MessageUtils.getBedrockMessage(packet.getMessage()));
-            }
-
-            session.getUpstream().sendPacket(textPacket);
-        });
-    }
-
-    public static void addTitlePackets() {
-        Registry.add(ServerTitlePacket.class, (packet, session) -> {
-            SetTitlePacket titlePacket = new SetTitlePacket();
-
-            switch (packet.getAction()) {
-                case TITLE:
-                    titlePacket.setType(SetTitlePacket.Type.SET_TITLE);
-                    titlePacket.setText(packet.getTitle().getFullText());
-                    break;
-                case SUBTITLE:
-                    titlePacket.setType(SetTitlePacket.Type.SET_SUBTITLE);
-                    titlePacket.setText(packet.getSubtitle().getFullText());
-                    break;
-                case CLEAR:
-                case RESET:
-                    titlePacket.setType(SetTitlePacket.Type.RESET_TITLE);
-                    titlePacket.setText("");
-                    break;
-                case ACTION_BAR:
-                    titlePacket.setType(SetTitlePacket.Type.SET_ACTIONBAR_MESSAGE);
-                    titlePacket.setText(packet.getActionBar().getFullText());
-                    break;
-            }
-
-            titlePacket.setFadeInTime(packet.getFadeIn());
-            titlePacket.setFadeOutTime(packet.getFadeOut());
-            titlePacket.setStayTime(packet.getStay());
-
-            session.getUpstream().sendPacket(titlePacket);
-        });
-    }
-
-    public static void addTimePackets() {
-        Registry.add(ServerUpdateTimePacket.class, (packet, session) -> {
-            SetTimePacket setTimePacket = new SetTimePacket();
-            setTimePacket.setTime((int) Math.abs(packet.getTime()));
-
-            session.getUpstream().sendPacket(setTimePacket);
-        });
-    }
-
-    public static void addEntityPackets() {
-        Registry.add(ServerEntityPositionPacket.class, (packet, session) -> {
-            MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
-            moveEntityPacket.setRuntimeEntityId(packet.getEntityId());
-            moveEntityPacket.setPosition(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
-            moveEntityPacket.setRotation(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
-            moveEntityPacket.setOnGround(packet.isOnGround());
-            moveEntityPacket.setTeleported(false);
-
-            session.getUpstream().sendPacket(moveEntityPacket);
-        });
-
-        Registry.add(ServerEntityPositionRotationPacket.class, (packet, session) -> {
-            MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
-            moveEntityPacket.setRuntimeEntityId(packet.getEntityId());
-            moveEntityPacket.setPosition(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
-            moveEntityPacket.setRotation(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
-            moveEntityPacket.setOnGround(true);
-            moveEntityPacket.setTeleported(false);
-
-            session.getUpstream().sendPacket(moveEntityPacket);
-        });
-
-        Registry.add(ServerEntityTeleportPacket.class, (packet, session) -> {
-            MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
-            moveEntityPacket.setRuntimeEntityId(packet.getEntityId());
-            moveEntityPacket.setPosition(new Vector3f(packet.getX(), packet.getY(), packet.getZ()));
-            moveEntityPacket.setRotation(new Vector3f(packet.getX(), packet.getY(), packet.getZ()));
-            moveEntityPacket.setOnGround(packet.isOnGround());
-            moveEntityPacket.setTeleported(true);
-
-            session.getUpstream().sendPacket(moveEntityPacket);
-        });
-
-        Registry.add(ServerEntityVelocityPacket.class, (packet, session) -> {
-            SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
-            entityMotionPacket.setRuntimeEntityId(packet.getEntityId());
-            entityMotionPacket.setMotion(new Vector3f(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ()));
-
-            session.getUpstream().sendPacket(entityMotionPacket);
-        });
-    }
-
-    public static void addNotifyPackets() {
-        Registry.add(ServerNotifyClientPacket.class, (packet, session) -> {
-            switch (packet.getNotification()) {
-                case START_RAIN:
-                    LevelEventPacket startRainPacket = new LevelEventPacket();
-                    startRainPacket.setEvent(LevelEventPacket.Event.START_RAIN);
-                    startRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000);
-                    startRainPacket.setPosition(new Vector3f(0, 0, 0));
-
-                    session.getUpstream().sendPacket(startRainPacket);
-                    break;
-                case STOP_RAIN:
-                    LevelEventPacket stopRainPacket = new LevelEventPacket();
-                    stopRainPacket.setEvent(LevelEventPacket.Event.STOP_RAIN);
-                    stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000);
-                    stopRainPacket.setPosition(new Vector3f(0, 0, 0));
-
-                    session.getUpstream().sendPacket(stopRainPacket);
-                    break;
-                case ENTER_CREDITS:
-                    // ShowCreditsPacket showCreditsPacket = new ShowCreditsPacket();
-                    // showCreditsPacket.setStatus(ShowCreditsPacket.Status.START_CREDITS);
-                    // showCreditsPacket.setRuntimeEntityId(runtimeEntityId);
-                    // session.getUpstream().sendPacket(showCreditsPacket);
-                    break;
-                default:
-                    break;
-            }
-        });
+        Registry.registerBedrock(AnimatePacket.class, new BedrockAnimateTranslator());
+        Registry.registerBedrock(CommandRequestPacket.class, new BedrockCommandRequestTranslator());
+        Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator());
     }
 }
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAnimateTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAnimateTranslator.java
new file mode 100644
index 000000000..6056c54c9
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockAnimateTranslator.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.network.translators.bedrock;
+
+import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
+import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerSwingArmPacket;
+import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
+
+    @Override
+    public void translate(AnimatePacket packet, GeyserSession session) {
+        switch (packet.getAction()) {
+            case SWING_ARM:
+                ClientPlayerSwingArmPacket swingArmPacket = new ClientPlayerSwingArmPacket(Hand.MAIN_HAND);
+                session.getDownstream().getSession().send(swingArmPacket);
+        }
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java
new file mode 100644
index 000000000..c453c31a3
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+
+package org.geysermc.connector.network.translators.bedrock;
+
+import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
+import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
+import org.geysermc.api.Geyser;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class BedrockCommandRequestTranslator extends PacketTranslator<CommandRequestPacket> {
+
+    @Override
+    public void translate(CommandRequestPacket packet, GeyserSession session) {
+        String command = packet.getCommand().replace("/", "");
+        if (Geyser.getConnector().getCommandMap().getCommands().containsKey(command)) {
+            Geyser.getConnector().getCommandMap().runCommand(session, command);
+        } else {
+            ClientChatPacket chatPacket = new ClientChatPacket(packet.getCommand());
+            session.getDownstream().getSession().send(chatPacket);
+        }
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockTextTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockTextTranslator.java
new file mode 100644
index 000000000..59d28eba0
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockTextTranslator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.network.translators.bedrock;
+
+import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
+import com.nukkitx.protocol.bedrock.packet.TextPacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
+
+    @Override
+    public void translate(TextPacket packet, GeyserSession session) {
+        if (packet.getMessage().charAt(0) == '.') {
+            ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage().replace(".", "/"));
+            session.getDownstream().getSession().send(chatPacket);
+            return;
+        }
+
+        ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage());
+        session.getDownstream().getSession().send(chatPacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java
new file mode 100644
index 000000000..cc5838c90
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaChatTranslator.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.github.steveice10.mc.protocol.data.message.TranslationMessage;
+import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket;
+import com.nukkitx.protocol.bedrock.packet.TextPacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+import org.geysermc.connector.utils.MessageUtils;
+
+public class JavaChatTranslator extends PacketTranslator<ServerChatPacket> {
+
+    @Override
+    public void translate(ServerChatPacket packet, GeyserSession session) {
+        TextPacket textPacket = new TextPacket();
+        textPacket.setPlatformChatId("");
+        textPacket.setSourceName("");
+        textPacket.setXuid(session.getAuthenticationData().getXboxUUID());
+        switch (packet.getType()) {
+            case CHAT:
+                textPacket.setType(TextPacket.Type.CHAT);
+            case SYSTEM:
+                textPacket.setType(TextPacket.Type.SYSTEM);
+            case NOTIFICATION:
+                textPacket.setType(TextPacket.Type.TIP);
+            default:
+                textPacket.setType(TextPacket.Type.RAW);
+        }
+
+        if (packet.getMessage() instanceof TranslationMessage) {
+            textPacket.setType(TextPacket.Type.TRANSLATION);
+            textPacket.setNeedsTranslation(true);
+            textPacket.setParameters(MessageUtils.getTranslationParams(((TranslationMessage) packet.getMessage()).getTranslationParams()));
+            textPacket.setMessage(MessageUtils.getBedrockMessage(packet.getMessage()));
+        } else {
+            textPacket.setNeedsTranslation(false);
+            textPacket.setMessage(MessageUtils.getBedrockMessage(packet.getMessage()));
+        }
+
+        session.getUpstream().sendPacket(textPacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityPositionRotationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityPositionRotationTranslator.java
new file mode 100644
index 000000000..e8414f487
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityPositionRotationTranslator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket;
+import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class JavaEntityPositionRotationTranslator extends PacketTranslator<ServerEntityPositionRotationPacket> {
+
+    @Override
+    public void translate(ServerEntityPositionRotationPacket packet, GeyserSession session) {
+        MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
+        moveEntityPacket.setRuntimeEntityId(packet.getEntityId());
+        moveEntityPacket.setPosition(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
+        moveEntityPacket.setRotation(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
+        moveEntityPacket.setOnGround(true);
+        moveEntityPacket.setTeleported(false);
+
+        session.getUpstream().sendPacket(moveEntityPacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityPositionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityPositionTranslator.java
new file mode 100644
index 000000000..ccdbb9d9a
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityPositionTranslator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionPacket;
+import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class JavaEntityPositionTranslator extends PacketTranslator<ServerEntityPositionPacket> {
+
+    @Override
+    public void translate(ServerEntityPositionPacket packet, GeyserSession session) {
+        MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
+        moveEntityPacket.setRuntimeEntityId(packet.getEntityId());
+        moveEntityPacket.setPosition(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
+        moveEntityPacket.setRotation(new Vector3f(packet.getMovementX(), packet.getMovementY(), packet.getMovementZ()));
+        moveEntityPacket.setOnGround(packet.isOnGround());
+        moveEntityPacket.setTeleported(false);
+
+        session.getUpstream().sendPacket(moveEntityPacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityTeleportTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityTeleportTranslator.java
new file mode 100644
index 000000000..694c48f9f
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityTeleportTranslator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket;
+import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class JavaEntityTeleportTranslator extends PacketTranslator<ServerEntityTeleportPacket> {
+
+    @Override
+    public void translate(ServerEntityTeleportPacket packet, GeyserSession session) {
+        MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket();
+        moveEntityPacket.setRuntimeEntityId(packet.getEntityId());
+        moveEntityPacket.setPosition(new Vector3f(packet.getX(), packet.getY(), packet.getZ()));
+        moveEntityPacket.setRotation(new Vector3f(packet.getX(), packet.getY(), packet.getZ()));
+        moveEntityPacket.setOnGround(packet.isOnGround());
+        moveEntityPacket.setTeleported(true);
+
+        session.getUpstream().sendPacket(moveEntityPacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityVelocityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityVelocityTranslator.java
new file mode 100644
index 000000000..43bfe3552
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaEntityVelocityTranslator.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket;
+import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class JavaEntityVelocityTranslator extends PacketTranslator<ServerEntityVelocityPacket> {
+
+    @Override
+    public void translate(ServerEntityVelocityPacket packet, GeyserSession session) {
+        SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
+        entityMotionPacket.setRuntimeEntityId(packet.getEntityId());
+        entityMotionPacket.setMotion(new Vector3f(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ()));
+
+        session.getUpstream().sendPacket(entityMotionPacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java
new file mode 100644
index 000000000..a43fd4a43
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
+import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket;
+import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+import org.geysermc.connector.network.translators.TranslatorsInit;
+
+public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacket> {
+
+    @Override
+    public void translate(ServerJoinGamePacket packet, GeyserSession session) {
+        AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
+        bedrockPacket.setUniqueEntityId(packet.getEntityId());
+        session.getUpstream().sendPacketImmediately(bedrockPacket);
+
+        Vector3f pos = new Vector3f(0, 0, 0);
+        int chunkX = pos.getFloorX() >> 4;
+        int chunkZ = pos.getFloorZ() >> 4;
+        for (int x = -3; x < 3; x++) {
+            for (int z = -3; z < 3; z++) {
+                LevelChunkPacket data = new LevelChunkPacket();
+                data.setChunkX(chunkX + x);
+                data.setChunkZ(chunkZ + z);
+                data.setSubChunksLength(0);
+
+                data.setData(TranslatorsInit.EMPTY_LEVEL_CHUNK_DATA);
+
+                session.getUpstream().sendPacketImmediately(data);
+
+            }
+        }
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaNotifyClientTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaNotifyClientTranslator.java
new file mode 100644
index 000000000..8aade7e32
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaNotifyClientTranslator.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket;
+import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyClientPacket> {
+
+    @Override
+    public void translate(ServerNotifyClientPacket packet, GeyserSession session) {
+        switch (packet.getNotification()) {
+            case START_RAIN:
+                LevelEventPacket startRainPacket = new LevelEventPacket();
+                startRainPacket.setEvent(LevelEventPacket.Event.START_RAIN);
+                startRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000);
+                startRainPacket.setPosition(new Vector3f(0, 0, 0));
+
+                session.getUpstream().sendPacket(startRainPacket);
+                break;
+            case STOP_RAIN:
+                LevelEventPacket stopRainPacket = new LevelEventPacket();
+                stopRainPacket.setEvent(LevelEventPacket.Event.STOP_RAIN);
+                stopRainPacket.setData(ThreadLocalRandom.current().nextInt(50000) + 10000);
+                stopRainPacket.setPosition(new Vector3f(0, 0, 0));
+
+                session.getUpstream().sendPacket(stopRainPacket);
+                break;
+            case ENTER_CREDITS:
+                // ShowCreditsPacket showCreditsPacket = new ShowCreditsPacket();
+                // showCreditsPacket.setStatus(ShowCreditsPacket.Status.START_CREDITS);
+                // showCreditsPacket.setRuntimeEntityId(runtimeEntityId);
+                // session.getUpstream().sendPacket(showCreditsPacket);
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTimeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTimeTranslator.java
new file mode 100644
index 000000000..52faa89da
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTimeTranslator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTimePacket;
+import com.nukkitx.protocol.bedrock.packet.SetTimePacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class JavaTimeTranslator extends PacketTranslator<ServerUpdateTimePacket> {
+
+    @Override
+    public void translate(ServerUpdateTimePacket packet, GeyserSession session) {
+        SetTimePacket setTimePacket = new SetTimePacket();
+        setTimePacket.setTime((int) Math.abs(packet.getTime()));
+
+        session.getUpstream().sendPacket(setTimePacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTitleTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTitleTranslator.java
new file mode 100644
index 000000000..c9239fe29
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaTitleTranslator.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.github.steveice10.mc.protocol.packet.ingame.server.ServerTitlePacket;
+import com.nukkitx.protocol.bedrock.packet.SetTitlePacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class JavaTitleTranslator extends PacketTranslator<ServerTitlePacket> {
+
+    @Override
+    public void translate(ServerTitlePacket packet, GeyserSession session) {
+        SetTitlePacket titlePacket = new SetTitlePacket();
+
+        switch (packet.getAction()) {
+            case TITLE:
+                titlePacket.setType(SetTitlePacket.Type.SET_TITLE);
+                titlePacket.setText(packet.getTitle().getFullText());
+                break;
+            case SUBTITLE:
+                titlePacket.setType(SetTitlePacket.Type.SET_SUBTITLE);
+                titlePacket.setText(packet.getSubtitle().getFullText());
+                break;
+            case CLEAR:
+            case RESET:
+                titlePacket.setType(SetTitlePacket.Type.RESET_TITLE);
+                titlePacket.setText("");
+                break;
+            case ACTION_BAR:
+                titlePacket.setType(SetTitlePacket.Type.SET_ACTIONBAR_MESSAGE);
+                titlePacket.setText(packet.getActionBar().getFullText());
+                break;
+        }
+
+        titlePacket.setFadeInTime(packet.getFadeIn());
+        titlePacket.setFadeOutTime(packet.getFadeOut());
+        titlePacket.setStayTime(packet.getStay());
+
+        session.getUpstream().sendPacket(titlePacket);
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaUpdateTimeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaUpdateTimeTranslator.java
new file mode 100644
index 000000000..27eb8151f
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaUpdateTimeTranslator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 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;
+
+import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTimePacket;
+import com.nukkitx.protocol.bedrock.packet.SetTimePacket;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.translators.PacketTranslator;
+
+public class JavaUpdateTimeTranslator extends PacketTranslator<ServerUpdateTimePacket> {
+
+    @Override
+    public void translate(ServerUpdateTimePacket packet, GeyserSession session) {
+        SetTimePacket setTimePacket = new SetTimePacket();
+        setTimePacket.setTime((int) Math.abs(packet.getTime()));
+
+        session.getUpstream().sendPacket(setTimePacket);
+    }
+}