diff --git a/logic.gradle b/logic.gradle index d00218d..c7a68fc 100644 --- a/logic.gradle +++ b/logic.gradle @@ -38,8 +38,6 @@ dependencies { testImplementation libs.test.junit5.api testImplementation libs.test.junit5.params testRuntimeOnly libs.test.junit5.engine - - testRuntimeOnly libs.test.logger } test { diff --git a/server-new/build.gradle b/server-new/build.gradle index 7c1af0e..62650da 100644 --- a/server-new/build.gradle +++ b/server-new/build.gradle @@ -23,8 +23,9 @@ application { } dependencies { - implementation project(':protocol-new') + implementation project(':cli-parser') + implementation libs.logger.logback implementation libs.hocon } diff --git a/server-new/src/main/java/mc/server/Main.java b/server-new/src/main/java/mc/server/Main.java new file mode 100644 index 0000000..8374a3e --- /dev/null +++ b/server-new/src/main/java/mc/server/Main.java @@ -0,0 +1,97 @@ +package mc.server; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.joran.spi.JoranException; +import com.typesafe.config.Config; +import lombok.SneakyThrows; +import mc.cliparser.CommandLine; +import mc.cliparser.CommandLineParser; +import mc.cliparser.Option; +import mc.server.di.ConfigComponent; +import mc.server.di.ConfigModule; +import mc.server.di.DaggerConfigComponent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nonnull; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; + +public class Main { + + public static void main(String[] args) throws IOException { + //region Setup CommandLine + Option logconfigOption = Option.builder().longName("logconfig").hasArgs(true).build(); + Option configOption = Option.builder().longName("config").hasArgs(true).build(); + var cliParser = new CommandLineParser(); + cliParser.addOption(logconfigOption); + cliParser.addOption(configOption); + + CommandLine commandLine = cliParser.parse(args); + //endregion + + //region Configuration Logback + Path logconfigPath; + if (commandLine.has(logconfigOption)) { + logconfigPath = Paths.get(logconfigOption.value()); + } else { + logconfigPath = defaultLogbackConfigPath(); + } + reconfigureLogback(logconfigPath); + //endregion + + //region Setup config + ConfigModule configModule = new ConfigModule("./config-default.conf", + commandLine.has(configOption) ? Paths.get(configOption.value()) : null); + ConfigComponent configComponent = DaggerConfigComponent.builder() + .configModule(configModule).build(); + Config config = configComponent.getConfig(); + //endregion + + Logger log = LoggerFactory.getLogger("LAUNCHER"); + if (log.isDebugEnabled()) { + log.debug("Logback config path: {}", logconfigOption.value() == null ? "(default)" : logconfigOption.value()); + log.debug("Config path: {}", configOption.value() == null ? "(default)" : configOption.value()); + + config.entrySet().stream() + .map(entry -> String.format("[CONFIG] %s = %s", entry.getKey(), entry.getValue().render())) + .sorted() + .forEach(log::debug); + } + } + + /** + * Перенастраиваем logback с учетом путей. + *
По-умолчанию, logback пытается искать свои конфиги по заранее зашитым путям.
+ * Здесь мы изменяем эти принципы.
+ */
+ private static void reconfigureLogback(@Nonnull Path configPath) throws IOException {
+ if (Files.notExists(configPath)) {
+ throw new FileNotFoundException(configPath.toAbsolutePath().toString());
+ }
+
+ LoggerContext logbackContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+ logbackContext.reset();
+ JoranConfigurator configurator = new JoranConfigurator();
+
+ try(InputStream in = Files.newInputStream(configPath)) {
+ configurator.setContext(logbackContext);
+ configurator.doConfigure(in);
+ } catch (JoranException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @SneakyThrows
+ private static Path defaultLogbackConfigPath() {
+ URL url = Objects.requireNonNull(Main.class.getResource("/logback-default.xml"));
+ return Paths.get(url.toURI());
+ }
+}
diff --git a/server-new/src/main/java/mc/server/di/ConfigModule.java b/server-new/src/main/java/mc/server/di/ConfigModule.java
index 5253d52..e9cd35c 100644
--- a/server-new/src/main/java/mc/server/di/ConfigModule.java
+++ b/server-new/src/main/java/mc/server/di/ConfigModule.java
@@ -15,11 +15,22 @@ import java.nio.file.Path;
@Slf4j
public class ConfigModule {
+ private final String defaultResource;
private final Path configPath;
@Provides
@Singleton
Config provideConfig() {
- return ConfigFactory.parseFile(configPath.toFile()).resolve();
+ Config defaultConfig = ConfigFactory.parseResources(defaultResource);
+ Config config;
+
+ if (configPath != null) {
+ Config userConfig = ConfigFactory.parseFile(configPath.toFile());
+ config = userConfig.withFallback(defaultConfig).resolve();
+ } else {
+ config = defaultConfig.resolve();
+ }
+
+ return config;
}
}
diff --git a/server-new/src/main/resources/config-default.conf b/server-new/src/main/resources/config-default.conf
new file mode 100644
index 0000000..5a91e83
--- /dev/null
+++ b/server-new/src/main/resources/config-default.conf
@@ -0,0 +1,27 @@
+server {
+ host: "127.0.0.1"
+ port: 25565
+}
+
+motd: """&bmc-project &8:: &4ZERO
+&8develop by &7DmitriyMX"""
+
+disconnect-reason: "&4Server is not available."
+
+players {
+ max-online: 0
+ fake-online {
+ enable: false
+ value: 0
+ }
+}
+
+# Размер значка: 64x64 px
+icon {
+ enable: false
+ path: "favicon.png"
+}
+
+world {
+ view-distance: 1
+}
diff --git a/server/src/main/resources/logback-sample.xml b/server-new/src/main/resources/logback-default.xml
similarity index 80%
rename from server/src/main/resources/logback-sample.xml
rename to server-new/src/main/resources/logback-default.xml
index f72ea29..2e6a315 100644
--- a/server/src/main/resources/logback-sample.xml
+++ b/server-new/src/main/resources/logback-default.xml
@@ -12,9 +12,12 @@