mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-28 05:35:26 +01:00
Cleanup parts of the sponge service implementation
This commit is contained in:
parent
98fb9946e4
commit
fbe84322b5
@ -45,7 +45,7 @@ public final class BukkitMigrationUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
log.logErr("Unable to get a UUID for user identifier: " + s);
|
log.logError("Unable to get a UUID for user identifier: " + s);
|
||||||
}
|
}
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
|||||||
|
|
||||||
WorldManager worldManager = WorldManager.getInstance();
|
WorldManager worldManager = WorldManager.getInstance();
|
||||||
if (worldManager == null) {
|
if (worldManager == null) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
|
|||||||
|
|
||||||
Set<String> users = configSection.getKeys(false);
|
Set<String> users = configSection.getKeys(false);
|
||||||
if (users == null) {
|
if (users == null) {
|
||||||
log.logErr("Couldn't get a list of users.");
|
log.logError("Couldn't get a list of users.");
|
||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
AtomicInteger userLoadCount = new AtomicInteger(0);
|
AtomicInteger userLoadCount = new AtomicInteger(0);
|
||||||
|
@ -74,14 +74,14 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
|||||||
log.log("Starting.");
|
log.log("Starting.");
|
||||||
|
|
||||||
if (!args.get(0).equalsIgnoreCase("true") && !args.get(0).equalsIgnoreCase("false")) {
|
if (!args.get(0).equalsIgnoreCase("true") && !args.get(0).equalsIgnoreCase("false")) {
|
||||||
log.logErr("Was expecting true/false, but got " + args.get(0) + " instead.");
|
log.logError("Was expecting true/false, but got " + args.get(0) + " instead.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
final boolean migrateAsGlobal = Boolean.parseBoolean(args.get(0));
|
final boolean migrateAsGlobal = Boolean.parseBoolean(args.get(0));
|
||||||
final Function<String, String> worldMappingFunc = s -> migrateAsGlobal ? null : s;
|
final Function<String, String> worldMappingFunc = s -> migrateAsGlobal ? null : s;
|
||||||
|
|
||||||
if (!Bukkit.getPluginManager().isPluginEnabled("GroupManager")) {
|
if (!Bukkit.getPluginManager().isPluginEnabled("GroupManager")) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class MigrationPermissionsBukkit extends SubCommand<Object> {
|
|||||||
log.log("Starting.");
|
log.log("Starting.");
|
||||||
|
|
||||||
if (!Bukkit.getPluginManager().isPluginEnabled("PermissionsBukkit")) {
|
if (!Bukkit.getPluginManager().isPluginEnabled("PermissionsBukkit")) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
|||||||
log.log("Starting.");
|
log.log("Starting.");
|
||||||
|
|
||||||
if (!Bukkit.getPluginManager().isPluginEnabled("PermissionsEx")) {
|
if (!Bukkit.getPluginManager().isPluginEnabled("PermissionsEx")) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
|||||||
log.log("Starting.");
|
log.log("Starting.");
|
||||||
|
|
||||||
if (!Bukkit.getPluginManager().isPluginEnabled("PowerfulPerms")) {
|
if (!Bukkit.getPluginManager().isPluginEnabled("PowerfulPerms")) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (uuids.isEmpty()) {
|
if (uuids.isEmpty()) {
|
||||||
log.logErr("Unable to find any UUIDs to migrate.");
|
log.logError("Unable to find any UUIDs to migrate.");
|
||||||
return CommandResult.FAILURE;
|
return CommandResult.FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +76,12 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
|||||||
log.log("Starting.");
|
log.log("Starting.");
|
||||||
|
|
||||||
if (!Bukkit.getPluginManager().isPluginEnabled("zPermissions")) {
|
if (!Bukkit.getPluginManager().isPluginEnabled("zPermissions")) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Bukkit.getServicesManager().isProvidedFor(ZPermissionsService.class)) {
|
if (!Bukkit.getServicesManager().isProvidedFor(ZPermissionsService.class)) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
|||||||
// Get BungeePerms instance
|
// Get BungeePerms instance
|
||||||
BungeePerms bp = BungeePerms.getInstance();
|
BungeePerms bp = BungeePerms.getInstance();
|
||||||
if (bp == null) {
|
if (bp == null) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
|||||||
|
|
||||||
SafeIteration.iterate(bp.getPermissionsManager().getBackEnd().loadUsers(), u -> {
|
SafeIteration.iterate(bp.getPermissionsManager().getBackEnd().loadUsers(), u -> {
|
||||||
if (u.getUUID() == null) {
|
if (u.getUUID() == null) {
|
||||||
log.logErr("Could not parse UUID for user: " + u.getName());
|
log.logError("Could not parse UUID for user: " + u.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class ProgressLogger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void logErr(String msg) {
|
public void logError(String msg) {
|
||||||
if (this.pluginName == null) {
|
if (this.pluginName == null) {
|
||||||
this.listeners.forEach(s -> this.logMessage.send(s, "Error -> " + msg));
|
this.listeners.forEach(s -> this.logMessage.send(s, "Error -> " + msg));
|
||||||
} else {
|
} else {
|
||||||
@ -80,7 +80,6 @@ public class ProgressLogger {
|
|||||||
|
|
||||||
public void logProgress(String msg, int amount) {
|
public void logProgress(String msg, int amount) {
|
||||||
if (amount % NOTIFY_FREQUENCY == 0) {
|
if (amount % NOTIFY_FREQUENCY == 0) {
|
||||||
// migrated {} groups so far.
|
|
||||||
logAllProgress(msg, amount);
|
logAllProgress(msg, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,30 @@
|
|||||||
|
|
||||||
package me.lucko.luckperms.common.model;
|
package me.lucko.luckperms.common.model;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public enum NodeMapType {
|
public enum NodeMapType {
|
||||||
|
|
||||||
ENDURING, TRANSIENT
|
ENDURING,
|
||||||
|
TRANSIENT;
|
||||||
|
|
||||||
|
// useful methods for fluent/conditional execution
|
||||||
|
|
||||||
|
public void run(Runnable ifEnduring, Runnable ifTransient) {
|
||||||
|
if (this == ENDURING) {
|
||||||
|
ifEnduring.run();
|
||||||
|
} else {
|
||||||
|
ifTransient.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T supply(Supplier<T> ifEnduring, Supplier<T> ifTransient) {
|
||||||
|
if (this == ENDURING) {
|
||||||
|
return ifEnduring.get();
|
||||||
|
} else {
|
||||||
|
return ifTransient.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -262,6 +262,10 @@ public abstract class PermissionHolder {
|
|||||||
return this.transientNodes;
|
return this.transientNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImmutableSetMultimap<ImmutableContextSet, Node> getNodes(NodeMapType type) {
|
||||||
|
return getData(type).immutable();
|
||||||
|
}
|
||||||
|
|
||||||
public ImmutableSetMultimap<ImmutableContextSet, Node> getEnduringNodes() {
|
public ImmutableSetMultimap<ImmutableContextSet, Node> getEnduringNodes() {
|
||||||
return this.enduringNodes.immutable();
|
return this.enduringNodes.immutable();
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ import me.lucko.luckperms.common.processors.MapProcessor;
|
|||||||
import me.lucko.luckperms.common.processors.PermissionProcessor;
|
import me.lucko.luckperms.common.processors.PermissionProcessor;
|
||||||
import me.lucko.luckperms.common.processors.RegexProcessor;
|
import me.lucko.luckperms.common.processors.RegexProcessor;
|
||||||
import me.lucko.luckperms.common.processors.WildcardProcessor;
|
import me.lucko.luckperms.common.processors.WildcardProcessor;
|
||||||
import me.lucko.luckperms.common.references.HolderType;
|
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.processors.GroupDefaultsProcessor;
|
import me.lucko.luckperms.sponge.processors.GroupDefaultsProcessor;
|
||||||
import me.lucko.luckperms.sponge.processors.SpongeWildcardProcessor;
|
import me.lucko.luckperms.sponge.processors.SpongeWildcardProcessor;
|
||||||
@ -68,9 +67,9 @@ public class SpongeCalculatorFactory extends AbstractCalculatorFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_SPONGE_DEFAULT_SUBJECTS)) {
|
if (this.plugin.getConfiguration().get(ConfigKeys.APPLY_SPONGE_DEFAULT_SUBJECTS)) {
|
||||||
if (metadata.getHolderType() == HolderType.USER) {
|
if (metadata.getHolderType().isUser()) {
|
||||||
processors.add(new UserDefaultsProcessor(this.plugin.getService(), contexts.getContexts().makeImmutable()));
|
processors.add(new UserDefaultsProcessor(this.plugin.getService(), contexts.getContexts().makeImmutable()));
|
||||||
} else if (metadata.getHolderType() == HolderType.GROUP) {
|
} else if (metadata.getHolderType().isGroup()) {
|
||||||
processors.add(new GroupDefaultsProcessor(this.plugin.getService(), contexts.getContexts().makeImmutable()));
|
processors.add(new GroupDefaultsProcessor(this.plugin.getService(), contexts.getContexts().makeImmutable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,14 +62,14 @@ public class SpongeConnectionListener extends AbstractLoginListener {
|
|||||||
/* Called when the player first attempts a connection with the server.
|
/* Called when the player first attempts a connection with the server.
|
||||||
Listening on AFTER_PRE priority to allow plugins to modify username / UUID data here. (auth plugins) */
|
Listening on AFTER_PRE priority to allow plugins to modify username / UUID data here. (auth plugins) */
|
||||||
|
|
||||||
final GameProfile p = e.getProfile();
|
final GameProfile profile = e.getProfile();
|
||||||
final String username = p.getName().orElseThrow(() -> new RuntimeException("No username present for user " + p.getUniqueId()));
|
final String username = profile.getName().orElseThrow(() -> new RuntimeException("No username present for user " + profile.getUniqueId()));
|
||||||
|
|
||||||
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
|
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
|
||||||
this.plugin.getLog().info("Processing auth event for " + p.getUniqueId() + " - " + p.getName());
|
this.plugin.getLog().info("Processing auth event for " + profile.getUniqueId() + " - " + profile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.plugin.getUniqueConnections().add(p.getUniqueId());
|
this.plugin.getUniqueConnections().add(profile.getUniqueId());
|
||||||
|
|
||||||
/* Actually process the login for the connection.
|
/* Actually process the login for the connection.
|
||||||
We do this here to delay the login until the data is ready.
|
We do this here to delay the login until the data is ready.
|
||||||
@ -81,13 +81,13 @@ public class SpongeConnectionListener extends AbstractLoginListener {
|
|||||||
- creating a user instance in the UserManager for this connection.
|
- creating a user instance in the UserManager for this connection.
|
||||||
- setting up cached data. */
|
- setting up cached data. */
|
||||||
try {
|
try {
|
||||||
User user = loadUser(p.getUniqueId(), username);
|
User user = loadUser(profile.getUniqueId(), username);
|
||||||
this.plugin.getEventFactory().handleUserLoginProcess(p.getUniqueId(), username, user);
|
this.plugin.getEventFactory().handleUserLoginProcess(profile.getUniqueId(), username, user);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
this.plugin.getLog().severe("Exception occurred whilst loading data for " + p.getUniqueId() + " - " + p.getName());
|
this.plugin.getLog().severe("Exception occurred whilst loading data for " + profile.getUniqueId() + " - " + profile.getName());
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
|
||||||
this.deniedAsyncLogin.add(p.getUniqueId());
|
this.deniedAsyncLogin.add(profile.getUniqueId());
|
||||||
|
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
e.setMessageCancelled(false);
|
e.setMessageCancelled(false);
|
||||||
@ -120,19 +120,19 @@ public class SpongeConnectionListener extends AbstractLoginListener {
|
|||||||
At this point, the users data should be present and loaded.
|
At this point, the users data should be present and loaded.
|
||||||
Listening on LOW priority to allow plugins to further modify data here. (auth plugins, etc.) */
|
Listening on LOW priority to allow plugins to further modify data here. (auth plugins, etc.) */
|
||||||
|
|
||||||
final GameProfile player = e.getProfile();
|
final GameProfile profile = e.getProfile();
|
||||||
|
|
||||||
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
|
if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
|
||||||
this.plugin.getLog().info("Processing login event for " + player.getUniqueId() + " - " + player.getName());
|
this.plugin.getLog().info("Processing login event for " + profile.getUniqueId() + " - " + profile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
final User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
|
final User user = this.plugin.getUserManager().getIfLoaded(profile.getUniqueId());
|
||||||
|
|
||||||
/* User instance is null for whatever reason. Could be that it was unloaded between asyncpre and now. */
|
/* User instance is null for whatever reason. Could be that it was unloaded between asyncpre and now. */
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
this.deniedLogin.add(player.getUniqueId());
|
this.deniedLogin.add(profile.getUniqueId());
|
||||||
|
|
||||||
this.plugin.getLog().warn("User " + player.getUniqueId() + " - " + player.getName() + " doesn't have data pre-loaded. - denying login.");
|
this.plugin.getLog().warn("User " + profile.getUniqueId() + " - " + profile.getName() + " doesn't have data pre-loaded. - denying login.");
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
e.setMessageCancelled(false);
|
e.setMessageCancelled(false);
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
|
@ -73,7 +73,7 @@ public class MigrationPermissionManager extends SubCommand<Object> {
|
|||||||
|
|
||||||
Optional<PluginContainer> pm = Sponge.getPluginManager().getPlugin("permissionmanager");
|
Optional<PluginContainer> pm = Sponge.getPluginManager().getPlugin("permissionmanager");
|
||||||
if (!pm.isPresent()) {
|
if (!pm.isPresent()) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ public class MigrationPermissionManager extends SubCommand<Object> {
|
|||||||
SafeIteration.iterate(pmService.getUserSubjects().getAllSubjects(), pmUser -> {
|
SafeIteration.iterate(pmService.getUserSubjects().getAllSubjects(), pmUser -> {
|
||||||
UUID uuid = Uuids.parseNullable(pmUser.getIdentifier());
|
UUID uuid = Uuids.parseNullable(pmUser.getIdentifier());
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
log.logErr("Could not parse UUID for user: " + pmUser.getIdentifier());
|
log.logError("Could not parse UUID for user: " + pmUser.getIdentifier());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
|||||||
|
|
||||||
Optional<PluginContainer> pex = Sponge.getPluginManager().getPlugin("permissionsex");
|
Optional<PluginContainer> pex = Sponge.getPluginManager().getPlugin("permissionsex");
|
||||||
if (!pex.isPresent()) {
|
if (!pex.isPresent()) {
|
||||||
log.logErr("Plugin not loaded.");
|
log.logError("Plugin not loaded.");
|
||||||
return CommandResult.STATE_ERROR;
|
return CommandResult.STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
|||||||
SafeIteration.iterate(pexService.getUserSubjects().getAllSubjects(), pexUser -> {
|
SafeIteration.iterate(pexService.getUserSubjects().getAllSubjects(), pexUser -> {
|
||||||
UUID uuid = Uuids.parseNullable(pexUser.getIdentifier());
|
UUID uuid = Uuids.parseNullable(pexUser.getIdentifier());
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
log.logErr("Could not parse UUID for user: " + pexUser.getIdentifier());
|
log.logError("Could not parse UUID for user: " + pexUser.getIdentifier());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,32 +25,11 @@
|
|||||||
|
|
||||||
package me.lucko.luckperms.sponge.model;
|
package me.lucko.luckperms.sponge.model;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.Tristate;
|
|
||||||
import me.lucko.luckperms.api.caching.MetaData;
|
|
||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
|
||||||
import me.lucko.luckperms.common.model.Group;
|
import me.lucko.luckperms.common.model.Group;
|
||||||
import me.lucko.luckperms.common.node.NodeFactory;
|
|
||||||
import me.lucko.luckperms.common.verbose.CheckOrigin;
|
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.internal.GroupSubject;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
|
|
||||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
|
||||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
|
||||||
|
|
||||||
import org.spongepowered.api.command.CommandSource;
|
|
||||||
import org.spongepowered.api.service.permission.PermissionService;
|
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class SpongeGroup extends Group {
|
|
||||||
|
|
||||||
|
public class SpongeGroup extends Group implements SpongePermissionHolder {
|
||||||
private final GroupSubject spongeData;
|
private final GroupSubject spongeData;
|
||||||
|
|
||||||
public SpongeGroup(String name, LPSpongePlugin plugin) {
|
public SpongeGroup(String name, LPSpongePlugin plugin) {
|
||||||
@ -58,133 +37,9 @@ public class SpongeGroup extends Group {
|
|||||||
this.spongeData = new GroupSubject(plugin, this);
|
this.spongeData = new GroupSubject(plugin, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public GroupSubject sponge() {
|
public GroupSubject sponge() {
|
||||||
return this.spongeData;
|
return this.spongeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GroupSubject implements LPSubject {
|
|
||||||
private final SpongeGroup parent;
|
|
||||||
private final LPSpongePlugin plugin;
|
|
||||||
|
|
||||||
private final LuckPermsSubjectData subjectData;
|
|
||||||
|
|
||||||
private final LuckPermsSubjectData transientSubjectData;
|
|
||||||
|
|
||||||
private GroupSubject(LPSpongePlugin plugin, SpongeGroup parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.subjectData = new LuckPermsSubjectData(true, plugin.getService(), parent, this);
|
|
||||||
this.transientSubjectData = new LuckPermsSubjectData(false, plugin.getService(), parent, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier() {
|
|
||||||
return this.parent.getObjectName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<String> getFriendlyIdentifier() {
|
|
||||||
return this.parent.getDisplayName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<CommandSource> getCommandSource() {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LPSubjectCollection getParentCollection() {
|
|
||||||
return this.plugin.getService().getGroupSubjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Subject sponge() {
|
|
||||||
return ProxyFactory.toSponge(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuckPermsService getService() {
|
|
||||||
return this.plugin.getService();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuckPermsSubjectData getSubjectData() {
|
|
||||||
return this.subjectData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuckPermsSubjectData getTransientSubjectData() {
|
|
||||||
return this.transientSubjectData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tristate getPermissionValue(ImmutableContextSet contexts, String permission) {
|
|
||||||
return this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getPermissionValue(permission, CheckOrigin.PLATFORM_LOOKUP_CHECK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChildOf(ImmutableContextSet contexts, LPSubjectReference parent) {
|
|
||||||
return parent.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP) && getPermissionValue(contexts, NodeFactory.groupNode(parent.getSubjectIdentifier())).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImmutableList<LPSubjectReference> getParents(ImmutableContextSet contexts) {
|
|
||||||
ImmutableSet.Builder<LPSubjectReference> subjects = ImmutableSet.builder();
|
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> entry : this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getImmutableBacking().entrySet()) {
|
|
||||||
if (!entry.getValue()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String groupName = NodeFactory.parseGroupNode(entry.getKey());
|
|
||||||
if (groupName == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.plugin.getGroupManager().isLoaded(groupName)) {
|
|
||||||
subjects.add(this.plugin.getService().getGroupSubjects().loadSubject(groupName).join().toReference());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subjects.addAll(this.plugin.getService().getGroupSubjects().getDefaults().getParents(contexts));
|
|
||||||
subjects.addAll(this.plugin.getService().getDefaults().getParents(contexts));
|
|
||||||
|
|
||||||
return getService().sortSubjects(subjects.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<String> getOption(ImmutableContextSet contexts, String s) {
|
|
||||||
MetaData data = this.parent.getCachedData().getMetaData(this.plugin.getContextManager().formContexts(contexts));
|
|
||||||
if (s.equalsIgnoreCase(NodeFactory.PREFIX_KEY)) {
|
|
||||||
if (data.getPrefix() != null) {
|
|
||||||
return Optional.of(data.getPrefix());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.equalsIgnoreCase(NodeFactory.SUFFIX_KEY)) {
|
|
||||||
if (data.getSuffix() != null) {
|
|
||||||
return Optional.of(data.getSuffix());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String val = data.getMeta().get(s);
|
|
||||||
if (val != null) {
|
|
||||||
return Optional.of(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<String> v = this.plugin.getService().getGroupSubjects().getDefaults().getOption(contexts, s);
|
|
||||||
if (v.isPresent()) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.plugin.getService().getDefaults().getOption(contexts, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaches(CacheLevel cacheLevel) {
|
|
||||||
// invalidate for all changes
|
|
||||||
this.parent.getCachedData().invalidateCaches();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of LuckPerms, licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||||
|
* Copyright (c) contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.model;
|
||||||
|
|
||||||
|
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||||
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sponge specific extension of {@link PermissionHolder}.
|
||||||
|
*/
|
||||||
|
public interface SpongePermissionHolder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a {@link LPSubject} representation of this holder.
|
||||||
|
*
|
||||||
|
* @return a subject
|
||||||
|
*/
|
||||||
|
LPSubject sponge();
|
||||||
|
|
||||||
|
}
|
@ -25,35 +25,17 @@
|
|||||||
|
|
||||||
package me.lucko.luckperms.sponge.model;
|
package me.lucko.luckperms.sponge.model;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.Tristate;
|
|
||||||
import me.lucko.luckperms.api.caching.MetaData;
|
|
||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
|
||||||
import me.lucko.luckperms.common.model.User;
|
import me.lucko.luckperms.common.model.User;
|
||||||
import me.lucko.luckperms.common.node.NodeFactory;
|
|
||||||
import me.lucko.luckperms.common.verbose.CheckOrigin;
|
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.internal.UserSubject;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
|
|
||||||
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
|
||||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
|
||||||
|
|
||||||
import org.spongepowered.api.Sponge;
|
|
||||||
import org.spongepowered.api.command.CommandSource;
|
|
||||||
import org.spongepowered.api.service.permission.PermissionService;
|
|
||||||
import org.spongepowered.api.service.permission.Subject;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class SpongeUser extends User {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of {@link User} to hold an implementation for {@link LPSubject}.
|
||||||
|
*/
|
||||||
|
public class SpongeUser extends User implements SpongePermissionHolder {
|
||||||
private final UserSubject spongeData;
|
private final UserSubject spongeData;
|
||||||
|
|
||||||
public SpongeUser(UUID uuid, LPSpongePlugin plugin) {
|
public SpongeUser(UUID uuid, LPSpongePlugin plugin) {
|
||||||
@ -66,134 +48,9 @@ public class SpongeUser extends User {
|
|||||||
this.spongeData = new UserSubject(plugin, this);
|
this.spongeData = new UserSubject(plugin, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public UserSubject sponge() {
|
public UserSubject sponge() {
|
||||||
return this.spongeData;
|
return this.spongeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class UserSubject implements LPSubject {
|
|
||||||
private final SpongeUser parent;
|
|
||||||
private final LPSpongePlugin plugin;
|
|
||||||
|
|
||||||
private final LuckPermsSubjectData subjectData;
|
|
||||||
|
|
||||||
private final LuckPermsSubjectData transientSubjectData;
|
|
||||||
|
|
||||||
private UserSubject(LPSpongePlugin plugin, SpongeUser parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.subjectData = new LuckPermsSubjectData(true, plugin.getService(), parent, this);
|
|
||||||
this.transientSubjectData = new LuckPermsSubjectData(false, plugin.getService(), parent, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier() {
|
|
||||||
return this.parent.getUuid().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<String> getFriendlyIdentifier() {
|
|
||||||
return this.parent.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<CommandSource> getCommandSource() {
|
|
||||||
final UUID uuid = this.parent.getUuid();
|
|
||||||
return Sponge.getServer().getPlayer(uuid).map(Function.identity());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LPSubjectCollection getParentCollection() {
|
|
||||||
return this.plugin.getService().getUserSubjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Subject sponge() {
|
|
||||||
return ProxyFactory.toSponge(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuckPermsService getService() {
|
|
||||||
return this.plugin.getService();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuckPermsSubjectData getSubjectData() {
|
|
||||||
return this.subjectData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuckPermsSubjectData getTransientSubjectData() {
|
|
||||||
return this.transientSubjectData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Tristate getPermissionValue(ImmutableContextSet contexts, String permission) {
|
|
||||||
return this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getPermissionValue(permission, CheckOrigin.PLATFORM_LOOKUP_CHECK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChildOf(ImmutableContextSet contexts, LPSubjectReference parent) {
|
|
||||||
return parent.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP) && getPermissionValue(contexts, NodeFactory.groupNode(parent.getSubjectIdentifier())).asBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImmutableList<LPSubjectReference> getParents(ImmutableContextSet contexts) {
|
|
||||||
ImmutableSet.Builder<LPSubjectReference> subjects = ImmutableSet.builder();
|
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> entry : this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getImmutableBacking().entrySet()) {
|
|
||||||
if (!entry.getValue()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String groupName = NodeFactory.parseGroupNode(entry.getKey());
|
|
||||||
if (groupName == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.plugin.getGroupManager().isLoaded(groupName)) {
|
|
||||||
subjects.add(this.plugin.getService().getGroupSubjects().loadSubject(groupName).join().toReference());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subjects.addAll(this.plugin.getService().getUserSubjects().getDefaults().getParents(contexts));
|
|
||||||
subjects.addAll(this.plugin.getService().getDefaults().getParents(contexts));
|
|
||||||
|
|
||||||
return getService().sortSubjects(subjects.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<String> getOption(ImmutableContextSet contexts, String s) {
|
|
||||||
MetaData data = this.parent.getCachedData().getMetaData(this.plugin.getContextManager().formContexts(contexts));
|
|
||||||
if (s.equalsIgnoreCase(NodeFactory.PREFIX_KEY)) {
|
|
||||||
if (data.getPrefix() != null) {
|
|
||||||
return Optional.of(data.getPrefix());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.equalsIgnoreCase(NodeFactory.SUFFIX_KEY)) {
|
|
||||||
if (data.getSuffix() != null) {
|
|
||||||
return Optional.of(data.getSuffix());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String val = data.getMeta().get(s);
|
|
||||||
if (val != null) {
|
|
||||||
return Optional.of(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<String> v = this.plugin.getService().getUserSubjects().getDefaults().getOption(contexts, s);
|
|
||||||
if (v.isPresent()) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.plugin.getService().getDefaults().getOption(contexts, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaches(CacheLevel cacheLevel) {
|
|
||||||
// invalidate for all changes
|
|
||||||
this.parent.getCachedData().invalidateCaches();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public final class LuckPermsPermissionDescription implements LPPermissionDescription {
|
public final class LuckPermsPermissionDescription implements LPPermissionDescription {
|
||||||
|
|
||||||
private final LPPermissionService service;
|
private final LPPermissionService service;
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
@ -37,7 +37,6 @@ import me.lucko.luckperms.sponge.LPSpongePlugin;
|
|||||||
import me.lucko.luckperms.sponge.contexts.SpongeProxiedContextCalculator;
|
import me.lucko.luckperms.sponge.contexts.SpongeProxiedContextCalculator;
|
||||||
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
|
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
|
||||||
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
|
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
|
||||||
import me.lucko.luckperms.sponge.service.legacy.LegacyDataMigrator;
|
|
||||||
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
|
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
@ -90,7 +89,6 @@ public class LuckPermsService implements LPPermissionService {
|
|||||||
this.spongeProxy = ProxyFactory.toSponge(this);
|
this.spongeProxy = ProxyFactory.toSponge(this);
|
||||||
|
|
||||||
this.storage = new SubjectStorage(this, new File(plugin.getDataDirectory(), "sponge-data"));
|
this.storage = new SubjectStorage(this, new File(plugin.getDataDirectory(), "sponge-data"));
|
||||||
new LegacyDataMigrator(plugin, new File(plugin.getDataDirectory(), "local"), this.storage).run();
|
|
||||||
|
|
||||||
this.userSubjects = plugin.getUserManager();
|
this.userSubjects = plugin.getUserManager();
|
||||||
this.groupSubjects = plugin.getGroupManager();
|
this.groupSubjects = plugin.getGroupManager();
|
||||||
|
@ -29,7 +29,6 @@ import com.github.benmanes.caffeine.cache.Caffeine;
|
|||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.Tristate;
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||||
@ -38,7 +37,6 @@ import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
|
|||||||
import me.lucko.luckperms.common.contexts.ContextSetComparator;
|
import me.lucko.luckperms.common.contexts.ContextSetComparator;
|
||||||
import me.lucko.luckperms.common.processors.MapProcessor;
|
import me.lucko.luckperms.common.processors.MapProcessor;
|
||||||
import me.lucko.luckperms.common.processors.PermissionProcessor;
|
import me.lucko.luckperms.common.processors.PermissionProcessor;
|
||||||
import me.lucko.luckperms.common.references.HolderType;
|
|
||||||
import me.lucko.luckperms.common.verbose.CheckOrigin;
|
import me.lucko.luckperms.common.verbose.CheckOrigin;
|
||||||
import me.lucko.luckperms.sponge.processors.SpongeWildcardProcessor;
|
import me.lucko.luckperms.sponge.processors.SpongeWildcardProcessor;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||||
@ -52,6 +50,7 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -60,33 +59,28 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* In-memory implementation of {@link LPSubjectData}.
|
* In-memory implementation of {@link LPSubjectData}.
|
||||||
*/
|
*/
|
||||||
public class CalculatedSubjectData implements LPSubjectData {
|
public class CalculatedSubjectData implements LPSubjectData {
|
||||||
|
|
||||||
private final LPSubject parentSubject;
|
private final LPSubject parentSubject;
|
||||||
|
|
||||||
private final LPPermissionService service;
|
private final LPPermissionService service;
|
||||||
private final String calculatorDisplayName;
|
|
||||||
|
|
||||||
private final Map<ImmutableContextSet, Map<String, Boolean>> permissions = new ConcurrentHashMap<>();
|
private final Map<ImmutableContextSet, Map<String, Boolean>> permissions = new ConcurrentHashMap<>();
|
||||||
private final Map<ImmutableContextSet, Set<LPSubjectReference>> parents = new ConcurrentHashMap<>();
|
private final Map<ImmutableContextSet, Set<LPSubjectReference>> parents = new ConcurrentHashMap<>();
|
||||||
private final Map<ImmutableContextSet, Map<String, String>> options = new ConcurrentHashMap<>();
|
private final Map<ImmutableContextSet, Map<String, String>> options = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final LoadingCache<ImmutableContextSet, CalculatorHolder> permissionCache = Caffeine.newBuilder()
|
private final LoadingCache<ImmutableContextSet, CalculatorHolder> permissionCache;
|
||||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
|
||||||
.build(contexts -> {
|
|
||||||
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
|
||||||
processors.add(new MapProcessor());
|
|
||||||
processors.add(new SpongeWildcardProcessor());
|
|
||||||
|
|
||||||
CalculatorHolder holder = new CalculatorHolder(new PermissionCalculator(CalculatedSubjectData.this.service.getPlugin(), PermissionCalculatorMetadata.of(HolderType.GROUP, CalculatedSubjectData.this.calculatorDisplayName, contexts), processors.build()));
|
|
||||||
holder.setPermissions(flattenMap(getRelevantEntries(contexts, CalculatedSubjectData.this.permissions)));
|
|
||||||
|
|
||||||
return holder;
|
|
||||||
});
|
|
||||||
|
|
||||||
public CalculatedSubjectData(LPSubject parentSubject, LPPermissionService service, String calculatorDisplayName) {
|
public CalculatedSubjectData(LPSubject parentSubject, LPPermissionService service, String calculatorDisplayName) {
|
||||||
this.parentSubject = parentSubject;
|
this.parentSubject = parentSubject;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.calculatorDisplayName = calculatorDisplayName;
|
this.permissionCache = Caffeine.newBuilder()
|
||||||
|
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||||
|
.build(contexts -> {
|
||||||
|
ImmutableList<PermissionProcessor> processors = ImmutableList.of(new MapProcessor(), new SpongeWildcardProcessor());
|
||||||
|
PermissionCalculatorMetadata calcMetadata = PermissionCalculatorMetadata.of(null, calculatorDisplayName, contexts);
|
||||||
|
|
||||||
|
CalculatorHolder holder = new CalculatorHolder(new PermissionCalculator(this.service.getPlugin(), calcMetadata, processors));
|
||||||
|
holder.setPermissions(processPermissionsMap(contexts, this.permissions));
|
||||||
|
return holder;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -103,7 +97,8 @@ public class CalculatedSubjectData implements LPSubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Tristate getPermissionValue(ImmutableContextSet contexts, String permission) {
|
public Tristate getPermissionValue(ImmutableContextSet contexts, String permission) {
|
||||||
return this.permissionCache.get(contexts).getCalculator().getPermissionValue(permission, CheckOrigin.INTERNAL);
|
CalculatorHolder calculatorHolder = Objects.requireNonNull(this.permissionCache.get(contexts));
|
||||||
|
return calculatorHolder.getCalculator().getPermissionValue(permission, CheckOrigin.INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replacePermissions(Map<ImmutableContextSet, Map<String, Boolean>> map) {
|
public void replacePermissions(Map<ImmutableContextSet, Map<String, Boolean>> map) {
|
||||||
@ -291,30 +286,25 @@ public class CalculatedSubjectData implements LPSubjectData {
|
|||||||
return CompletableFuture.completedFuture(!map.isEmpty());
|
return CompletableFuture.completedFuture(!map.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <V> Map<String, V> flattenMap(SortedMap<ImmutableContextSet, Map<String, V>> data) {
|
private static Map<String, Boolean> processPermissionsMap(ImmutableContextSet filter, Map<ImmutableContextSet, Map<String, Boolean>> input) {
|
||||||
Map<String, V> map = new HashMap<>();
|
// get relevant entries
|
||||||
|
SortedMap<ImmutableContextSet, Map<String, Boolean>> sorted = new TreeMap<>(ContextSetComparator.reverse());
|
||||||
for (Map<String, V> m : data.values()) {
|
for (Map.Entry<ImmutableContextSet, Map<String, Boolean>> entry : input.entrySet()) {
|
||||||
for (Map.Entry<String, V> e : m.entrySet()) {
|
if (!entry.getKey().isSatisfiedBy(filter)) {
|
||||||
map.putIfAbsent(e.getKey(), e.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImmutableMap.copyOf(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <K, V> SortedMap<ImmutableContextSet, Map<K, V>> getRelevantEntries(ImmutableContextSet set, Map<ImmutableContextSet, Map<K, V>> map) {
|
|
||||||
ImmutableSortedMap.Builder<ImmutableContextSet, Map<K, V>> perms = ImmutableSortedMap.orderedBy(ContextSetComparator.reverse());
|
|
||||||
|
|
||||||
for (Map.Entry<ImmutableContextSet, Map<K, V>> e : map.entrySet()) {
|
|
||||||
if (!e.getKey().isSatisfiedBy(set)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
perms.put(e.getKey(), ImmutableMap.copyOf(e.getValue()));
|
sorted.put(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return perms.build();
|
// flatten
|
||||||
|
Map<String, Boolean> result = new HashMap<>();
|
||||||
|
for (Map<String, Boolean> map : sorted.values()) {
|
||||||
|
for (Map.Entry<String, Boolean> e : map.entrySet()) {
|
||||||
|
result.putIfAbsent(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ImmutableMap.copyOf(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean stringEquals(String a, String b) {
|
private static boolean stringEquals(String a, String b) {
|
||||||
@ -322,9 +312,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class CalculatorHolder {
|
private static class CalculatorHolder {
|
||||||
|
|
||||||
private final PermissionCalculator calculator;
|
private final PermissionCalculator calculator;
|
||||||
|
|
||||||
private final Map<String, Boolean> permissions;
|
private final Map<String, Boolean> permissions;
|
||||||
|
|
||||||
public CalculatorHolder(PermissionCalculator calculator) {
|
public CalculatorHolder(PermissionCalculator calculator) {
|
||||||
|
@ -23,52 +23,42 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service.persisted;
|
package me.lucko.luckperms.sponge.service.internal;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
|
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||||
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||||
|
|
||||||
public final class OptionLookupKey {
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
|
||||||
public static OptionLookupKey of(String key, ImmutableContextSet contexts) {
|
import java.util.Optional;
|
||||||
return new OptionLookupKey(key, contexts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String key;
|
/**
|
||||||
private final ImmutableContextSet contexts;
|
* Implements {@link LPSubject} for a {@link SpongeGroup}.
|
||||||
|
*/
|
||||||
private OptionLookupKey(String key, ImmutableContextSet contexts) {
|
public class GroupSubject extends HolderSubject<SpongeGroup> implements LPSubject {
|
||||||
this.key = key;
|
public GroupSubject(LPSpongePlugin plugin, SpongeGroup parent) {
|
||||||
this.contexts = contexts;
|
super(plugin, parent);
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return this.key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImmutableContextSet getContexts() {
|
|
||||||
return this.contexts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public String getIdentifier() {
|
||||||
if (o == this) return true;
|
return this.parent.getObjectName();
|
||||||
if (!(o instanceof OptionLookupKey)) return false;
|
|
||||||
final OptionLookupKey other = (OptionLookupKey) o;
|
|
||||||
|
|
||||||
return this.getKey().equals(other.getKey()) && this.getContexts().equals(other.getContexts());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public Optional<String> getFriendlyIdentifier() {
|
||||||
final int PRIME = 59;
|
return this.parent.getDisplayName();
|
||||||
int result = 1;
|
|
||||||
result = result * PRIME + this.getKey().hashCode();
|
|
||||||
result = result * PRIME + this.getContexts().hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public Optional<CommandSource> getCommandSource() {
|
||||||
return "OptionLookupKey(key=" + this.getKey() + ", contexts=" + this.getContexts() + ")";
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LPSubjectCollection getParentCollection() {
|
||||||
|
return this.plugin.getService().getGroupSubjects();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of LuckPerms, licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||||
|
* Copyright (c) contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.internal;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import me.lucko.luckperms.api.Tristate;
|
||||||
|
import me.lucko.luckperms.api.caching.MetaData;
|
||||||
|
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||||
|
import me.lucko.luckperms.common.model.NodeMapType;
|
||||||
|
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||||
|
import me.lucko.luckperms.common.node.NodeFactory;
|
||||||
|
import me.lucko.luckperms.common.verbose.CheckOrigin;
|
||||||
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.sponge.service.ProxyFactory;
|
||||||
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||||
|
|
||||||
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@link LPSubject} for a {@link PermissionHolder}.
|
||||||
|
*/
|
||||||
|
public abstract class HolderSubject<T extends PermissionHolder> implements LPSubject {
|
||||||
|
protected final T parent;
|
||||||
|
protected final LPSpongePlugin plugin;
|
||||||
|
|
||||||
|
private final HolderSubjectData subjectData;
|
||||||
|
private final HolderSubjectData transientSubjectData;
|
||||||
|
|
||||||
|
HolderSubject(LPSpongePlugin plugin, T parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.subjectData = new HolderSubjectData(plugin.getService(), NodeMapType.ENDURING, parent, this);
|
||||||
|
this.transientSubjectData = new HolderSubjectData(plugin.getService(), NodeMapType.TRANSIENT, parent, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject sponge() {
|
||||||
|
return ProxyFactory.toSponge(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LuckPermsService getService() {
|
||||||
|
return this.plugin.getService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HolderSubjectData getSubjectData() {
|
||||||
|
return this.subjectData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HolderSubjectData getTransientSubjectData() {
|
||||||
|
return this.transientSubjectData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tristate getPermissionValue(ImmutableContextSet contexts, String permission) {
|
||||||
|
return this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getPermissionValue(permission, CheckOrigin.PLATFORM_LOOKUP_CHECK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildOf(ImmutableContextSet contexts, LPSubjectReference parent) {
|
||||||
|
return parent.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP) && getPermissionValue(contexts, NodeFactory.groupNode(parent.getSubjectIdentifier())).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImmutableList<LPSubjectReference> getParents(ImmutableContextSet contexts) {
|
||||||
|
ImmutableSet.Builder<LPSubjectReference> subjects = ImmutableSet.builder();
|
||||||
|
|
||||||
|
for (Map.Entry<String, Boolean> entry : this.parent.getCachedData().getPermissionData(this.plugin.getContextManager().formContexts(contexts)).getImmutableBacking().entrySet()) {
|
||||||
|
if (!entry.getValue()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String groupName = NodeFactory.parseGroupNode(entry.getKey());
|
||||||
|
if (groupName == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.plugin.getGroupManager().isLoaded(groupName)) {
|
||||||
|
subjects.add(this.plugin.getService().getGroupSubjects().loadSubject(groupName).join().toReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subjects.addAll(getParentCollection().getDefaults().getParents(contexts));
|
||||||
|
subjects.addAll(this.plugin.getService().getDefaults().getParents(contexts));
|
||||||
|
|
||||||
|
return getService().sortSubjects(subjects.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getOption(ImmutableContextSet contexts, String s) {
|
||||||
|
MetaData data = this.parent.getCachedData().getMetaData(this.plugin.getContextManager().formContexts(contexts));
|
||||||
|
if (s.equalsIgnoreCase(NodeFactory.PREFIX_KEY)) {
|
||||||
|
if (data.getPrefix() != null) {
|
||||||
|
return Optional.of(data.getPrefix());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.equalsIgnoreCase(NodeFactory.SUFFIX_KEY)) {
|
||||||
|
if (data.getSuffix() != null) {
|
||||||
|
return Optional.of(data.getSuffix());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String val = data.getMeta().get(s);
|
||||||
|
if (val != null) {
|
||||||
|
return Optional.of(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<String> v = getParentCollection().getDefaults().getOption(contexts, s);
|
||||||
|
if (v.isPresent()) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.plugin.getService().getDefaults().getOption(contexts, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCaches(CacheLevel cacheLevel) {
|
||||||
|
// invalidate for all changes
|
||||||
|
this.parent.getCachedData().invalidateCaches();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service;
|
package me.lucko.luckperms.sponge.service.internal;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
@ -35,9 +35,11 @@ import me.lucko.luckperms.api.Tristate;
|
|||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||||
import me.lucko.luckperms.common.caching.type.MetaAccumulator;
|
import me.lucko.luckperms.common.caching.type.MetaAccumulator;
|
||||||
import me.lucko.luckperms.common.model.Group;
|
import me.lucko.luckperms.common.model.Group;
|
||||||
|
import me.lucko.luckperms.common.model.NodeMapType;
|
||||||
import me.lucko.luckperms.common.model.PermissionHolder;
|
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.model.User;
|
import me.lucko.luckperms.common.model.User;
|
||||||
import me.lucko.luckperms.common.node.NodeFactory;
|
import me.lucko.luckperms.common.node.NodeFactory;
|
||||||
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
|
||||||
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
import me.lucko.luckperms.sponge.service.reference.LPSubjectReference;
|
||||||
@ -50,25 +52,27 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class LuckPermsSubjectData implements LPSubjectData {
|
public class HolderSubjectData implements LPSubjectData {
|
||||||
private final boolean enduring;
|
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
|
|
||||||
|
private final NodeMapType type;
|
||||||
private final PermissionHolder holder;
|
private final PermissionHolder holder;
|
||||||
|
|
||||||
private final LPSubject parentSubject;
|
private final LPSubject parentSubject;
|
||||||
|
|
||||||
public LuckPermsSubjectData(boolean enduring, LuckPermsService service, PermissionHolder holder, LPSubject parentSubject) {
|
public HolderSubjectData(LuckPermsService service, NodeMapType type, PermissionHolder holder, LPSubject parentSubject) {
|
||||||
this.enduring = enduring;
|
this.type = type;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.holder = holder;
|
this.holder = holder;
|
||||||
this.parentSubject = parentSubject;
|
this.parentSubject = parentSubject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stream<Node> streamNodes() {
|
||||||
|
return this.holder.getNodes(this.type).values().stream();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LPSubject getParentSubject() {
|
public LPSubject getParentSubject() {
|
||||||
return this.parentSubject;
|
return this.parentSubject;
|
||||||
@ -76,21 +80,15 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<ImmutableContextSet, ImmutableMap<String, Boolean>> getAllPermissions() {
|
public ImmutableMap<ImmutableContextSet, ImmutableMap<String, Boolean>> getAllPermissions() {
|
||||||
Map<ImmutableContextSet, ImmutableMap.Builder<String, Boolean>> perms = new HashMap<>();
|
ImmutableMap.Builder<ImmutableContextSet, ImmutableMap<String, Boolean>> ret = ImmutableMap.builder();
|
||||||
|
for (Map.Entry<ImmutableContextSet, Collection<Node>> entry : this.holder.getNodes(this.type).asMap().entrySet()) {
|
||||||
for (Map.Entry<ImmutableContextSet, Collection<Node>> e : (this.enduring ? this.holder.getEnduringNodes() : this.holder.getTransientNodes()).asMap().entrySet()) {
|
ImmutableMap.Builder<String, Boolean> builder = ImmutableMap.builder();
|
||||||
ImmutableMap.Builder<String, Boolean> results = ImmutableMap.builder();
|
for (Node n : entry.getValue()) {
|
||||||
for (Node n : e.getValue()) {
|
builder.put(n.getPermission(), n.getValuePrimitive());
|
||||||
results.put(n.getPermission(), n.getValuePrimitive());
|
|
||||||
}
|
}
|
||||||
perms.put(e.getKey(), results);
|
ret.put(entry.getKey(), builder.build());
|
||||||
}
|
}
|
||||||
|
return ret.build();
|
||||||
ImmutableMap.Builder<ImmutableContextSet, ImmutableMap<String, Boolean>> map = ImmutableMap.builder();
|
|
||||||
for (Map.Entry<ImmutableContextSet, ImmutableMap.Builder<String, Boolean>> e : perms.entrySet()) {
|
|
||||||
map.put(e.getKey(), e.getValue().build());
|
|
||||||
}
|
|
||||||
return map.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -102,42 +100,35 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
if (tristate == Tristate.UNDEFINED) {
|
if (tristate == Tristate.UNDEFINED) {
|
||||||
// Unset
|
// Unset
|
||||||
Node node = NodeFactory.builder(permission).withExtraContext(contexts).build();
|
Node node = NodeFactory.builder(permission).withExtraContext(contexts).build();
|
||||||
|
this.type.run(
|
||||||
if (this.enduring) {
|
() -> this.holder.unsetPermission(node),
|
||||||
this.holder.unsetPermission(node);
|
() -> this.holder.unsetTransientPermission(node)
|
||||||
} else {
|
);
|
||||||
this.holder.unsetTransientPermission(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectSave(this.holder).thenApply(v -> true);
|
return objectSave(this.holder).thenApply(v -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node node = NodeFactory.builder(permission).setValue(tristate.asBoolean()).withExtraContext(contexts).build();
|
Node node = NodeFactory.builder(permission).setValue(tristate.asBoolean()).withExtraContext(contexts).build();
|
||||||
|
this.type.run(
|
||||||
// Workaround: unset the inverse, to allow false -> true, true -> false overrides.
|
() -> {
|
||||||
if (this.enduring) {
|
// unset the inverse, to allow false -> true, true -> false overrides.
|
||||||
this.holder.unsetPermission(node);
|
this.holder.unsetPermission(node);
|
||||||
} else {
|
this.holder.setPermission(node);
|
||||||
this.holder.unsetTransientPermission(node);
|
},
|
||||||
}
|
() -> {
|
||||||
|
// unset the inverse, to allow false -> true, true -> false overrides.
|
||||||
if (this.enduring) {
|
this.holder.unsetTransientPermission(node);
|
||||||
this.holder.setPermission(node);
|
this.holder.setTransientPermission(node);
|
||||||
} else {
|
}
|
||||||
this.holder.setTransientPermission(node);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return objectSave(this.holder).thenApply(v -> true);
|
return objectSave(this.holder).thenApply(v -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearPermissions() {
|
public CompletableFuture<Boolean> clearPermissions() {
|
||||||
boolean ret;
|
boolean ret = this.type.supply(
|
||||||
if (this.enduring) {
|
this.holder::clearNodes,
|
||||||
ret = this.holder.clearNodes();
|
this.holder::clearTransientNodes
|
||||||
} else {
|
);
|
||||||
ret = this.holder.clearTransientNodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
@ -153,18 +144,17 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearPermissions(ImmutableContextSet contexts) {
|
public CompletableFuture<Boolean> clearPermissions(ImmutableContextSet contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
|
boolean ret = this.type.supply(
|
||||||
|
() -> this.holder.clearNodes(contexts),
|
||||||
|
() -> {
|
||||||
|
List<Node> toRemove = streamNodes()
|
||||||
|
.filter(n -> n.getFullContexts().equals(contexts))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
boolean ret;
|
toRemove.forEach(this.holder::unsetTransientPermission);
|
||||||
if (this.enduring) {
|
return !toRemove.isEmpty();
|
||||||
ret = this.holder.clearNodes(contexts);
|
}
|
||||||
} else {
|
);
|
||||||
List<Node> toRemove = streamNodes(false)
|
|
||||||
.filter(n -> n.getFullContexts().equals(contexts))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(false));
|
|
||||||
ret = !toRemove.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
@ -179,23 +169,17 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<ImmutableContextSet, ImmutableList<LPSubjectReference>> getAllParents() {
|
public ImmutableMap<ImmutableContextSet, ImmutableList<LPSubjectReference>> getAllParents() {
|
||||||
Map<ImmutableContextSet, ImmutableList.Builder<LPSubjectReference>> parents = new HashMap<>();
|
ImmutableMap.Builder<ImmutableContextSet, ImmutableList<LPSubjectReference>> ret = ImmutableMap.builder();
|
||||||
|
for (Map.Entry<ImmutableContextSet, Collection<Node>> entry : this.holder.getNodes(this.type).asMap().entrySet()) {
|
||||||
for (Map.Entry<ImmutableContextSet, Collection<Node>> e : (this.enduring ? this.holder.getEnduringNodes() : this.holder.getTransientNodes()).asMap().entrySet()) {
|
ImmutableList.Builder<LPSubjectReference> builder = ImmutableList.builder();
|
||||||
ImmutableList.Builder<LPSubjectReference> results = ImmutableList.builder();
|
for (Node n : entry.getValue()) {
|
||||||
for (Node n : e.getValue()) {
|
|
||||||
if (n.isGroupNode()) {
|
if (n.isGroupNode()) {
|
||||||
results.add(this.service.getGroupSubjects().loadSubject(n.getGroupName()).join().toReference());
|
builder.add(this.service.getGroupSubjects().loadSubject(n.getGroupName()).join().toReference());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parents.put(e.getKey(), results);
|
ret.put(entry.getKey(), builder.build());
|
||||||
}
|
}
|
||||||
|
return ret.build();
|
||||||
ImmutableMap.Builder<ImmutableContextSet, ImmutableList<LPSubjectReference>> map = ImmutableMap.builder();
|
|
||||||
for (Map.Entry<ImmutableContextSet, ImmutableList.Builder<LPSubjectReference>> e : parents.entrySet()) {
|
|
||||||
map.put(e.getKey(), e.getValue().build());
|
|
||||||
}
|
|
||||||
return map.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -203,28 +187,24 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
Objects.requireNonNull(subject, "subject");
|
Objects.requireNonNull(subject, "subject");
|
||||||
|
|
||||||
if (subject.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) {
|
if (!subject.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) {
|
||||||
return subject.resolveLp().thenCompose(sub -> {
|
return CompletableFuture.completedFuture(false);
|
||||||
DataMutateResult result;
|
|
||||||
|
|
||||||
if (this.enduring) {
|
|
||||||
result = this.holder.setPermission(NodeFactory.buildGroupNode(sub.getIdentifier())
|
|
||||||
.withExtraContext(contexts)
|
|
||||||
.build());
|
|
||||||
} else {
|
|
||||||
result = this.holder.setTransientPermission(NodeFactory.buildGroupNode(sub.getIdentifier())
|
|
||||||
.withExtraContext(contexts)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result.asBoolean()) {
|
|
||||||
return CompletableFuture.completedFuture(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectSave(this.holder).thenApply(v -> true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return CompletableFuture.completedFuture(false);
|
|
||||||
|
Node node = NodeFactory.buildGroupNode(subject.getSubjectIdentifier())
|
||||||
|
.withExtraContext(contexts)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
DataMutateResult result = this.type.supply(
|
||||||
|
() -> this.holder.setPermission(node),
|
||||||
|
() -> this.holder.setTransientPermission(node)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result.asBoolean()) {
|
||||||
|
return CompletableFuture.completedFuture(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectSave(this.holder).thenApply(v -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -232,47 +212,39 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
Objects.requireNonNull(subject, "subject");
|
Objects.requireNonNull(subject, "subject");
|
||||||
|
|
||||||
if (subject.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) {
|
if (!subject.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) {
|
||||||
subject.resolveLp().thenCompose(sub -> {
|
return CompletableFuture.completedFuture(false);
|
||||||
DataMutateResult result;
|
|
||||||
|
|
||||||
if (this.enduring) {
|
|
||||||
result = this.holder.unsetPermission(NodeFactory.buildGroupNode(sub.getIdentifier())
|
|
||||||
.withExtraContext(contexts)
|
|
||||||
.build());
|
|
||||||
} else {
|
|
||||||
result = this.holder.unsetTransientPermission(NodeFactory.buildGroupNode(sub.getIdentifier())
|
|
||||||
.withExtraContext(contexts)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result.asBoolean()) {
|
|
||||||
return CompletableFuture.completedFuture(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectSave(this.holder).thenApply(v -> true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return CompletableFuture.completedFuture(false);
|
|
||||||
|
Node node = NodeFactory.buildGroupNode(subject.getSubjectIdentifier())
|
||||||
|
.withExtraContext(contexts)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
DataMutateResult result = this.type.supply(
|
||||||
|
() -> this.holder.unsetPermission(node),
|
||||||
|
() -> this.holder.unsetTransientPermission(node)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!result.asBoolean()) {
|
||||||
|
return CompletableFuture.completedFuture(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectSave(this.holder).thenApply(v -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearParents() {
|
public CompletableFuture<Boolean> clearParents() {
|
||||||
boolean ret;
|
boolean ret = this.type.supply(
|
||||||
if (this.enduring) {
|
() -> this.holder.clearParents(true),
|
||||||
ret = this.holder.clearParents(true);
|
() -> {
|
||||||
} else {
|
List<Node> toRemove = streamNodes()
|
||||||
List<Node> toRemove = streamNodes(false)
|
.filter(Node::isGroupNode)
|
||||||
.filter(Node::isGroupNode)
|
.collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(false));
|
toRemove.forEach(this.holder::unsetTransientPermission);
|
||||||
ret = !toRemove.isEmpty();
|
return !toRemove.isEmpty();
|
||||||
|
}
|
||||||
if (ret && this.holder.getType().isUser()) {
|
);
|
||||||
this.service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) this.holder), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
@ -284,23 +256,18 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearParents(ImmutableContextSet contexts) {
|
public CompletableFuture<Boolean> clearParents(ImmutableContextSet contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
|
boolean ret = this.type.supply(
|
||||||
|
() -> this.holder.clearParents(contexts, true),
|
||||||
|
() -> {
|
||||||
|
List<Node> toRemove = streamNodes()
|
||||||
|
.filter(Node::isGroupNode)
|
||||||
|
.filter(n -> n.getFullContexts().equals(contexts))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
boolean ret;
|
toRemove.forEach(this.holder::unsetTransientPermission);
|
||||||
if (this.enduring) {
|
return !toRemove.isEmpty();
|
||||||
ret = this.holder.clearParents(contexts, true);
|
}
|
||||||
} else {
|
);
|
||||||
List<Node> toRemove = streamNodes(false)
|
|
||||||
.filter(Node::isGroupNode)
|
|
||||||
.filter(n -> n.getFullContexts().equals(contexts))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(false));
|
|
||||||
ret = !toRemove.isEmpty();
|
|
||||||
|
|
||||||
if (ret && this.holder.getType().isUser()) {
|
|
||||||
this.service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) this.holder), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
@ -315,7 +282,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
Map<ImmutableContextSet, Integer> minPrefixPriority = new HashMap<>();
|
Map<ImmutableContextSet, Integer> minPrefixPriority = new HashMap<>();
|
||||||
Map<ImmutableContextSet, Integer> minSuffixPriority = new HashMap<>();
|
Map<ImmutableContextSet, Integer> minSuffixPriority = new HashMap<>();
|
||||||
|
|
||||||
for (Node n : this.enduring ? this.holder.getEnduringNodes().values() : this.holder.getTransientNodes().values()) {
|
for (Node n : this.holder.getNodes(this.type).values()) {
|
||||||
if (!n.getValuePrimitive()) continue;
|
if (!n.getValuePrimitive()) continue;
|
||||||
if (!n.isMeta() && !n.isPrefix() && !n.isSuffix()) continue;
|
if (!n.isMeta() && !n.isPrefix() && !n.isSuffix()) continue;
|
||||||
|
|
||||||
@ -364,44 +331,46 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
Objects.requireNonNull(key, "key");
|
Objects.requireNonNull(key, "key");
|
||||||
Objects.requireNonNull(value, "value");
|
Objects.requireNonNull(value, "value");
|
||||||
|
|
||||||
|
Node node;
|
||||||
if (key.equalsIgnoreCase(NodeFactory.PREFIX_KEY) || key.equalsIgnoreCase(NodeFactory.SUFFIX_KEY)) {
|
if (key.equalsIgnoreCase(NodeFactory.PREFIX_KEY) || key.equalsIgnoreCase(NodeFactory.SUFFIX_KEY)) {
|
||||||
// special handling.
|
// special handling.
|
||||||
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
|
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
|
||||||
|
|
||||||
// remove all prefixes/suffixes from the user
|
// remove all prefixes/suffixes from the user
|
||||||
List<Node> toRemove = streamNodes(this.enduring)
|
List<Node> toRemove = streamNodes()
|
||||||
.filter(type::matches)
|
.filter(type::matches)
|
||||||
.filter(n -> n.getFullContexts().equals(contexts))
|
.filter(n -> n.getFullContexts().equals(contexts))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(this.enduring));
|
toRemove.forEach(n -> this.type.run(
|
||||||
|
() -> this.holder.unsetPermission(n),
|
||||||
|
() -> this.holder.unsetTransientPermission(n)
|
||||||
|
));
|
||||||
|
|
||||||
MetaAccumulator metaAccumulator = this.holder.accumulateMeta(null, this.service.getPlugin().getContextManager().formContexts(contexts));
|
MetaAccumulator metaAccumulator = this.holder.accumulateMeta(null, this.service.getPlugin().getContextManager().formContexts(contexts));
|
||||||
int priority = metaAccumulator.getChatMeta(type).keySet().stream().mapToInt(e -> e).max().orElse(0);
|
int priority = metaAccumulator.getChatMeta(type).keySet().stream().mapToInt(e -> e).max().orElse(0);
|
||||||
priority += 10;
|
priority += 10;
|
||||||
|
|
||||||
if (this.enduring) {
|
node = NodeFactory.buildChatMetaNode(type, priority, value).withExtraContext(contexts).build();
|
||||||
this.holder.setPermission(NodeFactory.buildChatMetaNode(type, priority, value).withExtraContext(contexts).build());
|
|
||||||
} else {
|
|
||||||
this.holder.setTransientPermission(NodeFactory.buildChatMetaNode(type, priority, value).withExtraContext(contexts).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// standard remove
|
// standard remove
|
||||||
List<Node> toRemove = streamNodes(this.enduring)
|
List<Node> toRemove = streamNodes()
|
||||||
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(key))
|
.filter(n -> n.isMeta() && n.getMeta().getKey().equals(key))
|
||||||
.filter(n -> n.getFullContexts().equals(contexts))
|
.filter(n -> n.getFullContexts().equals(contexts))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(this.enduring));
|
toRemove.forEach(n -> this.type.run(
|
||||||
|
() -> this.holder.unsetPermission(n),
|
||||||
|
() -> this.holder.unsetTransientPermission(n)
|
||||||
|
));
|
||||||
|
|
||||||
if (this.enduring) {
|
node = NodeFactory.buildMetaNode(key, value).withExtraContext(contexts).build();
|
||||||
this.holder.setPermission(NodeFactory.buildMetaNode(key, value).withExtraContext(contexts).build());
|
|
||||||
} else {
|
|
||||||
this.holder.setTransientPermission(NodeFactory.buildMetaNode(key, value).withExtraContext(contexts).build());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.type.run(
|
||||||
|
() -> this.holder.setPermission(node),
|
||||||
|
() -> this.holder.setTransientPermission(node)
|
||||||
|
);
|
||||||
return objectSave(this.holder).thenApply(v -> true);
|
return objectSave(this.holder).thenApply(v -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +379,7 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
Objects.requireNonNull(key, "key");
|
Objects.requireNonNull(key, "key");
|
||||||
|
|
||||||
List<Node> toRemove = streamNodes(this.enduring)
|
List<Node> toRemove = streamNodes()
|
||||||
.filter(n -> {
|
.filter(n -> {
|
||||||
if (key.equalsIgnoreCase(NodeFactory.PREFIX_KEY)) {
|
if (key.equalsIgnoreCase(NodeFactory.PREFIX_KEY)) {
|
||||||
return n.isPrefix();
|
return n.isPrefix();
|
||||||
@ -423,7 +392,10 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
.filter(n -> n.getFullContexts().equals(contexts))
|
.filter(n -> n.getFullContexts().equals(contexts))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(this.enduring));
|
toRemove.forEach(node -> this.type.run(
|
||||||
|
() -> this.holder.unsetPermission(node),
|
||||||
|
() -> this.holder.unsetTransientPermission(node)
|
||||||
|
));
|
||||||
|
|
||||||
return objectSave(this.holder).thenApply(v -> true);
|
return objectSave(this.holder).thenApply(v -> true);
|
||||||
}
|
}
|
||||||
@ -432,43 +404,36 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
public CompletableFuture<Boolean> clearOptions(ImmutableContextSet contexts) {
|
public CompletableFuture<Boolean> clearOptions(ImmutableContextSet contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
|
|
||||||
List<Node> toRemove = streamNodes(this.enduring)
|
List<Node> toRemove = streamNodes()
|
||||||
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix())
|
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix())
|
||||||
.filter(n -> n.getFullContexts().equals(contexts))
|
.filter(n -> n.getFullContexts().equals(contexts))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(this.enduring));
|
toRemove.forEach(node -> this.type.run(
|
||||||
|
() -> this.holder.unsetPermission(node),
|
||||||
|
() -> this.holder.unsetTransientPermission(node)
|
||||||
|
));
|
||||||
|
|
||||||
return objectSave(this.holder).thenApply(v -> !toRemove.isEmpty());
|
return objectSave(this.holder).thenApply(v -> !toRemove.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearOptions() {
|
public CompletableFuture<Boolean> clearOptions() {
|
||||||
List<Node> toRemove = streamNodes(this.enduring)
|
List<Node> toRemove = streamNodes()
|
||||||
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix())
|
.filter(n -> n.isMeta() || n.isPrefix() || n.isSuffix())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
toRemove.forEach(makeUnsetConsumer(this.enduring));
|
toRemove.forEach(node -> this.type.run(
|
||||||
|
() -> this.holder.unsetPermission(node),
|
||||||
|
() -> this.holder.unsetTransientPermission(node)
|
||||||
|
));
|
||||||
|
|
||||||
return objectSave(this.holder).thenApply(v -> !toRemove.isEmpty());
|
return objectSave(this.holder).thenApply(v -> !toRemove.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<Node> streamNodes(boolean enduring) {
|
|
||||||
return (enduring ? this.holder.getEnduringNodes() : this.holder.getTransientNodes()).values().stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Consumer<Node> makeUnsetConsumer(boolean enduring) {
|
|
||||||
return n -> {
|
|
||||||
if (enduring) {
|
|
||||||
this.holder.unsetPermission(n);
|
|
||||||
} else {
|
|
||||||
this.holder.unsetTransientPermission(n);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private CompletableFuture<Void> objectSave(PermissionHolder t) {
|
private CompletableFuture<Void> objectSave(PermissionHolder t) {
|
||||||
if (!this.enduring) {
|
// handle transient first
|
||||||
|
if (this.type == NodeMapType.TRANSIENT) {
|
||||||
// don't bother saving to primary storage. just refresh
|
// don't bother saving to primary storage. just refresh
|
||||||
if (t.getType().isUser()) {
|
if (t.getType().isUser()) {
|
||||||
User user = ((User) t);
|
User user = ((User) t);
|
||||||
@ -476,30 +441,31 @@ public class LuckPermsSubjectData implements LPSubjectData {
|
|||||||
} else {
|
} else {
|
||||||
return this.service.getPlugin().getUpdateTaskBuffer().request();
|
return this.service.getPlugin().getUpdateTaskBuffer().request();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle enduring
|
||||||
|
if (t.getType().isUser()) {
|
||||||
|
User user = ((User) t);
|
||||||
|
CompletableFuture<Void> fut = new CompletableFuture<>();
|
||||||
|
this.service.getPlugin().getStorage().saveUser(user).whenCompleteAsync((v, ex) -> {
|
||||||
|
if (ex != null) {
|
||||||
|
fut.complete(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
user.getRefreshBuffer().request().thenAccept(fut::complete);
|
||||||
|
}, this.service.getPlugin().getScheduler().async());
|
||||||
|
return fut;
|
||||||
} else {
|
} else {
|
||||||
if (t.getType().isUser()) {
|
Group group = ((Group) t);
|
||||||
User user = ((User) t);
|
CompletableFuture<Void> fut = new CompletableFuture<>();
|
||||||
CompletableFuture<Void> fut = new CompletableFuture<>();
|
this.service.getPlugin().getStorage().saveGroup(group).whenCompleteAsync((v, ex) -> {
|
||||||
this.service.getPlugin().getStorage().saveUser(user).whenCompleteAsync((v, ex) -> {
|
if (ex != null) {
|
||||||
if (ex != null) {
|
fut.complete(null);
|
||||||
fut.complete(null);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
user.getRefreshBuffer().request().thenAccept(fut::complete);
|
this.service.getPlugin().getUpdateTaskBuffer().request().thenAccept(fut::complete);
|
||||||
}, this.service.getPlugin().getScheduler().async());
|
}, this.service.getPlugin().getScheduler().async());
|
||||||
return fut;
|
return fut;
|
||||||
} else {
|
|
||||||
Group group = ((Group) t);
|
|
||||||
CompletableFuture<Void> fut = new CompletableFuture<>();
|
|
||||||
this.service.getPlugin().getStorage().saveGroup(group).whenCompleteAsync((v, ex) -> {
|
|
||||||
if (ex != null) {
|
|
||||||
fut.complete(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.service.getPlugin().getUpdateTaskBuffer().request().thenAccept(fut::complete);
|
|
||||||
}, this.service.getPlugin().getScheduler().async());
|
|
||||||
return fut;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of LuckPerms, licensed under the MIT License.
|
||||||
|
*
|
||||||
|
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||||
|
* Copyright (c) contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.sponge.service.internal;
|
||||||
|
|
||||||
|
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||||
|
import me.lucko.luckperms.sponge.model.SpongeUser;
|
||||||
|
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||||
|
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||||
|
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@link LPSubject} for a {@link SpongeUser}.
|
||||||
|
*/
|
||||||
|
public final class UserSubject extends HolderSubject<SpongeUser> implements LPSubject {
|
||||||
|
public UserSubject(LPSpongePlugin plugin, SpongeUser parent) {
|
||||||
|
super(plugin, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return this.parent.getUuid().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<String> getFriendlyIdentifier() {
|
||||||
|
return this.parent.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<CommandSource> getCommandSource() {
|
||||||
|
final UUID uuid = this.parent.getUuid();
|
||||||
|
return Sponge.getServer().getPlayer(uuid).map(Function.identity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LPSubjectCollection getParentCollection() {
|
||||||
|
return this.plugin.getService().getUserSubjects();
|
||||||
|
}
|
||||||
|
}
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of LuckPerms, licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
|
||||||
* Copyright (c) contributors
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service.legacy;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
|
||||||
import me.lucko.luckperms.sponge.service.storage.SubjectStorage;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class LegacyDataMigrator implements Runnable {
|
|
||||||
private final LPSpongePlugin plugin;
|
|
||||||
|
|
||||||
private final File oldDirectory;
|
|
||||||
private final SubjectStorage storage;
|
|
||||||
|
|
||||||
public LegacyDataMigrator(LPSpongePlugin plugin, File oldDirectory, SubjectStorage storage) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.oldDirectory = oldDirectory;
|
|
||||||
this.storage = storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!this.oldDirectory.exists() || !this.oldDirectory.isDirectory()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.plugin.getLog().warn("Migrating old sponge data... Please wait.");
|
|
||||||
|
|
||||||
File[] collections = this.oldDirectory.listFiles(File::isDirectory);
|
|
||||||
if (collections == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File collectionDir : collections) {
|
|
||||||
|
|
||||||
File[] subjects = collectionDir.listFiles((dir, name) -> name.endsWith(".json"));
|
|
||||||
if (subjects == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File subjectFile : subjects) {
|
|
||||||
String subjectName = subjectFile.getName().substring(0, subjectFile.getName().length() - ".json".length());
|
|
||||||
|
|
||||||
try (BufferedReader reader = Files.newBufferedReader(subjectFile.toPath(), StandardCharsets.UTF_8)) {
|
|
||||||
SubjectDataHolder holder = this.storage.getGson().fromJson(reader, SubjectDataHolder.class);
|
|
||||||
this.storage.saveToFile(holder.asSubjectModel(this.plugin.getService()), this.storage.resolveFile(collectionDir.getName(), subjectName));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
subjectFile.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
collectionDir.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.oldDirectory.delete();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of LuckPerms, licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
|
||||||
* Copyright (c) contributors
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service.legacy;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
|
||||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
|
||||||
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;
|
|
||||||
import me.lucko.luckperms.sponge.service.storage.SubjectStorageModel;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Because this format is no longer being used to store data.
|
|
||||||
* @see SubjectStorageModel
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
|
||||||
@Deprecated
|
|
||||||
public class SubjectDataHolder {
|
|
||||||
private Map<Map<String, String>, Map<String, Boolean>> permissions;
|
|
||||||
private Map<Map<String, String>, Map<String, String>> options;
|
|
||||||
private Map<Map<String, String>, List<String>> parents;
|
|
||||||
|
|
||||||
public SubjectDataHolder() {
|
|
||||||
// For gson
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubjectStorageModel asSubjectModel(LPPermissionService service) {
|
|
||||||
return new SubjectStorageModel(service,
|
|
||||||
this.permissions.entrySet().stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
k -> ImmutableContextSet.fromMap(k.getKey()),
|
|
||||||
Map.Entry::getValue
|
|
||||||
)),
|
|
||||||
this.options.entrySet().stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
k -> ImmutableContextSet.fromMap(k.getKey()),
|
|
||||||
Map.Entry::getValue
|
|
||||||
)),
|
|
||||||
this.parents.entrySet().stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
k -> ImmutableContextSet.fromMap(k.getKey()),
|
|
||||||
v -> v.getValue().stream().map(s -> SubjectReferenceFactory.deserialize(service, s)).collect(Collectors.toList())
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of LuckPerms, licensed under the MIT License.
|
|
||||||
*
|
|
||||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
|
||||||
* Copyright (c) contributors
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package me.lucko.luckperms.sponge.service.persisted;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
|
||||||
|
|
||||||
public final class PermissionLookupKey {
|
|
||||||
|
|
||||||
public static PermissionLookupKey of(String node, ImmutableContextSet contexts) {
|
|
||||||
return new PermissionLookupKey(node, contexts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String node;
|
|
||||||
private final ImmutableContextSet contexts;
|
|
||||||
|
|
||||||
private PermissionLookupKey(String node, ImmutableContextSet contexts) {
|
|
||||||
this.node = node;
|
|
||||||
this.contexts = contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNode() {
|
|
||||||
return this.node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImmutableContextSet getContexts() {
|
|
||||||
return this.contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == this) return true;
|
|
||||||
if (!(o instanceof PermissionLookupKey)) return false;
|
|
||||||
final PermissionLookupKey other = (PermissionLookupKey) o;
|
|
||||||
|
|
||||||
return this.getNode().equals(other.getNode()) && this.getContexts().equals(other.getContexts());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int PRIME = 59;
|
|
||||||
int result = 1;
|
|
||||||
result = result * PRIME + this.getNode().hashCode();
|
|
||||||
result = result * PRIME + this.getContexts().hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "PermissionLookupKey(node=" + this.getNode() + ", contexts=" + this.getContexts() + ")";
|
|
||||||
}
|
|
||||||
}
|
|
@ -62,7 +62,7 @@ public class PersistedCollection implements LPSubjectCollection {
|
|||||||
private final SubjectCollection spongeProxy;
|
private final SubjectCollection spongeProxy;
|
||||||
|
|
||||||
private final LoadingCache<String, PersistedSubject> subjects = Caffeine.newBuilder()
|
private final LoadingCache<String, PersistedSubject> subjects = Caffeine.newBuilder()
|
||||||
.build(s -> new PersistedSubject(s, getService(), PersistedCollection.this));
|
.build(s -> new PersistedSubject(s, getService(), this));
|
||||||
|
|
||||||
public PersistedCollection(LuckPermsService service, String identifier) {
|
public PersistedCollection(LuckPermsService service, String identifier) {
|
||||||
this.service = service;
|
this.service = service;
|
||||||
|
@ -64,7 +64,7 @@ public class PersistedSubject implements LPSubject {
|
|||||||
|
|
||||||
private final LoadingCache<PermissionLookupKey, Tristate> permissionLookupCache = Caffeine.newBuilder()
|
private final LoadingCache<PermissionLookupKey, Tristate> permissionLookupCache = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(20, TimeUnit.MINUTES)
|
.expireAfterAccess(20, TimeUnit.MINUTES)
|
||||||
.build(lookup -> lookupPermissionValue(lookup.getContexts(), lookup.getNode()));
|
.build(lookup -> lookupPermissionValue(lookup.contexts, lookup.node));
|
||||||
|
|
||||||
private final LoadingCache<ImmutableContextSet, ImmutableList<LPSubjectReference>> parentLookupCache = Caffeine.newBuilder()
|
private final LoadingCache<ImmutableContextSet, ImmutableList<LPSubjectReference>> parentLookupCache = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(20, TimeUnit.MINUTES)
|
.expireAfterAccess(20, TimeUnit.MINUTES)
|
||||||
@ -72,7 +72,7 @@ public class PersistedSubject implements LPSubject {
|
|||||||
|
|
||||||
private final LoadingCache<OptionLookupKey, Optional<String>> optionLookupCache = Caffeine.newBuilder()
|
private final LoadingCache<OptionLookupKey, Optional<String>> optionLookupCache = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(20, TimeUnit.MINUTES)
|
.expireAfterAccess(20, TimeUnit.MINUTES)
|
||||||
.build(lookup -> lookupOptionValue(lookup.getContexts(), lookup.getKey()));
|
.build(lookup -> lookupOptionValue(lookup.contexts, lookup.key));
|
||||||
|
|
||||||
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, 500L, r -> PersistedSubject.this.service.getPlugin().getScheduler().doAsync(r)) {
|
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, 500L, r -> PersistedSubject.this.service.getPlugin().getScheduler().doAsync(r)) {
|
||||||
@Override
|
@Override
|
||||||
@ -91,8 +91,9 @@ public class PersistedSubject implements LPSubject {
|
|||||||
this.service = service;
|
this.service = service;
|
||||||
this.parentCollection = parentCollection;
|
this.parentCollection = parentCollection;
|
||||||
|
|
||||||
this.subjectData = new PersistedSubjectData(service, parentCollection.getIdentifier() + "/" + identifier + "/p", this);
|
String displayName = parentCollection.getIdentifier() + "/" + identifier;
|
||||||
this.transientSubjectData = new CalculatedSubjectData(this, service, parentCollection.getIdentifier() + "/" + identifier + "/t");
|
this.subjectData = new PersistedSubjectData(service, displayName + "/p", this);
|
||||||
|
this.transientSubjectData = new CalculatedSubjectData(this, service, displayName + "/t");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -277,7 +278,7 @@ public class PersistedSubject implements LPSubject {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
Objects.requireNonNull(node, "node");
|
Objects.requireNonNull(node, "node");
|
||||||
|
|
||||||
Tristate t = this.permissionLookupCache.get(PermissionLookupKey.of(node, contexts));
|
Tristate t = this.permissionLookupCache.get(new PermissionLookupKey(node, contexts));
|
||||||
this.service.getPlugin().getVerboseHandler().offerCheckData(CheckOrigin.INTERNAL, getParentCollection().getIdentifier() + "/" + this.identifier, contexts, node, t);
|
this.service.getPlugin().getVerboseHandler().offerCheckData(CheckOrigin.INTERNAL, getParentCollection().getIdentifier() + "/" + this.identifier, contexts, node, t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -306,6 +307,54 @@ public class PersistedSubject implements LPSubject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<String> getOption(ImmutableContextSet contexts, String key) {
|
public Optional<String> getOption(ImmutableContextSet contexts, String key) {
|
||||||
return this.optionLookupCache.get(OptionLookupKey.of(key, contexts));
|
return this.optionLookupCache.get(new OptionLookupKey(key, contexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class PermissionLookupKey {
|
||||||
|
private final String node;
|
||||||
|
private final ImmutableContextSet contexts;
|
||||||
|
|
||||||
|
public PermissionLookupKey(String node, ImmutableContextSet contexts) {
|
||||||
|
this.node = node;
|
||||||
|
this.contexts = contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof PermissionLookupKey)) return false;
|
||||||
|
final PermissionLookupKey other = (PermissionLookupKey) o;
|
||||||
|
|
||||||
|
return this.node.equals(other.node) && this.contexts.equals(other.contexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.node, this.contexts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class OptionLookupKey {
|
||||||
|
private final String key;
|
||||||
|
private final ImmutableContextSet contexts;
|
||||||
|
|
||||||
|
public OptionLookupKey(String key, ImmutableContextSet contexts) {
|
||||||
|
this.key = key;
|
||||||
|
this.contexts = contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (!(o instanceof OptionLookupKey)) return false;
|
||||||
|
final OptionLookupKey other = (OptionLookupKey) o;
|
||||||
|
|
||||||
|
return this.key.equals(other.key) && this.contexts.equals(other.contexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.key, this.contexts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,11 +37,16 @@ import java.util.function.Function;
|
|||||||
/**
|
/**
|
||||||
* Extension of MemorySubjectData which persists data when modified
|
* Extension of MemorySubjectData which persists data when modified
|
||||||
*/
|
*/
|
||||||
public class PersistedSubjectData extends CalculatedSubjectData implements Function<Boolean, Boolean> {
|
public class PersistedSubjectData extends CalculatedSubjectData {
|
||||||
private final PersistedSubject subject;
|
private final PersistedSubject subject;
|
||||||
|
|
||||||
private boolean save = true;
|
private boolean save = true;
|
||||||
|
|
||||||
|
private final Function<Boolean, Boolean> saveFunction = b -> {
|
||||||
|
save();
|
||||||
|
return b;
|
||||||
|
};
|
||||||
|
|
||||||
public PersistedSubjectData(LuckPermsService service, String calculatorDisplayName, PersistedSubject subject) {
|
public PersistedSubjectData(LuckPermsService service, String calculatorDisplayName, PersistedSubject subject) {
|
||||||
super(subject, service, calculatorDisplayName);
|
super(subject, service, calculatorDisplayName);
|
||||||
this.subject = subject;
|
this.subject = subject;
|
||||||
@ -57,72 +62,62 @@ public class PersistedSubjectData extends CalculatedSubjectData implements Funct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setSave(boolean save) {
|
||||||
public Boolean apply(Boolean b) {
|
this.save = save;
|
||||||
save();
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> setPermission(ImmutableContextSet contexts, String permission, Tristate value) {
|
public CompletableFuture<Boolean> setPermission(ImmutableContextSet contexts, String permission, Tristate value) {
|
||||||
return super.setPermission(contexts, permission, value).thenApply(this);
|
return super.setPermission(contexts, permission, value).thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearPermissions() {
|
public CompletableFuture<Boolean> clearPermissions() {
|
||||||
return super.clearPermissions().thenApply(this);
|
return super.clearPermissions().thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearPermissions(ImmutableContextSet contexts) {
|
public CompletableFuture<Boolean> clearPermissions(ImmutableContextSet contexts) {
|
||||||
return super.clearPermissions(contexts).thenApply(this);
|
return super.clearPermissions(contexts).thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> addParent(ImmutableContextSet contexts, LPSubjectReference parent) {
|
public CompletableFuture<Boolean> addParent(ImmutableContextSet contexts, LPSubjectReference parent) {
|
||||||
return super.addParent(contexts, parent).thenApply(this);
|
return super.addParent(contexts, parent).thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> removeParent(ImmutableContextSet contexts, LPSubjectReference parent) {
|
public CompletableFuture<Boolean> removeParent(ImmutableContextSet contexts, LPSubjectReference parent) {
|
||||||
return super.removeParent(contexts, parent).thenApply(this);
|
return super.removeParent(contexts, parent).thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearParents() {
|
public CompletableFuture<Boolean> clearParents() {
|
||||||
return super.clearParents().thenApply(this);
|
return super.clearParents().thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearParents(ImmutableContextSet contexts) {
|
public CompletableFuture<Boolean> clearParents(ImmutableContextSet contexts) {
|
||||||
return super.clearParents(contexts).thenApply(this);
|
return super.clearParents(contexts).thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> setOption(ImmutableContextSet contexts, String key, String value) {
|
public CompletableFuture<Boolean> setOption(ImmutableContextSet contexts, String key, String value) {
|
||||||
return super.setOption(contexts, key, value).thenApply(this);
|
return super.setOption(contexts, key, value).thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> unsetOption(ImmutableContextSet contexts, String key) {
|
public CompletableFuture<Boolean> unsetOption(ImmutableContextSet contexts, String key) {
|
||||||
return super.unsetOption(contexts, key).thenApply(this);
|
return super.unsetOption(contexts, key).thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearOptions() {
|
public CompletableFuture<Boolean> clearOptions() {
|
||||||
return super.clearOptions().thenApply(this);
|
return super.clearOptions().thenApply(this.saveFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> clearOptions(ImmutableContextSet contexts) {
|
public CompletableFuture<Boolean> clearOptions(ImmutableContextSet contexts) {
|
||||||
return super.clearOptions(contexts).thenApply(this);
|
return super.clearOptions(contexts).thenApply(this.saveFunction);
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSave() {
|
|
||||||
return this.save;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSave(boolean save) {
|
|
||||||
this.save = save;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,8 @@ import java.util.stream.Collectors;
|
|||||||
* Handles persisted Subject I/O and (de)serialization
|
* Handles persisted Subject I/O and (de)serialization
|
||||||
*/
|
*/
|
||||||
public class SubjectStorage {
|
public class SubjectStorage {
|
||||||
|
|
||||||
private final LPPermissionService service;
|
private final LPPermissionService service;
|
||||||
|
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
|
|
||||||
private final File container;
|
private final File container;
|
||||||
|
|
||||||
public SubjectStorage(LPPermissionService service, File container) {
|
public SubjectStorage(LPPermissionService service, File container) {
|
||||||
@ -158,8 +155,4 @@ public class SubjectStorage {
|
|||||||
return Maps.immutableEntry(subjectName, model);
|
return Maps.immutableEntry(subjectName, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Gson getGson() {
|
|
||||||
return this.gson;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user