Remove context pre-processing (mostly)

This approach isn't very effective when contexts are frequently changing, and it is hard to guess in advance which contexts are going to be in-use.

The Sponge version has proven that this whole system isn't really necessary.

Contexts for 'allow all' and 'global' are still pre-processed, however this should be significantly less work for the server. (even if it is being done async)
This commit is contained in:
Luck 2017-10-12 20:17:52 +01:00
parent 9c505e4402
commit 8920396360
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
15 changed files with 53 additions and 227 deletions

View File

@ -174,11 +174,6 @@ public class BukkitListener implements Listener {
} }
plugin.refreshAutoOp(player); plugin.refreshAutoOp(player);
// We assume all users are not op, but those who are need extra calculation.
if (player.isOp()) {
plugin.doAsync(() -> user.getUserData().preCalculate(plugin.getPreProcessContexts(true)));
}
} }
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)

View File

@ -31,8 +31,6 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger; import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.PlatformType; import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.bukkit.calculators.BukkitCalculatorFactory; import me.lucko.luckperms.bukkit.calculators.BukkitCalculatorFactory;
import me.lucko.luckperms.bukkit.contexts.BukkitContextManager; import me.lucko.luckperms.bukkit.contexts.BukkitContextManager;
import me.lucko.luckperms.bukkit.contexts.WorldCalculator; import me.lucko.luckperms.bukkit.contexts.WorldCalculator;
@ -82,7 +80,6 @@ import me.lucko.luckperms.common.utils.LoginHelper;
import me.lucko.luckperms.common.utils.UuidCache; import me.lucko.luckperms.common.utils.UuidCache;
import me.lucko.luckperms.common.verbose.VerboseHandler; import me.lucko.luckperms.common.verbose.VerboseHandler;
import org.bukkit.World;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
@ -346,7 +343,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
final User user = getUserManager().getIfLoaded(getUuidCache().getUUID(player.getUniqueId())); final User user = getUserManager().getIfLoaded(getUuidCache().getUUID(player.getUniqueId()));
if (user != null) { if (user != null) {
user.unregisterData(); user.getUserData().invalidateCaches();
getUserManager().unload(user); getUserManager().unload(user);
} }
} }
@ -376,31 +373,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// Bukkit will do this again when #onDisable completes, but we do it early to prevent NPEs elsewhere. // Bukkit will do this again when #onDisable completes, but we do it early to prevent NPEs elsewhere.
getServer().getScheduler().cancelTasks(this); getServer().getScheduler().cancelTasks(this);
HandlerList.unregisterAll(this); HandlerList.unregisterAll(this);
getLog().info("Goodbye!");
// Null everything
vaultHookManager = null;
configuration = null;
userManager = null;
groupManager = null;
trackManager = null;
storage = null;
fileWatcher = null;
messagingService = null;
uuidCache = null;
listener = null;
apiProvider = null;
log = null;
defaultsProvider = null;
childPermissionProvider = null;
localeManager = null;
cachedStateManager = null;
contextManager = null;
calculatorFactory = null;
updateTaskBuffer = null;
verboseHandler = null;
senderFactory = null;
permissionVault = null;
logDispatcher = null;
} }
public void tryVaultHook(boolean force) { public void tryVaultHook(boolean force) {
@ -538,75 +511,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
} }
@Override @Override
public Set<Contexts> getPreProcessContexts(boolean op) { public Map<String, Object> getExtraInfo() {
Set<ContextSet> c = new HashSet<>(); Map<String, Object> map = new LinkedHashMap<>();
c.add(ContextSet.empty());
c.add(ContextSet.singleton("server", getConfiguration().get(ConfigKeys.SERVER)));
// Pre process all worlds
c.addAll(getServer().getWorlds().stream()
.map(World::getName)
.map(s -> {
MutableContextSet set = MutableContextSet.create();
set.add("server", getConfiguration().get(ConfigKeys.SERVER));
set.add("world", s);
set.addAll(configuration.getContextsFile().getStaticContexts());
return set.makeImmutable();
})
.collect(Collectors.toList())
);
// Pre process the separate Vault server, if any
if (!getConfiguration().get(ConfigKeys.SERVER).equals(getConfiguration().get(ConfigKeys.VAULT_SERVER))) {
c.add(ContextSet.singleton("server", getConfiguration().get(ConfigKeys.VAULT_SERVER)));
c.addAll(getServer().getWorlds().stream()
.map(World::getName)
.map(s -> {
MutableContextSet set = MutableContextSet.create();
set.add("server", getConfiguration().get(ConfigKeys.VAULT_SERVER));
set.add("world", s);
set.addAll(configuration.getContextsFile().getStaticContexts());
return set.makeImmutable();
})
.collect(Collectors.toList())
);
}
Set<Contexts> contexts = new HashSet<>();
// Convert to full Contexts
contexts.addAll(c.stream()
.map(set -> new Contexts(
set,
getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_PERMS),
getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_WORLD_PERMS),
true,
getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_GROUPS),
getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS),
op
))
.collect(Collectors.toSet())
);
// Check for and include varying Vault config options
boolean vaultDiff = getConfiguration().get(ConfigKeys.VAULT_INCLUDING_GLOBAL) != getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_PERMS) ||
!getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_WORLD_PERMS) ||
!getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_GROUPS) ||
!getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS);
if (vaultDiff) {
contexts.addAll(c.stream()
.map(map -> new Contexts(map, getConfiguration().get(ConfigKeys.VAULT_INCLUDING_GLOBAL), true, true, true, true, op))
.collect(Collectors.toSet())
);
}
return contexts;
}
@Override
public LinkedHashMap<String, Object> getExtraInfo() {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("Vault Enabled", vaultHookManager != null); map.put("Vault Enabled", vaultHookManager != null);
map.put("Bukkit Defaults count", defaultsProvider.size()); map.put("Bukkit Defaults count", defaultsProvider.size());
map.put("Bukkit Child Permissions count", childPermissionProvider.getPermissions().size()); map.put("Bukkit Child Permissions count", childPermissionProvider.getPermissions().size());

View File

@ -29,7 +29,6 @@ import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.bungee.event.TristateCheckEvent; import me.lucko.luckperms.bungee.event.TristateCheckEvent;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.locale.Message;
@ -44,12 +43,10 @@ import net.md_5.bungee.api.event.LoginEvent;
import net.md_5.bungee.api.event.PermissionCheckEvent; import net.md_5.bungee.api.event.PermissionCheckEvent;
import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.PostLoginEvent; import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority; import net.md_5.bungee.event.EventPriority;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor @RequiredArgsConstructor
@ -192,24 +189,4 @@ public class BungeeListener implements Listener {
e.setResult(result); e.setResult(result);
} }
// We don't pre-process all servers, so we have to do it here.
@EventHandler(priority = EventPriority.LOWEST)
public void onServerSwitch(ServerConnectEvent e) {
String serverName = e.getTarget().getName();
UUID uuid = e.getPlayer().getUniqueId();
plugin.doAsync(() -> {
MutableContextSet set = MutableContextSet.create();
set.add("server", plugin.getConfiguration().get(ConfigKeys.SERVER));
set.add("world", serverName);
User user = plugin.getUserManager().getIfLoaded(plugin.getUuidCache().getUUID(uuid));
if (user == null) {
return;
}
Contexts contexts = plugin.getContextManager().formContexts(e.getPlayer(), set.makeImmutable());
user.getUserData().preCalculate(contexts);
});
}
} }

