From 6063375180d99f07ed1344da9520bd034b9a3b48 Mon Sep 17 00:00:00 2001 From: Adrian3d04 Date: Fri, 5 Aug 2022 23:46:51 +0000 Subject: [PATCH] feat: Migrate to configurate --- common/build.gradle.kts | 5 +- .../authmevelocity/common/Constants.java | 6 + .../authmevelocity/common/LibsManager.java | 53 ++++---- .../configuration/ConfigurationContainer.java | 61 +++++++++ .../common/configuration/Loader.java | 85 ++++-------- .../configuration/ProxyConfiguration.java | 123 ++++++++++-------- paper/build.gradle.kts | 1 - velocity/build.gradle.kts | 1 - .../velocity/AuthMeVelocityPlugin.java | 19 +-- .../velocity/commands/AuthmeCommand.java | 18 +-- .../velocity/listener/ConnectListener.java | 4 +- .../listener/PluginMessageListener.java | 4 +- .../velocity/listener/ProxyListener.java | 6 +- 13 files changed, 218 insertions(+), 168 deletions(-) create mode 100644 common/src/main/java/me/adrianed/authmevelocity/common/Constants.java create mode 100644 common/src/main/java/me/adrianed/authmevelocity/common/configuration/ConfigurationContainer.java diff --git a/common/build.gradle.kts b/common/build.gradle.kts index def6d9e..2b07cc9 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -7,8 +7,7 @@ repositories { } dependencies { - compileOnly("space.arim.dazzleconf:dazzleconf-core:1.3.0-M1") - compileOnly("space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.3.0-M1") + compileOnly("org.spongepowered:configurate-hocon:4.1.2") compileOnly("org.slf4j:slf4j-api:1.7.36") compileOnly("net.byteflux:libby-core:1.1.5") } @@ -16,6 +15,6 @@ dependencies { tasks { shadowJar { relocate("net.byteflux.libby", "me.adrianed.authmevelocity.libs.libby") - relocate("space.arim.dazzleconf", "me.adrianed.authmevelocity.libs.dazzleconf") + relocate("org.spongepowered", "me.adrianed.authmevelocity.libs.sponge") } } \ No newline at end of file diff --git a/common/src/main/java/me/adrianed/authmevelocity/common/Constants.java b/common/src/main/java/me/adrianed/authmevelocity/common/Constants.java new file mode 100644 index 0000000..7636857 --- /dev/null +++ b/common/src/main/java/me/adrianed/authmevelocity/common/Constants.java @@ -0,0 +1,6 @@ +package me.adrianed.authmevelocity.common; + +public final class Constants { + public static final String CONFIGURATE = "4.1.2"; + public static final String GEANTYREF = "1.3.13"; +} diff --git a/common/src/main/java/me/adrianed/authmevelocity/common/LibsManager.java b/common/src/main/java/me/adrianed/authmevelocity/common/LibsManager.java index 22f5f7b..d34c2f7 100644 --- a/common/src/main/java/me/adrianed/authmevelocity/common/LibsManager.java +++ b/common/src/main/java/me/adrianed/authmevelocity/common/LibsManager.java @@ -14,35 +14,36 @@ public final class LibsManager { } public void loadLibraries() { - final String dazzlePackage = new String(new char[] { - 's','p','a','c','e','.','a','r','i','m','.','d','a','z','z','l','e','c','o','n','f'}); - final Relocation dazzleRelocation - = new Relocation(dazzlePackage, "me.adrianed.authmevelocity.libs.dazzleconf"); - final Relocation snakeYamlRelocation - = new Relocation("org.yaml.snakeyaml", "me.adrianed.authmevelocity.libs.snakeyaml"); - final Library dazzleConf = Library.builder() - .groupId(dazzlePackage) - .artifactId("dazzleconf-core") - .version("1.3.0-M1") - .relocate(dazzleRelocation) + final Relocation configurateRelocation + = new Relocation("org{}spongepowered", "me.adrianed.authmevelocity.libs.sponge"); + final Relocation geantyrefRelocation = + new Relocation("io{}leangen{}geantyref", "me.adrianed.authmevelocity.libs.geantyref"); + final Library hocon = Library.builder() + .groupId("org{}spongepowered") + .artifactId("configurate-hocon") + .version(Constants.CONFIGURATE) + .id("configurate-hocon") + .relocate(configurateRelocation) + .relocate(geantyrefRelocation) .build(); - final Library dazzleYaml = Library.builder() - .groupId(dazzlePackage) - .artifactId("dazzleconf-ext-snakeyaml") - .version("1.3.0-M1") - .relocate(dazzleRelocation) - .relocate(snakeYamlRelocation) + final Library confCore = Library.builder() + .groupId("org{}spongepowered") + .artifactId("configurate-core") + .version(Constants.CONFIGURATE) + .id("configurate-core") + .relocate(configurateRelocation) + .relocate(geantyrefRelocation) .build(); - final Library snakeYaml = Library.builder() - .groupId("org.yaml") - .artifactId("snakeyaml") - .version("1.30") - .relocate(dazzleRelocation) - .relocate(snakeYamlRelocation) + final Library geantyref = Library.builder() + .groupId("io{}leangen{}geantyref") + .artifactId("geantyref") + .version(Constants.GEANTYREF) + .id("geantyref") + .relocate(geantyrefRelocation) .build(); - manager.loadLibrary(snakeYaml); - manager.loadLibrary(dazzleConf); - manager.loadLibrary(dazzleYaml); + manager.loadLibrary(confCore); + manager.loadLibrary(hocon); + manager.loadLibrary(geantyref); } } diff --git a/common/src/main/java/me/adrianed/authmevelocity/common/configuration/ConfigurationContainer.java b/common/src/main/java/me/adrianed/authmevelocity/common/configuration/ConfigurationContainer.java new file mode 100644 index 0000000..57a392d --- /dev/null +++ b/common/src/main/java/me/adrianed/authmevelocity/common/configuration/ConfigurationContainer.java @@ -0,0 +1,61 @@ +package me.adrianed.authmevelocity.common.configuration; + +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + +import org.slf4j.Logger; +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.hocon.HoconConfigurationLoader; + +public class ConfigurationContainer { + private C config; + private final HoconConfigurationLoader loader; + private final Class clazz; + private final Logger logger; + + public ConfigurationContainer( + final C config, + final Class clazz, + final HoconConfigurationLoader loader, + final Logger logger + ) { + this.config = config; + this.loader = loader; + this.clazz = clazz; + this.logger = logger; + } + + public CompletableFuture reload() { + return this.safeReload(); + } + + public void setValues(Consumer consumer) { + consumer.accept(this.config); + this.safeReload(); + } + + public C get() { + return this.config; + } + + private final CompletableFuture safeReload() { + return CompletableFuture.supplyAsync(() -> { + C newConfig = null; + try { + final CommentedConfigurationNode node = loader.load(); + newConfig = node.get(clazz); + node.set(clazz, config); + loader.save(node); + return true; + } catch (ConfigurateException exception) { + logger.error("Could not load config.conf file", exception); + return false; + } finally { + if (newConfig != null) { + config = newConfig; + } + } + }); + } +} diff --git a/common/src/main/java/me/adrianed/authmevelocity/common/configuration/Loader.java b/common/src/main/java/me/adrianed/authmevelocity/common/configuration/Loader.java index 2d32069..a9ca594 100644 --- a/common/src/main/java/me/adrianed/authmevelocity/common/configuration/Loader.java +++ b/common/src/main/java/me/adrianed/authmevelocity/common/configuration/Loader.java @@ -1,65 +1,36 @@ package me.adrianed.authmevelocity.common.configuration; +import java.nio.file.Path; + import org.slf4j.Logger; -import space.arim.dazzleconf.ConfigurationFactory; -import space.arim.dazzleconf.ConfigurationOptions; -import space.arim.dazzleconf.error.ConfigFormatSyntaxException; -import space.arim.dazzleconf.error.InvalidConfigException; -import space.arim.dazzleconf.ext.snakeyaml.CommentMode; -import space.arim.dazzleconf.ext.snakeyaml.SnakeYamlConfigurationFactory; -import space.arim.dazzleconf.ext.snakeyaml.SnakeYamlOptions; -import space.arim.dazzleconf.helper.ConfigurationHelper; +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.hocon.HoconConfigurationLoader; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; +import org.spongepowered.configurate.objectmapping.meta.Comment; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Path; -public class Loader { - private final ConfigurationHelper configHelper; - private volatile C configData; - private final Logger logger; +public class Loader { + public static ConfigurationContainer loadMainConfig(final Path path, Class clazz, Logger logger){ + final HoconConfigurationLoader loader = HoconConfigurationLoader.builder() + .defaultOptions(opts -> opts + .shouldCopyDefaults(true) + .header("AuthMeVelocity | by Glyart & 4drian3d\n") + ) + .path(path.resolve("config.conf")) + .build(); - private Loader(ConfigurationHelper configHelper, Logger logger) { - this.configHelper = configHelper; - this.logger = logger; - } - - public static Loader create(Path configFolder, String fileName, Class configClass, Logger logger) { - SnakeYamlOptions yamlOptions = new SnakeYamlOptions.Builder() - .commentMode(CommentMode.alternativeWriter()) - .build(); - ConfigurationFactory configFactory = SnakeYamlConfigurationFactory.create( - configClass, - ConfigurationOptions.defaults(), - yamlOptions); - return new Loader<>(new ConfigurationHelper<>(configFolder, fileName, configFactory), logger); - } - - public boolean reloadConfig() { - try { - configData = configHelper.reloadConfigData(); - return true; - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } catch (ConfigFormatSyntaxException ex) { - configData = configHelper.getFactory().loadDefaults(); - logger.error("The yaml syntax in your configuration is invalid. " - + "Check your YAML syntax with a tool such as https://yaml-online-parser.appspot.com/", ex); - return false; - } catch (InvalidConfigException ex) { - configData = configHelper.getFactory().loadDefaults(); - logger.error("One of the values in your configuration is not valid. " - + "Check to make sure you have specified the right data types.", ex); - return false; - } - } - - public C getConfig() { - C configData = this.configData; - if (configData == null) { - throw new IllegalStateException("Configuration has not been loaded yet"); - } - return configData; - } + final C config; + try { + final CommentedConfigurationNode node = loader.load(); + config = node.get(clazz); + node.set(clazz, config); + loader.save(node); + } catch (ConfigurateException exception){ + logger.error("Could not load config.conf file", exception); + return null; + } + return new ConfigurationContainer<>(config, clazz, loader, logger); + } } diff --git a/common/src/main/java/me/adrianed/authmevelocity/common/configuration/ProxyConfiguration.java b/common/src/main/java/me/adrianed/authmevelocity/common/configuration/ProxyConfiguration.java index 7481245..05f373e 100644 --- a/common/src/main/java/me/adrianed/authmevelocity/common/configuration/ProxyConfiguration.java +++ b/common/src/main/java/me/adrianed/authmevelocity/common/configuration/ProxyConfiguration.java @@ -1,66 +1,77 @@ package me.adrianed.authmevelocity.common.configuration; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; +import org.spongepowered.configurate.objectmapping.meta.Comment; + import java.util.List; -import space.arim.dazzleconf.annote.ConfDefault; -import space.arim.dazzleconf.annote.ConfComments; -public interface ProxyConfiguration { - @ConfDefault.DefaultStrings({ - "auth1", "auth2" - }) - @ConfComments({ - "List of login/registration servers" - }) - List authServers(); - - @ConfDefault.DefaultObject("defaultSendOnLogin") - SendOnLogin sendOnLogin(); - - @ConfDefault.DefaultObject("defaultCommands") - Commands commands(); - - @ConfDefault.DefaultObject("defaultEnsureAuth") - EnsureAuthServer ensureAuthServer(); - - public interface SendOnLogin { - @ConfComments({ - "Send logged in players to another server?" - }) - @ConfDefault.DefaultBoolean(false) - boolean sendToServerOnLogin(); - - @ConfComments({ - "List of servers to send", - "One of these servers will be chosen at random" - }) - @ConfDefault.DefaultStrings({ - "lobby1", "lobby2" - }) - List teleportServers(); +@ConfigSerializable +public class ProxyConfiguration { + @Comment("List of login/registration servers") + private List authServers = List.of("auth1", "auth2"); + public List authServers() { + return this.authServers; + } + + private SendOnLogin sendOnLogin = new SendOnLogin(); + public SendOnLogin sendOnLogin() { + return this.sendOnLogin; } - public interface Commands { - @ConfComments({ - "Sets the commands that users who have not yet logged in can execute" - }) - @ConfDefault.DefaultStrings({ - "login", "register", "l", "reg", "email", "captcha" - }) - List allowedCommands(); - - @ConfComments({ - "Sets the message to send in case a non-logged-in player executes an unauthorized command", - "To deactivate the message, leave it empty" - }) - @ConfDefault.DefaultString("You cannot execute commands if you are not logged in yet") - String blockedCommandMessage(); + private Commands commands = new Commands(); + public Commands commands() { + return this.commands; } - public interface EnsureAuthServer { - @ConfComments({ - "Ensure that the first server to which players connect is an auth server" - }) - @ConfDefault.DefaultBoolean(false) - boolean ensureFirstServerIsAuthServer(); + private EnsureAuthServer ensureAuthServer = new EnsureAuthServer(); + public EnsureAuthServer ensureAuthServer() { + return this.ensureAuthServer; } + + @ConfigSerializable + public static class EnsureAuthServer { + @Comment("Ensure that the first server to which players connect is an auth server") + private boolean ensureAuthServer = false; + public boolean ensureFirstServerIsAuthServer() { + return this.ensureAuthServer; + } + } + + @ConfigSerializable + public static class SendOnLogin { + @Comment("Send logged in players to another server?") + private boolean sendOnLogin = false; + public boolean sendToServerOnLogin() { + return this.sendOnLogin; + } + + @Comment(""" + List of servers to send + One of these servers will be chosen at random + """) + private List teleportServers = List.of("lobby1", "lobby2"); + public List teleportServers() { + return this.teleportServers; + } + } + + @ConfigSerializable + public static class Commands { + @Comment("Sets the commands that users who have not yet logged in can execute") + private List allowedCommands = List.of("login", "register", "l", "reg", "email", "captcha"); + public List allowedCommands() { + return this.allowedCommands; + } + + @Comment(""" + Sets the message to send in case a non-logged-in player executes an unauthorized command + To deactivate the message, leave it empty + """) + private String blockedMessage = "You cannot execute commands if you are not logged in yet"; + public String blockedCommandMessage() { + return this.blockedMessage; + } + } + + } diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts index 2e9c852..d39f731 100644 --- a/paper/build.gradle.kts +++ b/paper/build.gradle.kts @@ -35,7 +35,6 @@ tasks { shadowJar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE relocate("net.byteflux.libby", "me.adrianed.authmevelocity.libs.libby") - relocate("space.arim.dazzleconf", "me.adrianed.authmevelocity.libs.dazzleconf") configurations = listOf(project.configurations.shadow.get()) } diff --git a/velocity/build.gradle.kts b/velocity/build.gradle.kts index 9319985..dcdbd4c 100644 --- a/velocity/build.gradle.kts +++ b/velocity/build.gradle.kts @@ -28,7 +28,6 @@ tasks { shadowJar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE relocate("net.byteflux.libby", "me.adrianed.authmevelocity.libs.libby") - relocate("space.arim.dazzleconf", "me.adrianed.authmevelocity.libs.dazzleconf") configurations = listOf(project.configurations.shadow.get()) } } diff --git a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/AuthMeVelocityPlugin.java b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/AuthMeVelocityPlugin.java index 7d47227..baa5775 100644 --- a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/AuthMeVelocityPlugin.java +++ b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/AuthMeVelocityPlugin.java @@ -7,6 +7,7 @@ import me.adrianed.authmevelocity.velocity.listener.PluginMessageListener; import me.adrianed.authmevelocity.velocity.listener.ProxyListener; import me.adrianed.authmevelocity.api.velocity.AuthMeVelocityAPI; import me.adrianed.authmevelocity.common.LibsManager; +import me.adrianed.authmevelocity.common.configuration.ConfigurationContainer; import me.adrianed.authmevelocity.common.configuration.Loader; import me.adrianed.authmevelocity.common.configuration.ProxyConfiguration; import com.google.inject.Inject; @@ -58,7 +59,7 @@ public final class AuthMeVelocityPlugin implements AuthMeVelocityAPI { private final ProxyServer proxy; private final Logger logger; private final Path pluginDirectory; - private Loader config; + private ConfigurationContainer config; protected final Set loggedPlayers = ConcurrentHashMap.newKeySet(); @@ -77,7 +78,7 @@ public final class AuthMeVelocityPlugin implements AuthMeVelocityAPI { logger, pluginDirectory, proxy.getPluginManager(), this)); libraries.loadLibraries(); - this.config = Loader.create(pluginDirectory, "config.yml", ProxyConfiguration.class, logger); + this.config = Loader.loadMainConfig(pluginDirectory, ProxyConfiguration.class, logger); proxy.getChannelRegistrar().register(AUTHMEVELOCITY_CHANNEL); @@ -110,14 +111,14 @@ public final class AuthMeVelocityPlugin implements AuthMeVelocityAPI { source.sendMessage(MiniMessage.miniMessage().deserialize( " --- AuthMeVelocity ---")); source.sendMessage(MiniMessage.miniMessage().deserialize( - "AuthServers: " + config.getConfig().authServers())); - if (config.getConfig().sendOnLogin().sendToServerOnLogin()) { + "AuthServers: " + config.get().authServers())); + if (config.get().sendOnLogin().sendToServerOnLogin()) { source.sendMessage(MiniMessage.miniMessage().deserialize( - "LobbyServers: " + config.getConfig().sendOnLogin().teleportServers())); + "LobbyServers: " + config.get().sendOnLogin().teleportServers())); } } - public Loader config() { + public ConfigurationContainer config() { return this.config; } @@ -153,16 +154,16 @@ public final class AuthMeVelocityPlugin implements AuthMeVelocityAPI { @Override public boolean isAuthServer(RegisteredServer server){ - return config.getConfig().authServers().contains(server.getServerInfo().getName()); + return config.get().authServers().contains(server.getServerInfo().getName()); } @Override public boolean isAuthServer(ServerConnection connection){ - return config.getConfig().authServers().contains(connection.getServerInfo().getName()); + return config.get().authServers().contains(connection.getServerInfo().getName()); } @Override public boolean isAuthServer(String server){ - return config.getConfig().authServers().contains(server); + return config.get().authServers().contains(server); } } diff --git a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/commands/AuthmeCommand.java b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/commands/AuthmeCommand.java index 2fc9f4a..00e9c91 100644 --- a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/commands/AuthmeCommand.java +++ b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/commands/AuthmeCommand.java @@ -20,14 +20,16 @@ public class AuthmeCommand { .then(LiteralArgumentBuilder.literal("reload") .executes(cmd -> { CommandSource source = cmd.getSource(); - if (plugin.config().reloadConfig()) { - plugin.sendInfoMessage(); - source.sendMessage(MiniMessage.miniMessage().deserialize( - "AuthmeVelocity has been successfully reloaded")); - } else { - source.sendMessage(MiniMessage.miniMessage().deserialize( - "There was an error while reloading the configuration. Check the server console")); - } + plugin.config().reload().thenAcceptAsync(result -> { + if(result) { + plugin.sendInfoMessage(); + source.sendMessage(MiniMessage.miniMessage().deserialize( + "AuthmeVelocity has been successfully reloaded")); + } else { + source.sendMessage(MiniMessage.miniMessage().deserialize( + "There was an error while reloading the configuration. Check the server console")); + } + }); return Command.SINGLE_SUCCESS; }) ).build(); diff --git a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ConnectListener.java b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ConnectListener.java index 26944f8..39e3602 100644 --- a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ConnectListener.java +++ b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ConnectListener.java @@ -32,7 +32,7 @@ public class ConnectListener { @Subscribe(order = PostOrder.LATE) public void onInitialServer(PlayerChooseInitialServerEvent event, Continuation continuation){ - if(!plugin.config().getConfig().ensureAuthServer().ensureFirstServerIsAuthServer()) { + if(!plugin.config().get().ensureAuthServer().ensureFirstServerIsAuthServer()) { continuation.resume(); return; } @@ -79,7 +79,7 @@ public class ConnectListener { // TODO: Implement #40 private @Nullable RegisteredServer getAvailableServer() { - for(String sv : plugin.config().getConfig().authServers()){ + for(String sv : plugin.config().get().authServers()){ Optional opt = proxy.getServer(sv); if (opt.isPresent()) return opt.get(); } diff --git a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/PluginMessageListener.java b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/PluginMessageListener.java index ca89b6a..ea137c0 100644 --- a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/PluginMessageListener.java +++ b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/PluginMessageListener.java @@ -85,7 +85,7 @@ public class PluginMessageListener { } private void createServerConnectionRequest(Player player, ServerConnection connection){ - if (!plugin.config().getConfig().sendOnLogin().sendToServerOnLogin()) { + if (!plugin.config().get().sendOnLogin().sendToServerOnLogin()) { return; } @@ -115,7 +115,7 @@ public class PluginMessageListener { } private String getRandomServer() { - final List serverList = plugin.config().getConfig().sendOnLogin().teleportServers(); + final List serverList = plugin.config().get().sendOnLogin().teleportServers(); return serverList.get(rm.nextInt(serverList.size())); } } diff --git a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ProxyListener.java b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ProxyListener.java index 711ea05..dc6d2b7 100644 --- a/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ProxyListener.java +++ b/velocity/src/main/java/me/adrianed/authmevelocity/velocity/listener/ProxyListener.java @@ -42,7 +42,7 @@ public final class ProxyListener { if (plugin.isInAuthServer(player)) { String command = AuthmeUtils.getFirstArgument(event.getCommand()); - if (!plugin.config().getConfig().commands().allowedCommands().contains(command)) { + if (!plugin.config().get().commands().allowedCommands().contains(command)) { sendBlockedMessage(player); event.setResult(CommandExecuteEvent.CommandResult.denied()); } @@ -67,7 +67,7 @@ public final class ProxyListener { } final String command = event.getPartialMessage(); - for (final String allowed : plugin.config().getConfig().commands().allowedCommands()) { + for (final String allowed : plugin.config().get().commands().allowedCommands()) { if (allowed.startsWith(command)) { return; } @@ -77,7 +77,7 @@ public final class ProxyListener { } void sendBlockedMessage(Player player){ - String blockedMessage = plugin.config().getConfig().commands().blockedCommandMessage(); + String blockedMessage = plugin.config().get().commands().blockedCommandMessage(); if (!blockedMessage.isBlank()){ player.sendMessage(MiniMessage.miniMessage().deserialize(blockedMessage)); }