今天用插件scripBlockPlus的时候呢,发现一个问题,就是插件没办法执行luckperms的部分指令
最后没办法跑去翻sbp的源码,发现了一个有趣的东西,就是它在执行命令的时候,在版本1.13之后,会调用nms里面的方法,而不是用bukkit的dispatchCommand, 没有继续翻,猜测是调用的命令方块的 方法。
那么,为什么作者不直接用bukkit的方法而使用nms里面的呢
而且命令方块的执行的话应该很多限制吧。
而且这个方法也被标明废弃了,虽然最新版还在用。。。
复制代码
最后没办法跑去翻sbp的源码,发现了一个有趣的东西,就是它在执行命令的时候,在版本1.13之后,会调用nms里面的方法,而不是用bukkit的dispatchCommand, 没有继续翻,猜测是调用的命令方块的 方法。
那么,为什么作者不直接用bukkit的方法而使用nms里面的呢
而且命令方块的执行的话应该很多限制吧。
而且这个方法也被标明废弃了,虽然最新版还在用。。。
- @SuppressWarnings("deprecation")
- public static boolean dispatchCommand(@NotNull CommandSender sender, @Nullable Location location, @NotNull String command) {
- Validate.notNull(sender, "Sender cannot be null");
- Validate.notNull(command, "Command cannot be null");
- boolean isCommandSelector = isPlatform() && SBConfig.COMMAND_SELECTOR.getValue();
- if (isCommandSelector && (isCBXXXorLater("1.13") || CommandSelector.isCommandPattern(command))) {
- if (location == null) {
- if (sender instanceof Player) {
- location = ((Player) sender).getLocation().clone();
- } else if (sender instanceof SBPlayer) {
- location = ((SBPlayer) sender).getLocation().clone();
- } else if (sender instanceof BlockCommandSender) {
- location = ((BlockCommandSender) sender).getBlock().getLocation().clone();
- } else if (sender instanceof CommandMinecart) {
- location = ((CommandMinecart) sender).getLocation().clone();
- }
- }
- if (location != null) {
- return CommandSelector.getListener().executeCommand(sender, location, command);
- }
- }
- return Bukkit.dispatchCommand(sender, command.startsWith("/") ? command.substring(1) : command);
- }
本帖最后由 蕾米洛伊 于 2020-7-2 00:26 编辑
因为它要对 @p 这些选择器做支持
猜测
因为它要对 @p 这些选择器做支持
猜测
本帖最后由 疾风暗影 于 2020-7-2 01:35 编辑
这实际牵扯到了spigot 1.13 API升级中争议非常大的一项改动
实际原因如下
https://github.com/yuttyann/Scri ... keCommandBlock.java
也就是作者希望匹配指令选择器(如楼上说的@p @a)之类
在1.12.2及以下版本,直接Bukkit.dispatchCommand即可
在1.13之后,Spigot做出了如下改动
https://hub.spigotmc.org/jira/browse/SPIGOT-4327
Spigot项目负责人md_5给出的评论如下:
也就是指令选择器是vanilla的东西,bukkit本就不应该支持
为了使用指令选择器,只好调用nms方法
至于部分指令无法使用,原因可能与vanilla/bukkit的不同namespace有关,尝试用luckperms:lp的形式调用
实际作者最早用的COMMAND_PATTERN判断有无选择器是最好的方法,可惜在后续commit中,作者改成了根据版本号一刀切
这实际牵扯到了spigot 1.13 API升级中争议非常大的一项改动
实际原因如下
https://github.com/yuttyann/Scri ... keCommandBlock.java
private static final Pattern COMMAND_PATTERN = Pattern.compile("^@([parf])(?:\\[([\\w=,!-]*)\\])?$");
也就是作者希望匹配指令选择器(如楼上说的@p @a)之类
在1.12.2及以下版本,直接Bukkit.dispatchCommand即可
在1.13之后,Spigot做出了如下改动
https://hub.spigotmc.org/jira/browse/SPIGOT-4327
Spigot项目负责人md_5给出的评论如下:
Yes, Bukkit should have never allowed mixing of Vanilla and Bukkit things - it completely breaks any map etc written for Vanilla as soon as plugins are added.
This is essentially a wontfix for me, I think it is working as designed.
If you (or someone else) want to add this as an optional "feature" then feel free, but it almost certainly involves rewriting the entire command system.
也就是指令选择器是vanilla的东西,bukkit本就不应该支持
为了使用指令选择器,只好调用nms方法
至于部分指令无法使用,原因可能与vanilla/bukkit的不同namespace有关,尝试用luckperms:lp的形式调用
实际作者最早用的COMMAND_PATTERN判断有无选择器是最好的方法,可惜在后续commit中,作者改成了根据版本号一刀切
疾风暗影 发表于 2020-7-2 01:33
这实际牵扯到了spigot 1.13 API升级中争议非常大的一项改动
实际原因如下
luckperms:lp这个方法无效
不过sbp那段判断实际已经包含了对命令是否选择做了筛选
- CommandSelector.isCommandPattern(command)
只是有个地方
- SBConfig.COMMAND_SELECTOR.getValue()
强制使用了命令选择器的模式
所以,只要把config里面的对应选项设置为false就可以用了