View File

@ -30,8 +30,6 @@ import lombok.Getter;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger; import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.PlatformType; import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.bungee.calculators.BungeeCalculatorFactory; import me.lucko.luckperms.bungee.calculators.BungeeCalculatorFactory;
import me.lucko.luckperms.bungee.contexts.BackendServerCalculator; import me.lucko.luckperms.bungee.contexts.BackendServerCalculator;
import me.lucko.luckperms.bungee.contexts.BungeeContextManager; import me.lucko.luckperms.bungee.contexts.BungeeContextManager;
@ -83,7 +81,6 @@ import net.md_5.bungee.api.plugin.Plugin;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -215,6 +212,9 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
permissionVault.setShutdown(true);
verboseHandler.setShutdown(true);
getLog().info("Closing storage..."); getLog().info("Closing storage...");
storage.shutdown(); storage.shutdown();
@ -231,8 +231,10 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
getLog().info("Shutting down internal scheduler..."); getLog().info("Shutting down internal scheduler...");
scheduler.shutdown(); scheduler.shutdown();
getProxy().getScheduler().cancel(this); getProxy().getScheduler().cancel(this);
getProxy().getPluginManager().unregisterListeners(this); getProxy().getPluginManager().unregisterListeners(this);
getLog().info("Goodbye!");
} }
@Override @Override
@ -324,14 +326,4 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
public Sender getConsoleSender() { public Sender getConsoleSender() {
return getSenderFactory().wrap(getProxy().getConsole()); return getSenderFactory().wrap(getProxy().getConsole());
} }
@Override
public Set<Contexts> getPreProcessContexts(boolean op) {
Set<ImmutableContextSet> c = new HashSet<>();
c.add(ContextSet.empty());
c.add(ContextSet.singleton("server", getConfiguration().get(ConfigKeys.SERVER)));
return c.stream()
.map(set -> contextManager.formContexts(null, set))
.collect(Collectors.toSet());
}
} }

