From f44860077a79d5efbdadb31dbc0b0acafd7adfdb Mon Sep 17 00:00:00 2001 From: TheMeinerLP Date: Sat, 25 Jul 2026 16:02:08 +0200 Subject: [PATCH 1/4] fix(cloudnet): read bind address from service properties and support clean shutdown CloudNet assigns the bind host/port per service via system properties and stops services by writing "stop" to stdin; hardcoded bind addresses and the lack of a stdin listener meant CloudNet could start but never cleanly manage the game/setup services. Co-Authored-By: Claude Sonnet 5 --- .../common/bootstrap/ServiceBootstrap.java | 52 +++++++++++++++++++ .../cygnus/common/bootstrap/StopCommand.java | 21 ++++++++ .../onelitefeather/cygnus/CygnusLoader.java | 4 +- .../cygnus/setup/SetupLoader.java | 4 +- 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java create mode 100644 common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java new file mode 100644 index 00000000..90433c73 --- /dev/null +++ b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java @@ -0,0 +1,52 @@ +package net.onelitefeather.cygnus.common.bootstrap; + +import net.minestom.server.MinecraftServer; +import net.minestom.server.command.CommandManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +/** + * Wires the parts a CloudNet-managed service process needs: reading the bind address CloudNet + * assigns per-service, and reacting to CloudNet's stdin-based stop signal instead of being killed + * after a timeout. + */ +public final class ServiceBootstrap { + + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceBootstrap.class); + private static final String DEFAULT_BIND_HOST = "localhost"; + private static final int DEFAULT_BIND_PORT = 25565; + + private ServiceBootstrap() { + } + + public static String resolveBindHost() { + return System.getProperty("service.bind.host", DEFAULT_BIND_HOST); + } + + public static int resolveBindPort() { + return Integer.getInteger("service.bind.port", DEFAULT_BIND_PORT); + } + + public static void installShutdownHandling() { + MinecraftServer.getCommandManager().register(new StopCommand()); + Thread.ofPlatform().name("cygnus-console-input").daemon().start(ServiceBootstrap::listenForConsoleInput); + } + + private static void listenForConsoleInput() { + CommandManager commandManager = MinecraftServer.getCommandManager(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + if (line.isBlank()) continue; + commandManager.execute(commandManager.getConsoleSender(), line); + } + } catch (IOException e) { + LOGGER.error("Failed to read command from stdin", e); + } + } +} diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java new file mode 100644 index 00000000..8339a9ee --- /dev/null +++ b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java @@ -0,0 +1,21 @@ +package net.onelitefeather.cygnus.common.bootstrap; + +import net.minestom.server.MinecraftServer; +import net.minestom.server.command.builder.Command; +import net.minestom.server.entity.Player; + +/** + * Shuts the service down cleanly. Reserved for non-player senders (the console/CloudNet), since + * a service should not be stoppable by regular players. + */ +public final class StopCommand extends Command { + + public StopCommand() { + super("stop"); + setCondition((sender, commandString) -> !(sender instanceof Player)); + setDefaultExecutor((sender, context) -> Thread.ofPlatform().name("cygnus-shutdown").start(() -> { + MinecraftServer.stopCleanly(); + System.exit(0); + })); + } +} diff --git a/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java b/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java index 09ed8577..dff5fd79 100644 --- a/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java +++ b/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java @@ -4,6 +4,7 @@ import eu.cloudnetservice.driver.inject.InjectionLayer; import eu.cloudnetservice.modules.bridge.impl.platform.minestom.MinestomBridgeExtension; import net.minestom.server.MinecraftServer; +import net.onelitefeather.cygnus.common.bootstrap.ServiceBootstrap; import net.onelitefeather.cygnus.common.dimension.DimensionFactory; public final class CygnusLoader { @@ -18,6 +19,7 @@ static void main() { try (InjectionLayer layer = InjectionLayer.ext()) { layer.instance(MinestomBridgeExtension.class).onLoad(); } - server.start("0.0.0.0", 25565); + ServiceBootstrap.installShutdownHandling(); + server.start(ServiceBootstrap.resolveBindHost(), ServiceBootstrap.resolveBindPort()); } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java index 98c69554..49c4df62 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java @@ -1,6 +1,7 @@ package net.onelitefeather.cygnus.setup; import net.minestom.server.MinecraftServer; +import net.onelitefeather.cygnus.common.bootstrap.ServiceBootstrap; import net.onelitefeather.cygnus.setup.player.SetupPlayerProvider; public class SetupLoader { @@ -9,7 +10,8 @@ static void main() { MinecraftServer minecraftServer = MinecraftServer.init(); new SetupExtension(); MinecraftServer.getConnectionManager().setPlayerProvider(new SetupPlayerProvider()); - minecraftServer.start("localhost", 25565); + ServiceBootstrap.installShutdownHandling(); + minecraftServer.start(ServiceBootstrap.resolveBindHost(), ServiceBootstrap.resolveBindPort()); } private SetupLoader() { From 0010be55fd2a8aa9b6bc2870f1bcac970bb25d5c Mon Sep 17 00:00:00 2001 From: TheMeinerLP Date: Sat, 25 Jul 2026 16:09:01 +0200 Subject: [PATCH 2/4] feat(cloudnet): gate stop command behind LuckPerms permission for players Bootstraps LuckPerms via net.luckperms:minestom-loader in both the game and setup services, so the "stop" command (introduced for CloudNet's stdin-based shutdown) can also be run by a player holding cygnus.command.stop, instead of only console/CloudNet. Co-Authored-By: Claude Sonnet 5 --- .gitignore | 5 ++++- common/build.gradle.kts | 3 +++ .../cygnus/common/bootstrap/StopCommand.java | 15 ++++++++++++--- game/build.gradle.kts | 16 ++++++++++++++++ .../net/onelitefeather/cygnus/CygnusLoader.java | 2 ++ settings.gradle.kts | 6 ++++++ setup/build.gradle.kts | 16 ++++++++++++++++ .../onelitefeather/cygnus/setup/SetupLoader.java | 2 ++ 8 files changed, 61 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 1b71ca16..3094f55d 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,7 @@ bin/ # OS-spezifisch .DS_Store -Thumbs.db \ No newline at end of file +Thumbs.db + +# LuckPerms (runtime-generated: config, H2 database, relocated libs) +data/ \ No newline at end of file diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 2b1ea844..091dfdca 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -10,6 +10,9 @@ dependencies { compileOnly(libs.minestom) compileOnly(libs.aves) compileOnly(libs.xerus) + compileOnly(libs.luckperms.api) { + exclude(group = "net.kyori.adventure") + } testImplementation(libs.minestom) testImplementation(libs.cyano) diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java index 8339a9ee..eda37365 100644 --- a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java +++ b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java @@ -1,21 +1,30 @@ package net.onelitefeather.cygnus.common.bootstrap; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; import net.minestom.server.MinecraftServer; import net.minestom.server.command.builder.Command; import net.minestom.server.entity.Player; /** - * Shuts the service down cleanly. Reserved for non-player senders (the console/CloudNet), since - * a service should not be stoppable by regular players. + * Shuts the service down cleanly. Reserved for non-player senders (the console/CloudNet) and + * players holding {@value #PERMISSION}, since a service should not be stoppable by regular players. */ public final class StopCommand extends Command { + private static final String PERMISSION = "cygnus.command.stop"; + public StopCommand() { super("stop"); - setCondition((sender, commandString) -> !(sender instanceof Player)); + setCondition((sender, commandString) -> !(sender instanceof Player player) || hasStopPermission(player)); setDefaultExecutor((sender, context) -> Thread.ofPlatform().name("cygnus-shutdown").start(() -> { MinecraftServer.stopCleanly(); System.exit(0); })); } + + private static boolean hasStopPermission(Player player) { + User user = LuckPermsProvider.get().getUserManager().getUser(player.getUuid()); + return user != null && user.getCachedData().getPermissionData().checkPermission(PERMISSION).asBoolean(); + } } diff --git a/game/build.gradle.kts b/game/build.gradle.kts index 3fcaa869..30ab3cdb 100644 --- a/game/build.gradle.kts +++ b/game/build.gradle.kts @@ -21,6 +21,18 @@ dependencies { implementation(platform(libs.cloudnet.bom)) implementation(libs.bundles.cloudnet) + //LuckPerms + implementation(libs.guava) + compileOnly(libs.luckperms.api) { + exclude(group = "net.kyori.adventure") + } + compileOnly(libs.luckperms.minestom.loader) { + exclude(group = "net.kyori.adventure") + } + runtimeOnly(libs.luckperms.minestom.loader) { + exclude(group = "net.kyori.adventure") + } + testImplementation(libs.minestom) testImplementation(libs.adventure) testImplementation(libs.cyano) @@ -32,6 +44,10 @@ dependencies { testRuntimeOnly(libs.junit.engine) } +configurations.testRuntimeClasspath { + exclude(group = "net.luckperms", module = "minestom-loader") +} + tasks { jar { archiveClassifier.set("unshaded") diff --git a/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java b/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java index dff5fd79..d41f20cf 100644 --- a/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java +++ b/game/src/main/java/net/onelitefeather/cygnus/CygnusLoader.java @@ -3,6 +3,7 @@ import dev.derklaro.aerogel.Injector; import eu.cloudnetservice.driver.inject.InjectionLayer; import eu.cloudnetservice.modules.bridge.impl.platform.minestom.MinestomBridgeExtension; +import me.lucko.luckperms.minestom.loader.MinestomLoader; import net.minestom.server.MinecraftServer; import net.onelitefeather.cygnus.common.bootstrap.ServiceBootstrap; import net.onelitefeather.cygnus.common.dimension.DimensionFactory; @@ -11,6 +12,7 @@ public final class CygnusLoader { static void main() { MinecraftServer server = MinecraftServer.init(); + MinestomLoader.get().load().registerShutdownHook().start(); String customDimensions = System.getProperty("cygnus.customDimension", "false"); if (Boolean.parseBoolean(customDimensions)) { DimensionFactory.registerAll(); diff --git a/settings.gradle.kts b/settings.gradle.kts index f899c566..59b7ce23 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,9 +29,15 @@ dependencyResolutionManagement { version("cyclonedx", "3.3.0") version("pica", "0.1.1") version("slf4j", "2.0.18") + version("luckperms", "5.5") + version("luckperms-minestom-loader", "5.6-SNAPSHOT") + version("guava", "33.6.0-jre") library("aonyx.bom", "net.onelitefeather", "aonyx-bom").versionRef("aonyx") library("slf4j.api", "org.slf4j", "slf4j-api").versionRef("slf4j") + library("guava", "com.google.guava", "guava").versionRef("guava") + library("luckperms.api", "net.luckperms", "api").versionRef("luckperms") + library("luckperms.minestom.loader", "net.luckperms", "minestom-loader").versionRef("luckperms-minestom-loader") library("minestom", "net.minestom", "minestom").withoutVersion() library("adventure", "net.kyori", "adventure-text-minimessage").withoutVersion() diff --git a/setup/build.gradle.kts b/setup/build.gradle.kts index 98543d89..b2a6649f 100644 --- a/setup/build.gradle.kts +++ b/setup/build.gradle.kts @@ -20,6 +20,18 @@ dependencies { implementation(libs.pica) implementation(libs.guira) + //LuckPerms + implementation(libs.guava) + compileOnly(libs.luckperms.api) { + exclude(group = "net.kyori.adventure") + } + compileOnly(libs.luckperms.minestom.loader) { + exclude(group = "net.kyori.adventure") + } + runtimeOnly(libs.luckperms.minestom.loader) { + exclude(group = "net.kyori.adventure") + } + testImplementation(libs.minestom) testImplementation(libs.cyano) testImplementation(libs.xerus) @@ -29,6 +41,10 @@ dependencies { testImplementation(libs.junit.platform.launcher) testRuntimeOnly(libs.junit.engine) } + +configurations.testRuntimeClasspath { + exclude(group = "net.luckperms", module = "minestom-loader") +} tasks { jar { archiveClassifier.set("unshaded") diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java index 49c4df62..a606681b 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupLoader.java @@ -1,5 +1,6 @@ package net.onelitefeather.cygnus.setup; +import me.lucko.luckperms.minestom.loader.MinestomLoader; import net.minestom.server.MinecraftServer; import net.onelitefeather.cygnus.common.bootstrap.ServiceBootstrap; import net.onelitefeather.cygnus.setup.player.SetupPlayerProvider; @@ -8,6 +9,7 @@ public class SetupLoader { static void main() { MinecraftServer minecraftServer = MinecraftServer.init(); + MinestomLoader.get().load().registerShutdownHook().start(); new SetupExtension(); MinecraftServer.getConnectionManager().setPlayerProvider(new SetupPlayerProvider()); ServiceBootstrap.installShutdownHandling(); From 54a5e7607feb62b55abe768afcd07003cd97f7ea Mon Sep 17 00:00:00 2001 From: TheMeinerLP Date: Sat, 25 Jul 2026 16:27:30 +0200 Subject: [PATCH 3/4] docs(cloudnet): add javadoc and tests for ServiceBootstrap/StopCommand Adds @author/@version/@since headers and method-level javadoc matching the project convention, plus unit tests for bind-address resolution and the stop command's console/non-player condition. Co-Authored-By: Claude Sonnet 5 --- .../common/bootstrap/ServiceBootstrap.java | 28 +++++++++++++- .../cygnus/common/bootstrap/StopCommand.java | 19 +++++++++- .../bootstrap/ServiceBootstrapTest.java | 37 +++++++++++++++++++ .../common/bootstrap/StopCommandTest.java | 29 +++++++++++++++ 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java create mode 100644 common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/StopCommandTest.java diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java index 90433c73..a7747327 100644 --- a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java +++ b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrap.java @@ -14,7 +14,11 @@ * Wires the parts a CloudNet-managed service process needs: reading the bind address CloudNet * assigns per-service, and reacting to CloudNet's stdin-based stop signal instead of being killed * after a timeout. - */ + * + * @author TheMeinerLP + * @version 1.0.0 + * @since 2.6.7 + **/ public final class ServiceBootstrap { private static final Logger LOGGER = LoggerFactory.getLogger(ServiceBootstrap.class); @@ -24,19 +28,41 @@ public final class ServiceBootstrap { private ServiceBootstrap() { } + /** + * Resolves the host to bind the server to. + * + * @return the value of the {@code service.bind.host} system property CloudNet assigns per + * service, or {@value #DEFAULT_BIND_HOST} for standalone (non-CloudNet) runs + */ public static String resolveBindHost() { return System.getProperty("service.bind.host", DEFAULT_BIND_HOST); } + /** + * Resolves the port to bind the server to. + * + * @return the value of the {@code service.bind.port} system property CloudNet assigns per + * service, or {@value #DEFAULT_BIND_PORT} for standalone (non-CloudNet) runs + */ public static int resolveBindPort() { return Integer.getInteger("service.bind.port", DEFAULT_BIND_PORT); } + /** + * Registers the {@link StopCommand} and starts a daemon thread reading commands from stdin, + * so CloudNet can stop the service cleanly instead of killing it after a timeout. Should be + * called once during startup, before the server starts accepting connections. + */ public static void installShutdownHandling() { MinecraftServer.getCommandManager().register(new StopCommand()); Thread.ofPlatform().name("cygnus-console-input").daemon().start(ServiceBootstrap::listenForConsoleInput); } + /** + * Reads lines from {@link System#in} until the stream closes and executes each one as a + * console command. This is what lets CloudNet's stdin-based {@code stop} signal reach the + * {@link StopCommand}. + */ private static void listenForConsoleInput() { CommandManager commandManager = MinecraftServer.getCommandManager(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8))) { diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java index eda37365..bd80f76c 100644 --- a/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java +++ b/common/src/main/java/net/onelitefeather/cygnus/common/bootstrap/StopCommand.java @@ -9,11 +9,18 @@ /** * Shuts the service down cleanly. Reserved for non-player senders (the console/CloudNet) and * players holding {@value #PERMISSION}, since a service should not be stoppable by regular players. - */ + * + * @author TheMeinerLP + * @version 1.0.0 + * @since 2.6.7 + **/ public final class StopCommand extends Command { private static final String PERMISSION = "cygnus.command.stop"; + /** + * Creates a new instance of the {@link StopCommand} and wires its condition and executor. + */ public StopCommand() { super("stop"); setCondition((sender, commandString) -> !(sender instanceof Player player) || hasStopPermission(player)); @@ -23,6 +30,16 @@ public StopCommand() { })); } + /** + * Checks whether the given player is allowed to run this command via LuckPerms. + *

+ * Assumes LuckPerms has already been bootstrapped (see {@code MinestomLoader}), which is + * guaranteed by the time a player can connect and send commands. + * + * @param player the player to check + * @return {@code true} if the player holds {@value #PERMISSION}, {@code false} otherwise + * (including when LuckPerms has no cached data for the player yet) + */ private static boolean hasStopPermission(Player player) { User user = LuckPermsProvider.get().getUserManager().getUser(player.getUuid()); return user != null && user.getCachedData().getPermissionData().checkPermission(PERMISSION).asBoolean(); diff --git a/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java b/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java new file mode 100644 index 00000000..5fa140c6 --- /dev/null +++ b/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java @@ -0,0 +1,37 @@ +package net.onelitefeather.cygnus.common.bootstrap; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ServiceBootstrapTest { + + @AfterEach + void clearSystemProperties() { + System.clearProperty("service.bind.host"); + System.clearProperty("service.bind.port"); + } + + @Test + void testDefaultBindHost() { + assertEquals("localhost", ServiceBootstrap.resolveBindHost()); + } + + @Test + void testDefaultBindPort() { + assertEquals(25565, ServiceBootstrap.resolveBindPort()); + } + + @Test + void testBindHostFromSystemProperty() { + System.setProperty("service.bind.host", "0.0.0.0"); + assertEquals("0.0.0.0", ServiceBootstrap.resolveBindHost()); + } + + @Test + void testBindPortFromSystemProperty() { + System.setProperty("service.bind.port", "30000"); + assertEquals(30000, ServiceBootstrap.resolveBindPort()); + } +} diff --git a/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/StopCommandTest.java b/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/StopCommandTest.java new file mode 100644 index 00000000..3abbe9e3 --- /dev/null +++ b/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/StopCommandTest.java @@ -0,0 +1,29 @@ +package net.onelitefeather.cygnus.common.bootstrap; + +import net.minestom.server.command.CommandSender; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(MicrotusExtension.class) +class StopCommandTest { + + @Test + void testCommandName() { + StopCommand command = new StopCommand(); + assertEquals("stop", command.getName()); + } + + @Test + void testConsoleSenderIsAlwaysAllowed(@NotNull Env env) { + StopCommand command = new StopCommand(); + CommandSender consoleSender = env.process().command().getConsoleSender(); + + assertTrue(command.getCondition().canUse(consoleSender, "stop")); + } +} From 0c50be47d19faa16ff51d56f9bc7d716d041f688 Mon Sep 17 00:00:00 2001 From: TheMeinerLP Date: Sat, 25 Jul 2026 16:34:25 +0200 Subject: [PATCH 4/4] test(cloudnet): guard default bind-address tests with @DisabledIfSystemProperty Skips the default-value assertions instead of failing them if service.bind.host/service.bind.port happen to already be set externally (e.g. the JVM actually running under CloudNet), per JUnit5's system-property conditional execution. Co-Authored-By: Claude Sonnet 5 --- .../cygnus/common/bootstrap/ServiceBootstrapTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java b/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java index 5fa140c6..c530a36a 100644 --- a/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java +++ b/common/src/test/java/net/onelitefeather/cygnus/common/bootstrap/ServiceBootstrapTest.java @@ -2,6 +2,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -14,11 +15,13 @@ void clearSystemProperties() { } @Test + @DisabledIfSystemProperty(named = "service.bind.host", matches = ".+") void testDefaultBindHost() { assertEquals("localhost", ServiceBootstrap.resolveBindHost()); } @Test + @DisabledIfSystemProperty(named = "service.bind.port", matches = ".+") void testDefaultBindPort() { assertEquals(25565, ServiceBootstrap.resolveBindPort()); }