diff --git a/README.md b/README.md
index e141b3263..fba796903 100644
--- a/README.md
+++ b/README.md
@@ -42,13 +42,7 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set
Extended height features can be "supported", but require additional work.
## 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
diff --git a/bootstrap/bungeecord/pom.xml b/bootstrap/bungeecord/pom.xml
index a62faa33a..9cf8b4763 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
@@ -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 12c8292e9..3dd25312c 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 7a5aaaf47..d9b3c3a93 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 class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
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 bcc62ed4c..b9f2e64f2 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 e4b5adee4..6529dbcd8 100644
--- a/connector/pom.xml
+++ b/connector/pom.xml
@@ -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 d2caac216..3f82889f5 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.fasterxml.jackson.databind.ObjectMapper;
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 @@ public class GeyserConnector {
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 400796392..454f03c8c 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.ingame.client.world.ClientTelepo
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 class GeyserSession implements CommandSender {
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 @@ public class GeyserSession implements CommandSender {
}
try {
msaAuthenticationService.login();
- protocol = new MinecraftProtocol(msaAuthenticationService);
+ protocol = new MinecraftProtocol(msaAuthenticationService.getSelectedProfile(), msaAuthenticationService.getAccessToken());
connectDownstream();
} catch (RequestException e) {
@@ -685,17 +684,17 @@ public class GeyserSession implements CommandSender {
// 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 class GeyserSession implements CommandSender {
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 class GeyserSession implements CommandSender {
* 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
@@ -1211,8 +1210,8 @@ public class GeyserSession implements CommandSender {
* @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 c82645dbf..cb3737895 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 class BookEditCache {
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 9b08df518..e1e8fd6c2 160000
--- a/connector/src/main/resources/languages
+++ b/connector/src/main/resources/languages
@@ -1 +1 @@
-Subproject commit 9b08df51898fd71ee24e7accdfbe56f164b5c539
+Subproject commit e1e8fd6c2b8abf366e60085c23a55a2c943806ae