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 d008b98ab..84bb63b95 100644 --- a/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java +++ b/connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java @@ -161,7 +161,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler { @Override public boolean handle(ModalFormResponsePacket packet) { - session.getEventLoop().execute(() -> session.getFormCache().handleResponse(packet)); + session.executeInEventLoop(() -> session.getFormCache().handleResponse(packet)); 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 6bd3fca90..a77d370c5 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 @@ -115,6 +115,7 @@ public class GeyserSession implements CommandSender { private final UpstreamSession upstream; /** * 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 TcpClientSession downstream; @@ -804,9 +805,8 @@ public class GeyserSession implements CommandSender { @Override public void packetReceived(PacketReceivedEvent event) { - if (!closed) { - PacketTranslatorRegistry.JAVA_TRANSLATOR.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this); - } + Packet packet = event.getPacket(); + PacketTranslatorRegistry.JAVA_TRANSLATOR.translate(packet.getClass(), packet, GeyserSession.this); } @Override @@ -874,6 +874,32 @@ public class GeyserSession implements CommandSender { disconnect(LanguageUtils.getPlayerLocaleString("geyser.network.close", getClientData().getLanguageCode())); } + /** + * Executes a task and prints a stack trace if an error occurs. + */ + public void executeInEventLoop(Runnable runnable) { + eventLoop.execute(() -> { + try { + runnable.run(); + } catch (Throwable e) { + e.printStackTrace(); + } + }); + } + + /** + * Schedules a task and prints a stack trace if an error occurs. + */ + public ScheduledFuture scheduleInEventLoop(Runnable runnable, long duration, TimeUnit timeUnit) { + return eventLoop.schedule(() -> { + try { + runnable.run(); + } catch (Throwable e) { + e.printStackTrace(); + } + }, duration, timeUnit); + } + /** * Called every 50 milliseconds - one Minecraft tick. */ diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java index c486c2521..a04773dbf 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/PacketTranslatorRegistry.java @@ -87,27 +87,31 @@ public class PacketTranslatorRegistry { @SuppressWarnings("unchecked") public

boolean translate(Class clazz, P packet, GeyserSession session) { if (!session.getUpstream().isClosed() && !session.isClosed()) { - try { - PacketTranslator

translator = (PacketTranslator

) translators.get(clazz); - if (translator != null) { - EventLoop eventLoop = session.getEventLoop(); - if (eventLoop.inEventLoop()) { - translator.translate(packet, session); - } else { - eventLoop.execute(() -> translator.translate(packet, session)); - } - return true; + PacketTranslator

translator = (PacketTranslator

) translators.get(clazz); + if (translator != null) { + EventLoop eventLoop = session.getEventLoop(); + if (eventLoop.inEventLoop()) { + translate0(session, translator, packet); } else { - if ((GeyserConnector.getInstance().getPlatformType() != PlatformType.STANDALONE || !(packet instanceof BedrockPacket)) && !IGNORED_PACKETS.contains(clazz)) { - // Other debug logs already take care of Bedrock packets for us if on standalone - GeyserConnector.getInstance().getLogger().debug("Could not find packet for " + (packet.toString().length() > 25 ? packet.getClass().getSimpleName() : packet)); - } + eventLoop.execute(() -> translate0(session, translator, packet)); + } + return true; + } else { + if ((GeyserConnector.getInstance().getPlatformType() != PlatformType.STANDALONE || !(packet instanceof BedrockPacket)) && !IGNORED_PACKETS.contains(clazz)) { + // Other debug logs already take care of Bedrock packets for us if on standalone + GeyserConnector.getInstance().getLogger().debug("Could not find packet for " + (packet.toString().length() > 25 ? packet.getClass().getSimpleName() : packet)); } - } catch (Throwable ex) { - GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex); - ex.printStackTrace(); } } return false; } + + private

void translate0(GeyserSession session, PacketTranslator

translator, P packet) { + try { + translator.translate(packet, session); + } catch (Throwable ex) { + GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.network.translator.packet.failed", packet.getClass().getSimpleName()), ex); + ex.printStackTrace(); + } + } } 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 index 0bae5261c..4d915b619 100644 --- 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 @@ -48,7 +48,7 @@ public class BedrockAnimateTranslator extends PacketTranslator { switch (packet.getAction()) { case SWING_ARM: // Delay so entity damage can be processed first - session.getEventLoop().schedule(() -> + session.scheduleInEventLoop(() -> session.sendDownstreamPacket(new ClientPlayerSwingArmPacket(Hand.MAIN_HAND)), 25, TimeUnit.MILLISECONDS 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 f901e128c..72cbdbd52 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 @@ -220,7 +220,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator { + session.setBucketScheduledFuture(session.scheduleInEventLoop(() -> { ClientPlayerUseItemPacket itemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); session.sendDownstreamPacket(itemPacket); }, 5, TimeUnit.MILLISECONDS)); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/BedrockEntityEventTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/BedrockEntityEventTranslator.java index ced40ca28..e5c2590da 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/BedrockEntityEventTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/entity/BedrockEntityEventTranslator.java @@ -53,7 +53,7 @@ public class BedrockEntityEventTranslator extends PacketTranslator { + session.scheduleInEventLoop(() -> { Entity villager = session.getPlayerEntity(); Inventory openInventory = session.getOpenInventory(); if (openInventory instanceof MerchantContainer) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java index 0d1f6f8d2..68fc2df39 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/window/JavaSetSlotTranslator.java @@ -78,7 +78,7 @@ public class JavaSetSlotTranslator extends PacketTranslator if (session.getCraftingGridFuture() != null) { session.getCraftingGridFuture().cancel(false); } - session.setCraftingGridFuture(session.getEventLoop().schedule(() -> updateCraftingGrid(session, packet, inventory, translator), 150, TimeUnit.MILLISECONDS)); + session.setCraftingGridFuture(session.scheduleInEventLoop(() -> updateCraftingGrid(session, packet, inventory, translator), 150, TimeUnit.MILLISECONDS)); GeyserItemStack newItem = GeyserItemStack.from(packet.getItem()); if (packet.getWindowId() == 0 && !(translator instanceof PlayerInventoryTranslator)) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java index 72dee2d94..491f54381 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SkullBlockEntityTranslator.java @@ -147,7 +147,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements if (session.getUpstream().isInitialized()) { player.spawnEntity(session); - SkullSkinManager.requestAndHandleSkin(player, session, (skin -> session.getEventLoop().schedule(() -> { + SkullSkinManager.requestAndHandleSkin(player, session, (skin -> session.scheduleInEventLoop(() -> { // Delay to minimize split-second "player" pop-in player.getMetadata().getFlags().setFlag(EntityFlag.INVISIBLE, false); player.updateBedrockMetadata(session); diff --git a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java index 2f4f2456e..d5978a7f5 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/InventoryUtils.java @@ -79,7 +79,7 @@ public class InventoryUtils { if (translator != null) { translator.prepareInventory(session, inventory); if (translator instanceof DoubleChestInventoryTranslator && !((Container) inventory).isUsingRealBlock()) { - session.getEventLoop().schedule(() -> { + session.scheduleInEventLoop(() -> { Inventory openInv = session.getOpenInventory(); if (openInv != null && openInv.getId() == inventory.getId()) { translator.openInventory(session, inventory);