From 14a590235cbfcc0b707be7fe43570d457915d9ca Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sun, 14 Jun 2026 18:08:50 +0200 Subject: [PATCH] fix(console): install jansi for forced ansi startup --- .../src/main/java/com/eu/habbo/Emulator.java | 41 +++++++++++++------ .../eu/habbo/EmulatorStartupConsoleTest.java | 14 +++++++ 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/Emulator/src/main/java/com/eu/habbo/Emulator.java b/Emulator/src/main/java/com/eu/habbo/Emulator.java index 26f113ce..caa28594 100644 --- a/Emulator/src/main/java/com/eu/habbo/Emulator.java +++ b/Emulator/src/main/java/com/eu/habbo/Emulator.java @@ -19,6 +19,7 @@ import com.eu.habbo.plugin.events.emulator.EmulatorStoppedEvent; import com.eu.habbo.threading.ThreadPooling; import com.eu.habbo.util.imager.badges.BadgeImager; import com.eu.habbo.util.logback.ConsoleStyle; +import org.fusesource.jansi.AnsiConsole; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,14 +111,12 @@ public final class Emulator { public static void main(String[] args) throws Exception { try { - if (OS_NAME.startsWith("Windows") && !CLASS_PATH.contains("idea_rt.jar")) { - ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - ConsoleAppender appender = (ConsoleAppender) root.getAppender("Console"); - - appender.stop(); - appender.setWithJansi(true); - appender.start(); - } + boolean styledConsole = shouldStyleConsole( + System.getenv(), + System.console() != null, + OS_NAME, + System.getProperty("habbo.console.style", "auto")); + configureAnsiConsole(styledConsole); Locale.setDefault(Locale.of("en")); setBuild(); @@ -125,11 +124,7 @@ public final class Emulator { ConsoleCommand.load(); Emulator.logging = new Logging(); - System.out.println(startupHero(shouldStyleConsole( - System.getenv(), - System.console() != null, - OS_NAME, - System.getProperty("habbo.console.style", "auto")))); + System.out.println(startupHero(styledConsole)); long startTime = System.nanoTime(); @@ -372,6 +367,26 @@ public final class Emulator { return ConsoleStyle.isEnabled(environment, interactiveConsole, osName, styleProperty); } + static void configureAnsiConsole(boolean styledConsole) { + if (!styledConsole || !OS_NAME.startsWith("Windows") || CLASS_PATH.contains("idea_rt.jar")) { + return; + } + + try { + AnsiConsole.systemInstall(); + + ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + ConsoleAppender appender = (ConsoleAppender) root.getAppender("Console"); + if (appender != null) { + appender.stop(); + appender.setWithJansi(true); + appender.start(); + } + } catch (Throwable e) { + LOGGER.debug("Unable to install Jansi console bridge; continuing with raw console output.", e); + } + } + private static String fit(String value, int width) { String safe = value == null ? "" : value; if (safe.length() > width) { diff --git a/Emulator/src/test/java/com/eu/habbo/EmulatorStartupConsoleTest.java b/Emulator/src/test/java/com/eu/habbo/EmulatorStartupConsoleTest.java index 3f61b09b..aa496cbe 100644 --- a/Emulator/src/test/java/com/eu/habbo/EmulatorStartupConsoleTest.java +++ b/Emulator/src/test/java/com/eu/habbo/EmulatorStartupConsoleTest.java @@ -3,6 +3,8 @@ package com.eu.habbo; import org.junit.jupiter.api.Test; import java.util.Map; +import java.nio.file.Files; +import java.nio.file.Path; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -55,4 +57,16 @@ class EmulatorStartupConsoleTest { "Windows 11", "plain")); } + + @Test + void windowsAnsiModeInstallsJansiBeforePrintingStartupHero() throws Exception { + String source = Files.readString(Path.of("src/main/java/com/eu/habbo/Emulator.java")); + + assertTrue(source.contains("AnsiConsole.systemInstall()"), + "forced ANSI mode must install the Jansi bridge for Windows CMD/System.out"); + assertTrue(source.contains("configureAnsiConsole(styledConsole)"), + "console bridge must be configured before startupHero is printed"); + assertTrue(source.indexOf("configureAnsiConsole(styledConsole)") < source.indexOf("startupHero(styledConsole)"), + "Jansi must be installed before writing ANSI startup output"); + } }