diff --git a/libs.gradle b/libs.gradle index d6958eb..33ed495 100644 --- a/libs.gradle +++ b/libs.gradle @@ -14,7 +14,8 @@ ext { guava : 'com.google.guava:guava:30.1-jre', lang3 : 'org.apache.commons:commons-lang3:3.11', netty : 'io.netty:netty-all:4.1.22.Final', - reactor : 'io.projectreactor:reactor-core:3.4.5' + reactor : 'io.projectreactor:reactor-core:3.4.5', + yaml : 'org.yaml:snakeyaml:1.28' ] libs.logger = [ diff --git a/protocol/src/main/java/mc/protocol/ProtocolConstant.java b/protocol/src/main/java/mc/protocol/ProtocolConstant.java new file mode 100644 index 0000000..4fbbada --- /dev/null +++ b/protocol/src/main/java/mc/protocol/ProtocolConstant.java @@ -0,0 +1,10 @@ +package mc.protocol; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ProtocolConstant { + + public static final String PROTOCOL_NAME = "1.12.2"; + public static final int PROTOCOL_NUMBER = 340; +} diff --git a/server/build.gradle b/server/build.gradle index 491cc7b..46c8b98 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -3,6 +3,7 @@ gradle :server:run */ +//file:noinspection GrUnresolvedAccess apply from: rootDir.toPath().resolve('logic.gradle').toFile() apply plugin: 'application' @@ -18,4 +19,5 @@ dependencies { implementation libs.netty implementation libs.reactor implementation libs.guava + implementation libs.yaml } diff --git a/server/src/main/java/mc/server/Main.java b/server/src/main/java/mc/server/Main.java index d0a445b..7736a56 100644 --- a/server/src/main/java/mc/server/Main.java +++ b/server/src/main/java/mc/server/Main.java @@ -2,18 +2,38 @@ package mc.server; import lombok.extern.slf4j.Slf4j; import mc.protocol.NettyServer; +import mc.protocol.ProtocolConstant; import mc.protocol.packets.PingPacket; import mc.protocol.packets.client.HandshakePacket; import mc.protocol.packets.client.LoginStartPacket; import mc.protocol.packets.client.StatusServerRequest; import mc.protocol.packets.server.DisconnectPacket; import mc.protocol.packets.server.StatusServerResponse; +import mc.server.config.Config; +import mc.server.di.ConfigModule; +import mc.server.di.DaggerServerComponent; +import mc.server.di.ServerComponent; + +import java.nio.file.Paths; @Slf4j public class Main { public static void main(String[] args) { - log.info("hello"); + log.info("mc-project launch"); + + ConfigModule configModule; + if (args.length > 0) { + configModule = new ConfigModule(Paths.get(args[0])); + } else { + configModule = new ConfigModule(Paths.get("config.yml")); + } + + ServerComponent serverComponent = DaggerServerComponent.builder() + .configModule(configModule) + .build(); + + Config config = serverComponent.getConfig(); NettyServer server = NettyServer.createServer(); @@ -31,16 +51,16 @@ public class Main { StatusServerResponse response = new StatusServerResponse(); response.setInfo("{\n" + " \"version\": {\n" + - " \"name\": \"1.12.2\",\n" + - " \"protocol\": 340\n" + + " \"name\": \"" + ProtocolConstant.PROTOCOL_NAME + "\",\n" + + " \"protocol\": " + ProtocolConstant.PROTOCOL_NUMBER + "\n" + " },\n" + " \"players\": {\n" + - " \"max\": 0,\n" + - " \"online\": 0,\n" + + " \"max\": " + config.players().maxOnlile() + ",\n" + + " \"online\": " + config.players().onlile() + ",\n" + " \"sample\": []\n" + " },\n" + " \"description\": {\n" + - " \"text\": \"Hello world\"\n" + + " \"text\": \"" + config.motd() + "\"\n" + " }\n" + "}"); @@ -58,6 +78,6 @@ public class Main { channel.getCtx().writeAndFlush(disconnectPacket).channel().disconnect(); }); - server.bind("127.0.0.1", 25565); + server.bind(config.server().host(), config.server().port()); } } diff --git a/server/src/main/java/mc/server/config/Config.java b/server/src/main/java/mc/server/config/Config.java new file mode 100644 index 0000000..f8f5f14 --- /dev/null +++ b/server/src/main/java/mc/server/config/Config.java @@ -0,0 +1,35 @@ +package mc.server.config; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.nio.file.Path; + +@Getter +@Setter +@ToString +public class Config { + + private final Server server = new Server(); + private final Players players = new Players(); + + private String motd; + private Path iconPath; + + @Getter + @Setter + @ToString + public static class Server { + private String host; + private int port; + } + + @Getter + @Setter + @ToString + public static class Players { + private int maxOnlile; + private int onlile; + } +} diff --git a/server/src/main/java/mc/server/config/lombok.config b/server/src/main/java/mc/server/config/lombok.config new file mode 100644 index 0000000..f4387a7 --- /dev/null +++ b/server/src/main/java/mc/server/config/lombok.config @@ -0,0 +1 @@ +lombok.accessors.fluent=true \ No newline at end of file diff --git a/server/src/main/java/mc/server/di/ConfigModule.java b/server/src/main/java/mc/server/di/ConfigModule.java new file mode 100644 index 0000000..510b077 --- /dev/null +++ b/server/src/main/java/mc/server/di/ConfigModule.java @@ -0,0 +1,66 @@ +package mc.server.di; + +import dagger.Module; +import dagger.Provides; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import mc.server.config.Config; +import org.yaml.snakeyaml.Yaml; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +@Slf4j +@Module +@RequiredArgsConstructor +public class ConfigModule { + + private final Path configPath; + + @Provides + Config provideConfig() { + Config config = new Config(); + Map map = new Yaml().load(readConfigAsString()); + + config.server().host(fromYamlPath("server/host", map, "127.0.0.1")); + config.server().port(fromYamlPath("server/port", map, 25565)); + config.motd(fromYamlPath("motd", map, "")); + config.players().maxOnlile(fromYamlPath("players/max-online", map, 0)); + config.players().onlile(fromYamlPath("players/online", map, 0)); + + if (Boolean.TRUE.equals(fromYamlPath("icon/enable", map, false))) { + config.iconPath(Paths.get(fromYamlPath("icon/path", map, "favicon.png"))); + } + + map.clear(); + return config; + } + + private String readConfigAsString() { + try { + return Files.readString(configPath); + } catch (IOException e) { + log.error("Can't load config from '{}'", configPath.toAbsolutePath(), e); + return ""; + } + } + + @SuppressWarnings("unchecked") + private static T fromYamlPath(String mapPath, Map map, T defaultValue) { + String[] keys = mapPath.split("/", 2); + + if (map.containsKey(keys[0])) { + Object object = map.get(keys[0]); + if (keys.length > 1) { + return fromYamlPath(keys[1], (Map) object, defaultValue); + } else { + return (T) object; + } + } else { + return defaultValue; + } + } +} diff --git a/server/src/main/java/mc/server/di/ServerComponent.java b/server/src/main/java/mc/server/di/ServerComponent.java new file mode 100644 index 0000000..4147205 --- /dev/null +++ b/server/src/main/java/mc/server/di/ServerComponent.java @@ -0,0 +1,10 @@ +package mc.server.di; + +import dagger.Component; +import mc.server.config.Config; + +@Component(modules = ConfigModule.class) +public interface ServerComponent { + + Config getConfig(); +} diff --git a/server/src/main/resources/config.yml b/server/src/main/resources/config.yml new file mode 100644 index 0000000..af6b6aa --- /dev/null +++ b/server/src/main/resources/config.yml @@ -0,0 +1,13 @@ +server: + host: 127.0.0.1 + port: 25565 + +motd: 'mc-project::ZERO' + +players: + max-online: 0 + online: 0 + +icon: + enable: false + path: favicon.png \ No newline at end of file