From dbf366b138c581c4bbb139b3bdb353274fbfa62d Mon Sep 17 00:00:00 2001
From: Camotoy <20743703+Camotoy@users.noreply.github.com>
Date: Mon, 10 May 2021 21:14:30 -0400
Subject: [PATCH 1/6] ACTUALLY fix swapping armor in hotbar when armor is
already present (#2206)
Tested with iOS, desktop and console
---
.../bedrock/BedrockInventoryTransactionTranslator.java | 10 ++++------
1 file changed, 4 insertions(+), 6 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 2358fa2783e..6378c0ba956 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,10 +39,7 @@
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlags;
-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.data.inventory.*;
import com.nukkitx.protocol.bedrock.packet.*;
import org.geysermc.connector.entity.CommandBlockMinecartEntity;
import org.geysermc.connector.entity.Entity;
@@ -241,9 +238,10 @@ else if (packet.getItemInHand() != null && ItemRegistry.BUCKETS.contains(packet.
session.setInteracting(true);
break;
case 1:
- if (packet.getActions().size() == 1) {
+ if (packet.getActions().size() == 1 && packet.getLegacySlots().size() > 0) {
InventoryActionData actionData = packet.getActions().get(0);
- if (actionData.getSlot() == 6 && actionData.getToItem().getId() != 0) {
+ LegacySetItemSlotData slotData = packet.getLegacySlots().get(0);
+ if (slotData.getContainerId() == 6 && actionData.getToItem().getId() != 0) {
// The player is trying to swap out an armor piece that already has an item in it
// Java Edition does not allow this; let's revert it
session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory());
From 3e3b8faf16ad09fa8aeb436cf1de53b1c90f82cd Mon Sep 17 00:00:00 2001
From: Konicai <71294714+Konicai@users.noreply.github.com>
Date: Fri, 14 May 2021 22:48:34 -0400
Subject: [PATCH 2/6] Add client setting for cooldown type, refactor
show-coordinates (#2193)
---
.../geysermc/connector/GeyserConnector.java | 2 +-
.../network/session/GeyserSession.java | 4 +-
.../session/cache/PreferencesCache.java | 71 +++++++++++++++++++
.../network/session/cache/WorldCache.java | 21 ------
.../connector/utils/CooldownUtils.java | 31 +++++---
.../connector/utils/SettingsUtils.java | 37 +++++++---
connector/src/main/resources/languages | 2 +-
7 files changed, 125 insertions(+), 43 deletions(-)
create mode 100644 connector/src/main/java/org/geysermc/connector/network/session/cache/PreferencesCache.java
diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
index 03bf7538cfc..d2caac216a2 100644
--- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
+++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
@@ -188,7 +188,7 @@ private GeyserConnector(PlatformType platformType, GeyserBootstrap bootstrap) {
defaultAuthType = AuthType.getByName(config.getRemote().getAuthType());
- CooldownUtils.setShowCooldown(config.getShowCooldown());
+ CooldownUtils.setDefaultShowCooldown(config.getShowCooldown());
DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether
SkullBlockEntityTranslator.ALLOW_CUSTOM_SKULLS = config.isAllowCustomSkulls();
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 28aff40b914..3748a3ba202 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
@@ -144,6 +144,7 @@ public class GeyserSession implements CommandSender {
private ChunkCache chunkCache;
private EntityCache entityCache;
private EntityEffectCache effectCache;
+ private final PreferencesCache preferencesCache;
private final TagCache tagCache;
private WorldCache worldCache;
private WindowCache windowCache;
@@ -451,6 +452,7 @@ public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServ
this.chunkCache = new ChunkCache(this);
this.entityCache = new EntityCache(this);
this.effectCache = new EntityEffectCache();
+ this.preferencesCache = new PreferencesCache(this);
this.tagCache = new TagCache();
this.worldCache = new WorldCache(this);
this.windowCache = new WindowCache(this);
@@ -1224,7 +1226,7 @@ public void sendDownstreamPacket(Packet packet) {
public void setReducedDebugInfo(boolean value) {
reducedDebugInfo = value;
// Set the showCoordinates data. This is done because updateShowCoordinates() uses this gamerule as a variable.
- getWorldCache().updateShowCoordinates();
+ preferencesCache.updateShowCoordinates();
}
/**
diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/PreferencesCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/PreferencesCache.java
new file mode 100644
index 00000000000..d477066c219
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/PreferencesCache.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019-2021 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.session.cache;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.geysermc.connector.configuration.GeyserConfiguration;
+import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.utils.CooldownUtils;
+
+@Getter
+public class PreferencesCache {
+ private final GeyserSession session;
+
+ /**
+ * True if the client prefers being shown their coordinates, regardless if they're being shown or not.
+ * This will be true everytime the client joins the server because neither the client nor server store the preference permanently.
+ */
+ @Setter
+ private boolean prefersShowCoordinates = true;
+ /**
+ * If the client's preference will be ignored, this will return false.
+ */
+ private boolean allowShowCoordinates;
+
+ /**
+ * Which CooldownType the client prefers. Initially set to {@link CooldownUtils#getDefaultShowCooldown()}.
+ */
+ @Setter
+ private CooldownUtils.CooldownType cooldownPreference = CooldownUtils.getDefaultShowCooldown();
+
+ public PreferencesCache(GeyserSession session) {
+ this.session = session;
+ }
+
+ /**
+ * Tell the client to hide or show the coordinates.
+ *
+ * If {@link #prefersShowCoordinates} is true, coordinates will be shown, unless either of the following conditions apply:
+ *
+ * {@link GeyserSession#reducedDebugInfo} is enabled
+ * {@link GeyserConfiguration#isShowCoordinates()} is disabled
+ */
+ public void updateShowCoordinates() {
+ allowShowCoordinates = !session.isReducedDebugInfo() && session.getConnector().getConfig().isShowCoordinates();
+ session.sendGameRule("showcoordinates", allowShowCoordinates && prefersShowCoordinates);
+ }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/WorldCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/WorldCache.java
index 84678c21133..4a293962120 100644
--- a/connector/src/main/java/org/geysermc/connector/network/session/cache/WorldCache.java
+++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/WorldCache.java
@@ -28,7 +28,6 @@
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
import lombok.Getter;
import lombok.Setter;
-import org.geysermc.connector.configuration.GeyserConfiguration;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.scoreboard.Objective;
import org.geysermc.connector.scoreboard.Scoreboard;
@@ -40,13 +39,6 @@ public class WorldCache {
@Setter
private Difficulty difficulty = Difficulty.EASY;
- /**
- * True if the client prefers being shown their coordinates, regardless if they're being shown or not.
- * This will be true everytime the client joins the server because neither the client nor server store the preference permanently.
- */
- @Setter
- private boolean prefersShowCoordinates = true;
-
private Scoreboard scoreboard;
private final ScoreboardUpdater scoreboardUpdater;
@@ -71,17 +63,4 @@ public int increaseAndGetScoreboardPacketsPerSecond() {
int pps = scoreboardUpdater.getPacketsPerSecond();
return Math.max(pps, pendingPps);
}
-
- /**
- * Tell the client to hide or show the coordinates.
- *
- * If {@link #prefersShowCoordinates} is true, coordinates will be shown, unless either of the following conditions apply:
- *
- * {@link GeyserSession#reducedDebugInfo} is enabled
- * {@link GeyserConfiguration#isShowCoordinates()} is disabled
- */
- public void updateShowCoordinates() {
- boolean allowShowCoordinates = !session.isReducedDebugInfo() && session.getConnector().getConfig().isShowCoordinates();
- session.sendGameRule("showcoordinates", allowShowCoordinates && prefersShowCoordinates);
- }
}
\ No newline at end of file
diff --git a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java
index 0b5c2bdd3d4..6151435894c 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java
@@ -28,6 +28,7 @@
import com.nukkitx.protocol.bedrock.packet.SetTitlePacket;
import lombok.Getter;
import org.geysermc.connector.network.session.GeyserSession;
+import org.geysermc.connector.network.session.cache.PreferencesCache;
import java.util.concurrent.TimeUnit;
@@ -36,18 +37,25 @@
* Much of the work here is from the wonderful folks from ViaRewind: https://github.com/ViaVersion/ViaRewind
*/
public class CooldownUtils {
- private static CooldownType SHOW_COOLDOWN;
+ private static CooldownType DEFAULT_SHOW_COOLDOWN;
- public static void setShowCooldown(String showCooldown) {
- SHOW_COOLDOWN = CooldownType.getByName(showCooldown);
+ public static void setDefaultShowCooldown(String showCooldown) {
+ DEFAULT_SHOW_COOLDOWN = CooldownType.getByName(showCooldown);
+ }
+
+ public static CooldownType getDefaultShowCooldown() {
+ return DEFAULT_SHOW_COOLDOWN;
}
/**
- * Starts sending the fake cooldown to the Bedrock client.
+ * Starts sending the fake cooldown to the Bedrock client. If the cooldown is not disabled, the sent type is {@link PreferencesCache#getCooldownPreference()}
* @param session GeyserSession
*/
public static void sendCooldown(GeyserSession session) {
- if (SHOW_COOLDOWN == CooldownType.DISABLED) return;
+ if (DEFAULT_SHOW_COOLDOWN == CooldownType.DISABLED) return;
+ CooldownType sessionPreference = session.getPreferencesCache().getCooldownPreference();
+ if (sessionPreference == CooldownType.DISABLED) return;
+
if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used
// Needs to be sent or no subtitle packet is recognized by the client
SetTitlePacket titlePacket = new SetTitlePacket();
@@ -56,19 +64,20 @@ public static void sendCooldown(GeyserSession session) {
session.sendUpstreamPacket(titlePacket);
session.setLastHitTime(System.currentTimeMillis());
long lastHitTime = session.getLastHitTime(); // Used later to prevent multiple scheduled cooldown threads
- computeCooldown(session, lastHitTime);
+ computeCooldown(session, sessionPreference, lastHitTime);
}
/**
* Keeps updating the cooldown until the bar is complete.
* @param session GeyserSession
+ * @param sessionPreference The type of cooldown the client prefers
* @param lastHitTime The time of the last hit. Used to gauge how long the cooldown is taking.
*/
- private static void computeCooldown(GeyserSession session, long lastHitTime) {
+ private static void computeCooldown(GeyserSession session, CooldownType sessionPreference, long lastHitTime) {
if (session.isClosed()) return; // Don't run scheduled tasks if the client left
if (lastHitTime != session.getLastHitTime()) return; // Means another cooldown has started so there's no need to continue this one
SetTitlePacket titlePacket = new SetTitlePacket();
- if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) {
+ if (sessionPreference == CooldownType.ACTIONBAR) {
titlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
} else {
titlePacket.setType(SetTitlePacket.Type.SUBTITLE);
@@ -79,10 +88,10 @@ private static void computeCooldown(GeyserSession session, long lastHitTime) {
titlePacket.setStayTime(2);
session.sendUpstreamPacket(titlePacket);
if (hasCooldown(session)) {
- session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50
+ session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, sessionPreference, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50
} else {
SetTitlePacket removeTitlePacket = new SetTitlePacket();
- if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) {
+ if (sessionPreference == CooldownType.ACTIONBAR) {
removeTitlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
} else {
removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE);
@@ -133,7 +142,7 @@ public enum CooldownType {
public static final CooldownType[] VALUES = values();
/**
- * Convert the CooldownType string (from config) to the enum, TITLE on fail
+ * Convert the CooldownType string (from config) to the enum, DISABLED on fail
*
* @param name CooldownType string
*
diff --git a/connector/src/main/java/org/geysermc/connector/utils/SettingsUtils.java b/connector/src/main/java/org/geysermc/connector/utils/SettingsUtils.java
index 1d06c8a0f1a..d0cfce86236 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/SettingsUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/SettingsUtils.java
@@ -57,11 +57,24 @@ public static void buildForm(GeyserSession session) {
CustomFormBuilder builder = new CustomFormBuilder(LanguageUtils.getPlayerLocaleString("geyser.settings.title.main", language));
builder.setIcon(new FormImage(FormImage.FormImageType.PATH, "textures/ui/settings_glyph_color_2x.png"));
- // Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
- if (!session.isReducedDebugInfo() && session.getConnector().getConfig().isShowCoordinates()) {
+ // Only show the client title if any of the client settings are available
+ if (session.getPreferencesCache().isAllowShowCoordinates() || CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
builder.addComponent(new LabelComponent(LanguageUtils.getPlayerLocaleString("geyser.settings.title.client", language)));
- builder.addComponent(new ToggleComponent(LanguageUtils.getPlayerLocaleString("geyser.settings.option.coordinates", language), session.getWorldCache().isPrefersShowCoordinates()));
+ // Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
+ if (session.getPreferencesCache().isAllowShowCoordinates()) {
+ builder.addComponent(new ToggleComponent(LanguageUtils.getPlayerLocaleString("geyser.settings.option.coordinates", language), session.getPreferencesCache().isPrefersShowCoordinates()));
+ }
+
+ if (CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
+ DropdownComponent cooldownDropdown = new DropdownComponent();
+ cooldownDropdown.setText(LocaleUtils.getLocaleString("options.attackIndicator", language));
+ cooldownDropdown.setOptions(new ArrayList<>());
+ cooldownDropdown.addOption(LocaleUtils.getLocaleString("options.attack.crosshair", language), session.getPreferencesCache().getCooldownPreference() == CooldownUtils.CooldownType.TITLE);
+ cooldownDropdown.addOption(LocaleUtils.getLocaleString("options.attack.hotbar", language), session.getPreferencesCache().getCooldownPreference() == CooldownUtils.CooldownType.ACTIONBAR);
+ cooldownDropdown.addOption(LocaleUtils.getLocaleString("options.off", language), session.getPreferencesCache().getCooldownPreference() == CooldownUtils.CooldownType.DISABLED);
+ builder.addComponent(cooldownDropdown);
+ }
}
@@ -121,13 +134,21 @@ public static boolean handleSettingsForm(GeyserSession session, String response)
}
int offset = 0;
- // Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
- if (!session.isReducedDebugInfo() && session.getConnector().getConfig().isShowCoordinates()) {
+ if (session.getPreferencesCache().isAllowShowCoordinates() || CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
offset++; // Client settings title
- session.getWorldCache().setPrefersShowCoordinates(settingsResponse.getToggleResponses().get(offset));
- session.getWorldCache().updateShowCoordinates();
- offset++;
+ // Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
+ if (session.getPreferencesCache().isAllowShowCoordinates()) {
+ session.getPreferencesCache().setPrefersShowCoordinates(settingsResponse.getToggleResponses().get(offset));
+ session.getPreferencesCache().updateShowCoordinates();
+ offset++;
+ }
+
+ if (CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
+ CooldownUtils.CooldownType cooldownType = CooldownUtils.CooldownType.VALUES[settingsResponse.getDropdownResponses().get(offset).getElementID()];
+ session.getPreferencesCache().setCooldownPreference(cooldownType);
+ offset++;
+ }
}
if (session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.server")) {
diff --git a/connector/src/main/resources/languages b/connector/src/main/resources/languages
index 96e7ed66ccd..9b08df51898 160000
--- a/connector/src/main/resources/languages
+++ b/connector/src/main/resources/languages
@@ -1 +1 @@
-Subproject commit 96e7ed66ccdafea0cc991b8004566d448e8f6e6a
+Subproject commit 9b08df51898fd71ee24e7accdfbe56f164b5c539
From dfc24f1ecb1f626002b1eacc79916471b7047ada Mon Sep 17 00:00:00 2001
From: Konicai <71294714+Konicai@users.noreply.github.com>
Date: Fri, 14 May 2021 23:12:37 -0400
Subject: [PATCH 3/6] Fix Javadoc in CooldownUtils (#2213)
---
.../main/java/org/geysermc/connector/utils/CooldownUtils.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java
index 6151435894c..43675ebfd78 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/CooldownUtils.java
@@ -48,7 +48,7 @@ public static CooldownType getDefaultShowCooldown() {
}
/**
- * Starts sending the fake cooldown to the Bedrock client. If the cooldown is not disabled, the sent type is {@link PreferencesCache#getCooldownPreference()}
+ * Starts sending the fake cooldown to the Bedrock client. If the cooldown is not disabled, the sent type is the cooldownPreference in {@link PreferencesCache}
* @param session GeyserSession
*/
public static void sendCooldown(GeyserSession session) {
From 74a688b44b189a81ccd07ffefcce9a8becd04aaf Mon Sep 17 00:00:00 2001
From: Redned
Date: Fri, 21 May 2021 18:46:26 -0500
Subject: [PATCH 4/6] Replace the "What can't be fixed" list with a link to a
new page on the wiki
---
README.md | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/README.md b/README.md
index a51c61f9fd5..21cdf945ed8 100644
--- a/README.md
+++ b/README.md
@@ -40,13 +40,7 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set
- Structure block UI
## What can't be fixed
-The following things cannot be fixed without changes to Bedrock. As of now, they are not fixable in Geyser.
-
-- Custom heads in inventories
-- Clickable links in chat
-- Glowing effect
-
-Do note that some things require the [GeyserOptionalPack](https://github.com/GeyserMC/Geyser/wiki/GeyserOptionalPack) in order to function, such as custom armor stand poses.
+There are a few things Geyser is unable to support due to various differences between Minecraft Bedrock and Java. For a list of these limitations, see the [Current Limitations](https://github.com/GeyserMC/Geyser/wiki/Current-Limitations) page.
## Compiling
1. Clone the repo to your computer
From f8315579191c2e4aba9e57e6c0746b44fc046164 Mon Sep 17 00:00:00 2001
From: Hellohi3654 <57390764+Hellohi3654@users.noreply.github.com>
Date: Sat, 22 May 2021 23:26:47 +1000
Subject: [PATCH 5/6] Update pom.xml (#2220)
---
bootstrap/bungeecord/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml
index a62faa33a2c..738c1ee1cf6 100644
--- a/bootstrap/bungeecord/pom.xml
+++ b/bootstrap/bungeecord/pom.xml
@@ -20,7 +20,7 @@
net.md-5
bungeecord-api
- 1.16-R0.4-SNAPSHOT
+ 1.16-R0.5-SNAPSHOT
provided
From 4734ce20595bdc38608af54648142ed209c298ac Mon Sep 17 00:00:00 2001
From: Camotoy <20743703+Camotoy@users.noreply.github.com>
Date: Sun, 23 May 2021 15:55:01 -0400
Subject: [PATCH 6/6] Update MCProtocolLib + PacketLib (#2211)
By updating these dependencies, we bring in a couple fixes that should improve network performance:
Use TCP_NODELAY for the Java connection
Use Epoll/KQueue if possible for the Java connection
Only use one event loop for the Java connection
Fix Netty dependencies so Spigot and BungeeCord can use native network types
Currently, Geyser-Spigot pre-1.12 breaks with these changes. It is unlikely that this will be fixed.
---
bootstrap/bungeecord/pom.xml | 15 +++++++--
bootstrap/spigot/pom.xml | 18 ++++++++---
.../platform/spigot/GeyserSpigotPlugin.java | 17 ++++++++++
bootstrap/velocity/pom.xml | 1 +
connector/pom.xml | 4 +--
.../geysermc/connector/GeyserConnector.java | 15 +++++++++
.../network/session/GeyserSession.java | 31 +++++++++----------
.../network/session/cache/BookEditCache.java | 2 +-
connector/src/main/resources/languages | 2 +-
9 files changed, 79 insertions(+), 26 deletions(-)
diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml
index 738c1ee1cf6..9cf8b476395 100644
--- a/bootstrap/bungeecord/pom.xml
+++ b/bootstrap/bungeecord/pom.xml
@@ -66,8 +66,10 @@
org.geysermc.platform.bungeecord.shaded.jackson
- io.netty
- org.geysermc.platform.bungeecord.shaded.netty
+
+ io.netty.channel.kqueue
+ org.geysermc.platform.bungeecord.shaded.io.netty.channel.kqueue
org.reflections
@@ -98,6 +100,15 @@
com.google.code.gson:*
org.yaml:*
+ io.netty:netty-transport-native-epoll:*
+ io.netty:netty-transport-native-unix-common:*
+ io.netty:netty-handler:*
+ io.netty:netty-common:*
+ io.netty:netty-buffer:*
+ io.netty:netty-resolver:*
+ io.netty:netty-transport:*
+ io.netty:netty-codec:*
+ io.netty:netty-resolver-dns:*
diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml
index 12c8292e911..3dd25312c76 100644
--- a/bootstrap/spigot/pom.xml
+++ b/bootstrap/spigot/pom.xml
@@ -68,10 +68,6 @@
-
- io.netty
- org.geysermc.platform.spigot.shaded.netty
-
it.unimi.dsi.fastutil
org.geysermc.platform.spigot.shaded.fastutil
@@ -109,6 +105,20 @@
com.google.code.gson:*
org.yaml:*
+
+
+ io.netty:netty-transport-native-epoll:*
+ io.netty:netty-transport-native-unix-common:*
+ io.netty:netty-transport-native-kqueue:*
+ io.netty:netty-handler:*
+ io.netty:netty-common:*
+ io.netty:netty-buffer:*
+ io.netty:netty-resolver:*
+ io.netty:netty-transport:*
+ io.netty:netty-codec:*
+ io.netty:netty-codec-dns:*
+ io.netty:netty-resolver-dns:*
+ io.netty:netty-resolver-dns-native-macos:*
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java
index 671ad18cf99..b45cb700046 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java
@@ -95,6 +95,23 @@ public void onEnable() {
ex.printStackTrace();
}
+ try {
+ // Required for the Cloudburst Network dependency to initialize.
+ Class.forName("io.netty.channel.kqueue.KQueue");
+ } catch (ClassNotFoundException e) {
+ // While we could support these older versions, the downside is not having KQueue working at all
+ // And since there are alternative ways to get Geyser working for these aging platforms, it's not worth it.
+ getLogger().severe("*********************************************");
+ getLogger().severe("");
+ getLogger().severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.unsupported_server.header"));
+ getLogger().severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.unsupported_server.message", "1.12.2"));
+ getLogger().severe("");
+ getLogger().severe("*********************************************");
+
+ Bukkit.getPluginManager().disablePlugin(this);
+ return;
+ }
+
// By default this should be localhost but may need to be changed in some circumstances
if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) {
geyserConfig.setAutoconfiguredRemote(true);
diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml
index bcc62ed4cb0..b9f2e64f2b4 100644
--- a/bootstrap/velocity/pom.xml
+++ b/bootstrap/velocity/pom.xml
@@ -103,6 +103,7 @@
io.netty:netty-resolver:*
io.netty:netty-transport:*
io.netty:netty-codec:*
+ io.netty:netty-codec-haproxy:*
org.slf4j:*
org.ow2.asm:*
diff --git a/connector/pom.xml b/connector/pom.xml
index 7d4bae7a05f..9feb717b9e5 100644
--- a/connector/pom.xml
+++ b/connector/pom.xml
@@ -122,7 +122,7 @@
com.github.steveice10
mcprotocollib
- 26201a4
+ 8c204eb
compile
@@ -142,7 +142,7 @@
com.github.GeyserMC
PacketLib
- b77a427
+ 6e5dea9
compile
diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
index d2caac216a2..3f82889f5e2 100644
--- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
+++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
@@ -31,6 +31,8 @@
import com.nukkitx.network.raknet.RakNetConstants;
import com.nukkitx.network.util.EventLoops;
import com.nukkitx.protocol.bedrock.BedrockServer;
+import io.netty.channel.epoll.Epoll;
+import io.netty.channel.kqueue.KQueue;
import lombok.Getter;
import lombok.Setter;
import org.geysermc.common.PlatformType;
@@ -203,6 +205,19 @@ private GeyserConnector(PlatformType platformType, GeyserBootstrap bootstrap) {
EventLoops.commonGroup(),
enableProxyProtocol
);
+
+ if (config.isDebugMode()) {
+ logger.debug("EventLoop type: " + EventLoops.getChannelType());
+ if (EventLoops.getChannelType() == EventLoops.ChannelType.NIO) {
+ if (System.getProperties().contains("disableNativeEventLoop")) {
+ logger.debug("EventLoop type is NIO because native event loops are disabled.");
+ } else {
+ logger.debug("Reason for no Epoll: " + Epoll.unavailabilityCause().toString());
+ logger.debug("Reason for no KQueue: " + KQueue.unavailabilityCause().toString());
+ }
+ }
+ }
+
bedrockServer.setHandler(new ConnectorServerEventHandler(this));
bedrockServer.bind().whenComplete((avoid, throwable) -> {
if (throwable == null) {
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 3748a3ba202..1130356c1b7 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
@@ -46,10 +46,9 @@
import com.github.steveice10.mc.protocol.packet.login.client.LoginPluginResponsePacket;
import com.github.steveice10.mc.protocol.packet.login.server.LoginSuccessPacket;
import com.github.steveice10.packetlib.BuiltinFlags;
-import com.github.steveice10.packetlib.Client;
import com.github.steveice10.packetlib.event.session.*;
import com.github.steveice10.packetlib.packet.Packet;
-import com.github.steveice10.packetlib.tcp.TcpSessionFactory;
+import com.github.steveice10.packetlib.tcp.TcpClientSession;
import com.nukkitx.math.GenericMath;
import com.nukkitx.math.vector.*;
import com.nukkitx.protocol.bedrock.BedrockPacket;
@@ -118,7 +117,7 @@ public class GeyserSession implements CommandSender {
private final GeyserConnector connector;
private final UpstreamSession upstream;
- private Client downstream;
+ private TcpClientSession downstream;
@Setter
private AuthData authData;
@Setter
@@ -587,7 +586,7 @@ public void authenticate(String username, String password) {
authenticationService.setPassword(password);
authenticationService.login();
- protocol = new MinecraftProtocol(authenticationService);
+ protocol = new MinecraftProtocol(authenticationService.getSelectedProfile(), authenticationService.getAccessToken());
} else {
protocol = new MinecraftProtocol(username);
}
@@ -645,7 +644,7 @@ private void attemptCodeAuthentication(MsaAuthenticationService msaAuthenticatio
}
try {
msaAuthenticationService.login();
- protocol = new MinecraftProtocol(msaAuthenticationService);
+ protocol = new MinecraftProtocol(msaAuthenticationService.getSelectedProfile(), msaAuthenticationService.getAccessToken());
connectDownstream();
} catch (RequestException e) {
@@ -685,17 +684,17 @@ private void connectDownstream() {
// Start ticking
tickThread = connector.getGeneralThreadPool().scheduleAtFixedRate(this::tick, 50, 50, TimeUnit.MILLISECONDS);
- downstream = new Client(this.remoteAddress, this.remotePort, protocol, new TcpSessionFactory());
+ downstream = new TcpClientSession(this.remoteAddress, this.remotePort, protocol);
disableSrvResolving();
if (connector.getConfig().getRemote().isUseProxyProtocol()) {
- downstream.getSession().setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
- downstream.getSession().setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
+ downstream.setFlag(BuiltinFlags.ENABLE_CLIENT_PROXY_PROTOCOL, true);
+ downstream.setFlag(BuiltinFlags.CLIENT_PROXIED_ADDRESS, upstream.getAddress());
}
if (connector.getConfig().isForwardPlayerPing()) {
// Let Geyser handle sending the keep alive
- downstream.getSession().setFlag(MinecraftConstants.AUTOMATIC_KEEP_ALIVE_MANAGEMENT, false);
+ downstream.setFlag(MinecraftConstants.AUTOMATIC_KEEP_ALIVE_MANAGEMENT, false);
}
- downstream.getSession().addListener(new SessionAdapter() {
+ downstream.addListener(new SessionAdapter() {
@Override
public void packetSending(PacketSendingEvent event) {
//todo move this somewhere else
@@ -818,15 +817,15 @@ public void packetError(PacketErrorEvent event) {
if (!daylightCycle) {
setDaylightCycle(true);
}
- downstream.getSession().connect();
+ downstream.connect();
connector.addPlayer(this);
}
public void disconnect(String reason) {
if (!closed) {
loggedIn = false;
- if (downstream != null && downstream.getSession() != null) {
- downstream.getSession().disconnect(reason);
+ if (downstream != null) {
+ downstream.disconnect(reason);
}
if (upstream != null && !upstream.isClosed()) {
connector.getPlayers().remove(this);
@@ -954,7 +953,7 @@ public boolean adjustSpeed() {
* Will be overwritten for GeyserConnect.
*/
protected void disableSrvResolving() {
- this.downstream.getSession().setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, false);
+ this.downstream.setFlag(BuiltinFlags.ATTEMPT_SRV_RESOLVE, false);
}
@Override
@@ -1210,8 +1209,8 @@ public void sendUpstreamPacketImmediately(BedrockPacket packet) {
* @param packet the java edition packet from MCProtocolLib
*/
public void sendDownstreamPacket(Packet packet) {
- if (downstream != null && downstream.getSession() != null && (protocol.getSubProtocol().equals(SubProtocol.GAME) || packet.getClass() == LoginPluginResponsePacket.class)) {
- downstream.getSession().send(packet);
+ if (downstream != null && (protocol.getSubProtocol().equals(SubProtocol.GAME) || packet.getClass() == LoginPluginResponsePacket.class)) {
+ downstream.send(packet);
} else {
connector.getLogger().debug("Tried to send downstream packet " + packet.getClass().getSimpleName() + " before connected to the server");
}
diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/BookEditCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/BookEditCache.java
index c82645dbfdb..cb373789577 100644
--- a/connector/src/main/java/org/geysermc/connector/network/session/cache/BookEditCache.java
+++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/BookEditCache.java
@@ -68,7 +68,7 @@ public void checkForSend() {
packet = null;
return;
}
- session.getDownstream().getSession().send(packet);
+ session.sendDownstreamPacket(packet);
packet = null;
lastBookUpdate = System.currentTimeMillis();
}
diff --git a/connector/src/main/resources/languages b/connector/src/main/resources/languages
index 9b08df51898..e1e8fd6c2b8 160000
--- a/connector/src/main/resources/languages
+++ b/connector/src/main/resources/languages
@@ -1 +1 @@
-Subproject commit 9b08df51898fd71ee24e7accdfbe56f164b5c539
+Subproject commit e1e8fd6c2b8abf366e60085c23a55a2c943806ae