diff --git a/modules/mapping/api/src/main/java/org/bitbucket/_newage/commandhook/util/VersionUtil.java b/modules/mapping/api/src/main/java/org/bitbucket/_newage/commandhook/util/VersionUtil.java new file mode 100644 index 0000000..9dd560f --- /dev/null +++ b/modules/mapping/api/src/main/java/org/bitbucket/_newage/commandhook/util/VersionUtil.java @@ -0,0 +1,25 @@ +package org.bitbucket._newage.commandhook.util; + +import org.bukkit.Bukkit; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class VersionUtil { + private static final Pattern BUKKIT_VERSION_PATTERN = Pattern.compile("(\\d+\\.\\d+(\\.\\d+)?)"); + private static final Pattern MINOR_VERSION_PATTERN = Pattern.compile("\\d+\\.(\\d+)(\\.\\d+)?"); + + public static String getMinecraftVersion() { + final Matcher bukkitVersionMatcher = BUKKIT_VERSION_PATTERN.matcher(Bukkit.getServer().getBukkitVersion()); + + if (bukkitVersionMatcher.find()) { + return bukkitVersionMatcher.group(); + } + return null; + } + public static int getMinorVersion(String minecraftVersion) { + final Matcher minorVersionMatcher = MINOR_VERSION_PATTERN.matcher(minecraftVersion); + minorVersionMatcher.find(); + return Integer.parseInt(minorVersionMatcher.group(1)); + } +} diff --git a/modules/mapping/spigot/provider/src/main/java/org/bitbucket/_newage/commandhook/mapping/SpigotMappingSelector.java b/modules/mapping/spigot/provider/src/main/java/org/bitbucket/_newage/commandhook/mapping/SpigotMappingSelector.java index 9c526c8..4d8121d 100644 --- a/modules/mapping/spigot/provider/src/main/java/org/bitbucket/_newage/commandhook/mapping/SpigotMappingSelector.java +++ b/modules/mapping/spigot/provider/src/main/java/org/bitbucket/_newage/commandhook/mapping/SpigotMappingSelector.java @@ -5,13 +5,13 @@ import org.bitbucket._newage.commandhook.mapping.api.IMapping; import org.bitbucket._newage.commandhook.mapping.api.MappingSelector; +import org.bitbucket._newage.commandhook.util.VersionUtil; import org.bukkit.Bukkit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SpigotMappingSelector extends MappingSelector { private static final Pattern NMS_PATTERN = Pattern.compile("(v\\d+_\\d+_\\w+)"); - private static final Pattern BUKKIT_VERSION_PATTERN = Pattern.compile("(\\d+\\.\\d+(\\.\\d+)?)"); private static final Logger log = LoggerFactory.getLogger(SpigotMappingSelector.class); @Override @@ -30,11 +30,10 @@ public IMapping getMapping() { } private IMapping getMappingFromBukkitVersion() { - final Matcher bukkitVersionMatcher = BUKKIT_VERSION_PATTERN.matcher(Bukkit.getServer().getBukkitVersion()); + String version = VersionUtil.getMinecraftVersion(); IMapping mapping = null; - if (bukkitVersionMatcher.find()) { - String version = bukkitVersionMatcher.group(); + if (version != null) { log.info("Minecraft version found: {}", version); mapping = fromMinecraftVersion(version); } diff --git a/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandBlockListener.java b/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandBlockListener.java index 14503e2..27952ac 100644 --- a/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandBlockListener.java +++ b/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandBlockListener.java @@ -4,6 +4,7 @@ import java.util.regex.Pattern; import org.bitbucket._newage.commandhook.mapping.api.IMapping; +import org.bitbucket._newage.commandhook.util.VersionUtil; import org.bukkit.Bukkit; import org.bukkit.command.BlockCommandSender; @@ -16,10 +17,15 @@ public class CommandBlockListener implements Listener { private static final Pattern SELECTOR_PATTERN = Pattern.compile("@[aeprs]([^a-zA-Z0-9]|$)"); + private static final Pattern SELECTOR_PATTERN_WITH_AT_N = Pattern.compile("@[aenprs]([^a-zA-Z0-9]|$)"); + private final IMapping mapping; + private final Pattern selectorPattern; - public CommandBlockListener(IMapping mapping) { + public CommandBlockListener(IMapping mapping, String minecraftVersion) { this.mapping = mapping; + int minorVersion = VersionUtil.getMinorVersion(minecraftVersion); + selectorPattern = minorVersion >= 21 ? SELECTOR_PATTERN_WITH_AT_N : SELECTOR_PATTERN; } @EventHandler(priority = EventPriority.MONITOR) @@ -34,7 +40,7 @@ public void onCommandBlockDispatch(ServerCommandEvent e) { return; } - if (SELECTOR_PATTERN.matcher(cmd).find()) { + if (selectorPattern.matcher(cmd).find()) { String selector = getSelectorWithArguments(cmd); List entities = mapping.getEntitiesFromSelector(selector, ((BlockCommandSender) e.getSender()).getBlock()); diff --git a/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandHook.java b/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandHook.java index ffdad82..95ad1e6 100644 --- a/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandHook.java +++ b/modules/plugin/src/main/java/org/bitbucket/_newage/commandhook/CommandHook.java @@ -3,6 +3,7 @@ import org.bitbucket._newage.commandhook.mapping.MappingProvider; import org.bitbucket._newage.commandhook.mapping.ServerBrand; import org.bitbucket._newage.commandhook.mapping.api.IMapping; +import org.bitbucket._newage.commandhook.util.VersionUtil; import org.bukkit.plugin.java.JavaPlugin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,7 +20,7 @@ public void onEnable() { return; } - CommandBlockListener listener = new CommandBlockListener(mapping); + CommandBlockListener listener = new CommandBlockListener(mapping, VersionUtil.getMinecraftVersion()); getServer().getPluginManager().registerEvents(listener, this); } diff --git a/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorParserTest.java b/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorParserTest.java index 87bcc59..2ae4082 100644 --- a/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorParserTest.java +++ b/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorParserTest.java @@ -23,6 +23,14 @@ void testSelectorNoArgumentsAtTheEnd() { assertEquals("@a", result); } + @Test + void testSelectorAtN() { + final String selector = "tp @n[type=player] ~ ~1 ~"; + final String result = getSelectorWithArguments(selector); + + assertEquals("@n[type=player]", result); + } + @Test void testSelectorWithArguments() { final String selector = "/kick @e[type=player,distance=..2] Too close to me"; diff --git a/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorRegexTest.java b/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorRegexTest.java index 1c5dfd0..57c7b03 100644 --- a/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorRegexTest.java +++ b/modules/plugin/src/test/java/org/bitbucket/_newage/commandhook/SelectorRegexTest.java @@ -13,7 +13,7 @@ class SelectorRegexTest { private final BlockCommandSender sender = mock(); private final IMapping mapping = mock(); - private final CommandBlockListener listener = new CommandBlockListener(mapping); + private final CommandBlockListener listener = new CommandBlockListener(mapping, "1.21"); @Test void verifyNoInteractionsForMinecraftVanillaCommand() {