Fix Sponge subjects from being unloaded and never reinitialized - closes #124

This commit is contained in:
Luck 2017-01-10 19:17:45 +00:00
parent ab0f9bbdbd
commit dd50193c18
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
6 changed files with 82 additions and 56 deletions

View File

@ -41,6 +41,15 @@ import java.util.Map;
*/
public abstract class AbstractManager<I, T extends Identifiable<I>> implements Manager<I, T> {
@SuppressWarnings("unchecked")
private static <I> I lowerCase(I i) {
if (i instanceof String) {
return (I) ((String) i).toLowerCase();
} else {
return i;
}
}
private final LoadingCache<I, T> objects = CacheBuilder.newBuilder()
.build(new CacheLoader<I, T>() {
@Override
@ -61,36 +70,30 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> 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());
}
}

View File

@ -66,6 +66,13 @@ public interface Manager<I, T extends Identifiable<I>> extends Function<I, T> {
*/
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
*

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -125,6 +125,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
Set<UserIdentifier> set = new HashSet<>();
for (Map.Entry<UserIdentifier, SpongeUser> 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

View File

@ -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<SubjectReference> 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<String> 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<String> v = plugin.getService().getUserSubjects().getDefaultSubject().resolve(getService()).getOption(contexts, s);
if (v.isPresent()) {
return v;