Use a filter permission to see if a player can use the root command.

The permission is set as child of all command permissions 
(sub commands of the root command). This is done in post enable to not
have to add it 100 times to the plugin.yml. Hopefully permission plugins
handle this right, superperms (permissions.yml) does.
This commit is contained in:
asofold 2013-06-12 02:08:22 +02:00
parent 00696c1624
commit 21442c4e22
5 changed files with 80 additions and 23 deletions

View File

@ -30,6 +30,7 @@ import fr.neatmonster.nocheatplus.command.admin.notify.NotifyCommand;
import fr.neatmonster.nocheatplus.components.INotifyReload;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
/*
* MM'""""'YMM dP
@ -114,6 +115,18 @@ public class NoCheatPlusCommand extends BaseCommand{
}
}
/**
* Retrieve a collection with all sub-command permissions.
* @return
*/
public Collection<String> getAllSubCommandPermissions(){
final Set<String> set = new LinkedHashSet<String>(rootLabels.size());
for (final String label : rootLabels){
set.add(subCommands.get(label).permission);
}
return set;
}
/* (non-Javadoc)
* @see org.bukkit.command.CommandExecutor#onCommand(org.bukkit.command.CommandSender, org.bukkit.command.Command,
* java.lang.String, java.lang.String[])
@ -128,22 +141,13 @@ public class NoCheatPlusCommand extends BaseCommand{
* | |__| (_) | | | | | | | | | | | (_| | | | | (_| |
* \____\___/|_| |_| |_|_| |_| |_|\__,_|_| |_|\__,_|
*/
if (!command.getName().equalsIgnoreCase("nocheatplus")){
// Not our command, how did it get here?
if (!command.getName().equalsIgnoreCase("nocheatplus"))
return false;
final boolean protectPlugins = ConfigManager.getConfigFile().getBoolean(ConfPaths.MISCELLANEOUS_PROTECTPLUGINS);
// Bit crude workaround.
// TODO: Replace this by checking a permission set as child permission of each and every child command.
boolean hasSomePermission = false;
for (AbstractCommand<?> cmd : subCommands.values()){
if (sender.hasPermission(cmd.permission)){
hasSomePermission = true;
}
}
if (hasSomePermission){
if (sender.hasPermission(Permissions.FEATURE_COMMAND_NOCHEATPLUS)){
// Check sub-commands.
if (args.length > 0){
AbstractCommand<?> subCommand = subCommands.get(args[0].trim().toLowerCase());
@ -156,14 +160,15 @@ public class NoCheatPlusCommand extends BaseCommand{
return false;
}
if (protectPlugins){
if (ConfigManager.getConfigFile().getBoolean(ConfPaths.MISCELLANEOUS_PROTECTPLUGINS)){
// Prevent the NCP usage printout:
sender.sendMessage("Unknown command. Type \"help\" for help.");
return true;
}
else
else{
return false;
}
}
// /**
// * Check which of the choices starts with prefix

View File

@ -125,4 +125,28 @@ public class PermissionUtil {
}
return changed;
}
/**
* Set a permission as child for all the other permissions given in a Collection.
* @param permissions Not expected to exist.
* @param childPermissionName
*/
public static void addChildPermission(final Collection<String> permissions, final String childPermissionName, final PermissionDefault permissionDefault) {
final PluginManager pm = Bukkit.getPluginManager();
Permission childPermission = pm.getPermission(childPermissionName);
if (childPermission == null){
childPermission = new Permission(childPermissionName, "auto-generated child permission (NoCheatPlus)", permissionDefault);
pm.addPermission(childPermission);
}
for (final String permissionName : permissions){
Permission permission = pm.getPermission(permissionName);
if (permission == null){
permission = new Permission(permissionName, "auto-generated permission (NoCheatPlus)", permissionDefault);
pm.addPermission(permission);
}
if (!permission.getChildren().containsKey(childPermissionName)){
childPermission.addParent(permission, true);
}
}
}
}

View File

@ -52,6 +52,11 @@ public class Permissions {
private final static String BYPASS = NOCHEATPLUS + ".bypass";
public static final String BYPASS_DENY_LOGIN = BYPASS + "denylogin";
private static final String FEATURE = "feature";
public static final String FEATURE_COMMAND = FEATURE + ".command";
public static final String FEATURE_COMMAND_NOCHEATPLUS = FEATURE_COMMAND + ".nocheatplus";
// Permissions for the individual checks.
public static final String CHECKS = NOCHEATPLUS + ".checks";

View File

@ -30,6 +30,7 @@ import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
@ -641,7 +642,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
protected void setupCommandProtection() {
final List<CommandProtectionEntry> changedCommands = PermissionUtil.protectCommands(
Arrays.asList("plugins", "version", "icanhasbukkit"), "nocheatplus.feature.command", false);
Arrays.asList("plugins", "version", "icanhasbukkit"), Permissions.FEATURE_COMMAND, false);
if (this.changedCommands == null) this.changedCommands = changedCommands;
else this.changedCommands.addAll(changedCommands);
}
@ -761,8 +762,8 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
}
// Register the commands handler.
PluginCommand command = getCommand("nocheatplus");
NoCheatPlusCommand commandHandler = new NoCheatPlusCommand(this, notifyReload);
final PluginCommand command = getCommand("nocheatplus");
final NoCheatPlusCommand commandHandler = new NoCheatPlusCommand(this, notifyReload);
command.setExecutor(commandHandler);
// (CommandHandler is TabExecutor.)
@ -846,7 +847,15 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
@Override
public void run() {
postEnable(onlinePlayers);
postEnable(onlinePlayers,
new Runnable() {
@Override
public void run() {
// Set child permissions for commands for faster checking.
PermissionUtil.addChildPermission(commandHandler.getAllSubCommandPermissions(), Permissions.FEATURE_COMMAND_NOCHEATPLUS, PermissionDefault.OP);
}
}
);
}
});
@ -961,7 +970,16 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
/**
* Actions to be done after enable of all plugins. This aims at reloading mainly.
*/
private void postEnable(final Player[] onlinePlayers){
private void postEnable(final Player[] onlinePlayers, Runnable... runnables){
for (final Runnable runnable : runnables){
try{
runnable.run();
}
catch(Throwable t){
LogUtil.logSevere("[NoCheatPlus] Encountered a problem during post-enable: " + t.getClass().getSimpleName());
LogUtil.logSevere(t);
}
}
for (final Player player : onlinePlayers){
updatePermStateReceivers(player);
NCPExemptionManager.registerPlayer(player);

View File

@ -77,6 +77,11 @@ permissions:
children:
nocheatplus.bypass.denylogin:
description: Bypass the login denial, such as exists with the ncp tempkick command.
nocheatplus.feature.command:
description: Allows use of all commands protected by the command protection, like the ncp root command. Does not give functionality but allow seeing usage and tab-completion of the command. In future there can be many children not listed in this config.
children:
nocheatplus.feature.command.nocheatplus:
description: Filter permission to allow using sub commands of the /nocheatplus command. This permission should not be necessary to ever be given to any player unless the permission plugin is incompatible with aspects of super-perms.
nocheatplus.checks:
description: Allow the player to bypass all checks.
children: