Cleanup with way permissibles are monitored on Bukkit/Nukkit

- The removal of the call to recalculatePermissions should fix CMEs on startup, in particular with Vault.
- Monitored permissibles are now uninjected when the plugin disables.
This commit is contained in:
Luck 2019-01-07 20:21:36 +00:00
parent 9b1c73ed23
commit d0c016f6b7
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
6 changed files with 68 additions and 28 deletions

View File

@ -189,7 +189,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
new InjectorSubscriptionMap(this),
new InjectorPermissionMap(this),
new InjectorDefaultsMap(this),
new PermissibleMonitoringInjector(this)
new PermissibleMonitoringInjector(this, PermissibleMonitoringInjector.Mode.INJECT)
};
for (Runnable injector : injectors) {
@ -317,6 +317,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
InjectorSubscriptionMap.uninject();
InjectorPermissionMap.uninject();
InjectorDefaultsMap.uninject();
new PermissibleMonitoringInjector(this, PermissibleMonitoringInjector.Mode.UNINJECT).run();
// unhook vault
if (this.vaultHookManager != null) {

View File

@ -47,7 +47,7 @@ import java.util.Set;
* Method calls are forwarded to the delegate permissible.
*/
public class MonitoredPermissibleBase extends PermissibleBase {
private final LuckPermsPlugin plugin;
final LuckPermsPlugin plugin;
private final PermissibleBase delegate;
private final String name;
@ -64,10 +64,6 @@ public class MonitoredPermissibleBase extends PermissibleBase {
this.delegate = delegate;
this.name = name;
this.initialised = true;
// since we effectively cancel the execution of this call in the super
// constructor we need to call it again.
recalculatePermissions();
}
private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) {

View File

@ -43,8 +43,15 @@ import java.util.Objects;
public class PermissibleMonitoringInjector implements Runnable {
private final LPBukkitPlugin plugin;
public PermissibleMonitoringInjector(LPBukkitPlugin plugin) {
public enum Mode {
INJECT, UNINJECT
}
private final Mode mode;
public PermissibleMonitoringInjector(LPBukkitPlugin plugin, Mode mode) {
this.plugin = plugin;
this.mode = mode;
}
@Override
@ -68,14 +75,24 @@ public class PermissibleMonitoringInjector implements Runnable {
}
}
private MonitoredPermissibleBase wrap(PermissibleBase permBase, String name) {
private PermissibleBase transform(PermissibleBase permBase, String name) {
Objects.requireNonNull(permBase, "permBase");
// don't bother injecting if already setup.
if (this.mode == Mode.INJECT && permBase instanceof MonitoredPermissibleBase && ((MonitoredPermissibleBase) permBase).plugin == this.plugin) {
return null;
}
// unwrap any previous injection
if (permBase instanceof MonitoredPermissibleBase) {
permBase = ((MonitoredPermissibleBase) permBase).getDelegate();
}
// if the mode is uninject, just return the unwrapped PermissibleBase
if (this.mode == Mode.UNINJECT) {
return permBase;
}
// create a monitored instance which delegates to the previous PermissibleBase
return new MonitoredPermissibleBase(this.plugin, permBase, name);
}
@ -93,10 +110,13 @@ public class PermissibleMonitoringInjector implements Runnable {
// get the PermissibleBase instance
PermissibleBase permBase = (PermissibleBase) permField.get(consoleSender);
// create a monitored instance which delegates to the previous PermissibleBase
MonitoredPermissibleBase newPermBase = wrap(permBase, "internal/console");
// create a new instance which delegates to the previous PermissibleBase
PermissibleBase newPermBase = transform(permBase, "internal/console");
if (newPermBase == null) {
return;
}
// inject the monitored instance
// inject the new instance
permField.set(consoleSender, newPermBase);
}
@ -117,10 +137,13 @@ public class PermissibleMonitoringInjector implements Runnable {
permBase = new PermissibleBase(new CommandBlockServerOperator());
}
// create a monitored instance which delegates to the previous PermissibleBase
MonitoredPermissibleBase newPermBase = wrap(permBase, "internal/commandblock");
// create a new instance which delegates to the previous PermissibleBase
PermissibleBase newPermBase = transform(permBase, "internal/commandblock");
if (newPermBase == null) {
return;
}
// inject the monitored instance
// inject the new instance
permField.set(null, newPermBase);
}
@ -140,10 +163,13 @@ public class PermissibleMonitoringInjector implements Runnable {
Field permField = entityClass.getDeclaredField("perm");
permField.setAccessible(true);
// create a monitored instance which delegates to the previous PermissibleBase
MonitoredPermissibleBase newPermBase = wrap(permBase, "internal/entity");
// create a new instance which delegates to the previous PermissibleBase
PermissibleBase newPermBase = transform(permBase, "internal/entity");
if (newPermBase == null) {
return;
}
// inject the monitored instance
// inject the new instance
permField.set(null, newPermBase);
}

View File

@ -162,7 +162,7 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin {
new InjectorSubscriptionMap(this),
new InjectorPermissionMap(this),
new InjectorDefaultsMap(this),
new PermissibleMonitoringInjector(this)
new PermissibleMonitoringInjector(this, PermissibleMonitoringInjector.Mode.INJECT)
};
for (Runnable injector : injectors) {
@ -266,6 +266,7 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin {
InjectorSubscriptionMap.uninject();
InjectorPermissionMap.uninject();
InjectorDefaultsMap.uninject();
new PermissibleMonitoringInjector(this, PermissibleMonitoringInjector.Mode.UNINJECT).run();
}
public void refreshAutoOp(Player player) {

View File

@ -47,7 +47,7 @@ import java.util.Map;
* Method calls are forwarded to the delegate permissible.
*/
public class MonitoredPermissibleBase extends PermissibleBase {
private final LuckPermsPlugin plugin;
final LuckPermsPlugin plugin;
private final PermissibleBase delegate;
private final String name;
@ -64,10 +64,6 @@ public class MonitoredPermissibleBase extends PermissibleBase {
this.delegate = delegate;
this.name = name;
this.initialised = true;
// since we effectively cancel the execution of this call in the super
// constructor we need to call it again.
recalculatePermissions();
}
private void logCheck(PermissionCheckEvent.Origin origin, String permission, boolean result) {

View File

@ -40,8 +40,15 @@ import java.util.Objects;
public class PermissibleMonitoringInjector implements Runnable {
private final LPNukkitPlugin plugin;
public PermissibleMonitoringInjector(LPNukkitPlugin plugin) {
public enum Mode {
INJECT, UNINJECT
}
private final Mode mode;
public PermissibleMonitoringInjector(LPNukkitPlugin plugin, Mode mode) {
this.plugin = plugin;
this.mode = mode;
}
@Override
@ -53,14 +60,24 @@ public class PermissibleMonitoringInjector implements Runnable {
}
}
private MonitoredPermissibleBase wrap(PermissibleBase permBase, String name) {
private PermissibleBase transform(PermissibleBase permBase, String name) {
Objects.requireNonNull(permBase, "permBase");
// don't bother injecting if already setup.
if (this.mode == Mode.INJECT && permBase instanceof MonitoredPermissibleBase && ((MonitoredPermissibleBase) permBase).plugin == this.plugin) {
return null;
}
// unwrap any previous injection
if (permBase instanceof MonitoredPermissibleBase) {
permBase = ((MonitoredPermissibleBase) permBase).getDelegate();
}
// if the mode is uninject, just return the unwrapped PermissibleBase
if (this.mode == Mode.UNINJECT) {
return permBase;
}
// create a monitored instance which delegates to the previous PermissibleBase
return new MonitoredPermissibleBase(this.plugin, permBase, name);
}
@ -75,10 +92,13 @@ public class PermissibleMonitoringInjector implements Runnable {
// get the PermissibleBase instance
PermissibleBase permBase = (PermissibleBase) permField.get(consoleSender);
// create a monitored instance which delegates to the previous PermissibleBase
MonitoredPermissibleBase newPermBase = wrap(permBase, "internal/console");
// create a new instance which delegates to the previous PermissibleBase
PermissibleBase newPermBase = transform(permBase, "internal/console");
if (newPermBase == null) {
return;
}
// inject the monitored instance
// inject the new instance
permField.set(consoleSender, newPermBase);
}
}