refactoring: Config
YAML -> HOCON
This commit is contained in:
@@ -14,7 +14,7 @@ ext {
|
|||||||
annotations: 'com.google.code.findbugs:jsr305:3.0.2',
|
annotations: 'com.google.code.findbugs:jsr305:3.0.2',
|
||||||
lang3 : 'org.apache.commons:commons-lang3:3.11',
|
lang3 : 'org.apache.commons:commons-lang3:3.11',
|
||||||
reactor : 'io.projectreactor:reactor-core:3.4.5',
|
reactor : 'io.projectreactor:reactor-core:3.4.5',
|
||||||
yaml : 'org.yaml:snakeyaml:1.28',
|
hocon : 'com.typesafe:config:1.4.1',
|
||||||
json : 'com.eclipsesource.minimal-json:minimal-json:0.9.5',
|
json : 'com.eclipsesource.minimal-json:minimal-json:0.9.5',
|
||||||
ioutils : 'commons-io:commons-io:2.6',
|
ioutils : 'commons-io:commons-io:2.6',
|
||||||
jopt : 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3',
|
jopt : 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3',
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ dependencies {
|
|||||||
implementation libs.dagger2.implementation
|
implementation libs.dagger2.implementation
|
||||||
annotationProcessor libs.dagger2.annotationProcessor
|
annotationProcessor libs.dagger2.annotationProcessor
|
||||||
|
|
||||||
|
testAnnotationProcessor libs.lombok
|
||||||
|
testCompileOnly libs.lombok
|
||||||
|
|
||||||
testImplementation libs.test.junit5.api
|
testImplementation libs.test.junit5.api
|
||||||
testImplementation libs.test.junit5.params
|
testImplementation libs.test.junit5.params
|
||||||
testRuntimeOnly libs.test.junit5.engine
|
testRuntimeOnly libs.test.junit5.engine
|
||||||
|
|||||||
35
server-new/build.gradle
Normal file
35
server-new/build.gradle
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Запуск
|
||||||
|
gradle :server:run --args="--config=config.yml --logconfig==logback.xml"
|
||||||
|
|
||||||
|
Сборка
|
||||||
|
gradle :server:shadowJar
|
||||||
|
*/
|
||||||
|
|
||||||
|
//file:noinspection GrUnresolvedAccess
|
||||||
|
plugins {
|
||||||
|
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: rootDir.toPath().resolve('logic.gradle').toFile()
|
||||||
|
apply plugin: 'application'
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClassName = 'mc.server.Main'
|
||||||
|
|
||||||
|
if (project.hasProperty('jvmArgs')) {
|
||||||
|
applicationDefaultJvmArgs = List.of((project.jvmArgs as String).split('\\s+'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':protocol-new')
|
||||||
|
|
||||||
|
implementation libs.hocon
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
archiveBaseName.set(jar.archiveBaseName.get())
|
||||||
|
archiveVersion.set(project.version as String)
|
||||||
|
archiveClassifier.set('')
|
||||||
|
}
|
||||||
2
server-new/gradle.properties
Normal file
2
server-new/gradle.properties
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# suppress inspection "UnusedProperty" for whole file
|
||||||
|
module.name=server
|
||||||
13
server-new/src/main/java/mc/server/di/ConfigComponent.java
Normal file
13
server-new/src/main/java/mc/server/di/ConfigComponent.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package mc.server.di;
|
||||||
|
|
||||||
|
import com.typesafe.config.Config;
|
||||||
|
import dagger.Component;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@Component(modules = ConfigModule.class)
|
||||||
|
@Singleton
|
||||||
|
public interface ConfigComponent {
|
||||||
|
|
||||||
|
Config getConfig();
|
||||||
|
}
|
||||||
25
server-new/src/main/java/mc/server/di/ConfigModule.java
Normal file
25
server-new/src/main/java/mc/server/di/ConfigModule.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package mc.server.di;
|
||||||
|
|
||||||
|
import com.typesafe.config.Config;
|
||||||
|
import com.typesafe.config.ConfigFactory;
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class ConfigModule {
|
||||||
|
|
||||||
|
private final Path configPath;
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Config provideConfig() {
|
||||||
|
return ConfigFactory.parseFile(configPath.toFile()).resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
59
server-new/src/test/java/mc/server/di/ConfigModuleTest.java
Normal file
59
server-new/src/test/java/mc/server/di/ConfigModuleTest.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package mc.server.di;
|
||||||
|
|
||||||
|
import com.typesafe.config.Config;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class ConfigModuleTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void singleton() {
|
||||||
|
ConfigComponent component = DaggerConfigComponent.builder()
|
||||||
|
.configModule(new ConfigModule(pathResource("/config-1.conf"))).build();
|
||||||
|
Config config1 = component.getConfig();
|
||||||
|
Config config2 = component.getConfig();
|
||||||
|
|
||||||
|
assertEquals(config1, config2);
|
||||||
|
assertSame(config1, config2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void loadConfig() {
|
||||||
|
ConfigComponent component = DaggerConfigComponent.builder()
|
||||||
|
.configModule(new ConfigModule(pathResource("/config-1.conf"))).build();
|
||||||
|
|
||||||
|
Config config = component.getConfig();
|
||||||
|
assertEquals("value1", config.getString("key1"));
|
||||||
|
assertEquals("value2", config.getString("key2.subkey1"));
|
||||||
|
assertEquals("value3", config.getString("key3.subkey1"));
|
||||||
|
assertEquals("value4", config.getString("\"key4.somename\""));
|
||||||
|
assertEquals("value5", config.getString("key5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void includeTest() {
|
||||||
|
ConfigComponent component = DaggerConfigComponent.builder()
|
||||||
|
.configModule(new ConfigModule(pathResource("/config-2.conf"))).build();
|
||||||
|
|
||||||
|
Config config = component.getConfig();
|
||||||
|
assertEquals("value1", config.getString("key1"));
|
||||||
|
assertEquals("value2", config.getString("key2.subkey1"));
|
||||||
|
assertEquals("value3", config.getString("key3.subkey1"));
|
||||||
|
assertEquals("value4", config.getString("\"key4.somename\""));
|
||||||
|
assertEquals("value5", config.getString("key5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static Path pathResource(String resource) {
|
||||||
|
URL url = ConfigModuleTest.class.getResource(resource);
|
||||||
|
assertNotNull(url);
|
||||||
|
|
||||||
|
return Paths.get(url.toURI());
|
||||||
|
}
|
||||||
|
}
|
||||||
12
server-new/src/test/resources/config-1.conf
Normal file
12
server-new/src/test/resources/config-1.conf
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
key1: value1
|
||||||
|
|
||||||
|
key2.subkey1: value2
|
||||||
|
|
||||||
|
key3 {
|
||||||
|
subkey1: value3
|
||||||
|
}
|
||||||
|
|
||||||
|
"key4.somename": value4
|
||||||
|
|
||||||
|
variable: value5
|
||||||
|
key5: ${variable}
|
||||||
1
server-new/src/test/resources/config-2.conf
Normal file
1
server-new/src/test/resources/config-2.conf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include "config-1.conf"
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package mc.server.config;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
@Accessors(fluent = true)
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
public class Config {
|
|
||||||
|
|
||||||
private final Server server = new Server();
|
|
||||||
private final Players players = new Players();
|
|
||||||
private final World world = new World();
|
|
||||||
|
|
||||||
private String motd;
|
|
||||||
private String disconnectReason;
|
|
||||||
private Path iconPath;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
public static class Server {
|
|
||||||
private String host;
|
|
||||||
private int port;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
public static class Players {
|
|
||||||
private final FakeOnline fakeOnline = new FakeOnline();
|
|
||||||
|
|
||||||
private int maxOnlile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
public static class FakeOnline {
|
|
||||||
private boolean enable;
|
|
||||||
private int value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
public static class World {
|
|
||||||
private int viewDistance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
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<String, Object> 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.disconnectReason(fromYamlPath("disconnect-reason", map, ""));
|
|
||||||
|
|
||||||
config.players().maxOnlile(fromYamlPath("players/max-online", map, 0));
|
|
||||||
config.players().fakeOnline().enable(fromYamlPath("players/fake-online/enable", map, false));
|
|
||||||
config.players().fakeOnline().value(fromYamlPath("players/fake-online/value", map, 0));
|
|
||||||
|
|
||||||
config.world().viewDistance(fromYamlPath("world/view-distance", 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> T fromYamlPath(String mapPath, Map<String, Object> 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<String, Object>) object, defaultValue);
|
|
||||||
} else {
|
|
||||||
return (T) object;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -12,5 +12,6 @@ rootProject.name = map.get('project.name')
|
|||||||
|
|
||||||
include('utils')
|
include('utils')
|
||||||
include('protocol-new')
|
include('protocol-new')
|
||||||
|
include('server-new')
|
||||||
//include('protocol')
|
//include('protocol')
|
||||||
//include('server')
|
//include('server')
|
||||||
Reference in New Issue
Block a user