Add better perms handling and a way to disable options for constructing disguises
This commit is contained in:
parent
f02d212c9b
commit
c1ada67da6
@ -2,7 +2,9 @@ package me.libraryaddict.disguise;
|
|||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
import me.libraryaddict.disguise.disguisetypes.AnimalColor;
|
import me.libraryaddict.disguise.disguisetypes.AnimalColor;
|
||||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||||
@ -18,17 +20,41 @@ import org.bukkit.entity.Horse.Style;
|
|||||||
import org.bukkit.entity.Ocelot.Type;
|
import org.bukkit.entity.Ocelot.Type;
|
||||||
import org.bukkit.entity.Villager.Profession;
|
import org.bukkit.entity.Villager.Profession;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||||
import org.bukkit.potion.PotionEffectType;
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
|
||||||
public abstract class BaseDisguiseCommand implements CommandExecutor {
|
public abstract class BaseDisguiseCommand implements CommandExecutor {
|
||||||
|
|
||||||
protected ArrayList<String> getAllowedDisguises(CommandSender sender, String permissionNode) {
|
protected ArrayList<String> getAllowedDisguises(CommandSender sender, String permissionNode) {
|
||||||
ArrayList<String> names = new ArrayList<String>();
|
ArrayList<String> names = new ArrayList<String>();
|
||||||
for (DisguiseType type : DisguiseType.values()) {
|
ArrayList<String> forbiddenDisguises = new ArrayList<String>();
|
||||||
String name = type.name().toLowerCase();
|
for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) {
|
||||||
if (sender.hasPermission("libsdisguises." + permissionNode + ".*")
|
String perm = permission.getPermission().toLowerCase();
|
||||||
|| sender.hasPermission("libsdisguises." + permissionNode + "." + name))
|
if (perm.startsWith(permissionNode)) {
|
||||||
names.add(name);
|
perm = perm.substring(permissionNode.length());
|
||||||
|
for (DisguiseType type : DisguiseType.values()) {
|
||||||
|
String name = type.name().toLowerCase();
|
||||||
|
if (perm.split("//.")[0].equals("*") && permission.getValue()) {
|
||||||
|
names.add(name);
|
||||||
|
} else if (perm.split("//.")[0].equals(name)) {
|
||||||
|
if (permission.getValue()) {
|
||||||
|
names.add(name);
|
||||||
|
} else {
|
||||||
|
forbiddenDisguises.add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for (DisguiseType type : DisguiseType.values()) {
|
||||||
|
if (!names.contains(type.name().toLowerCase())) {
|
||||||
|
if (sender.hasPermission(permissionNode + "*")
|
||||||
|
|| sender.hasPermission(permissionNode + type.name().toLowerCase())) {
|
||||||
|
names.add(type.name().toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
names.removeAll(forbiddenDisguises);
|
||||||
Collections.sort(names, String.CASE_INSENSITIVE_ORDER);
|
Collections.sort(names, String.CASE_INSENSITIVE_ORDER);
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
@ -51,13 +77,41 @@ public abstract class BaseDisguiseCommand implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns null if they have all perms. Else they can only use the options in the returned
|
||||||
|
*/
|
||||||
|
protected HashSet<HashSet<String>> getPermissions(CommandSender sender, String disguiseType) {
|
||||||
|
HashSet<HashSet<String>> perms = new HashSet<HashSet<String>>();
|
||||||
|
String permNode = "libsdisguises." + getClass().getSimpleName().replace("Command", "").toLowerCase() + ".";
|
||||||
|
for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) {
|
||||||
|
if (permission.getValue()) {
|
||||||
|
String s = permission.getPermission().toLowerCase();
|
||||||
|
if (s.startsWith(permNode + disguiseType) || s.startsWith(permNode + "*")) {
|
||||||
|
if (s.startsWith(permNode + disguiseType))
|
||||||
|
s = s.substring((permNode + disguiseType).length());
|
||||||
|
else if (s.startsWith(permNode + "*")) {
|
||||||
|
s = s.substring((permNode + "*").length());
|
||||||
|
if (s.length() == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (s.length() == 0)
|
||||||
|
return new HashSet<HashSet<String>>();
|
||||||
|
HashSet<String> p = new HashSet<String>();
|
||||||
|
p.addAll(Arrays.asList(s.split("\\.")));
|
||||||
|
perms.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return perms;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the disguise if it all parsed correctly. Returns a exception with a complete message if it didn't. The
|
* Returns the disguise if it all parsed correctly. Returns a exception with a complete message if it didn't. The
|
||||||
* commandsender is purely used for checking permissions. Would defeat the purpose otherwise. To reach this point, the
|
* commandsender is purely used for checking permissions. Would defeat the purpose otherwise. To reach this point, the
|
||||||
* disguise has been feed a proper disguisetype.
|
* disguise has been feed a proper disguisetype.
|
||||||
*/
|
*/
|
||||||
protected Disguise parseDisguise(CommandSender sender, String[] args) throws Exception {
|
protected Disguise parseDisguise(CommandSender sender, String[] args) throws Exception {
|
||||||
String permissionNode = getClass().getSimpleName().replace("Command", "").toLowerCase();
|
String permissionNode = "libsdisguises." + getClass().getSimpleName().replace("Command", "").toLowerCase() + ".";
|
||||||
ArrayList<String> allowedDisguises = getAllowedDisguises(sender, permissionNode);
|
ArrayList<String> allowedDisguises = getAllowedDisguises(sender, permissionNode);
|
||||||
if (allowedDisguises.isEmpty()) {
|
if (allowedDisguises.isEmpty()) {
|
||||||
throw new Exception(ChatColor.RED + "You are forbidden to use this command.");
|
throw new Exception(ChatColor.RED + "You are forbidden to use this command.");
|
||||||
@ -80,11 +134,14 @@ public abstract class BaseDisguiseCommand implements CommandExecutor {
|
|||||||
if (!allowedDisguises.contains(disguiseType.name().toLowerCase())) {
|
if (!allowedDisguises.contains(disguiseType.name().toLowerCase())) {
|
||||||
throw new Exception(ChatColor.RED + "You are forbidden to use this disguise!");
|
throw new Exception(ChatColor.RED + "You are forbidden to use this disguise!");
|
||||||
}
|
}
|
||||||
|
HashSet<String> usedOptions = new HashSet<String>();
|
||||||
Disguise disguise = null;
|
Disguise disguise = null;
|
||||||
// How many args to skip due to the disugise being constructed
|
// How many args to skip due to the disugise being constructed
|
||||||
int toSkip = 1;
|
int toSkip = 1;
|
||||||
// Time to start constructing the disguise.
|
// Time to start constructing the disguise.
|
||||||
// We will need to check between all 3 kinds of disguises
|
// We will need to check between all 3 kinds of disguises
|
||||||
|
|
||||||
|
HashSet<HashSet<String>> optionPermissions = this.getPermissions(sender, disguiseType.name().toLowerCase());
|
||||||
if (disguiseType.isPlayer()) {// If he is doing a player disguise
|
if (disguiseType.isPlayer()) {// If he is doing a player disguise
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
// He needs to give the player name
|
// He needs to give the player name
|
||||||
@ -99,11 +156,15 @@ public abstract class BaseDisguiseCommand implements CommandExecutor {
|
|||||||
boolean adult = true;
|
boolean adult = true;
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
if (args[1].equalsIgnoreCase("true") || args[1].equalsIgnoreCase("false")) {
|
if (args[1].equalsIgnoreCase("true") || args[1].equalsIgnoreCase("false")) {
|
||||||
|
usedOptions.add("setbaby");
|
||||||
|
doCheck(optionPermissions, usedOptions);
|
||||||
adult = "false".equalsIgnoreCase(args[1]);
|
adult = "false".equalsIgnoreCase(args[1]);
|
||||||
sender.sendMessage(ChatColor.RED
|
sender.sendMessage(ChatColor.RED
|
||||||
+ "I notice you are using true/false for constructing a mob disguise! This will soon be removed in favor of the simple 'baby'");
|
+ "I notice you are using true/false for constructing a mob disguise! This will soon be removed in favor of the simple 'baby'");
|
||||||
toSkip++;
|
toSkip++;
|
||||||
} else if (args[1].equalsIgnoreCase("baby")) {
|
} else if (args[1].equalsIgnoreCase("baby")) {
|
||||||
|
usedOptions.add("setbaby");
|
||||||
|
doCheck(optionPermissions, usedOptions);
|
||||||
adult = false;
|
adult = false;
|
||||||
toSkip++;
|
toSkip++;
|
||||||
}
|
}
|
||||||
@ -138,7 +199,6 @@ public abstract class BaseDisguiseCommand implements CommandExecutor {
|
|||||||
newArgs[i - toSkip] = args[i];
|
newArgs[i - toSkip] = args[i];
|
||||||
}
|
}
|
||||||
args = newArgs;
|
args = newArgs;
|
||||||
// Don't throw a error about uneven methods names and values so we can throw the error about what is unknown later.
|
|
||||||
for (int i = 0; i < args.length; i += 2) {
|
for (int i = 0; i < args.length; i += 2) {
|
||||||
String methodName = args[i];
|
String methodName = args[i];
|
||||||
if (i + 1 >= args.length) {
|
if (i + 1 >= args.length) {
|
||||||
@ -266,12 +326,25 @@ public abstract class BaseDisguiseCommand implements CommandExecutor {
|
|||||||
if (methodToUse == null) {
|
if (methodToUse == null) {
|
||||||
throw new Exception(ChatColor.RED + "Cannot find the option " + methodName);
|
throw new Exception(ChatColor.RED + "Cannot find the option " + methodName);
|
||||||
}
|
}
|
||||||
|
usedOptions.add(methodName.toLowerCase());
|
||||||
|
doCheck(optionPermissions, usedOptions);
|
||||||
methodToUse.invoke(disguise.getWatcher(), value);
|
methodToUse.invoke(disguise.getWatcher(), value);
|
||||||
}
|
}
|
||||||
// Alright. We've constructed our disguise.
|
// Alright. We've constructed our disguise.
|
||||||
return disguise;
|
return disguise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doCheck(HashSet<HashSet<String>> optionPermissions, HashSet<String> usedOptions) throws Exception {
|
||||||
|
if (!optionPermissions.isEmpty()) {
|
||||||
|
for (HashSet<String> perms : optionPermissions) {
|
||||||
|
if (!perms.containsAll(usedOptions)) {
|
||||||
|
throw new Exception(ChatColor.RED + "You do not have the permission to use the option "
|
||||||
|
+ usedOptions.iterator().next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Exception parseToException(String expectedValue, String receivedInstead, String methodName) {
|
private Exception parseToException(String expectedValue, String receivedInstead, String methodName) {
|
||||||
return new Exception(ChatColor.RED + "Expected " + ChatColor.GREEN + expectedValue + ChatColor.RED + ", received "
|
return new Exception(ChatColor.RED + "Expected " + ChatColor.GREEN + expectedValue + ChatColor.RED + ", received "
|
||||||
+ ChatColor.GREEN + receivedInstead + ChatColor.RED + " instead for " + ChatColor.GREEN + methodName);
|
+ ChatColor.GREEN + receivedInstead + ChatColor.RED + " instead for " + ChatColor.GREEN + methodName);
|
||||||
|
Loading…
Reference in New Issue
Block a user