mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 14:59:20 +00:00
Switched to ConfigUtils and prepared the addition of metrics
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
object Versions {
|
object Versions {
|
||||||
const val geyserVersion = "2.0.0-SNAPSHOT"
|
const val geyserVersion = "2.0.0-SNAPSHOT"
|
||||||
const val cumulusVersion = "1.0-SNAPSHOT"
|
const val cumulusVersion = "1.0-SNAPSHOT"
|
||||||
|
const val configUtilsVersion = "1.0-SNAPSHOT"
|
||||||
const val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
const val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
||||||
const val fastutilVersion = "8.5.3"
|
const val fastutilVersion = "8.5.3"
|
||||||
const val lombokVersion = "1.18.20"
|
const val lombokVersion = "1.18.20"
|
||||||
@@ -33,6 +34,7 @@ object Versions {
|
|||||||
const val nettyVersion = "4.1.49.Final"
|
const val nettyVersion = "4.1.49.Final"
|
||||||
const val snakeyamlVersion = "1.28"
|
const val snakeyamlVersion = "1.28"
|
||||||
const val cloudVersion = "1.5.0"
|
const val cloudVersion = "1.5.0"
|
||||||
|
const val bstatsVersion = "3.0.0"
|
||||||
|
|
||||||
const val javaWebsocketVersion = "1.5.2"
|
const val javaWebsocketVersion = "1.5.2"
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ fun Project.isSnapshot(): Boolean =
|
|||||||
fun Project.fullVersion(): String {
|
fun Project.fullVersion(): String {
|
||||||
var version = version.toString()
|
var version = version.toString()
|
||||||
if (version.endsWith("-SNAPSHOT")) {
|
if (version.endsWith("-SNAPSHOT")) {
|
||||||
version += " (b${buildNumberAsString()}-${lastCommitHash()}}"
|
version += " (b${buildNumberAsString()}-${lastCommitHash()})"
|
||||||
}
|
}
|
||||||
return version
|
return version
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("floodgate.shadow-conventions")
|
id("floodgate.publish-conventions")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
plugins {
|
||||||
|
id("floodgate.shadow-conventions")
|
||||||
|
id("com.jfrog.artifactory")
|
||||||
|
id("maven-publish")
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications.create<MavenPublication>("mavenJava") {
|
||||||
|
groupId = project.group as String
|
||||||
|
artifactId = "floodgate-" + project.name
|
||||||
|
version = project.version as String
|
||||||
|
|
||||||
|
artifact(tasks["shadowJar"])
|
||||||
|
artifact(tasks["sourcesJar"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactory {
|
||||||
|
publish {
|
||||||
|
repository {
|
||||||
|
setRepoKey(if (isSnapshot()) "maven-snapshots" else "maven-releases")
|
||||||
|
setMavenCompatible(true)
|
||||||
|
}
|
||||||
|
defaults {
|
||||||
|
publishConfigs("archives")
|
||||||
|
setPublishArtifacts(true)
|
||||||
|
setPublishPom(true)
|
||||||
|
setPublishIvy(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,8 +3,6 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
|||||||
plugins {
|
plugins {
|
||||||
id("floodgate.base-conventions")
|
id("floodgate.base-conventions")
|
||||||
id("com.github.johnrengelman.shadow")
|
id("com.github.johnrengelman.shadow")
|
||||||
id("com.jfrog.artifactory")
|
|
||||||
id("maven-publish")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
@@ -32,29 +30,3 @@ tasks {
|
|||||||
dependsOn(shadowJar)
|
dependsOn(shadowJar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications.create<MavenPublication>("mavenJava") {
|
|
||||||
groupId = project.group as String
|
|
||||||
artifactId = "floodgate-" + project.name
|
|
||||||
version = project.version as String
|
|
||||||
|
|
||||||
artifact(tasks["shadowJar"])
|
|
||||||
artifact(tasks["sourcesJar"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
artifactory {
|
|
||||||
publish {
|
|
||||||
repository {
|
|
||||||
setRepoKey(if (isSnapshot()) "maven-snapshots" else "maven-releases")
|
|
||||||
setMavenCompatible(true)
|
|
||||||
}
|
|
||||||
defaults {
|
|
||||||
publishConfigs("archives")
|
|
||||||
setPublishArtifacts(true)
|
|
||||||
setPublishPom(true)
|
|
||||||
setPublishIvy(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -44,7 +44,7 @@ subprojects {
|
|||||||
plugins.apply("floodgate.database-conventions")
|
plugins.apply("floodgate.database-conventions")
|
||||||
} else {
|
} else {
|
||||||
when (this) {
|
when (this) {
|
||||||
in platforms -> plugins.apply("floodgate.shadow-conventions")
|
in platforms -> plugins.apply("floodgate.publish-conventions")
|
||||||
else -> plugins.apply("floodgate.base-conventions")
|
else -> plugins.apply("floodgate.base-conventions")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import net.kyori.blossom.BlossomExtension
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("net.kyori.blossom")
|
id("net.kyori.blossom")
|
||||||
|
id("floodgate.shadow-conventions")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.api)
|
api(projects.api)
|
||||||
|
api("org.geysermc.configutils", "configutils", Versions.configUtilsVersion)
|
||||||
|
|
||||||
api("com.google.inject", "guice", Versions.guiceVersion)
|
api("com.google.inject", "guice", Versions.guiceVersion)
|
||||||
api("com.nukkitx.fastutil", "fastutil-short-object-maps", Versions.fastutilVersion)
|
api("com.nukkitx.fastutil", "fastutil-short-object-maps", Versions.fastutilVersion)
|
||||||
@@ -13,12 +15,15 @@ dependencies {
|
|||||||
api("org.java-websocket", "Java-WebSocket", Versions.javaWebsocketVersion)
|
api("org.java-websocket", "Java-WebSocket", Versions.javaWebsocketVersion)
|
||||||
api("cloud.commandframework", "cloud-core", Versions.cloudVersion)
|
api("cloud.commandframework", "cloud-core", Versions.cloudVersion)
|
||||||
api("org.yaml", "snakeyaml", Versions.snakeyamlVersion)
|
api("org.yaml", "snakeyaml", Versions.snakeyamlVersion)
|
||||||
|
api("org.bstats", "bstats-base", Versions.bstatsVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// present on all platforms
|
// present on all platforms
|
||||||
provided("io.netty", "netty-transport", Versions.nettyVersion)
|
provided("io.netty", "netty-transport", Versions.nettyVersion)
|
||||||
provided("io.netty", "netty-codec", Versions.nettyVersion)
|
provided("io.netty", "netty-codec", Versions.nettyVersion)
|
||||||
|
|
||||||
|
relocate("org.bstats")
|
||||||
|
|
||||||
configure<BlossomExtension> {
|
configure<BlossomExtension> {
|
||||||
val constantsFile = "src/main/java/org/geysermc/floodgate/util/Constants.java"
|
val constantsFile = "src/main/java/org/geysermc/floodgate/util/Constants.java"
|
||||||
replaceToken("\${branch}", branchName(), constantsFile)
|
replaceToken("\${branch}", branchName(), constantsFile)
|
||||||
|
|||||||
@@ -25,15 +25,22 @@
|
|||||||
|
|
||||||
package org.geysermc.floodgate.config;
|
package org.geysermc.floodgate.config;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.geysermc.configutils.loader.callback.CallbackResult;
|
||||||
|
import org.geysermc.configutils.loader.callback.GenericPostInitializeCallback;
|
||||||
|
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The global Floodgate configuration file used in every platform. Some platforms have their own
|
* The global Floodgate configuration file used in every platform. Some platforms have their own
|
||||||
* addition to the global configuration like {@link ProxyFloodgateConfig} for the proxies.
|
* addition to the global configuration like {@link ProxyFloodgateConfig} for the proxies.
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public class FloodgateConfig {
|
public class FloodgateConfig implements GenericPostInitializeCallback<ConfigLoader> {
|
||||||
private String keyFileName;
|
private String keyFileName;
|
||||||
private String usernamePrefix;
|
private String usernamePrefix;
|
||||||
private boolean replaceSpaces;
|
private boolean replaceSpaces;
|
||||||
@@ -42,22 +49,36 @@ public class FloodgateConfig {
|
|||||||
|
|
||||||
private DisconnectMessages disconnect;
|
private DisconnectMessages disconnect;
|
||||||
private PlayerLinkConfig playerLink;
|
private PlayerLinkConfig playerLink;
|
||||||
|
private MetricsConfig metrics;
|
||||||
|
|
||||||
private boolean debug;
|
private boolean debug;
|
||||||
private int configVersion;
|
private int configVersion;
|
||||||
|
|
||||||
private Key key;
|
private Key key;
|
||||||
|
|
||||||
public void setKey(Key key) {
|
|
||||||
if (this.key == null) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isProxy() {
|
public boolean isProxy() {
|
||||||
return this instanceof ProxyFloodgateConfig;
|
return this instanceof ProxyFloodgateConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CallbackResult postInitialize(ConfigLoader loader) {
|
||||||
|
Path keyPath = loader.getDataFolder().resolve(getKeyFileName());
|
||||||
|
|
||||||
|
// don't assume that the key always exists with the existence of a config
|
||||||
|
if (!Files.exists(keyPath)) {
|
||||||
|
loader.generateKey(keyPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Key floodgateKey = loader.getKeyProducer().produceFrom(keyPath);
|
||||||
|
loader.getCipher().init(floodgateKey);
|
||||||
|
key = floodgateKey;
|
||||||
|
} catch (IOException exception) {
|
||||||
|
return CallbackResult.failed(exception.getMessage());
|
||||||
|
}
|
||||||
|
return CallbackResult.ok();
|
||||||
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public static class DisconnectMessages {
|
public static class DisconnectMessages {
|
||||||
private String invalidKey;
|
private String invalidKey;
|
||||||
@@ -68,10 +89,16 @@ public class FloodgateConfig {
|
|||||||
public static class PlayerLinkConfig {
|
public static class PlayerLinkConfig {
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private boolean requireLink;
|
private boolean requireLink;
|
||||||
private boolean enableOwnLinking = false;
|
private boolean enableOwnLinking;
|
||||||
private boolean allowed;
|
private boolean allowed;
|
||||||
private long linkCodeTimeout;
|
private long linkCodeTimeout;
|
||||||
private String type;
|
private String type;
|
||||||
private boolean enableGlobalLinking;
|
private boolean enableGlobalLinking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public static class MetricsConfig {
|
||||||
|
private boolean enabled;
|
||||||
|
private UUID uuid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/Floodgate
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.floodgate.config.loader;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
import org.yaml.snakeyaml.constructor.Constructor;
|
|
||||||
import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
|
|
||||||
import org.yaml.snakeyaml.introspector.BeanAccess;
|
|
||||||
import org.yaml.snakeyaml.introspector.FieldProperty;
|
|
||||||
import org.yaml.snakeyaml.introspector.Property;
|
|
||||||
import org.yaml.snakeyaml.introspector.PropertyUtils;
|
|
||||||
|
|
||||||
public class ConfigInitializer {
|
|
||||||
private static final Yaml YAML;
|
|
||||||
|
|
||||||
static {
|
|
||||||
Constructor constructor =
|
|
||||||
new CustomClassLoaderConstructor(ConfigInitializer.class.getClassLoader());
|
|
||||||
|
|
||||||
constructor.setPropertyUtils(new PropertyUtils() {
|
|
||||||
@Override
|
|
||||||
protected Map<String, Property> getPropertiesMap(Class<?> type, BeanAccess bAccess) {
|
|
||||||
Map<String, Property> properties = new LinkedHashMap<>();
|
|
||||||
getPropertiesFromClass(type, FloodgateConfig.class, properties);
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getPropertiesFromClass(
|
|
||||||
Class<?> type,
|
|
||||||
Class<?> stopAfter,
|
|
||||||
Map<String, Property> propertyMap) {
|
|
||||||
|
|
||||||
Class<?> current = type;
|
|
||||||
while (!Object.class.equals(current)) {
|
|
||||||
for (Field field : current.getDeclaredFields()) {
|
|
||||||
int modifiers = field.getModifiers();
|
|
||||||
if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {
|
|
||||||
String correctName = getCorrectName(field.getName());
|
|
||||||
// children should override parents
|
|
||||||
propertyMap.putIfAbsent(correctName, new FieldProperty(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.getClass().getSuperclass().equals(current)) {
|
|
||||||
getPropertiesFromClass(field.getClass(), field.getClass(), propertyMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current.equals(stopAfter)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
current = type.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getCorrectName(String name) {
|
|
||||||
// convert sendFloodgateData to send-floodgate-data,
|
|
||||||
// which is the style of writing config fields
|
|
||||||
StringBuilder propertyBuilder = new StringBuilder();
|
|
||||||
for (int i = 0; i < name.length(); i++) {
|
|
||||||
char current = name.charAt(i);
|
|
||||||
if (Character.isUpperCase(current)) {
|
|
||||||
propertyBuilder.append('-').append(Character.toLowerCase(current));
|
|
||||||
} else {
|
|
||||||
propertyBuilder.append(current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return propertyBuilder.toString();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
constructor.getPropertyUtils().setSkipMissingProperties(true);
|
|
||||||
YAML = new Yaml(constructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends FloodgateConfig> T initializeFrom(
|
|
||||||
InputStream dataStream,
|
|
||||||
Class<T> configClass) {
|
|
||||||
return YAML.loadAs(dataStream, configClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,24 +25,27 @@
|
|||||||
|
|
||||||
package org.geysermc.floodgate.config.loader;
|
package org.geysermc.floodgate.config.loader;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
|
import java.util.UUID;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.geysermc.configutils.ConfigUtilities;
|
||||||
|
import org.geysermc.configutils.file.codec.PathFileCodec;
|
||||||
|
import org.geysermc.configutils.file.template.ResourceTemplateReader;
|
||||||
|
import org.geysermc.configutils.updater.change.Changes;
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||||
import org.geysermc.floodgate.config.updater.ConfigUpdater;
|
|
||||||
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
import org.geysermc.floodgate.crypto.FloodgateCipher;
|
||||||
import org.geysermc.floodgate.crypto.KeyProducer;
|
import org.geysermc.floodgate.crypto.KeyProducer;
|
||||||
|
|
||||||
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public final class ConfigLoader {
|
public final class ConfigLoader {
|
||||||
private final Path dataFolder;
|
private final Path dataFolder;
|
||||||
private final Class<? extends FloodgateConfig> configClass;
|
private final Class<? extends FloodgateConfig> configClass;
|
||||||
private final DefaultConfigHandler configCreator;
|
|
||||||
private final ConfigUpdater updater;
|
|
||||||
|
|
||||||
private final KeyProducer keyProducer;
|
private final KeyProducer keyProducer;
|
||||||
private final FloodgateCipher cipher;
|
private final FloodgateCipher cipher;
|
||||||
@@ -51,61 +54,42 @@ public final class ConfigLoader {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends FloodgateConfig> T load() {
|
public <T extends FloodgateConfig> T load() {
|
||||||
Path configPath = dataFolder.resolve("config.yml");
|
String templateFile = "config.yml";
|
||||||
|
if (ProxyFloodgateConfig.class.isAssignableFrom(configClass)) {
|
||||||
String defaultConfigName = "config.yml";
|
templateFile = "proxy-" + templateFile;
|
||||||
boolean proxy = ProxyFloodgateConfig.class.isAssignableFrom(configClass);
|
|
||||||
if (proxy) {
|
|
||||||
defaultConfigName = "proxy-" + defaultConfigName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean newConfig = !Files.exists(configPath);
|
//todo old Floodgate logged a message when version = 0 and it generated a new key.
|
||||||
if (newConfig) {
|
// Might be nice to allow you to run a function for a specific version.
|
||||||
try {
|
|
||||||
configCreator.createDefaultConfig(defaultConfigName, configPath);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
logger.error("Error while creating config", exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T configInstance;
|
// it would also be nice to have sections in versionBuilder so that you don't have to
|
||||||
try {
|
// provide the path all the time
|
||||||
// check and update if the config is outdated
|
|
||||||
if (!newConfig) {
|
|
||||||
updater.update(this, defaultConfigName);
|
|
||||||
}
|
|
||||||
|
|
||||||
FloodgateConfig config = ConfigInitializer.initializeFrom(
|
ConfigUtilities utilities =
|
||||||
Files.newInputStream(configPath), configClass);
|
ConfigUtilities.builder()
|
||||||
|
.fileCodec(PathFileCodec.of(dataFolder))
|
||||||
|
.configFile("config.yml")
|
||||||
|
.templateReader(ResourceTemplateReader.of(getClass()))
|
||||||
|
.template(templateFile)
|
||||||
|
.changes(Changes.builder()
|
||||||
|
.version(1, Changes.versionBuilder()
|
||||||
|
.keyRenamed("player-link.enable", "player-link.enabled")
|
||||||
|
.keyRenamed("player-link.allow-linking", "player-link.allowed"))
|
||||||
|
.version(2, Changes.versionBuilder()
|
||||||
|
.keyRenamed("player-link.use-global-linking", "player-link.enable-global-linking"))
|
||||||
|
.build())
|
||||||
|
.definePlaceholder("metrics.uuid", UUID::randomUUID)
|
||||||
|
.postInitializeCallbackArgument(this)
|
||||||
|
.build();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
configInstance = (T) config;
|
return (T) utilities.executeOn(configClass);
|
||||||
} catch (ClassCastException exception) {
|
} catch (Throwable throwable) {
|
||||||
logger.error("Failed to cast config file to required class.", exception);
|
|
||||||
throw new RuntimeException(exception);
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
logger.error("Error while loading config", exception);
|
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"Failed to load the config! Try to delete the config file", exception);
|
"Failed to load the config! Try to delete the config file if this error persists",
|
||||||
|
throwable
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path keyPath = dataFolder.resolve(configInstance.getKeyFileName());
|
|
||||||
// don't assume that the key always exists with the existence of a config
|
|
||||||
if (!Files.exists(keyPath)) {
|
|
||||||
generateKey(keyPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Key key = keyProducer.produceFrom(keyPath);
|
|
||||||
cipher.init(key);
|
|
||||||
configInstance.setKey(key);
|
|
||||||
} catch (IOException exception) {
|
|
||||||
logger.error("Error while reading the key", exception);
|
|
||||||
throw new RuntimeException("Failed to read the key!", exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
return configInstance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateKey(Path keyPath) {
|
public void generateKey(Path keyPath) {
|
||||||
|
|||||||
@@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/Floodgate
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.floodgate.config.loader;
|
|
||||||
|
|
||||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import org.geysermc.floodgate.util.Utils;
|
|
||||||
|
|
||||||
public class DefaultConfigHandler {
|
|
||||||
public void createDefaultConfig(String defaultConfigLocation, Path configPath) throws IOException {
|
|
||||||
List<String> configLines = loadDefaultConfig(defaultConfigLocation);
|
|
||||||
|
|
||||||
// writing the new config file
|
|
||||||
Files.write(configPath, configLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> loadDefaultConfig(String defaultConfigLocation)
|
|
||||||
throws IOException {
|
|
||||||
List<String> lines = Utils.readAllLines(defaultConfigLocation);
|
|
||||||
|
|
||||||
List<String> configLines = new ArrayList<>();
|
|
||||||
String parentConfig = null;
|
|
||||||
List<String> parentLines = null;
|
|
||||||
|
|
||||||
int lastInsertLine = -1;
|
|
||||||
int tempAddAfter = -1;
|
|
||||||
|
|
||||||
for (String line : lines) {
|
|
||||||
// >>(space) or >>|
|
|
||||||
if (line.startsWith(">>")) {
|
|
||||||
if (line.length() >= 3) {
|
|
||||||
|
|
||||||
// define parent file
|
|
||||||
if (line.charAt(2) == ' ') {
|
|
||||||
if (tempAddAfter != -1) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Cannot define new parent without closing the current section");
|
|
||||||
}
|
|
||||||
parentConfig = line.substring(3);
|
|
||||||
parentLines = null;
|
|
||||||
lastInsertLine = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// define start / end of insert section
|
|
||||||
if (line.charAt(2) == '|') {
|
|
||||||
// end section
|
|
||||||
if (line.length() == 3) {
|
|
||||||
if (tempAddAfter == -1) {
|
|
||||||
throw new IllegalStateException("Cannot close an unclosed section");
|
|
||||||
}
|
|
||||||
lastInsertLine = tempAddAfter;
|
|
||||||
tempAddAfter = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// start insert section
|
|
||||||
if (parentConfig == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Cannot start insert section without providing a parent");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tempAddAfter != -1) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Cannot start section with an unclosed section");
|
|
||||||
}
|
|
||||||
|
|
||||||
// note that addAfter starts counting from 1
|
|
||||||
int addAfter = Integer.parseInt(line.substring(4)) - 1;
|
|
||||||
if (lastInsertLine > -1 && addAfter < lastInsertLine) {
|
|
||||||
throw new IllegalStateException(format(
|
|
||||||
"Cannot add the same lines twice {} {}",
|
|
||||||
addAfter, lastInsertLine
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// as you can see by this implementation
|
|
||||||
// we don't support parent files in parent files
|
|
||||||
|
|
||||||
if (lastInsertLine == -1) {
|
|
||||||
parentLines = Utils.readAllLines(parentConfig);
|
|
||||||
|
|
||||||
for (int i = 0; i <= addAfter; i++) {
|
|
||||||
configLines.add(parentLines.get(i));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = lastInsertLine; i <= addAfter; i++) {
|
|
||||||
configLines.add(parentLines.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tempAddAfter = addAfter;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.charAt(2) == '*') {
|
|
||||||
if (parentConfig == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Cannot write rest of the parent without providing a parent");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tempAddAfter != -1) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Cannot write rest of the parent config while an insert section is still open");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastInsertLine == -1) {
|
|
||||||
parentLines = Utils.readAllLines(parentConfig);
|
|
||||||
configLines.addAll(parentLines);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the lastInsertLine has already been printed, so we won't print it twice
|
|
||||||
for (int i = lastInsertLine + 1; i < parentLines.size(); i++) {
|
|
||||||
configLines.add(parentLines.get(i));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"The use of >>" + line.charAt(2) + " is unknown");
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Unable do something with just >>");
|
|
||||||
}
|
|
||||||
// everything else: comments and key/value lines will be added
|
|
||||||
configLines.add(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return configLines;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/Floodgate
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.floodgate.config.updater;
|
|
||||||
|
|
||||||
import com.google.common.base.Ascii;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
|
||||||
import org.geysermc.floodgate.config.loader.DefaultConfigHandler;
|
|
||||||
|
|
||||||
public final class ConfigFileUpdater {
|
|
||||||
@Inject private FloodgateLogger logger;
|
|
||||||
@Inject private DefaultConfigHandler defaultConfigHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple config file updater. Please note that all the keys should be unique and that this
|
|
||||||
* system wasn't made for complex configurations.
|
|
||||||
*
|
|
||||||
* @param configLocation the location of the Floodgate config
|
|
||||||
* @param currentVersion the key value map of the current config
|
|
||||||
* @param renames name changes introduced in this version. new (key) to old
|
|
||||||
* (value)
|
|
||||||
* @param defaultConfigLocation the location of the default Floodgate config
|
|
||||||
* @throws IOException if an I/O error occurs
|
|
||||||
*/
|
|
||||||
public void update(
|
|
||||||
Path configLocation,
|
|
||||||
Map<String, Object> currentVersion,
|
|
||||||
Map<String, String> renames,
|
|
||||||
String defaultConfigLocation)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
List<String> notFound = new ArrayList<>();
|
|
||||||
List<String> newConfig = defaultConfigHandler.loadDefaultConfig(defaultConfigLocation);
|
|
||||||
|
|
||||||
String spaces = "";
|
|
||||||
Map<String, Object> map = null;
|
|
||||||
|
|
||||||
String line;
|
|
||||||
for (int i = 0; i < newConfig.size(); i++) {
|
|
||||||
line = newConfig.get(i);
|
|
||||||
// we don't have to check comments or empty lines
|
|
||||||
if (line.isEmpty() || line.charAt(0) == '#') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder currentSpaces = new StringBuilder();
|
|
||||||
while (line.charAt(currentSpaces.length()) == Ascii.SPACE) {
|
|
||||||
currentSpaces.append(Ascii.SPACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// end of subcategory
|
|
||||||
if (!spaces.isEmpty() && currentSpaces.length() < spaces.length()) {
|
|
||||||
// we can assume this since we don't allow subcategories of subcategories
|
|
||||||
spaces = "";
|
|
||||||
map = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore comments
|
|
||||||
if (line.charAt(currentSpaces.length()) == '#') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int splitIndex = line.indexOf(':');
|
|
||||||
// if the line has a 'key: value' structure
|
|
||||||
if (splitIndex != -1) {
|
|
||||||
|
|
||||||
// start of a subcategory
|
|
||||||
if (line.length() == splitIndex + 1) {
|
|
||||||
if (currentSpaces.length() > 0) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Config too complex! I can't understand subcategories of a subcategory");
|
|
||||||
}
|
|
||||||
|
|
||||||
spaces = " ";
|
|
||||||
//todo allow rename of subcategory?
|
|
||||||
//noinspection unchecked
|
|
||||||
map = (Map<String, Object>) currentVersion.get(line.substring(0, splitIndex));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = line.substring(spaces.length(), splitIndex);
|
|
||||||
|
|
||||||
// don't change the config-version to the old value!
|
|
||||||
if (name.equals("config-version")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow multiple renames
|
|
||||||
String tempName;
|
|
||||||
String oldName = name;
|
|
||||||
do {
|
|
||||||
tempName = oldName;
|
|
||||||
oldName = renames.getOrDefault(oldName, oldName);
|
|
||||||
} while (!oldName.equals(tempName));
|
|
||||||
|
|
||||||
Object value;
|
|
||||||
if (map != null) {
|
|
||||||
value = map.get(oldName);
|
|
||||||
} else {
|
|
||||||
value = currentVersion.get(spaces + oldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// use default value if the key doesn't exist in the current version
|
|
||||||
if (value == null) {
|
|
||||||
notFound.add(name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value instanceof String) {
|
|
||||||
String v = (String) value;
|
|
||||||
if (!v.startsWith("\"") || !v.endsWith("\"")) {
|
|
||||||
value = "\"" + value + "\"";
|
|
||||||
}
|
|
||||||
//todo this doesn't update {0} {1} to {} {} e.g.
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug(name + " has been changed to " + value);
|
|
||||||
newConfig.set(i, spaces + name + ": " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.deleteIfExists(configLocation.getParent().resolve("config-old.yml"));
|
|
||||||
Files.copy(configLocation, configLocation.getParent().resolve("config-old.yml"));
|
|
||||||
Files.write(configLocation, newConfig);
|
|
||||||
|
|
||||||
logger.info("Successfully updated the config file! " +
|
|
||||||
"Your old config has been moved to config-old.yml");
|
|
||||||
|
|
||||||
if (!notFound.isEmpty()) {
|
|
||||||
StringBuilder messageBuilder = new StringBuilder(
|
|
||||||
"Please note that the following keys we not found in the old config and " +
|
|
||||||
"are now using the default Floodgate config value. Missing/new keys: ");
|
|
||||||
|
|
||||||
boolean first = true;
|
|
||||||
for (String value : notFound) {
|
|
||||||
if (!first) {
|
|
||||||
messageBuilder.append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
String renamed = renames.get(value);
|
|
||||||
if (renamed != null) {
|
|
||||||
messageBuilder.append(renamed).append(" to ");
|
|
||||||
}
|
|
||||||
|
|
||||||
messageBuilder.append(value);
|
|
||||||
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info(messageBuilder.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/Floodgate
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.floodgate.config.updater;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
|
||||||
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
|
||||||
import org.yaml.snakeyaml.Yaml;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public final class ConfigUpdater {
|
|
||||||
private static final int CONFIG_VERSION = 2;
|
|
||||||
private final Path dataFolder;
|
|
||||||
private final ConfigFileUpdater fileUpdater;
|
|
||||||
private final FloodgateLogger logger;
|
|
||||||
|
|
||||||
public void update(ConfigLoader loader, String defaultConfigLocation) {
|
|
||||||
Path configLocation = dataFolder.resolve("config.yml");
|
|
||||||
|
|
||||||
Map<String, Object> config;
|
|
||||||
|
|
||||||
try (BufferedReader configReader = Files.newBufferedReader(configLocation)) {
|
|
||||||
config = new Yaml().load(configReader);
|
|
||||||
} catch (IOException exception) {
|
|
||||||
logger.error("Error while opening the config file", exception);
|
|
||||||
throw new RuntimeException("Failed to update config", exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
// new name -> old name
|
|
||||||
Map<String, String> renames = new HashMap<>();
|
|
||||||
|
|
||||||
int version = 0; // pre-rewrite is the default config version
|
|
||||||
|
|
||||||
Object versionElement = config.get("config-version");
|
|
||||||
// only rewrite configs have a config-version
|
|
||||||
if (versionElement == null) {
|
|
||||||
logger.warn("We've detected a pre-rewrite config file, please note that Floodgate " +
|
|
||||||
"doesn't not work properly if you don't update your Floodgate key used on " +
|
|
||||||
"all your servers (including Geyser). We'll try to update your Floodgate " +
|
|
||||||
"config now and we'll also generate a new Floodgate key for you, but if " +
|
|
||||||
"you're running a network or if you're running a Spigot server with " +
|
|
||||||
"Geyser Standalone please update as you'll no longer be able to connect.");
|
|
||||||
renames.put("enabled", "enable");
|
|
||||||
renames.put("allowed", "allow-linking");
|
|
||||||
|
|
||||||
// relocate the old key so that they can restore it if it was a new key
|
|
||||||
Path keyFilePath = dataFolder.resolve((String) config.get("key-file-name"));
|
|
||||||
if (Files.exists(keyFilePath)) {
|
|
||||||
try {
|
|
||||||
Files.copy(keyFilePath, dataFolder.resolve("old-key.pem"));
|
|
||||||
} catch (IOException exception) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"Failed to relocate the old key to make place for a new key",
|
|
||||||
exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loader.generateKey(keyFilePath);
|
|
||||||
} else {
|
|
||||||
// get (and verify) the config version
|
|
||||||
checkArgument(
|
|
||||||
versionElement instanceof Integer,
|
|
||||||
"Config version should be an integer. Did someone mess with the config?"
|
|
||||||
);
|
|
||||||
|
|
||||||
version = (int) versionElement;
|
|
||||||
checkArgument(
|
|
||||||
version > 0 && version <= CONFIG_VERSION,
|
|
||||||
format("Config is newer then possible on this version! Expected {}, got {}",
|
|
||||||
CONFIG_VERSION, version));
|
|
||||||
}
|
|
||||||
|
|
||||||
// config is already up-to-date
|
|
||||||
if (version == CONFIG_VERSION) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version < 2) {
|
|
||||||
// renamed 'use-global-linking' to 'enable-global-linking'
|
|
||||||
// and added 'enable-own-linking'
|
|
||||||
renames.put("enable-global-linking", "use-global-linking");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
fileUpdater.update(configLocation, config, renames, defaultConfigLocation);
|
|
||||||
} catch (IOException exception) {
|
|
||||||
logger.error("Error while updating the config file", exception);
|
|
||||||
throw new RuntimeException("Failed to update config", exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -43,9 +43,6 @@ import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
|||||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
||||||
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
import org.geysermc.floodgate.config.loader.ConfigLoader;
|
||||||
import org.geysermc.floodgate.config.loader.DefaultConfigHandler;
|
|
||||||
import org.geysermc.floodgate.config.updater.ConfigFileUpdater;
|
|
||||||
import org.geysermc.floodgate.config.updater.ConfigUpdater;
|
|
||||||
import org.geysermc.floodgate.crypto.AesCipher;
|
import org.geysermc.floodgate.crypto.AesCipher;
|
||||||
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
import org.geysermc.floodgate.crypto.AesKeyProducer;
|
||||||
import org.geysermc.floodgate.crypto.Base64Topping;
|
import org.geysermc.floodgate.crypto.Base64Topping;
|
||||||
@@ -105,27 +102,10 @@ public class CommonModule extends AbstractModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
public ConfigLoader configLoader(
|
public ConfigLoader configLoader(
|
||||||
@Named("configClass") Class<? extends FloodgateConfig> configClass,
|
@Named("configClass") Class<? extends FloodgateConfig> configClass,
|
||||||
DefaultConfigHandler defaultConfigHandler,
|
|
||||||
ConfigUpdater configUpdater,
|
|
||||||
KeyProducer producer,
|
KeyProducer producer,
|
||||||
FloodgateCipher cipher,
|
FloodgateCipher cipher,
|
||||||
FloodgateLogger logger) {
|
FloodgateLogger logger) {
|
||||||
return new ConfigLoader(dataDirectory, configClass, defaultConfigHandler, configUpdater,
|
return new ConfigLoader(dataDirectory, configClass, producer, cipher, logger);
|
||||||
producer, cipher, logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public DefaultConfigHandler defaultConfigCreator() {
|
|
||||||
return new DefaultConfigHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public ConfigUpdater configUpdater(
|
|
||||||
ConfigFileUpdater configFileUpdater,
|
|
||||||
FloodgateLogger logger) {
|
|
||||||
return new ConfigUpdater(dataDirectory, configFileUpdater, logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
@@ -58,5 +58,9 @@ player-link:
|
|||||||
# you have limited internet access.
|
# you have limited internet access.
|
||||||
enable-global-linking: true
|
enable-global-linking: true
|
||||||
|
|
||||||
|
metrics:
|
||||||
|
enabled: true
|
||||||
|
uuid: ${metrics.uuid}
|
||||||
|
|
||||||
# Do not change this
|
# Do not change this
|
||||||
config-version: 2
|
config-version: 3
|
||||||
|
|||||||
@@ -10,10 +10,6 @@
|
|||||||
|
|
||||||
<!-- UnusedPrivateMethod -->
|
<!-- UnusedPrivateMethod -->
|
||||||
<exclude-pattern>.*/CommonPlayerLink.*</exclude-pattern>
|
<exclude-pattern>.*/CommonPlayerLink.*</exclude-pattern>
|
||||||
<!-- NullAssignment -->
|
|
||||||
<exclude-pattern>.*/DefaultConfigHandler.*</exclude-pattern>
|
|
||||||
<!-- NullAssignment -->
|
|
||||||
<exclude-pattern>.*/ConfigFileUpdater.*</exclude-pattern>
|
|
||||||
<!-- RedundantFieldInitializer -->
|
<!-- RedundantFieldInitializer -->
|
||||||
<exclude-pattern>.*/FloodgateConfig.*</exclude-pattern>
|
<exclude-pattern>.*/FloodgateConfig.*</exclude-pattern>
|
||||||
<!-- CloseResource, there is no shutdown event and it has to load classes on the fly -->
|
<!-- CloseResource, there is no shutdown event and it has to load classes on the fly -->
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ var gsonVersion = "2.8.5"
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(projects.core)
|
api(projects.core)
|
||||||
|
|
||||||
|
implementation("cloud.commandframework", "cloud-bukkit", Versions.cloudVersion)
|
||||||
// hack to make pre 1.12 work
|
// hack to make pre 1.12 work
|
||||||
implementation("com.google.guava", "guava", guavaVersion)
|
implementation("com.google.guava", "guava", guavaVersion)
|
||||||
implementation("cloud.commandframework", "cloud-bukkit", Versions.cloudVersion)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
relocate("com.google.inject")
|
relocate("com.google.inject")
|
||||||
|
|||||||
Reference in New Issue
Block a user