From 3408250fc1765896d6186e62183387db2997147f Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:11:31 +0100 Subject: [PATCH 1/4] Fix missing console logs with gui present --- bootstrap/standalone/build.gradle.kts | 2 + .../standalone/GeyserStandaloneBootstrap.java | 27 ++----- .../standalone/gui/GeyserStandaloneGUI.java | 77 ++++++++++++------- .../standalone/src/main/resources/log4j2.xml | 4 - 4 files changed, 58 insertions(+), 52 deletions(-) diff --git a/bootstrap/standalone/build.gradle.kts b/bootstrap/standalone/build.gradle.kts index e794c266c5d..5a13056eb4e 100644 --- a/bootstrap/standalone/build.gradle.kts +++ b/bootstrap/standalone/build.gradle.kts @@ -40,4 +40,6 @@ tasks.named("run") { dir.mkdirs() jvmArgs("-Dio.netty.leakDetection.level=PARANOID") workingDir = dir + + standardInput = System.`in` } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java index 87fbbf0aad5..f997f137594 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java @@ -32,12 +32,9 @@ import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition; import io.netty.util.ResourceLeakDetector; import lombok.Getter; -import net.minecrell.terminalconsole.TerminalConsoleAppender; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.Logger; -import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserImpl; @@ -175,17 +172,10 @@ public static void main(String[] args) { @Override public void onGeyserInitialize() { log4jLogger = (Logger) LogManager.getRootLogger(); - for (Appender appender : log4jLogger.getAppenders().values()) { - // Remove the appender that is not in use - // Prevents multiple appenders/double logging and removes harmless errors - if ((useGui && appender instanceof TerminalConsoleAppender) || (!useGui && appender instanceof ConsoleAppender)) { - log4jLogger.removeAppender(appender); - } - } if (useGui && gui == null) { gui = new GeyserStandaloneGUI(geyserLogger); - gui.redirectSystemStreams(); + gui.addGuiAppender(); gui.startUpdateThread(); } @@ -198,7 +188,7 @@ public void onGeyserInitialize() { public void onGeyserEnable() { try { File configFile = FileUtils.fileOrCopiedFromResource(new File(configFilename), "config.yml", - (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this); + (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this); geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class); handleArgsConfigOptions(); @@ -246,9 +236,7 @@ public void onGeyserEnable() { geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser); - if (!useGui) { - geyserLogger.start(); // Throws an error otherwise - } + geyserLogger.start(); } /** @@ -261,7 +249,8 @@ private boolean isHeadless() { Class graphicsEnv = Class.forName("java.awt.GraphicsEnvironment"); Method isHeadless = graphicsEnv.getDeclaredMethod("isHeadless"); return (boolean) isHeadless.invoke(null); - } catch (Exception ignore) { } + } catch (Exception ignore) { + } return true; } @@ -347,12 +336,12 @@ public static List getPOJOForClass(Class clazz) { // Get the ignored properties Set ignoredProperties = OBJECT_MAPPER.getSerializationConfig().getAnnotationIntrospector() - .findPropertyIgnoralByName(OBJECT_MAPPER.getSerializationConfig() ,beanDescription.getClassInfo()).getIgnored(); + .findPropertyIgnoralByName(OBJECT_MAPPER.getSerializationConfig(), beanDescription.getClassInfo()).getIgnored(); // Filter properties removing the ignored ones return properties.stream() - .filter(property -> !ignoredProperties.contains(property.getName())) - .collect(Collectors.toList()); + .filter(property -> !ignoredProperties.contains(property.getName())) + .collect(Collectors.toList()); } /** diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java index 4cbd178af77..b1acb585b04 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java @@ -25,7 +25,14 @@ package org.geysermc.geyser.platform.standalone.gui; -import org.checkerframework.checker.nullness.qual.NonNull; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.Logger; +import org.apache.logging.log4j.core.appender.AbstractAppender; +import org.apache.logging.log4j.core.config.NullConfiguration; +import org.apache.logging.log4j.core.config.Property; +import org.apache.logging.log4j.core.layout.PatternLayout; +import org.apache.logging.log4j.core.pattern.PatternFormatter; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.command.CommandRegistry; @@ -36,11 +43,16 @@ import javax.swing.table.DefaultTableModel; import javax.swing.text.Document; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -83,7 +95,8 @@ public GeyserStandaloneGUI(GeyserLogger logger) { // Remove Java UI look try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception ignored) { } + } catch (Exception ignored) { + } // Show a confirm dialog on close frame.addWindowListener(new WindowAdapter() { @@ -181,7 +194,8 @@ private void setupMenuBar(JFrame frame) { openButton.addActionListener(e -> { try { Desktop.getDesktop().open(new File("./")); - } catch (IOException ignored) { } + } catch (IOException ignored) { + } }); fileMenu.add(openButton); @@ -245,29 +259,8 @@ private void appendConsole(final String text) { /** * Redirect the default io streams to the text pane */ - public void redirectSystemStreams() { - // Setup a new output stream to forward it to the text pane - OutputStream out = new OutputStream() { - @Override - public void write(final int b) { - appendConsole(String.valueOf((char) b)); - } - - @Override - public void write(byte @NonNull [] b, int off, int len) { - appendConsole(new String(b, off, len)); - } - - @Override - public void write(byte @NonNull[] b) { - write(b, 0, b.length); - } - }; - - // Override the system output streams - System.setOut(new PrintStream(out, true)); - System.setErr(new PrintStream(out, true)); - + public void addGuiAppender() { + new GUIAppender().start(); } /** @@ -354,4 +347,30 @@ public void actionPerformed(ActionEvent e) { commandInput.setText(""); // clear the input } } + + private class GUIAppender extends AbstractAppender { + private static final List FORMATTERS = PatternLayout.createPatternParser(new NullConfiguration()) + .parse( + "[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n", + true, + false, + false + ); + + protected GUIAppender() { + super("GUIAppender", null, null, false, Property.EMPTY_ARRAY); + + ((Logger) LogManager.getRootLogger()).addAppender(this); + } + + @Override + public void append(LogEvent event) { + StringBuilder formatted = new StringBuilder(); + for (PatternFormatter formatter : FORMATTERS) { + formatter.format(event, formatted); + } + + appendConsole(formatted.toString()); + } + } } diff --git a/bootstrap/standalone/src/main/resources/log4j2.xml b/bootstrap/standalone/src/main/resources/log4j2.xml index bf361a851de..0304e192454 100644 --- a/bootstrap/standalone/src/main/resources/log4j2.xml +++ b/bootstrap/standalone/src/main/resources/log4j2.xml @@ -4,9 +4,6 @@ - - - @@ -18,7 +15,6 @@ - From 43f8bac08050e00932d8c1af4e91788276ca2216 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:27:30 +0100 Subject: [PATCH 2/4] Properly redirect stdout & stderr & also redirect JUL --- .../standalone/GeyserStandaloneBootstrap.java | 3 +++ .../platform/standalone/GeyserStandaloneLogger.java | 12 ++++++++++++ gradle/libs.versions.toml | 4 +++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java index f997f137594..5bdb206db7b 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java @@ -89,6 +89,9 @@ public static void main(String[] args) { ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); // Can eat performance } + System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager"); + GeyserStandaloneLogger.setupStreams(); + GeyserStandaloneBootstrap bootstrap = new GeyserStandaloneBootstrap(); // Set defaults boolean useGuiOpts = bootstrap.useGui; diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java index b614a7b2375..9c744f01576 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneLogger.java @@ -28,7 +28,10 @@ import lombok.extern.slf4j.Slf4j; import net.minecrell.terminalconsole.SimpleTerminalConsole; import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.config.Configurator; +import org.apache.logging.log4j.io.IoBuilder; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.command.GeyserCommandSource; @@ -39,6 +42,15 @@ @Slf4j public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger, GeyserCommandSource { + private static final Logger logger = LogManager.getLogger("GeyserConsole"); + + /** + * Sets up {@code System.out} and {@code System.err} to redirect to log4j. + */ + public static void setupStreams() { + System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream()); + System.setErr(IoBuilder.forLogger(logger).setLevel(Level.ERROR).buildPrintStream()); + } @Override protected LineReader buildReader(LineReaderBuilder builder) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ae35c6e34a2..f7a8d2824ba 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -91,6 +91,8 @@ netty-transport-native-io_uring = { group = "io.netty.incubator", name = "netty- log4j-api = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" } log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" } log4j-slf4j2-impl = { group = "org.apache.logging.log4j", name = "log4j-slf4j2-impl", version.ref = "log4j" } +log4j-iostreams = { group = "org.apache.logging.log4j", name = "log4j-iostreams", version.ref = "log4j" } +log4j-jul = { group = "org.apache.logging.log4j", name = "log4j-jul", version.ref = "log4j" } jline-terminal = { group = "org.jline", name = "jline-terminal", version.ref = "jline" } jline-terminal-jna = { group = "org.jline", name = "jline-terminal-jna", version.ref = "jline" } @@ -160,6 +162,6 @@ runpaper = { id = "xyz.jpenilla.run-paper", version.ref = "runtask" } jackson = [ "jackson-annotations", "jackson-databind", "jackson-dataformat-yaml" ] fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ] adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ] -log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ] +log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl", "log4j-iostreams", "log4j-jul" ] jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ] protocol = [ "protocol-common", "protocol-codec", "protocol-connection" ] From 2078445bc9fd65d8313f01c87e0f0fb805011154 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Fri, 28 Feb 2025 12:57:23 +0100 Subject: [PATCH 3/4] Implement changes --- .../src/main/kotlin/geyser.base-conventions.gradle.kts | 2 +- .../java/org/geysermc/geyser/network/netty/LocalSession.java | 3 ++- .../org/geysermc/geyser/session/GeyserSessionAdapter.java | 5 ++--- gradle/libs.versions.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts index 093f0a8c098..09f52b422d6 100644 --- a/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/geyser.base-conventions.gradle.kts @@ -26,7 +26,7 @@ dependencies { } repositories { - // mavenLocal() + mavenLocal() mavenCentral() diff --git a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java index 0f6e6b5bcd6..620a693a2c5 100644 --- a/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java +++ b/core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java @@ -41,6 +41,7 @@ import org.geysermc.mcprotocollib.network.netty.MinecraftChannelInitializer; import org.geysermc.mcprotocollib.network.packet.PacketProtocol; import org.geysermc.mcprotocollib.network.session.ClientNetworkSession; +import org.geysermc.mcprotocollib.protocol.MinecraftProtocol; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -56,7 +57,7 @@ public final class LocalSession extends ClientNetworkSession { private final SocketAddress spoofedRemoteAddress; - public LocalSession(SocketAddress targetAddress, String clientIp, PacketProtocol protocol, Executor packetHandlerExecutor) { + public LocalSession(SocketAddress targetAddress, String clientIp, MinecraftProtocol protocol, Executor packetHandlerExecutor) { super(targetAddress, protocol, packetHandlerExecutor, null, null); this.spoofedRemoteAddress = new InetSocketAddress(clientIp, 0); } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java index 81245664495..830c4c6d67d 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java @@ -68,7 +68,7 @@ public GeyserSessionAdapter(GeyserSession session) { @Override public void packetSending(PacketSendingEvent event) { - if (event.getPacket() instanceof ClientIntentionPacket) { + if (event.getPacket() instanceof ClientIntentionPacket intentionPacket) { BedrockClientData clientData = geyserSession.getClientData(); String addressSuffix; @@ -109,8 +109,6 @@ public void packetSending(PacketSendingEvent event) { addressSuffix = ""; } - ClientIntentionPacket intentionPacket = event.getPacket(); - String address; if (geyser.getConfig().getRemote().isForwardHost()) { address = clientData.getServerAddress().split(":")[0]; @@ -226,6 +224,7 @@ public void disconnected(DisconnectedEvent event) { @Override public void packetReceived(Session session, Packet packet) { + System.out.println("Received packet: " + packet.getClass().getSimpleName()); Registries.JAVA_PACKET_TRANSLATORS.translate(packet.getClass(), packet, geyserSession, true); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f7a8d2824ba..42b67c1b20a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ protocol-common = "3.0.0.Beta6-20250212.131009-3" protocol-codec = "3.0.0.Beta6-20250212.131009-3" raknet = "1.0.0.CR3-20250218.160705-18" minecraftauth = "4.1.1" -mcprotocollib = "1.21.4-20250218.175633-22" +mcprotocollib = "1.21.4-LOLOLOLOL" adventure = "4.14.0" adventure-platform = "4.3.0" junit = "5.9.2" From 7be70687707c9b1e828d26e36bc7018fa669c4b7 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Sun, 2 Mar 2025 18:38:09 +0100 Subject: [PATCH 4/4] Remove debug log --- .../java/org/geysermc/geyser/session/GeyserSessionAdapter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java index 830c4c6d67d..363635ba6c0 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSessionAdapter.java @@ -224,7 +224,6 @@ public void disconnected(DisconnectedEvent event) { @Override public void packetReceived(Session session, Packet packet) { - System.out.println("Received packet: " + packet.getClass().getSimpleName()); Registries.JAVA_PACKET_TRANSLATORS.translate(packet.getClass(), packet, geyserSession, true); }