From 7739d94b46711f08d73550f7a2b5fa1293bff91c Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Tue, 29 Dec 2020 23:04:36 +0100 Subject: [PATCH 1/7] Implementation of CommandFilters, replacing cooldowns and costs --- .../earth2me/essentials/CommandFilter.java | 69 ++++++++ .../earth2me/essentials/CommandFilters.java | 154 ++++++++++++++++++ .../com/earth2me/essentials/Essentials.java | 12 ++ .../essentials/EssentialsPlayerListener.java | 28 +++- .../essentials/EssentialsUpgrade.java | 50 ++++++ .../com/earth2me/essentials/IEssentials.java | 2 + .../com/earth2me/essentials/ISettings.java | 12 ++ .../com/earth2me/essentials/Settings.java | 14 +- .../java/com/earth2me/essentials/Trade.java | 16 +- .../src/main/resources/command-filters.yml | 49 ++++++ Essentials/src/main/resources/config.yml | 26 +-- 11 files changed, 395 insertions(+), 37 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java create mode 100644 Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java create mode 100644 Essentials/src/main/resources/command-filters.yml diff --git a/Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java b/Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java new file mode 100644 index 00000000000..b64b2a0f9b4 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java @@ -0,0 +1,69 @@ +package com.earth2me.essentials; + +import net.ess3.api.IUser; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.regex.Pattern; + +public class CommandFilter { + + private final String name; + private final String command; + private final Pattern pattern; + private final Integer cooldown; + private final boolean persistentCooldown; + private final BigDecimal cost; + + public CommandFilter(String name, String command, Pattern pattern, Integer cooldown, boolean persistentCooldown, BigDecimal cost) { + this.name = name; + this.command = command; + this.pattern = pattern; + this.cooldown = cooldown; + this.persistentCooldown = persistentCooldown; + this.cost = cost; + } + + public String getName() { + return name; + } + + public String getCommand() { + return command; + } + + public boolean hasCommand() { + return command != null; + } + + public Pattern getPattern() { + return pattern; + } + + public boolean hasCooldown() { + return cooldown != null; + } + + public Integer getCooldown() { + return cooldown; + } + + public boolean applyCooldownTo(IUser user) { + if (!hasCooldown()) return false; + final Date expiry = new Date(System.currentTimeMillis() + cooldown); + user.addCommandCooldown(pattern, expiry, persistentCooldown); + return true; + } + + public boolean isPersistentCooldown() { + return persistentCooldown; + } + + public boolean hasCost() { + return cost != null; + } + + public BigDecimal getCost() { + return cost; + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java new file mode 100644 index 00000000000..96bedc09bb6 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java @@ -0,0 +1,154 @@ +package com.earth2me.essentials; + +import net.ess3.api.IUser; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.MemoryConfiguration; + +import java.io.File; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +public class CommandFilters implements IConf { + + private final IEssentials essentials; + private final EssentialsConf config; + private ConfigurationSection filters; + private Map commandFilters; + + public CommandFilters(final IEssentials essentials) { + this.essentials = essentials; + config = new EssentialsConf(new File(essentials.getDataFolder(), "command-filters.yml")); + config.setTemplateName("/command-filters.yml"); + + reloadConfig(); + } + + @Override + public void reloadConfig() { + config.load(); + filters = _getCommandFilterSection(); + commandFilters = _getCommandFilters(); + } + + private ConfigurationSection _getCommandFilterSection() { + if (config.isConfigurationSection("filters")) { + final ConfigurationSection section = config.getConfigurationSection("filters"); + final ConfigurationSection newSection = new MemoryConfiguration(); + for (final String filterItem : section.getKeys(false)) { + if (section.isConfigurationSection(filterItem)) { + newSection.set(filterItem.toLowerCase(Locale.ENGLISH), section.getConfigurationSection(filterItem)); + } + } + return newSection; + } + return null; + } + + private Map _getCommandFilters() { + final Map commandFilters = new HashMap<>(); + for (final String name : filters.getKeys(false)) { + if (!filters.isConfigurationSection(name)) { + EssentialsConf.LOGGER.warning("Invalid command filter '" + name + "'"); + continue; + } + + final ConfigurationSection section = Objects.requireNonNull(filters.getConfigurationSection(name)); + Pattern pattern = section.isString("pattern") ? compileRegex(section.getString("pattern")) : null; + final String command = section.getString("command"); + + if (pattern == null && command == null) { + EssentialsConf.LOGGER.warning("Invalid command filter '" + name + "', filter must either define 'pattern' or 'command'!"); + continue; + } + + if (pattern != null && command != null) { + EssentialsConf.LOGGER.warning("Invalid command filter '" + name + "', filter can't have both 'pattern' and 'command'!"); + continue; + } + + // Compile the command as a regex if the pattern hasn't been set, so pattern is always available. + if (pattern == null) { + pattern = compileRegex(command); + } + + Integer cooldown = section.getInt("cooldown", -1); + if (cooldown < 0) { + cooldown = null; + } else { + cooldown *= 1000; // Convert to milliseconds + } + + final boolean persistentCooldown = section.getBoolean("persistent-cooldown", true); + final BigDecimal cost = EssentialsConf.toBigDecimal(section.getString("cost"), null); + + final String lowerName = name.toLowerCase(Locale.ENGLISH); + commandFilters.put(lowerName, new CommandFilter(lowerName, command, pattern, cooldown, persistentCooldown, cost)); + } + config.save(); + return commandFilters; + } + + private Pattern compileRegex(String regex) { + if (regex.startsWith("^")) { + try { + return Pattern.compile(regex.substring(1)); + } catch (final PatternSyntaxException e) { + essentials.getLogger().warning("Command cooldown error: " + e.getMessage()); + return null; + } + } else { + // Escape above Regex + if (regex.startsWith("\\^")) { + regex = regex.substring(1); + } + final String cmd = regex.replaceAll("\\*", ".*"); // Wildcards are accepted as asterisk * as known universally. + return Pattern.compile(cmd + "( .*)?"); // This matches arguments, if present, to "ignore" them from the feature. + } + } + + public EssentialsConf getConfig() { + return config; + } + + public CommandFilter getFilterByName(final String name) { + return commandFilters.get(name.toLowerCase(Locale.ENGLISH)); + } + + public CommandFilter getCommandCooldown(final IUser user, final String label, boolean essCommand) { + if (user.isAuthorized("essentials.commandcooldowns.bypass")) return null; + return getFilter(label, essCommand, filter -> filter.hasCooldown() && !user.isAuthorized("essentials.commandcooldowns.bypass." + filter.getName())); + } + + public CommandFilter getCommandCost(final IUser user, final String label, boolean essCommand) { + if (user.isAuthorized("essentials.nocommandcost.all")) return null; + return getFilter(label, essCommand, filter -> filter.hasCost() && !user.isAuthorized("essentials.nocommandcost." + filter.getName())); + } + + private CommandFilter getFilter(final String label, boolean essCommand, Predicate filterPredicate) { + for (CommandFilter filter : commandFilters.values()) { + // When the label is an ess command, the filter must define a command entry. + if (essCommand && !filter.hasCommand()) continue; + + // Same vice versa. + if (!essCommand && filter.hasCommand()) continue; + + if (!filterPredicate.test(filter)) continue; + + final boolean matches = filter.getPattern().matcher(label).matches(); + if (essentials.getSettings().isDebug()) { + essentials.getLogger().info(String.format("Checking command '%s' against filter '%s': %s", label, filter.getName(), matches)); + } + + if (matches) { + return filter; + } + } + return null; + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index 69ec3eaacf6..7e13bf141e5 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -138,6 +138,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials { private transient KnownCommandsProvider knownCommandsProvider; private transient ProviderListener recipeBookEventProvider; private transient Kits kits; + private transient CommandFilters commandFilters; private transient RandomTeleport randomTeleport; static { @@ -184,6 +185,7 @@ public void setupForTesting(final Server server) throws IOException, InvalidDesc jails = new Jails(this); registerListeners(server.getPluginManager()); kits = new Kits(this); + commandFilters = new CommandFilters(this); } @Override @@ -238,6 +240,11 @@ public void onEnable() { upgrade.convertKits(); execTimer.mark("Kits"); + commandFilters = new CommandFilters(this); + confList.add(commandFilters); + upgrade.convertCommandFilters(); + execTimer.mark("CommandFilters"); + upgrade.afterSettings(); execTimer.mark("Upgrade2"); @@ -738,6 +745,11 @@ public Kits getKits() { return kits; } + @Override + public CommandFilters getCommandFilters() { + return commandFilters; + } + @Override public RandomTeleport getRandomTeleport() { return randomTeleport; diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index 77e784dfe38..5eb8a68bd3f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -8,6 +8,7 @@ import com.earth2me.essentials.utils.DateUtil; import com.earth2me.essentials.utils.LocationUtil; import com.earth2me.essentials.utils.MaterialUtil; +import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.VersionUtil; import io.papermc.lib.PaperLib; import net.ess3.api.IEssentials; @@ -51,6 +52,7 @@ import java.io.IOException; import java.lang.management.ManagementFactory; +import java.math.BigDecimal; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Date; @@ -572,8 +574,7 @@ public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) user.updateActivityOnInteract(broadcast); } - if (ess.getSettings().isCommandCooldownsEnabled() && pluginCommand != null - && !user.isAuthorized("essentials.commandcooldowns.bypass")) { + if (pluginCommand != null) { final int argStartIndex = event.getMessage().indexOf(" "); final String args = argStartIndex == -1 ? "" // No arguments present : " " + event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there. @@ -602,14 +603,27 @@ public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) } if (!cooldownFound) { - final Entry cooldownEntry = ess.getSettings().getCommandCooldownEntry(fullCommand); + final CommandFilter cooldownFilter = ess.getCommandFilters().getCommandCooldown(user, fullCommand, false); + if (cooldownFilter != null) { + if (ess.getSettings().isDebug()) { + ess.getLogger().info("Applying " + cooldownFilter.getCooldown() + "ms cooldown on /" + fullCommand + " for" + user.getName() + "."); + } + cooldownFilter.applyCooldownTo(user); + } - if (cooldownEntry != null) { + final CommandFilter costFilter = ess.getCommandFilters().getCommandCost(user, fullCommand, false); + if (costFilter != null) { if (ess.getSettings().isDebug()) { - ess.getLogger().info("Applying " + cooldownEntry.getValue() + "ms cooldown on /" + fullCommand + " for" + user.getName() + "."); + ess.getLogger().info("Applying a cost of " + costFilter.getCost() + " on /" + fullCommand + " for" + user.getName() + "."); + } + + final BigDecimal cost = costFilter.getCost(); + if (!user.canAfford(cost) && cost.signum() > 0) { + player.sendMessage(tl("notEnoughMoney", NumberUtil.displayCurrency(cost, ess))); + event.setCancelled(true); + return; } - final Date expiry = new Date(System.currentTimeMillis() + cooldownEntry.getValue()); - user.addCommandCooldown(cooldownEntry.getKey(), expiry, ess.getSettings().isCommandCooldownPersistent(fullCommand)); + user.takeMoney(cost); } } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index f48cdf77837..c1e340d9ffd 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -224,6 +224,56 @@ public void convertKits() { LOGGER.info("Done converting kits."); } + public void convertCommandFilters() { + final CommandFilters commandFilters = ess.getCommandFilters(); + final EssentialsConf config = commandFilters.getConfig(); + if (doneFile.getBoolean("commandFiltersYml", false)) { + return; + } + + LOGGER.info("Attempting to convert old command-cooldowns and -costs in config.yml to new command-filters.yml"); + + final ConfigurationSection commandCooldowns = ess.getSettings().getCommandCooldowns(); + if (commandCooldowns != null) { + convertCommandCooldowns(commandCooldowns, config); + } else { + LOGGER.info("No command cooldowns found to migrate."); + } + + final ConfigurationSection commandCosts = ess.getSettings().getCommandCosts(); + if (commandCosts != null) { + convertCommandCosts(commandCosts, config); + } else { + LOGGER.info("No command costs found to migrate."); + } + + config.save(); + doneFile.setProperty("commandFiltersYml", true); + doneFile.save(); + LOGGER.info("Done converting command filters."); + } + + private void convertCommandCooldowns(ConfigurationSection commandCooldowns, EssentialsConf config) { + final boolean persistent = ess.getSettings().isCommandCooldownPersistent("dummy"); + for (Map.Entry entry : commandCooldowns.getValues(false).entrySet()) { + LOGGER.info("Converting cooldown \"" + entry.getKey() + "\""); + + final String key = entry.getKey().replace("\\.", "{dot}"); // Convert periods + config.set("filters." + key + ".pattern", entry.getKey()); + config.set("filters." + key + ".cooldown", entry.getValue()); + config.set("filters." + key + ".persistent-cooldown", persistent); + } + } + + private void convertCommandCosts(ConfigurationSection commandCosts, EssentialsConf config) { + for (Map.Entry entry : commandCosts.getValues(false).entrySet()) { + LOGGER.info("Converting cost \"" + entry.getKey() + "\""); + + config.set("filters." + entry.getKey() + ".pattern", entry.getKey()); + config.set("filters." + entry.getKey() + ".cost", entry.getValue()); + } + } + private void moveMotdRulesToFile(final String name) { if (doneFile.getBoolean("move" + name + "ToFile", false)) { return; diff --git a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java index dda4eba61b2..73fa9f6a6cc 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IEssentials.java @@ -68,6 +68,8 @@ public interface IEssentials extends Plugin { Kits getKits(); + CommandFilters getCommandFilters(); + RandomTeleport getRandomTeleport(); BukkitTask runTaskAsynchronously(Runnable run); diff --git a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java index 2a2c4ffb973..e4a847677b6 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java @@ -41,8 +41,13 @@ public interface ISettings extends IConf { char getChatQuestion(); + @Deprecated + ConfigurationSection getCommandCosts(); + + @Deprecated BigDecimal getCommandCost(IEssentialsCommand cmd); + @Deprecated BigDecimal getCommandCost(String label); String getCurrencySymbol(); @@ -311,16 +316,23 @@ public interface ISettings extends IConf { boolean isTeleportToCenterLocation(); + @Deprecated boolean isCommandCooldownsEnabled(); boolean isWorldChangeFlyResetEnabled(); boolean isWorldChangeSpeedResetEnabled(); + @Deprecated + ConfigurationSection getCommandCooldowns(); + + @Deprecated long getCommandCooldownMs(String label); + @Deprecated Entry getCommandCooldownEntry(String label); + @Deprecated boolean isCommandCooldownPersistent(String label); boolean isNpcsInBalanceRanking(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index a78222edd5e..b3c82521946 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -316,6 +316,11 @@ public BigDecimal getCommandCost(final IEssentialsCommand cmd) { return getCommandCost(cmd.getName()); } + @Override + public ConfigurationSection getCommandCosts() { + return commandCosts; + } + private ConfigurationSection _getCommandCosts() { if (config.isConfigurationSection("command-costs")) { final ConfigurationSection section = config.getConfigurationSection("command-costs"); @@ -1370,6 +1375,14 @@ public boolean isTeleportToCenterLocation() { return config.getBoolean("teleport-to-center", true); } + @Override + public ConfigurationSection getCommandCooldowns() { + if (config.isConfigurationSection("command-cooldowns")) { + return config.getConfigurationSection("command-cooldowns"); + } + return null; + } + private Map _getCommandCooldowns() { if (!config.isConfigurationSection("command-cooldowns")) { return null; @@ -1453,7 +1466,6 @@ public Entry getCommandCooldownEntry(final String label) { @Override public boolean isCommandCooldownPersistent(final String label) { - // TODO: enable per command cooldown specification for persistence. return config.getBoolean("command-cooldown-persistence", true); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/Trade.java b/Essentials/src/main/java/com/earth2me/essentials/Trade.java index 34779982f27..9991256605b 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Trade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Trade.java @@ -283,6 +283,13 @@ public void charge(final IUser user) throws ChargeException { } catch (final ExecutionException e) { throw (ChargeException) e.getCause(); } + } else { + if (command != null && !command.isEmpty()) { + final CommandFilter cooldownFilter = ess.getCommandFilters().getCommandCooldown(user, command, true); + if (cooldownFilter != null) { + cooldownFilter.applyCooldownTo(user); + } + } } } @@ -362,8 +369,10 @@ public TradeType getType() { public BigDecimal getCommandCost(final IUser user) { BigDecimal cost = BigDecimal.ZERO; if (command != null && !command.isEmpty()) { - cost = ess.getSettings().getCommandCost(command.charAt(0) == '/' ? command.substring(1) : command); - if (cost.signum() == 0 && fallbackTrade != null) { + final CommandFilter filter = ess.getCommandFilters().getCommandCost(user, command.charAt(0) == '/' ? command.substring(1) : command, true); + if (filter != null && filter.getCost().signum() != 0) { + cost = filter.getCost(); + } else if (fallbackTrade != null) { cost = fallbackTrade.getCommandCost(user); } @@ -371,9 +380,6 @@ public BigDecimal getCommandCost(final IUser user) { ess.getLogger().log(Level.INFO, "calculated command (" + command + ") cost for " + user.getName() + " as " + cost); } } - if (cost.signum() != 0 && (user.isAuthorized("essentials.nocommandcost.all") || user.isAuthorized("essentials.nocommandcost." + command))) { - return BigDecimal.ZERO; - } return cost; } diff --git a/Essentials/src/main/resources/command-filters.yml b/Essentials/src/main/resources/command-filters.yml new file mode 100644 index 00000000000..00926a21100 --- /dev/null +++ b/Essentials/src/main/resources/command-filters.yml @@ -0,0 +1,49 @@ +# This file stores cooldowns and costs for commands. + +# Each filter must follow the following template keys: + +# [command] - the name of an EssentialsX command; these filters will ensure that the command succeeds before charging the player or starting the cooldown +# All commands do not start with a Forward Slash (/). Instead of /msg, write msg +# Sub-commands are supported: for example, "kit tools" would be look like this: + +# example: +# command: "kit-tools" +# cost: 1000 +# which would result in a 1000 cost for "/kit tools". + +# [pattern] - a regex to match any plugin's command against; these filters will not check whether the command succeeds +# Wildcards are also supported. E.g. +# - '*i*': 50 +# adds a 50 second cooldown to all commands that include the letter i + +# EssentialsX supports regex by starting the command with a caret ^ +# For example, to target commands starting with ban and not banip the following would be used: + +# example: +# pattern: "^ban([^ip])( .*)?" +# cooldown: 60 +# which would result in a 60 seconds /ban cooldown. +# Note: If you have a command that starts with ^, then you can escape it using backslash (\). e.g. \^command: 123 + +# [cooldown] - the length of time that the player will have to wait until they can use a command matching this filter again, in seconds + +# [cost] - the amount that will be deducted from the player's economy balance when they use the command + +# You need to set at least the pattern or command. + +# The "warp" example will charge 100 bucks for "/warp examplewarp", and have a cooldown of 10 seconds. +# The cooldown can be bypassed with "essentials.commandcooldowns.bypass.warp", or if you want to bypass all cooldowns: "essentials.commandcooldowns.bypass". +# The cost can be bypassed with "essentials.nocommandcost.warp", or if you want to bypass all costs: "essentials.nocommandcost.all". + +# The "commands" example will charge 10000 for "/example" and "/othercommand". +# Bypass permissions are the same as above, but now with "commands" instead of "warp". + +filters: + warp: + command: "warp-examplewarp" + cost: 100 + cooldown: 10 + + commands: + pattern: "(example|othercommand)" + cost: 10000 \ No newline at end of file diff --git a/Essentials/src/main/resources/config.yml b/Essentials/src/main/resources/config.yml index 3ad7dc799b3..f73260fd6f2 100644 --- a/Essentials/src/main/resources/config.yml +++ b/Essentials/src/main/resources/config.yml @@ -579,23 +579,7 @@ send-fly-enable-on-join: true # Give someone permission to teleport to a world with essentials.time.world.. world-time-permissions: false -# Specify cooldown for both Essentials commands and external commands as well. -# All commands do not start with a Forward Slash (/). Instead of /msg, write msg -# -# Wildcards are supported. E.g. -# - '*i*': 50 -# adds a 50 second cooldown to all commands that include the letter i -# -# EssentialsX supports regex by starting the command with a caret ^ -# For example, to target commands starting with ban and not banip the following would be used: -# '^ban([^ip])( .*)?': 60 # 60 seconds /ban cooldown. -# Note: If you have a command that starts with ^, then you can escape it using backslash (\). e.g. \^command: 123 -command-cooldowns: -# feed: 100 # 100 second cooldown on /feed command -# '*': 5 # 5 Second cooldown on all commands - -# Whether command cooldowns should be persistent past server shutdowns -command-cooldown-persistence: true +# command-cooldowns are now in command-filters.yml # Whether NPC balances should be listed in balance ranking features such as /balancetop. # NPC balances can include features like factions from FactionsUUID plugin. @@ -707,13 +691,7 @@ confirm-home-overwrite: false # Defines the balance with which new players begin. Defaults to 0. starting-balance: 0 -# Defines the cost to use the given commands PER USE. -# Some commands like /repair have sub-costs, check the wiki for more information. -command-costs: - # /example costs $1000 PER USE - #example: 1000 - # /kit tools costs $1500 PER USE - #kit-tools: 1500 +# command-costs are now in command-filters.yml # Set this to a currency symbol you want to use. # Remember, if you want to use special characters in this document, From 0a03e5066a99e802084c10d26e1a6dba082a372b Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Wed, 30 Dec 2020 01:40:19 +0100 Subject: [PATCH 2/7] Add command-filters.yml to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8f0bcd583f7..4e886561519 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ /Essentials/kits.yml /Essentials/userdata/testplayer1.yml /Essentials/usermap.csv +/Essentials/command-filters.yml # Build files .gradle/ From 76e45fdef198993baa878c03f2a82533d201ee5d Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Wed, 30 Dec 2020 01:42:12 +0100 Subject: [PATCH 3/7] Change automatic upgrading of command-costs to 'command' instead --- .../main/java/com/earth2me/essentials/EssentialsUpgrade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index c1e340d9ffd..ede55732cf3 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -269,7 +269,7 @@ private void convertCommandCosts(ConfigurationSection commandCosts, EssentialsCo for (Map.Entry entry : commandCosts.getValues(false).entrySet()) { LOGGER.info("Converting cost \"" + entry.getKey() + "\""); - config.set("filters." + entry.getKey() + ".pattern", entry.getKey()); + config.set("filters." + entry.getKey() + ".command", entry.getKey()); config.set("filters." + entry.getKey() + ".cost", entry.getValue()); } } From dfda202f48d94c391b8538b1e966ae974dac1f2a Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Thu, 31 Dec 2020 19:57:02 +0100 Subject: [PATCH 4/7] @FrankHeijden Make CommandFilter more extendable + fix AsyncTeleport not applying command cooldown --- .../earth2me/essentials/AsyncTeleport.java | 12 ++++- .../earth2me/essentials/CommandFilter.java | 21 ++++----- .../earth2me/essentials/CommandFilters.java | 46 ++++++++----------- .../earth2me/essentials/EssCommandFilter.java | 18 ++++++++ .../essentials/EssentialsPlayerListener.java | 8 ++-- .../essentials/RegexCommandFilter.java | 11 +++++ .../java/com/earth2me/essentials/Trade.java | 27 +++++++---- 7 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/EssCommandFilter.java create mode 100644 Essentials/src/main/java/com/earth2me/essentials/RegexCommandFilter.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java index 5c1f0648c2f..b818e621189 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/AsyncTeleport.java @@ -258,6 +258,7 @@ private void teleport(final IUser teleportee, final ITarget target, final Trade delay = event.getDelay(); Trade cashCharge = chargeFor; + String cooldownCommand = null; if (chargeFor != null) { chargeFor.isAffordableFor(teleportOwner, future); @@ -265,6 +266,9 @@ private void teleport(final IUser teleportee, final ITarget target, final Trade return; } + // When cashCharge is being reassigned below, ensure the charge knows the command we should apply cooldown on + cooldownCommand = chargeFor.getCommand(); + //This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world. if (!chargeFor.getCommandCost(teleportOwner).equals(BigDecimal.ZERO)) { //By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport. @@ -281,7 +285,7 @@ private void teleport(final IUser teleportee, final ITarget target, final Trade } nowAsync(teleportee, target, cause, future); if (cashCharge != null) { - cashCharge.charge(teleportOwner, future); + cashCharge.charge(teleportOwner, cooldownCommand, future); if (future.isCompletedExceptionally()) { return; } @@ -305,6 +309,7 @@ private void teleportOther(final IUser teleporter, final IUser teleportee, final delay = event.getDelay(); Trade cashCharge = chargeFor; + String cooldownCommand = null; if (teleporter != null && chargeFor != null) { chargeFor.isAffordableFor(teleporter, future); @@ -312,6 +317,9 @@ private void teleportOther(final IUser teleporter, final IUser teleportee, final return; } + // When cashCharge is being reassigned below, ensure the charge knows the command we should apply cooldown on + cooldownCommand = chargeFor.getCommand(); + //This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world. if (!chargeFor.getCommandCost(teleporter).equals(BigDecimal.ZERO)) { //By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport. @@ -332,7 +340,7 @@ private void teleportOther(final IUser teleporter, final IUser teleportee, final nowAsync(teleportee, target, cause, future); if (teleporter != null && cashCharge != null) { - cashCharge.charge(teleporter, future); + cashCharge.charge(teleporter, cooldownCommand, future); if (future.isCompletedExceptionally()) { return; } diff --git a/Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java b/Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java index b64b2a0f9b4..7466abd04f2 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java +++ b/Essentials/src/main/java/com/earth2me/essentials/CommandFilter.java @@ -1,23 +1,28 @@ package com.earth2me.essentials; +import com.google.common.base.Preconditions; import net.ess3.api.IUser; import java.math.BigDecimal; import java.util.Date; import java.util.regex.Pattern; -public class CommandFilter { +public abstract class CommandFilter { + + public enum Type { + REGEX, + ESS + } private final String name; - private final String command; private final Pattern pattern; private final Integer cooldown; private final boolean persistentCooldown; private final BigDecimal cost; - public CommandFilter(String name, String command, Pattern pattern, Integer cooldown, boolean persistentCooldown, BigDecimal cost) { + public CommandFilter(String name, Pattern pattern, Integer cooldown, boolean persistentCooldown, BigDecimal cost) { + Preconditions.checkNotNull(pattern); this.name = name; - this.command = command; this.pattern = pattern; this.cooldown = cooldown; this.persistentCooldown = persistentCooldown; @@ -28,14 +33,6 @@ public String getName() { return name; } - public String getCommand() { - return command; - } - - public boolean hasCommand() { - return command != null; - } - public Pattern getPattern() { return pattern; } diff --git a/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java index 96bedc09bb6..89843876564 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java +++ b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java @@ -6,7 +6,9 @@ import java.io.File; import java.math.BigDecimal; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; @@ -19,7 +21,7 @@ public class CommandFilters implements IConf { private final IEssentials essentials; private final EssentialsConf config; private ConfigurationSection filters; - private Map commandFilters; + private Map> commandFilters; public CommandFilters(final IEssentials essentials) { this.essentials = essentials; @@ -50,8 +52,8 @@ private ConfigurationSection _getCommandFilterSection() { return null; } - private Map _getCommandFilters() { - final Map commandFilters = new HashMap<>(); + private Map> _getCommandFilters() { + final Map> commandFilters = new EnumMap<>(CommandFilter.Type.class); for (final String name : filters.getKeys(false)) { if (!filters.isConfigurationSection(name)) { EssentialsConf.LOGGER.warning("Invalid command filter '" + name + "'"); @@ -59,7 +61,7 @@ private Map _getCommandFilters() { } final ConfigurationSection section = Objects.requireNonNull(filters.getConfigurationSection(name)); - Pattern pattern = section.isString("pattern") ? compileRegex(section.getString("pattern")) : null; + final Pattern pattern = section.isString("pattern") ? compileRegex(section.getString("pattern")) : null; final String command = section.getString("command"); if (pattern == null && command == null) { @@ -72,11 +74,6 @@ private Map _getCommandFilters() { continue; } - // Compile the command as a regex if the pattern hasn't been set, so pattern is always available. - if (pattern == null) { - pattern = compileRegex(command); - } - Integer cooldown = section.getInt("cooldown", -1); if (cooldown < 0) { cooldown = null; @@ -88,7 +85,12 @@ private Map _getCommandFilters() { final BigDecimal cost = EssentialsConf.toBigDecimal(section.getString("cost"), null); final String lowerName = name.toLowerCase(Locale.ENGLISH); - commandFilters.put(lowerName, new CommandFilter(lowerName, command, pattern, cooldown, persistentCooldown, cost)); + + if (pattern == null) { + commandFilters.computeIfAbsent(CommandFilter.Type.ESS, k -> new ArrayList<>()).add(new EssCommandFilter(lowerName, command, compileRegex(command), cooldown, persistentCooldown, cost)); + } else { + commandFilters.computeIfAbsent(CommandFilter.Type.REGEX, k -> new ArrayList<>()).add(new RegexCommandFilter(lowerName, pattern, cooldown, persistentCooldown, cost)); + } } config.save(); return commandFilters; @@ -116,28 +118,18 @@ public EssentialsConf getConfig() { return config; } - public CommandFilter getFilterByName(final String name) { - return commandFilters.get(name.toLowerCase(Locale.ENGLISH)); - } - - public CommandFilter getCommandCooldown(final IUser user, final String label, boolean essCommand) { + public CommandFilter getCommandCooldown(final IUser user, final String label, CommandFilter.Type type) { if (user.isAuthorized("essentials.commandcooldowns.bypass")) return null; - return getFilter(label, essCommand, filter -> filter.hasCooldown() && !user.isAuthorized("essentials.commandcooldowns.bypass." + filter.getName())); + return getFilter(label, type, filter -> filter.hasCooldown() && !user.isAuthorized("essentials.commandcooldowns.bypass." + filter.getName())); } - public CommandFilter getCommandCost(final IUser user, final String label, boolean essCommand) { + public CommandFilter getCommandCost(final IUser user, final String label, CommandFilter.Type type) { if (user.isAuthorized("essentials.nocommandcost.all")) return null; - return getFilter(label, essCommand, filter -> filter.hasCost() && !user.isAuthorized("essentials.nocommandcost." + filter.getName())); + return getFilter(label, type, filter -> filter.hasCost() && !user.isAuthorized("essentials.nocommandcost." + filter.getName())); } - private CommandFilter getFilter(final String label, boolean essCommand, Predicate filterPredicate) { - for (CommandFilter filter : commandFilters.values()) { - // When the label is an ess command, the filter must define a command entry. - if (essCommand && !filter.hasCommand()) continue; - - // Same vice versa. - if (!essCommand && filter.hasCommand()) continue; - + private CommandFilter getFilter(final String label, CommandFilter.Type type, Predicate filterPredicate) { + for (CommandFilter filter : commandFilters.get(type)) { if (!filterPredicate.test(filter)) continue; final boolean matches = filter.getPattern().matcher(label).matches(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssCommandFilter.java b/Essentials/src/main/java/com/earth2me/essentials/EssCommandFilter.java new file mode 100644 index 00000000000..b2e2e943b4f --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/EssCommandFilter.java @@ -0,0 +1,18 @@ +package com.earth2me.essentials; + +import java.math.BigDecimal; +import java.util.regex.Pattern; + +public class EssCommandFilter extends CommandFilter { + + private final String command; + + public EssCommandFilter(String name, String command, Pattern pattern, Integer cooldown, boolean persistentCooldown, BigDecimal cost) { + super(name, pattern, cooldown, persistentCooldown, cost); + this.command = command; + } + + public String getCommand() { + return command; + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index 5eb8a68bd3f..91bad18b4c4 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -603,18 +603,18 @@ public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) } if (!cooldownFound) { - final CommandFilter cooldownFilter = ess.getCommandFilters().getCommandCooldown(user, fullCommand, false); + final CommandFilter cooldownFilter = ess.getCommandFilters().getCommandCooldown(user, fullCommand, CommandFilter.Type.REGEX); if (cooldownFilter != null) { if (ess.getSettings().isDebug()) { - ess.getLogger().info("Applying " + cooldownFilter.getCooldown() + "ms cooldown on /" + fullCommand + " for" + user.getName() + "."); + ess.getLogger().info("Applying " + cooldownFilter.getCooldown() + "ms cooldown on /" + fullCommand + " for " + user.getName() + "."); } cooldownFilter.applyCooldownTo(user); } - final CommandFilter costFilter = ess.getCommandFilters().getCommandCost(user, fullCommand, false); + final CommandFilter costFilter = ess.getCommandFilters().getCommandCost(user, fullCommand, CommandFilter.Type.REGEX); if (costFilter != null) { if (ess.getSettings().isDebug()) { - ess.getLogger().info("Applying a cost of " + costFilter.getCost() + " on /" + fullCommand + " for" + user.getName() + "."); + ess.getLogger().info("Applying a cost of " + costFilter.getCost() + " on /" + fullCommand + " for " + user.getName() + "."); } final BigDecimal cost = costFilter.getCost(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/RegexCommandFilter.java b/Essentials/src/main/java/com/earth2me/essentials/RegexCommandFilter.java new file mode 100644 index 00000000000..81674a87dce --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/RegexCommandFilter.java @@ -0,0 +1,11 @@ +package com.earth2me.essentials; + +import java.math.BigDecimal; +import java.util.regex.Pattern; + +public class RegexCommandFilter extends CommandFilter { + + public RegexCommandFilter(String name, Pattern pattern, Integer cooldown, boolean persistentCooldown, BigDecimal cost) { + super(name, pattern, cooldown, persistentCooldown, cost); + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/Trade.java b/Essentials/src/main/java/com/earth2me/essentials/Trade.java index 9991256605b..920c088be77 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Trade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Trade.java @@ -283,17 +283,14 @@ public void charge(final IUser user) throws ChargeException { } catch (final ExecutionException e) { throw (ChargeException) e.getCause(); } - } else { - if (command != null && !command.isEmpty()) { - final CommandFilter cooldownFilter = ess.getCommandFilters().getCommandCooldown(user, command, true); - if (cooldownFilter != null) { - cooldownFilter.applyCooldownTo(user); - } - } } } public void charge(final IUser user, final CompletableFuture future) { + charge(user, this.command, future); + } + + public void charge(final IUser user, final String cooldownCommand, final CompletableFuture future) { if (ess.getSettings().isDebug()) { ess.getLogger().log(Level.INFO, "attempting to charge user " + user.getName()); } @@ -340,6 +337,20 @@ public void charge(final IUser user, final CompletableFuture future) { if (ess.getSettings().isDebug()) { ess.getLogger().log(Level.INFO, "charge user " + user.getName() + " completed"); } + + if (cooldownCommand != null && !cooldownCommand.isEmpty()) { + final CommandFilter cooldownFilter = ess.getCommandFilters().getCommandCooldown(user, cooldownCommand, CommandFilter.Type.ESS); + if (cooldownFilter != null) { + if (ess.getSettings().isDebug()) { + ess.getLogger().info("Applying " + cooldownFilter.getCooldown() + "ms cooldown on /" + cooldownCommand + " for " + user.getName() + "."); + } + cooldownFilter.applyCooldownTo(user); + } + } + } + + public String getCommand() { + return command; } public BigDecimal getMoney() { @@ -369,7 +380,7 @@ public TradeType getType() { public BigDecimal getCommandCost(final IUser user) { BigDecimal cost = BigDecimal.ZERO; if (command != null && !command.isEmpty()) { - final CommandFilter filter = ess.getCommandFilters().getCommandCost(user, command.charAt(0) == '/' ? command.substring(1) : command, true); + final CommandFilter filter = ess.getCommandFilters().getCommandCost(user, command.charAt(0) == '/' ? command.substring(1) : command, CommandFilter.Type.ESS); if (filter != null && filter.getCost().signum() != 0) { cost = filter.getCost(); } else if (fallbackTrade != null) { From b681c1c150fc97fca3b4091119ebb8bb3983f945 Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Tue, 15 Jun 2021 13:57:48 +0200 Subject: [PATCH 5/7] Convert to sponge config --- .../earth2me/essentials/EssentialsUpgrade.java | 15 ++++++++------- .../java/com/earth2me/essentials/ISettings.java | 4 ++-- .../java/com/earth2me/essentials/Settings.java | 7 ++----- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index bb1dc4faee3..73c10b4af34 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -24,6 +24,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.math.BigDecimal; import java.math.BigInteger; import java.security.DigestInputStream; import java.security.MessageDigest; @@ -287,14 +288,14 @@ public void convertCommandFilters() { LOGGER.info("Attempting to convert old command-cooldowns and -costs in config.yml to new command-filters.yml"); - final ConfigurationSection commandCooldowns = ess.getSettings().getCommandCooldowns(); + final CommentedConfigurationNode commandCooldowns = ess.getSettings().getCommandCooldowns(); if (commandCooldowns != null) { convertCommandCooldowns(commandCooldowns, config); } else { LOGGER.info("No command cooldowns found to migrate."); } - final ConfigurationSection commandCosts = ess.getSettings().getCommandCosts(); + final Map commandCosts = ess.getSettings().getCommandCosts(); if (commandCosts != null) { convertCommandCosts(commandCosts, config); } else { @@ -307,9 +308,9 @@ public void convertCommandFilters() { LOGGER.info("Done converting command filters."); } - private void convertCommandCooldowns(ConfigurationSection commandCooldowns, EssentialsConf config) { + private void convertCommandCooldowns(CommentedConfigurationNode commandCooldowns, EssentialsConf config) { final boolean persistent = ess.getSettings().isCommandCooldownPersistent("dummy"); - for (Map.Entry entry : commandCooldowns.getValues(false).entrySet()) { + for (Map.Entry entry : ConfigurateUtil.getRawMap(commandCooldowns).entrySet()) { LOGGER.info("Converting cooldown \"" + entry.getKey() + "\""); final String key = entry.getKey().replace("\\.", "{dot}"); // Convert periods @@ -319,12 +320,12 @@ private void convertCommandCooldowns(ConfigurationSection commandCooldowns, Esse } } - private void convertCommandCosts(ConfigurationSection commandCosts, EssentialsConf config) { - for (Map.Entry entry : commandCosts.getValues(false).entrySet()) { + private void convertCommandCosts(Map commandCosts, EssentialsConf config) { + for (Map.Entry entry : commandCosts.entrySet()) { LOGGER.info("Converting cost \"" + entry.getKey() + "\""); config.set("filters." + entry.getKey() + ".command", entry.getKey()); - config.set("filters." + entry.getKey() + ".cost", entry.getValue()); + config.set("filters." + entry.getKey() + ".cost", entry.getValue().toString()); } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java index c7568bc26d6..7d18d3696ea 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java @@ -44,7 +44,7 @@ public interface ISettings extends IConf { char getChatQuestion(); @Deprecated - ConfigurationSection getCommandCosts(); + Map getCommandCosts(); @Deprecated BigDecimal getCommandCost(IEssentialsCommand cmd); @@ -318,7 +318,7 @@ public interface ISettings extends IConf { boolean isWorldChangeSpeedResetEnabled(); @Deprecated - ConfigurationSection getCommandCooldowns(); + CommentedConfigurationNode getCommandCooldowns(); @Deprecated long getCommandCooldownMs(String label); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index 0db80b2582f..32c9806ef8a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -1492,11 +1492,8 @@ public boolean isTeleportToCenterLocation() { } @Override - public ConfigurationSection getCommandCooldowns() { - if (config.isConfigurationSection("command-cooldowns")) { - return config.getConfigurationSection("command-cooldowns"); - } - return null; + public CommentedConfigurationNode getCommandCooldowns() { + return config.getSection("command-cooldowns"); } private Map _getCommandCooldowns() { From 9dbd5dda35d843b3e81c19d6301172c7063fba43 Mon Sep 17 00:00:00 2001 From: Frank van der Heijden Date: Sat, 4 Dec 2021 00:00:56 +0100 Subject: [PATCH 6/7] Update to configurate --- .../earth2me/essentials/CommandFilters.java | 65 +++++++------------ .../essentials/EssentialsUpgrade.java | 21 +++--- 2 files changed, 35 insertions(+), 51 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java index 89843876564..349fea7ea22 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java +++ b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java @@ -1,8 +1,9 @@ package com.earth2me.essentials; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import net.ess3.api.IUser; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.MemoryConfiguration; +import org.spongepowered.configurate.CommentedConfigurationNode; import java.io.File; import java.math.BigDecimal; @@ -11,7 +12,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -19,14 +19,12 @@ public class CommandFilters implements IConf { private final IEssentials essentials; - private final EssentialsConf config; - private ConfigurationSection filters; + private final EssentialsConfiguration config; private Map> commandFilters; public CommandFilters(final IEssentials essentials) { this.essentials = essentials; - config = new EssentialsConf(new File(essentials.getDataFolder(), "command-filters.yml")); - config.setTemplateName("/command-filters.yml"); + config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "command-filters.yml"), "/command-filters.yml"); reloadConfig(); } @@ -34,65 +32,46 @@ public CommandFilters(final IEssentials essentials) { @Override public void reloadConfig() { config.load(); - filters = _getCommandFilterSection(); - commandFilters = _getCommandFilters(); + commandFilters = parseCommandFilters(config); } - private ConfigurationSection _getCommandFilterSection() { - if (config.isConfigurationSection("filters")) { - final ConfigurationSection section = config.getConfigurationSection("filters"); - final ConfigurationSection newSection = new MemoryConfiguration(); - for (final String filterItem : section.getKeys(false)) { - if (section.isConfigurationSection(filterItem)) { - newSection.set(filterItem.toLowerCase(Locale.ENGLISH), section.getConfigurationSection(filterItem)); - } - } - return newSection; - } - return null; - } - - private Map> _getCommandFilters() { + private Map> parseCommandFilters(EssentialsConfiguration config) { final Map> commandFilters = new EnumMap<>(CommandFilter.Type.class); - for (final String name : filters.getKeys(false)) { - if (!filters.isConfigurationSection(name)) { - EssentialsConf.LOGGER.warning("Invalid command filter '" + name + "'"); - continue; - } - - final ConfigurationSection section = Objects.requireNonNull(filters.getConfigurationSection(name)); - final Pattern pattern = section.isString("pattern") ? compileRegex(section.getString("pattern")) : null; - final String command = section.getString("command"); + final CommentedConfigurationNode filterSection = config.getSection("filters"); + for (final String filterItem : ConfigurateUtil.getKeys(filterSection)) { + final CommentedConfigurationNode section = filterSection.node(filterItem); + final String patternString = section.node("pattern").getString(); + final Pattern pattern = patternString == null ? null : compileRegex(patternString); + final String command = section.node("command").getString(); if (pattern == null && command == null) { - EssentialsConf.LOGGER.warning("Invalid command filter '" + name + "', filter must either define 'pattern' or 'command'!"); + EssentialsConf.LOGGER.warning("Invalid command filter '" + filterItem + "', filter must either define 'pattern' or 'command'!"); continue; } if (pattern != null && command != null) { - EssentialsConf.LOGGER.warning("Invalid command filter '" + name + "', filter can't have both 'pattern' and 'command'!"); + EssentialsConf.LOGGER.warning("Invalid command filter '" + filterItem + "', filter can't have both 'pattern' and 'command'!"); continue; } - Integer cooldown = section.getInt("cooldown", -1); + Integer cooldown = section.node("cooldown").getInt(-1); if (cooldown < 0) { cooldown = null; } else { cooldown *= 1000; // Convert to milliseconds } - final boolean persistentCooldown = section.getBoolean("persistent-cooldown", true); - final BigDecimal cost = EssentialsConf.toBigDecimal(section.getString("cost"), null); + final boolean persistentCooldown = section.node("persistent-cooldown").getBoolean(true); + final BigDecimal cost = EssentialsConf.toBigDecimal(section.node("cost").getString(), null); - final String lowerName = name.toLowerCase(Locale.ENGLISH); + final String filterItemName = filterItem.toLowerCase(Locale.ENGLISH); if (pattern == null) { - commandFilters.computeIfAbsent(CommandFilter.Type.ESS, k -> new ArrayList<>()).add(new EssCommandFilter(lowerName, command, compileRegex(command), cooldown, persistentCooldown, cost)); + commandFilters.computeIfAbsent(CommandFilter.Type.ESS, k -> new ArrayList<>()).add(new EssCommandFilter(filterItemName, command, compileRegex(command), cooldown, persistentCooldown, cost)); } else { - commandFilters.computeIfAbsent(CommandFilter.Type.REGEX, k -> new ArrayList<>()).add(new RegexCommandFilter(lowerName, pattern, cooldown, persistentCooldown, cost)); + commandFilters.computeIfAbsent(CommandFilter.Type.REGEX, k -> new ArrayList<>()).add(new RegexCommandFilter(filterItemName, pattern, cooldown, persistentCooldown, cost)); } } - config.save(); return commandFilters; } @@ -114,7 +93,7 @@ private Pattern compileRegex(String regex) { } } - public EssentialsConf getConfig() { + public EssentialsConfiguration getConfig() { return config; } diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index dbbedaa198f..4b9396b1f45 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -466,7 +466,7 @@ public void convertKits() { public void convertCommandFilters() { final CommandFilters commandFilters = ess.getCommandFilters(); - final EssentialsConf config = commandFilters.getConfig(); + final EssentialsConfiguration config = commandFilters.getConfig(); if (doneFile.getBoolean("commandFiltersYml", false)) { return; } @@ -493,24 +493,29 @@ public void convertCommandFilters() { LOGGER.info("Done converting command filters."); } - private void convertCommandCooldowns(CommentedConfigurationNode commandCooldowns, EssentialsConf config) { + private void convertCommandCooldowns(CommentedConfigurationNode commandCooldowns, EssentialsConfiguration config) { final boolean persistent = ess.getSettings().isCommandCooldownPersistent("dummy"); for (Map.Entry entry : ConfigurateUtil.getRawMap(commandCooldowns).entrySet()) { LOGGER.info("Converting cooldown \"" + entry.getKey() + "\""); final String key = entry.getKey().replace("\\.", "{dot}"); // Convert periods - config.set("filters." + key + ".pattern", entry.getKey()); - config.set("filters." + key + ".cooldown", entry.getValue()); - config.set("filters." + key + ".persistent-cooldown", persistent); + config.setProperty("filters." + key + ".pattern", entry.getKey()); + final String cooldownKey = "filters." + key + ".cooldown"; + if (entry.getValue() instanceof Double) { + config.setProperty(cooldownKey, (double) entry.getValue()); + } else if (entry.getValue() instanceof Integer) { + config.setProperty(cooldownKey, (int) entry.getValue()); + } + config.setProperty("filters." + key + ".persistent-cooldown", persistent); } } - private void convertCommandCosts(Map commandCosts, EssentialsConf config) { + private void convertCommandCosts(Map commandCosts, EssentialsConfiguration config) { for (Map.Entry entry : commandCosts.entrySet()) { LOGGER.info("Converting cost \"" + entry.getKey() + "\""); - config.set("filters." + entry.getKey() + ".command", entry.getKey()); - config.set("filters." + entry.getKey() + ".cost", entry.getValue().toString()); + config.setProperty("filters." + entry.getKey() + ".command", entry.getKey()); + config.setProperty("filters." + entry.getKey() + ".cost", entry.getValue().toString()); } } From 2b8c8bf8bde9aaf279dc01b2c57fd190d32f4b51 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 11 Nov 2023 18:21:02 -0500 Subject: [PATCH 7/7] Fix build --- .../earth2me/essentials/CommandFilters.java | 20 +++++++++---------- .../essentials/EssentialsUpgrade.java | 12 +++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java index 349fea7ea22..8e1e58f561b 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java +++ b/Essentials/src/main/java/com/earth2me/essentials/CommandFilters.java @@ -18,13 +18,13 @@ public class CommandFilters implements IConf { - private final IEssentials essentials; + private final IEssentials ess; private final EssentialsConfiguration config; private Map> commandFilters; - public CommandFilters(final IEssentials essentials) { - this.essentials = essentials; - config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "command-filters.yml"), "/command-filters.yml"); + public CommandFilters(final IEssentials ess) { + this.ess = ess; + config = new EssentialsConfiguration(new File(ess.getDataFolder(), "command-filters.yml"), "/command-filters.yml"); reloadConfig(); } @@ -45,12 +45,12 @@ private Map> parseCommandFilters(Essenti final String command = section.node("command").getString(); if (pattern == null && command == null) { - EssentialsConf.LOGGER.warning("Invalid command filter '" + filterItem + "', filter must either define 'pattern' or 'command'!"); + ess.getLogger().warning("Invalid command filter '" + filterItem + "', filter must either define 'pattern' or 'command'!"); continue; } if (pattern != null && command != null) { - EssentialsConf.LOGGER.warning("Invalid command filter '" + filterItem + "', filter can't have both 'pattern' and 'command'!"); + ess.getLogger().warning("Invalid command filter '" + filterItem + "', filter can't have both 'pattern' and 'command'!"); continue; } @@ -62,7 +62,7 @@ private Map> parseCommandFilters(Essenti } final boolean persistentCooldown = section.node("persistent-cooldown").getBoolean(true); - final BigDecimal cost = EssentialsConf.toBigDecimal(section.node("cost").getString(), null); + final BigDecimal cost = ConfigurateUtil.toBigDecimal(section.node("cost").getString(), null); final String filterItemName = filterItem.toLowerCase(Locale.ENGLISH); @@ -80,7 +80,7 @@ private Pattern compileRegex(String regex) { try { return Pattern.compile(regex.substring(1)); } catch (final PatternSyntaxException e) { - essentials.getLogger().warning("Command cooldown error: " + e.getMessage()); + ess.getLogger().warning("Command cooldown error: " + e.getMessage()); return null; } } else { @@ -112,8 +112,8 @@ private CommandFilter getFilter(final String label, CommandFilter.Type type, Pre if (!filterPredicate.test(filter)) continue; final boolean matches = filter.getPattern().matcher(label).matches(); - if (essentials.getSettings().isDebug()) { - essentials.getLogger().info(String.format("Checking command '%s' against filter '%s': %s", label, filter.getName(), matches)); + if (ess.getSettings().isDebug()) { + ess.getLogger().info(String.format("Checking command '%s' against filter '%s': %s", label, filter.getName(), matches)); } if (matches) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index 5125aa7d2ad..96f4b83a2d6 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -470,32 +470,32 @@ public void convertCommandFilters() { return; } - LOGGER.info("Attempting to convert old command-cooldowns and -costs in config.yml to new command-filters.yml"); + ess.getLogger().info("Attempting to convert old command-cooldowns and -costs in config.yml to new command-filters.yml"); final CommentedConfigurationNode commandCooldowns = ess.getSettings().getCommandCooldowns(); if (commandCooldowns != null) { convertCommandCooldowns(commandCooldowns, config); } else { - LOGGER.info("No command cooldowns found to migrate."); + ess.getLogger().info("No command cooldowns found to migrate."); } final Map commandCosts = ess.getSettings().getCommandCosts(); if (commandCosts != null) { convertCommandCosts(commandCosts, config); } else { - LOGGER.info("No command costs found to migrate."); + ess.getLogger().info("No command costs found to migrate."); } config.save(); doneFile.setProperty("commandFiltersYml", true); doneFile.save(); - LOGGER.info("Done converting command filters."); + ess.getLogger().info("Done converting command filters."); } private void convertCommandCooldowns(CommentedConfigurationNode commandCooldowns, EssentialsConfiguration config) { final boolean persistent = ess.getSettings().isCommandCooldownPersistent("dummy"); for (Map.Entry entry : ConfigurateUtil.getRawMap(commandCooldowns).entrySet()) { - LOGGER.info("Converting cooldown \"" + entry.getKey() + "\""); + ess.getLogger().info("Converting cooldown \"" + entry.getKey() + "\""); final String key = entry.getKey().replace("\\.", "{dot}"); // Convert periods config.setProperty("filters." + key + ".pattern", entry.getKey()); @@ -511,7 +511,7 @@ private void convertCommandCooldowns(CommentedConfigurationNode commandCooldowns private void convertCommandCosts(Map commandCosts, EssentialsConfiguration config) { for (Map.Entry entry : commandCosts.entrySet()) { - LOGGER.info("Converting cost \"" + entry.getKey() + "\""); + ess.getLogger().info("Converting cost \"" + entry.getKey() + "\""); config.setProperty("filters." + entry.getKey() + ".command", entry.getKey()); config.setProperty("filters." + entry.getKey() + ".cost", entry.getValue().toString());