diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java index 2f4778043..5baa9d412 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java @@ -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) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java index e86d67aaa..ca7a30113 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/MonitoredPermissibleBase.java @@ -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) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/PermissibleMonitoringInjector.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/PermissibleMonitoringInjector.java index 21a27d6f7..e0795bd04 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/PermissibleMonitoringInjector.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/PermissibleMonitoringInjector.java @@ -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); } diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java index ad7ddbf3f..710ffc0b0 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitPlugin.java @@ -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) { diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java index 57a82e74b..353d085a3 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/MonitoredPermissibleBase.java @@ -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) { diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/PermissibleMonitoringInjector.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/PermissibleMonitoringInjector.java index b89f2a307..604d313cb 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/PermissibleMonitoringInjector.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/PermissibleMonitoringInjector.java @@ -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); } }