From d111fce37b97bf6b1d24d1a444efe0371dbafe2e Mon Sep 17 00:00:00 2001 From: Vankka Date: Thu, 7 Sep 2023 17:41:50 +0300 Subject: [PATCH 1/4] Add filtering for which control characters can be sent to Minecraft, add removal of line break spam to default config --- .../config/main/channels/DiscordToMinecraftChatConfig.java | 4 +++- .../messageforwarding/discord/DiscordChatMessageModule.java | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java index 916bd2e9..d49cf39d 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java @@ -51,7 +51,9 @@ public class DiscordToMinecraftChatConfig { // TODO: more info on regex pairs (String#replaceAll) @Comment("Regex filters for Discord message contents (this is the %message% part of the \"format\" option)") @Untranslated(Untranslated.Type.VALUE) - public Map contentRegexFilters = new LinkedHashMap<>(); + public Map contentRegexFilters = new LinkedHashMap() {{ + put(Pattern.compile("\\n{2,}"), "\n"); + }}; @Comment("Users, bots, roles and webhooks to ignore") public DiscordIgnoresConfig ignores = new DiscordIgnoresConfig(); diff --git a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java index eeaaa80c..46cfc7b5 100644 --- a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java +++ b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordChatMessageModule.java @@ -52,9 +52,14 @@ import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; +import java.util.regex.Pattern; public class DiscordChatMessageModule extends AbstractModule { + // Filter for ASCII control characters which have no use being displayed, but might be misinterpreted somewhere + // Notably this excludes, 0x09 HT (\t), 0x0A LF (\n), 0x0B VT (\v) and 0x0D CR (\r) (which may be used for text formatting) + private static final Pattern ASCII_CONTROL_FILTER = Pattern.compile("[\\u0000-\\u0008\\u000C\\u000E-\\u001F\\u007F]"); + private final Map sends = new ConcurrentHashMap<>(); public DiscordChatMessageModule(DiscordSRV discordSRV) { @@ -182,6 +187,7 @@ public class DiscordChatMessageModule extends AbstractModule { } Placeholders message = new Placeholders(event.getContent()); + message.replaceAll(ASCII_CONTROL_FILTER, ""); chatConfig.contentRegexFilters.forEach(message::replaceAll); Component messageComponent = DiscordSRVMinecraftRenderer.getWithContext(guild, chatConfig, () -> From 75c76743f83b8dd026b2cdfd6f5cce5ab14e2b74 Mon Sep 17 00:00:00 2001 From: Vankka Date: Thu, 7 Sep 2023 17:42:04 +0300 Subject: [PATCH 2/4] Attempt to add double quotes to PatternSerializer --- .../config/configurate/serializer/PatternSerializer.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/com/discordsrv/common/config/configurate/serializer/PatternSerializer.java b/common/src/main/java/com/discordsrv/common/config/configurate/serializer/PatternSerializer.java index 0f2450a0..c8a35716 100644 --- a/common/src/main/java/com/discordsrv/common/config/configurate/serializer/PatternSerializer.java +++ b/common/src/main/java/com/discordsrv/common/config/configurate/serializer/PatternSerializer.java @@ -18,10 +18,13 @@ package com.discordsrv.common.config.configurate.serializer; +import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.TypeSerializer; +import org.spongepowered.configurate.yaml.ScalarStyle; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; import java.lang.reflect.Type; import java.util.regex.Pattern; @@ -31,11 +34,12 @@ public class PatternSerializer implements TypeSerializer { @Override public Pattern deserialize(Type type, ConfigurationNode node) { String pattern = node != null ? node.getString() : null; - return pattern != null ? Pattern.compile(pattern) : null; + return StringUtils.isNotEmpty(pattern) ? Pattern.compile(pattern) : null; } @Override public void serialize(Type type, @Nullable Pattern obj, ConfigurationNode node) throws SerializationException { - node.set(obj != null ? obj.pattern() : null); + node = node.hint(YamlConfigurationLoader.SCALAR_STYLE, ScalarStyle.DOUBLE_QUOTED); + node.raw(obj != null ? obj.pattern() : null); } } From 09968ba8c29f34ffd3260a2a52a0f18d67d1be73 Mon Sep 17 00:00:00 2001 From: Vankka Date: Sun, 10 Sep 2023 01:01:36 +0300 Subject: [PATCH 3/4] Add enum serializer and remove wacky loading of enum options --- .../BukkitRequiredLinkingListener.java | 5 +- .../discordsrv/common/AbstractDiscordSRV.java | 10 ++-- .../commands/subcommand/ExecuteCommand.java | 6 +-- .../abstraction/ConfigurateConfigManager.java | 17 +++--- .../abstraction/TranslatedConfigManager.java | 2 +- .../serializer/EnumSerializer.java | 54 +++++++++++++++++++ .../config/main/DiscordCommandConfig.java | 18 ++----- .../common/config/main/GroupSyncConfig.java | 34 ++++-------- .../main/channels/JoinMessageConfig.java | 17 ++++-- .../main/linking/LinkedAccountConfig.java | 8 ++- .../linking/ServerRequiredLinkingConfig.java | 9 +++- .../common/groupsync/GroupSyncModule.java | 12 ++--- 12 files changed, 121 insertions(+), 71 deletions(-) create mode 100644 common/src/main/java/com/discordsrv/common/config/configurate/serializer/EnumSerializer.java diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/listener/BukkitRequiredLinkingListener.java b/bukkit/src/main/java/com/discordsrv/bukkit/listener/BukkitRequiredLinkingListener.java index adafe505..86eb1d01 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/listener/BukkitRequiredLinkingListener.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/listener/BukkitRequiredLinkingListener.java @@ -23,6 +23,7 @@ import com.discordsrv.bukkit.config.main.BukkitRequiredLinkingConfig; import com.discordsrv.bukkit.requiredlinking.BukkitRequiredLinkingModule; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.component.util.ComponentUtil; +import com.discordsrv.common.config.main.linking.ServerRequiredLinkingConfig; import com.discordsrv.common.player.IPlayer; import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer; import net.kyori.adventure.text.Component; @@ -141,7 +142,7 @@ public class BukkitRequiredLinkingListener implements Listener { Consumer disallow ) { BukkitRequiredLinkingConfig config = discordSRV.config().requiredLinking; - if (!config.enabled || !config.action.equalsIgnoreCase("KICK") + if (!config.enabled || config.action != ServerRequiredLinkingConfig.Action.KICK || !eventType.equals(config.kick.event) || !priority.name().equals(config.kick.priority)) { return; } @@ -185,7 +186,7 @@ public class BukkitRequiredLinkingListener implements Listener { } BukkitRequiredLinkingConfig config = discordSRV.config().requiredLinking; - if (!config.enabled || !config.action.equalsIgnoreCase("FREEZE")) { + if (!config.enabled || config.action != ServerRequiredLinkingConfig.Action.FREEZE) { return; } diff --git a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java index bbe65d94..513b765d 100644 --- a/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java +++ b/common/src/main/java/com/discordsrv/common/AbstractDiscordSRV.java @@ -673,13 +673,13 @@ public abstract class AbstractDiscordSRV< if (flags.contains(ReloadFlag.LINKED_ACCOUNT_PROVIDER)) { LinkedAccountConfig linkedAccountConfig = config().linkedAccounts; if (linkedAccountConfig != null && linkedAccountConfig.enabled) { - String provider = linkedAccountConfig.provider; + LinkedAccountConfig.Provider provider = linkedAccountConfig.provider; boolean permitMinecraftAuth = connectionConfig().minecraftAuth.allow; - if (provider.equals("auto")) { - provider = permitMinecraftAuth && onlineMode().isOnline() ? "minecraftauth" : "storage"; + if (provider == LinkedAccountConfig.Provider.AUTO) { + provider = permitMinecraftAuth && onlineMode().isOnline() ? LinkedAccountConfig.Provider.MINECRAFTAUTH : LinkedAccountConfig.Provider.STORAGE; } switch (provider) { - case "minecraftauth": + case MINECRAFTAUTH: if (!permitMinecraftAuth) { linkProvider = null; logger().error("minecraftauth.me is disabled in the " + ConnectionConfig.FILE_NAME + ", " @@ -690,7 +690,7 @@ public abstract class AbstractDiscordSRV< linkProvider = new MinecraftAuthenticationLinker(this); logger().info("Using minecraftauth.me for linked accounts"); break; - case "storage": + case STORAGE: linkProvider = new StorageLinker(this); logger().info("Using storage for linked accounts"); break; diff --git a/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java b/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java index ff073210..567e7b71 100644 --- a/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java +++ b/common/src/main/java/com/discordsrv/common/command/discord/commands/subcommand/ExecuteCommand.java @@ -89,7 +89,7 @@ public class ExecuteCommand implements Consumer new ExecutionContext(discordSRV, ih, config.getOutputMode(), ephemeral).run(command)); + .queue(ih -> new ExecutionContext(discordSRV, ih, config.outputMode, ephemeral).run(command)); } @Override @@ -214,7 +214,7 @@ public class ExecuteCommand implements Consumer>) (Object) Enum.class, new EnumSerializer(logger)); builder.register(Color.class, new ColorSerializer()); builder.register(Pattern.class, new PatternSerializer()); builder.register(DiscordMessageEmbed.Builder.class, new DiscordMessageEmbedSerializer(NAMING_SCHEME)); diff --git a/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java b/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java index 37356201..2b4b024c 100644 --- a/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java +++ b/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java @@ -50,7 +50,7 @@ public abstract class TranslatedConfigManager> { + + private final Logger logger; + + public EnumSerializer(Logger logger) { + this.logger = logger; + } + + @SuppressWarnings("unchecked") // Enum generic + @Override + public Enum deserialize(Type type, ConfigurationNode node) throws SerializationException { + Class> theEnum = (Class>) GenericTypeReflector.erase(type).asSubclass(Enum.class); + String configValue = node.getString(); + if (configValue == null) { + return null; + } + configValue = configValue.toLowerCase(Locale.ROOT); + + List values = new ArrayList<>(); + for (Enum constant : theEnum.getEnumConstants()) { + String lower = constant.name().toLowerCase(Locale.ROOT); + if (lower.equals(configValue)) { + return constant; + } + values.add(lower); + } + + logger.error( + "Option \"" + node.key() + "\" " + + "has invalid value: \"" + configValue + "\", " + + "acceptable values: " + String.join(", ", values) + ); + return null; + } + + @Override + public void serialize(Type type, @Nullable Enum obj, ConfigurationNode node) throws SerializationException { + node.raw(obj != null ? obj.name().toLowerCase(Locale.ROOT) : null); + } +} diff --git a/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java b/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java index 230e9319..d9006898 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java @@ -7,7 +7,6 @@ import org.spongepowered.configurate.objectmapping.meta.Comment; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Locale; @ConfigSerializable public class DiscordCommandConfig { @@ -36,20 +35,9 @@ public class DiscordCommandConfig { + "- markdown: Regular Discord markdown\n" + "- ansi: A colored ansi code block\n" + "- plain: Plain text\n" - + "- codeblock: Plain code block\n" + + "- code_block: Plain code block\n" + "- off: No command output") - public String outputMode = "markdown"; - - public OutputMode getOutputMode() { - switch (outputMode.toLowerCase(Locale.ROOT)) { - default: - case "markdown": return OutputMode.MARKDOWN; - case "ansi": return OutputMode.ANSI; - case "plain": return OutputMode.PLAIN; - case "codeblock": return OutputMode.PLAIN_BLOCK; - case "off": return OutputMode.OFF; - } - } + public OutputMode outputMode = OutputMode.MARKDOWN; @Comment("At least one condition has to match to allow execution") public List filters = new ArrayList<>(); @@ -66,7 +54,7 @@ public class DiscordCommandConfig { MARKDOWN, ANSI, PLAIN, - PLAIN_BLOCK, + CODEBLOCK, OFF } } diff --git a/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java b/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java index 83e3d276..ce55a0ff 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java @@ -42,16 +42,8 @@ public class GroupSyncConfig { public Long roleId = 0L; @Comment("The direction this group-role pair will synchronize in.\n" - + "Valid options: BIDIRECTIONAL, MINECRAFT_TO_DISCORD, DISCORD_TO_MINECRAFT") - public String direction = GroupSyncDirection.BIDIRECTIONAL.name(); - - public GroupSyncDirection direction() { - try { - return GroupSyncDirection.valueOf(direction); - } catch (IllegalArgumentException ignored) { - return null; - } - } + + "Valid options: bidirectional, minecraft_to_discord, discord_to_minecraft") + public GroupSyncDirection direction = GroupSyncDirection.BIDIRECTIONAL; @Comment("Timed resynchronization.\n" + "This is required if you're not using LuckPerms and want to use Minecraft to Discord synchronization") @@ -68,16 +60,8 @@ public class GroupSyncConfig { } @Comment("Decides which side takes priority when using timed synchronization or the resync command\n" - + "Valid options: MINECRAFT, DISCORD") - public String tieBreaker = GroupSyncSide.MINECRAFT.name(); - - public GroupSyncSide tieBreaker() { - try { - return GroupSyncSide.valueOf(tieBreaker); - } catch (IllegalArgumentException ignored) { - return null; - } - } + + "Valid options: minecraft, discord") + public GroupSyncSide tieBreaker = GroupSyncSide.MINECRAFT; @Comment("The LuckPerms \"server\" context value, used when adding, removing and checking the groups of players.\n" + "Make this blank (\"\") to use the current server's value, or \"global\" to not use the context") @@ -90,7 +74,7 @@ public class GroupSyncConfig { public boolean validate(DiscordSRV discordSRV) { String label = "Group synchronization (" + groupName + ":" + Long.toUnsignedString(roleId) + ")"; boolean invalidTieBreaker, invalidDirection = false; - if ((invalidTieBreaker = (tieBreaker() == null)) || (invalidDirection = (direction == null))) { + if ((invalidTieBreaker = (tieBreaker == null)) || (invalidDirection = (direction == null))) { if (invalidTieBreaker) { discordSRV.logger().error(label + " has invalid tie-breaker: " + tieBreaker + ", should be one of " + Arrays.toString(GroupSyncSide.values())); @@ -100,10 +84,10 @@ public class GroupSyncConfig { + ", should be one of " + Arrays.toString(GroupSyncDirection.values())); } return false; - } else if (direction() != GroupSyncDirection.BIDIRECTIONAL) { + } else if (direction != GroupSyncDirection.BIDIRECTIONAL) { boolean minecraft; - if ((direction() == GroupSyncDirection.MINECRAFT_TO_DISCORD) != (minecraft = (tieBreaker() == GroupSyncSide.MINECRAFT))) { - String opposite = (minecraft ? GroupSyncSide.DISCORD : GroupSyncSide.MINECRAFT).name(); + if ((direction == GroupSyncDirection.MINECRAFT_TO_DISCORD) != (minecraft = (tieBreaker == GroupSyncSide.MINECRAFT))) { + GroupSyncSide opposite = (minecraft ? GroupSyncSide.DISCORD : GroupSyncSide.MINECRAFT); discordSRV.logger().warning(label + " with direction " + direction + " with tie-breaker " + tieBreaker + " (should be " + opposite + ")"); @@ -116,7 +100,7 @@ public class GroupSyncConfig { @Override public String toString() { String arrow; - switch (direction()) { + switch (direction) { default: case BIDIRECTIONAL: arrow = "<->"; diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java index 59cc76c9..ac49a7da 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java @@ -68,8 +68,17 @@ public class JoinMessageConfig implements IMessageConfig { @ConfigSerializable public static class FirstJoin implements IMessageConfig { - @Comment("How first join should behave:\n- enabled (uses the format below)\n- disabled (first join messages are disabled)\n- use_regular (uses the format above)") - public String firstJoinPreference = "enabled"; + @Comment("How first join should behave:\n" + + "- enabled (uses the format below)\n" + + "- disabled (first join messages are disabled)\n" + + "- use_regular (uses the format above)") + public Preference preference = Preference.ENABLED; + + public enum Preference { + ENABLED, + DISABLED, + USE_REGULAR + } @Untranslated(Untranslated.Type.VALUE) public SendableDiscordMessage.Builder format = SendableDiscordMessage.builder() @@ -81,12 +90,12 @@ public class JoinMessageConfig implements IMessageConfig { ); public boolean isRegular() { - return "use_regular".equalsIgnoreCase(firstJoinPreference); + return preference == Preference.USE_REGULAR; } @Override public boolean enabled() { - return "enabled".equalsIgnoreCase(firstJoinPreference); + return preference == Preference.ENABLED; } @Override diff --git a/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java b/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java index 1fee60f9..943f1e90 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java @@ -33,5 +33,11 @@ public class LinkedAccountConfig { + " - auto: Uses \"minecraftauth\" if the " + ConnectionConfig.FILE_NAME + " permits it and the server is in online mode, otherwise \"storage\"\n" + " - minecraftauth: Uses minecraftauth.me as the linked account provider\n" + " - storage: Use the configured database for linked accounts") - public String provider = "auto"; + public Provider provider = Provider.AUTO; + + public enum Provider { + AUTO, + MINECRAFTAUTH, + STORAGE + } } diff --git a/common/src/main/java/com/discordsrv/common/config/main/linking/ServerRequiredLinkingConfig.java b/common/src/main/java/com/discordsrv/common/config/main/linking/ServerRequiredLinkingConfig.java index cb19f3e4..19e460ea 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/linking/ServerRequiredLinkingConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/linking/ServerRequiredLinkingConfig.java @@ -26,8 +26,13 @@ import org.spongepowered.configurate.objectmapping.meta.Setting; @ConfigSerializable public class ServerRequiredLinkingConfig extends RequiredLinkingConfig { - @Comment("How the player should be blocked from joining the server.\nAvailable options: KICK, FREEZE") - public String action = "KICK"; + @Comment("How the player should be blocked from joining the server.\nAvailable options: kick, freeze") + public Action action = Action.KICK; + + public enum Action { + KICK, + FREEZE + } @Setting(nodeFromParent = true) @Order(10) diff --git a/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java b/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java index 8e8bf4bd..aaa1f145 100644 --- a/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java +++ b/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java @@ -149,8 +149,8 @@ public class GroupSyncModule extends AbstractModule { for (Map.Entry> entry : pairs.entrySet()) { GroupSyncConfig.PairConfig pair = entry.getKey(); builder.append("\n- ").append(pair) - .append(" (tie-breaker: ").append(pair.tieBreaker()) - .append(", direction: ").append(pair.direction()) + .append(" (tie-breaker: ").append(pair.tieBreaker) + .append(", direction: ").append(pair.direction) .append(", server context: ").append(pair.serverContext).append(")"); if (entry.getValue() != null) { builder.append(" [Timed]"); @@ -343,8 +343,8 @@ public class GroupSyncModule extends AbstractModule { return; } - GroupSyncSide side = pair.tieBreaker(); - GroupSyncDirection direction = pair.direction(); + GroupSyncSide side = pair.tieBreaker; + GroupSyncDirection direction = pair.direction; CompletableFuture future; GroupSyncResult result; if (hasRole) { @@ -473,7 +473,7 @@ public class GroupSyncModule extends AbstractModule { Map> futures = new LinkedHashMap<>(); for (GroupSyncConfig.PairConfig pair : pairs) { - GroupSyncDirection direction = pair.direction(); + GroupSyncDirection direction = pair.direction; if (direction == GroupSyncDirection.MINECRAFT_TO_DISCORD) { // Not going Discord -> Minecraft futures.put(pair, CompletableFuture.completedFuture(GroupSyncResult.WRONG_DIRECTION)); @@ -543,7 +543,7 @@ public class GroupSyncModule extends AbstractModule { PermissionDataProvider.Groups permissionProvider = getPermissionProvider(); Map> futures = new LinkedHashMap<>(); for (GroupSyncConfig.PairConfig pair : pairs) { - GroupSyncDirection direction = pair.direction(); + GroupSyncDirection direction = pair.direction; if (direction == GroupSyncDirection.DISCORD_TO_MINECRAFT) { // Not going Minecraft -> Discord futures.put(pair, CompletableFuture.completedFuture(GroupSyncResult.WRONG_DIRECTION)); From cfcb1bdc26d255a2109f7e5733a26d81f9d7fba4 Mon Sep 17 00:00:00 2001 From: Vankka Date: Sun, 10 Sep 2023 02:18:59 +0300 Subject: [PATCH 4/4] Add constants annotation for defining stuff that shouldn't be translated --- .../common/channel/ChannelConfigHelper.java | 4 +- .../configurate/annotation/Constants.java | 25 +++++ .../manager/ConnectionConfigManager.java | 10 +- .../manager/MainConfigManager.java | 10 +- .../abstraction/ConfigurateConfigManager.java | 99 ++++++++++++++++--- .../abstraction/TranslatedConfigManager.java | 9 +- .../documentation/DocumentationURLs.java | 7 +- .../config/main/AvatarProviderConfig.java | 2 +- .../common/config/main/DebugConfig.java | 4 +- .../config/main/DiscordCommandConfig.java | 15 +-- .../common/config/main/GameCommandConfig.java | 10 +- .../common/config/main/GroupSyncConfig.java | 12 ++- .../common/config/main/MainConfig.java | 22 +++-- .../DiscordToMinecraftChatConfig.java | 5 +- .../main/channels/JoinMessageConfig.java | 8 +- .../main/generic/DestinationConfig.java | 5 +- .../main/linking/LinkedAccountConfig.java | 8 +- .../config/DiscordSRVTranslation.java | 7 +- .../config/TranslationConfigManagerProxy.java | 5 +- 19 files changed, 195 insertions(+), 72 deletions(-) create mode 100644 common/src/main/java/com/discordsrv/common/config/configurate/annotation/Constants.java diff --git a/common/src/main/java/com/discordsrv/common/channel/ChannelConfigHelper.java b/common/src/main/java/com/discordsrv/common/channel/ChannelConfigHelper.java index f8530790..f8b20870 100644 --- a/common/src/main/java/com/discordsrv/common/channel/ChannelConfigHelper.java +++ b/common/src/main/java/com/discordsrv/common/channel/ChannelConfigHelper.java @@ -85,8 +85,8 @@ public class ChannelConfigHelper { throws SerializationException { MainConfigManager configManager = discordSRV.configManager(); - CommentedConfigurationNode defaultNode = CommentedConfigurationNode.root(configManager.nodeOptions()); - CommentedConfigurationNode target = CommentedConfigurationNode.root(configManager.nodeOptions()); + CommentedConfigurationNode defaultNode = CommentedConfigurationNode.root(configManager.nodeOptions(true)); + CommentedConfigurationNode target = CommentedConfigurationNode.root(configManager.nodeOptions(true)); configManager.objectMapper() .get((Class) defaultConfig.getClass()) diff --git a/common/src/main/java/com/discordsrv/common/config/configurate/annotation/Constants.java b/common/src/main/java/com/discordsrv/common/config/configurate/annotation/Constants.java new file mode 100644 index 00000000..79106ffe --- /dev/null +++ b/common/src/main/java/com/discordsrv/common/config/configurate/annotation/Constants.java @@ -0,0 +1,25 @@ +package com.discordsrv.common.config.configurate.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A config annotation that should be used to define config (comment) parts that should not be translated, + * remaining the same for all languages (for example, config option names referenced in comments, urls, etc.). + *

+ * Replacements are {@code %i} where {@code i} start counting up from {@code 1}. + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface Constants { + + String[] value(); + + /** + * Needs to go after {@link org.spongepowered.configurate.objectmapping.meta.Comment}. + */ + @Retention(RetentionPolicy.RUNTIME) + @interface Comment { + + String[] value(); + } +} diff --git a/common/src/main/java/com/discordsrv/common/config/configurate/manager/ConnectionConfigManager.java b/common/src/main/java/com/discordsrv/common/config/configurate/manager/ConnectionConfigManager.java index 7d1c51e3..7c21fb01 100644 --- a/common/src/main/java/com/discordsrv/common/config/configurate/manager/ConnectionConfigManager.java +++ b/common/src/main/java/com/discordsrv/common/config/configurate/manager/ConnectionConfigManager.java @@ -19,13 +19,12 @@ package com.discordsrv.common.config.configurate.manager; import com.discordsrv.common.DiscordSRV; +import com.discordsrv.common.config.configurate.manager.abstraction.TranslatedConfigManager; import com.discordsrv.common.config.configurate.manager.loader.YamlConfigLoaderProvider; import com.discordsrv.common.config.connection.ConnectionConfig; -import com.discordsrv.common.config.configurate.manager.abstraction.TranslatedConfigManager; -import org.spongepowered.configurate.ConfigurationOptions; -import org.spongepowered.configurate.objectmapping.ObjectMapper; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; +import java.lang.reflect.Field; import java.nio.file.Path; public abstract class ConnectionConfigManager @@ -41,9 +40,8 @@ public abstract class ConnectionConfigManager } @Override - public ConfigurationOptions configurationOptions(ObjectMapper.Factory objectMapper) { - return super.configurationOptions(objectMapper) - .header(ConnectionConfig.HEADER); + protected Field headerField() throws ReflectiveOperationException { + return ConnectionConfig.class.getField("HEADER"); } @Override diff --git a/common/src/main/java/com/discordsrv/common/config/configurate/manager/MainConfigManager.java b/common/src/main/java/com/discordsrv/common/config/configurate/manager/MainConfigManager.java index a6a0b155..d9e07673 100644 --- a/common/src/main/java/com/discordsrv/common/config/configurate/manager/MainConfigManager.java +++ b/common/src/main/java/com/discordsrv/common/config/configurate/manager/MainConfigManager.java @@ -19,13 +19,12 @@ package com.discordsrv.common.config.configurate.manager; import com.discordsrv.common.DiscordSRV; +import com.discordsrv.common.config.configurate.manager.abstraction.TranslatedConfigManager; import com.discordsrv.common.config.configurate.manager.loader.YamlConfigLoaderProvider; import com.discordsrv.common.config.main.MainConfig; -import com.discordsrv.common.config.configurate.manager.abstraction.TranslatedConfigManager; -import org.spongepowered.configurate.ConfigurationOptions; -import org.spongepowered.configurate.objectmapping.ObjectMapper; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; +import java.lang.reflect.Field; import java.nio.file.Path; public abstract class MainConfigManager @@ -41,9 +40,8 @@ public abstract class MainConfigManager } @Override - public ConfigurationOptions configurationOptions(ObjectMapper.Factory objectMapper) { - return super.configurationOptions(objectMapper) - .header(MainConfig.HEADER); + protected Field headerField() throws ReflectiveOperationException { + return MainConfig.class.getField("HEADER"); } @Override diff --git a/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/ConfigurateConfigManager.java b/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/ConfigurateConfigManager.java index 4e797c1a..99c460cc 100644 --- a/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/ConfigurateConfigManager.java +++ b/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/ConfigurateConfigManager.java @@ -22,6 +22,7 @@ import com.discordsrv.api.color.Color; import com.discordsrv.api.discord.entity.message.DiscordMessageEmbed; import com.discordsrv.api.discord.entity.message.SendableDiscordMessage; import com.discordsrv.common.DiscordSRV; +import com.discordsrv.common.config.configurate.annotation.Constants; import com.discordsrv.common.config.configurate.annotation.DefaultOnly; import com.discordsrv.common.config.configurate.annotation.Order; import com.discordsrv.common.config.configurate.fielddiscoverer.OrderedFieldDiscovererProxy; @@ -48,6 +49,7 @@ import org.spongepowered.configurate.util.NamingSchemes; import org.spongepowered.configurate.yaml.ScalarStyle; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; +import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.file.Path; import java.util.Arrays; @@ -82,7 +84,7 @@ public abstract class ConfigurateConfigManager { @@ -152,16 +190,16 @@ public abstract class ConfigurateConfigManager> fieldOrder = Comparator.comparingInt(data -> { Order order = data.annotations().getAnnotation(Order.class); return order != null ? order.value() : 0; @@ -170,11 +208,50 @@ public abstract class ConfigurateConfigManager((FieldDiscoverer) FieldDiscoverer.emptyConstructorObject(), fieldOrder)) - .addDiscoverer(new OrderedFieldDiscovererProxy<>((FieldDiscoverer) FieldDiscoverer.record(), fieldOrder)); + .addDiscoverer(new OrderedFieldDiscovererProxy<>((FieldDiscoverer) FieldDiscoverer.record(), fieldOrder)) + .addProcessor(Constants.Comment.class, (data, fieldType) -> (value, destination) -> { + // This needs to go before comment processing. + if (commentSubstitutions && destination instanceof CommentedConfigurationNode) { + String comment = ((CommentedConfigurationNode) destination).comment(); + if (comment != null) { + ((CommentedConfigurationNode) destination).comment( + doSubstitution(comment, data.value()) + ); + } + } + }) + .addProcessor(Constants.class, (data, fieldType) -> (value, destination) -> { + if (data == null || data.value().length == 0) { + return; + } + + String optionValue = destination.getString(); + if (optionValue == null) { + return; + } + + try { + destination.set( + doSubstitution( + destination.getString(), + data.value() + ) + ); + } catch (SerializationException e) { + throw new RuntimeException(e); + } + }); } - public ObjectMapper.Factory.Builder objectMapperBuilder() { - return commonObjectMapperBuilder() + private static String doSubstitution(String input, String[] values) { + for (int i = 0; i < values.length; i++) { + input = input.replace("%" + (i + 1), values[i]); + } + return input; + } + + public ObjectMapper.Factory.Builder objectMapperBuilder(boolean commentSubstitutions) { + return commonObjectMapperBuilder(commentSubstitutions) .addProcessor(Comment.class, (data, fieldType) -> { Processor processor = Processor.comments().make(data, fieldType); @@ -192,7 +269,7 @@ public abstract class ConfigurateConfigManager (value1, destination) -> { String[] children = data.value(); boolean whitelist = data.whitelist(); diff --git a/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java b/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java index 2b4b024c..a505005a 100644 --- a/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java +++ b/common/src/main/java/com/discordsrv/common/config/configurate/manager/abstraction/TranslatedConfigManager.java @@ -25,9 +25,7 @@ import org.jetbrains.annotations.Nullable; import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; import org.spongepowered.configurate.ConfigurationNode; -import org.spongepowered.configurate.ConfigurationOptions; import org.spongepowered.configurate.loader.AbstractConfigurationLoader; -import org.spongepowered.configurate.objectmapping.ObjectMapper; import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; @@ -66,12 +64,11 @@ public abstract class TranslatedConfigManager> additionalLevels = new HashMap<>(); } diff --git a/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java b/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java index d9006898..a67fdb2b 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/DiscordCommandConfig.java @@ -1,5 +1,6 @@ package com.discordsrv.common.config.main; +import com.discordsrv.common.config.configurate.annotation.Constants; import com.discordsrv.common.config.main.generic.GameCommandFilterConfig; import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Comment; @@ -32,11 +33,12 @@ public class DiscordCommandConfig { public boolean ephemeral = true; @Comment("The mode for the command output, available options are:\n" - + "- markdown: Regular Discord markdown\n" - + "- ansi: A colored ansi code block\n" - + "- plain: Plain text\n" - + "- code_block: Plain code block\n" - + "- off: No command output") + + "- %1: Regular Discord markdown\n" + + "- %2: A colored ansi code block\n" + + "- %3: Plain text\n" + + "- %4: Plain code block\n" + + "- %5: No command output") + @Constants.Comment({"markdown", "ansi", "plain", "code_block", "off"}) public OutputMode outputMode = OutputMode.MARKDOWN; @Comment("At least one condition has to match to allow execution") @@ -46,7 +48,8 @@ public class DiscordCommandConfig { "Suggestions go through the server's main thread (on servers with a main thread) to ensure compatability.") public boolean suggest = true; - @Comment("If suggestions should be filtered based on the \"filters\" option") + @Comment("If suggestions should be filtered based on the \"%1\" option") + @Constants.Comment("filters") public boolean filterSuggestions = true; } diff --git a/common/src/main/java/com/discordsrv/common/config/main/GameCommandConfig.java b/common/src/main/java/com/discordsrv/common/config/main/GameCommandConfig.java index 9446f0e8..0d84c051 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/GameCommandConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/GameCommandConfig.java @@ -18,18 +18,22 @@ package com.discordsrv.common.config.main; +import com.discordsrv.common.config.configurate.annotation.Constants; import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Comment; @ConfigSerializable public class GameCommandConfig { - @Comment("If the /discord command should be set by DiscordSRV") + @Comment("If the %1 command should be set by DiscordSRV") + @Constants.Comment("/discord") public boolean useDiscordCommand = true; - @Comment("If /link should be used as a alias for /discord link") + @Comment("If %1 should be used as a alias for %2") + @Constants.Comment({"/link", "/discord link"}) public boolean useLinkAlias = false; - @Comment("The Discord command response format (/discord), player placeholders may be used") + @Comment("The Discord command response format (%1), player placeholders may be used") + @Constants.Comment("/discord") public String discordFormat = "[click:open_url:%discord_invite%][color:aqua][bold:on]Click here [color][bold][color:green]to join our Discord server!"; } diff --git a/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java b/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java index ce55a0ff..20647fb3 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/GroupSyncConfig.java @@ -19,6 +19,7 @@ package com.discordsrv.common.config.main; import com.discordsrv.common.DiscordSRV; +import com.discordsrv.common.config.configurate.annotation.Constants; import com.discordsrv.common.groupsync.enums.GroupSyncDirection; import com.discordsrv.common.groupsync.enums.GroupSyncSide; import org.spongepowered.configurate.objectmapping.ConfigSerializable; @@ -42,7 +43,8 @@ public class GroupSyncConfig { public Long roleId = 0L; @Comment("The direction this group-role pair will synchronize in.\n" - + "Valid options: bidirectional, minecraft_to_discord, discord_to_minecraft") + + "Valid options: %1, %2, %3") + @Constants.Comment({"bidirectional", "minecraft_to_discord", "discord_to_minecraft"}) public GroupSyncDirection direction = GroupSyncDirection.BIDIRECTIONAL; @Comment("Timed resynchronization.\n" @@ -60,11 +62,13 @@ public class GroupSyncConfig { } @Comment("Decides which side takes priority when using timed synchronization or the resync command\n" - + "Valid options: minecraft, discord") + + "Valid options: %1, %2") + @Constants.Comment({"minecraft", "discord"}) public GroupSyncSide tieBreaker = GroupSyncSide.MINECRAFT; - @Comment("The LuckPerms \"server\" context value, used when adding, removing and checking the groups of players.\n" - + "Make this blank (\"\") to use the current server's value, or \"global\" to not use the context") + @Comment("The LuckPerms \"%1\" context value, used when adding, removing and checking the groups of players.\n" + + "Make this blank (\"\") to use the current server's value, or \"%2\" to not use the context") + @Constants.Comment({"server", "global"}) public String serverContext = "global"; public boolean isTheSameAs(PairConfig config) { diff --git a/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java b/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java index 1ddb45bf..096dbe69 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java @@ -20,9 +20,11 @@ package com.discordsrv.common.config.main; import com.discordsrv.api.channel.GameChannel; import com.discordsrv.common.config.Config; +import com.discordsrv.common.config.configurate.annotation.Constants; import com.discordsrv.common.config.configurate.annotation.DefaultOnly; import com.discordsrv.common.config.configurate.annotation.Order; import com.discordsrv.common.config.connection.ConnectionConfig; +import com.discordsrv.common.config.documentation.DocumentationURLs; import com.discordsrv.common.config.main.channels.base.BaseChannelConfig; import com.discordsrv.common.config.main.channels.base.ChannelConfig; import com.discordsrv.common.config.main.linking.LinkedAccountConfig; @@ -38,12 +40,13 @@ public abstract class MainConfig implements Config { public static final String FILE_NAME = "config.yaml"; + @Constants({DocumentationURLs.ELT_FORMAT, DocumentationURLs.DISCORD_MARKDOWN}) public static final String HEADER = String.join("\n", Arrays.asList( "Welcome to the DiscordSRV configuration file", "", "Looking for the \"BotToken\" option? It has been moved into the " + ConnectionConfig.FILE_NAME, - "Need help with the format for Minecraft messages? https://github.com/Vankka/EnhancedLegacyText/wiki/Format", - "Need help with Discord markdown? https://support.discord.com/hc/en-us/articles/210298617" + "Need help with the format for Minecraft messages? %1", + "Need help with Discord markdown? %2" )); @Override @@ -62,10 +65,11 @@ public abstract class MainConfig implements Config { @DefaultOnly(ChannelConfig.DEFAULT_KEY) @Comment("Channels configuration\n\n" + "This is where everything related to in-game chat channels is configured.\n" - + "The key of this option is the in-game channel name (the default keys are \"global\" and \"default\")\n" - + "channel-ids and threads can be configured for all channels except \"default\"\n" - + "\"default\" is a special section which has the default values for all channels unless they are specified (overridden) under the channel's own section\n" - + "So if you don't specify a certain option under a channel's own section, the option will take its value from the \"default\" section") + + "The key of this option is the in-game channel name (the default keys are \"%1\" and \"%2\")\n" + + "%3 and %4 can be configured for all channels except \"%2\"\n" + + "\"%2\" is a special section which has the default values for all channels unless they are specified (overridden) under the channel's own section\n" + + "So if you don't specify a certain option under a channel's own section, the option will take its value from the \"%2\" section") + @Constants.Comment({GameChannel.DEFAULT_NAME, ChannelConfig.DEFAULT_KEY, "channel-ids", "threads"}) public Map channels = new LinkedHashMap() {{ put(GameChannel.DEFAULT_NAME, createDefaultChannel()); put(ChannelConfig.DEFAULT_KEY, createDefaultBaseChannel()); @@ -84,13 +88,15 @@ public abstract class MainConfig implements Config { @Comment("Discord command configuration") public DiscordCommandConfig discordCommand = new DiscordCommandConfig(); - @Comment("Configuration for the %discord_invite% placeholder. The below options will be attempted in the order they are in") + @Comment("Configuration for the %1 placeholder. The below options will be attempted in the order they are in") + @Constants.Comment("%discord_invite%") public DiscordInviteConfig invite = new DiscordInviteConfig(); public MessagesMainConfig messages = new MessagesMainConfig(); @Order(10) // To go below required linking config @ 5 - @Comment("Configuration for the %player_avatar_url% placeholder") + @Comment("Configuration for the %1 placeholder") + @Constants.Comment("%player_avatar_url%") public AvatarProviderConfig avatarProvider = new AvatarProviderConfig(); public abstract PluginIntegrationConfig integrations(); diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java index d49cf39d..b9ff43bb 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/DiscordToMinecraftChatConfig.java @@ -18,6 +18,7 @@ package com.discordsrv.common.config.main.channels; +import com.discordsrv.common.config.configurate.annotation.Constants; import com.discordsrv.common.config.configurate.annotation.Untranslated; import com.discordsrv.common.config.main.generic.DiscordIgnoresConfig; import org.spongepowered.configurate.objectmapping.ConfigSerializable; @@ -33,19 +34,15 @@ public class DiscordToMinecraftChatConfig { public boolean enabled = true; @Comment("The Discord to Minecraft message format for regular users and bots") - @Untranslated(Untranslated.Type.VALUE) public String format = "[[color:#5865F2]Discord[color]] [hover:show_text:Username: @%user_tag%\nRoles: %user_roles:', '|text:'[color:gray][italics:on]None[color][italics]'%]%user_color%%user_effective_server_name%[color][hover]%message_reply% » %message%%message_attachments%"; @Comment("The Discord to Minecraft message format for webhook messages (if enabled)") - @Untranslated(Untranslated.Type.VALUE) public String webhookFormat = "[[color:#5865F2]Discord[color]] [hover:show_text:Bot message]%user_effective_name%[hover] » %message%%message_attachments%"; @Comment("Format for a single attachment in the %message_attachments% placeholder") - @Untranslated(Untranslated.Type.VALUE) public String attachmentFormat = " [hover:show_text:Open %file_name% in browser][click:open_url:%file_url%][color:green][[color:white]%file_name%[color:green]][color][click][hover]"; @Comment("Format for the %message_reply% placeholder, when the message is a reply to another message") - @Untranslated(Untranslated.Type.VALUE) public String replyFormat = " [hover:show_text:%message%][click:open_url:%message_jump_url%]replying to %user_color|text:''%%user_effective_server_name|user_effective_name%[color][click][hover]"; // TODO: more info on regex pairs (String#replaceAll) diff --git a/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java b/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java index ac49a7da..e7ecc044 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/channels/JoinMessageConfig.java @@ -21,6 +21,7 @@ package com.discordsrv.common.config.main.channels; import com.discordsrv.api.discord.entity.message.DiscordMessageEmbed; import com.discordsrv.api.discord.entity.message.SendableDiscordMessage; import com.discordsrv.api.event.events.message.receive.game.JoinMessageReceiveEvent; +import com.discordsrv.common.config.configurate.annotation.Constants; import com.discordsrv.common.config.configurate.annotation.Untranslated; import com.discordsrv.common.config.main.generic.IMessageConfig; import org.jetbrains.annotations.Nullable; @@ -69,9 +70,10 @@ public class JoinMessageConfig implements IMessageConfig { public static class FirstJoin implements IMessageConfig { @Comment("How first join should behave:\n" - + "- enabled (uses the format below)\n" - + "- disabled (first join messages are disabled)\n" - + "- use_regular (uses the format above)") + + "- %1 (uses the format below)\n" + + "- %2 (first join messages are disabled)\n" + + "- %3 (uses the format above)") + @Constants.Comment({"enabled", "disabled", "use_regular"}) public Preference preference = Preference.ENABLED; public enum Preference { diff --git a/common/src/main/java/com/discordsrv/common/config/main/generic/DestinationConfig.java b/common/src/main/java/com/discordsrv/common/config/main/generic/DestinationConfig.java index 76474fb8..8f3b3f90 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/generic/DestinationConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/generic/DestinationConfig.java @@ -1,5 +1,6 @@ package com.discordsrv.common.config.main.generic; +import com.discordsrv.common.config.configurate.annotation.Constants; import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Comment; import org.spongepowered.configurate.objectmapping.meta.Setting; @@ -15,8 +16,8 @@ public class DestinationConfig { @Comment("The channels this in-game channel will forward to in Discord") public List channelIds = new ArrayList<>(); - @Setting("threads") - @Comment("The threads that this in-game channel will forward to in Discord (this can be used instead of or with the channel-ids option)") + @Comment("The threads that this in-game channel will forward to in Discord (this can be used instead of or with the %1 option)") + @Constants.Comment("channel-ids") public List threads = new ArrayList<>(Collections.singletonList(new ThreadConfig())); } diff --git a/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java b/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java index 943f1e90..4481376d 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/linking/LinkedAccountConfig.java @@ -18,6 +18,7 @@ package com.discordsrv.common.config.main.linking; +import com.discordsrv.common.config.configurate.annotation.Constants; import com.discordsrv.common.config.connection.ConnectionConfig; import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Comment; @@ -30,9 +31,10 @@ public class LinkedAccountConfig { @Comment("The linked account provider\n" + "\n" - + " - auto: Uses \"minecraftauth\" if the " + ConnectionConfig.FILE_NAME + " permits it and the server is in online mode, otherwise \"storage\"\n" - + " - minecraftauth: Uses minecraftauth.me as the linked account provider\n" - + " - storage: Use the configured database for linked accounts") + + " - auto: Uses \"%3\" if the %1 permits it and the server is in online mode, otherwise \"%4\"\n" + + " - %3: Uses %2 as the linked account provider\n" + + " - %4: Use the configured database for linked accounts") + @Constants.Comment({ConnectionConfig.FILE_NAME, "minecraftauth.me", "minecraftauth", "storage"}) public Provider provider = Provider.AUTO; public enum Provider { diff --git a/i18n/src/main/java/com/discordsrv/config/DiscordSRVTranslation.java b/i18n/src/main/java/com/discordsrv/config/DiscordSRVTranslation.java index d662a452..1a1dfd6a 100644 --- a/i18n/src/main/java/com/discordsrv/config/DiscordSRVTranslation.java +++ b/i18n/src/main/java/com/discordsrv/config/DiscordSRVTranslation.java @@ -24,6 +24,7 @@ import com.discordsrv.common.config.Config; import com.discordsrv.common.config.configurate.annotation.Untranslated; import com.discordsrv.common.config.configurate.manager.abstraction.ConfigurateConfigManager; import com.discordsrv.common.config.configurate.manager.abstraction.TranslatedConfigManager; +import com.discordsrv.common.logging.backend.impl.JavaLoggerImpl; import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; import org.spongepowered.configurate.ConfigurationNode; @@ -82,16 +83,16 @@ public final class DiscordSRVTranslation { String fileIdentifier = config.getFileName(); ConfigurationNode commentSection = node.node(fileIdentifier + "_comments"); - String header = configManager.nodeOptions().header(); + String header = configManager.nodeOptions(false).header(); if (header != null) { commentSection.node("$header").set(header); } - ObjectMapper.Factory mapperFactory = configManager.objectMapperBuilder() + ObjectMapper.Factory mapperFactory = configManager.objectMapperBuilder(false) .addProcessor(Untranslated.class, untranslatedProcessorFactory) .build(); - TranslationConfigManagerProxy configManagerProxy = new TranslationConfigManagerProxy<>(DATA_DIRECTORY, mapperFactory, configManager); + TranslationConfigManagerProxy configManagerProxy = new TranslationConfigManagerProxy<>(DATA_DIRECTORY, JavaLoggerImpl.getRoot(), mapperFactory, configManager); CommentedConfigurationNode configurationNode = configManagerProxy.getDefaultNode(mapperFactory); convertCommentsToOptions(configurationNode, commentSection); diff --git a/i18n/src/main/java/com/discordsrv/config/TranslationConfigManagerProxy.java b/i18n/src/main/java/com/discordsrv/config/TranslationConfigManagerProxy.java index c740238c..b039a216 100644 --- a/i18n/src/main/java/com/discordsrv/config/TranslationConfigManagerProxy.java +++ b/i18n/src/main/java/com/discordsrv/config/TranslationConfigManagerProxy.java @@ -20,6 +20,7 @@ package com.discordsrv.config; import com.discordsrv.common.config.configurate.manager.abstraction.ConfigurateConfigManager; import com.discordsrv.common.config.configurate.manager.loader.YamlConfigLoaderProvider; +import com.discordsrv.common.logging.Logger; import org.spongepowered.configurate.objectmapping.ObjectMapper; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; @@ -32,8 +33,8 @@ public class TranslationConfigManagerProxy private final ObjectMapper.Factory objectMapper; private final ConfigurateConfigManager configManager; - public TranslationConfigManagerProxy(Path dataDirectory, ObjectMapper.Factory objectMapper, ConfigurateConfigManager configManager) { - super(dataDirectory); + public TranslationConfigManagerProxy(Path dataDirectory, Logger logger, ObjectMapper.Factory objectMapper, ConfigurateConfigManager configManager) { + super(dataDirectory, logger); this.objectMapper = objectMapper; this.configManager = configManager; }