diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java b/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java index 97d4f0b23..9f4673151 100644 --- a/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/managers/AbstractManager.java @@ -41,6 +41,15 @@ import java.util.Map; */ public abstract class AbstractManager> implements Manager { + @SuppressWarnings("unchecked") + private static I lowerCase(I i) { + if (i instanceof String) { + return (I) ((String) i).toLowerCase(); + } else { + return i; + } + } + private final LoadingCache objects = CacheBuilder.newBuilder() .build(new CacheLoader() { @Override @@ -61,36 +70,30 @@ public abstract class AbstractManager> implements M @Override public T getOrMake(I id) { - if (id instanceof String) { - return objects.getUnchecked((I) ((String) id).toLowerCase()); - } else { - return objects.getUnchecked(id); - } - + return objects.getUnchecked(lowerCase(id)); } @Override public T getIfLoaded(I id) { - if (id instanceof String) { - return objects.getIfPresent(((String) id).toLowerCase()); - } else { - return objects.getIfPresent(id); - } + return objects.getIfPresent(lowerCase(id)); } @Override public boolean isLoaded(I id) { - if (id instanceof String) { - return objects.asMap().containsKey(((String) id).toLowerCase()); - } else { - return objects.asMap().containsKey(id); + return objects.asMap().containsKey(lowerCase(id)); + } + + @Override + public void unload(I id) { + if (id != null) { + objects.invalidate(lowerCase(id)); } } @Override public void unload(T t) { if (t != null) { - objects.invalidate(t.getId()); + unload(t.getId()); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java b/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java index d1d5d8b6e..723eeb653 100644 --- a/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java +++ b/common/src/main/java/me/lucko/luckperms/common/managers/Manager.java @@ -66,6 +66,13 @@ public interface Manager> extends Function { */ boolean isLoaded(I id); + /** + * Removes and unloads the object from the manager + * + * @param id The object id to unload + */ + void unload(I id); + /** * Removes and unloads the object from the manager * diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeListener.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeListener.java index 5a1574039..ea043bc00 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeListener.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeListener.java @@ -25,6 +25,7 @@ package me.lucko.luckperms.sponge; import me.lucko.luckperms.api.caching.UserData; import me.lucko.luckperms.api.context.MutableContextSet; import me.lucko.luckperms.common.constants.Message; +import me.lucko.luckperms.common.core.UuidCache; import me.lucko.luckperms.common.core.model.User; import me.lucko.luckperms.common.utils.AbstractListener; import me.lucko.luckperms.sponge.timings.LPTiming; @@ -113,7 +114,15 @@ public class SpongeListener extends AbstractListener { @Listener(order = Order.LAST) public void onClientLeave(ClientConnectionEvent.Disconnect e) { try (Timing ignored = plugin.getTimings().time(LPTiming.ON_CLIENT_LEAVE)) { - onLeave(e.getTargetEntity().getUniqueId()); + final UuidCache cache = plugin.getUuidCache(); + + final User user = plugin.getUserManager().get(cache.getUUID(e.getTargetEntity().getUniqueId())); + if (user != null) { + user.unregisterData(); + } + + // Unload the user from memory when they disconnect; + cache.clearCache(e.getTargetEntity().getUniqueId()); } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeGroupManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeGroupManager.java index 70051b8e8..7e8704f47 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeGroupManager.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeGroupManager.java @@ -113,23 +113,30 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection { @Override public SpongeGroup getOrMake(String id) { - return objects.getUnchecked(id); + return objects.getUnchecked(id.toLowerCase()); } @Override public SpongeGroup getIfLoaded(String id) { - return objects.getIfPresent(id); + return objects.getIfPresent(id.toLowerCase()); } @Override public boolean isLoaded(String id) { - return objects.asMap().containsKey(id); + return objects.asMap().containsKey(id.toLowerCase()); + } + + @Override + public void unload(String id) { + if (id != null) { + objects.invalidate(id.toLowerCase()); + } } @Override public void unload(Group t) { if (t != null) { - objects.invalidate(t.getId()); + unload(t.getId()); } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeUserManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeUserManager.java index 1163d19c9..3d91c69f2 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeUserManager.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/managers/SpongeUserManager.java @@ -125,6 +125,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection { Set set = new HashSet<>(); for (Map.Entry user : objects.asMap().entrySet()) { if (user.getValue().getSpongeData().shouldCleanup()) { + user.getValue().unregisterData(); set.add(user.getKey()); } } @@ -156,10 +157,17 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection { return objects.asMap().containsKey(id); } + @Override + public void unload(UserIdentifier id) { + if (id != null) { + objects.invalidate(id); + } + } + @Override public void unload(User t) { if (t != null) { - objects.invalidate(t.getId()); + unload(t.getId()); } } @@ -194,9 +202,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection { @Override public void cleanup(User user) { - if (!plugin.isOnline(plugin.getUuidCache().getExternalUUID(user.getUuid()))) { - unload(user); - } + // Do nothing - this instance uses other means in order to cleanup } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java b/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java index 152db0c4c..51cfd6195 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java @@ -93,12 +93,10 @@ public class SpongeUser extends User { return (now - lastUse) > 600000; } - private boolean hasData() { - if (parent.getUserData() != null) { - return true; - } else { + private void checkData() { + if (parent.getUserData() == null) { plugin.getLog().warn("User " + parent.getName() + " - " + parent.getUuid() + " does not have any data loaded."); - return false; + parent.setupData(false); } } @@ -133,10 +131,7 @@ public class SpongeUser extends User { public Tristate getPermissionValue(ContextSet contexts, String permission) { logUsage(); try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_PERMISSION_VALUE)) { - if (!hasData()) { - return Tristate.UNDEFINED; - } - + checkData(); return parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getPermissionValue(permission); } } @@ -155,16 +150,15 @@ public class SpongeUser extends User { try (Timing ignored = plugin.getTimings().time(LPTiming.USER_GET_PARENTS)) { ImmutableSet.Builder subjects = ImmutableSet.builder(); - if (hasData()) { - for (String perm : parent.getUserData().getPermissionData(plugin.getService().calculateContexts(contexts)).getImmutableBacking().keySet()) { - if (!perm.startsWith("group.")) { - continue; - } + checkData(); + 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).toReference()); - } + String groupName = perm.substring("group.".length()); + if (plugin.getGroupManager().isLoaded(groupName)) { + subjects.add(plugin.getService().getGroupSubjects().get(groupName).toReference()); } } @@ -179,25 +173,25 @@ public class SpongeUser extends User { public Optional getOption(ContextSet contexts, String s) { logUsage(); 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()); - } - } + checkData(); - if (s.equalsIgnoreCase("suffix")) { - if (data.getSuffix() != null) { - return Optional.of(data.getSuffix()); - } + MetaData data = parent.getUserData().getMetaData(plugin.getService().calculateContexts(contexts)); + if (s.equalsIgnoreCase("prefix")) { + if (data.getPrefix() != null) { + return Optional.of(data.getPrefix()); } + } - if (data.getMeta().containsKey(s)) { - return Optional.of(data.getMeta().get(s)); + 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 v = plugin.getService().getUserSubjects().getDefaultSubject().resolve(getService()).getOption(contexts, s); if (v.isPresent()) { return v;