diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHook.java index 64c264df..d26a75d9 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHook.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultHook.java @@ -43,6 +43,10 @@ public class VaultHook { permissionHook.setServer(plugin.getConfiguration().getVaultServer()); permissionHook.setIncludeGlobal(plugin.getConfiguration().isVaultIncludingGlobal()); permissionHook.setIgnoreWorld(plugin.getConfiguration().isVaultIgnoreWorld()); + permissionHook.setPgo(plugin.getConfiguration().isVaultPrimaryGroupOverrides()); + permissionHook.setPgoCheckInherited(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckInherited()); + permissionHook.setPgoCheckExists(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckExists()); + permissionHook.setPgoCheckMemberOf(plugin.getConfiguration().isVaultPrimaryGroupOverridesCheckMemberOf()); permissionHook.setup(); if (chatHook == null) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java index 89d15482..484e42d6 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java @@ -22,11 +22,15 @@ package me.lucko.luckperms.bukkit.vault; +import lombok.AccessLevel; import lombok.Getter; import lombok.NonNull; import lombok.Setter; import me.lucko.luckperms.api.Contexts; +import me.lucko.luckperms.api.LocalizedNode; import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.api.Tristate; +import me.lucko.luckperms.api.caching.PermissionData; import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.bukkit.LPBukkitPlugin; import me.lucko.luckperms.common.core.PermissionHolder; @@ -43,27 +47,24 @@ import java.util.Map; * The LuckPerms Vault Permission implementation * Most lookups are cached. */ +@Getter +@Setter public class VaultPermissionHook extends Permission { - - @Getter - @Setter private LPBukkitPlugin plugin; - @Getter + @Setter(value = AccessLevel.NONE) private VaultScheduler scheduler; - @Getter - @Setter private String server = "global"; - - @Getter - @Setter private boolean includeGlobal = true; - - @Getter - @Setter private boolean ignoreWorld = false; + // Primary Group override settings + private boolean pgo = false; + private boolean pgoCheckInherited = false; + private boolean pgoCheckExists = true; + private boolean pgoCheckMemberOf = true; + public void setup() { scheduler = new VaultScheduler(plugin); } @@ -311,9 +312,73 @@ public class VaultPermissionHook extends Permission { @Override public String getPrimaryGroup(String world, @NonNull String player) { + world = ignoreWorld ? null : world; // Correct world value log("Getting primary group of player: " + player); final User user = plugin.getUserManager().get(player); - return (user == null) ? null : user.getPrimaryGroup(); + + if (user == null) { + return null; + } + + if (!pgo) { + return user.getPrimaryGroup(); + } + + if (pgoCheckInherited) { + PermissionData data = user.getUserData().getPermissionData(createContext(server, world)); + for (Map.Entry e : data.getImmutableBacking().entrySet()) { + if (!e.getKey().toLowerCase().startsWith("vault.primarygroup.")) { + continue; + } + + String group = e.getKey().substring("vault.primarygroup.".length()); + if (pgoCheckExists) { + if (!plugin.getGroupManager().isLoaded(group)) { + continue; + } + } + + if (pgoCheckMemberOf) { + if (data.getPermissionValue("group." + group) != Tristate.TRUE) { + continue; + } + } + + return group; + } + } else { + for (LocalizedNode node : user.getPermissions(true)) { + if (!node.getPermission().toLowerCase().startsWith("vault.primarygroup.")) { + continue; + } + + if (!node.shouldApplyOnServer(server, isIncludeGlobal(), false)) { + continue; + } + + if (!node.shouldApplyOnWorld(world, true, false)) { + continue; + } + + String group = node.getPermission().substring("vault.primarygroup.".length()); + if (pgoCheckExists) { + if (!plugin.getGroupManager().isLoaded(group)) { + continue; + } + } + + if (pgoCheckMemberOf) { + if (!user.getLocalGroups(server, world).contains(group.toLowerCase())) { + continue; + } + } + + return group; + } + } + + // Fallback + return user.getPrimaryGroup(); } @Override diff --git a/bukkit/src/main/resources/config.yml b/bukkit/src/main/resources/config.yml index 7d2aedf5..6c779331 100644 --- a/bukkit/src/main/resources/config.yml +++ b/bukkit/src/main/resources/config.yml @@ -112,6 +112,19 @@ vault-include-global: true # If Vault operations should ignore any world arguments if supplied. vault-ignore-world: false +# This block controls the Primary Group override feature +# See the wiki for more information. +vault-primary-groups-overrides: + # If the feature is enabled + enabled: false + # If the check should query the user's inherited permissions. + # (a value of false only checks the permissions they explicitly have) + check-inherited-permissions: false + # If LuckPerms should check if the group exists + check-group-exists: true + # If LuckPerms should check if the user is actually a member of the group + check-user-member-of: true + # Mirrors world names. Whenever LuckPerms checks what world a user is in, if the world name is in this list, the value assigned # will be sent forward for permission calculation instead. world-rewrite: diff --git a/common/src/main/java/me/lucko/luckperms/common/config/AbstractConfiguration.java b/common/src/main/java/me/lucko/luckperms/common/config/AbstractConfiguration.java index e05f3eda..397f62e8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/config/AbstractConfiguration.java +++ b/common/src/main/java/me/lucko/luckperms/common/config/AbstractConfiguration.java @@ -67,6 +67,10 @@ public abstract class AbstractConfiguration implement private String vaultServer; private boolean vaultIncludingGlobal; private boolean vaultIgnoreWorld; + private boolean vaultPrimaryGroupOverrides; + private boolean vaultPrimaryGroupOverridesCheckInherited; + private boolean vaultPrimaryGroupOverridesCheckExists; + private boolean vaultPrimaryGroupOverridesCheckMemberOf; private Map worldRewrites; private Map groupNameRewrites; private List defaultAssignments; @@ -113,6 +117,10 @@ public abstract class AbstractConfiguration implement vaultServer = getString("vault-server", "global"); vaultIncludingGlobal = getBoolean("vault-include-global", true); vaultIgnoreWorld = getBoolean("vault-ignore-world", false); + vaultPrimaryGroupOverrides = getBoolean("vault-primary-groups-overrides.enabled", false); + vaultPrimaryGroupOverridesCheckInherited = getBoolean("vault-primary-groups-overrides.check-inherited-permissions", false); + vaultPrimaryGroupOverridesCheckExists = getBoolean("vault-primary-groups-overrides.check-group-exists", true); + vaultPrimaryGroupOverridesCheckMemberOf = getBoolean("vault-primary-groups-overrides.check-user-member-of", true); worldRewrites = ImmutableMap.copyOf(getMap("world-rewrite", Collections.emptyMap())); groupNameRewrites = ImmutableMap.copyOf(getMap("group-name-rewrite", Collections.emptyMap())); diff --git a/common/src/main/java/me/lucko/luckperms/common/config/LPConfiguration.java b/common/src/main/java/me/lucko/luckperms/common/config/LPConfiguration.java index ffcec226..3cd3c62b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/config/LPConfiguration.java +++ b/common/src/main/java/me/lucko/luckperms/common/config/LPConfiguration.java @@ -78,6 +78,14 @@ public interface LPConfiguration { boolean isVaultIgnoreWorld(); + boolean isVaultPrimaryGroupOverrides(); + + boolean isVaultPrimaryGroupOverridesCheckInherited(); + + boolean isVaultPrimaryGroupOverridesCheckExists(); + + boolean isVaultPrimaryGroupOverridesCheckMemberOf(); + Map getWorldRewrites(); Map getGroupNameRewrites();