Skip to content

Commit b39ac82

Browse files
committed
Create cached permission system
1 parent 506893d commit b39ac82

5 files changed

Lines changed: 73 additions & 0 deletions

File tree

Essentials/src/main/java/com/earth2me/essentials/IUser.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
public interface IUser {
3333
boolean isAuthorized(String node);
3434

35+
boolean isAuthorizedCached(String node);
36+
3537
boolean isAuthorized(IEssentialsCommand cmd);
3638

3739
boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix);

Essentials/src/main/java/com/earth2me/essentials/User.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,19 @@ public boolean isAuthorized(final String node) {
147147
return result;
148148
}
149149

150+
@Override
151+
public boolean isAuthorizedCached(final String node) {
152+
if (Essentials.TESTING) {
153+
return false;
154+
}
155+
156+
final boolean result = isAuthorizedCachedCheck(node);
157+
if (ess.getSettings().isDebug()) {
158+
ess.getLogger().log(Level.INFO, "checking if " + base.getName() + " has " + node + " (cached) - " + result);
159+
}
160+
return result;
161+
}
162+
150163
@Override
151164
public boolean isPermissionSet(final String node) {
152165
if (Essentials.TESTING) {
@@ -186,6 +199,24 @@ private boolean isAuthorizedCheck(final String node) {
186199
}
187200
}
188201

202+
private boolean isAuthorizedCachedCheck(final String node) {
203+
if (base instanceof OfflinePlayerStub) {
204+
return false;
205+
}
206+
207+
try {
208+
return ess.getPermissionsHandler().hasPermissionCached(base, node);
209+
} catch (final Exception ex) {
210+
if (ess.getSettings().isDebug()) {
211+
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
212+
} else {
213+
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage());
214+
}
215+
216+
return false;
217+
}
218+
}
219+
189220
private boolean isPermSetCheck(final String node) {
190221
if (base instanceof OfflinePlayerStub) {
191222
return false;

Essentials/src/main/java/com/earth2me/essentials/perm/IPermissionsHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public interface IPermissionsHandler {
2828

2929
boolean hasPermission(Player base, String node);
3030

31+
default boolean hasPermissionCached(Player base, String node) {
32+
return hasPermission(base, node);
33+
}
34+
3135
// Does not check for * permissions
3236
boolean isPermissionSet(Player base, String node);
3337

Essentials/src/main/java/com/earth2me/essentials/perm/PermissionsHandler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ public boolean hasPermission(final Player base, final String node) {
105105
return handler.hasPermission(base, node);
106106
}
107107

108+
@Override
109+
public boolean hasPermissionCached(final Player base, final String node) {
110+
return handler.hasPermissionCached(base, node);
111+
}
112+
108113
@Override
109114
public boolean isPermissionSet(final Player base, final String node) {
110115
return handler.isPermissionSet(base, node);

Essentials/src/main/java/com/earth2me/essentials/perm/impl/LuckPermsHandler.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,31 @@
77
import net.luckperms.api.context.ContextConsumer;
88
import net.luckperms.api.context.ContextSet;
99
import net.luckperms.api.context.ImmutableContextSet;
10+
import net.luckperms.api.event.EventSubscription;
11+
import net.luckperms.api.event.user.UserDataRecalculateEvent;
1012
import net.luckperms.api.model.group.Group;
1113
import net.luckperms.api.query.QueryOptions;
1214
import org.bukkit.Bukkit;
1315
import org.bukkit.entity.Player;
1416
import org.bukkit.plugin.RegisteredServiceProvider;
1517

18+
import java.util.logging.Level;
1619
import java.util.ArrayList;
1720
import java.util.HashSet;
1821
import java.util.List;
22+
import java.util.Map;
1923
import java.util.Set;
2024
import java.util.UUID;
25+
import java.util.concurrent.ConcurrentHashMap;
2126
import java.util.function.Function;
2227
import java.util.function.Supplier;
2328

2429
public class LuckPermsHandler extends ModernVaultHandler {
2530
private LuckPerms luckPerms;
2631
private Essentials ess;
2732
private CombinedCalculator calculator;
33+
private final Map<UUID, Map<String, Boolean>> permissionCache = new ConcurrentHashMap<>();
34+
private EventSubscription<UserDataRecalculateEvent> recalculateSubscription;
2835

2936
@Override
3037
public void registerContext(final String context, final Function<User, Iterable<String>> calculator, final Supplier<Iterable<String>> suggestions) {
@@ -41,6 +48,25 @@ public void unregisterContexts() {
4148
this.luckPerms.getContextManager().unregisterCalculator(this.calculator);
4249
this.calculator = null;
4350
}
51+
if (this.recalculateSubscription != null) {
52+
this.recalculateSubscription.close();
53+
this.recalculateSubscription = null;
54+
}
55+
this.permissionCache.clear();
56+
}
57+
58+
@Override
59+
public boolean hasPermissionCached(final Player base, final String node) {
60+
final UUID uuid = base.getUniqueId();
61+
final Map<String, Boolean> userCache = permissionCache.computeIfAbsent(uuid, k -> new ConcurrentHashMap<>());
62+
return userCache.computeIfAbsent(node, k -> hasPermission(base, node));
63+
}
64+
65+
public void invalidateCache(final UUID uuid) {
66+
if (ess.getSettings().isDebug()) {
67+
ess.getLogger().log(Level.INFO, "Invalidating permission cache for " + uuid);
68+
}
69+
permissionCache.remove(uuid);
4470
}
4571

4672
@Override
@@ -77,6 +103,11 @@ public boolean tryProvider(Essentials ess) {
77103
if (provider != null) {
78104
this.luckPerms = provider.getProvider();
79105
this.ess = ess;
106+
this.recalculateSubscription = this.luckPerms.getEventBus().subscribe(
107+
ess,
108+
UserDataRecalculateEvent.class,
109+
event -> invalidateCache(event.getUser().getUniqueId())
110+
);
80111
}
81112
return luckPerms != null && super.tryProvider(ess);
82113
}

0 commit comments

Comments
 (0)