Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Shanwer committed Dec 6, 2024
2 parents a70b781 + 2019e53 commit 51a4b79
Show file tree
Hide file tree
Showing 17 changed files with 41 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ private void workAroundWeirdBug(GeyserBootstrap bootstrap) {
MinecraftProtocol protocol = new MinecraftProtocol();
LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(),
bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress,
InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper());
InetAddress.getLoopbackAddress().getHostAddress(), protocol, Runnable::run);
session.connect();
}

Expand Down
3 changes: 0 additions & 3 deletions core/src/main/java/org/geysermc/geyser/GeyserImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,6 @@ private void startInstance() {
}
}

// Ensure that PacketLib does not create an event loop for handling packets; we'll do that ourselves
TcpSession.USE_EVENT_LOOP_FOR_PACKETS = false;

pendingMicrosoftAuthentication = new PendingMicrosoftAuthentication(config.getPendingAuthenticationTimeout());

this.newsHandler = new NewsHandler(BRANCH, this.buildNumber());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public UpstreamPacketHandler(GeyserImpl geyser, GeyserSession session) {
}

private PacketSignal translateAndDefault(BedrockPacket packet) {
Registries.BEDROCK_PACKET_TRANSLATORS.translate(packet.getClass(), packet, session);
Registries.BEDROCK_PACKET_TRANSLATORS.translate(packet.getClass(), packet, session, false);
return PacketSignal.HANDLED; // PacketSignal.UNHANDLED will log a WARN publicly
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
Expand All @@ -72,11 +73,11 @@ public final class LocalSession extends TcpSession {
private final String clientIp;
private final PacketCodecHelper codecHelper;

public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, MinecraftCodecHelper codecHelper) {
super(host, port, protocol);
public LocalSession(String host, int port, SocketAddress targetAddress, String clientIp, PacketProtocol protocol, Executor packetHandlerExecutor) {
super(host, port, protocol, packetHandlerExecutor);
this.targetAddress = targetAddress;
this.clientIp = clientIp;
this.codecHelper = codecHelper;
this.codecHelper = protocol.createHelper();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ protected PacketTranslatorRegistry() {
}

@SuppressWarnings("unchecked")
public <P extends T> boolean translate(Class<? extends P> clazz, P packet, GeyserSession session) {
public <P extends T> boolean translate(Class<? extends P> clazz, P packet, GeyserSession session, boolean canRunImmediately) {
if (session.getUpstream().isClosed() || session.isClosed()) {
return false;
}

PacketTranslator<P> translator = (PacketTranslator<P>) this.mappings.get(clazz);
if (translator != null) {
EventLoop eventLoop = session.getEventLoop();
if (!translator.shouldExecuteInEventLoop() || eventLoop.inEventLoop()) {
EventLoop eventLoop = session.getTickEventLoop();
if (canRunImmediately || !translator.shouldExecuteInEventLoop() || eventLoop.inEventLoop()) {
translate0(session, translator, packet);
} else {
eventLoop.execute(() -> translate0(session, translator, packet));
Expand Down
49 changes: 24 additions & 25 deletions core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
* The loop where all packets and ticking is processed to prevent concurrency issues.
* If this is manually called, ensure that any exceptions are properly handled.
*/
private final EventLoop eventLoop;
private final EventLoop tickEventLoop;
@Setter
private AuthData authData;
private BedrockClientData clientData;
Expand Down Expand Up @@ -658,10 +658,10 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {

private MinecraftProtocol protocol;

public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop eventLoop) {
public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop tickEventLoop) {
this.geyser = geyser;
this.upstream = new UpstreamSession(bedrockServerSession);
this.eventLoop = eventLoop;
this.tickEventLoop = tickEventLoop;

this.erosionHandler = new GeyserboundHandshakePacketHandler(this);

Expand Down Expand Up @@ -1000,17 +1000,17 @@ private void connectDownstream() {
boolean floodgate = this.remoteServer.authType() == AuthType.FLOODGATE;

// Start ticking
tickThread = eventLoop.scheduleAtFixedRate(this::tick, 50, 50, TimeUnit.MILLISECONDS);
tickThread = tickEventLoop.scheduleAtFixedRate(this::tick, 50, 50, TimeUnit.MILLISECONDS);

TcpSession downstream;
if (geyser.getBootstrap().getSocketAddress() != null) {
// We're going to connect through the JVM and not through TCP
downstream = new LocalSession(this.remoteServer.address(), this.remoteServer.port(),
geyser.getBootstrap().getSocketAddress(), upstream.getAddress().getAddress().getHostAddress(),
this.protocol, this.protocol.createHelper());
this.protocol, tickEventLoop);
this.downstream = new DownstreamSession(downstream);
} else {
downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), this.protocol);
downstream = new TcpClientSession(this.remoteServer.address(), this.remoteServer.port(), "0.0.0.0", 0, this.protocol, null, tickEventLoop);
this.downstream = new DownstreamSession(downstream);

boolean resolveSrv = false;
Expand Down Expand Up @@ -1196,7 +1196,7 @@ public void disconnected(DisconnectedEvent event) {

@Override
public void packetReceived(Session session, Packet packet) {
Registries.JAVA_PACKET_TRANSLATORS.translate(packet.getClass(), packet, GeyserSession.this);
Registries.JAVA_PACKET_TRANSLATORS.translate(packet.getClass(), packet, GeyserSession.this, true);
}

@Override
Expand Down Expand Up @@ -1266,26 +1266,19 @@ public void disconnect(String reason) {
* Moves task to the session event loop if already not in it. Otherwise, the task is automatically ran.
*/
public void ensureInEventLoop(Runnable runnable) {
if (eventLoop.inEventLoop()) {
runnable.run();
if (tickEventLoop.inEventLoop()) {
executeRunnable(runnable);
return;
}

executeInEventLoop(runnable);
}

/**
* Executes a task and prints a stack trace if an error occurs.
*/
public void executeInEventLoop(Runnable runnable) {
eventLoop.execute(() -> {
try {
runnable.run();
} catch (ErosionCancellationException e) {
geyser.getLogger().debug("Caught ErosionCancellationException");
} catch (Throwable e) {
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
}
});
tickEventLoop.execute(() -> executeRunnable(runnable));
}

/**
Expand All @@ -1294,19 +1287,25 @@ public void executeInEventLoop(Runnable runnable) {
* The task will not run if the session is closed.
*/
public ScheduledFuture<?> scheduleInEventLoop(Runnable runnable, long duration, TimeUnit timeUnit) {
return eventLoop.schedule(() -> {
try {
return tickEventLoop.schedule(() -> {
executeRunnable(() -> {
if (!closed) {
runnable.run();
}
} catch (ErosionCancellationException e) {
geyser.getLogger().debug("Caught ErosionCancellationException");
} catch (Throwable e) {
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
}
});
}, duration, timeUnit);
}

private void executeRunnable(Runnable runnable) {
try {
runnable.run();
} catch (ErosionCancellationException e) {
geyser.getLogger().debug("Caught ErosionCancellationException");
} catch (Throwable e) {
geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
}
}

/**
* Called every 50 milliseconds - one Minecraft tick.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,8 @@ private static UUID getUUID(NbtMap profile) {
session.getGeyser().getLogger().debug("Custom skull with invalid profile tag: " + blockPosition + " " + javaNbt);
return;
}
if (session.getEventLoop().inEventLoop()) {
putSkull(session, blockPosition, uuid, texturesProperty, blockState);
} else {
session.executeInEventLoop(() -> putSkull(session, blockPosition, uuid, texturesProperty, blockState));
}

session.ensureInEventLoop(() -> putSkull(session, blockPosition, uuid, texturesProperty, blockState));
});

// We don't have the textures yet, so we can't determine if a custom block was defined for this skull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public abstract class PacketTranslator<T> {
/**
* Determines if this packet should be handled in the session's event loop. This should generally be true -
* only when the packet has to be executed immediately should it be false.
* This method is only used for bedrock packets, java packets have a more sophisticated system through MCProtocolLib.
*/
public boolean shouldExecuteInEventLoop() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,8 @@ public void translate(GeyserSession session, EmotePacket packet) {
for (GeyserSession otherSession : session.getGeyser().getSessionManager().getSessions().values()) {
if (otherSession != session) {
if (otherSession.isClosed()) continue;
if (otherSession.getEventLoop().inEventLoop()) {
playEmote(otherSession, javaId, xuid, emote);
} else {
otherSession.executeInEventLoop(() -> playEmote(otherSession, javaId, xuid, emote));
}

otherSession.ensureInEventLoop(() -> playEmote(otherSession, javaId, xuid, emote));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,4 @@ public void translate(GeyserSession session, ClientboundCustomPayloadPacket pack
});
}
}

@Override
public boolean shouldExecuteInEventLoop() {
// For Erosion packets
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,4 @@ public class JavaDisconnectTranslator extends PacketTranslator<ClientboundDiscon
public void translate(GeyserSession session, ClientboundDisconnectPacket packet) {
session.disconnect(MessageTranslator.convertMessage(packet.getReason(), session.locale()));
}

@Override
public boolean shouldExecuteInEventLoop() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,4 @@ public void translate(GeyserSession session, ClientboundKeepAlivePacket packet)
latencyPacket.setTimestamp(timestamp);
session.sendUpstreamPacketImmediately(latencyPacket);
}

@Override
public boolean shouldExecuteInEventLoop() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,4 @@ private boolean testForOutdatedServer(Component disconnectReason) {
private boolean testForMissingProfilePublicKey(Component disconnectReason) {
return disconnectReason instanceof TranslatableComponent component && "multiplayer.disconnect.missing_public_key".equals(component.key());
}

@Override
public boolean shouldExecuteInEventLoop() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,4 @@ public void translate(GeyserSession session, ClientboundSelectKnownPacks packet)
}
session.sendDownstreamPacket(new ServerboundSelectKnownPacks(knownPacks));
}

@Override
public boolean shouldExecuteInEventLoop() {
// This technically isn't correct behavior, but it prevents race conditions between MCProtocolLib's packet handler and ours.
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,4 @@ public void translate(GeyserSession session, ClientboundStartConfigurationPacket
erosionHandler.close();
}
}

@Override
public boolean shouldExecuteInEventLoop() {
// Execute outside of event loop to cancel any pending erosion futures
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundCookieRequestPacket;
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ServerboundCookieResponsePacket;
import org.geysermc.mcprotocollib.protocol.packet.cookie.clientbound.ClientboundCookieRequestPacket;
import org.geysermc.mcprotocollib.protocol.packet.cookie.serverbound.ServerboundCookieResponsePacket;

@Translator(packet = ClientboundCookieRequestPacket.class)
public class JavaCookieRequestTranslator extends PacketTranslator<ClientboundCookieRequestPacket> {
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protocol-codec = "3.0.0.Beta5-20241203.200249-19"
raknet = "1.0.0.CR3-20240416.144209-1"
mcauthlib = "e5b0bcc"
minecraftauth = "4.1.1"
mcprotocollib = "1.21.2-20241107.110329-3"
mcprotocollib = "1.21.2-20241127.160724-5"
adventure = "4.14.0"
adventure-platform = "4.3.0"
junit = "5.9.2"
Expand Down

0 comments on commit 51a4b79

Please sign in to comment.