mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-29 12:37:40 +01:00
Add wildcard permissions
This commit is contained in:
parent
e07b677632
commit
e14ea73626
25
README.md
25
README.md
@ -8,6 +8,7 @@ A permissions implementation for Bukkit/Spigot, BungeeCord and Sponge.
|
||||
## Features
|
||||
* **Group inheritance** - users can be members of multiple groups, groups can inherit other groups
|
||||
* **Temporary permissions** - users/groups can be given permissions that expire after a given time
|
||||
* **Wildcard permissions** - users/groups can be given wildcard permissions (e.g. "minecraft.command.*"), even when plugins haven't implemented their own wildcards.
|
||||
* **Temporary groups** - users/groups can be added to/inherit other groups temporarily
|
||||
* **Multi-server support** - data is synced across all servers/platforms
|
||||
* **Full offline-mode/mixed-mode support** - player permissions are synced properly over offline-mode or mixed online/offline-mode networks.
|
||||
@ -34,23 +35,31 @@ You can define the settings for per-server permissions, the storage method and c
|
||||
|
||||
## Info
|
||||
### Permission Calculation
|
||||
Permissions are calculated based on a priority system as follows.
|
||||
#### Permissions are calculated based on a priority system as follows.
|
||||
|
||||
* Temporary permissions will override non-temporary permissions.
|
||||
* **Non wildcard permissions will override wildcard permissions**
|
||||
|
||||
Example: if a user has a true permission set for "luckperms.\*", and a false permission set for "luckperms.something", the non-wildcard permission will override the wildcard, and "luckperms.something" will be set to false, despite the wildcard.
|
||||
|
||||
* **More specific wildcards override less specific ones**
|
||||
|
||||
Example: if a user has "luckperms.\*" set to true, but "luckperms.user.\*" set to false, all of the user permissions will be set to false, despite the more generic wildcard for "luckperms.*".
|
||||
|
||||
* **Temporary permissions will override non-temporary permissions.**
|
||||
|
||||
Example: if a user has a false permission set for "test.node", and a temporary true permission set for "test.node", the temporary permission will override the permanent one, and the user will be granted the true node.
|
||||
|
||||
* World specific permissions will override generic permissions.
|
||||
* **World specific permissions will override generic permissions.**
|
||||
|
||||
Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission in the "world_nether" world, the world specific permission will override the globally defined one, and the user will be granted the negated node (provided they're in that world, of course.).
|
||||
|
||||
* Server specific permissions will override generic/global permissions.
|
||||
* **Server specific permissions will override generic/global permissions.**
|
||||
|
||||
Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission on the "factions" server, the server specific permission will override the globally defined one, and the user will be granted the negated node.
|
||||
Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission on the "factions" server, the server specific permission will override the globally defined one, and the user will be granted the negated node (provided they're on that server).
|
||||
|
||||
* Inherited permissions will be overridden by an objects own permissions.
|
||||
* **Inherited permissions will be overridden by an objects own permissions.**
|
||||
|
||||
Example: A user is a member of the default group, which grants "some.thing.perm", but the users own permissions has "some.thing.perm" set to false. The inherited permission will be overridden by the users own permissions, and the user will be granted the negative node (provided they're on that server).
|
||||
Example: A user is a member of the default group, which grants "some.thing.perm", but the users own permissions has "some.thing.perm" set to false. The inherited permission will be overridden by the users own permissions, and the user will be granted the negative node.
|
||||
|
||||
### Temporary Permissions
|
||||
Temporary permissions are checked each time a user/group is loaded, and when the sync task runs. This means if you set a temporary permission to expire after 30 seconds, it won't actually be removed until the sync task runs.
|
||||
@ -102,7 +111,7 @@ You can add LuckPerms as a Maven dependency by adding the following to your proj
|
||||
<dependency>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms-api</artifactId>
|
||||
<version>2.0</version>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
````
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.0</version>
|
||||
<version>2.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -59,6 +59,11 @@ public interface LPConfiguration {
|
||||
*/
|
||||
boolean getOnlineMode();
|
||||
|
||||
/**
|
||||
* @return if LuckPerms is applying wildcard permissions
|
||||
*/
|
||||
boolean getApplyWildcards();
|
||||
|
||||
/**
|
||||
* @return the database values set in the configuration
|
||||
*/
|
||||
|
@ -262,6 +262,16 @@ public interface PermissionHolder {
|
||||
*/
|
||||
void unsetPermission(String node, String server, String world, boolean temporary) throws ObjectLacksException;
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
* @param world The world to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes);
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
@ -273,8 +283,17 @@ public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for (can be null)
|
||||
* @param excludedGroups Groups that shouldn't be inherited, can be null (to prevent circular inheritance issues)
|
||||
* @param server The server to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes);
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups);
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.0</version>
|
||||
<version>2.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -40,7 +40,6 @@ import me.lucko.luckperms.users.UserManager;
|
||||
import me.lucko.luckperms.utils.LPConfiguration;
|
||||
import me.lucko.luckperms.utils.LogUtil;
|
||||
import me.lucko.luckperms.utils.UuidCache;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
@ -48,6 +47,7 @@ import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@ -71,7 +71,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
configuration = new BukkitConfig(this);
|
||||
|
||||
// register events
|
||||
PluginManager pm = Bukkit.getPluginManager();
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
pm.registerEvents(new BukkitListener(this), this);
|
||||
|
||||
// register commands
|
||||
@ -155,12 +155,12 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
@Override
|
||||
public void doAsync(Runnable r) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(this, r);
|
||||
getServer().getScheduler().runTaskAsynchronously(this, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSync(Runnable r) {
|
||||
Bukkit.getScheduler().runTask(this, r);
|
||||
getServer().getScheduler().runTask(this, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -183,6 +183,18 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
return getServer().getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossiblePermissions() {
|
||||
final List<String> perms = new ArrayList<>();
|
||||
|
||||
getServer().getPluginManager().getPermissions().forEach(p -> {
|
||||
perms.add(p.getName());
|
||||
p.getChildren().keySet().forEach(perms::add);
|
||||
});
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUpdateTask() {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, new UpdateTask(this));
|
||||
|
@ -22,6 +22,11 @@ include-global: true
|
||||
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
|
||||
online-mode: true
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard. This will only work for plugins that define all of their permissions to the server.
|
||||
apply-wildcards: true
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, flatfile
|
||||
# Fill out connection info below if you're using MySQL
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.0</version>
|
||||
<version>2.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -29,14 +29,13 @@ import me.lucko.luckperms.utils.UuidCache;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.LoginEvent;
|
||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.api.event.*;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -49,6 +48,27 @@ class BungeeListener extends AbstractListener implements Listener {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerPermissionCheck(PermissionCheckEvent e) {
|
||||
if (!(e.getSender() instanceof ProxiedPlayer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ProxiedPlayer player = ((ProxiedPlayer) e.getSender());
|
||||
final User user = plugin.getUserManager().getUser(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user == null) return;
|
||||
|
||||
|
||||
final String server = player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
Map<String, Boolean> local = user.getLocalPermissions(plugin.getConfiguration().getServer(), server, null, Collections.singletonList(e.getPermission()));
|
||||
for (Map.Entry<String, Boolean> en : local.entrySet()) {
|
||||
if (en.getKey().equalsIgnoreCase(e.getPermission())) {
|
||||
e.setHasPermission(en.getValue());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerLogin(LoginEvent e) {
|
||||
/* Delay the login here, as we want to cache UUID data before the player is connected to a backend bukkit server.
|
||||
|
@ -41,6 +41,7 @@ import me.lucko.luckperms.utils.UuidCache;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -143,6 +144,12 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
return getProxy().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossiblePermissions() {
|
||||
// No such thing on Bungee. Wildcards are processed in the listener instead.
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUpdateTask() {
|
||||
doAsync(new UpdateTask(this));
|
||||
|
@ -23,38 +23,20 @@
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.LPBungeePlugin;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeUser extends User {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
BungeeUser(UUID uuid, LPBungeePlugin plugin) {
|
||||
super(uuid, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
BungeeUser(UUID uuid, String username, LPBungeePlugin plugin) {
|
||||
super(uuid, username, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshPermissions() {
|
||||
ProxiedPlayer player = plugin.getProxy().getPlayer(plugin.getUuidCache().getExternalUUID(getUuid()));
|
||||
if (player == null) return;
|
||||
|
||||
// Clear existing permissions
|
||||
Collection<String> perms = new ArrayList<>(player.getPermissions());
|
||||
perms.forEach(p -> player.setPermission(p, false));
|
||||
|
||||
// Re-add all defined permissions for the user
|
||||
final String server = player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
Map<String, Boolean> local = getLocalPermissions(getPlugin().getConfiguration().getServer(), server, null);
|
||||
local.entrySet().forEach(e -> player.setPermission(e.getKey(), e.getValue()));
|
||||
// Do nothing. Permissions are applied when needed in a listener.
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,11 @@ include-global: false
|
||||
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
|
||||
online-mode: true
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard. This will only work for plugins that define all of their permissions to the server.
|
||||
apply-wildcards: true
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql & flatfile
|
||||
# Fill out connection info below if you're using MySQL
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.0</version>
|
||||
<version>2.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -106,6 +106,12 @@ public interface LuckPermsPlugin {
|
||||
*/
|
||||
List<String> getPlayerList();
|
||||
|
||||
/**
|
||||
* Gets all possible permission nodes, used for resolving wildcards
|
||||
* @return a {@link List} of permission nodes
|
||||
*/
|
||||
List<String> getPossiblePermissions();
|
||||
|
||||
/**
|
||||
* Runs an update task
|
||||
*/
|
||||
|
@ -63,6 +63,11 @@ public class LPConfigurationLink implements LPConfiguration {
|
||||
return master.getOnlineMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getApplyWildcards() {
|
||||
return master.getApplyWildcards();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MySQLConfiguration getDatabaseValues() {
|
||||
return master.getDatabaseValues();
|
||||
|
@ -175,11 +175,21 @@ class PermissionHolderLink implements PermissionHolder {
|
||||
master.unsetPermission(checkNode(node), checkServer(server), world, temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return master.getLocalPermissions(server, world, excludedGroups, possibleNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups) {
|
||||
return master.getLocalPermissions(server, world, excludedGroups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return master.getLocalPermissions(server, excludedGroups, possibleNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups) {
|
||||
return master.getLocalPermissions(server, excludedGroups);
|
||||
|
@ -23,7 +23,6 @@
|
||||
package me.lucko.luckperms.constants;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.lucko.luckperms.commands.Sender;
|
||||
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
@ -42,74 +41,56 @@ public enum Permission {
|
||||
DELETE_TRACK("deletetrack", null),
|
||||
LIST_TRACKS("listtracks", null),
|
||||
|
||||
USER_INFO("info", PermissionGroup.USER),
|
||||
USER_GETUUID("getuuid", PermissionGroup.USER),
|
||||
USER_LISTNODES("listnodes", PermissionGroup.USER),
|
||||
USER_HASPERMISSION("haspermission", PermissionGroup.USER),
|
||||
USER_INHERITSPERMISSION("inheritspermission", PermissionGroup.USER),
|
||||
USER_SETPERMISSION("setpermission", PermissionGroup.USER),
|
||||
USER_UNSETPERMISSION("unsetpermission", PermissionGroup.USER),
|
||||
USER_ADDGROUP("addgroup", PermissionGroup.USER),
|
||||
USER_REMOVEGROUP("removegroup", PermissionGroup.USER),
|
||||
USER_SET_TEMP_PERMISSION("settemppermission", PermissionGroup.USER),
|
||||
USER_UNSET_TEMP_PERMISSION("unsettemppermission", PermissionGroup.USER),
|
||||
USER_ADDTEMPGROUP("addtempgroup", PermissionGroup.USER),
|
||||
USER_REMOVETEMPGROUP("removetempgroup", PermissionGroup.USER),
|
||||
USER_SETPRIMARYGROUP("setprimarygroup", PermissionGroup.USER),
|
||||
USER_SHOWTRACKS("showtracks", PermissionGroup.USER),
|
||||
USER_PROMOTE("promote", PermissionGroup.USER),
|
||||
USER_DEMOTE("demote", PermissionGroup.USER),
|
||||
USER_SHOWPOS("showpos", PermissionGroup.USER),
|
||||
USER_CLEAR("clear", PermissionGroup.USER),
|
||||
USER_INFO("info", "user"),
|
||||
USER_GETUUID("getuuid", "user"),
|
||||
USER_LISTNODES("listnodes", "user"),
|
||||
USER_HASPERMISSION("haspermission", "user"),
|
||||
USER_INHERITSPERMISSION("inheritspermission", "user"),
|
||||
USER_SETPERMISSION("setpermission", "user"),
|
||||
USER_UNSETPERMISSION("unsetpermission", "user"),
|
||||
USER_ADDGROUP("addgroup", "user"),
|
||||
USER_REMOVEGROUP("removegroup", "user"),
|
||||
USER_SET_TEMP_PERMISSION("settemppermission", "user"),
|
||||
USER_UNSET_TEMP_PERMISSION("unsettemppermission", "user"),
|
||||
USER_ADDTEMPGROUP("addtempgroup", "user"),
|
||||
USER_REMOVETEMPGROUP("removetempgroup", "user"),
|
||||
USER_SETPRIMARYGROUP("setprimarygroup", "user"),
|
||||
USER_SHOWTRACKS("showtracks", "user"),
|
||||
USER_PROMOTE("promote", "user"),
|
||||
USER_DEMOTE("demote", "user"),
|
||||
USER_SHOWPOS("showpos", "user"),
|
||||
USER_CLEAR("clear", "user"),
|
||||
|
||||
GROUP_INFO("info", PermissionGroup.GROUP),
|
||||
GROUP_LISTNODES("listnodes", PermissionGroup.GROUP),
|
||||
GROUP_HASPERMISSION("haspermission", PermissionGroup.GROUP),
|
||||
GROUP_INHERITSPERMISSION("inheritspermission", PermissionGroup.GROUP),
|
||||
GROUP_SETPERMISSION("setpermission", PermissionGroup.GROUP),
|
||||
GROUP_UNSETPERMISSION("unsetpermission", PermissionGroup.GROUP),
|
||||
GROUP_SETINHERIT("setinherit", PermissionGroup.GROUP),
|
||||
GROUP_UNSETINHERIT("unsetinherit", PermissionGroup.GROUP),
|
||||
GROUP_SET_TEMP_PERMISSION("settemppermission", PermissionGroup.GROUP),
|
||||
GROUP_UNSET_TEMP_PERMISSION("unsettemppermission", PermissionGroup.GROUP),
|
||||
GROUP_SET_TEMP_INHERIT("settempinherit", PermissionGroup.GROUP),
|
||||
GROUP_UNSET_TEMP_INHERIT("unsettempinherit", PermissionGroup.GROUP),
|
||||
GROUP_SHOWTRACKS("showtracks", PermissionGroup.GROUP),
|
||||
GROUP_CLEAR("clear", PermissionGroup.GROUP),
|
||||
GROUP_INFO("info", "group"),
|
||||
GROUP_LISTNODES("listnodes", "group"),
|
||||
GROUP_HASPERMISSION("haspermission", "group"),
|
||||
GROUP_INHERITSPERMISSION("inheritspermission", "group"),
|
||||
GROUP_SETPERMISSION("setpermission", "group"),
|
||||
GROUP_UNSETPERMISSION("unsetpermission", "group"),
|
||||
GROUP_SETINHERIT("setinherit", "group"),
|
||||
GROUP_UNSETINHERIT("unsetinherit", "group"),
|
||||
GROUP_SET_TEMP_PERMISSION("settemppermission", "group"),
|
||||
GROUP_UNSET_TEMP_PERMISSION("unsettemppermission", "group"),
|
||||
GROUP_SET_TEMP_INHERIT("settempinherit", "group"),
|
||||
GROUP_UNSET_TEMP_INHERIT("unsettempinherit", "group"),
|
||||
GROUP_SHOWTRACKS("showtracks", "group"),
|
||||
GROUP_CLEAR("clear", "group"),
|
||||
|
||||
TRACK_INFO("info", PermissionGroup.TRACK),
|
||||
TRACK_APPEND("append", PermissionGroup.TRACK),
|
||||
TRACK_INSERT("insert", PermissionGroup.TRACK),
|
||||
TRACK_REMOVE("remove", PermissionGroup.TRACK),
|
||||
TRACK_CLEAR("clear", PermissionGroup.TRACK);
|
||||
TRACK_INFO("info", "track"),
|
||||
TRACK_APPEND("append", "track"),
|
||||
TRACK_INSERT("insert", "track"),
|
||||
TRACK_REMOVE("remove", "track"),
|
||||
TRACK_CLEAR("clear", "track");
|
||||
|
||||
private String node;
|
||||
private PermissionGroup group;
|
||||
private String group;
|
||||
|
||||
public boolean isAuthorized(Sender sender) {
|
||||
if (sender.hasPermission("luckperms.*")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (group != null) {
|
||||
return group.isAuthorized(sender) || sender.hasPermission("luckperms." + group.getNode() + "." + node);
|
||||
return sender.hasPermission("luckperms." + group + "." + node);
|
||||
}
|
||||
|
||||
return sender.hasPermission("luckperms." + node);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
private enum PermissionGroup {
|
||||
USER("user"),
|
||||
GROUP("group"),
|
||||
TRACK("track");
|
||||
|
||||
private String node;
|
||||
|
||||
private boolean isAuthorized(Sender sender) {
|
||||
return sender.hasPermission("luckperms." + node + ".*");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ public class Group extends PermissionHolder {
|
||||
*/
|
||||
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
||||
// Call super #getPermissions method, and just sort through those
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal);
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal, null);
|
||||
return perms.keySet().stream()
|
||||
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
||||
.map(s -> Patterns.DOT.split(s, 2)[1])
|
||||
|
@ -313,7 +313,7 @@ public abstract class User extends PermissionHolder {
|
||||
*/
|
||||
private List<String> getGroups(String server, String world, boolean includeGlobal) {
|
||||
// Call super #getPermissions method, and just sort through those
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal);
|
||||
Map<String, Boolean> perms = getPermissions(server, world, null, includeGlobal, null);
|
||||
return perms.keySet().stream()
|
||||
.filter(s -> Patterns.GROUP_MATCH.matcher(s).matches())
|
||||
.map(s -> Patterns.DOT.split(s, 2)[1])
|
||||
|
@ -88,6 +88,10 @@ public abstract class LPConfiguration<T extends LuckPermsPlugin> {
|
||||
return getBoolean("online-mode", true);
|
||||
}
|
||||
|
||||
public boolean getApplyWildcards() {
|
||||
return getBoolean("apply-wildcards", true);
|
||||
}
|
||||
|
||||
public MySQLConfiguration getDatabaseValues() {
|
||||
return new MySQLConfiguration(
|
||||
getString("sql.address", null),
|
||||
|
@ -396,6 +396,18 @@ public abstract class PermissionHolder {
|
||||
unsetPermission(server + "-" + world + "/" + node, temporary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
* @param world The world to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return getPermissions(server, world, excludedGroups, plugin.getConfiguration().getIncludeGlobalPerms(), possibleNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
@ -404,7 +416,18 @@ public abstract class PermissionHolder {
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups) {
|
||||
return getPermissions(server, world, excludedGroups, plugin.getConfiguration().getIncludeGlobalPerms());
|
||||
return getPermissions(server, world, excludedGroups, plugin.getConfiguration().getIncludeGlobalPerms(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the permissions and inherited permissions that apply to a specific server
|
||||
* @param server The server to get nodes for
|
||||
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
|
||||
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes) {
|
||||
return getLocalPermissions(server, null, excludedGroups, possibleNodes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -414,7 +437,7 @@ public abstract class PermissionHolder {
|
||||
* @return a {@link Map} of the permissions
|
||||
*/
|
||||
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups) {
|
||||
return getLocalPermissions(server, null, excludedGroups);
|
||||
return getLocalPermissions(server, null, excludedGroups, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -468,7 +491,7 @@ public abstract class PermissionHolder {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
protected Map<String, Boolean> getPermissions(String server, String world, List<String> excludedGroups, boolean includeGlobal) {
|
||||
protected Map<String, Boolean> getPermissions(String server, String world, List<String> excludedGroups, boolean includeGlobal, List<String> possibleNodes) {
|
||||
if (excludedGroups == null) {
|
||||
excludedGroups = new ArrayList<>();
|
||||
}
|
||||
@ -643,9 +666,61 @@ public abstract class PermissionHolder {
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.getConfiguration().getApplyWildcards()) {
|
||||
if (possibleNodes != null && !possibleNodes.isEmpty()) {
|
||||
return applyWildcards(perms, possibleNodes);
|
||||
}
|
||||
return applyWildcards(perms, plugin.getPossiblePermissions());
|
||||
}
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
private Map<String, Boolean> applyWildcards(Map<String, Boolean> input, List<String> possibleNodes) {
|
||||
// Add all group nodes, so wildcard group.* and '*' can apply.
|
||||
plugin.getGroupManager().getGroups().keySet().forEach(s -> possibleNodes.add("group." + s));
|
||||
|
||||
SortedMap<Integer, Map<String, Boolean>> wildcards = new TreeMap<>(Collections.reverseOrder());
|
||||
for (Map.Entry<String, Boolean> e : input.entrySet()) {
|
||||
if (e.getKey().equals("*") || e.getKey().equals("'*'")) {
|
||||
wildcards.put(0, Collections.singletonMap("*", e.getValue()));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!e.getKey().endsWith(".*")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String node = e.getKey().substring(0, e.getKey().length() - 2);
|
||||
final String[] parts = Patterns.DOT.split(node);
|
||||
|
||||
if (!wildcards.containsKey(parts.length)) {
|
||||
wildcards.put(parts.length, new HashMap<>());
|
||||
}
|
||||
|
||||
wildcards.get(parts.length).put(node, e.getValue());
|
||||
}
|
||||
|
||||
for (Map.Entry<Integer, Map<String, Boolean>> e : wildcards.entrySet()) {
|
||||
if (e.getKey() == 0) {
|
||||
// Apply all permissions
|
||||
possibleNodes.stream()
|
||||
.filter(n -> !input.containsKey(n)) // Don't override existing nodes
|
||||
.forEach(n -> input.put(n, e.getValue().get("*")));
|
||||
break;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Boolean> wc : e.getValue().entrySet()) {
|
||||
possibleNodes.stream()
|
||||
.filter(n -> n.startsWith(wc.getKey() + ".")) // Only nodes that match the wildcard are applied
|
||||
.filter(n -> !input.containsKey(n)) // Don't override existing nodes
|
||||
.forEach(n -> input.put(n, wc.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
private static String stripTime(String s) {
|
||||
if (s.contains("$")) {
|
||||
return Patterns.TEMP_DELIMITER.split(s)[0];
|
||||
|
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<version>2.0</version>
|
||||
<version>2.1</version>
|
||||
<modules>
|
||||
<module>common</module>
|
||||
<module>api</module>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>2.0</version>
|
||||
<version>2.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -50,6 +50,8 @@ import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
|
||||
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
|
||||
import org.spongepowered.api.plugin.Plugin;
|
||||
import org.spongepowered.api.scheduler.Scheduler;
|
||||
import org.spongepowered.api.service.permission.PermissionDescription;
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
@ -181,6 +183,12 @@ public class LPSpongePlugin implements LuckPermsPlugin {
|
||||
return game.getServer().getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossiblePermissions() {
|
||||
PermissionService p = game.getServiceManager().provideUnchecked(PermissionService.class);
|
||||
return p.getDescriptions().stream().map(PermissionDescription::getId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runUpdateTask() {
|
||||
scheduler.createTaskBuilder().async().execute(new UpdateTask(this)).submit(LPSpongePlugin.this);
|
||||
|
@ -22,6 +22,11 @@ include-global=true
|
||||
# matter what is set in server.properties. (we can just fallback to the servers uuid cache)
|
||||
online-mode=true
|
||||
|
||||
# If the plugin should apply wildcard permissions.
|
||||
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
|
||||
# the wildcard. This will only work for plugins that define all of their permissions to the server.
|
||||
apply-wildcards=true
|
||||
|
||||
# Which storage method the plugin should use.
|
||||
# Currently supported: mysql, sqlite, flatfile
|
||||
# Fill out connection info below if you're using MySQL
|
||||
|
Loading…
Reference in New Issue
Block a user