From 652f414a545fe9b469f870cf53846deaeb871622 Mon Sep 17 00:00:00 2001 From: Leo G Date: Tue, 12 May 2020 16:07:05 +0200 Subject: [PATCH] Offline exempt permissions with Vault --- .../advancedban/manager/UUIDManager.java | 65 +++++++++------ .../utils/commands/PunishmentProcessor.java | 83 ++++++++++--------- src/main/resources/config.yml | 1 + src/main/resources/plugin.yml | 1 + 4 files changed, 88 insertions(+), 62 deletions(-) diff --git a/src/main/java/me/leoko/advancedban/manager/UUIDManager.java b/src/main/java/me/leoko/advancedban/manager/UUIDManager.java index 99a8dc3a..23a21d6a 100644 --- a/src/main/java/me/leoko/advancedban/manager/UUIDManager.java +++ b/src/main/java/me/leoko/advancedban/manager/UUIDManager.java @@ -32,23 +32,23 @@ public static UUIDManager get() { * Initially setup the uuid manager by determening which {@link FetcherMode} should be used * based on the configured preference and the servers capabilities. */ - public void setup(){ - if(mi.getBoolean(mi.getConfig(), "UUID-Fetcher.Dynamic", true)){ - if(!mi.isOnlineMode()) { + public void setup() { + if (mi.getBoolean(mi.getConfig(), "UUID-Fetcher.Dynamic", true)) { + if (!mi.isOnlineMode()) { mode = FetcherMode.DISABLED; - }else{ - if(Universal.get().isBungee()){ + } else { + if (Universal.get().isBungee()) { mode = FetcherMode.MIXED; - }else{ + } else { mode = FetcherMode.INTERN; } } - }else{ - if(!mi.getBoolean(mi.getConfig(), "UUID-Fetcher.Enabled", true)) { + } else { + if (!mi.getBoolean(mi.getConfig(), "UUID-Fetcher.Enabled", true)) { mode = FetcherMode.DISABLED; - }else if(mi.getBoolean(mi.getConfig(), "UUID-Fetcher.Intern", false)){ + } else if (mi.getBoolean(mi.getConfig(), "UUID-Fetcher.Intern", false)) { mode = FetcherMode.INTERN; - }else{ + } else { mode = FetcherMode.RESTFUL; } } @@ -63,12 +63,12 @@ public void setup(){ */ public String getInitialUUID(String name) { name = name.toLowerCase(); - if(mode == FetcherMode.DISABLED) + if (mode == FetcherMode.DISABLED) return name; - if(mode == FetcherMode.INTERN || mode == FetcherMode.MIXED) { + if (mode == FetcherMode.INTERN || mode == FetcherMode.MIXED) { String internUUID = mi.getInternUUID(name); - if(mode == FetcherMode.INTERN || internUUID != null) + if (mode == FetcherMode.INTERN || internUUID != null) return internUUID; } @@ -106,11 +106,26 @@ public String getInitialUUID(String name) { * @param uuid the uuid */ public void supplyInternUUID(String name, UUID uuid) { - if(mode == FetcherMode.INTERN || mode == FetcherMode.MIXED) { + if (mode == FetcherMode.INTERN || mode == FetcherMode.MIXED) { activeUUIDs.put(name, uuid.toString().replace("-", "")); } } + /** + * Convert String to UUID even if dashes are missing + * + * @param uuid + * @return + */ + public UUID fromString(String uuid) { + if (!uuid.contains("-") && uuid.length() == 32) + uuid = uuid + .replaceFirst( + "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", "$1-$2-$3-$4-$5"); + + return uuid.length() == 36 && uuid.contains("-") ? UUID.fromString(uuid) : null; + } + /** * Get the uuid to a name. * @@ -125,18 +140,18 @@ public String getUUID(String name) { /** * Gets a uuid from a name only if AdvancedBan * already has the uuid/name mapping in memory. - * + * * @param name the player name * @return the nonhyphenated uuid or null if not found */ public String getInMemoryUUID(String name) { - return activeUUIDs.get(name); + return activeUUIDs.get(name); } /** * Gets a name from a uuid only if AdvancedBan * already has the uuid/name mapping in memory. - * + * * @param uuid the uuid without hyphens * @return the player name or null if not found */ @@ -160,17 +175,17 @@ public String getNameFromUUID(String uuid, boolean forceInitial) { if (mode == FetcherMode.DISABLED) return uuid; - if(mode == FetcherMode.INTERN || mode == FetcherMode.MIXED) { + if (mode == FetcherMode.INTERN || mode == FetcherMode.MIXED) { String internName = mi.getName(uuid); - if(mode == FetcherMode.INTERN || internName != null) + if (mode == FetcherMode.INTERN || internName != null) return internName; } if (!forceInitial) { - String inMemoryName = getInMemoryName(uuid); - if (inMemoryName != null) { - return inMemoryName; - } + String inMemoryName = getInMemoryName(uuid); + if (inMemoryName != null) { + return inMemoryName; + } } try (Scanner scanner = new Scanner(new URL("https://api.mojang.com/user/profiles/" + uuid + "/names").openStream(), "UTF-8")) { @@ -182,6 +197,8 @@ public String getNameFromUUID(String uuid, boolean forceInitial) { } } + + private String askAPI(String url, String name, String key) throws IOException { HttpURLConnection request = (HttpURLConnection) new URL(url.replaceAll("%NAME%", name).replaceAll("%TIMESTAMP%", new Date().getTime() + "")).openConnection(); request.connect(); @@ -210,7 +227,7 @@ public FetcherMode getMode() { /** * The fetcher-mode describes how the {@link UUIDManager} resolves UUIDs. */ - public enum FetcherMode{ + public enum FetcherMode { /** * No UUID Fetcher is used. The Username will be treated as an UUID.
* Recommended for: Servers running in offline mode (cracked). diff --git a/src/main/java/me/leoko/advancedban/utils/commands/PunishmentProcessor.java b/src/main/java/me/leoko/advancedban/utils/commands/PunishmentProcessor.java index eb0c6377..61fa0314 100644 --- a/src/main/java/me/leoko/advancedban/utils/commands/PunishmentProcessor.java +++ b/src/main/java/me/leoko/advancedban/utils/commands/PunishmentProcessor.java @@ -9,9 +9,9 @@ import me.leoko.advancedban.utils.Punishment; import me.leoko.advancedban.utils.PunishmentType; -import java.sql.Time; import java.util.List; import java.util.function.Consumer; +import java.util.function.Function; import static me.leoko.advancedban.utils.CommandUtils.*; @@ -27,10 +27,6 @@ public void accept(Command.CommandInput input) { boolean silent = processTag(input, "-s"); String name = input.getPrimary(); - // is exempted - if (processExempt(input, type)) - return; - // extract target String target = type.isIpOrientated() ? processIP(input) @@ -38,6 +34,10 @@ public void accept(Command.CommandInput input) { if (target == null) return; + // is exempted + if (processExempt(name, target, input.getSender(), type)) + return; + // calculate duration if necessary Long end = -1L; String timeTemplate = ""; @@ -48,7 +48,7 @@ public void accept(Command.CommandInput input) { end = calculation.time; - if(calculation.template != null) + if (calculation.template != null) timeTemplate = calculation.template; } @@ -90,38 +90,44 @@ private static TimeCalculation processTime(Command.CommandInput input, String uu List timeLayout = mi.getStringList(mi.getLayouts(), "Time." + layout); String timeName = timeLayout.get(Math.min(i, timeLayout.size() - 1)); if (timeName.equalsIgnoreCase("perma")) { - return new TimeCalculation(layout, -1L); + return new TimeCalculation(layout, -1L); } - Long actualTime = TimeManager.getTime() + TimeManager.toMilliSec(timeName); + Long actualTime = TimeManager.getTime() + TimeManager.toMilliSec(timeName); return new TimeCalculation(layout, actualTime); } - long toAdd = TimeManager.toMilliSec(time); - if (!Universal.get().hasPerms(input.getSender(), "ab." + type.getName() + ".dur.max")) { - long max = -1; - for (int i = 10; i >= 1; i--) { - if (Universal.get().hasPerms(input.getSender(), "ab." + type.getName() + ".dur." + i) && - mi.contains(mi.getConfig(), "TempPerms." + i)) { - max = mi.getLong(mi.getConfig(), "TempPerms." + i) * 1000; - break; - } - } - if (max != -1 && toAdd > max) { - MessageManager.sendMessage(input.getSender(), type.getConfSection() + ".MaxDuration", true, "MAX", max / 1000 + ""); - return null; - } - } - return new TimeCalculation(null, TimeManager.getTime() + toAdd); + long toAdd = TimeManager.toMilliSec(time); + if (!Universal.get().hasPerms(input.getSender(), "ab." + type.getName() + ".dur.max")) { + long max = -1; + for (int i = 10; i >= 1; i--) { + if (Universal.get().hasPerms(input.getSender(), "ab." + type.getName() + ".dur." + i) && + mi.contains(mi.getConfig(), "TempPerms." + i)) { + max = mi.getLong(mi.getConfig(), "TempPerms." + i) * 1000; + break; + } + } + if (max != -1 && toAdd > max) { + MessageManager.sendMessage(input.getSender(), type.getConfSection() + ".MaxDuration", true, "MAX", max / 1000 + ""); + return null; + } + } + return new TimeCalculation(null, TimeManager.getTime() + toAdd); } // Checks whether target is exempted from punishment - private static boolean processExempt(Command.CommandInput input, PunishmentType type) { - String name = input.getPrimary(); + private static boolean processExempt(String name, String target, Object sender, PunishmentType type) { MethodInterface mi = Universal.get().getMethods(); String dataName = name.toLowerCase(); - // ( isOnline && hasOnlineExempt ) || hasOfflineExempt - if ((mi.isOnline(dataName) && !canPunish(input.getSender(), mi.getPlayer(dataName), type.getName())) - || Universal.get().isExemptPlayer(dataName)) { - MessageManager.sendMessage(input.getSender(), type.getBasic().getConfSection() + ".Exempt", + + boolean onlineExempt = false; + if (mi.isOnline(dataName)) { + Object onlineTarget = mi.getPlayer(dataName); + onlineExempt = canNotPunish((perms) -> mi.hasPerms(sender, perms), (perms) -> mi.hasPerms(onlineTarget, perms), type.getName()); + } + + boolean offlineExempt = !onlineExempt && (Universal.get().isExemptPlayer(dataName) || canNotPunish((perms) -> mi.hasPerms(sender, perms), (perms) -> mi.hasOfflinePerms(name, perms), type.getName())); + + if (onlineExempt || offlineExempt) { + MessageManager.sendMessage(sender, type.getBasic().getConfSection() + ".Exempt", true, "NAME", name); return true; } @@ -129,18 +135,19 @@ private static boolean processExempt(Command.CommandInput input, PunishmentType } // Check based on exempt level if some is able to ban a player - public static boolean canPunish(Object operator, Object target, String path) { + public static boolean canNotPunish(Function operatorHasPerms, Function targetHasPerms, String path) { final String perms = "ab." + path + ".exempt"; - if (Universal.get().hasPerms(target, perms)) - return false; + if (targetHasPerms.apply(perms)) + return true; + + int targetLevel = permissionLevel(targetHasPerms, perms); - int targetLevel = permissionLevel(target, perms); - return targetLevel == 0 || permissionLevel(operator, perms) > targetLevel; + return targetLevel != 0 && permissionLevel(operatorHasPerms, perms) <= targetLevel; } - private static int permissionLevel(Object subject, String permission){ + private static int permissionLevel(Function hasPerms, String permission) { for (int i = 10; i >= 1; i--) - if(Universal.get().hasPerms(subject, permission+"."+i)) + if (hasPerms.apply(permission + "." + i)) return i; return 0; @@ -164,7 +171,7 @@ private static boolean alreadyPunished(String target, PunishmentType type) { || (type.getBasic() == PunishmentType.BAN && PunishmentManager.get().isBanned(target)); } - private static class TimeCalculation{ + private static class TimeCalculation { private String template; private Long time; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a70ef903..1035dcd2 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -62,6 +62,7 @@ MuteCommands: # These players will not be able to get punished in any way # this also works if the player is offline +# Use Vault to make exempt permissions also work for offline players ExemptPlayers: - 'Leoko' - 'md5' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5cc3080a..72528a3f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,6 +2,7 @@ name: ${project.artifactId} version: ${project.version} main: ${project.groupId}.bukkit.BukkitMain author: Leoko +softdepend: [Vault] commands: AdvancedBan: