Pre-process permissions and apply immediately on login events
This commit is contained in:
parent
13bccd1d3f
commit
82789328c1
@ -23,6 +23,7 @@
|
|||||||
package me.lucko.luckperms;
|
package me.lucko.luckperms;
|
||||||
|
|
||||||
import me.lucko.luckperms.constants.Message;
|
import me.lucko.luckperms.constants.Message;
|
||||||
|
import me.lucko.luckperms.contexts.Contexts;
|
||||||
import me.lucko.luckperms.inject.Injector;
|
import me.lucko.luckperms.inject.Injector;
|
||||||
import me.lucko.luckperms.inject.LPPermissible;
|
import me.lucko.luckperms.inject.LPPermissible;
|
||||||
import me.lucko.luckperms.users.BukkitUser;
|
import me.lucko.luckperms.users.BukkitUser;
|
||||||
@ -34,6 +35,8 @@ import org.bukkit.event.EventPriority;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.*;
|
import org.bukkit.event.player.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
class BukkitListener extends AbstractListener implements Listener {
|
class BukkitListener extends AbstractListener implements Listener {
|
||||||
@ -52,7 +55,41 @@ class BukkitListener extends AbstractListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process login
|
||||||
onAsyncLogin(e.getUniqueId(), e.getName());
|
onAsyncLogin(e.getUniqueId(), e.getName());
|
||||||
|
|
||||||
|
// Pre-process the user's permissions, so they're ready for PLE.
|
||||||
|
BukkitUser user = (BukkitUser) plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getUniqueId()));
|
||||||
|
Map<String, Boolean> toApply = user.exportNodes(
|
||||||
|
new Contexts(
|
||||||
|
Collections.singletonMap("server", plugin.getConfiguration().getServer()),
|
||||||
|
plugin.getConfiguration().isIncludingGlobalPerms(),
|
||||||
|
plugin.getConfiguration().isIncludingGlobalWorldPerms(),
|
||||||
|
true,
|
||||||
|
plugin.getConfiguration().isApplyingGlobalGroups(),
|
||||||
|
plugin.getConfiguration().isApplyingGlobalWorldGroups()
|
||||||
|
),
|
||||||
|
Collections.emptyList(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
user.setLoginPreProcess(toApply);
|
||||||
|
|
||||||
|
// Hook with Vault early
|
||||||
|
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||||
|
plugin.getVaultHook().getPermissionHook().getVaultUserManager().setupUser(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerPreLoginMonitor(AsyncPlayerPreLoginEvent e) {
|
||||||
|
if (plugin.getDatastore().isAcceptingLogins() && e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||||
|
// Login event was cancelled by another plugin
|
||||||
|
final UUID internal = plugin.getUuidCache().getUUID(e.getUniqueId());
|
||||||
|
onLeave(e.getUniqueId());
|
||||||
|
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||||
|
plugin.getVaultHook().getPermissionHook().getVaultUserManager().clearUser(internal);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
@ -65,19 +102,39 @@ class BukkitListener extends AbstractListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user instanceof BukkitUser) {
|
BukkitUser u = (BukkitUser) user;
|
||||||
BukkitUser u = (BukkitUser) user;
|
try {
|
||||||
|
// Make a new permissible for the user
|
||||||
|
LPPermissible lpPermissible = new LPPermissible(player, plugin, plugin.getDefaultsProvider());
|
||||||
|
|
||||||
try {
|
// Insert the pre-processed permissions into the permissible
|
||||||
LPPermissible lpPermissible = new LPPermissible(player, plugin, plugin.getDefaultsProvider());
|
lpPermissible.getLuckPermsPermissions().putAll(u.getLoginPreProcess());
|
||||||
Injector.inject(player, lpPermissible);
|
u.setLoginPreProcess(null);
|
||||||
u.setLpPermissible(lpPermissible);
|
|
||||||
} catch (Throwable t) {
|
// Inject into the player
|
||||||
t.printStackTrace();
|
Injector.inject(player, lpPermissible);
|
||||||
}
|
u.setLpPermissible(lpPermissible);
|
||||||
|
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plugin.doAsync(user::refreshPermissions);
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerLoginMonitor(PlayerLoginEvent e) {
|
||||||
|
if (e.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
||||||
|
// The player got denied on sync login.
|
||||||
|
final UUID internal = plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId());
|
||||||
|
onLeave(e.getPlayer().getUniqueId());
|
||||||
|
if (plugin.getVaultHook() != null && plugin.getVaultHook().isHooked()) {
|
||||||
|
plugin.getVaultHook().getPermissionHook().getVaultUserManager().clearUser(internal);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||||
|
|
||||||
|
// Call another update to calculate full context. (incl. per world permissions)
|
||||||
|
plugin.doAsync(user::refreshPermissions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
@ -57,7 +57,7 @@ public class ContextCache {
|
|||||||
processors.add(new RegexProcessor(permissionCache));
|
processors.add(new RegexProcessor(permissionCache));
|
||||||
}
|
}
|
||||||
|
|
||||||
processors.add(new DefaultsProcessor(() -> ((BukkitUser) user).getLpPermissible().isOp(), defaultsProvider));
|
processors.add(new DefaultsProcessor(((BukkitUser) user)::isOp, defaultsProvider));
|
||||||
calculator = new PermissionCalculator(plugin, user.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
calculator = new PermissionCalculator(plugin, user.getName(), plugin.getConfiguration().isDebugPermissionChecks(), processors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class Injector {
|
|||||||
try {
|
try {
|
||||||
Permissible permissible = getPermissible(sender);
|
Permissible permissible = getPermissible(sender);
|
||||||
if (permissible instanceof LPPermissible) {
|
if (permissible instanceof LPPermissible) {
|
||||||
getPermField(sender).set(sender, new PermissibleBase(sender));
|
getPermField(sender).set(sender, null);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -44,6 +44,10 @@ public class BukkitUser extends User {
|
|||||||
@Setter
|
@Setter
|
||||||
private LPPermissible lpPermissible = null;
|
private LPPermissible lpPermissible = null;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Map<String, Boolean> loginPreProcess = null;
|
||||||
|
|
||||||
BukkitUser(UUID uuid, LPBukkitPlugin plugin) {
|
BukkitUser(UUID uuid, LPBukkitPlugin plugin) {
|
||||||
super(uuid, plugin);
|
super(uuid, plugin);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@ -54,6 +58,10 @@ public class BukkitUser extends User {
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOp() {
|
||||||
|
return lpPermissible != null && lpPermissible.isOp();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public synchronized void refreshPermissions() {
|
public synchronized void refreshPermissions() {
|
||||||
|
@ -41,12 +41,12 @@ abstract class FlatfileDatastore extends Datastore {
|
|||||||
private final Logger actionLogger = Logger.getLogger("lp_actions");
|
private final Logger actionLogger = Logger.getLogger("lp_actions");
|
||||||
private Map<String, String> uuidCache = new ConcurrentHashMap<>();
|
private Map<String, String> uuidCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
final File pluginDir;
|
private final File pluginDir;
|
||||||
|
private File uuidData;
|
||||||
|
private File actionLog;
|
||||||
File usersDir;
|
File usersDir;
|
||||||
File groupsDir;
|
File groupsDir;
|
||||||
File tracksDir;
|
File tracksDir;
|
||||||
File uuidData;
|
|
||||||
File actionLog;
|
|
||||||
|
|
||||||
FlatfileDatastore(LuckPermsPlugin plugin, String name, File pluginDir) {
|
FlatfileDatastore(LuckPermsPlugin plugin, String name, File pluginDir) {
|
||||||
super(plugin, name);
|
super(plugin, name);
|
||||||
|
@ -70,7 +70,9 @@ public class AbstractListener {
|
|||||||
final UuidCache cache = plugin.getUuidCache();
|
final UuidCache cache = plugin.getUuidCache();
|
||||||
|
|
||||||
final User user = plugin.getUserManager().get(cache.getUUID(uuid));
|
final User user = plugin.getUserManager().get(cache.getUUID(uuid));
|
||||||
plugin.getUserManager().unload(user);
|
if (user != null) {
|
||||||
|
plugin.getUserManager().unload(user);
|
||||||
|
}
|
||||||
|
|
||||||
// Unload the user from memory when they disconnect;
|
// Unload the user from memory when they disconnect;
|
||||||
cache.clearCache(uuid);
|
cache.clearCache(uuid);
|
||||||
|
Loading…
Reference in New Issue
Block a user