View File

@ -108,7 +108,7 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
@Override @Override
public void setupDataCache() { public void setupDataCache() {
handle.preCalculateData(false); handle.preCalculateData();
} }
@Override @Override

View File

@ -31,12 +31,10 @@ import lombok.RequiredArgsConstructor;
import com.github.benmanes.caffeine.cache.CacheLoader; import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.api.ChatMetaType; import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.MetaContexts; import me.lucko.luckperms.api.caching.MetaContexts;
import me.lucko.luckperms.api.caching.PermissionData;
import me.lucko.luckperms.api.caching.UserData; import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.contexts.ExtractedContexts; import me.lucko.luckperms.common.contexts.ExtractedContexts;
@ -59,20 +57,22 @@ public class UserCache implements UserData {
private final User user; private final User user;
private final LoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder() private final LoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(2, TimeUnit.MINUTES)
.build(new PermissionCacheLoader()); .build(new PermissionCacheLoader());
private final LoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder() private final LoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(2, TimeUnit.MINUTES)
.build(new MetaCacheLoader()); .build(new MetaCacheLoader());
@Override @Override
public PermissionCache getPermissionData(@NonNull Contexts contexts) { public PermissionCache getPermissionData(@NonNull Contexts contexts) {
//noinspection ConstantConditions
return permission.get(contexts); return permission.get(contexts);
} }
@Override @Override
public MetaCache getMetaData(@NonNull MetaContexts contexts) { public MetaCache getMetaData(@NonNull MetaContexts contexts) {
//noinspection ConstantConditions
return meta.get(contexts); return meta.get(contexts);
} }
@ -131,14 +131,14 @@ public class UserCache implements UserData {
@Override @Override
public void recalculatePermissions() { public void recalculatePermissions() {
Set<Contexts> keys = ImmutableSet.copyOf(permission.asMap().keySet()); Set<Contexts> keys = permission.asMap().keySet();
keys.forEach(permission::refresh); keys.forEach(this::recalculatePermissions);
} }
@Override @Override
public void recalculateMeta() { public void recalculateMeta() {
Set<MetaContexts> keys = ImmutableSet.copyOf(meta.asMap().keySet()); Set<MetaContexts> keys = meta.asMap().keySet();
keys.forEach(meta::refresh); keys.forEach(this::recalculateMeta);
} }
@Override @Override
@ -148,30 +148,27 @@ public class UserCache implements UserData {
@Override @Override
public void preCalculate(@NonNull Contexts contexts) { public void preCalculate(@NonNull Contexts contexts) {
permission.get(contexts); // pre-calculate just by requesting the data from this cache.
meta.get(makeFromMetaContextsConfig(contexts, user.getPlugin())); // if the data isn't already loaded, it will be calculated.
getPermissionData(contexts);
getMetaData(contexts);
} }
public void invalidateCache() { public void invalidateCaches() {
permission.invalidateAll(); permission.invalidateAll();
meta.invalidateAll(); meta.invalidateAll();
} }
@Override @Override
public void invalidatePermissionCalculators() { public void invalidatePermissionCalculators() {
permission.asMap().values().forEach(PermissionData::invalidateCache); permission.asMap().values().forEach(PermissionCache::invalidateCache);
} }
public void cleanup() { public void doCacheCleanup() {
permission.cleanUp(); permission.cleanUp();
meta.cleanUp(); meta.cleanUp();
} }
public void clear() {
permission.invalidateAll();
meta.invalidateAll();
}
private final class PermissionCacheLoader implements CacheLoader<Contexts, PermissionCache> { private final class PermissionCacheLoader implements CacheLoader<Contexts, PermissionCache> {
@Override @Override
public PermissionCache load(Contexts contexts) { public PermissionCache load(Contexts contexts) {

View File

@ -99,7 +99,7 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
plugin.getScheduler().asyncLater(() -> { plugin.getScheduler().asyncLater(() -> {
User user = getIfLoaded(plugin.getUuidCache().getUUID(uuid)); User user = getIfLoaded(plugin.getUuidCache().getUUID(uuid));
if (user != null && !plugin.isPlayerOnline(uuid)) { if (user != null && !plugin.isPlayerOnline(uuid)) {
user.unregisterData(); user.getUserData().invalidateCaches();
unload(user); unload(user);
plugin.getUuidCache().clearCache(uuid); plugin.getUuidCache().clearCache(uuid);
} }

View File

@ -29,6 +29,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.api.delegates.UserDelegate; import me.lucko.luckperms.common.api.delegates.UserDelegate;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.caching.UserCache; import me.lucko.luckperms.common.caching.UserCache;
@ -161,16 +162,14 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
* Sets up the UserData cache * Sets up the UserData cache
* Blocking call. * Blocking call.
*/ */
public synchronized void preCalculateData(boolean op) { public synchronized void preCalculateData() {
userData.preCalculate(getPlugin().getPreProcessContexts(op)); // first try to refresh any existing permissions
getPlugin().onUserRefresh(this); refreshPermissions();
}
/** // pre-calc the allowall & global contexts
* Removes the UserData cache from this user // since contexts change so frequently, it's not worth trying to calculate any more than this.
*/ userData.preCalculate(Contexts.allowAll());
public void unregisterData() { userData.preCalculate(Contexts.global());
userData.clear();
} }
/** /**
@ -205,10 +204,6 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
} }
} }
public void cleanup() {
userData.cleanup();
}
private static final class UserRefreshBuffer extends BufferedRequest<Void> { private static final class UserRefreshBuffer extends BufferedRequest<Void> {
private final User user; private final User user;

View File

@ -55,8 +55,8 @@ import me.lucko.luckperms.common.verbose.VerboseHandler;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -369,14 +369,6 @@ public interface LuckPermsPlugin {
*/ */
Set<UUID> getUniqueConnections(); Set<UUID> getUniqueConnections();
/**
* Gets a set of Contexts that should be pre-processed in advance
*
* @param op if the user being processed is op
* @return a set of contexts
*/
Set<Contexts> getPreProcessContexts(boolean op);
default List<Command> getExtraCommands() { default List<Command> getExtraCommands() {
return Collections.emptyList(); return Collections.emptyList();
} }
@ -386,7 +378,7 @@ public interface LuckPermsPlugin {
* *
* @return a map of options, or null * @return a map of options, or null
*/ */
default LinkedHashMap<String, Object> getExtraInfo() { default Map<String, Object> getExtraInfo() {
return null; return null;
} }

View File

@ -37,7 +37,7 @@ public class CacheHousekeepingTask implements Runnable {
@Override @Override
public void run() { public void run() {
for (User user : plugin.getUserManager().getAll().values()) { for (User user : plugin.getUserManager().getAll().values()) {
user.cleanup(); user.getUserData().doCacheCleanup();
} }
} }
} }

View File

@ -90,7 +90,8 @@ public class LoginHelper {
plugin.getStorage().noBuffer().saveUser(user).join(); plugin.getStorage().noBuffer().saveUser(user).join();
} }
user.preCalculateData(false); // Pretty nasty calculation call. Sets up the caching system so data is ready when the user joins. // Does some minimum pre-calculations to (maybe) speed things up later.
user.preCalculateData();
} }
final long time = System.currentTimeMillis() - startTime; final long time = System.currentTimeMillis() - startTime;

View File

@ -114,6 +114,7 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -295,6 +296,9 @@ public class LPSpongePlugin implements LuckPermsPlugin {
@Listener @Listener
public void onDisable(GameStoppingServerEvent event) { public void onDisable(GameStoppingServerEvent event) {
permissionVault.setShutdown(true);
verboseHandler.setShutdown(true);
getLog().info("Closing storage..."); getLog().info("Closing storage...");
storage.shutdown(); storage.shutdown();
@ -311,6 +315,8 @@ public class LPSpongePlugin implements LuckPermsPlugin {
getLog().info("Shutting down internal scheduler..."); getLog().info("Shutting down internal scheduler...");
scheduler.shutdown(); scheduler.shutdown();
getLog().info("Goodbye!");
} }
@Listener @Listener
@ -470,19 +476,14 @@ public class LPSpongePlugin implements LuckPermsPlugin {
return getSenderFactory().wrap(game.getServer().getConsole()); return getSenderFactory().wrap(game.getServer().getConsole());
} }
@Override
public Set<Contexts> getPreProcessContexts(boolean op) {
return Collections.emptySet();
}
@Override @Override
public List<Command> getExtraCommands() { public List<Command> getExtraCommands() {
return Collections.singletonList(new SpongeMainCommand(this)); return Collections.singletonList(new SpongeMainCommand(this));
} }
@Override @Override
public LinkedHashMap<String, Object> getExtraInfo() { public Map<String, Object> getExtraInfo() {
LinkedHashMap<String, Object> map = new LinkedHashMap<>(); Map<String, Object> map = new LinkedHashMap<>();
map.put("SubjectCollection count", service.getLoadedCollections().size()); map.put("SubjectCollection count", service.getLoadedCollections().size());
map.put("Subject count", map.put("Subject count",
service.getLoadedCollections().values().stream() service.getLoadedCollections().values().stream()

View File

@ -27,8 +27,6 @@ package me.lucko.luckperms.sponge;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
@ -36,7 +34,6 @@ import me.lucko.luckperms.common.utils.LoginHelper;
import me.lucko.luckperms.common.utils.UuidCache; import me.lucko.luckperms.common.utils.UuidCache;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order; import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.command.SendCommandEvent; import org.spongepowered.api.event.command.SendCommandEvent;
@ -45,15 +42,11 @@ import org.spongepowered.api.event.network.ClientConnectionEvent;
import org.spongepowered.api.profile.GameProfile; import org.spongepowered.api.profile.GameProfile;
import org.spongepowered.api.text.serializer.TextSerializers; import org.spongepowered.api.text.serializer.TextSerializers;
import org.spongepowered.api.util.Tristate; import org.spongepowered.api.util.Tristate;
import org.spongepowered.api.world.World;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
@RequiredArgsConstructor @RequiredArgsConstructor
public class SpongeListener { public class SpongeListener {
@ -160,29 +153,6 @@ public class SpongeListener {
e.setMessageCancelled(false); e.setMessageCancelled(false);
//noinspection deprecation //noinspection deprecation
e.setMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(Message.LOADING_ERROR.asString(plugin.getLocaleManager()))); e.setMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(Message.LOADING_ERROR.asString(plugin.getLocaleManager())));
return;
}
// Attempt to pre-process some permissions for the user to save time later. Might not work, but it's better than nothing.
Optional<Player> p = e.getCause().first(Player.class);
if (p.isPresent()) {
MutableContextSet context = MutableContextSet.fromSet(plugin.getContextManager().getApplicableContext(p.get()));
List<String> worlds = plugin.getGame().isServerAvailable() ? plugin.getGame().getServer().getWorlds().stream()
.map(World::getName)
.collect(Collectors.toList()) : Collections.emptyList();
plugin.doAsync(() -> {
UserData data = user.getUserData();
data.preCalculate(plugin.getService().calculateContexts(context.makeImmutable()));
for (String world : worlds) {
MutableContextSet modified = MutableContextSet.fromSet(context);
modified.removeAll("world");
modified.add("world", world);
data.preCalculate(plugin.getService().calculateContexts(modified.makeImmutable()));
}
});
} }
} }

View File

@ -85,7 +85,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
user.getIoLock().unlock(); user.getIoLock().unlock();
// ok, data is here, let's do the pre-calculation stuff. // ok, data is here, let's do the pre-calculation stuff.
user.preCalculateData(false); user.preCalculateData();
return user.sponge(); return user.sponge();
} }
@ -97,7 +97,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
throw new RuntimeException(); throw new RuntimeException();
} }
user.preCalculateData(false); user.preCalculateData();
return user.sponge(); return user.sponge();
}); });

View File

@ -191,7 +191,7 @@ public class SpongeUser extends User {
@Override @Override
public void invalidateCaches(CacheLevel cacheLevel) { public void invalidateCaches(CacheLevel cacheLevel) {
// invalidate for all changes // invalidate for all changes
parent.getUserData().invalidateCache(); parent.getUserData().invalidateCaches();
} }
} }