From 2db1d16f5c2b923bcc4bf3145e9e6f64a021829a Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Mon, 21 Sep 2020 16:06:25 -0400 Subject: [PATCH 1/9] Only send the client brand on game join (#1299) * Only send the client brand on game join * Apply suggested changes --- .../java/JavaJoinGameTranslator.java | 4 +++ .../PluginMessageUtils.java} | 33 +++++++------------ 2 files changed, 16 insertions(+), 21 deletions(-) rename connector/src/main/java/org/geysermc/connector/{network/translators/java/JavaPluginMessageTranslator.java => utils/PluginMessageUtils.java} (66%) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java index a8fc122bd..c479b23fe 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.connector.network.translators.java; import com.github.steveice10.mc.protocol.data.game.entity.player.HandPreference; import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility; import com.github.steveice10.mc.protocol.data.game.setting.SkinPart; +import com.github.steveice10.mc.protocol.packet.ingame.client.ClientPluginMessagePacket; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientSettingsPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; import com.nukkitx.protocol.bedrock.data.GameRuleData; @@ -38,6 +39,7 @@ import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; import org.geysermc.connector.utils.DimensionUtils; +import org.geysermc.connector.utils.PluginMessageUtils; import java.util.Arrays; import java.util.List; @@ -92,6 +94,8 @@ public class JavaJoinGameTranslator extends PacketTranslator { +public class PluginMessageUtils { - private static byte[] brandData; + private static final byte[] BRAND_DATA; static { byte[] data = GeyserConnector.NAME.getBytes(StandardCharsets.UTF_8); byte[] varInt = writeVarInt(data.length); - brandData = new byte[varInt.length + data.length]; - System.arraycopy(varInt, 0, brandData, 0, varInt.length); - System.arraycopy(data, 0, brandData, varInt.length, data.length); + BRAND_DATA = new byte[varInt.length + data.length]; + System.arraycopy(varInt, 0, BRAND_DATA, 0, varInt.length); + System.arraycopy(data, 0, BRAND_DATA, varInt.length, data.length); } - - @Override - public void translate(ServerPluginMessagePacket packet, GeyserSession session) { - if (packet.getChannel().equals("minecraft:brand")) { - session.sendDownstreamPacket( - new ClientPluginMessagePacket(packet.getChannel(), brandData) - ); - } + /** + * Get the prebuilt brand as a byte array + * @return the brand information of the Geyser client + */ + public static byte[] getGeyserBrandData() { + return BRAND_DATA; } private static byte[] writeVarInt(int value) { From 02aeddbadd7c1366c3719b74d22ba52a6920f82c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Mon, 21 Sep 2020 23:55:13 -0400 Subject: [PATCH 2/9] Scoreboard: Fix various issues (#1286) * Scoreboard: update score on UpdateType.ADD * Actually fix * Readd the Objective when a score changes It looks like Objectives only update when you Remove the Objective and add it back using the SetDisplayObjective. This is hopefully a hotfix, but I think that there is no better way. * Explain score tracking Co-authored-by: Tim203 --- .../geysermc/connector/scoreboard/Objective.java | 2 +- .../geysermc/connector/scoreboard/Scoreboard.java | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java b/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java index 92a1add34..b2f648612 100644 --- a/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java +++ b/connector/src/main/java/org/geysermc/connector/scoreboard/Objective.java @@ -83,7 +83,7 @@ public class Objective { public void setScore(String id, int score) { if (scores.containsKey(id)) { - scores.get(id).setScore(score).setUpdateType(UpdateType.ADD); + scores.get(id).setScore(score); return; } registerScore(id, score); diff --git a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java index 9f89d9d2b..ae1b82757 100644 --- a/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java +++ b/connector/src/main/java/org/geysermc/connector/scoreboard/Scoreboard.java @@ -26,7 +26,6 @@ package org.geysermc.connector.scoreboard; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreboardPosition; -import com.nukkitx.protocol.bedrock.BedrockPacket; import com.nukkitx.protocol.bedrock.data.ScoreInfo; import com.nukkitx.protocol.bedrock.packet.RemoveObjectivePacket; import com.nukkitx.protocol.bedrock.packet.SetDisplayObjectivePacket; @@ -153,6 +152,10 @@ public class Scoreboard { boolean globalAdd = objective.getUpdateType() == ADD; boolean globalRemove = objective.getUpdateType() == REMOVE; + // Track if any scores changed + // Used to delete and resend scoreboard objectives; otherwise they won't update on Bedrock + boolean scoreChanged = false; + for (Score score : objective.getScores().values()) { Team team = score.getTeam(); @@ -187,6 +190,10 @@ public class Scoreboard { if (remove) { removeScores.add(score.getCachedInfo()); } + + if (add || remove) { + scoreChanged = true; + } // score is pending to be updated, so we use the current score as the old score score.setOldScore(score.getScore()); @@ -198,7 +205,7 @@ public class Scoreboard { score.setUpdateType(NOTHING); } - if (globalRemove || globalUpdate) { + if (globalRemove || globalUpdate || scoreChanged) { RemoveObjectivePacket removeObjectivePacket = new RemoveObjectivePacket(); removeObjectivePacket.setObjectiveId(objective.getObjectiveName()); session.sendUpstreamPacket(removeObjectivePacket); @@ -208,7 +215,7 @@ public class Scoreboard { } } - if (globalAdd || globalUpdate) { + if (globalAdd || globalUpdate || scoreChanged) { SetDisplayObjectivePacket displayObjectivePacket = new SetDisplayObjectivePacket(); displayObjectivePacket.setObjectiveId(objective.getObjectiveName()); displayObjectivePacket.setDisplayName(objective.getDisplayName()); From 2dc7dc10ff11b9435920d8a2188a57298dca9f2c Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Tue, 22 Sep 2020 14:15:59 -0400 Subject: [PATCH 3/9] Remove warning about slot 50 (#1325) We know that it occurs with console crafting. --- .../translators/inventory/CraftingInventoryTranslator.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java index f5ebe62df..b260565b8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/inventory/CraftingInventoryTranslator.java @@ -30,12 +30,9 @@ import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.data.inventory.InventoryActionData; import com.nukkitx.protocol.bedrock.data.inventory.InventorySource; -import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; -import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.inventory.updater.CursorInventoryUpdater; -import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater; import org.geysermc.connector.utils.InventoryUtils; import java.util.List; @@ -48,7 +45,7 @@ public class CraftingInventoryTranslator extends BlockInventoryTranslator { @Override public int bedrockSlotToJava(InventoryActionData action) { if (action.getSlot() == 50) { - GeyserConnector.getInstance().getLogger().warning("Slot 50 found, please report: " + action); + // Slot 50 is used for crafting with a controller. return 0; } From b4c7682130d4e8931da2f5dfa10d984eb2e17f9d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Tue, 22 Sep 2020 14:16:57 -0400 Subject: [PATCH 4/9] Implement experience sounds (#1320) Bedrock sends a level event for the experience sound around the same time as a Java entity collect item packet is sent. --- .../JavaEntityCollectItemTranslator.java} | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) rename connector/src/main/java/org/geysermc/connector/network/translators/java/{world/JavaCollectItemTranslator.java => entity/JavaEntityCollectItemTranslator.java} (61%) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaCollectItemTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityCollectItemTranslator.java similarity index 61% rename from connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaCollectItemTranslator.java rename to connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityCollectItemTranslator.java index a90c7016b..270c33a7a 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaCollectItemTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/JavaEntityCollectItemTranslator.java @@ -23,26 +23,32 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.connector.network.translators.java.world; +package org.geysermc.connector.network.translators.java.entity; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityCollectItemPacket; +import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import com.nukkitx.protocol.bedrock.packet.TakeItemEntityPacket; import org.geysermc.connector.entity.Entity; +import org.geysermc.connector.entity.ExpOrbEntity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +/** + * This packet is called whenever a player picks up an item. + * In Java, this is called for item entities, experience orbs and arrows + * Bedrock uses it for arrows and item entities, but not experience orbs. + */ @Translator(packet = ServerEntityCollectItemPacket.class) -public class JavaCollectItemTranslator extends PacketTranslator { +public class JavaEntityCollectItemTranslator extends PacketTranslator { @Override public void translate(ServerEntityCollectItemPacket packet, GeyserSession session) { - // This is the definition of translating - both packets take the same values - TakeItemEntityPacket takeItemEntityPacket = new TakeItemEntityPacket(); - // Collected entity is the item + // Collected entity is the other entity Entity collectedEntity = session.getEntityCache().getEntityByJavaId(packet.getCollectedEntityId()); if (collectedEntity == null) return; - // Collector is the entity picking up the item + // Collector is the entity 'picking up' the item Entity collectorEntity; if (packet.getCollectorEntityId() == session.getPlayerEntity().getEntityId()) { collectorEntity = session.getPlayerEntity(); @@ -50,8 +56,19 @@ public class JavaCollectItemTranslator extends PacketTranslator Date: Tue, 22 Sep 2020 20:10:38 -0500 Subject: [PATCH 5/9] Use SERVER_READY in BedrockRespawnTranslator to fix respawn bug --- .../network/translators/bedrock/BedrockRespawnTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java index 4e4b4a307..71d52e134 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java @@ -43,7 +43,7 @@ public class BedrockRespawnTranslator extends PacketTranslator { RespawnPacket respawnPacket = new RespawnPacket(); respawnPacket.setRuntimeEntityId(0); respawnPacket.setPosition(Vector3f.ZERO); - respawnPacket.setState(RespawnPacket.State.SERVER_SEARCHING); + respawnPacket.setState(RespawnPacket.State.SERVER_READY); session.sendUpstreamPacket(respawnPacket); } From 1ec768d95d313525e03af4b500927c29a2eb5762 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+DoctorMacc@users.noreply.github.com> Date: Thu, 24 Sep 2020 12:54:18 -0400 Subject: [PATCH 6/9] Fix interaction spam bug (#1324) * Fix interaction spam bug This references the Nukkit 1.0 fix for the client bug of spamming to interact. Holding down still works. * Remove interaction position set at action type 1 * Remove debug line --- .../connector/network/session/GeyserSession.java | 14 +++++++++++++- .../BedrockInventoryTransactionTranslator.java | 14 +++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 81b922826..0a28b11f1 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 @@ -156,8 +156,13 @@ public class GeyserSession implements CommandSender { @Setter private boolean interacting; + /** + * Stores the last position of the block the player interacted with. This can either be a block that the client + * placed or an existing block the player interacted with (for example, a chest).
+ * Initialized as (0, 0, 0) so it is always not-null. + */ @Setter - private Vector3i lastInteractionPosition; + private Vector3i lastInteractionPosition = Vector3i.ZERO; private boolean manyDimPackets = false; private ServerRespawnPacket lastDimPacket = null; @@ -193,6 +198,13 @@ public class GeyserSession implements CommandSender { @Setter private long lastHitTime; + /** + * Store the last time the player interacted. Used to fix a right-click spam bug. + * See https://github.com/GeyserMC/Geyser/issues/503 for context. + */ + @Setter + private long lastInteractionTime; + private boolean reducedDebugInfo = false; @Setter 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 95e669572..131fdcc97 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 @@ -78,6 +78,17 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator Date: Thu, 24 Sep 2020 15:11:42 -0400 Subject: [PATCH 7/9] Fix picking up liquids with buckets (#1311) * Fix picking up liquids with buckets The last fix to prevent bucket placement upon interacting with an inventory had an oversight with empty buckets, making them unusable. This commit fixes that while keeping the previous fix. * Remove debug line * Fix milk drinking and visual bucket item apperance * Comment elaboration * Make indentiation better --- ...BedrockInventoryTransactionTranslator.java | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) 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 131fdcc97..8e891d925 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 @@ -39,8 +39,10 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlaye import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.protocol.bedrock.data.LevelEventType; +import com.nukkitx.protocol.bedrock.data.inventory.ContainerId; import com.nukkitx.protocol.bedrock.data.inventory.ContainerType; import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket; +import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket; import com.nukkitx.protocol.bedrock.packet.LevelEventPacket; import org.geysermc.connector.entity.CommandBlockMinecartEntity; @@ -112,11 +114,23 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator Date: Fri, 25 Sep 2020 15:09:02 -0400 Subject: [PATCH 8/9] Prevent Bedrock from changing gamemode client-side (#1337) In vanilla Bedrock, if you have operator status, the client sends a packet to change gamemode without confirmation from the server. Since we have a custom server option to request the gamemode, we just reset the gamemode and ignore this packet. --- .../BedrockSetPlayerGameTypeTranslator.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.java new file mode 100644 index 000000000..d61b37863 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/player/BedrockSetPlayerGameTypeTranslator.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.bedrock.entity.player; + +import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; +import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.PacketTranslator; +import org.geysermc.connector.network.translators.Translator; + +/** + * In vanilla Bedrock, if you have operator status, this sets the player's gamemode without confirmation from the server. + * Since we have a custom server option to request the gamemode, we just reset the gamemode and ignore this. + */ +@Translator(packet = SetPlayerGameTypePacket.class) +public class BedrockSetPlayerGameTypeTranslator extends PacketTranslator { + + @Override + public void translate(SetPlayerGameTypePacket packet, GeyserSession session) { + // no + SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); + playerGameTypePacket.setGamemode(session.getGameMode().ordinal()); + session.sendUpstreamPacket(playerGameTypePacket); + } +} From d9b05f5b72beed41d0a57d0594de6c88b47b649d Mon Sep 17 00:00:00 2001 From: Luke <32024335+lukeeey@users.noreply.github.com> Date: Fri, 25 Sep 2020 20:52:44 +0100 Subject: [PATCH 9/9] Update the CI link in the README (#1339) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ba3e6fc2d..e0404a934 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![forthebadge made-with-java](http://ForTheBadge.com/images/badges/made-with-java.svg)](https://java.com/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -[![Build Status](https://ci.nukkitx.com/job/Geyser/job/master/badge/icon)](https://ci.nukkitx.com/job/Geyser/job/master/) +[![Build Status](https://ci.nukkitx.com/job/Geyser/job/master/badge/icon)](https://ci.nukkitx.com/job/GeyserMC/job/Geyser/job/master/) [![Discord](https://img.shields.io/discord/613163671870242838.svg?color=%237289da&label=discord)](http://discord.geysermc.org/) [![HitCount](http://hits.dwyl.io/Geyser/GeyserMC.svg)](http://hits.dwyl.io/Geyser/GeyserMC) [![Crowdin](https://badges.crowdin.net/geyser/localized.svg)](https://translate.geysermc.org/)