diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/dummy/DummyPermissibleBase.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/dummy/DummyPermissibleBase.java index 8566bfdc..8f8524de 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/dummy/DummyPermissibleBase.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/dummy/DummyPermissibleBase.java @@ -64,6 +64,19 @@ public class DummyPermissibleBase extends PermissibleBase { } } + public static void copyFields(PermissibleBase from, PermissibleBase to) { + try { + ATTACHMENTS_FIELD.set(to, ATTACHMENTS_FIELD.get(from)); + } catch (Exception e) { + // ignore + } + try { + PERMISSIONS_FIELD.set(to, PERMISSIONS_FIELD.get(from)); + } catch (Exception e) { + // ignore + } + } + public static final DummyPermissibleBase INSTANCE = new DummyPermissibleBase(); private DummyPermissibleBase() { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissible.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissible.java index 67614088..1d72ee5b 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissible.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissible.java @@ -25,11 +25,14 @@ package me.lucko.luckperms.bukkit.model.permissible; +import com.google.common.collect.ImmutableList; + import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.bukkit.LPBukkitPlugin; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.contexts.ContextsCache; import me.lucko.luckperms.common.model.User; +import me.lucko.luckperms.common.utils.ImmutableCollectors; import me.lucko.luckperms.common.verbose.CheckOrigin; import org.bukkit.entity.Player; @@ -39,14 +42,18 @@ import org.bukkit.permissions.PermissionAttachment; import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; +import java.lang.reflect.Field; import java.util.Collection; -import java.util.HashSet; -import java.util.Map; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.Nonnull; + /** * PermissibleBase for LuckPerms. * @@ -63,6 +70,17 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public class LPPermissible extends PermissibleBase { + private static final Field ATTACHMENTS_FIELD; + + static { + try { + ATTACHMENTS_FIELD = PermissibleBase.class.getDeclaredField("attachments"); + ATTACHMENTS_FIELD.setAccessible(true); + } catch (NoSuchFieldException e) { + throw new ExceptionInInitializerError(e); + } + } + // the LuckPerms user this permissible references. private final User user; @@ -83,7 +101,7 @@ public class LPPermissible extends PermissibleBase { // the attachments hooked onto the permissible. // this collection is only modified by the attachments themselves - final Set attachments = ConcurrentHashMap.newKeySet(); + final Set lpAttachments = ConcurrentHashMap.newKeySet(); public LPPermissible(Player player, User user, LPBukkitPlugin plugin) { super(player); @@ -91,6 +109,26 @@ public class LPPermissible extends PermissibleBase { this.player = Objects.requireNonNull(player, "player"); this.plugin = Objects.requireNonNull(plugin, "plugin"); this.contextsCache = plugin.getContextManager().getCacheFor(player); + + injectFakeAttachmentsList(); + } + + /** + * Injects a fake 'attachments' list into the superclass, for dumb plugins + * which for some reason decided to add attachments via reflection. + * + * The fake list proxies (some) calls back to the proper methods on this permissible. + */ + private void injectFakeAttachmentsList() { + FakeAttachmentList fakeList = new FakeAttachmentList(); + + try { + // the field we need to modify is in the superclass - it has private + // and final modifiers so we have to use reflection to modify it. + ATTACHMENTS_FIELD.set(this, fakeList); + } catch (Exception e) { + e.printStackTrace(); + } } @Override @@ -154,7 +192,7 @@ public class LPPermissible extends PermissibleBase { * * @param attachments the attachments to add */ - public void convertAndAddAttachments(Collection attachments) { + void convertAndAddAttachments(Collection attachments) { for (PermissionAttachment attachment : attachments) { new LPPermissionAttachment(this, attachment).hook(); } @@ -167,14 +205,9 @@ public class LPPermissible extends PermissibleBase { @Override public Set getEffectivePermissions() { - Set> permissions = this.user.getCachedData().getPermissionData(this.contextsCache.getContexts()).getImmutableBacking().entrySet(); - Set ret = new HashSet<>(permissions.size()); - - for (Map.Entry entry : permissions) { - ret.add(new PermissionAttachmentInfo(this.player, entry.getKey(), null, entry.getValue())); - } - - return ret; + return this.user.getCachedData().getPermissionData(this.contextsCache.getContexts()).getImmutableBacking().entrySet().stream() + .map(entry -> new PermissionAttachmentInfo(this.player, entry.getKey(), null, entry.getValue())) + .collect(ImmutableCollectors.toSet()); } @Override @@ -240,11 +273,20 @@ public class LPPermissible extends PermissibleBase { throw new NullPointerException("attachment"); } + LPPermissionAttachment a; + if (!(attachment instanceof LPPermissionAttachment)) { - throw new IllegalArgumentException("Given attachment is not a LPPermissionAttachment."); + // try to find a match + LPPermissionAttachment match = this.lpAttachments.stream().filter(at -> at.getSource() == attachment).findFirst().orElse(null); + if (match != null) { + a = match; + } else { + throw new IllegalArgumentException("Given attachment is not a LPPermissionAttachment."); + } + } else { + a = (LPPermissionAttachment) attachment; } - LPPermissionAttachment a = ((LPPermissionAttachment) attachment); if (a.getPermissible() != this) { throw new IllegalArgumentException("Attachment does not belong to this permissible."); } @@ -259,7 +301,7 @@ public class LPPermissible extends PermissibleBase { @Override public void clearPermissions() { - this.attachments.forEach(LPPermissionAttachment::remove); + this.lpAttachments.forEach(LPPermissionAttachment::remove); } public User getUser() { @@ -274,15 +316,102 @@ public class LPPermissible extends PermissibleBase { return this.plugin; } - public PermissibleBase getOldPermissible() { + PermissibleBase getOldPermissible() { return this.oldPermissible; } - public AtomicBoolean getActive() { + AtomicBoolean getActive() { return this.active; } - public void setOldPermissible(PermissibleBase oldPermissible) { + void setOldPermissible(PermissibleBase oldPermissible) { this.oldPermissible = oldPermissible; } + + /** + * A fake list to be injected into the superclass. This implementation simply + * proxies calls back to this permissible instance. + * + * Some (clever/dumb??) plugins attempt to add/remove/query attachments using reflection. + * + * An instance of this map is injected into the super instance so these plugins continue + * to work with LuckPerms. + */ + private final class FakeAttachmentList implements List { + + @Override + public boolean add(PermissionAttachment attachment) { + if (LPPermissible.this.lpAttachments.stream().anyMatch(at -> at.getSource() == attachment)) { + return false; + } + + new LPPermissionAttachment(LPPermissible.this, attachment).hook(); + return true; + } + + @Override + public boolean remove(Object o) { + removeAttachment((PermissionAttachment) o); + return true; + } + + @Override + public void clear() { + clearPermissions(); + } + + @Override + public boolean addAll(@Nonnull Collection c) { + boolean modified = false; + for (PermissionAttachment e : c) { + if (add(e)) { + modified = true; + } + } + return modified; + } + + @Override + public boolean contains(Object o) { + PermissionAttachment attachment = (PermissionAttachment) o; + return LPPermissible.this.lpAttachments.stream().anyMatch(at -> at.getSource() == attachment); + } + + @Override + public Iterator iterator() { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).iterator(); + } + + @Override + public ListIterator listIterator() { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).listIterator(); + } + + @Nonnull + @Override + public Object[] toArray() { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).toArray(); + } + + @Nonnull + @Override + public T[] toArray(@Nonnull T[] a) { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).toArray(a); + } + + @Override public int size() { throw new UnsupportedOperationException(); } + @Override public boolean isEmpty() { throw new UnsupportedOperationException(); } + @Override public boolean containsAll(@Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public boolean addAll(int index, @Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public boolean removeAll(@Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public boolean retainAll(@Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public PermissionAttachment get(int index) { throw new UnsupportedOperationException(); } + @Override public PermissionAttachment set(int index, PermissionAttachment element) { throw new UnsupportedOperationException(); } + @Override public void add(int index, PermissionAttachment element) { throw new UnsupportedOperationException(); } + @Override public PermissionAttachment remove(int index) { throw new UnsupportedOperationException(); } + @Override public int indexOf(Object o) { throw new UnsupportedOperationException(); } + @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); } + @Nonnull @Override public ListIterator listIterator(int index) { throw new UnsupportedOperationException(); } + @Nonnull @Override public List subList(int fromIndex, int toIndex) { throw new UnsupportedOperationException(); } + } } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java index 403b4eac..71a7c65c 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/LPPermissionAttachment.java @@ -94,6 +94,11 @@ public class LPPermissionAttachment extends PermissionAttachment { */ private PermissionRemovedExecutor removalCallback = null; + /** + * Delegate attachment + */ + private PermissionAttachment source; + public LPPermissionAttachment(LPPermissible permissible, Plugin owner) { super(DummyPlugin.INSTANCE, null); this.permissible = permissible; @@ -102,13 +107,14 @@ public class LPPermissionAttachment extends PermissionAttachment { injectFakeMap(); } - public LPPermissionAttachment(LPPermissible permissible, PermissionAttachment bukkit) { + public LPPermissionAttachment(LPPermissible permissible, PermissionAttachment source) { super(DummyPlugin.INSTANCE, null); this.permissible = permissible; this.owner = null; // copy - this.perms.putAll(bukkit.getPermissions()); + this.perms.putAll(source.getPermissions()); + this.source = source; injectFakeMap(); } @@ -148,12 +154,16 @@ public class LPPermissionAttachment extends PermissionAttachment { this.removalCallback = removalCallback; } + PermissionAttachment getSource() { + return this.source; + } + /** * Hooks this attachment with the parent {@link User} instance. */ public void hook() { this.hooked = true; - this.permissible.attachments.add(this); + this.permissible.lpAttachments.add(this); for (Map.Entry entry : this.perms.entrySet()) { if (entry.getKey() == null || entry.getKey().isEmpty()) { continue; @@ -214,7 +224,7 @@ public class LPPermissionAttachment extends PermissionAttachment { // unhook from the permissible this.hooked = false; - this.permissible.attachments.remove(this); + this.permissible.lpAttachments.remove(this); return true; } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/MonitoredPermissibleBase.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/MonitoredPermissibleBase.java index 85bf58f3..5478cc7d 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/MonitoredPermissibleBase.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/model/permissible/MonitoredPermissibleBase.java @@ -58,7 +58,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { public MonitoredPermissibleBase(LuckPermsPlugin plugin, PermissibleBase delegate, String name) { super(null); - DummyPermissibleBase.nullFields(this); + DummyPermissibleBase.copyFields(delegate, this); this.plugin = plugin; this.delegate = delegate; diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/dummy/DummyPermissibleBase.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/dummy/DummyPermissibleBase.java index 15f7b54e..15af8c25 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/dummy/DummyPermissibleBase.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/dummy/DummyPermissibleBase.java @@ -64,6 +64,19 @@ public class DummyPermissibleBase extends PermissibleBase { } } + public static void copyFields(PermissibleBase from, PermissibleBase to) { + try { + ATTACHMENTS_FIELD.set(to, ATTACHMENTS_FIELD.get(from)); + } catch (Exception e) { + // ignore + } + try { + PERMISSIONS_FIELD.set(to, PERMISSIONS_FIELD.get(from)); + } catch (Exception e) { + // ignore + } + } + public static final DummyPermissibleBase INSTANCE = new DummyPermissibleBase(); private DummyPermissibleBase() { diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissible.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissible.java index 13f705c7..b9dc8e96 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissible.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissible.java @@ -25,10 +25,13 @@ package me.lucko.luckperms.nukkit.model.permissible; +import com.google.common.collect.ImmutableList; + import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.contexts.ContextsCache; import me.lucko.luckperms.common.model.User; +import me.lucko.luckperms.common.utils.ImmutableCollectors; import me.lucko.luckperms.common.verbose.CheckOrigin; import me.lucko.luckperms.nukkit.LPNukkitPlugin; import me.lucko.luckperms.nukkit.model.PermissionDefault; @@ -40,14 +43,19 @@ import cn.nukkit.permission.PermissionAttachment; import cn.nukkit.permission.PermissionAttachmentInfo; import cn.nukkit.plugin.Plugin; +import java.lang.reflect.Field; import java.util.Collection; -import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.Nonnull; + /** * PermissibleBase for LuckPerms. * @@ -64,6 +72,17 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public class LPPermissible extends PermissibleBase { + private static final Field ATTACHMENTS_FIELD; + + static { + try { + ATTACHMENTS_FIELD = PermissibleBase.class.getDeclaredField("attachments"); + ATTACHMENTS_FIELD.setAccessible(true); + } catch (NoSuchFieldException e) { + throw new ExceptionInInitializerError(e); + } + } + // the LuckPerms user this permissible references. private final User user; @@ -84,7 +103,7 @@ public class LPPermissible extends PermissibleBase { // the attachments hooked onto the permissible. // this collection is only modified by the attachments themselves - final Set attachments = ConcurrentHashMap.newKeySet(); + final Set lpAttachments = ConcurrentHashMap.newKeySet(); public LPPermissible(Player player, User user, LPNukkitPlugin plugin) { super(player); @@ -92,6 +111,26 @@ public class LPPermissible extends PermissibleBase { this.player = Objects.requireNonNull(player, "player"); this.plugin = Objects.requireNonNull(plugin, "plugin"); this.contextsCache = plugin.getContextManager().getCacheFor(player); + + injectFakeAttachmentsList(); + } + + /** + * Injects a fake 'attachments' list into the superclass, for dumb plugins + * which for some reason decided to add attachments via reflection. + * + * The fake list proxies (some) calls back to the proper methods on this permissible. + */ + private void injectFakeAttachmentsList() { + FakeAttachmentList fakeList = new FakeAttachmentList(); + + try { + // the field we need to modify is in the superclass - it has private + // and final modifiers so we have to use reflection to modify it. + ATTACHMENTS_FIELD.set(this, fakeList); + } catch (Exception e) { + e.printStackTrace(); + } } @Override @@ -157,7 +196,7 @@ public class LPPermissible extends PermissibleBase { * * @param attachments the attachments to add */ - public void convertAndAddAttachments(Collection attachments) { + void convertAndAddAttachments(Collection attachments) { for (PermissionAttachment attachment : attachments) { new LPPermissionAttachment(this, attachment).hook(); } @@ -170,14 +209,8 @@ public class LPPermissible extends PermissibleBase { @Override public Map getEffectivePermissions() { - Set> permissions = this.user.getCachedData().getPermissionData(this.contextsCache.getContexts()).getImmutableBacking().entrySet(); - Map ret = new HashMap<>(permissions.size()); - - for (Map.Entry entry : permissions) { - ret.put(entry.getKey(), new PermissionAttachmentInfo(this.player, entry.getKey(), null, entry.getValue())); - } - - return ret; + return this.user.getCachedData().getPermissionData(this.contextsCache.getContexts()).getImmutableBacking().entrySet().stream() + .collect(ImmutableCollectors.toMap(Map.Entry::getKey, entry -> new PermissionAttachmentInfo(this.player, entry.getKey(), null, entry.getValue()))); } @Override @@ -225,11 +258,20 @@ public class LPPermissible extends PermissibleBase { throw new NullPointerException("attachment"); } + LPPermissionAttachment a; + if (!(attachment instanceof LPPermissionAttachment)) { - throw new IllegalArgumentException("Given attachment is not a LPPermissionAttachment."); + // try to find a match + LPPermissionAttachment match = this.lpAttachments.stream().filter(at -> at.getSource() == attachment).findFirst().orElse(null); + if (match != null) { + a = match; + } else { + throw new IllegalArgumentException("Given attachment is not a LPPermissionAttachment."); + } + } else { + a = (LPPermissionAttachment) attachment; } - LPPermissionAttachment a = ((LPPermissionAttachment) attachment); if (a.getPermissible() != this) { throw new IllegalArgumentException("Attachment does not belong to this permissible."); } @@ -244,7 +286,7 @@ public class LPPermissible extends PermissibleBase { @Override public void clearPermissions() { - this.attachments.forEach(LPPermissionAttachment::remove); + this.lpAttachments.forEach(LPPermissionAttachment::remove); } public User getUser() { @@ -259,15 +301,102 @@ public class LPPermissible extends PermissibleBase { return this.plugin; } - public PermissibleBase getOldPermissible() { + PermissibleBase getOldPermissible() { return this.oldPermissible; } - public AtomicBoolean getActive() { + AtomicBoolean getActive() { return this.active; } - public void setOldPermissible(PermissibleBase oldPermissible) { + void setOldPermissible(PermissibleBase oldPermissible) { this.oldPermissible = oldPermissible; } + + /** + * A fake list to be injected into the superclass. This implementation simply + * proxies calls back to this permissible instance. + * + * Some (clever/dumb??) plugins attempt to add/remove/query attachments using reflection. + * + * An instance of this map is injected into the super instance so these plugins continue + * to work with LuckPerms. + */ + private final class FakeAttachmentList implements List { + + @Override + public boolean add(PermissionAttachment attachment) { + if (LPPermissible.this.lpAttachments.stream().anyMatch(at -> at.getSource() == attachment)) { + return false; + } + + new LPPermissionAttachment(LPPermissible.this, attachment).hook(); + return true; + } + + @Override + public boolean remove(Object o) { + removeAttachment((PermissionAttachment) o); + return true; + } + + @Override + public void clear() { + clearPermissions(); + } + + @Override + public boolean addAll(@Nonnull Collection c) { + boolean modified = false; + for (PermissionAttachment e : c) { + if (add(e)) { + modified = true; + } + } + return modified; + } + + @Override + public boolean contains(Object o) { + PermissionAttachment attachment = (PermissionAttachment) o; + return LPPermissible.this.lpAttachments.stream().anyMatch(at -> at.getSource() == attachment); + } + + @Override + public Iterator iterator() { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).iterator(); + } + + @Override + public ListIterator listIterator() { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).listIterator(); + } + + @Nonnull + @Override + public Object[] toArray() { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).toArray(); + } + + @Nonnull + @Override + public T[] toArray(@Nonnull T[] a) { + return ImmutableList.copyOf(LPPermissible.this.lpAttachments).toArray(a); + } + + @Override public int size() { throw new UnsupportedOperationException(); } + @Override public boolean isEmpty() { throw new UnsupportedOperationException(); } + @Override public boolean containsAll(@Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public boolean addAll(int index, @Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public boolean removeAll(@Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public boolean retainAll(@Nonnull Collection c) { throw new UnsupportedOperationException(); } + @Override public PermissionAttachment get(int index) { throw new UnsupportedOperationException(); } + @Override public PermissionAttachment set(int index, PermissionAttachment element) { throw new UnsupportedOperationException(); } + @Override public void add(int index, PermissionAttachment element) { throw new UnsupportedOperationException(); } + @Override public PermissionAttachment remove(int index) { throw new UnsupportedOperationException(); } + @Override public int indexOf(Object o) { throw new UnsupportedOperationException(); } + @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); } + @Nonnull @Override public ListIterator listIterator(int index) { throw new UnsupportedOperationException(); } + @Nonnull @Override public List subList(int fromIndex, int toIndex) { throw new UnsupportedOperationException(); } + } } diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissionAttachment.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissionAttachment.java index 6cf4b8ef..2182542d 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissionAttachment.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/LPPermissionAttachment.java @@ -96,6 +96,11 @@ public class LPPermissionAttachment extends PermissionAttachment { */ private PermissionRemovedExecutor removalCallback = null; + /** + * Delegate attachment + */ + private PermissionAttachment source; + public LPPermissionAttachment(LPPermissible permissible, Plugin owner) { super(DummyPlugin.INSTANCE, null); this.permissible = permissible; @@ -111,6 +116,7 @@ public class LPPermissionAttachment extends PermissionAttachment { // copy this.perms.putAll(nukkit.getPermissions()); + this.source = source; injectFakeMap(); } @@ -149,12 +155,16 @@ public class LPPermissionAttachment extends PermissionAttachment { this.removalCallback = removalCallback; } + PermissionAttachment getSource() { + return this.source; + } + /** * Hooks this attachment with the parent {@link User} instance. */ public void hook() { this.hooked = true; - this.permissible.attachments.add(this); + this.permissible.lpAttachments.add(this); for (Map.Entry entry : this.perms.entrySet()) { if (entry.getKey() == null || entry.getKey().isEmpty()) { continue; @@ -215,7 +225,7 @@ public class LPPermissionAttachment extends PermissionAttachment { // unhook from the permissible this.hooked = false; - this.permissible.attachments.remove(this); + this.permissible.lpAttachments.remove(this); } @Override diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/MonitoredPermissibleBase.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/MonitoredPermissibleBase.java index 6385d5a3..11a1fdc3 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/MonitoredPermissibleBase.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/model/permissible/MonitoredPermissibleBase.java @@ -58,7 +58,7 @@ public class MonitoredPermissibleBase extends PermissibleBase { public MonitoredPermissibleBase(LuckPermsPlugin plugin, PermissibleBase delegate, String name) { super(null); - DummyPermissibleBase.nullFields(this); + DummyPermissibleBase.copyFields(delegate, this); this.plugin = plugin; this.delegate = delegate; diff --git a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectProxy.java b/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectProxy.java index 91ad02ba..5f6bae14 100644 --- a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectProxy.java +++ b/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectProxy.java @@ -173,6 +173,11 @@ public final class SubjectProxy implements Subject, ProxiedSubject { return CompatibilityUtil.convertContexts(getContextsCache().getContextSet()); } + @Override + public ImmutableContextSet getActiveContextSet() { + return getContextsCache().getContextSet(); + } + @Override public boolean equals(Object o) { return o == this || o instanceof SubjectProxy && this.ref.equals(((SubjectProxy) o).ref); diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectProxy.java b/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectProxy.java index c08c7f15..9b192345 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectProxy.java +++ b/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectProxy.java @@ -174,6 +174,11 @@ public final class SubjectProxy implements Subject, ProxiedSubject { return CompatibilityUtil.convertContexts(getContextsCache().getContextSet()); } + @Override + public ImmutableContextSet getActiveContextSet() { + return getContextsCache().getContextSet(); + } + @Override public boolean equals(Object o) { return o == this || o instanceof SubjectProxy && this.ref.equals(((SubjectProxy) o).ref); diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedSubject.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedSubject.java index bb4bc9c4..ae8d50b9 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedSubject.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedSubject.java @@ -25,6 +25,8 @@ package me.lucko.luckperms.sponge.service.model; +import me.lucko.luckperms.api.context.ImmutableContextSet; + import org.spongepowered.api.service.permission.Subject; import javax.annotation.Nonnull; @@ -37,4 +39,6 @@ public interface ProxiedSubject { @Nonnull LPSubjectReference asSubjectReference(); + ImmutableContextSet getActiveContextSet(); + }