Refactor Sponge subject handling

This commit is contained in:
Luck 2016-11-25 20:59:28 +00:00
parent 443906da55
commit 18dd59ed0f
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
50 changed files with 919 additions and 741 deletions

View File

@ -124,7 +124,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
// Make a LuckPerms group for the one being migrated.
plugin.getStorage().createAndLoadGroup(groupName).join();
me.lucko.luckperms.common.core.model.Group lpGroup = plugin.getGroupManager().get(groupName);
me.lucko.luckperms.common.core.model.Group lpGroup = plugin.getGroupManager().getIfLoaded(groupName);
try {
LogEntry.build()
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())

View File

@ -73,7 +73,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
for (Group g : gg.getGroupList()) {
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
try {
LogEntry.build()
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())
@ -196,7 +196,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
for (Map.Entry<String, Map<Map.Entry<String, String>, Boolean>> e : groups.entrySet()) {
plugin.getStorage().createAndLoadGroup(e.getKey()).join();
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().get(e.getKey());
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(e.getKey());
try {
LogEntry.build()
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())

View File

@ -101,7 +101,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
final String name = group.getName().toLowerCase();
plugin.getStorage().createAndLoadGroup(name).join();
Group lpGroup = plugin.getGroupManager().get(name);
Group lpGroup = plugin.getGroupManager().getIfLoaded(name);
try {
LogEntry.build()
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())

View File

@ -252,7 +252,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
Map<Integer, Group> groups = pm.getGroups(); // All versions
for (Group g : groups.values()) {
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
try {
LogEntry.build()
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())

View File

@ -81,7 +81,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
log.info("zPermissions Migration: Starting group migration.");
for (String g : service.getAllGroups()) {
plugin.getStorage().createAndLoadGroup(g.toLowerCase()).join();
Group group = plugin.getGroupManager().get(g.toLowerCase());
Group group = plugin.getGroupManager().getIfLoaded(g.toLowerCase());
PermissionEntity entity = internalService.getEntity(g, null, true);
migrateEntity(group, entity);
@ -93,7 +93,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
log.info("zPermissions Migration: Starting track migration.");
for (String t : service.getAllTracks()) {
plugin.getStorage().createAndLoadTrack(t.toLowerCase()).join();
Track track = plugin.getTrackManager().get(t.toLowerCase());
Track track = plugin.getTrackManager().getIfLoaded(t.toLowerCase());
track.setGroups(service.getTrackGroups(t));
plugin.getStorage().saveTrack(track);
}

View File

@ -244,47 +244,47 @@ public class VaultChatHook extends Chat {
}
public String getPlayerPrefix(String world, @NonNull String player) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
return getUserChatMeta(true, user, world);
}
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
setChatMeta(true, user, prefix, world);
}
public String getPlayerSuffix(String world, @NonNull String player) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
return getUserChatMeta(false, user, world);
}
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
setChatMeta(false, user, suffix, world);
}
public String getGroupPrefix(String world, @NonNull String group) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
return getGroupChatMeta(false, g, world);
}
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
setChatMeta(true, g, prefix, world);
}
public String getGroupSuffix(String world, @NonNull String group) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
return getGroupChatMeta(false, g, world);
}
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
setChatMeta(false, g, suffix, world);
}
public int getPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int defaultValue) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
try {
return Integer.parseInt(getUserMeta(user, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
@ -293,12 +293,12 @@ public class VaultChatHook extends Chat {
}
public void setPlayerInfoInteger(String world, @NonNull String player, @NonNull String node, int value) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
setMeta(user, world, node, String.valueOf(value));
}
public int getGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int defaultValue) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
try {
return Integer.parseInt(getGroupMeta(g, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
@ -307,12 +307,12 @@ public class VaultChatHook extends Chat {
}
public void setGroupInfoInteger(String world, @NonNull String group, @NonNull String node, int value) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
setMeta(g, world, node, String.valueOf(value));
}
public double getPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double defaultValue) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
try {
return Double.parseDouble(getUserMeta(user, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
@ -321,12 +321,12 @@ public class VaultChatHook extends Chat {
}
public void setPlayerInfoDouble(String world, @NonNull String player, @NonNull String node, double value) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
setMeta(user, world, node, String.valueOf(value));
}
public double getGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double defaultValue) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
try {
return Double.parseDouble(getGroupMeta(g, world, node, String.valueOf(defaultValue)));
} catch (NumberFormatException e) {
@ -335,12 +335,12 @@ public class VaultChatHook extends Chat {
}
public void setGroupInfoDouble(String world, @NonNull String group, @NonNull String node, double value) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
setMeta(g, world, node, String.valueOf(value));
}
public boolean getPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean defaultValue) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
String s = getUserMeta(user, world, node, String.valueOf(defaultValue));
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
return defaultValue;
@ -349,12 +349,12 @@ public class VaultChatHook extends Chat {
}
public void setPlayerInfoBoolean(String world, @NonNull String player, @NonNull String node, boolean value) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
setMeta(user, world, node, String.valueOf(value));
}
public boolean getGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean defaultValue) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
String s = getGroupMeta(g, world, node, String.valueOf(defaultValue));
if (!s.equalsIgnoreCase("true") && !s.equalsIgnoreCase("false")) {
return defaultValue;
@ -363,27 +363,27 @@ public class VaultChatHook extends Chat {
}
public void setGroupInfoBoolean(String world, @NonNull String group, @NonNull String node, boolean value) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
setMeta(g, world, node, String.valueOf(value));
}
public String getPlayerInfoString(String world, @NonNull String player, @NonNull String node, String defaultValue) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
return getUserMeta(user, world, node, defaultValue);
}
public void setPlayerInfoString(String world, @NonNull String player, @NonNull String node, String value) {
final User user = perms.getPlugin().getUserManager().get(player);
final User user = perms.getPlugin().getUserManager().getByUsername(player);
setMeta(user, world, node, value);
}
public String getGroupInfoString(String world, @NonNull String group, @NonNull String node, String defaultValue) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
return getGroupMeta(g, world, node, defaultValue);
}
public void setGroupInfoString(String world, @NonNull String group, @NonNull String node, String value) {
final Group g = perms.getPlugin().getGroupManager().get(group);
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
setMeta(g, world, node, value);
}

View File

