Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix command permission messages (2.7.1 issue) #6126

Merged
merged 1 commit into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 43 additions & 25 deletions src/main/java/ch/njol/skript/command/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.help.HelpMap;
import org.bukkit.help.HelpTopic;
Expand Down Expand Up @@ -68,7 +69,7 @@
*/
@SuppressWarnings("deprecation")
public abstract class Commands {

public final static ArgsMessage m_too_many_arguments = new ArgsMessage("commands.too many arguments");
public final static Message m_internal_error = new Message("commands.internal error");
public final static Message m_correct_usage = new Message("commands.correct usage");
Expand All @@ -79,38 +80,38 @@ public abstract class Commands {
public static final int CONVERTER_NO_COMMAND_ARGUMENTS = 4;

private final static Map<String, ScriptCommand> commands = new HashMap<>();

@Nullable
private static SimpleCommandMap commandMap = null;
@Nullable
private static Map<String, Command> cmKnownCommands;
@Nullable
private static Set<String> cmAliases;

static {
init(); // separate method for the annotation
}
public static Set<String> getScriptCommands(){
return commands.keySet();
}

@Nullable
public static SimpleCommandMap getCommandMap(){
return commandMap;
}

@SuppressWarnings("unchecked")
private static void init() {
try {
if (Bukkit.getPluginManager() instanceof SimplePluginManager) {
Field commandMapField = SimplePluginManager.class.getDeclaredField("commandMap");
commandMapField.setAccessible(true);
commandMap = (SimpleCommandMap) commandMapField.get(Bukkit.getPluginManager());

Field knownCommandsField = SimpleCommandMap.class.getDeclaredField("knownCommands");
knownCommandsField.setAccessible(true);
cmKnownCommands = (Map<String, Command>) knownCommandsField.get(commandMap);

try {
Field aliasesField = SimpleCommandMap.class.getDeclaredField("aliases");
aliasesField.setAccessible(true);
Expand All @@ -125,25 +126,42 @@ private static void init() {
commandMap = null;
}
}

@Nullable
public static List<Argument<?>> currentArguments = null;

@SuppressWarnings("null")
private final static Pattern escape = Pattern.compile("[" + Pattern.quote("(|)<>%\\") + "]");
@SuppressWarnings("null")
private final static Pattern unescape = Pattern.compile("\\\\[" + Pattern.quote("(|)<>%\\") + "]");

public static String escape(String string) {
return "" + escape.matcher(string).replaceAll("\\\\$0");
}

public static String unescape(String string) {
return "" + unescape.matcher(string).replaceAll("$0");
}

private final static Listener commandListener = new Listener() {
@SuppressWarnings("null")

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
// Spigot will simply report that the command doesn't exist if a player does not have permission to use it.
// This is good security but, well, it's a breaking change for Skript. So we need to check for permissions
// ourselves and handle those messages, for every command.

// parse command, see if it's a skript command
String[] cmd = event.getMessage().substring(1).split("\\s+", 2);
String label = cmd[0].toLowerCase(Locale.ENGLISH);
String arguments = cmd.length == 1 ? "" : "" + cmd[1];
ScriptCommand command = commands.get(label);

// if so, check permissions
if (command != null && !command.checkPermissions(event.getPlayer(), label, arguments))
event.setCancelled(true);
}

@EventHandler(priority = EventPriority.HIGHEST)
public void onServerCommand(ServerCommandEvent event) {
if (event.getCommand().isEmpty() || event.isCancelled())
Expand All @@ -154,7 +172,7 @@ public void onServerCommand(ServerCommandEvent event) {
}
}
};

static boolean handleEffectCommand(CommandSender sender, String command) {
if (!(sender instanceof ConsoleCommandSender || sender.hasPermission("skript.effectcommands") || SkriptConfig.allowOpsToUseEffectCommands.value() && sender.isOp()))
return false;
Expand All @@ -170,7 +188,7 @@ static boolean handleEffectCommand(CommandSender sender, String command) {
parserInstance.setCurrentEvent("effect command", EffectCommandEvent.class);
Effect effect = Effect.parse(command, null);
parserInstance.deleteCurrentEvent();

if (effect != null) {
log.clear(); // ignore warnings and stuff
log.printLog();
Expand Down Expand Up @@ -219,7 +237,7 @@ public static boolean scriptCommandExists(String command) {
ScriptCommand scriptCommand = commands.get(command);
return scriptCommand != null && scriptCommand.getName().equals(command);
}

public static void registerCommand(ScriptCommand command) {
// Validate that there are no duplicates
ScriptCommand existingCommand = commands.get(command.getLabel());
Expand All @@ -230,7 +248,7 @@ public static void registerCommand(ScriptCommand command) {
);
return;
}

if (commandMap != null) {
assert cmKnownCommands != null;// && cmAliases != null;
command.register(commandMap, cmKnownCommands, cmAliases);
Expand Down Expand Up @@ -262,9 +280,9 @@ public static void unregisterCommand(ScriptCommand scriptCommand) {
}
commands.values().removeIf(command -> command == scriptCommand);
}

private static boolean registeredListeners = false;

public static void registerListeners() {
if (!registeredListeners) {
Bukkit.getPluginManager().registerEvents(commandListener, Skript.getInstance());
Expand Down Expand Up @@ -298,23 +316,23 @@ public void onPlayerChat(AsyncPlayerChatEvent event) {
registeredListeners = true;
}
}

/**
* copied from CraftBukkit (org.bukkit.craftbukkit.help.CommandAliasHelpTopic)
*/
public static final class CommandAliasHelpTopic extends HelpTopic {

private final String aliasFor;
private final HelpMap helpMap;

public CommandAliasHelpTopic(String alias, String aliasFor, HelpMap helpMap) {
this.aliasFor = aliasFor.startsWith("/") ? aliasFor : "/" + aliasFor;
this.helpMap = helpMap;
name = alias.startsWith("/") ? alias : "/" + alias;
Validate.isTrue(!name.equals(this.aliasFor), "Command " + name + " cannot be alias for itself");
shortText = ChatColor.YELLOW + "Alias for " + ChatColor.WHITE + this.aliasFor;
}

@Override
@NotNull
public String getFullText(CommandSender forWho) {
Expand All @@ -326,7 +344,7 @@ public String getFullText(CommandSender forWho) {
}
return "" + fullText;
}

@Override
public boolean canSee(CommandSender commandSender) {
if (amendedPermission != null)
Expand All @@ -335,5 +353,5 @@ public boolean canSee(CommandSender commandSender) {
return aliasForTopic != null && aliasForTopic.canSee(commandSender);
}
}

}
40 changes: 25 additions & 15 deletions src/main/java/ch/njol/skript/command/ScriptCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public class ScriptCommand implements TabExecutor {

/**
* Creates a new SkriptCommand.
*
*
* @param name /name
* @param pattern
* @param arguments the list of Arguments this command takes
Expand Down Expand Up @@ -237,16 +237,8 @@ public boolean execute(final CommandSender sender, final String commandLabel, fi

final ScriptCommandEvent event = new ScriptCommandEvent(ScriptCommand.this, sender, commandLabel, rest);

if (!permission.isEmpty() && !sender.hasPermission(permission)) {
if (sender instanceof Player) {
List<MessageComponent> components =
permissionMessage.getMessageComponents(event);
((Player) sender).spigot().sendMessage(BungeeConverter.convert(components));
} else {
sender.sendMessage(permissionMessage.getSingle(event));
}
if (!checkPermissions(sender, event))
return false;
}

cooldownCheck : {
if (sender instanceof Player && cooldown != null) {
Expand Down Expand Up @@ -316,19 +308,37 @@ boolean execute2(final ScriptCommandEvent event, final CommandSender sender, fin
} finally {
log.stop();
}

if (Skript.log(Verbosity.VERY_HIGH))
Skript.info("# /" + name + " " + rest);
final long startTrigger = System.nanoTime();

if (!trigger.execute(event))
sender.sendMessage(Commands.m_internal_error.toString());

if (Skript.log(Verbosity.VERY_HIGH))
Skript.info("# " + name + " took " + 1. * (System.nanoTime() - startTrigger) / 1000000. + " milliseconds");
return true;
}

public boolean checkPermissions(CommandSender sender, String commandLabel, String arguments) {
return checkPermissions(sender, new ScriptCommandEvent(this, sender, commandLabel, arguments));
}

public boolean checkPermissions(CommandSender sender, Event event) {
if (!permission.isEmpty() && !sender.hasPermission(permission)) {
if (sender instanceof Player) {
List<MessageComponent> components =
permissionMessage.getMessageComponents(event);
((Player) sender).spigot().sendMessage(BungeeConverter.convert(components));
} else {
sender.sendMessage(permissionMessage.getSingle(event));
}
return false;
}
return true;
}

public void sendHelp(final CommandSender sender) {
if (!description.isEmpty())
sender.sendMessage(description);
Expand All @@ -337,7 +347,7 @@ public void sendHelp(final CommandSender sender) {

/**
* Gets the arguments this command takes.
*
*
* @return The internal list of arguments. Do not modify it!
*/
public List<Argument<?>> getArguments() {
Expand Down Expand Up @@ -575,7 +585,7 @@ public List<String> onTabComplete(@Nullable CommandSender sender, @Nullable Comm
Class<?> argType = arg.getType();
if (argType.equals(Player.class) || argType.equals(OfflinePlayer.class))
return null; // Default completion

return Collections.emptyList(); // No tab completion here!
}

Expand Down