diff --git a/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java b/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java index e7b149f62..10dd62dd7 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java +++ b/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java @@ -69,7 +69,7 @@ class BukkitListener extends AbstractListener implements Listener { BukkitUser u = (BukkitUser) user; try { - LPPermissible lpPermissible = new LPPermissible(player, plugin); + LPPermissible lpPermissible = new LPPermissible(player, plugin, plugin.getDefaultsProvider()); Injector.inject(player, lpPermissible); u.setLpPermissible(lpPermissible); } catch (Throwable t) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java index 7846fcfe7..0fc2c9062 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java @@ -35,6 +35,7 @@ import me.lucko.luckperms.core.LPConfiguration; import me.lucko.luckperms.core.UuidCache; import me.lucko.luckperms.data.Importer; import me.lucko.luckperms.groups.GroupManager; +import me.lucko.luckperms.inject.DefaultsProvider; import me.lucko.luckperms.runnables.ExpireTemporaryTask; import me.lucko.luckperms.runnables.UpdateTask; import me.lucko.luckperms.storage.Datastore; @@ -68,6 +69,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { private Logger log; private Importer importer; private ConsecutiveExecutor consecutiveExecutor; + private DefaultsProvider defaultsProvider; @Override public void onEnable() { @@ -75,6 +77,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { getLog().info("Loading configuration..."); configuration = new BukkitConfig(this); + defaultsProvider = new DefaultsProvider(); + defaultsProvider.refresh(); // register events PluginManager pm = getServer().getPluginManager(); diff --git a/bukkit/src/main/java/me/lucko/luckperms/inject/DefaultsProvider.java b/bukkit/src/main/java/me/lucko/luckperms/inject/DefaultsProvider.java new file mode 100644 index 000000000..41d829a8f --- /dev/null +++ b/bukkit/src/main/java/me/lucko/luckperms/inject/DefaultsProvider.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.inject; + +import lombok.AllArgsConstructor; +import me.lucko.luckperms.api.Tristate; +import org.bukkit.Bukkit; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class DefaultsProvider { + + private final DummyPermissible opDummy = new DummyPermissible(this::refreshOp); + private final DummyPermissible nonOpDummy = new DummyPermissible(this::refreshNonOp); + + private final Map op = new HashMap<>(); + private final Map nonOp = new HashMap<>(); + + public void refresh() { + refreshOp(); + refreshNonOp(); + } + + private void refreshOp() { + calculateDefaults(op, opDummy, true); + } + + private void refreshNonOp() { + calculateDefaults(nonOp, nonOpDummy, false); + } + + private static void calculateDefaults(Map map, DummyPermissible p, boolean op) { + Set perms = map.keySet(); + + for (String name : perms) { + Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, p); + } + + Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, p); + Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, p); + + map.clear(); + + Set defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(op); + Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(op, p); + + for (Permission perm : defaults) { + String name = perm.getName().toLowerCase(); + map.put(name, true); + Bukkit.getServer().getPluginManager().subscribeToPermission(name, p); + calculateChildPermissions(map, p, perm.getChildren(), false); + } + } + + private static void calculateChildPermissions(Map map, DummyPermissible p, Map children, boolean invert) { + for (Map.Entry e : children.entrySet()) { + Permission perm = Bukkit.getServer().getPluginManager().getPermission(e.getKey()); + boolean value = e.getValue() ^ invert; + String lName = e.getKey().toLowerCase(); + + map.put(lName, value); + Bukkit.getServer().getPluginManager().subscribeToPermission(e.getKey(), p); + + if (perm != null) { + calculateChildPermissions(map, p, perm.getChildren(), !value); + } + } + } + + public Tristate hasDefault(String permission, boolean isOp) { + Map map = isOp ? op : nonOp; + if (!map.containsKey(permission)) { + return Tristate.UNDEFINED; + } + + return Tristate.fromBoolean(map.get(permission)); + } + + @AllArgsConstructor + private static class DummyPermissible implements Permissible { + private final Runnable onRefresh; + + @Override + public void recalculatePermissions() { + onRefresh.run(); + } + + @Override + public Set getEffectivePermissions() { + return Collections.emptySet(); + } + + @Override + public boolean isPermissionSet(String name) { + return false; + } + + @Override + public boolean isPermissionSet(Permission perm) { + return false; + } + + @Override + public boolean hasPermission(String name) { + return false; + } + + @Override + public boolean hasPermission(Permission perm) { + return false; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin) { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + return null; + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + return null; + } + + @Override + public void removeAttachment(PermissionAttachment attachment) { + + } + + @Override + public boolean isOp() { + return false; + } + + @Override + public void setOp(boolean value) { + + } + } + +} diff --git a/bukkit/src/main/java/me/lucko/luckperms/inject/LPPermissible.java b/bukkit/src/main/java/me/lucko/luckperms/inject/LPPermissible.java index 3aa1fcc76..3052ea224 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/inject/LPPermissible.java +++ b/bukkit/src/main/java/me/lucko/luckperms/inject/LPPermissible.java @@ -55,7 +55,7 @@ public class LPPermissible extends PermissibleBase { private final List attachments = new LinkedList<>(); private final Map attachmentPermissions = new HashMap<>(); - public LPPermissible(@NonNull CommandSender sender, LuckPermsPlugin plugin) { + public LPPermissible(@NonNull CommandSender sender, LuckPermsPlugin plugin, DefaultsProvider defaultsProvider) { super(sender); this.parent = sender; @@ -68,7 +68,7 @@ public class LPPermissible extends PermissibleBase { if (plugin.getConfiguration().getApplyRegex()) { processors.add(new PermissionCalculator.RegexProcessor(luckPermsPermissions)); } - processors.add(new BukkitDefaultsProcessor(parent::isOp)); + processors.add(new BukkitDefaultsProcessor(parent::isOp, defaultsProvider)); calculator = new PermissionCalculator(plugin, parent.getName(), plugin.getConfiguration().getDebugPermissionChecks(), processors); @@ -200,16 +200,6 @@ public class LPPermissible extends PermissibleBase { } attachmentPermissions.clear(); - Set defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp()); - Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), parent); - - for (Permission perm : defaults) { - String name = perm.getName().toLowerCase(); - - attachmentPermissions.put(name, new PermissionAttachmentInfo(parent, name, null, true)); - Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent); - calculateChildPermissions(perm.getChildren(), false, null); - } for (PermissionAttachment attachment : attachments) { calculateChildPermissions(attachment.getPermissions(), false, attachment); @@ -291,9 +281,15 @@ public class LPPermissible extends PermissibleBase { @AllArgsConstructor private static class BukkitDefaultsProcessor implements PermissionProcessor { private final Supplier isOp; + private final DefaultsProvider defaultsProvider; @Override public Tristate hasPermission(String permission) { + Tristate t = defaultsProvider.hasDefault(permission, isOp.get()); + if (t != Tristate.UNDEFINED) { + return t; + } + Permission defPerm = Bukkit.getServer().getPluginManager().getPermission(permission); if (defPerm != null) { return Tristate.fromBoolean(defPerm.getDefault().getValue(isOp.get()));