diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index 3b8c2f6e3f4..231c9ab4b15 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -776,7 +776,8 @@ public void onPlayerBucketEmpty(final PlayerBucketEmptyEvent event) { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) { - final String cmd = event.getMessage().split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH); + final String commandLabel = event.getMessage().split(" ")[0].replace("/", ""); + final String cmd = commandLabel.toLowerCase(Locale.ENGLISH); 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. @@ -784,7 +785,7 @@ public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) // If the plugin command does not exist, check if it is an alias from commands.yml if (ess.getServer().getPluginCommand(cmd) == null) { final Command knownCommand = ess.provider(KnownCommandsProvider.class).getKnownCommands().get(cmd); - if (knownCommand instanceof FormattedCommandAlias) { + if (isCommandRegistered(commandLabel) && knownCommand instanceof FormattedCommandAlias) { final FormattedCommandAlias command = (FormattedCommandAlias) knownCommand; for (String fullCommand : ess.provider(FormattedCommandAliasProvider.class).createCommands(command, event.getPlayer(), args.split(" "))) { handlePlayerCommandPreprocess(event, fullCommand); @@ -794,12 +795,13 @@ public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) } // Handle the command given from the event. - handlePlayerCommandPreprocess(event, cmd + args); + handlePlayerCommandPreprocess(event, commandLabel + args); } public void handlePlayerCommandPreprocess(final PlayerCommandPreprocessEvent event, final String effectiveCommand) { final Player player = event.getPlayer(); - final String cmd = effectiveCommand.split(" ")[0].replace("/", "").toLowerCase(Locale.ENGLISH); + final String commandLabel = effectiveCommand.split(" ")[0].replace("/", ""); + final String cmd = commandLabel.toLowerCase(Locale.ENGLISH); final PluginCommand pluginCommand = ess.getServer().getPluginCommand(cmd); if (ess.getSettings().getSocialSpyCommands().contains(cmd) || ess.getSettings().getSocialSpyCommands().contains("*")) { @@ -862,7 +864,8 @@ public void handlePlayerCommandPreprocess(final PlayerCommandPreprocessEvent eve user.updateActivityOnInteract(broadcast); } - if (ess.getSettings().isCommandCooldownsEnabled() + if (isCommandRegistered(commandLabel) + && ess.getSettings().isCommandCooldownsEnabled() && !user.isAuthorized("essentials.commandcooldowns.bypass") && (pluginCommand == null || !user.isAuthorized("essentials.commandcooldowns.bypass." + pluginCommand.getName()))) { final int argStartIndex = effectiveCommand.indexOf(" "); @@ -902,6 +905,12 @@ public void handlePlayerCommandPreprocess(final PlayerCommandPreprocessEvent eve } } + private boolean isCommandRegistered(final String commandLabel) { + final Map knownCommands = ess.provider(KnownCommandsProvider.class).getKnownCommands(); + return knownCommands.containsKey(commandLabel) + || (VersionUtil.PRE_FLATTENING && knownCommands.containsKey(commandLabel.toLowerCase(Locale.ENGLISH))); + } + @EventHandler(priority = EventPriority.NORMAL) public void onPlayerChangedWorldFlyReset(final PlayerChangedWorldEvent event) { final User user = ess.getUser(event.getPlayer()); diff --git a/Essentials/src/test/java/com/earth2me/essentials/EssentialsPlayerListenerTest.java b/Essentials/src/test/java/com/earth2me/essentials/EssentialsPlayerListenerTest.java new file mode 100644 index 00000000000..dc98c807003 --- /dev/null +++ b/Essentials/src/test/java/com/earth2me/essentials/EssentialsPlayerListenerTest.java @@ -0,0 +1,82 @@ +package com.earth2me.essentials; + +import net.ess3.api.IEssentials; +import net.ess3.provider.KnownCommandsProvider; +import org.bukkit.Server; +import org.bukkit.command.PluginCommand; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockbukkit.mockbukkit.MockBukkit; + +import java.util.AbstractMap; +import java.util.Collections; +import java.util.Date; +import java.util.regex.Pattern; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class EssentialsPlayerListenerTest { + private IEssentials ess; + private ISettings settings; + private User user; + private Player player; + private Pattern cooldownPattern; + private EssentialsPlayerListener listener; + + @BeforeEach + public void setUp() { + player = MockBukkit.mock().addPlayer(); + ess = mock(IEssentials.class); + settings = mock(ISettings.class); + user = mock(User.class); + final Server commandServer = mock(Server.class); + final PluginCommand pluginCommand = mock(PluginCommand.class); + final KnownCommandsProvider knownCommandsProvider = mock(KnownCommandsProvider.class); + cooldownPattern = Pattern.compile("feed"); + + when(ess.getServer()).thenReturn(commandServer); + when(ess.getSettings()).thenReturn(settings); + when(ess.getUser(player)).thenReturn(user); + when(ess.provider(KnownCommandsProvider.class)).thenReturn(knownCommandsProvider); + when(knownCommandsProvider.getKnownCommands()).thenReturn(Collections.singletonMap("efeed", pluginCommand)); + when(commandServer.getPluginCommand("efeed")).thenReturn(pluginCommand); + when(pluginCommand.getName()).thenReturn("feed"); + when(settings.getSocialSpyCommands()).thenReturn(Collections.emptySet()); + when(settings.getMuteCommands()).thenReturn(Collections.emptySet()); + when(settings.isCommandCooldownsEnabled()).thenReturn(true); + when(settings.getCommandCooldownEntry("feed")).thenReturn(new AbstractMap.SimpleImmutableEntry<>(cooldownPattern, 60_000L)); + when(user.getCommandCooldowns()).thenReturn(Collections.emptyMap()); + listener = new EssentialsPlayerListener(ess); + } + + @AfterEach + public void tearDown() { + MockBukkit.unmock(); + } + + @Test + public void testUnregisteredCaseVariantDoesNotStartCooldown() { + listener.onPlayerCommandPreprocess(new PlayerCommandPreprocessEvent(player, "/EFEED")); + + verify(settings, never()).getCommandCooldownEntry(anyString()); + verify(user, never()).addCommandCooldown(any(Pattern.class), any(Date.class), anyBoolean()); + } + + @Test + public void testRegisteredAliasStartsCanonicalCommandCooldown() { + listener.onPlayerCommandPreprocess(new PlayerCommandPreprocessEvent(player, "/efeed")); + + verify(settings).getCommandCooldownEntry("feed"); + verify(user).addCommandCooldown(eq(cooldownPattern), any(Date.class), eq(false)); + } +}