diff --git a/velocity/src/main/java/org/zhdev/varioutil/VelocityPlugin.java b/velocity/src/main/java/org/zhdev/varioutil/VelocityPlugin.java new file mode 100644 index 0000000..14738c9 --- /dev/null +++ b/velocity/src/main/java/org/zhdev/varioutil/VelocityPlugin.java @@ -0,0 +1,30 @@ +package org.zhdev.varioutil; + +import com.velocitypowered.api.proxy.ProxyServer; +import org.slf4j.Logger; + +import java.nio.file.Path; + +public abstract class VelocityPlugin { + protected final ProxyServer server; + protected final Logger logger; + protected final Path dataFolder; + + protected VelocityPlugin(ProxyServer server, Logger logger, Path dataDirectory) { + this.server = server; + this.logger = logger; + this.dataFolder = dataDirectory; + } + + public ProxyServer getServer() { + return server; + } + + public Path getDataDirectory() { + return dataFolder; + } + + public Logger getLogger() { + return logger; + } +} diff --git a/velocity/src/main/java/org/zhdev/varioutil/VelocityPreparedPlugin.java b/velocity/src/main/java/org/zhdev/varioutil/VelocityPreparedPlugin.java new file mode 100644 index 0000000..bdafaf6 --- /dev/null +++ b/velocity/src/main/java/org/zhdev/varioutil/VelocityPreparedPlugin.java @@ -0,0 +1,78 @@ +package org.zhdev.varioutil; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; +import com.velocitypowered.api.proxy.ProxyServer; +import org.slf4j.Logger; +import org.zhdev.varioutil.config.Config; +import org.zhdev.varioutil.config.ConfigSection; +import org.zhdev.varioutil.config.VelocityTomlConfig; +import org.zhdev.varioutil.language.Language; +import org.zhdev.varioutil.sql.SqlAdapter; +import org.zhdev.varioutil.util.ColorUtils; +import org.zhdev.varioutil.util.ConfigUtils; + +import java.nio.file.Path; + +public abstract class VelocityPreparedPlugin extends VelocityPlugin implements PreparedPlugin { + protected final Config defaultConfig = new VelocityTomlConfig(); + protected final Language language = new Language(); + protected final SqlAdapter sqlAdapter = createSqlAdapter(); + + protected VelocityPreparedPlugin(ProxyServer server, Logger logger, Path dataFolder) { + super(server, logger, dataFolder); + loadConfig(defaultConfig); + loadPhrases(); + establishSqlConnection(); + } + + protected SqlAdapter createSqlAdapter() { + return new SqlAdapter(); + } + + protected void loadPhrases() { + ConfigSection languageSection = defaultConfig.getOrCreateSection("language"); + String locale = languageSection.getString("locale", "default"); + Config languageConfig = new VelocityTomlConfig("language/" + locale + ".toml"); + loadConfig(languageConfig, "language.toml"); + loadConfig(languageConfig, "language/default.toml"); + loadConfig(languageConfig); + ConfigUtils.addPhrases(language, languageConfig, ColorUtils::translateAlternateColorCodes); + } + + protected void establishSqlConnection() { + Config databaseConfig = new VelocityTomlConfig("database.toml"); + loadConfig(databaseConfig); + sqlAdapter.setProvider(ConfigUtils.createSqlConnectionProvider(databaseConfig, getDataDirectory().toString())); + } + + @Override + public Config getDefaultConfig() { + return defaultConfig; + } + + @Override + public Language getLanguage() { + return language; + } + + @Override + public SqlAdapter getSqlAdapter() { + return sqlAdapter; + } + + protected void onEnabling() {} + + protected void onDisabling() {} + + @Subscribe + private void onProxyInitialization(ProxyInitializeEvent event) { + onEnabling(); + } + + @Subscribe + private void onProxyInitialization(ProxyShutdownEvent event) { + onDisabling(); + } +} diff --git a/velocity/src/main/java/org/zhdev/varioutil/config/VelocityTomlConfig.java b/velocity/src/main/java/org/zhdev/varioutil/config/VelocityTomlConfig.java new file mode 100644 index 0000000..beb9483 --- /dev/null +++ b/velocity/src/main/java/org/zhdev/varioutil/config/VelocityTomlConfig.java @@ -0,0 +1,128 @@ +package org.zhdev.varioutil.config; + +import com.electronwill.nightconfig.core.CommentedConfig; +import com.electronwill.nightconfig.toml.TomlFormat; +import com.electronwill.nightconfig.toml.TomlParser; +import com.electronwill.nightconfig.toml.TomlWriter; + +import java.io.Reader; +import java.io.Writer; +import java.nio.file.Path; +import java.util.Map; + +public final class VelocityTomlConfig extends MapConfigSection implements Config { + private static final String DEFAULT_KEY = "config.toml"; + + private final String key; + + public VelocityTomlConfig(String key) { + super(); + this.key = key; + } + + public VelocityTomlConfig() { + this(DEFAULT_KEY); + } + + @Override + public String getKey() { + return key; + } + + private String[] splitComments(String comment) { + String[] comments = comment.split("\n"); + for (int i = 0; i < comments.length; i++) { + comments[i] = comments[i].trim(); + } + return comments; + } + + private String joinComments(String[] comments) { + return ' ' + String.join("\n ", comments); + } + + private void nightConfigToSections(MapConfigSection section, CommentedConfig config) { + for (CommentedConfig.Entry entry : config.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (value instanceof CommentedConfig) { + MapConfigSection childSection; + ConfigSectionNode node = section.map.get(key); + if (node == null || !(node.value instanceof MapConfigSection)) { + childSection = new MapConfigSection(); + } else { + childSection = (MapConfigSection) node.value; + } + nightConfigToSections(childSection, (CommentedConfig) value); + value = childSection; + } + + ConfigSectionNode sectionNode = new ConfigSectionNode(value); + + if (entry.getComment() != null) { + sectionNode.blockComments = splitComments(entry.getComment()); + } + + section.map.put(key, sectionNode); + } + } + + @Override + public void load(Reader reader) { + TomlParser tomlParser = new TomlParser(); + CommentedConfig commentedConfig = tomlParser.parse(reader); + nightConfigToSections(this, commentedConfig); + } + + @Override + public Path load() throws ConfigException { + return load(key); + } + + private void sectionsToNightConfig(MapConfigSection section, CommentedConfig config) { + for (Map.Entry entry : section.map.entrySet()) { + String key = entry.getKey(); + ConfigSectionNode sectionNode = entry.getValue(); + Object value = sectionNode.value; + if (value instanceof MapConfigSection) { + CommentedConfig subConfig = config.createSubConfig(); + sectionsToNightConfig((MapConfigSection) value, subConfig); + value = subConfig; + } + + config.set(key, value); + + if (sectionNode.blockComments != null) { + config.setComment(key, joinComments(sectionNode.blockComments)); + } + + if (sectionNode.inlineComments != null) { + config.setComment(key, config.getComment(key) + "\n\n" + joinComments(sectionNode.inlineComments)); + } + } + } + + @Override + public void save(Writer writer) { + TomlWriter tomlWriter = new TomlWriter(); + CommentedConfig config = TomlFormat.newConfig(); + sectionsToNightConfig(this, config); + tomlWriter.write(config, writer); + } + + @Override + public Path save() throws ConfigException { + return save(key); + } + + @Override + public Path saveIfEmpty() throws ConfigException { + return saveIfEmpty(key); + } + + @Override + public String toString() { + return key; + } +}