@ -155,7 +155,7 @@ public class VaultPermissionHook extends Permission {
world = ignoreWorld ? null : world; // Correct world value
log("Checking if player " + player + " has permission: " + permission + " on world " + world + ", server " + server);
User user = plugin.getUserManager().get(player);
User user = plugin.getUserManager().getByUsername(player);
if (user == null) return false;
if (user.getUserData() == null) {
@ -171,7 +171,7 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Adding permission to player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
final User user = plugin.getUserManager().get(player);
final User user = plugin.getUserManager().getByUsername(player);
if (user == null) return false;
scheduler.scheduleTask(() -> add(finalWorld, user, permission));
@ -183,7 +183,7 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Removing permission from player " + player + ": '" + permission + "' on world " + finalWorld + ", server " + server);
final User user = plugin.getUserManager().get(player);
final User user = plugin.getUserManager().getByUsername(player);
if (user == null) return false;
scheduler.scheduleTask(() -> remove(finalWorld, user, permission));
@ -195,7 +195,7 @@ public class VaultPermissionHook extends Permission {
world = ignoreWorld ? null : world; // Correct world value
log("Checking if group " + groupName + " has permission: " + permission + " on world " + world + ", server " + server);
final Group group = plugin.getGroupManager().get(groupName);
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) return false;
// This is a nasty call. Groups aren't cached. :(
@ -209,7 +209,7 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Adding permission to group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
final Group group = plugin.getGroupManager().get(groupName);
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) return false;
scheduler.scheduleTask(() -> add(finalWorld, group, permission));
@ -221,7 +221,7 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Removing permission from group " + groupName + ": '" + permission + "' on world " + finalWorld + ", server " + server);
final Group group = plugin.getGroupManager().get(groupName);
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) return false;
scheduler.scheduleTask(() -> remove(finalWorld, group, permission));
@ -233,7 +233,7 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Checking if player " + player + " is in group: " + group + " on world " + finalWorld + ", server " + server);
final User user = plugin.getUserManager().get(player);
final User user = plugin.getUserManager().getByUsername(player);
if (user == null) return false;
return user.getNodes().stream()
@ -250,10 +250,10 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Adding player " + player + " to group: '" + groupName + "' on world " + finalWorld + ", server " + server);
final User user = plugin.getUserManager().get(player);
final User user = plugin.getUserManager().getByUsername(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().get(groupName);
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) return false;
scheduler.scheduleTask(() -> {
@ -274,10 +274,10 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Removing player " + player + " from group: '" + groupName + "' on world " + finalWorld + ", server " + server);
final User user = plugin.getUserManager().get(player);
final User user = plugin.getUserManager().getByUsername(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().get(groupName);
final Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) return false;
scheduler.scheduleTask(() -> {
@ -298,7 +298,7 @@ public class VaultPermissionHook extends Permission {
String finalWorld = ignoreWorld ? null : world; // Correct world value
log("Getting groups of player: " + player + ", on world " + finalWorld + ", server " + server);
User user = plugin.getUserManager().get(player);
User user = plugin.getUserManager().getByUsername(player);
if (user == null) return new String[0];
return user.getNodes().stream()
@ -313,7 +313,7 @@ public class VaultPermissionHook extends Permission {
public String getPrimaryGroup(String world, @NonNull String player) {
world = ignoreWorld ? null : world; // Correct world value
log("Getting primary group of player: " + player);
final User user = plugin.getUserManager().get(player);
final User user = plugin.getUserManager().getByUsername(player);
if (user == null) {
return null;

View File

@ -65,7 +65,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
// Make a LuckPerms group for the one being migrated
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(g.getName().toLowerCase());
try {
LogEntry.build()
.actor(Constants.getConsoleUUID()).actorName(Constants.getConsoleName())

View File

@ -138,7 +138,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public User getUser(@NonNull String name) {
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(name);
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().getByUsername(name);
return user == null ? null : new UserLink(user);
}
@ -165,7 +165,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Group getGroup(@NonNull String name) {
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().get(name);
final me.lucko.luckperms.common.core.model.Group group = plugin.getGroupManager().getIfLoaded(name);
return group == null ? null : new GroupLink(group);
}
@ -186,7 +186,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public Track getTrack(@NonNull String name) {
final me.lucko.luckperms.common.core.model.Track track = plugin.getTrackManager().get(name);
final me.lucko.luckperms.common.core.model.Track track = plugin.getTrackManager().getIfLoaded(name);
return track == null ? null : new TrackLink(track);
}

View File

@ -66,7 +66,7 @@ public class ParentAdd extends SharedSubCommand {
return CommandResult.INVALID_ARGS;
}
Group group = plugin.getGroupManager().get(groupName);
Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -69,7 +69,7 @@ public class ParentAddTemp extends SharedSubCommand {
return CommandResult.INVALID_ARGS;
}
Group group = plugin.getGroupManager().get(groupName);
Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;

View File

@ -67,7 +67,7 @@ public class ParentSet extends SharedSubCommand {
return CommandResult.INVALID_ARGS;
}
Group group = plugin.getGroupManager().get(groupName);
Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -66,7 +66,7 @@ public class DeleteGroup extends SingleCommand {
return CommandResult.INVALID_ARGS;
}
Group group = plugin.getGroupManager().get(groupName);
Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) {
Message.GROUP_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -62,7 +62,7 @@ public class GroupClone extends SubCommand<Group> {
return CommandResult.FAILURE;
}
Group newGroup = plugin.getGroupManager().get(newGroupName);
Group newGroup = plugin.getGroupManager().getIfLoaded(newGroupName);
if (newGroup == null) {
Message.GROUP_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -60,7 +60,7 @@ public class GroupMainCommand extends MainCommand<Group> {
return null;
}
Group group = plugin.getGroupManager().get(target);
Group group = plugin.getGroupManager().getIfLoaded(target);
if (group == null) {
Message.GROUP_NOT_FOUND.send(sender);

View File

@ -62,7 +62,7 @@ public class GroupRename extends SubCommand<Group> {
return CommandResult.FAILURE;
}
Group newGroup = plugin.getGroupManager().get(newGroupName);
Group newGroup = plugin.getGroupManager().getIfLoaded(newGroupName);
if (newGroup == null) {
Message.GROUP_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -60,7 +60,7 @@ public class DeleteTrack extends SingleCommand {
return CommandResult.INVALID_ARGS;
}
Track track = plugin.getTrackManager().get(trackName);
Track track = plugin.getTrackManager().getIfLoaded(trackName);
if (track == null) {
Message.TRACK_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -61,7 +61,7 @@ public class TrackAppend extends SubCommand<Track> {
return CommandResult.INVALID_ARGS;
}
Group group = plugin.getGroupManager().get(groupName);
Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -62,7 +62,7 @@ public class TrackClone extends SubCommand<Track> {
return CommandResult.FAILURE;
}
Track newTrack = plugin.getTrackManager().get(newTrackName);
Track newTrack = plugin.getTrackManager().getIfLoaded(newTrackName);
if (newTrack == null) {
Message.TRACK_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -72,7 +72,7 @@ public class TrackInsert extends SubCommand<Track> {
return CommandResult.INVALID_ARGS;
}
Group group = plugin.getGroupManager().get(groupName);
Group group = plugin.getGroupManager().getIfLoaded(groupName);
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -54,7 +54,7 @@ public class TrackMainCommand extends MainCommand<Track> {
return null;
}
Track track = plugin.getTrackManager().get(target);
Track track = plugin.getTrackManager().getIfLoaded(target);
if (track == null) {
Message.TRACK_NOT_FOUND.send(sender);
return null;

View File

@ -62,7 +62,7 @@ public class TrackRename extends SubCommand<Track> {
return CommandResult.FAILURE;
}
Track newTrack = plugin.getTrackManager().get(newTrackName);
Track newTrack = plugin.getTrackManager().getIfLoaded(newTrackName);
if (newTrack == null) {
Message.TRACK_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;

View File

@ -77,7 +77,7 @@ public class UserDemote extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
Track track = plugin.getTrackManager().get(trackName);
Track track = plugin.getTrackManager().getIfLoaded(trackName);
if (track == null) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;
@ -152,7 +152,7 @@ public class UserDemote extends SubCommand<User> {
return CommandResult.STATE_ERROR;
}
Group previousGroup = plugin.getGroupManager().get(previous);
Group previousGroup = plugin.getGroupManager().getIfLoaded(previous);
if (previousGroup == null) {
Message.USER_DEMOTE_ERROR_MALFORMED.send(sender, previous);
return CommandResult.LOADING_ERROR;

View File

@ -77,7 +77,7 @@ public class UserPromote extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
Track track = plugin.getTrackManager().get(trackName);
Track track = plugin.getTrackManager().getIfLoaded(trackName);
if (track == null) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;
@ -152,7 +152,7 @@ public class UserPromote extends SubCommand<User> {
return CommandResult.STATE_ERROR;
}
Group nextGroup = plugin.getGroupManager().get(next);
Group nextGroup = plugin.getGroupManager().getIfLoaded(next);
if (nextGroup == null) {
Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, next);
return CommandResult.LOADING_ERROR;

View File

@ -47,7 +47,7 @@ public class UserSwitchPrimaryGroup extends SubCommand<User> {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) throws CommandException {
Group group = plugin.getGroupManager().get(args.get(0).toLowerCase());
Group group = plugin.getGroupManager().getIfLoaded(args.get(0).toLowerCase());
if (group == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;

View File

@ -45,7 +45,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
@Override
public String getId() {
return name;
return name.toLowerCase();
}
public String getRawDisplayName() {

View File

@ -285,7 +285,7 @@ public abstract class PermissionHolder {
for (Map.Entry<Integer, Node> e : sortedParents) {
Node parent = e.getValue();
Group group = plugin.getGroupManager().get(parent.getGroupName());
Group group = plugin.getGroupManager().getIfLoaded(parent.getGroupName());
if (group == null) {
continue;
}
@ -361,7 +361,7 @@ public abstract class PermissionHolder {
for (Map.Entry<Integer, Node> e : sortedParents) {
Node parent = e.getValue();
Group group = plugin.getGroupManager().get(parent.getGroupName());
Group group = plugin.getGroupManager().getIfLoaded(parent.getGroupName());
if (group == null) {
continue;
}

View File

@ -58,7 +58,7 @@ public class Track implements Identifiable<String> {
@Override
public String getId() {
return name;
return name.toLowerCase();
}
/**

View File

@ -59,17 +59,30 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements M
@Override
public T getOrMake(I id) {
return objects.getUnchecked(id);
if (id instanceof String) {
return objects.getUnchecked((I) ((String) id).toLowerCase());
} else {
return objects.getUnchecked(id);
}
}
@Override
public T get(I id) {
return objects.getIfPresent(id);
public T getIfLoaded(I id) {
if (id instanceof String) {
return objects.getIfPresent(((String) id).toLowerCase());
} else {
return objects.getIfPresent(id);
}
}
@Override
public boolean isLoaded(I id) {
return objects.asMap().containsKey(id);
if (id instanceof String) {
return objects.asMap().containsKey(((String) id).toLowerCase());
} else {
return objects.asMap().containsKey(id);
}
}
@Override

View File

@ -38,7 +38,7 @@ public interface Manager<I, T extends Identifiable<I>> extends Function<I, T> {
* Gets a map containing all cached instances held by this manager.
* @return all instances held in this manager
*/
Map<I, T> getAll();
Map<I, ? extends T> getAll();
/**
* Gets or creates an object by id
@ -52,7 +52,7 @@ public interface Manager<I, T extends Identifiable<I>> extends Function<I, T> {
* @param id The id to search by
* @return a {@link T} object if the object is loaded, returns null if the object is not loaded
*/
T get(I id);
T getIfLoaded(I id);
/**
* Check to see if a object is loaded or not

View File

@ -35,7 +35,7 @@ public interface UserManager extends Manager<UserIdentifier, User> {
* @param name The name to search by
* @return a {@link User} object if the user is loaded, returns null if the user is not loaded
*/
User get(String name);
User getByUsername(String name);
/**
* Get a user object by uuid
@ -50,13 +50,6 @@ public interface UserManager extends Manager<UserIdentifier, User> {
*/
boolean giveDefaultIfNeeded(User user, boolean save);
/**
* Check whether the user's state indicates that they should be persisted to storage.
* @param user the user to check
* @return true if the user should be saved
*/
boolean shouldSave(User user);
/**
* Checks to see if the user is online, and if they are not, runs {@link #unload(Identifiable)}
* @param user The user to be cleaned up

View File

@ -29,7 +29,6 @@ import me.lucko.luckperms.common.core.UserIdentifier;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.managers.AbstractManager;
import me.lucko.luckperms.common.managers.UserManager;
import me.lucko.luckperms.common.utils.Identifiable;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import java.util.Set;
@ -46,12 +45,8 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
new User(id.getUuid(), id.getUsername(), plugin);
}
/**
* Get a user object by name
* @param name The name to search by
* @return a {@link User} object if the user is loaded, returns null if the user is not loaded
*/
public User get(String name) {
@Override
public User getByUsername(String name) {
for (User user : getAll().values()) {
if (user.getName().equalsIgnoreCase(name)) {
return user;
@ -60,15 +55,37 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
return null;
}
@Override
public User get(UUID uuid) {
return get(UserIdentifier.of(uuid, null));
return getIfLoaded(UserIdentifier.of(uuid, null));
}
/**
* Set a user to the default group
* @param user the user to give to
*/
@Override
public boolean giveDefaultIfNeeded(User user, boolean save) {
return giveDefaultIfNeeded(user, save, plugin);
}
@Override
public void cleanup(User user) {
if (!plugin.isOnline(plugin.getUuidCache().getExternalUUID(user.getUuid()))) {
unload(user);
}
}
@Override
public void updateAllUsers() {
plugin.doSync(() -> {
Set<UUID> players = plugin.getOnlinePlayers();
plugin.doAsync(() -> {
for (UUID uuid : players) {
UUID internal = plugin.getUuidCache().getUUID(uuid);
plugin.getStorage().loadUser(internal, "null").join();
}
});
});
}
public static boolean giveDefaultIfNeeded(User user, boolean save, LuckPermsPlugin plugin) {
boolean hasGroup = false;
if (user.getPrimaryGroup() != null && !user.getPrimaryGroup().isEmpty()) {
@ -96,7 +113,12 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
return true;
}
public boolean shouldSave(User user) {
/**
* Check whether the user's state indicates that they should be persisted to storage.
* @param user the user to check
* @return true if the user should be saved
*/
public static boolean shouldSave(User user) {
if (user.getNodes().size() != 1) {
return true;
}
@ -123,29 +145,4 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
return false;
}
/**
* Checks to see if the user is online, and if they are not, runs {@link #unload(Identifiable)}
* @param user The user to be cleaned up
*/
public void cleanup(User user) {
if (!plugin.isOnline(plugin.getUuidCache().getExternalUUID(user.getUuid()))) {
unload(user);
}
}
/**
* Reloads the data of all online users
*/
public void updateAllUsers() {
plugin.doSync(() -> {
Set<UUID> players = plugin.getOnlinePlayers();
plugin.doAsync(() -> {
for (UUID uuid : players) {
UUID internal = plugin.getUuidCache().getUUID(uuid);
plugin.getStorage().loadUser(internal, "null").join();
}
});
});
}
}

View File

@ -32,6 +32,7 @@ import me.lucko.luckperms.common.core.model.Track;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import java.io.*;
import java.util.*;
@ -131,7 +132,7 @@ public class JSONBacking extends FlatfileBacking {
return true;
});
} else {
if (plugin.getUserManager().shouldSave(user)) {
if (GenericUserManager.shouldSave(user)) {
user.clearNodes();
user.setPrimaryGroup(null);
plugin.getUserManager().giveDefaultIfNeeded(user, false);
@ -151,7 +152,7 @@ public class JSONBacking extends FlatfileBacking {
try {
return call(() -> {
File userFile = new File(usersDir, user.getUuid().toString() + ".json");
if (!plugin.getUserManager().shouldSave(user)) {
if (!GenericUserManager.shouldSave(user)) {
if (userFile.exists()) {
userFile.delete();
}

View File

@ -38,6 +38,7 @@ import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import me.lucko.luckperms.common.storage.DatastoreConfiguration;
import org.bson.Document;
@ -167,7 +168,7 @@ public class MongoDBBacking extends AbstractBacking {
c.replaceOne(new Document("_id", user.getUuid()), fromUser(user));
}
} else {
if (plugin.getUserManager().shouldSave(user)) {
if (GenericUserManager.shouldSave(user)) {
user.clearNodes();
user.setPrimaryGroup(null);
plugin.getUserManager().giveDefaultIfNeeded(user, false);
@ -184,7 +185,7 @@ public class MongoDBBacking extends AbstractBacking {
@Override
public boolean saveUser(User user) {
if (!plugin.getUserManager().shouldSave(user)) {
if (!GenericUserManager.shouldSave(user)) {
user.getIoLock().lock();
try {
return call(() -> {

View File

@ -33,6 +33,7 @@ import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import java.lang.reflect.Type;
import java.sql.Connection;
@ -205,7 +206,7 @@ abstract class SQLBacking extends AbstractBacking {
}
} else {
if (plugin.getUserManager().shouldSave(user)) {
if (GenericUserManager.shouldSave(user)) {
user.clearNodes();
user.setPrimaryGroup(null);
plugin.getUserManager().giveDefaultIfNeeded(user, false);
@ -221,7 +222,7 @@ abstract class SQLBacking extends AbstractBacking {
@Override
public boolean saveUser(User user) {
if (!plugin.getUserManager().shouldSave(user)) {
if (!GenericUserManager.shouldSave(user)) {
user.getIoLock().lock();
try {
return runQuery(USER_DELETE, preparedStatement -> {

View File

@ -30,6 +30,7 @@ import me.lucko.luckperms.common.core.model.Track;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
@ -113,7 +114,7 @@ public class YAMLBacking extends FlatfileBacking {
return true;
});
} else {
if (plugin.getUserManager().shouldSave(user)) {
if (GenericUserManager.shouldSave(user)) {
user.clearNodes();
user.setPrimaryGroup(null);
plugin.getUserManager().giveDefaultIfNeeded(user, false);
@ -133,7 +134,7 @@ public class YAMLBacking extends FlatfileBacking {
try {
return call(() -> {
File userFile = new File(usersDir, user.getUuid().toString() + ".yml");
if (!plugin.getUserManager().shouldSave(user)) {
if (!GenericUserManager.shouldSave(user)) {
if (userFile.exists()) {
userFile.delete();
}

View File

@ -22,8 +22,17 @@
package me.lucko.luckperms.common.utils;
/**
* Interface to represent an identifiable object
* @param <T>
*/
public interface Identifiable<T> {
/**
* Returns the objects identifier.
* If the type is a {@link String}, this method must return a {@link String#toLowerCase()} representation
* @return the identifier
*/
T getId();
}

View File

@ -41,12 +41,8 @@ import me.lucko.luckperms.common.contexts.ServerCalculator;
import me.lucko.luckperms.common.core.UuidCache;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.data.Importer;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.UserManager;
import me.lucko.luckperms.common.managers.impl.GenericGroupManager;
import me.lucko.luckperms.common.managers.impl.GenericTrackManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import me.lucko.luckperms.common.messaging.RedisMessaging;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
@ -55,6 +51,8 @@ import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.utils.*;
import me.lucko.luckperms.sponge.commands.SpongeMainCommand;
import me.lucko.luckperms.sponge.contexts.WorldCalculator;
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.timings.LPTimings;
import me.lucko.luckperms.sponge.utils.VersionData;
@ -119,8 +117,8 @@ public class LPSpongePlugin implements LuckPermsPlugin {
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
private LPConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private SpongeUserManager userManager;
private SpongeGroupManager groupManager;
private TrackManager trackManager;
private Storage storage;
private RedisMessaging redisMessaging = null;
@ -199,8 +197,8 @@ public class LPSpongePlugin implements LuckPermsPlugin {
// load internal managers
getLog().info("Loading internal permission managers...");
uuidCache = new UuidCache(getConfiguration().isOnlineMode());
userManager = new GenericUserManager(this);
groupManager = new GenericGroupManager(this);
userManager = new SpongeUserManager(this);
groupManager = new SpongeGroupManager(this);
trackManager = new GenericTrackManager();
importer = new Importer(commandManager);
consecutiveExecutor = new ConsecutiveExecutor(commandManager);

View File

@ -110,7 +110,6 @@ public class SpongeListener extends AbstractListener {
public void onClientLeave(ClientConnectionEvent.Disconnect e) {
try (Timing ignored = plugin.getTimings().time(LPTiming.ON_CLIENT_LEAVE)) {
onLeave(e.getTargetEntity().getUniqueId());
plugin.getService().getUserSubjects().unload(plugin.getUuidCache().getUUID(e.getTargetEntity().getUniqueId()));
}
}
}

View File

@ -20,22 +20,23 @@
* SOFTWARE.
*/
package me.lucko.luckperms.sponge.service.collections;
package me.lucko.luckperms.sponge.managers;
import co.aikar.timings.Timing;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import lombok.NonNull;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.core.model.Group;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.utils.ArgumentChecker;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.LuckPermsGroupSubject;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.model.SpongeGroup;
import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
import me.lucko.luckperms.sponge.timings.LPTiming;
@ -48,37 +49,74 @@ import org.spongepowered.api.util.Tristate;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
public class GroupCollection implements SubjectCollection {
private final LuckPermsService service;
private final GroupManager manager;
public class SpongeGroupManager implements GroupManager, SubjectCollection {
private final LPSpongePlugin plugin;
private final SimpleCollection fallback;
private final LoadingCache<String, LuckPermsGroupSubject> groups = CacheBuilder.newBuilder()
.build(new CacheLoader<String, LuckPermsGroupSubject>() {
private final LoadingCache<String, SpongeGroup> objects = CacheBuilder.newBuilder()
.build(new CacheLoader<String, SpongeGroup>() {
@Override
public LuckPermsGroupSubject load(String id) throws Exception {
Group group = manager.get(id);
if (group == null) {
throw new IllegalStateException("User not loaded");
}
return LuckPermsGroupSubject.wrapGroup(group, service);
public SpongeGroup load(String i) {
return apply(i);
}
@Override
public ListenableFuture<LuckPermsGroupSubject> reload(String str, LuckPermsGroupSubject s) {
return Futures.immediateFuture(s); // Never needs to be refreshed.
public ListenableFuture<SpongeGroup> reload(String i, SpongeGroup t) {
return Futures.immediateFuture(t); // Never needs to be refreshed.
}
});
public GroupCollection(LuckPermsService service, GroupManager manager) {
this.service = service;
this.manager = manager;
this.fallback = new SimpleCollection(service, "fallback-groups");
public SpongeGroupManager(LPSpongePlugin plugin) {
this.plugin = plugin;
this.fallback = plugin.getService().getFallbackGroupSubjects();
}
@Override
public SpongeGroup apply(String name) {
return new SpongeGroup(name, plugin);
}
/* ------------------------------------------
* Manager methods
* ------------------------------------------ */
@Override
public Map<String, SpongeGroup> getAll() {
return ImmutableMap.copyOf(objects.asMap());
}
@Override
public SpongeGroup getOrMake(String id) {
return objects.getUnchecked(id);
}
@Override
public SpongeGroup getIfLoaded(String id) {
return objects.getIfPresent(id);
}
@Override
public boolean isLoaded(String id) {
return objects.asMap().containsKey(id);
}
@Override
public void unload(Group t) {
if (t != null) {
objects.invalidate(t.getId());
}
}
@Override
public void unloadAll() {
objects.invalidateAll();
}
/* ------------------------------------------
* SubjectCollection methods
* ------------------------------------------ */
@Override
public String getIdentifier() {
return PermissionService.SUBJECTS_GROUP;
@ -86,27 +124,33 @@ public class GroupCollection implements SubjectCollection {
@Override
public Subject get(@NonNull String id) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_COLLECTION_GET)) {
// Special Sponge method. This call will actually load the group from the datastore if not already present.
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_COLLECTION_GET)) {
id = id.toLowerCase();
if (ArgumentChecker.checkName(id)) {
service.getPlugin().getLog().warn("Couldn't get group subject for id: " + id + " (invalid name)");
plugin.getLog().warn("Couldn't get group subject for id: " + id + " (invalid name)");
return fallback.get(id); // fallback to transient collection
}
// check if the user is loaded in memory. hopefully this call is not on the main thread. :(
if (!manager.isLoaded(id)) {
service.getPlugin().getLog().warn("Group Subject '" + id + "' was requested, but is not loaded in memory. Loading it from storage now.");
long startTime = System.currentTimeMillis();
service.getPlugin().getStorage().createAndLoadGroup(id).join();
service.getPlugin().getLog().warn("Loading '" + id + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
}
// check if the group is loaded in memory.
if (isLoaded(id)) {
return getIfLoaded(id).getSpongeData();
} else {
try {
return groups.get(id);
} catch (ExecutionException | UncheckedExecutionException e) {
service.getPlugin().getLog().warn("Unable to get group subject '" + id + "' from memory.");
e.printStackTrace();
return fallback.get(id);
// Group isn't already loaded. hopefully this call is not on the main thread. :(
plugin.getLog().warn("Group Subject '" + id + "' was requested, but is not loaded in memory. Loading it from storage now.");
long startTime = System.currentTimeMillis();
plugin.getStorage().createAndLoadGroup(id).join();
SpongeGroup group = getIfLoaded(id);
if (group == null) {
plugin.getLog().severe("Error whilst loading group '" + id + "'.");
return fallback.get(id);
}
plugin.getLog().warn("Loading '" + id + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
return group.getSpongeData();
}
}
}
@ -114,29 +158,30 @@ public class GroupCollection implements SubjectCollection {
@Override
public boolean hasRegistered(@NonNull String id) {
id = id.toLowerCase();
return !ArgumentChecker.checkName(id) && (groups.asMap().containsKey(id) || manager.isLoaded(id));
return !ArgumentChecker.checkName(id) && isLoaded(id);
}
@Override
public Iterable<Subject> getAllSubjects() {
return groups.asMap().values().stream().collect(ImmutableCollectors.toImmutableList());
return objects.asMap().values().stream().map(SpongeGroup::getSpongeData).collect(ImmutableCollectors.toImmutableList());
}
@Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull String node) {
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, node);
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, id);
}
@Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
ContextSet cs = LuckPermsService.convertContexts(contexts);
return groups.asMap().values().stream()
return objects.asMap().values().stream()
.map(SpongeGroup::getSpongeData)
.filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
}
@Override
public Subject getDefaults() {
return service.getDefaultSubjects().get(getIdentifier());
return plugin.getService().getDefaultSubjects().get(getIdentifier());
}
}

View File

@ -0,0 +1,245 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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.managers;
import co.aikar.timings.Timing;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.NonNull;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.core.UserIdentifier;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.managers.UserManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.model.SpongeUser;
import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.PermissionService;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.permission.SubjectCollection;
import org.spongepowered.api.service.permission.SubjectData;
import org.spongepowered.api.util.Tristate;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
public class SpongeUserManager implements UserManager, SubjectCollection {
private final LPSpongePlugin plugin;
private final SimpleCollection fallback;
private final LoadingCache<UserIdentifier, SpongeUser> objects = CacheBuilder.newBuilder()
.build(new CacheLoader<UserIdentifier, SpongeUser>() {
@Override
public SpongeUser load(UserIdentifier i) {
return apply(i);
}
@Override
public ListenableFuture<SpongeUser> reload(UserIdentifier i, SpongeUser t) {
return Futures.immediateFuture(t); // Never needs to be refreshed.
}
});
public SpongeUserManager(LPSpongePlugin plugin) {
this.plugin = plugin;
this.fallback = plugin.getService().getFallbackUserSubjects();
}
@Override
public SpongeUser apply(UserIdentifier id) {
return id.getUsername() == null ?
new SpongeUser(id.getUuid(), plugin) :
new SpongeUser(id.getUuid(), id.getUsername(), plugin);
}
/* ------------------------------------------
* Manager methods
* ------------------------------------------ */
@Override
public Map<UserIdentifier, SpongeUser> getAll() {
return ImmutableMap.copyOf(objects.asMap());
}
@Override
public SpongeUser getOrMake(UserIdentifier id) {
return objects.getUnchecked(id);
}
@Override
public SpongeUser getIfLoaded(UserIdentifier id) {
return objects.getIfPresent(id);
}
@Override
public boolean isLoaded(UserIdentifier id) {
return objects.asMap().containsKey(id);
}
@Override
public void unload(User t) {
// TODO override
if (t != null) {
objects.invalidate(t.getId());
}
}
@Override
public void unloadAll() {
objects.invalidateAll();
}
/* ------------------------------------------
* UserManager methods
* ------------------------------------------ */
@Override
public SpongeUser getByUsername(String name) {
for (SpongeUser user : getAll().values()) {
if (user.getName().equalsIgnoreCase(name)) {
return user;
}
}
return null;
}
@Override
public SpongeUser get(UUID uuid) {
return getIfLoaded(UserIdentifier.of(uuid, null));
}
@Override
public boolean giveDefaultIfNeeded(User user, boolean save) {
return GenericUserManager.giveDefaultIfNeeded(user, save, plugin);
}
@Override
public void cleanup(User user) {
if (!plugin.isOnline(plugin.getUuidCache().getExternalUUID(user.getUuid()))) {
unload(user);
}
}
@Override
public void updateAllUsers() {
plugin.doSync(() -> {
Set<UUID> players = plugin.getOnlinePlayers();
plugin.doAsync(() -> {
for (UUID uuid : players) {
UUID internal = plugin.getUuidCache().getUUID(uuid);
plugin.getStorage().loadUser(internal, "null").join();
}
});
});
}
/* ------------------------------------------
* SubjectCollection methods
* ------------------------------------------ */
@Override
public String getIdentifier() {
return PermissionService.SUBJECTS_USER;
}
@Override
public Subject get(@NonNull String id) {
// Special Sponge method. This call will actually load the user from the datastore if not already present.
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_COLLECTION_GET)) {
UUID uuid = Util.parseUuid(id);
if (uuid == null) {
plugin.getLog().warn("Couldn't get user subject for id: " + id + " (not a uuid)");
return fallback.get(id); // fallback to the transient collection
}
UUID u = plugin.getUuidCache().getUUID(uuid);
// check if the user is loaded in memory.
if (isLoaded(UserIdentifier.of(u, null))) {
return get(u).getSpongeData();
} else {
// User isn't already loaded. hopefully this call is not on the main thread. :(
plugin.getLog().warn("User Subject '" + u + "' was requested, but is not loaded in memory. Loading them from storage now.");
long startTime = System.currentTimeMillis();
plugin.getStorage().loadUser(u, "null").join();
SpongeUser user = get(u);
if (user == null) {
plugin.getLog().severe("Error whilst loading user '" + u + "'.");
return fallback.get(u.toString());
}
user.setupData(false);
plugin.getLog().warn("Loading '" + u + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
return user.getSpongeData();
}
}
}
@Override
public boolean hasRegistered(@NonNull String id) {
UUID uuid = Util.parseUuid(id);
if (uuid == null) {
return false;
}
UUID internal = plugin.getUuidCache().getUUID(uuid);
return isLoaded(UserIdentifier.of(internal, null));
}
@Override
public Iterable<Subject> getAllSubjects() {
return objects.asMap().values().stream().map(SpongeUser::getSpongeData).collect(ImmutableCollectors.toImmutableList());
}
@Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, id);
}
@Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
ContextSet cs = LuckPermsService.convertContexts(contexts);
return objects.asMap().values().stream()
.map(SpongeUser::getSpongeData)
.filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
}
@Override
public Subject getDefaults() {
return plugin.getService().getDefaultSubjects().get(getIdentifier());
}
}

View File

@ -90,7 +90,7 @@ public class MigrationPermissionManager extends SubCommand<Object> {
// Make a LuckPerms group for the one being migrated
plugin.getStorage().createAndLoadGroup(pmGroup.getIdentifier().toLowerCase()).join();
Group group = plugin.getGroupManager().get(pmGroup.getIdentifier().toLowerCase());
Group group = plugin.getGroupManager().getIfLoaded(pmGroup.getIdentifier().toLowerCase());
migrateSubject(pmGroup, group);
plugin.getStorage().saveGroup(group);
}

View File

@ -84,7 +84,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
// Make a LuckPerms group for the one being migrated
plugin.getStorage().createAndLoadGroup(pexGroup.getIdentifier().toLowerCase()).join();
Group group = plugin.getGroupManager().get(pexGroup.getIdentifier().toLowerCase());
Group group = plugin.getGroupManager().getIfLoaded(pexGroup.getIdentifier().toLowerCase());
migrateSubject(pexGroup, group);
plugin.getStorage().saveGroup(group);
}

View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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 co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList;
import lombok.Getter;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.core.model.Group;
import me.lucko.luckperms.common.utils.ExtractedContexts;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.LuckPermsSubject;
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.permission.NodeTree;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.permission.SubjectCollection;
import org.spongepowered.api.util.Tristate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
public class SpongeGroup extends Group {
@Getter
private final GroupSubject spongeData;
public SpongeGroup(String name, LPSpongePlugin plugin) {
super(name, plugin);
this.spongeData = new GroupSubject(plugin, this);
}
public static class GroupSubject extends LuckPermsSubject {
private final SpongeGroup parent;
private final LPSpongePlugin plugin;
@Getter
private final LuckPermsSubjectData subjectData;
@Getter
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.transientSubjectData = new LuckPermsSubjectData(false, plugin.getService(), parent);
}
@Override
public String getIdentifier() {
return parent.getObjectName();
}
@Override
public Optional<CommandSource> getCommandSource() {
return Optional.empty();
}
@Override
public SubjectCollection getContainingCollection() {
return plugin.getService().getGroupSubjects();
}
@Override
public Tristate getPermissionValue(ContextSet contexts, String permission) {
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PERMISSION_VALUE)) {
Map<String, Boolean> permissions = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
.map(LocalizedNode::getNode)
.collect(Collectors.toMap(Node::getPermission, Node::getValue));
Tristate t = NodeTree.of(permissions).get(permission);
if (t != Tristate.UNDEFINED) {
return t;
}
t = plugin.getService().getGroupSubjects().getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
if (t != Tristate.UNDEFINED) {
return t;
}
t = plugin.getService().getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
return t;
}
}
@Override
public boolean isChildOf(ContextSet contexts, Subject parent) {
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_IS_CHILD_OF)) {
return parent instanceof SpongeGroup && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
}
}
@Override
public List<Subject> getParents(ContextSet contexts) {
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PARENTS)) {
List<Subject> subjects = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
.map(LocalizedNode::getNode)
.filter(Node::isGroupNode)
.map(Node::getGroupName)
.map(s -> plugin.getService().getGroupSubjects().get(s))
.collect(Collectors.toList());
subjects.addAll(plugin.getService().getGroupSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
subjects.addAll(plugin.getService().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
return ImmutableList.copyOf(subjects);
}
}
@Override
public Optional<String> getOption(ContextSet contexts, String s) {
try (Timing ignored = plugin.getService().getPlugin().getTimings().time(LPTiming.GROUP_GET_OPTION)) {
Optional<String> option;
if (s.equalsIgnoreCase("prefix")) {
option = getChatMeta(contexts, true);
} else if (s.equalsIgnoreCase("suffix")) {
option = getChatMeta(contexts, false);
} else {
option = getMeta(contexts, s);
}
if (option.isPresent()) {
return option;
}
option = plugin.getService().getGroupSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (option.isPresent()) {
return option;
}
return plugin.getService().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
}
}
@Override
public ContextSet getActiveContextSet() {
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_ACTIVE_CONTEXTS)) {
return plugin.getContextManager().getApplicableContext(this);
}
}
private Optional<String> getChatMeta(ContextSet contexts, boolean prefix) {
int priority = Integer.MIN_VALUE;
String meta = null;
for (Node n : parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts)))) {
if (!n.getValue()) {
continue;
}
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
continue;
}
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
if (value.getKey() > priority) {
meta = value.getValue();
priority = value.getKey();
}
}
return meta == null ? Optional.empty() : Optional.of(MetaUtils.unescapeCharacters(meta));
}
private Optional<String> getMeta(ContextSet contexts, String key) {
for (Node n : parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts)))) {
if (!n.getValue()) {
continue;
}
if (!n.isMeta()) {
continue;
}
Map.Entry<String, String> m = n.getMeta();
if (!m.getKey().equalsIgnoreCase(key)) {
continue;
}
return Optional.of(MetaUtils.unescapeCharacters(m.getValue()));
}
return Optional.empty();
}
}
}

View File

@ -0,0 +1,188 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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 co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList;
import lombok.Getter;
import me.lucko.luckperms.api.caching.MetaData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.LuckPermsSubject;
import me.lucko.luckperms.sponge.service.LuckPermsSubjectData;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.permission.SubjectCollection;
import org.spongepowered.api.util.Tristate;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class SpongeUser extends User {
@Getter
private final UserSubject spongeData;
public SpongeUser(UUID uuid, LPSpongePlugin plugin) {
super(uuid, plugin);
this.spongeData = new UserSubject(plugin, this);
}
public SpongeUser(UUID uuid, String name, LPSpongePlugin plugin) {
super(uuid, name, plugin);
this.spongeData = new UserSubject(plugin, this);
}
public static class UserSubject extends LuckPermsSubject {
private final SpongeUser parent;
private final LPSpongePlugin plugin;
@Getter
private final LuckPermsSubjectData subjectData;
@Getter
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.transientSubjectData = new LuckPermsSubjectData(false, plugin.getService(), parent);
}
private boolean hasData() {
return parent.getUserData() != null;
}
@Override
public String getIdentifier() {
return plugin.getUuidCache().getExternalUUID(parent.getUuid()).toString();
}
@Override
public Optional<CommandSource> getCommandSource() {
final UUID uuid = plugin.getUuidCache().getExternalUUID(parent.getUuid());
Optional<Player> p = Sponge.getServer().getPlayer(uuid);
if (p.isPresent()) {
return Optional.of(p.get());
}
return Optional.empty();
}
@Override
public SubjectCollection getContainingCollection() {
return plugin.getService().getUserSubjects();
}
@Override
public Tristate getPermissionValue(ContextSet contexts, String permission) {
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_PERMISSION_VALUE)) {
if (!hasData()) {
return Tristate.UNDEFINED;
}
return LuckPermsService.convertTristate(parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getPermissionValue(permission));
}
}
@Override
public boolean isChildOf(ContextSet contexts, Subject parent) {
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_IS_CHILD_OF)) {
return parent instanceof SpongeGroup && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
}
}
@Override
public List<Subject> getParents(ContextSet contexts) {
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_PARENTS)) {
ImmutableList.Builder<Subject> subjects = ImmutableList.builder();
if (hasData()) {
for (String perm : parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getImmutableBacking().keySet()) {
if (!perm.startsWith("group.")) {
continue;
}
String groupName = perm.substring("group.".length());
if (plugin.getGroupManager().isLoaded(groupName)) {
subjects.add(plugin.getService().getGroupSubjects().get(groupName));
}
}
}
subjects.addAll(plugin.getService().getUserSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
subjects.addAll(plugin.getService().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
return subjects.build();
}
}
@Override
public Optional<String> getOption(ContextSet contexts, String s) {
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_OPTION)) {
if (hasData()) {
MetaData data = parent.getUserData().getMetaData(plugin.getService().calculateContexts(contexts));
if (s.equalsIgnoreCase("prefix")) {
if (data.getPrefix() != null) {
return Optional.of(data.getPrefix());
}
}
if (s.equalsIgnoreCase("suffix")) {
if (data.getSuffix() != null) {
return Optional.of(data.getSuffix());
}
}
if (data.getMeta().containsKey(s)) {
return Optional.of(data.getMeta().get(s));
}
}
Optional<String> v = plugin.getService().getUserSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (v.isPresent()) {
return v;
}
return plugin.getService().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
}
}
@Override
public ContextSet getActiveContextSet() {
try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_ACTIVE_CONTEXTS)) {
return plugin.getContextManager().getApplicableContext(this);
}
}
}
}

View File

@ -1,208 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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;
import co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.core.model.Group;
import me.lucko.luckperms.common.utils.ExtractedContexts;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.permission.NodeTree;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.permission.SubjectCollection;
import org.spongepowered.api.util.Tristate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import static me.lucko.luckperms.api.MetaUtils.unescapeCharacters;
@Getter
@EqualsAndHashCode(of = "group", callSuper = false)
public class LuckPermsGroupSubject extends LuckPermsSubject {
public static LuckPermsGroupSubject wrapGroup(Group group, LuckPermsService service) {
return new LuckPermsGroupSubject(group, service);
}
@Getter(value = AccessLevel.NONE)
private LuckPermsService service;
private Group group;
private LuckPermsSubjectData subjectData;
private LuckPermsSubjectData transientSubjectData;
private LuckPermsGroupSubject(Group group, LuckPermsService service) {
this.group = group;
this.subjectData = new LuckPermsSubjectData(true, service, group);
this.transientSubjectData = new LuckPermsSubjectData(false, service, group);
this.service = service;
}
@Override
public String getIdentifier() {
return group.getObjectName();
}
@Override
public Optional<CommandSource> getCommandSource() {
return Optional.empty();
}
@Override
public SubjectCollection getContainingCollection() {
return service.getGroupSubjects();
}
@Override
public Tristate getPermissionValue(ContextSet contexts, String permission) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_PERMISSION_VALUE)) {
Map<String, Boolean> permissions = group.getAllNodesFiltered(ExtractedContexts.generate(service.calculateContexts(contexts))).stream()
.map(LocalizedNode::getNode)
.collect(Collectors.toMap(Node::getPermission, Node::getValue));
Tristate t = NodeTree.of(permissions).get(permission);
if (t != Tristate.UNDEFINED) {
return t;
}
t = service.getGroupSubjects().getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
if (t != Tristate.UNDEFINED) {
return t;
}
t = service.getDefaults().getPermissionValue(LuckPermsService.convertContexts(contexts), permission);
return t;
}
}
@Override
public boolean isChildOf(ContextSet contexts, Subject parent) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_IS_CHILD_OF)) {
return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
}
}
@Override
public List<Subject> getParents(ContextSet contexts) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_PARENTS)) {
List<Subject> subjects = group.getAllNodesFiltered(ExtractedContexts.generate(service.calculateContexts(contexts))).stream()
.map(LocalizedNode::getNode)
.filter(Node::isGroupNode)
.map(Node::getGroupName)
.map(s -> service.getGroupSubjects().get(s))
.collect(Collectors.toList());
subjects.addAll(service.getGroupSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
subjects.addAll(service.getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
return ImmutableList.copyOf(subjects);
}
}
@Override
public Optional<String> getOption(ContextSet contexts, String s) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_OPTION)) {
Optional<String> option;
if (s.equalsIgnoreCase("prefix")) {
option = getChatMeta(contexts, true);
} else if (s.equalsIgnoreCase("suffix")) {
option = getChatMeta(contexts, false);
} else {
option = getMeta(contexts, s);
}
if (option.isPresent()) {
return option;
}
option = service.getGroupSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (option.isPresent()) {
return option;
}
return service.getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
}
}
@Override
public ContextSet getActiveContextSet() {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_GET_ACTIVE_CONTEXTS)) {
return service.getPlugin().getContextManager().getApplicableContext(this);
}
}
private Optional<String> getChatMeta(ContextSet contexts, boolean prefix) {
int priority = Integer.MIN_VALUE;
String meta = null;
for (Node n : group.getAllNodesFiltered(ExtractedContexts.generate(service.calculateContexts(contexts)))) {
if (!n.getValue()) {
continue;
}
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
continue;
}
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
if (value.getKey() > priority) {
meta = value.getValue();
priority = value.getKey();
}
}
return meta == null ? Optional.empty() : Optional.of(unescapeCharacters(meta));
}
private Optional<String> getMeta(ContextSet contexts, String key) {
for (Node n : group.getAllNodesFiltered(ExtractedContexts.generate(service.calculateContexts(contexts)))) {
if (!n.getValue()) {
continue;
}
if (!n.isMeta()) {
continue;
}
Map.Entry<String, String> m = n.getMeta();
if (!m.getKey().equalsIgnoreCase(key)) {
continue;
}
return Optional.of(m.getValue());
}
return Optional.empty();
}
}

View File

@ -29,13 +29,15 @@ import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.*;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.contexts.SpongeCalculatorLink;
import me.lucko.luckperms.sponge.service.collections.GroupCollection;
import me.lucko.luckperms.sponge.service.collections.UserCollection;
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
import me.lucko.luckperms.sponge.service.persisted.PersistedCollection;
import me.lucko.luckperms.sponge.service.persisted.SubjectStorage;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
@ -61,8 +63,10 @@ public class LuckPermsService implements PermissionService {
private final LPSpongePlugin plugin;
private final SubjectStorage storage;
private final UserCollection userSubjects;
private final GroupCollection groupSubjects;
private final SpongeUserManager userSubjects;
private final SimpleCollection fallbackUserSubjects;
private final SpongeGroupManager groupSubjects;
private final SimpleCollection fallbackGroupSubjects;
private final PersistedCollection defaultSubjects;
private final Set<PermissionDescription> descriptionSet;
@ -73,6 +77,11 @@ public class LuckPermsService implements PermissionService {
public SubjectCollection load(String s) {
return new SimpleCollection(LuckPermsService.this, s);
}
@Override
public ListenableFuture<SubjectCollection> reload(String s, SubjectCollection collection) {
return Futures.immediateFuture(collection); // Never needs to be refreshed.
}
});
public LuckPermsService(LPSpongePlugin plugin) {
@ -80,13 +89,17 @@ public class LuckPermsService implements PermissionService {
storage = new SubjectStorage(new File(plugin.getDataFolder(), "local"));
userSubjects = new UserCollection(this, plugin.getUserManager());
groupSubjects = new GroupCollection(this, plugin.getGroupManager());
userSubjects = plugin.getUserManager();
fallbackUserSubjects = new SimpleCollection(this, "fallback-users");
groupSubjects = plugin.getGroupManager();
fallbackGroupSubjects = new SimpleCollection(this, "fallback-groups");
defaultSubjects = new PersistedCollection(this, "defaults");
defaultSubjects.loadAll();
collections.put(PermissionService.SUBJECTS_USER, userSubjects);
collections.put("fallback-users", fallbackUserSubjects);
collections.put(PermissionService.SUBJECTS_GROUP, groupSubjects);
collections.put("fallback-groups", fallbackGroupSubjects);
collections.put("defaults", defaultSubjects);
descriptionSet = ConcurrentHashMap.newKeySet();

View File

@ -38,6 +38,7 @@ import me.lucko.luckperms.common.core.model.PermissionHolder;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.sponge.model.SpongeGroup;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.Subject;
@ -252,17 +253,17 @@ public class LuckPermsSubjectData implements SubjectData {
@Override
public boolean addParent(@NonNull Set<Context> set, @NonNull Subject subject) {
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_ADD_PARENT)) {
if (subject instanceof LuckPermsGroupSubject) {
LuckPermsGroupSubject permsSubject = ((LuckPermsGroupSubject) subject);
if (subject instanceof SpongeGroup) {
SpongeGroup permsSubject = ((SpongeGroup) subject);
ContextSet contexts = LuckPermsService.convertContexts(set);
try {
if (enduring) {
holder.setPermission(new NodeBuilder("group." + permsSubject.getIdentifier())
holder.setPermission(new NodeBuilder("group." + permsSubject.getName())
.withExtraContext(contexts)
.build());
} else {
holder.setTransientPermission(new NodeBuilder("group." + permsSubject.getIdentifier())
holder.setTransientPermission(new NodeBuilder("group." + permsSubject.getName())
.withExtraContext(contexts)
.build());
}
@ -278,17 +279,17 @@ public class LuckPermsSubjectData implements SubjectData {
@Override
public boolean removeParent(@NonNull Set<Context> set, @NonNull Subject subject) {
try (Timing i = service.getPlugin().getTimings().time(LPTiming.LP_SUBJECT_REMOVE_PARENT)) {
if (subject instanceof LuckPermsGroupSubject) {
LuckPermsGroupSubject permsSubject = ((LuckPermsGroupSubject) subject);
if (subject instanceof SpongeGroup) {
SpongeGroup permsSubject = ((SpongeGroup) subject);
ContextSet contexts = LuckPermsService.convertContexts(set);
try {
if (enduring) {
holder.unsetPermission(new NodeBuilder("group." + permsSubject.getIdentifier())
holder.unsetPermission(new NodeBuilder("group." + permsSubject.getName())
.withExtraContext(contexts)
.build());
} else {
holder.unsetTransientPermission(new NodeBuilder("group." + permsSubject.getIdentifier())
holder.unsetTransientPermission(new NodeBuilder("group." + permsSubject.getName())
.withExtraContext(contexts)
.build());
}

View File

@ -1,172 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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;
import co.aikar.timings.Timing;
import com.google.common.collect.ImmutableList;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import me.lucko.luckperms.api.caching.MetaData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.permission.SubjectCollection;
import org.spongepowered.api.util.Tristate;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Getter
@EqualsAndHashCode(of = "user", callSuper = false)
public class LuckPermsUserSubject extends LuckPermsSubject {
public static LuckPermsUserSubject wrapUser(User user, LuckPermsService service) {
return new LuckPermsUserSubject(user, service);
}
@Getter(value = AccessLevel.NONE)
private LuckPermsService service;
private User user;
private LuckPermsSubjectData subjectData;
private LuckPermsSubjectData transientSubjectData;
private LuckPermsUserSubject(User user, LuckPermsService service) {
this.user = user;
this.service = service;
this.subjectData = new LuckPermsSubjectData(true, service, user);
this.transientSubjectData = new LuckPermsSubjectData(false, service, user);
}
private boolean hasData() {
return user.getUserData() != null;
}
@Override
public String getIdentifier() {
return service.getPlugin().getUuidCache().getExternalUUID(user.getUuid()).toString();
}
@Override
public Optional<CommandSource> getCommandSource() {
final UUID uuid = service.getPlugin().getUuidCache().getExternalUUID(user.getUuid());
Optional<Player> p = Sponge.getServer().getPlayer(uuid);
if (p.isPresent()) {
return Optional.of(p.get());
}
return Optional.empty();
}
@Override
public SubjectCollection getContainingCollection() {
return service.getUserSubjects();
}
@Override
public Tristate getPermissionValue(ContextSet contexts, String permission) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_PERMISSION_VALUE)) {
return !hasData() ?
Tristate.UNDEFINED :
LuckPermsService.convertTristate(
user.getUserData().getPermissionData(service.calculateContexts(contexts)).getPermissionValue(permission)
);
}
}
@Override
public boolean isChildOf(ContextSet contexts, Subject parent) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_IS_CHILD_OF)) {
return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
}
}
@Override
public List<Subject> getParents(ContextSet contexts) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_PARENTS)) {
ImmutableList.Builder<Subject> subjects = ImmutableList.builder();
if (hasData()) {
for (String perm : user.getUserData().getPermissionData(service.calculateContexts(contexts)).getImmutableBacking().keySet()) {
if (!perm.startsWith("group.")) {
continue;
}
String groupName = perm.substring("group.".length());
if (service.getPlugin().getGroupManager().isLoaded(groupName)) {
subjects.add(service.getGroupSubjects().get(groupName));
}
}
}
subjects.addAll(service.getUserSubjects().getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
subjects.addAll(service.getDefaults().getParents(LuckPermsService.convertContexts(contexts)));
return subjects.build();
}
}
@Override
public Optional<String> getOption(ContextSet contexts, String s) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_OPTION)) {
if (hasData()) {
MetaData data = user.getUserData().getMetaData(service.calculateContexts(contexts));
if (s.equalsIgnoreCase("prefix")) {
if (data.getPrefix() != null) {
return Optional.of(data.getPrefix());
}
}
if (s.equalsIgnoreCase("suffix")) {
if (data.getSuffix() != null) {
return Optional.of(data.getSuffix());
}
}
if (data.getMeta().containsKey(s)) {
return Optional.of(data.getMeta().get(s));
}
}
Optional<String> v = service.getUserSubjects().getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
if (v.isPresent()) {
return v;
}
return service.getDefaults().getOption(LuckPermsService.convertContexts(contexts), s);
}
}
@Override
public ContextSet getActiveContextSet() {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_GET_ACTIVE_CONTEXTS)) {
return service.getPlugin().getContextManager().getApplicableContext(this);
}
}
}

View File

@ -1,163 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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.collections;
import co.aikar.timings.Timing;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import lombok.NonNull;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.core.UserIdentifier;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.managers.UserManager;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.LuckPermsUserSubject;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
import me.lucko.luckperms.sponge.timings.LPTiming;
import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.PermissionService;
import org.spongepowered.api.service.permission.Subject;
import org.spongepowered.api.service.permission.SubjectCollection;
import org.spongepowered.api.service.permission.SubjectData;
import org.spongepowered.api.util.Tristate;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
/**
* Manages low level Subject instances for the PermissionService.
* Most calls are cached.
*/
public class UserCollection implements SubjectCollection {
private final LuckPermsService service;
private final UserManager manager;
private final SimpleCollection fallback;
private final LoadingCache<UUID, LuckPermsUserSubject> users = CacheBuilder.newBuilder()
.build(new CacheLoader<UUID, LuckPermsUserSubject>() {
@Override
public LuckPermsUserSubject load(UUID uuid) throws Exception {
User user = manager.get(uuid);
if (user == null) {
throw new IllegalStateException("User not loaded");
}
return LuckPermsUserSubject.wrapUser(user, service);
}
@Override
public ListenableFuture<LuckPermsUserSubject> reload(UUID uuid, LuckPermsUserSubject s) {
return Futures.immediateFuture(s); // Never needs to be refreshed.
}
});
public UserCollection(LuckPermsService service, UserManager manager) {
this.service = service;
this.manager = manager;
this.fallback = new SimpleCollection(service, "fallback-users");
}
@Override
public String getIdentifier() {
return PermissionService.SUBJECTS_USER;
}
public void unload(UUID uuid) {
users.invalidate(uuid);
}
@Override
public Subject get(@NonNull String id) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_COLLECTION_GET)) {
UUID uuid = Util.parseUuid(id);
if (uuid == null) {
service.getPlugin().getLog().warn("Couldn't get user subject for id: " + id + " (not a uuid)");
return fallback.get(id); // fallback to the transient collection
}
UUID u = service.getPlugin().getUuidCache().getUUID(uuid);
// check if the user is loaded in memory. hopefully this call is not on the main thread. :(
if (!manager.isLoaded(UserIdentifier.of(u, null))) {
service.getPlugin().getLog().warn("User Subject '" + u + "' was requested, but is not loaded in memory. Loading them from storage now.");
long startTime = System.currentTimeMillis();
service.getPlugin().getStorage().loadUser(u, "null").join();
User user = service.getPlugin().getUserManager().get(u);
if (user != null) {
user.setupData(false);
}
service.getPlugin().getLog().warn("Loading '" + u + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
}
try {
return users.get(u);
} catch (ExecutionException | UncheckedExecutionException e) {
service.getPlugin().getLog().warn("Unable to get user subject '" + u + "' from memory.");
e.printStackTrace();
return fallback.get(u.toString());
}
}
}
@Override
public boolean hasRegistered(@NonNull String id) {
UUID uuid = Util.parseUuid(id);
if (uuid == null) {
return false;
}
UUID internal = service.getPlugin().getUuidCache().getUUID(uuid);
return users.asMap().containsKey(internal) || manager.isLoaded(UserIdentifier.of(internal, null));
}
@Override
public Iterable<Subject> getAllSubjects() {
return users.asMap().values().stream().collect(ImmutableCollectors.toImmutableList());
}
@Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, id);
}
@Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
ContextSet cs = LuckPermsService.convertContexts(contexts);
return users.asMap().values().stream()
.filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
}
@Override
public Subject getDefaults() {
return service.getDefaultSubjects().get(getIdentifier());
}
}