From ee79f53612addc11cc080492ced82a7561b6477c Mon Sep 17 00:00:00 2001 From: lucko Date: Mon, 7 Feb 2022 21:10:01 +0000 Subject: [PATCH] SpongeAPI 8 (#2728) --- .../bungee/context/BungeeContextManager.java | 18 +- .../luckperms/common/backup/Exporter.java | 3 +- .../luckperms/common/backup/Importer.java | 3 +- .../cacheddata/AbstractCachedDataManager.java | 3 +- .../context/manager/ContextManager.java | 28 ++- .../manager/InlineQueryOptionsSupplier.java | 45 ++++ .../manager/user/AbstractUserManager.java | 7 +- .../ReflectionClassPathAppender.java | 7 +- .../common/sender/AbstractSender.java | 2 +- .../common/util/CompletableFutures.java | 37 ++- settings.gradle | 2 +- sponge/build.gradle | 23 +- .../proxy/api6/DescriptionBuilder.java | 142 ------------ .../api6/PermissionDescriptionProxy.java | 89 -------- .../proxy/api6/PermissionServiceProxy.java | 121 ---------- .../proxy/api6/SubjectCollectionProxy.java | 128 ----------- .../service/proxy/api6/SubjectDataProxy.java | 211 ------------------ .../service/proxy/api6/SubjectProxy.java | 187 ---------------- sponge/sponge-service-api7/build.gradle | 15 -- .../build.gradle | 4 +- .../proxy/api8}/DescriptionBuilder.java | 35 ++- .../api8}/PermissionDescriptionProxy.java | 60 ++++- .../proxy/api8}/PermissionServiceProxy.java | 61 ++--- .../proxy/api8}/SubjectCollectionProxy.java | 39 ++-- .../service/proxy/api8}/SubjectDataProxy.java | 100 +++++++-- .../service/proxy/api8}/SubjectProxy.java | 105 ++++----- sponge/sponge-service/build.gradle | 4 +- .../service/PermissionAndContextService.java} | 13 +- .../model/LPPermissionDescription.java | 7 +- .../service/model/LPPermissionService.java | 24 +- ...bject.java => LPProxiedServiceObject.java} | 2 +- ...xiedSubject.java => LPProxiedSubject.java} | 2 +- .../sponge/service/model/LPSubject.java | 7 +- .../service/model/LPSubjectCollection.java | 3 +- .../sponge/service/model/LPSubjectUser.java} | 18 +- .../reference/CachedSubjectReference.java | 8 +- .../reference/SubjectReferenceFactory.java | 24 +- .../luckperms/sponge/LPSpongeBootstrap.java | 146 ++++++------ .../luckperms/sponge/LPSpongePlugin.java | 151 +++++++++---- .../sponge/SpongeClassPathAppender.java | 64 ++++++ .../sponge/SpongeCommandExecutor.java | 53 ++--- .../luckperms/sponge/SpongeEventBus.java | 8 +- .../sponge/SpongeSchedulerAdapter.java | 80 +++---- .../luckperms/sponge/SpongeSenderFactory.java | 71 +++--- .../luckperms/sponge/commands/ParentAdd.java | 4 +- .../sponge/commands/ParentRemove.java | 4 +- .../sponge/commands/SpongeCommandUtils.java | 4 +- .../sponge/context/SpongeContextManager.java | 69 ++++-- .../context/SpongePlayerCalculator.java | 108 ++++----- .../listeners/SpongeCommandListUpdater.java | 108 +++++++++ .../listeners/SpongeConnectionListener.java | 69 +++--- .../listeners/SpongePlatformListener.java | 15 +- .../messaging/PluginMessageMessenger.java | 58 ++--- .../model/manager/SpongeGroupManager.java | 3 +- .../model/manager/SpongeUserManager.java | 3 +- .../sponge/service/LuckPermsService.java | 43 +++- .../sponge/service/ProxyFactory.java | 49 ++-- .../service/model/ContextCalculatorProxy.java | 59 +++-- .../model/SimplePermissionDescription.java | 11 +- .../SubjectDataUpdateEventImpl.java} | 17 +- .../model/TemporaryCauseHolderSubject.java | 108 +++++++++ .../model/permissionholder/GroupSubject.java | 7 - .../PermissionHolderSubject.java | 15 +- .../PermissionHolderSubjectData.java | 8 +- .../model/permissionholder/UserSubject.java | 16 +- .../model/persisted/PersistedCollection.java | 3 +- .../model/persisted/PersistedSubject.java | 29 +-- .../model/persisted/SubjectDataContainer.java | 4 +- .../resources/META-INF/sponge_plugins.json | 31 +++ sponge/src/main/resources/luckperms.conf | 3 + 70 files changed, 1301 insertions(+), 1707 deletions(-) create mode 100644 common/src/main/java/me/lucko/luckperms/common/context/manager/InlineQueryOptionsSupplier.java rename sponge/src/main/java/me/lucko/luckperms/sponge/service/events/UpdateEventHandler.java => common/src/main/java/me/lucko/luckperms/common/util/CompletableFutures.java (52%) delete mode 100644 sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/DescriptionBuilder.java delete mode 100644 sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionDescriptionProxy.java delete mode 100644 sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionServiceProxy.java delete mode 100644 sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectCollectionProxy.java delete mode 100644 sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectDataProxy.java delete mode 100644 sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectProxy.java delete mode 100644 sponge/sponge-service-api7/build.gradle rename sponge/{sponge-service-api6 => sponge-service-api8}/build.gradle (70%) rename sponge/{sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7 => sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8}/DescriptionBuilder.java (81%) rename sponge/{sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7 => sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8}/PermissionDescriptionProxy.java (65%) rename sponge/{sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7 => sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8}/PermissionServiceProxy.java (72%) rename sponge/{sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7 => sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8}/SubjectCollectionProxy.java (79%) rename sponge/{sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7 => sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8}/SubjectDataProxy.java (68%) rename sponge/{sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7 => sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8}/SubjectProxy.java (55%) rename sponge/{sponge-service-api7/src/main/java/org/spongepowered/api/event/permission/SubjectDataUpdateEvent.java => sponge-service/src/main/java/me/lucko/luckperms/sponge/service/PermissionAndContextService.java} (76%) rename sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/{ProxiedServiceObject.java => LPProxiedServiceObject.java} (97%) rename sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/{ProxiedSubject.java => LPProxiedSubject.java} (95%) rename sponge/{sponge-service-api6/src/main/java/org/spongepowered/api/service/permission/SubjectReference.java => sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectUser.java} (76%) create mode 100644 sponge/src/main/java/me/lucko/luckperms/sponge/SpongeClassPathAppender.java create mode 100644 sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeCommandListUpdater.java rename sponge/src/main/java/me/lucko/luckperms/sponge/service/{events/LPSubjectDataUpdateEvent.java => model/SubjectDataUpdateEventImpl.java} (81%) create mode 100644 sponge/src/main/java/me/lucko/luckperms/sponge/service/model/TemporaryCauseHolderSubject.java create mode 100644 sponge/src/main/resources/META-INF/sponge_plugins.json diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/context/BungeeContextManager.java b/bungee/src/main/java/me/lucko/luckperms/bungee/context/BungeeContextManager.java index 73bf1112d..364ce3182 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/context/BungeeContextManager.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/context/BungeeContextManager.java @@ -29,6 +29,7 @@ import com.github.benmanes.caffeine.cache.LoadingCache; import me.lucko.luckperms.bungee.LPBungeePlugin; import me.lucko.luckperms.common.context.manager.ContextManager; +import me.lucko.luckperms.common.context.manager.InlineQueryOptionsSupplier; import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier; import me.lucko.luckperms.common.util.CaffeineFactory; @@ -60,9 +61,10 @@ public class BungeeContextManager extends ContextManager(subject, this.contextsCache); } + // override getContext, getQueryOptions and invalidateCache to skip the QueryOptionsSupplier @Override public ImmutableContextSet getContext(ProxiedPlayer subject) { return getQueryOptions(subject).context(); @@ -83,18 +85,4 @@ public class BungeeContextManager extends ContextManager cache; - - private InlineQueryOptionsSupplier(ProxiedPlayer key, LoadingCache cache) { - this.key = key; - this.cache = cache; - } - - @Override - public QueryOptions getQueryOptions() { - return this.cache.get(this.key); - } - } } diff --git a/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java b/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java index b326b7aa9..08b029bd2 100644 --- a/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java +++ b/common/src/main/java/me/lucko/luckperms/common/backup/Exporter.java @@ -38,6 +38,7 @@ import me.lucko.luckperms.common.node.utils.NodeJsonSerializer; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.storage.Storage; +import me.lucko.luckperms.common.util.CompletableFutures; import me.lucko.luckperms.common.util.gson.GsonProvider; import me.lucko.luckperms.common.util.gson.JArray; import me.lucko.luckperms.common.util.gson.JObject; @@ -193,7 +194,7 @@ public abstract class Exporter implements Runnable { } // all of the threads have been scheduled now and are running. we just need to wait for them all to complete - CompletableFuture overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + CompletableFuture overallFuture = CompletableFutures.allOf(futures); while (true) { try { diff --git a/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java b/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java index 26bfdd4d9..820604389 100644 --- a/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java +++ b/common/src/main/java/me/lucko/luckperms/common/backup/Importer.java @@ -39,6 +39,7 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.utils.NodeJsonSerializer; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.sender.Sender; +import me.lucko.luckperms.common.util.CompletableFutures; import me.lucko.luckperms.common.util.Uuids; import net.luckperms.api.event.cause.CreationCause; @@ -260,7 +261,7 @@ public class Importer implements Runnable { } // all of the threads have been scheduled now and are running. we just need to wait for them all to complete - CompletableFuture overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + CompletableFuture overallFuture = CompletableFutures.allOf(futures); this.notify.forEach(s -> Message.IMPORT_INFO.send(s, "All data entries have been processed and scheduled for import - now waiting for the execution to complete.")); diff --git a/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java b/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java index 930db77fe..b48a450bd 100644 --- a/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/cacheddata/AbstractCachedDataManager.java @@ -33,6 +33,7 @@ import me.lucko.luckperms.common.calculator.CalculatorFactory; import me.lucko.luckperms.common.calculator.PermissionCalculator; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.util.CaffeineFactory; +import me.lucko.luckperms.common.util.CompletableFutures; import net.luckperms.api.cacheddata.CachedData; import net.luckperms.api.cacheddata.CachedDataManager; @@ -241,7 +242,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager { @Override public @NonNull CompletableFuture reload() { Set keys = this.cache.keySet(); - return CompletableFuture.allOf(keys.stream().map(this::reload).toArray(CompletableFuture[]::new)); + return CompletableFutures.allOf(keys.stream().map(this::reload)); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/context/manager/ContextManager.java b/common/src/main/java/me/lucko/luckperms/common/context/manager/ContextManager.java index 4c82dcdd8..dbdfddfe1 100644 --- a/common/src/main/java/me/lucko/luckperms/common/context/manager/ContextManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/context/manager/ContextManager.java @@ -135,16 +135,28 @@ public abstract class ContextManager { this.calculators.remove(calculator); } + protected void callContextCalculator(ContextCalculator calculator, S subject, ContextConsumer consumer) { + try { + calculator.calculate(subject, consumer); + } catch (Throwable e) { + this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating the context of subject " + subject, e); + } + } + + protected void callStaticContextCalculator(StaticContextCalculator calculator, ContextConsumer consumer) { + try { + calculator.calculate(consumer); + } catch (Throwable e) { + this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating static contexts", e); + } + } + protected QueryOptions calculate(S subject) { ImmutableContextSet.Builder accumulator = new ImmutableContextSetImpl.BuilderImpl(); ContextConsumer consumer = accumulator::add; for (ContextCalculator calculator : this.calculators.calculators()) { - try { - calculator.calculate(subject, consumer); - } catch (Throwable e) { - this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating the context of subject " + subject, e); - } + callContextCalculator(calculator, subject, consumer); } return formQueryOptions(subject, accumulator.build()); @@ -155,11 +167,7 @@ public abstract class ContextManager { ContextConsumer consumer = accumulator::add; for (StaticContextCalculator calculator : this.calculators.staticCalculators()) { - try { - calculator.calculate(consumer); - } catch (Throwable e) { - this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating static contexts", e); - } + callStaticContextCalculator(calculator, consumer); } return formQueryOptions(accumulator.build()); diff --git a/common/src/main/java/me/lucko/luckperms/common/context/manager/InlineQueryOptionsSupplier.java b/common/src/main/java/me/lucko/luckperms/common/context/manager/InlineQueryOptionsSupplier.java new file mode 100644 index 000000000..798a1d772 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/context/manager/InlineQueryOptionsSupplier.java @@ -0,0 +1,45 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * 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.common.context.manager; + +import com.github.benmanes.caffeine.cache.LoadingCache; + +import net.luckperms.api.query.QueryOptions; + +public final class InlineQueryOptionsSupplier implements QueryOptionsSupplier { + private final T key; + private final LoadingCache cache; + + public InlineQueryOptionsSupplier(T key, LoadingCache cache) { + this.key = key; + this.cache = cache; + } + + @Override + public QueryOptions getQueryOptions() { + return this.cache.get(this.key); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java b/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java index 451fe11bb..bd3b4771e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/manager/user/AbstractUserManager.java @@ -32,6 +32,7 @@ import me.lucko.luckperms.common.model.manager.AbstractManager; import me.lucko.luckperms.common.model.manager.group.GroupManager; import me.lucko.luckperms.common.node.types.Inheritance; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.util.CompletableFutures; import me.lucko.luckperms.common.verbose.event.CheckOrigin; import net.luckperms.api.model.data.DataType; @@ -165,11 +166,9 @@ public abstract class AbstractUserManager extends AbstractManage Set ids = new HashSet<>(getAll().keySet()); ids.addAll(this.plugin.getBootstrap().getOnlinePlayers()); - CompletableFuture[] loadTasks = ids.stream() + return ids.stream() .map(id -> this.plugin.getStorage().loadUser(id, null)) - .toArray(CompletableFuture[]::new); - - return CompletableFuture.allOf(loadTasks); + .collect(CompletableFutures.collector()); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java index 11cdb8f97..c33aafb96 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java @@ -34,8 +34,7 @@ import java.nio.file.Path; public class ReflectionClassPathAppender implements ClassPathAppender { private final URLClassLoaderAccess classLoaderAccess; - public ReflectionClassPathAppender(LuckPermsBootstrap bootstrap) throws IllegalStateException { - ClassLoader classLoader = bootstrap.getClass().getClassLoader(); + public ReflectionClassPathAppender(ClassLoader classLoader) throws IllegalStateException { if (classLoader instanceof URLClassLoader) { this.classLoaderAccess = URLClassLoaderAccess.create((URLClassLoader) classLoader); } else { @@ -43,6 +42,10 @@ public class ReflectionClassPathAppender implements ClassPathAppender { } } + public ReflectionClassPathAppender(LuckPermsBootstrap bootstrap) throws IllegalStateException { + this(bootstrap.getClass().getClassLoader()); + } + @Override public void addJarToClasspath(Path file) { try { diff --git a/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java b/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java index 63e8601c6..1722722eb 100644 --- a/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java +++ b/common/src/main/java/me/lucko/luckperms/common/sender/AbstractSender.java @@ -130,7 +130,7 @@ public final class AbstractSender implements Sender { // A small utility method which splits components built using // > join(newLine(), components...) // back into separate components. - private static Iterable splitNewlines(Component message) { + public static Iterable splitNewlines(Component message) { if (message instanceof TextComponent && message.style().isEmpty() && !message.children().isEmpty() && ((TextComponent) message).content().isEmpty()) { LinkedList> split = new LinkedList<>(); split.add(new ArrayList<>()); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/events/UpdateEventHandler.java b/common/src/main/java/me/lucko/luckperms/common/util/CompletableFutures.java similarity index 52% rename from sponge/src/main/java/me/lucko/luckperms/sponge/service/events/UpdateEventHandler.java rename to common/src/main/java/me/lucko/luckperms/common/util/CompletableFutures.java index a2fc9e4b4..93244f82f 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/events/UpdateEventHandler.java +++ b/common/src/main/java/me/lucko/luckperms/common/util/CompletableFutures.java @@ -23,20 +23,35 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.events; +package me.lucko.luckperms.common.util; -import me.lucko.luckperms.sponge.LPSpongePlugin; -import me.lucko.luckperms.sponge.service.model.LPSubjectData; +import com.google.common.collect.ImmutableList; -import org.spongepowered.api.event.permission.SubjectDataUpdateEvent; +import java.util.Collection; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collector; +import java.util.stream.Stream; -public final class UpdateEventHandler { - private UpdateEventHandler() {} +public final class CompletableFutures { + private CompletableFutures() {} - public static void fireUpdateEvent(LPSpongePlugin plugin, LPSubjectData subjectData) { - plugin.getBootstrap().getScheduler().executeAsync(() -> { - SubjectDataUpdateEvent event = new LPSubjectDataUpdateEvent(plugin, subjectData); - plugin.getBootstrap().getGame().getEventManager().post(event); - }); + public static > Collector, CompletableFuture> collector() { + return Collector.of( + ImmutableList.Builder::new, + ImmutableList.Builder::add, + (l, r) -> l.addAll(r.build()), + builder -> allOf(builder.build()) + ); } + + public static CompletableFuture allOf(Stream> futures) { + CompletableFuture[] arr = futures.toArray(CompletableFuture[]::new); + return CompletableFuture.allOf(arr); + } + + public static CompletableFuture allOf(Collection> futures) { + CompletableFuture[] arr = futures.toArray(new CompletableFuture[0]); + return CompletableFuture.allOf(arr); + } + } diff --git a/settings.gradle b/settings.gradle index 37f938678..db3bdea62 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,6 +23,6 @@ include ( 'fabric', 'nukkit', 'nukkit:loader', - 'sponge', 'sponge:sponge-service', 'sponge:sponge-service-api6', 'sponge:sponge-service-api7', + 'sponge', 'sponge:sponge-service', 'sponge:sponge-service-api8', 'velocity' ) diff --git a/sponge/build.gradle b/sponge/build.gradle index 67038ca9f..275da4a33 100644 --- a/sponge/build.gradle +++ b/sponge/build.gradle @@ -1,25 +1,17 @@ plugins { - id 'net.kyori.blossom' version '1.3.0' id 'com.github.johnrengelman.shadow' version '7.0.0' } repositories { - maven { url 'https://repo.spongepowered.org/maven' } + maven { url 'https://repo.spongepowered.org/repository/maven-public/' } } dependencies { implementation project(':common') implementation project(':sponge:sponge-service') - implementation project(':sponge:sponge-service-api6') - implementation project(':sponge:sponge-service-api7') + implementation project(':sponge:sponge-service-api8') - compileOnly('org.spongepowered:spongeapi:7.3.0') { - exclude(module: 'configurate-core') - exclude(module: 'configurate-hocon') - exclude(module: 'configurate-gson') - exclude(module: 'configurate-yaml') - } - annotationProcessor('org.spongepowered:spongeapi:7.3.0') { + compileOnly('org.spongepowered:spongeapi:8.0.0') { exclude(module: 'configurate-core') exclude(module: 'configurate-hocon') exclude(module: 'configurate-gson') @@ -27,9 +19,10 @@ dependencies { } } -blossom { - replaceTokenIn('src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java') - replaceToken '@version@', project.ext.fullVersion +processResources { + filesMatching('META-INF/sponge_plugins.json') { + expand 'pluginVersion': project.ext.fullVersion + } } shadowJar { @@ -40,7 +33,7 @@ shadowJar { include(dependency('me.lucko.luckperms:.*')) } - relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure' + //relocate 'net.kyori.adventure', 'me.lucko.luckperms.lib.adventure' relocate 'net.kyori.event', 'me.lucko.luckperms.lib.eventbus' relocate 'com.github.benmanes.caffeine', 'me.lucko.luckperms.lib.caffeine' relocate 'okio', 'me.lucko.luckperms.lib.okio' diff --git a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/DescriptionBuilder.java b/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/DescriptionBuilder.java deleted file mode 100644 index f6d3bd583..000000000 --- a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/DescriptionBuilder.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * 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.sponge.service.proxy.api6; - -import me.lucko.luckperms.common.context.ImmutableContextSetImpl; -import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; -import me.lucko.luckperms.sponge.service.model.LPPermissionService; -import me.lucko.luckperms.sponge.service.model.LPSubject; -import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; - -import net.luckperms.api.util.Tristate; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.plugin.PluginContainer; -import org.spongepowered.api.service.permission.PermissionDescription; -import org.spongepowered.api.service.permission.PermissionService; -import org.spongepowered.api.text.Text; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -public final class DescriptionBuilder implements PermissionDescription.Builder, ProxiedServiceObject { - - public static LPPermissionDescription registerDescription(LPPermissionService service, PermissionDescription description) { - //noinspection ConstantConditions - if (description.getOwner() == null) { - return null; - } - return service.registerPermissionDescription(description.getId(), description.getDescription(), description.getOwner()); - } - - private final @NonNull LPPermissionService service; - private final @NonNull PluginContainer container; - private final @NonNull Map roles = new HashMap<>(); - private @Nullable String id = null; - private @Nullable Text description = null; - - public DescriptionBuilder(@NonNull LPPermissionService service, @NonNull PluginContainer container) { - this.service = Objects.requireNonNull(service, "service"); - this.container = Objects.requireNonNull(container, "container"); - } - - @Override - public PermissionDescription.@NonNull Builder id(@NonNull String id) { - this.id = Objects.requireNonNull(id, "id"); - return this; - } - - @Override - public PermissionDescription.@NonNull Builder description(@NonNull Text description) { - this.description = Objects.requireNonNull(description, "description"); - return this; - } - - @Override - public PermissionDescription.@NonNull Builder assign(@NonNull String role, boolean value) { - Objects.requireNonNull(role, "role"); - this.roles.put(role, Tristate.of(value)); - return this; - } - - @Override - public @NonNull PermissionDescription register() throws IllegalStateException { - if (this.id == null) { - throw new IllegalStateException("id cannot be null"); - } - - LPPermissionDescription description = this.service.registerPermissionDescription(this.id, this.description, this.container); - - // Set role-templates - LPSubjectCollection subjects = this.service.getCollection(PermissionService.SUBJECTS_ROLE_TEMPLATE); - for (Map.Entry assignment : this.roles.entrySet()) { - LPSubject roleSubject = subjects.loadSubject(assignment.getKey()).join(); - roleSubject.getTransientSubjectData().setPermission(ImmutableContextSetImpl.EMPTY, this.id, assignment.getValue()); - } - - // null stuff so this instance can be reused - this.roles.clear(); - this.id = null; - this.description = null; - - return description.sponge(); - } - - @Override - public boolean equals(Object o) { - if (o == this) return true; - if (!(o instanceof DescriptionBuilder)) return false; - final DescriptionBuilder other = (DescriptionBuilder) o; - - return this.container.equals(other.container) && - this.roles.equals(other.roles) && - Objects.equals(this.id, other.id) && - Objects.equals(this.description, other.description); - } - - @Override - public int hashCode() { - final int PRIME = 59; - int result = 1; - result = result * PRIME + this.container.hashCode(); - result = result * PRIME + this.roles.hashCode(); - result = result * PRIME + (this.id == null ? 43 : this.id.hashCode()); - result = result * PRIME + (this.description == null ? 43 : this.description.hashCode()); - return result; - } - - @Override - public String toString() { - return "SimpleDescriptionBuilder(" + - "container=" + this.container + ", " + - "roles=" + this.roles + ", " + - "id=" + this.id + ", " + - "description=" + this.description + ")"; - } -} diff --git a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionDescriptionProxy.java b/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionDescriptionProxy.java deleted file mode 100644 index e59f41c7d..000000000 --- a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionDescriptionProxy.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * 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.sponge.service.proxy.api6; - -import me.lucko.luckperms.common.util.ImmutableCollectors; -import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; -import me.lucko.luckperms.sponge.service.model.LPPermissionService; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.plugin.PluginContainer; -import org.spongepowered.api.service.permission.PermissionDescription; -import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.text.Text; - -import java.util.Map; - -public final class PermissionDescriptionProxy implements PermissionDescription, ProxiedServiceObject { - private final LPPermissionService service; - private final LPPermissionDescription handle; - - public PermissionDescriptionProxy(LPPermissionService service, LPPermissionDescription handle) { - this.service = service; - this.handle = handle; - } - - @Override - public @NonNull String getId() { - return this.handle.getId(); - } - - @Override - public @NonNull Text getDescription() { - return this.handle.getDescription().orElse(Text.EMPTY); - } - - @Override - public @NonNull PluginContainer getOwner() { - return this.handle.getOwner().orElseGet(() -> Sponge.getGame().getPluginManager().fromInstance(this.service.getPlugin()).orElseThrow(() -> new RuntimeException("Unable to get LuckPerms instance."))); - } - - @Override - public @NonNull Map getAssignedSubjects(@NonNull String s) { - return this.handle.getAssignedSubjects(s).entrySet().stream() - .collect(ImmutableCollectors.toMap( - e -> new SubjectProxy(this.service, e.getKey().toReference()), - Map.Entry::getValue - )); - } - - @Override - public boolean equals(Object o) { - return o == this || o instanceof PermissionDescriptionProxy && this.handle.equals(((PermissionDescriptionProxy) o).handle); - } - - @Override - public int hashCode() { - return this.handle.hashCode(); - } - - @Override - public String toString() { - return "luckperms.api6.PermissionDescriptionProxy(handle=" + this.handle + ")"; - } -} diff --git a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionServiceProxy.java b/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionServiceProxy.java deleted file mode 100644 index 18e278ec8..000000000 --- a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/PermissionServiceProxy.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * 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.sponge.service.proxy.api6; - -import me.lucko.luckperms.common.util.ImmutableCollectors; -import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; -import me.lucko.luckperms.sponge.service.model.LPPermissionService; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.plugin.PluginContainer; -import org.spongepowered.api.service.context.ContextCalculator; -import org.spongepowered.api.service.permission.PermissionDescription; -import org.spongepowered.api.service.permission.PermissionService; -import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.service.permission.SubjectCollection; - -import java.util.Collection; -import java.util.Map; -import java.util.Optional; - -public final class PermissionServiceProxy implements PermissionService, ProxiedServiceObject { - private final LPPermissionService handle; - - public PermissionServiceProxy(LPPermissionService handle) { - this.handle = handle; - } - - @Override - public @NonNull SubjectCollection getUserSubjects() { - return this.handle.getUserSubjects().sponge(); - } - - @Override - public @NonNull SubjectCollection getGroupSubjects() { - return this.handle.getGroupSubjects().sponge(); - } - - @Override - public @NonNull Subject getDefaults() { - return this.handle.getRootDefaults().sponge(); - } - - @Override - public @NonNull SubjectCollection getSubjects(@NonNull String s) { - return this.handle.getCollection(s).sponge(); - } - - @Override - public @NonNull Map getKnownSubjects() { - return this.handle.getLoadedCollections().entrySet().stream() - .collect(ImmutableCollectors.toMap( - Map.Entry::getKey, - e -> e.getValue().sponge() - )); - } - - @Override - public Optional newDescriptionBuilder(@NonNull Object o) { - Optional container = Sponge.getGame().getPluginManager().fromInstance(o); - if (!container.isPresent()) { - throw new IllegalArgumentException("Couldn't find a plugin container for " + o.getClass().getSimpleName()); - } - - return Optional.of(new DescriptionBuilder(this.handle, container.get())); - } - - @Override - public @NonNull Optional getDescription(@NonNull String s) { - return this.handle.getDescription(s).map(LPPermissionDescription::sponge); - } - - @Override - public @NonNull Collection getDescriptions() { - return this.handle.getDescriptions().stream().map(LPPermissionDescription::sponge).collect(ImmutableCollectors.toSet()); - } - - @Override - public void registerContextCalculator(@NonNull ContextCalculator contextCalculator) { - this.handle.registerContextCalculator(contextCalculator); - } - - @Override - public boolean equals(Object o) { - return o == this || o instanceof PermissionServiceProxy && this.handle.equals(((PermissionServiceProxy) o).handle); - } - - @Override - public int hashCode() { - return this.handle.hashCode(); - } - - @Override - public String toString() { - return "luckperms.api6.PermissionServiceProxy(handle=" + this.handle + ")"; - } -} diff --git a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectCollectionProxy.java b/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectCollectionProxy.java deleted file mode 100644 index b3133a715..000000000 --- a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectCollectionProxy.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * 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.sponge.service.proxy.api6; - -import me.lucko.luckperms.common.util.ImmutableCollectors; -import me.lucko.luckperms.sponge.service.CompatibilityUtil; -import me.lucko.luckperms.sponge.service.model.LPPermissionService; -import me.lucko.luckperms.sponge.service.model.LPSubject; -import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.service.context.Context; -import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.service.permission.SubjectCollection; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -@SuppressWarnings("unchecked") -public final class SubjectCollectionProxy implements SubjectCollection, ProxiedServiceObject { - private final LPPermissionService service; - private final LPSubjectCollection handle; - - public SubjectCollectionProxy(LPPermissionService service, LPSubjectCollection handle) { - this.service = service; - this.handle = handle; - } - - @Override - public @NonNull String getIdentifier() { - return this.handle.getIdentifier(); - } - - @Override - public @NonNull Subject get(@NonNull String s) { - // force load the subject. - // after this call, users will expect that the subject is loaded in memory. - return this.handle.loadSubject(s).thenApply(LPSubject::sponge).join(); - } - - @Override - public boolean hasRegistered(@NonNull String s) { - return this.handle.hasRegistered(s).join(); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull Iterable getAllSubjects() { - // this will lazily load all subjects. it will initially just get the identifiers of each subject, and will initialize dummy - // providers for those identifiers. when any methods against the dummy are called, the actual data will be loaded. - // this behaviour should be replaced when CompletableFutures are added to Sponge - return (List) this.handle.getAllIdentifiers() - .thenApply(ids -> ids.stream() - .map(s -> new SubjectProxy(this.service, this.service.getReferenceFactory().obtain(getIdentifier(), s))) - .collect(ImmutableCollectors.toList()) - ).join(); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull Map getAllWithPermission(@NonNull String s) { - // again, these methods will lazily load subjects. - return (Map) this.handle.getAllWithPermission(s) - .thenApply(map -> map.entrySet().stream() - .collect(ImmutableCollectors.toMap( - e -> new SubjectProxy(this.service, e.getKey()), - Map.Entry::getValue - )) - ).join(); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull Map getAllWithPermission(@NonNull Set set, @NonNull String s) { - return (Map) this.handle.getAllWithPermission(CompatibilityUtil.convertContexts(set), s) - .thenApply(map -> map.entrySet().stream() - .collect(ImmutableCollectors.toMap( - e -> new SubjectProxy(this.service, e.getKey()), - Map.Entry::getValue - )) - ).join(); - } - - @Override - public @NonNull Subject getDefaults() { - return this.handle.getDefaults().sponge(); - } - - @Override - public boolean equals(Object o) { - return o == this || o instanceof SubjectCollectionProxy && this.handle.equals(((SubjectCollectionProxy) o).handle); - } - - @Override - public int hashCode() { - return this.handle.hashCode(); - } - - @Override - public String toString() { - return "luckperms.api6.SubjectCollectionProxy(handle=" + this.handle + ")"; - } -} diff --git a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectDataProxy.java b/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectDataProxy.java deleted file mode 100644 index 4451b0531..000000000 --- a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectDataProxy.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * 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.sponge.service.proxy.api6; - -import me.lucko.luckperms.common.util.ImmutableCollectors; -import me.lucko.luckperms.sponge.service.CompatibilityUtil; -import me.lucko.luckperms.sponge.service.model.LPPermissionService; -import me.lucko.luckperms.sponge.service.model.LPSubject; -import me.lucko.luckperms.sponge.service.model.LPSubjectData; -import me.lucko.luckperms.sponge.service.model.LPSubjectReference; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.service.context.Context; -import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.service.permission.SubjectData; -import org.spongepowered.api.util.Tristate; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletableFuture; - -@SuppressWarnings("unchecked") -public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject { - private final LPPermissionService service; - private final LPSubjectReference ref; - private final boolean enduring; - - public SubjectDataProxy(LPPermissionService service, LPSubjectReference ref, boolean enduring) { - this.service = service; - this.ref = ref; - this.enduring = enduring; - } - - private CompletableFuture handle() { - return this.enduring ? - this.ref.resolveLp().thenApply(LPSubject::getSubjectData) : - this.ref.resolveLp().thenApply(LPSubject::getTransientSubjectData); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull Map, Map> getAllPermissions() { - return (Map) handle().thenApply(handle -> handle.getAllPermissions().entrySet().stream() - .collect(ImmutableCollectors.toMap( - e -> CompatibilityUtil.convertContexts(e.getKey()), - Map.Entry::getValue - ))).join(); - } - - @Override - public @NonNull Map getPermissions(@NonNull Set contexts) { - return handle().thenApply(handle -> handle.getPermissions(CompatibilityUtil.convertContexts(contexts))).join(); - } - - @Override - public boolean setPermission(@NonNull Set contexts, @NonNull String permission, @NonNull Tristate value) { - handle().thenCompose(handle -> handle.setPermission( - CompatibilityUtil.convertContexts(contexts), - permission, - CompatibilityUtil.convertTristate(value) - )); - return true; - } - - @Override - public boolean clearPermissions() { - handle().thenCompose(LPSubjectData::clearPermissions); - return true; - } - - @Override - public boolean clearPermissions(@NonNull Set contexts) { - handle().thenCompose(handle -> handle.clearPermissions(CompatibilityUtil.convertContexts(contexts))); - return true; - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull Map, List> getAllParents() { - return (Map) handle().thenApply(handle -> handle.getAllParents().entrySet().stream() - .collect(ImmutableCollectors.toMap( - e -> CompatibilityUtil.convertContexts(e.getKey()), - e -> e.getValue().stream() - .map(s -> new SubjectProxy(this.service, s)) - .collect(ImmutableCollectors.toList()) - ) - )).join(); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull List getParents(@NonNull Set contexts) { - return (List) handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts)).stream() - .map(s -> new SubjectProxy(this.service, s)) - .collect(ImmutableCollectors.toList())).join(); - } - - @Override - public boolean addParent(@NonNull Set contexts, @NonNull Subject parent) { - handle().thenCompose(handle -> handle.addParent( - CompatibilityUtil.convertContexts(contexts), - this.service.getReferenceFactory().obtain(parent) - )); - return true; - } - - @Override - public boolean removeParent(@NonNull Set contexts, @NonNull Subject parent) { - handle().thenCompose(handle -> handle.removeParent( - CompatibilityUtil.convertContexts(contexts), - this.service.getReferenceFactory().obtain(parent) - )); - return true; - } - - @Override - public boolean clearParents() { - handle().thenCompose(LPSubjectData::clearParents); - return true; - } - - @Override - public boolean clearParents(@NonNull Set contexts) { - handle().thenCompose(handle -> handle.clearParents(CompatibilityUtil.convertContexts(contexts))); - return true; - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull Map, Map> getAllOptions() { - return (Map) handle().thenApply(handle -> handle.getAllOptions().entrySet().stream() - .collect(ImmutableCollectors.toMap( - e -> CompatibilityUtil.convertContexts(e.getKey()), - Map.Entry::getValue - ))).join(); - } - - @Override - public @NonNull Map getOptions(@NonNull Set contexts) { - return handle().thenApply(handle -> handle.getOptions(CompatibilityUtil.convertContexts(contexts))).join(); - } - - @Override - public boolean setOption(@NonNull Set contexts, @NonNull String key, String value) { - if (value == null) { - handle().thenCompose(handle -> handle.unsetOption(CompatibilityUtil.convertContexts(contexts), key)); - } else { - handle().thenCompose(handle -> handle.setOption(CompatibilityUtil.convertContexts(contexts), key, value)); - } - return true; - } - - @Override - public boolean clearOptions(@NonNull Set contexts) { - handle().thenCompose(handle -> handle.clearOptions(CompatibilityUtil.convertContexts(contexts))); - return true; - } - - @Override - public boolean clearOptions() { - handle().thenCompose(LPSubjectData::clearOptions); - return true; - } - - @Override - public boolean equals(Object o) { - if (o == this) return true; - if (!(o instanceof SubjectDataProxy)) return false; - final SubjectDataProxy other = (SubjectDataProxy) o; - return this.ref.equals(other.ref) && this.enduring == other.enduring; - } - - @Override - public int hashCode() { - final int PRIME = 59; - int result = 1; - result = result * PRIME + this.ref.hashCode(); - result = result * PRIME + (this.enduring ? 79 : 97); - return result; - } - - @Override - public String toString() { - return "luckperms.api6.SubjectDataProxy(ref=" + this.ref + ", enduring=" + this.enduring + ")"; - } -} 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 deleted file mode 100644 index 237362660..000000000 --- a/sponge/sponge-service-api6/src/main/java/me/lucko/luckperms/sponge/service/proxy/api6/SubjectProxy.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * 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.sponge.service.proxy.api6; - -import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier; -import me.lucko.luckperms.common.util.ImmutableCollectors; -import me.lucko.luckperms.sponge.service.CompatibilityUtil; -import me.lucko.luckperms.sponge.service.model.LPPermissionService; -import me.lucko.luckperms.sponge.service.model.LPSubject; -import me.lucko.luckperms.sponge.service.model.LPSubjectReference; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; -import me.lucko.luckperms.sponge.service.model.ProxiedSubject; - -import net.luckperms.api.query.QueryOptions; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.service.context.Context; -import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.service.permission.SubjectCollection; -import org.spongepowered.api.service.permission.SubjectData; -import org.spongepowered.api.util.Tristate; - -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; - -@SuppressWarnings("unchecked") -public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServiceObject { - private final LPPermissionService service; - private final LPSubjectReference ref; - - private QueryOptionsSupplier queryOptionsSupplier = null; - - public SubjectProxy(LPPermissionService service, LPSubjectReference ref) { - this.service = service; - this.ref = ref; - } - - private CompletableFuture handle() { - return this.ref.resolveLp(); - } - - // lazy init - private QueryOptionsSupplier getContextsCache() { - if (this.queryOptionsSupplier == null) { - this.queryOptionsSupplier = this.service.getContextManager().getCacheFor(this); - } - return this.queryOptionsSupplier; - } - - @Override - public @NonNull LPSubjectReference asSubjectReference() { - return this.ref; - } - - @Override - public @NonNull QueryOptions getQueryOptions() { - return getContextsCache().getQueryOptions(); - } - - @Override - public @NonNull Optional getCommandSource() { - return handle().thenApply(LPSubject::getCommandSource).join(); - } - - @Override - public @NonNull SubjectCollection getContainingCollection() { - return this.service.getCollection(this.ref.getCollectionIdentifier()).sponge(); - } - - @Override - public SubjectData getSubjectData() { - return new SubjectDataProxy(this.service, this.ref, true); - } - - @Override - public SubjectData getTransientSubjectData() { - return new SubjectDataProxy(this.service, this.ref, false); - } - - @Override - public boolean hasPermission(@NonNull Set contexts, @NonNull String permission) { - return handle().thenApply(handle -> handle.getPermissionValue(CompatibilityUtil.convertContexts(contexts), permission).asBoolean()).join(); - } - - @Override - public boolean hasPermission(@NonNull String permission) { - return handle().thenApply(handle -> handle.getPermissionValue(getContextsCache().getContextSet(), permission).asBoolean()).join(); - } - - @Override - public @NonNull Tristate getPermissionValue(@NonNull Set contexts, @NonNull String permission) { - return handle().thenApply(handle -> CompatibilityUtil.convertTristate(handle.getPermissionValue(CompatibilityUtil.convertContexts(contexts), permission))).join(); - } - - @Override - public boolean isChildOf(@NonNull Subject parent) { - return handle().thenApply(handle -> handle.isChildOf( - getContextsCache().getContextSet(), - this.service.getReferenceFactory().obtain(parent) - )).join(); - } - - @Override - public boolean isChildOf(@NonNull Set contexts, @NonNull Subject parent) { - return handle().thenApply(handle -> handle.isChildOf( - CompatibilityUtil.convertContexts(contexts), - this.service.getReferenceFactory().obtain(parent) - )).join(); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull List getParents() { - return (List) handle().thenApply(handle -> handle.getParents(getContextsCache().getContextSet()).stream() - .map(s -> new SubjectProxy(this.service, s)) - .collect(ImmutableCollectors.toList())).join(); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull List getParents(@NonNull Set contexts) { - return (List) handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts)).stream() - .map(s -> new SubjectProxy(this.service, s)) - .collect(ImmutableCollectors.toList())).join(); - } - - @Override - public @NonNull Optional getOption(@NonNull Set contexts, @NonNull String key) { - return handle().thenApply(handle -> handle.getOption(CompatibilityUtil.convertContexts(contexts), key)).join(); - } - - @Override - public @NonNull Optional getOption(@NonNull String key) { - return handle().thenApply(handle -> handle.getOption(getContextsCache().getContextSet(), key)).join(); - } - - @Override - public String getIdentifier() { - return this.ref.getSubjectIdentifier(); - } - - @Override - public @NonNull Set getActiveContexts() { - return CompatibilityUtil.convertContexts(getContextsCache().getContextSet()); - } - - @Override - public boolean equals(Object o) { - return o == this || o instanceof SubjectProxy && this.ref.equals(((SubjectProxy) o).ref); - } - - @Override - public int hashCode() { - return this.ref.hashCode(); - } - - @Override - public String toString() { - return "luckperms.api6.SubjectProxy(ref=" + this.ref + ")"; - } -} diff --git a/sponge/sponge-service-api7/build.gradle b/sponge/sponge-service-api7/build.gradle deleted file mode 100644 index a3fab4305..000000000 --- a/sponge/sponge-service-api7/build.gradle +++ /dev/null @@ -1,15 +0,0 @@ -repositories { - maven { url 'https://repo.spongepowered.org/maven' } -} - -dependencies { - implementation project(':common') - implementation project(':sponge:sponge-service') - - compileOnly('org.spongepowered:spongeapi:7.3.0') { - exclude(module: 'configurate-core') - exclude(module: 'configurate-hocon') - exclude(module: 'configurate-gson') - exclude(module: 'configurate-yaml') - } -} diff --git a/sponge/sponge-service-api6/build.gradle b/sponge/sponge-service-api8/build.gradle similarity index 70% rename from sponge/sponge-service-api6/build.gradle rename to sponge/sponge-service-api8/build.gradle index d423d5f03..27b324b0c 100644 --- a/sponge/sponge-service-api6/build.gradle +++ b/sponge/sponge-service-api8/build.gradle @@ -1,12 +1,12 @@ repositories { - maven { url 'https://repo.spongepowered.org/maven' } + maven { url 'https://repo.spongepowered.org/repository/maven-public/' } } dependencies { implementation project(':common') implementation project(':sponge:sponge-service') - compileOnly('org.spongepowered:spongeapi:6.0.0') { + compileOnly('org.spongepowered:spongeapi:8.0.0') { exclude(module: 'configurate-core') exclude(module: 'configurate-hocon') exclude(module: 'configurate-gson') diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/DescriptionBuilder.java b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/DescriptionBuilder.java similarity index 81% rename from sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/DescriptionBuilder.java rename to sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/DescriptionBuilder.java index cccb156f9..072813bcf 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/DescriptionBuilder.java +++ b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/DescriptionBuilder.java @@ -23,42 +23,34 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.proxy.api7; +package me.lucko.luckperms.sponge.service.proxy.api8; import me.lucko.luckperms.common.context.ImmutableContextSetImpl; import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; import me.lucko.luckperms.sponge.service.model.LPPermissionService; +import me.lucko.luckperms.sponge.service.model.LPProxiedServiceObject; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; +import net.kyori.adventure.text.Component; import net.luckperms.api.util.Tristate; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.service.permission.PermissionDescription; import org.spongepowered.api.service.permission.PermissionService; -import org.spongepowered.api.text.Text; +import org.spongepowered.plugin.PluginContainer; import java.util.HashMap; import java.util.Map; import java.util.Objects; -public final class DescriptionBuilder implements PermissionDescription.Builder, ProxiedServiceObject { - - public static LPPermissionDescription registerDescription(LPPermissionService service, PermissionDescription description) { - if (!description.getOwner().isPresent()) { - return null; - } - return service.registerPermissionDescription(description.getId(), description.getDescription().orElse(null), description.getOwner().get()); - } - +public final class DescriptionBuilder implements PermissionDescription.Builder, LPProxiedServiceObject { private final @NonNull LPPermissionService service; private final @NonNull PluginContainer container; private final @NonNull Map roles = new HashMap<>(); private @Nullable String id = null; - private @Nullable Text description = null; + private @Nullable Component description = null; public DescriptionBuilder(LPPermissionService service, PluginContainer container) { this.service = Objects.requireNonNull(service, "service"); @@ -72,7 +64,7 @@ public final class DescriptionBuilder implements PermissionDescription.Builder, } @Override - public PermissionDescription.@NonNull Builder description(@Nullable Text description) { + public PermissionDescription.@NonNull Builder description(@Nullable Component description) { this.description = description; return this; } @@ -84,6 +76,11 @@ public final class DescriptionBuilder implements PermissionDescription.Builder, return this; } + @Override + public PermissionDescription.Builder defaultValue(org.spongepowered.api.util.Tristate defaultValue) { + throw new UnsupportedOperationException("LuckPerms does not support assigning a default value to permission descriptions"); + } + @Override public @NonNull PermissionDescription register() throws IllegalStateException { if (this.id == null) { @@ -121,13 +118,7 @@ public final class DescriptionBuilder implements PermissionDescription.Builder, @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - result = result * PRIME + this.container.hashCode(); - result = result * PRIME + this.roles.hashCode(); - result = result * PRIME + (this.id == null ? 43 : this.id.hashCode()); - result = result * PRIME + (this.description == null ? 43 : this.description.hashCode()); - return result; + return Objects.hash(this.container, this.roles, this.id, this.description); } @Override diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/PermissionDescriptionProxy.java b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/PermissionDescriptionProxy.java similarity index 65% rename from sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/PermissionDescriptionProxy.java rename to sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/PermissionDescriptionProxy.java index e9ea3fee7..9212a53df 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/PermissionDescriptionProxy.java +++ b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/PermissionDescriptionProxy.java @@ -23,25 +23,29 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.proxy.api7; +package me.lucko.luckperms.sponge.service.proxy.api8; import me.lucko.luckperms.common.util.ImmutableCollectors; import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; import me.lucko.luckperms.sponge.service.model.LPPermissionService; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; +import me.lucko.luckperms.sponge.service.model.LPProxiedServiceObject; + +import net.kyori.adventure.text.Component; import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.plugin.PluginContainer; +import org.spongepowered.api.ResourceKey; import org.spongepowered.api.service.permission.PermissionDescription; import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.SubjectReference; -import org.spongepowered.api.text.Text; +import org.spongepowered.api.util.Tristate; +import org.spongepowered.plugin.PluginContainer; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.CompletableFuture; -public final class PermissionDescriptionProxy implements PermissionDescription, ProxiedServiceObject { +public final class PermissionDescriptionProxy implements PermissionDescription, LPProxiedServiceObject { private final LPPermissionService service; private final LPPermissionDescription handle; @@ -51,22 +55,27 @@ public final class PermissionDescriptionProxy implements PermissionDescription, } @Override - public @NonNull String getId() { + public @NonNull String id() { return this.handle.getId(); } @Override - public @NonNull Optional getDescription() { + public @NonNull Optional description() { return this.handle.getDescription(); } @Override - public @NonNull Optional getOwner() { + public @NonNull Optional owner() { return this.handle.getOwner(); } @Override - public @NonNull Map getAssignedSubjects(@NonNull String s) { + public Tristate defaultValue() { + return Tristate.UNDEFINED; + } + + @Override + public @NonNull Map assignedSubjects(@NonNull String s) { return this.handle.getAssignedSubjects(s).entrySet().stream() .collect(ImmutableCollectors.toMap( e -> new SubjectProxy(this.service, e.getKey().toReference()), @@ -74,6 +83,37 @@ public final class PermissionDescriptionProxy implements PermissionDescription, )); } + @Override + public boolean query(Subject subj) { + return subj.hasPermission(this.handle.getId()); + } + + @Override + public boolean query(Subject subj, String parameter) { + Objects.requireNonNull(parameter, "parameter"); + return subj.hasPermission(this.handle.getId() + '.' + parameter); + } + + @Override + public boolean query(Subject subj, ResourceKey key) { + return query(subj, key.namespace() + '.' + key.value()); + } + + @Override + public boolean query(Subject subj, String... parameters) { + if (parameters.length == 0) { + return this.query(subj); + } else if (parameters.length == 1) { + return this.query(subj, parameters[0]); + } + + StringBuilder builder = new StringBuilder(this.handle.getId()); + for (String parameter : parameters) { + builder.append('.').append(parameter); + } + return subj.hasPermission(builder.toString()); + } + @Override @SuppressWarnings({"unchecked", "rawtypes"}) public @NonNull CompletableFuture> findAssignedSubjects(@NonNull String s) { @@ -92,6 +132,6 @@ public final class PermissionDescriptionProxy implements PermissionDescription, @Override public String toString() { - return "luckperms.api7.PermissionDescriptionProxy(handle=" + this.handle + ")"; + return "luckperms.api8.PermissionDescriptionProxy(handle=" + this.handle + ")"; } } diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/PermissionServiceProxy.java b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/PermissionServiceProxy.java similarity index 72% rename from sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/PermissionServiceProxy.java rename to sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/PermissionServiceProxy.java index dfca717a2..0c5648a62 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/PermissionServiceProxy.java +++ b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/PermissionServiceProxy.java @@ -23,25 +23,28 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.proxy.api7; +package me.lucko.luckperms.sponge.service.proxy.api8; import com.google.common.collect.ImmutableSet; import me.lucko.luckperms.common.util.ImmutableCollectors; +import me.lucko.luckperms.sponge.service.CompatibilityUtil; +import me.lucko.luckperms.sponge.service.PermissionAndContextService; import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; import me.lucko.luckperms.sponge.service.model.LPPermissionService; +import me.lucko.luckperms.sponge.service.model.LPProxiedServiceObject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.plugin.PluginContainer; +import org.spongepowered.api.event.Cause; +import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.ContextCalculator; import org.spongepowered.api.service.permission.PermissionDescription; import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.SubjectCollection; import org.spongepowered.api.service.permission.SubjectReference; +import org.spongepowered.plugin.PluginContainer; import java.util.Collection; import java.util.Locale; @@ -52,7 +55,7 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; -public final class PermissionServiceProxy implements PermissionService, ProxiedServiceObject { +public final class PermissionServiceProxy implements PermissionAndContextService, LPProxiedServiceObject { private final LPPermissionService handle; public PermissionServiceProxy(LPPermissionService handle) { @@ -60,22 +63,22 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS } @Override - public @NonNull SubjectCollection getUserSubjects() { + public @NonNull SubjectCollection userSubjects() { return this.handle.getUserSubjects().sponge(); } @Override - public @NonNull SubjectCollection getGroupSubjects() { + public @NonNull SubjectCollection groupSubjects() { return this.handle.getGroupSubjects().sponge(); } @Override - public @NonNull Subject getDefaults() { + public @NonNull Subject defaults() { return this.handle.getRootDefaults().sponge(); } @Override - public @NonNull Predicate getIdentifierValidityPredicate() { + public @NonNull Predicate identifierValidityPredicate() { return this.handle.getIdentifierValidityPredicate(); } @@ -85,7 +88,7 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS } @Override - public @NonNull Optional getCollection(String s) { + public @NonNull Optional collection(String s) { return Optional.ofNullable(this.handle.getLoadedCollections().get(s.toLowerCase(Locale.ROOT))).map(LPSubjectCollection::sponge); } @@ -95,7 +98,7 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS } @Override - public @NonNull Map getLoadedCollections() { + public @NonNull Map loadedCollections() { return this.handle.getLoadedCollections().entrySet().stream() .collect(ImmutableCollectors.toMap( Map.Entry::getKey, @@ -104,7 +107,7 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS } @Override - public CompletableFuture> getAllIdentifiers() { + public CompletableFuture> allIdentifiers() { return CompletableFuture.completedFuture(ImmutableSet.copyOf(this.handle.getLoadedCollections().keySet())); } @@ -114,10 +117,11 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS Objects.requireNonNull(subjectIdentifier, "subjectIdentifier"); // test the identifiers - String collection = collectionIdentifier.toLowerCase(Locale.ROOT); - if (collection.equals("user") && !this.handle.getUserSubjects().getIdentifierValidityPredicate().test(subjectIdentifier)) { + if (collectionIdentifier.equalsIgnoreCase(PermissionService.SUBJECTS_USER) && + !this.handle.getUserSubjects().getIdentifierValidityPredicate().test(subjectIdentifier)) { throw new IllegalArgumentException("Subject identifier '" + subjectIdentifier + "' does not pass the validity predicate for the user subject collection"); - } else if (collection.equals("group") && !this.handle.getGroupSubjects().getIdentifierValidityPredicate().test(subjectIdentifier)) { + } else if (collectionIdentifier.equalsIgnoreCase(PermissionService.SUBJECTS_GROUP) && + !this.handle.getGroupSubjects().getIdentifierValidityPredicate().test(subjectIdentifier)) { throw new IllegalArgumentException("Subject identifier '" + subjectIdentifier + "' does not pass the validity predicate for the group subject collection"); } @@ -126,27 +130,32 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS } @Override - public PermissionDescription.Builder newDescriptionBuilder(@NonNull Object o) { - Optional container = Sponge.getGame().getPluginManager().fromInstance(o); - if (!container.isPresent()) { - throw new IllegalArgumentException("Couldn't find a plugin container for " + o.getClass().getSimpleName()); - } - - return new DescriptionBuilder(this.handle, container.get()); + public PermissionDescription.Builder newDescriptionBuilder(@NonNull PluginContainer container) { + return new DescriptionBuilder(this.handle, container); } @Override - public @NonNull Optional getDescription(@NonNull String s) { + public @NonNull Optional description(@NonNull String s) { return this.handle.getDescription(s).map(LPPermissionDescription::sponge); } @Override - public @NonNull Collection getDescriptions() { + public @NonNull Collection descriptions() { return this.handle.getDescriptions().stream().map(LPPermissionDescription::sponge).collect(ImmutableCollectors.toSet()); } @Override - public void registerContextCalculator(@NonNull ContextCalculator contextCalculator) { + public Set contexts() { + return CompatibilityUtil.convertContexts(this.handle.getContextsForCurrentCause()); + } + + @Override + public Set contextsFor(Cause cause) { + return CompatibilityUtil.convertContexts(this.handle.getContextsForCurrentCause()); + } + + @Override + public void registerContextCalculator(@NonNull ContextCalculator contextCalculator) { this.handle.registerContextCalculator(contextCalculator); } @@ -162,6 +171,6 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS @Override public String toString() { - return "luckperms.api7.PermissionServiceProxy(handle=" + this.handle + ")"; + return "luckperms.api8.PermissionServiceProxy(handle=" + this.handle + ")"; } } diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectCollectionProxy.java b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectCollectionProxy.java similarity index 79% rename from sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectCollectionProxy.java rename to sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectCollectionProxy.java index fe66e8df7..e054193ab 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectCollectionProxy.java +++ b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectCollectionProxy.java @@ -23,16 +23,15 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.proxy.api7; +package me.lucko.luckperms.sponge.service.proxy.api8; import me.lucko.luckperms.common.util.ImmutableCollectors; -import me.lucko.luckperms.sponge.service.CompatibilityUtil; +import me.lucko.luckperms.sponge.service.model.LPProxiedServiceObject; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.service.context.Context; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.SubjectCollection; import org.spongepowered.api.service.permission.SubjectReference; @@ -46,7 +45,7 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; @SuppressWarnings("unchecked") -public final class SubjectCollectionProxy implements SubjectCollection, ProxiedServiceObject { +public final class SubjectCollectionProxy implements SubjectCollection, LPProxiedServiceObject { private final LPSubjectCollection handle; public SubjectCollectionProxy(LPSubjectCollection handle) { @@ -54,12 +53,12 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS } @Override - public @NonNull String getIdentifier() { + public @NonNull String identifier() { return this.handle.getIdentifier(); } @Override - public @NonNull Predicate getIdentifierValidityPredicate() { + public @NonNull Predicate identifierValidityPredicate() { return this.handle.getIdentifierValidityPredicate(); } @@ -69,7 +68,7 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS } @Override - public @NonNull Optional getSubject(@NonNull String s) { + public @NonNull Optional subject(@NonNull String s) { return this.handle.getSubject(s).map(LPSubject::sponge); } @@ -79,18 +78,18 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS } @Override - public @NonNull CompletableFuture> loadSubjects(@NonNull Set set) { + public @NonNull CompletableFuture> loadSubjects(@NonNull Iterable set) { return this.handle.loadSubjects(set).thenApply(subs -> subs.stream().collect(ImmutableCollectors.toMap(lpSubject -> lpSubject.getIdentifier().getName(), LPSubject::sponge))); } @Override - public @NonNull Collection getLoadedSubjects() { + public @NonNull Collection loadedSubjects() { return this.handle.getLoadedSubjects().stream().map(LPSubject::sponge).collect(ImmutableCollectors.toSet()); } @SuppressWarnings("rawtypes") @Override - public @NonNull CompletableFuture> getAllIdentifiers() { + public @NonNull CompletableFuture> allIdentifiers() { return (CompletableFuture) this.handle.getAllIdentifiers(); } @@ -101,23 +100,23 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS throw new IllegalArgumentException("Subject identifier '" + subjectIdentifier + "' does not pass the validity predicate"); } - return this.handle.getService().getReferenceFactory().obtain(getIdentifier(), subjectIdentifier); + return this.handle.getService().getReferenceFactory().obtain(identifier(), subjectIdentifier); } @SuppressWarnings("rawtypes") @Override - public @NonNull CompletableFuture> getAllWithPermission(@NonNull String s) { + public @NonNull CompletableFuture> allWithPermission(@NonNull String s) { return (CompletableFuture) this.handle.getAllWithPermission(s); } @SuppressWarnings("rawtypes") @Override - public @NonNull CompletableFuture> getAllWithPermission(@NonNull Set set, @NonNull String s) { - return (CompletableFuture) this.handle.getAllWithPermission(CompatibilityUtil.convertContexts(set), s); + public @NonNull CompletableFuture> allWithPermission(@NonNull String s, @NonNull Cause cause) { + return (CompletableFuture) this.handle.getAllWithPermission(this.handle.getService().getContextsForCause(cause), s); } @Override - public @NonNull Map getLoadedWithPermission(@NonNull String s) { + public @NonNull Map loadedWithPermission(@NonNull String s) { return this.handle.getLoadedWithPermission(s).entrySet().stream() .collect(ImmutableCollectors.toMap( sub -> sub.getKey().sponge(), @@ -126,8 +125,8 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS } @Override - public @NonNull Map getLoadedWithPermission(@NonNull Set set, @NonNull String s) { - return this.handle.getLoadedWithPermission(CompatibilityUtil.convertContexts(set), s).entrySet().stream() + public @NonNull Map loadedWithPermission(@NonNull String s, @NonNull Cause cause) { + return this.handle.getLoadedWithPermission(this.handle.getService().getContextsForCause(cause), s).entrySet().stream() .collect(ImmutableCollectors.toMap( sub -> sub.getKey().sponge(), Map.Entry::getValue @@ -135,7 +134,7 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS } @Override - public @NonNull Subject getDefaults() { + public @NonNull Subject defaults() { return this.handle.getDefaults().sponge(); } @@ -156,7 +155,7 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS @Override public String toString() { - return "luckperms.api7.SubjectCollectionProxy(handle=" + this.handle + ")"; + return "luckperms.api8.SubjectCollectionProxy(handle=" + this.handle + ")"; } } diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectDataProxy.java b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectDataProxy.java similarity index 68% rename from sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectDataProxy.java rename to sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectDataProxy.java index 588454ab9..a9e1d21dc 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectDataProxy.java +++ b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectDataProxy.java @@ -23,29 +23,36 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.proxy.api7; +package me.lucko.luckperms.sponge.service.proxy.api8; +import com.google.common.collect.ImmutableMap; + +import me.lucko.luckperms.common.util.CompletableFutures; import me.lucko.luckperms.common.util.ImmutableCollectors; import me.lucko.luckperms.sponge.service.CompatibilityUtil; import me.lucko.luckperms.sponge.service.model.LPPermissionService; +import me.lucko.luckperms.sponge.service.model.LPProxiedServiceObject; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectData; import me.lucko.luckperms.sponge.service.model.LPSubjectReference; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.service.context.Context; +import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.SubjectData; +import org.spongepowered.api.service.permission.SubjectReference; +import org.spongepowered.api.service.permission.TransferMethod; import org.spongepowered.api.util.Tristate; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; @SuppressWarnings("unchecked") -public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject { +public final class SubjectDataProxy implements SubjectData, LPProxiedServiceObject { private final LPPermissionService service; private final LPSubjectReference ref; private final boolean enduring; @@ -62,9 +69,19 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject this.ref.resolveLp().thenApply(LPSubject::getTransientSubjectData); } + @Override + public Subject subject() { + return handle().thenApply(handle -> handle.getParentSubject().sponge()).join(); + } + + @Override + public boolean isTransient() { + return !this.enduring; + } + @SuppressWarnings("rawtypes") @Override - public @NonNull Map, Map> getAllPermissions() { + public @NonNull Map, Map> allPermissions() { return (Map) handle().thenApply(handle -> handle.getAllPermissions().entrySet().stream() .collect(ImmutableCollectors.toMap( e -> CompatibilityUtil.convertContexts(e.getKey()), @@ -73,7 +90,7 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject } @Override - public @NonNull Map getPermissions(@NonNull Set contexts) { + public @NonNull Map permissions(@NonNull Set contexts) { return handle().thenApply(handle -> handle.getPermissions(CompatibilityUtil.convertContexts(contexts))).join(); } @@ -86,6 +103,43 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject )); } + @Override + public CompletableFuture setPermissions(Set contexts, Map permissions, TransferMethod method) { + CompletableFuture fut; + if (method == TransferMethod.OVERWRITE) { + fut = clearPermissions(contexts); + } else { + fut = CompletableFuture.completedFuture(true); + } + + return fut.thenCompose(bool -> permissions.entrySet().stream() + .map(entry -> setPermission(contexts, entry.getKey(), Tristate.fromBoolean(entry.getValue()))) + .collect(CompletableFutures.collector()) + ) + .thenApply(x -> true); + } + + @Override + public Tristate fallbackPermissionValue(Set contexts) { + // TODO: check subject type here to return a more appropriate value? + return Tristate.UNDEFINED; + } + + @Override + public Map, Tristate> allFallbackPermissionValues() { + return ImmutableMap.of(); + } + + @Override + public CompletableFuture setFallbackPermissionValue(Set contexts, Tristate fallback) { + throw new UnsupportedOperationException("LuckPerms does not support setting fallback permission values"); + } + + @Override + public CompletableFuture clearFallbackPermissionValues() { + return CompletableFuture.completedFuture(true); + } + @Override public @NonNull CompletableFuture clearPermissions() { return handle().thenCompose(LPSubjectData::clearPermissions); @@ -98,7 +152,7 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject @SuppressWarnings("rawtypes") @Override - public @NonNull Map, List> getAllParents() { + public @NonNull Map, List> allParents() { return (Map) handle().thenApply(handle -> handle.getAllParents().entrySet().stream() .collect(ImmutableCollectors.toMap( e -> CompatibilityUtil.convertContexts(e.getKey()), @@ -108,10 +162,15 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject @SuppressWarnings("rawtypes") @Override - public @NonNull List getParents(@NonNull Set contexts) { + public @NonNull List parents(@NonNull Set contexts) { return (List) handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts))).join(); } + @Override + public CompletableFuture setParents(Set contexts, List parents, TransferMethod method) { + return null; + } + @Override public @NonNull CompletableFuture addParent(@NonNull Set contexts, org.spongepowered.api.service.permission.@NonNull SubjectReference ref) { return handle().thenCompose(handle -> handle.addParent(CompatibilityUtil.convertContexts(contexts), this.service.getReferenceFactory().obtain(ref))); @@ -134,7 +193,7 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject @SuppressWarnings("rawtypes") @Override - public @NonNull Map, Map> getAllOptions() { + public @NonNull Map, Map> allOptions() { return (Map) handle().thenApply(handle -> handle.getAllOptions().entrySet().stream() .collect(ImmutableCollectors.toMap( e -> CompatibilityUtil.convertContexts(e.getKey()), @@ -143,7 +202,7 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject } @Override - public @NonNull Map getOptions(@NonNull Set contexts) { + public @NonNull Map options(@NonNull Set contexts) { return handle().thenApply(handle -> handle.getOptions(CompatibilityUtil.convertContexts(contexts))).join(); } @@ -156,6 +215,11 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject } } + @Override + public CompletableFuture setOptions(Set contexts, Map options, TransferMethod method) { + return null; + } + @Override public @NonNull CompletableFuture clearOptions() { return handle().thenCompose(LPSubjectData::clearOptions); @@ -166,6 +230,16 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject return handle().thenCompose(handle -> handle.clearOptions(CompatibilityUtil.convertContexts(contexts))); } + @Override + public CompletableFuture copyFrom(SubjectData other, TransferMethod method) { + return null; + } + + @Override + public CompletableFuture moveFrom(SubjectData other, TransferMethod method) { + return null; + } + @Override public boolean equals(Object o) { if (o == this) return true; @@ -176,15 +250,11 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject @Override public int hashCode() { - final int PRIME = 59; - int result = 1; - result = result * PRIME + this.ref.hashCode(); - result = result * PRIME + (this.enduring ? 79 : 97); - return result; + return Objects.hash(this.ref, this.enduring); } @Override public String toString() { - return "luckperms.api7.SubjectDataProxy(ref=" + this.ref + ", enduring=" + this.enduring + ")"; + return "luckperms.api8.SubjectDataProxy(ref=" + this.ref + ", enduring=" + this.enduring + ")"; } } diff --git a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectProxy.java b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectProxy.java similarity index 55% rename from sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectProxy.java rename to sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectProxy.java index e8492738c..f80280e2e 100644 --- a/sponge/sponge-service-api7/src/main/java/me/lucko/luckperms/sponge/service/proxy/api7/SubjectProxy.java +++ b/sponge/sponge-service-api8/src/main/java/me/lucko/luckperms/sponge/service/proxy/api8/SubjectProxy.java @@ -23,21 +23,23 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.proxy.api7; +package me.lucko.luckperms.sponge.service.proxy.api8; -import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier; import me.lucko.luckperms.sponge.service.CompatibilityUtil; import me.lucko.luckperms.sponge.service.model.LPPermissionService; +import me.lucko.luckperms.sponge.service.model.LPProxiedServiceObject; +import me.lucko.luckperms.sponge.service.model.LPProxiedSubject; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectReference; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; -import me.lucko.luckperms.sponge.service.model.ProxiedSubject; +import me.lucko.luckperms.sponge.service.model.LPSubjectUser; import net.luckperms.api.query.QueryOptions; import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.service.context.Context; +import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.SubjectCollection; import org.spongepowered.api.service.permission.SubjectData; @@ -50,12 +52,10 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; @SuppressWarnings("unchecked") -public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServiceObject { +public final class SubjectProxy implements Subject, LPProxiedSubject, LPProxiedServiceObject { private final LPPermissionService service; private final LPSubjectReference ref; - private QueryOptionsSupplier queryOptionsSupplier; - public SubjectProxy(LPPermissionService service, LPSubjectReference ref) { this.service = service; this.ref = ref; @@ -65,14 +65,6 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi return this.ref.resolveLp(); } - // lazy init - private QueryOptionsSupplier queryOptionsCache() { - if (this.queryOptionsSupplier == null) { - this.queryOptionsSupplier = this.service.getContextManager().getCacheFor(this); - } - return this.queryOptionsSupplier; - } - @Override public @NonNull LPSubjectReference asSubjectReference() { return this.ref; @@ -80,17 +72,12 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi @Override public @NonNull QueryOptions getQueryOptions() { - return queryOptionsCache().getQueryOptions(); + return this.service.getContextManager().getQueryOptions(this); } @Override - public @NonNull Optional getCommandSource() { - return handle().thenApply(LPSubject::getCommandSource).join(); - } - - @Override - public @NonNull SubjectCollection getContainingCollection() { - return this.service.getCollection(this.ref.getCollectionIdentifier()).sponge(); + public @NonNull SubjectCollection containingCollection() { + return this.service.getCollection(this.ref.collectionIdentifier()).sponge(); } @Override @@ -99,75 +86,77 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi } @Override - public SubjectData getSubjectData() { + public SubjectData subjectData() { return new SubjectDataProxy(this.service, this.ref, true); } @Override - public SubjectData getTransientSubjectData() { + public SubjectData transientSubjectData() { return new SubjectDataProxy(this.service, this.ref, false); } @Override - public boolean hasPermission(@NonNull Set contexts, @NonNull String permission) { - return handle().thenApply(handle -> handle.getPermissionValue(CompatibilityUtil.convertContexts(contexts), permission).asBoolean()).join(); + public @NonNull Tristate permissionValue(@NonNull String permission, @NonNull Cause cause) { + return handle().thenApply(handle -> CompatibilityUtil.convertTristate(handle.getPermissionValue(this.service.getContextsForCause(cause), permission))).join(); } @Override - public boolean hasPermission(@NonNull String permission) { - return handle().thenApply(handle -> handle.getPermissionValue(queryOptionsCache().getContextSet(), permission).asBoolean()).join(); - } - - @Override - public @NonNull Tristate getPermissionValue(@NonNull Set contexts, @NonNull String permission) { + public @NonNull Tristate permissionValue(@NonNull String permission, @NonNull Set contexts) { return handle().thenApply(handle -> CompatibilityUtil.convertTristate(handle.getPermissionValue(CompatibilityUtil.convertContexts(contexts), permission))).join(); } @Override - public boolean isChildOf(@NonNull SubjectReference parent) { - return handle().thenApply(handle -> handle.isChildOf(queryOptionsCache().getContextSet(), this.service.getReferenceFactory().obtain(parent))).join(); + public boolean isChildOf(@NonNull SubjectReference parent, @NonNull Cause cause) { + return handle().thenApply(handle -> handle.isChildOf(this.service.getContextsForCause(cause), this.service.getReferenceFactory().obtain(parent))).join(); } @Override - public boolean isChildOf(@NonNull Set contexts, @NonNull SubjectReference parent) { + public boolean isChildOf(@NonNull SubjectReference parent, @NonNull Set contexts) { return handle().thenApply(handle -> handle.isChildOf(CompatibilityUtil.convertContexts(contexts), this.service.getReferenceFactory().obtain(parent))).join(); } - @SuppressWarnings("rawtypes") @Override - public @NonNull List getParents() { - return (List) handle().thenApply(handle -> handle.getParents(queryOptionsCache().getContextSet())).join(); - } - - @SuppressWarnings("rawtypes") - @Override - public @NonNull List getParents(@NonNull Set contexts) { - return (List) handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts))).join(); + public List parents(@NonNull Cause cause) { + return handle().thenApply(handle -> handle.getParents(this.service.getContextsForCause(cause))).join(); } @Override - public @NonNull Optional getOption(@NonNull Set contexts, @NonNull String key) { + public @NonNull List parents(@NonNull Set contexts) { + return handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts))).join(); + } + + @Override + public Optional option(@NonNull String key, @NonNull Cause cause) { + return handle().thenApply(handle -> handle.getOption(this.service.getContextsForCause(cause), key)).join(); + } + + @Override + public @NonNull Optional option(@NonNull String key, @NonNull Set contexts) { return handle().thenApply(handle -> handle.getOption(CompatibilityUtil.convertContexts(contexts), key)).join(); } @Override - public @NonNull Optional getOption(@NonNull String key) { - return handle().thenApply(handle -> handle.getOption(queryOptionsCache().getContextSet(), key)).join(); + public String identifier() { + return this.ref.subjectIdentifier(); } @Override - public String getIdentifier() { - return this.ref.getSubjectIdentifier(); - } - - @Override - public @NonNull Optional getFriendlyIdentifier() { + public @NonNull Optional friendlyIdentifier() { return handle().thenApply(LPSubject::getFriendlyIdentifier).join(); } @Override - public @NonNull Set getActiveContexts() { - return CompatibilityUtil.convertContexts(queryOptionsCache().getContextSet()); + public Optional associatedObject() { + if (this.ref.collectionIdentifier().equals(PermissionService.SUBJECTS_USER)) { + LPSubject lpSubject = handle().join(); + if (lpSubject instanceof LPSubjectUser) { + ServerPlayer player = ((LPSubjectUser) lpSubject).resolvePlayer().orElse(null); + if (player != null) { + return Optional.of(player); + } + } + } + return Optional.empty(); } @Override @@ -182,6 +171,6 @@ public final class SubjectProxy implements Subject, ProxiedSubject, ProxiedServi @Override public String toString() { - return "luckperms.api7.SubjectProxy(ref=" + this.ref + ")"; + return "luckperms.api8.SubjectProxy(ref=" + this.ref + ")"; } } diff --git a/sponge/sponge-service/build.gradle b/sponge/sponge-service/build.gradle index 88c3f2e04..4557ad3d6 100644 --- a/sponge/sponge-service/build.gradle +++ b/sponge/sponge-service/build.gradle @@ -1,11 +1,11 @@ repositories { - maven { url 'https://repo.spongepowered.org/maven' } + maven { url 'https://repo.spongepowered.org/repository/maven-public/' } } dependencies { implementation project(':common') - compileOnly('org.spongepowered:spongeapi:7.2.0') { + compileOnly('org.spongepowered:spongeapi:8.0.0') { exclude(module: 'configurate-core') exclude(module: 'configurate-hocon') exclude(module: 'configurate-gson') diff --git a/sponge/sponge-service-api7/src/main/java/org/spongepowered/api/event/permission/SubjectDataUpdateEvent.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/PermissionAndContextService.java similarity index 76% rename from sponge/sponge-service-api7/src/main/java/org/spongepowered/api/event/permission/SubjectDataUpdateEvent.java rename to sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/PermissionAndContextService.java index 987acaeb3..d567e9bc8 100644 --- a/sponge/sponge-service-api7/src/main/java/org/spongepowered/api/event/permission/SubjectDataUpdateEvent.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/PermissionAndContextService.java @@ -23,14 +23,11 @@ * SOFTWARE. */ -package org.spongepowered.api.event.permission; +package me.lucko.luckperms.sponge.service; -import org.spongepowered.api.event.Event; -import org.spongepowered.api.service.permission.SubjectData; +import org.spongepowered.api.service.context.ContextService; +import org.spongepowered.api.service.permission.PermissionService; -// Copy of https://github.com/SpongePowered/SpongeAPI/blob/api-8/src/main/java/org/spongepowered/api/event/permission/SubjectDataUpdateEvent.java -public interface SubjectDataUpdateEvent extends Event { +public interface PermissionAndContextService extends PermissionService, ContextService { - SubjectData getUpdatedData(); - -} \ No newline at end of file +} diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionDescription.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionDescription.java index 72de947ad..24b0b39fa 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionDescription.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionDescription.java @@ -25,9 +25,10 @@ package me.lucko.luckperms.sponge.service.model; -import org.spongepowered.api.plugin.PluginContainer; +import net.kyori.adventure.text.Component; + import org.spongepowered.api.service.permission.PermissionDescription; -import org.spongepowered.api.text.Text; +import org.spongepowered.plugin.PluginContainer; import java.util.Map; import java.util.Optional; @@ -44,7 +45,7 @@ public interface LPPermissionDescription { String getId(); - Optional getDescription(); + Optional getDescription(); Optional getOwner(); diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionService.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionService.java index 8b4159bf6..1eed19a27 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionService.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPPermissionService.java @@ -30,14 +30,18 @@ import com.google.common.collect.ImmutableMap; import me.lucko.luckperms.common.context.manager.ContextManager; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.sponge.service.PermissionAndContextService; import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.plugin.PluginContainer; +import net.kyori.adventure.text.Component; +import net.luckperms.api.context.ImmutableContextSet; + +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.service.context.ContextCalculator; import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.text.Text; +import org.spongepowered.plugin.PluginContainer; import java.util.Optional; import java.util.function.Predicate; @@ -49,11 +53,11 @@ public interface LPPermissionService { LuckPermsPlugin getPlugin(); - ContextManager getContextManager(); + ContextManager getContextManager(); SubjectReferenceFactory getReferenceFactory(); - PermissionService sponge(); + PermissionAndContextService sponge(); LPSubjectCollection getUserSubjects(); @@ -69,13 +73,19 @@ public interface LPPermissionService { ImmutableMap getLoadedCollections(); - LPPermissionDescription registerPermissionDescription(String id, Text description, PluginContainer owner); + LPPermissionDescription registerPermissionDescription(String id, Component description, PluginContainer owner); Optional getDescription(String permission); ImmutableCollection getDescriptions(); - void registerContextCalculator(ContextCalculator calculator); + void registerContextCalculator(ContextCalculator calculator); + + ImmutableContextSet getContextsForCause(Cause cause); + + ImmutableContextSet getContextsForCurrentCause(); + + void fireUpdateEvent(LPSubjectData subjectData); void invalidateAllCaches(); } diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedServiceObject.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPProxiedServiceObject.java similarity index 97% rename from sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedServiceObject.java rename to sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPProxiedServiceObject.java index 66960fd5f..c851762c7 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedServiceObject.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPProxiedServiceObject.java @@ -28,6 +28,6 @@ package me.lucko.luckperms.sponge.service.model; /** * Marks that an object is a proxy implementation for a PermissionService related class. */ -public interface ProxiedServiceObject { +public interface LPProxiedServiceObject { } 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/LPProxiedSubject.java similarity index 95% rename from sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ProxiedSubject.java rename to sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPProxiedSubject.java index edf2fe303..c717401af 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/LPProxiedSubject.java @@ -33,7 +33,7 @@ import org.spongepowered.api.service.permission.Subject; /** * Marks that an object is a proxied representation of a {@link Subject}. */ -public interface ProxiedSubject extends Subject, ProxiedServiceObject { +public interface LPProxiedSubject extends Subject, LPProxiedServiceObject { @Override @NonNull LPSubjectReference asSubjectReference(); diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java index 9713d238e..42c5daa68 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubject.java @@ -33,7 +33,6 @@ import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.query.QueryOptions; import net.luckperms.api.util.Tristate; -import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.service.permission.Subject; import java.util.Optional; @@ -43,7 +42,7 @@ import java.util.Optional; */ public interface LPSubject { - ProxiedSubject sponge(); + LPProxiedSubject sponge(); LPPermissionService getService(); @@ -59,10 +58,6 @@ public interface LPSubject { return Optional.empty(); } - default Optional getCommandSource() { - return Optional.empty(); - } - LPSubjectCollection getParentCollection(); LPSubjectData getSubjectData(); diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java index cff2f416e..a94e0b109 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java @@ -35,7 +35,6 @@ import net.luckperms.api.query.dataorder.DataQueryOrder; import org.spongepowered.api.service.permission.SubjectCollection; import java.util.Optional; -import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; @@ -71,7 +70,7 @@ public interface LPSubjectCollection { CompletableFuture hasRegistered(String identifier); - CompletableFuture> loadSubjects(Set identifiers); + CompletableFuture> loadSubjects(Iterable identifiers); ImmutableCollection getLoadedSubjects(); diff --git a/sponge/sponge-service-api6/src/main/java/org/spongepowered/api/service/permission/SubjectReference.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectUser.java similarity index 76% rename from sponge/sponge-service-api6/src/main/java/org/spongepowered/api/service/permission/SubjectReference.java rename to sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectUser.java index 03929c5a5..7d81230c6 100644 --- a/sponge/sponge-service-api6/src/main/java/org/spongepowered/api/service/permission/SubjectReference.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectUser.java @@ -23,20 +23,14 @@ * SOFTWARE. */ -package org.spongepowered.api.service.permission; +package me.lucko.luckperms.sponge.service.model; -import java.util.concurrent.CompletableFuture; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; -/** - * This is included, as the interface didn't exist in API6. - * We just shade it into the LP jar so we can still implement it. :) - */ -public interface SubjectReference { +import java.util.Optional; - String getCollectionIdentifier(); +public interface LPSubjectUser extends LPSubject { - String getSubjectIdentifier(); + Optional resolvePlayer(); - CompletableFuture resolve(); - -} \ No newline at end of file +} diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/CachedSubjectReference.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/CachedSubjectReference.java index 588389085..6586f8fb6 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/CachedSubjectReference.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/CachedSubjectReference.java @@ -76,12 +76,12 @@ final class CachedSubjectReference implements LPSubjectReference { } @Override - public @NonNull String getCollectionIdentifier() { + public @NonNull String collectionIdentifier() { return this.collectionIdentifier; } @Override - public @NonNull String getSubjectIdentifier() { + public @NonNull String subjectIdentifier() { return this.subjectIdentifier; } @@ -158,8 +158,8 @@ final class CachedSubjectReference implements LPSubjectReference { if (o == this) return true; if (!(o instanceof LPSubjectReference)) return false; final LPSubjectReference other = (LPSubjectReference) o; - return this.collectionIdentifier.equals(other.getCollectionIdentifier()) && - this.subjectIdentifier.equals(other.getSubjectIdentifier()); + return this.collectionIdentifier.equals(other.collectionIdentifier()) && + this.subjectIdentifier.equals(other.subjectIdentifier()); } @Override diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java index 9efa6d95b..2a92f2e53 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/reference/SubjectReferenceFactory.java @@ -30,9 +30,9 @@ import com.google.common.base.Splitter; import me.lucko.luckperms.common.util.CaffeineFactory; import me.lucko.luckperms.sponge.service.model.LPPermissionService; +import me.lucko.luckperms.sponge.service.model.LPProxiedSubject; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectReference; -import me.lucko.luckperms.sponge.service.model.ProxiedSubject; import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.SubjectReference; @@ -86,11 +86,11 @@ public final class SubjectReferenceFactory { public LPSubjectReference obtain(Subject subject) { Objects.requireNonNull(subject, "subject"); - if (subject instanceof ProxiedSubject) { - return ((ProxiedSubject) subject).asSubjectReference(); + if (subject instanceof LPProxiedSubject) { + return ((LPProxiedSubject) subject).asSubjectReference(); } - return obtain(subject.getContainingCollection().getIdentifier(), subject.getIdentifier()); + return obtain(subject.containingCollection().identifier(), subject.identifier()); } public LPSubjectReference obtain(SubjectReference reference) { @@ -98,7 +98,7 @@ public final class SubjectReferenceFactory { if (reference instanceof LPSubjectReference) { return (LPSubjectReference) reference; } else { - return obtain(reference.getCollectionIdentifier(), reference.getSubjectIdentifier()); + return obtain(reference.collectionIdentifier(), reference.subjectIdentifier()); } } @@ -119,23 +119,15 @@ public final class SubjectReferenceFactory { private SubjectReferenceAttributes(String collectionId, String id) { this.collectionId = collectionId.toLowerCase(Locale.ROOT); this.id = id.toLowerCase(Locale.ROOT); - this.hashCode = calculateHashCode(); + this.hashCode = Objects.hash(this.collectionId, this.id); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof SubjectReferenceAttributes)) return false; - final SubjectReferenceAttributes other = (SubjectReferenceAttributes) o; - return this.collectionId.equals(other.collectionId) && this.id.equals(other.id); - } - - private int calculateHashCode() { - final int PRIME = 59; - int result = 1; - result = result * PRIME + this.collectionId.hashCode(); - result = result * PRIME + this.id.hashCode(); - return result; + final SubjectReferenceAttributes that = (SubjectReferenceAttributes) o; + return this.collectionId.equals(that.collectionId) && this.id.equals(that.id); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java index fae255ed2..d74cd065d 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongeBootstrap.java @@ -29,33 +29,30 @@ import com.google.inject.Inject; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; -import me.lucko.luckperms.common.plugin.classpath.ReflectionClassPathAppender; +import me.lucko.luckperms.common.plugin.logging.Log4jPluginLogger; import me.lucko.luckperms.common.plugin.logging.PluginLogger; -import me.lucko.luckperms.common.plugin.logging.Slf4jPluginLogger; -import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter; import me.lucko.luckperms.common.util.MoreFiles; -import org.slf4j.Logger; +import net.luckperms.api.platform.Platform; + +import org.apache.logging.log4j.Logger; import org.spongepowered.api.Game; -import org.spongepowered.api.Platform; +import org.spongepowered.api.Platform.Component; import org.spongepowered.api.Server; -import org.spongepowered.api.Sponge; import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; -import org.spongepowered.api.event.game.state.GamePreInitializationEvent; -import org.spongepowered.api.event.game.state.GameStoppingServerEvent; -import org.spongepowered.api.plugin.Dependency; -import org.spongepowered.api.plugin.Plugin; -import org.spongepowered.api.plugin.PluginContainer; +import org.spongepowered.api.event.lifecycle.ConstructPluginEvent; +import org.spongepowered.api.event.lifecycle.StoppingEngineEvent; import org.spongepowered.api.profile.GameProfile; -import org.spongepowered.api.scheduler.AsynchronousExecutor; -import org.spongepowered.api.scheduler.Scheduler; -import org.spongepowered.api.scheduler.SpongeExecutorService; -import org.spongepowered.api.scheduler.SynchronousExecutor; +import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.builtin.jvm.Plugin; +import org.spongepowered.plugin.metadata.PluginMetadata; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; @@ -69,18 +66,7 @@ import java.util.concurrent.CountDownLatch; /** * Bootstrap plugin for LuckPerms running on Sponge. */ -@Plugin( - id = "luckperms", - name = "LuckPerms", - version = "@version@", - authors = "Luck", - description = "A permissions plugin", - url = "https://luckperms.net", - dependencies = { - // explicit dependency on spongeapi with no defined API version - @Dependency(id = "spongeapi") - } -) +@Plugin("luckperms") public class LPSpongeBootstrap implements LuckPermsBootstrap { /** @@ -91,7 +77,7 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { /** * A scheduler adapter for the platform */ - private final SchedulerAdapter schedulerAdapter; + private final SpongeSchedulerAdapter schedulerAdapter; /** * The plugin class path appender @@ -115,33 +101,27 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { /** * Reference to the central {@link Game} instance in the API */ - @Inject - private Game game; - - /** - * Reference to the sponge scheduler - */ - private final Scheduler spongeScheduler; - - /** - * Injected configuration directory for the plugin - */ - @Inject - @ConfigDir(sharedRoot = false) - private Path configDirectory; + private final Game game; /** * Injected plugin container for the plugin */ - @Inject - private PluginContainer pluginContainer; + private final PluginContainer pluginContainer; + + /** + * Injected configuration directory for the plugin + */ + private final Path configDirectory; @Inject - public LPSpongeBootstrap(Logger logger, @SynchronousExecutor SpongeExecutorService syncExecutor, @AsynchronousExecutor SpongeExecutorService asyncExecutor) { - this.logger = new Slf4jPluginLogger(logger); - this.spongeScheduler = Sponge.getScheduler(); - this.schedulerAdapter = new SpongeSchedulerAdapter(this, this.spongeScheduler, syncExecutor, asyncExecutor); - this.classPathAppender = new ReflectionClassPathAppender(this); + public LPSpongeBootstrap(Logger logger, Game game, PluginContainer pluginContainer, @ConfigDir(sharedRoot = false) Path configDirectory) { + this.logger = new Log4jPluginLogger(logger); + this.game = game; + this.pluginContainer = pluginContainer; + this.configDirectory = configDirectory; + + this.schedulerAdapter = new SpongeSchedulerAdapter(this.game, this.pluginContainer); + this.classPathAppender = new SpongeClassPathAppender(this); this.plugin = new LPSpongePlugin(this); } @@ -153,7 +133,7 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { } @Override - public SchedulerAdapter getScheduler() { + public SpongeSchedulerAdapter getScheduler() { return this.schedulerAdapter; } @@ -163,9 +143,8 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { } // lifecycle - @Listener(order = Order.FIRST) - public void onEnable(GamePreInitializationEvent event) { + public void onEnable(ConstructPluginEvent event) { this.startTime = Instant.now(); try { this.plugin.load(); @@ -180,13 +159,8 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { } } - @Listener(order = Order.LATE) - public void onLateEnable(GamePreInitializationEvent event) { - this.plugin.lateEnable(); - } - @Listener - public void onDisable(GameStoppingServerEvent event) { + public void onDisable(StoppingEngineEvent event) { this.plugin.disable(); } @@ -207,22 +181,22 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { } public Optional getServer() { - return this.game.isServerAvailable() ? Optional.of(this.game.getServer()) : Optional.empty(); - } - - public Scheduler getSpongeScheduler() { - return this.spongeScheduler; + return this.game.isServerAvailable() ? Optional.of(this.game.server()) : Optional.empty(); } public PluginContainer getPluginContainer() { return this.pluginContainer; } + public void registerListeners(Object obj) { + this.game.eventManager().registerListeners(this.pluginContainer, obj); + } + // provide information about the plugin @Override public String getVersion() { - return "@version@"; + return this.pluginContainer.metadata().version().toString(); } @Override @@ -233,25 +207,26 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { // provide information about the platform @Override - public net.luckperms.api.platform.Platform.Type getType() { - return net.luckperms.api.platform.Platform.Type.SPONGE; + public Platform.Type getType() { + return Platform.Type.SPONGE; } @Override public String getServerBrand() { - return this.game.getPlatform().getContainer(Platform.Component.IMPLEMENTATION).getName(); + PluginMetadata brandMetadata = this.game.platform().container(Component.IMPLEMENTATION).metadata(); + return brandMetadata.name().orElseGet(brandMetadata::id); } @Override public String getServerVersion() { - PluginContainer api = this.game.getPlatform().getContainer(Platform.Component.API); - PluginContainer impl = this.game.getPlatform().getContainer(Platform.Component.IMPLEMENTATION); - return api.getName() + ": " + api.getVersion().orElse("null") + " - " + impl.getName() + ": " + impl.getVersion().orElse("null"); + PluginMetadata api = this.game.platform().container(Component.API).metadata(); + PluginMetadata impl = this.game.platform().container(Component.IMPLEMENTATION).metadata(); + return api.name().orElse("API") + ": " + api.version() + " - " + impl.name().orElse("Impl") + ": " + impl.version(); } @Override public Path getDataDirectory() { - Path dataDirectory = this.game.getGameDirectory().toAbsolutePath().resolve("luckperms"); + Path dataDirectory = this.game.gameDirectory().toAbsolutePath().resolve("luckperms"); try { MoreFiles.createDirectoriesIfNotExists(dataDirectory); } catch (IOException e) { @@ -266,14 +241,19 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { } @Override - public Optional getPlayer(UUID uniqueId) { - return getServer().flatMap(s -> s.getPlayer(uniqueId)); + public InputStream getResourceStream(String path) { + return getClass().getClassLoader().getResourceAsStream(path); + } + + @Override + public Optional getPlayer(UUID uniqueId) { + return getServer().flatMap(s -> s.player(uniqueId)); } @Override public Optional lookupUniqueId(String username) { - return getServer().flatMap(server -> server.getGameProfileManager().get(username) - .thenApply(p -> Optional.of(p.getUniqueId())) + return getServer().flatMap(server -> server.gameProfileManager().profile(username) + .thenApply(p -> Optional.of(p.uniqueId())) .exceptionally(x -> Optional.empty()) .join() ); @@ -281,8 +261,8 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { @Override public Optional lookupUsername(UUID uniqueId) { - return getServer().flatMap(server -> server.getGameProfileManager().get(uniqueId) - .thenApply(GameProfile::getName) + return getServer().flatMap(server -> server.gameProfileManager().profile(uniqueId) + .thenApply(GameProfile::name) .exceptionally(x -> Optional.empty()) .join() ); @@ -290,16 +270,16 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { @Override public int getPlayerCount() { - return getServer().map(server -> server.getOnlinePlayers().size()).orElse(0); + return getServer().map(server -> server.onlinePlayers().size()).orElse(0); } @Override public Collection getPlayerList() { return getServer().map(server -> { - Collection players = server.getOnlinePlayers(); + Collection players = server.onlinePlayers(); List list = new ArrayList<>(players.size()); for (Player player : players) { - list.add(player.getName()); + list.add(player.name()); } return list; }).orElse(Collections.emptyList()); @@ -308,10 +288,10 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { @Override public Collection getOnlinePlayers() { return getServer().map(server -> { - Collection players = server.getOnlinePlayers(); + Collection players = server.onlinePlayers(); List list = new ArrayList<>(players.size()); for (Player player : players) { - list.add(player.getUniqueId()); + list.add(player.uniqueId()); } return list; }).orElse(Collections.emptyList()); @@ -319,7 +299,7 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap { @Override public boolean isPlayerOnline(UUID uniqueId) { - return getServer().flatMap(server -> server.getPlayer(uniqueId).map(Player::isOnline)).orElse(false); + return getServer().map(server -> server.player(uniqueId).isPresent()).orElse(false); } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java index 90ed9664f..655ed6a7d 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/LPSpongePlugin.java @@ -27,7 +27,6 @@ package me.lucko.luckperms.sponge; import me.lucko.luckperms.common.api.LuckPermsApiProvider; import me.lucko.luckperms.common.calculator.CalculatorFactory; -import me.lucko.luckperms.common.command.abstraction.Command; import me.lucko.luckperms.common.command.access.CommandPermission; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.generic.adapter.ConfigurationAdapter; @@ -38,34 +37,42 @@ import me.lucko.luckperms.common.messaging.MessagingFactory; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.manager.track.StandardTrackManager; import me.lucko.luckperms.common.plugin.AbstractLuckPermsPlugin; +import me.lucko.luckperms.common.sender.AbstractSender; import me.lucko.luckperms.common.sender.DummyConsoleSender; import me.lucko.luckperms.common.sender.Sender; +import me.lucko.luckperms.common.util.MoreFiles; import me.lucko.luckperms.sponge.calculator.SpongeCalculatorFactory; import me.lucko.luckperms.sponge.commands.SpongeParentCommand; import me.lucko.luckperms.sponge.context.SpongeContextManager; import me.lucko.luckperms.sponge.context.SpongePlayerCalculator; +import me.lucko.luckperms.sponge.listeners.SpongeCommandListUpdater; import me.lucko.luckperms.sponge.listeners.SpongeConnectionListener; import me.lucko.luckperms.sponge.listeners.SpongePlatformListener; import me.lucko.luckperms.sponge.messaging.SpongeMessagingFactory; import me.lucko.luckperms.sponge.model.manager.SpongeGroupManager; import me.lucko.luckperms.sponge.model.manager.SpongeUserManager; import me.lucko.luckperms.sponge.service.LuckPermsService; -import me.lucko.luckperms.sponge.service.ProxyFactory; -import me.lucko.luckperms.sponge.service.model.LPPermissionService; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; -import me.lucko.luckperms.sponge.service.model.ProxiedServiceObject; import me.lucko.luckperms.sponge.service.model.persisted.PersistedCollection; import me.lucko.luckperms.sponge.tasks.ServiceCacheHousekeepingTask; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.luckperms.api.LuckPerms; import net.luckperms.api.query.QueryOptions; -import org.spongepowered.api.service.permission.PermissionDescription; +import org.spongepowered.api.command.Command; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.lifecycle.ProvideServiceEvent; +import org.spongepowered.api.event.lifecycle.RegisterCommandEvent; +import org.spongepowered.api.service.context.ContextService; import org.spongepowered.api.service.permission.PermissionService; +import org.spongepowered.plugin.PluginContainer; -import java.util.Collection; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -88,8 +95,6 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { private SpongeContextManager contextManager; private LuckPermsService service; - private boolean lateLoad = false; - public LPSpongePlugin(LPSpongeBootstrap bootstrap) { this.bootstrap = bootstrap; } @@ -107,8 +112,11 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { @Override protected Set getGlobalDependencies() { Set dependencies = super.getGlobalDependencies(); - dependencies.add(Dependency.ADVENTURE_PLATFORM); + + //dependencies.add(Dependency.ADVENTURE_PLATFORM); //dependencies.add(Dependency.ADVENTURE_PLATFORM_SPONGEAPI); + dependencies.remove(Dependency.ADVENTURE); + dependencies.add(Dependency.CONFIGURATE_CORE); dependencies.add(Dependency.CONFIGURATE_HOCON); dependencies.add(Dependency.HOCON_CONFIG); @@ -117,14 +125,14 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { @Override protected ConfigurationAdapter provideConfigurationAdapter() { - return new SpongeConfigAdapter(this, resolveConfig("luckperms.conf")); + return new SpongeConfigAdapter(this, resolveConfig()); } @Override protected void registerPlatformListeners() { this.connectionListener = new SpongeConnectionListener(this); - this.bootstrap.getGame().getEventManager().registerListeners(this.bootstrap, this.connectionListener); - this.bootstrap.getGame().getEventManager().registerListeners(this.bootstrap, new SpongePlatformListener(this)); + this.bootstrap.registerListeners(this.connectionListener); + this.bootstrap.registerListeners(new SpongePlatformListener(this)); } @Override @@ -135,7 +143,22 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { @Override protected void registerCommands() { this.commandManager = new SpongeCommandExecutor(this); - this.bootstrap.getGame().getCommandManager().register(this.bootstrap, this.commandManager, "luckperms", "lp", "perm", "perms", "permission", "permissions"); + this.bootstrap.registerListeners(new RegisterCommandsListener(this.bootstrap.getPluginContainer(), this.commandManager)); + } + + public static final class RegisterCommandsListener { + private final PluginContainer pluginContainer; + private final Command.Raw command; + + RegisterCommandsListener(PluginContainer pluginContainer, Command.Raw command) { + this.pluginContainer = pluginContainer; + this.command = command; + } + + @Listener + public void onCommandRegister(RegisterCommandEvent event) { + event.register(this.pluginContainer, this.command, "luckperms", "lp", "perm", "perms", "permission", "permissions"); + } } @Override @@ -154,36 +177,46 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { protected void setupContextManager() { this.contextManager = new SpongeContextManager(this); - SpongePlayerCalculator playerCalculator = new SpongePlayerCalculator(this, getConfiguration().get(ConfigKeys.DISABLED_CONTEXTS)); - this.bootstrap.getGame().getEventManager().registerListeners(this.bootstrap, playerCalculator); + SpongePlayerCalculator playerCalculator = new SpongePlayerCalculator(this); + this.bootstrap.registerListeners(playerCalculator); this.contextManager.registerCalculator(playerCalculator); } @Override protected void setupPlatformHooks() { - getLogger().info("Registering PermissionService..."); this.service = new LuckPermsService(this); - PermissionService oldService = this.bootstrap.getGame().getServiceManager().provide(PermissionService.class).orElse(null); - if (oldService != null && !(oldService instanceof ProxiedServiceObject)) { + //PermissionService oldService = this.bootstrap.getGame().getServiceManager().provide(PermissionService.class).orElse(null); + //if (oldService != null && !(oldService instanceof ProxiedServiceObject)) { + // + // // before registering our permission service, copy any existing permission descriptions + // Collection permissionDescriptions = oldService.getDescriptions(); + // for (PermissionDescription description : permissionDescriptions) { + // if (description instanceof ProxiedServiceObject) { + // continue; + // } + // ProxyFactory.registerDescription(this.service, description); + // } + //} - // before registering our permission service, copy any existing permission descriptions - Collection permissionDescriptions = oldService.getDescriptions(); - for (PermissionDescription description : permissionDescriptions) { - if (description instanceof ProxiedServiceObject) { - continue; - } - ProxyFactory.registerDescription(this.service, description); - } + this.bootstrap.registerListeners(new RegisterServiceListener(this.service)); + } + + public static final class RegisterServiceListener { + private final LuckPermsService service; + + RegisterServiceListener(LuckPermsService service) { + this.service = service; } - if (this.bootstrap.getGame().getPluginManager().getPlugin("permissionsex").isPresent()) { - getLogger().warn("Detected PermissionsEx - assuming it's loaded for migration."); - getLogger().warn("Delaying LuckPerms PermissionService registration."); - this.lateLoad = true; - } else { - this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LPPermissionService.class, this.service); - this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, PermissionService.class, this.service.sponge()); + @Listener + public void onPermissionServiceProvide(ProvideServiceEvent.EngineScoped event) { + event.suggest(this.service::sponge); + } + + @Listener + public void onContextServiceProvide(ProvideServiceEvent.EngineScoped event) { + event.suggest(this.service::sponge); } } @@ -194,7 +227,20 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { @Override protected void registerApiOnPlatform(LuckPerms api) { - this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LuckPerms.class, api); + this.bootstrap.registerListeners(new RegisterApiListener(api)); + } + + public static final class RegisterApiListener { + private final LuckPerms api; + + RegisterApiListener(LuckPerms api) { + this.api = api; + } + + @Listener + public void onLuckPermsServiceProvide(ProvideServiceEvent event) { + event.suggest(() -> this.api); + } } @Override @@ -209,13 +255,10 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { for (CommandPermission perm : CommandPermission.values()) { this.service.registerPermissionDescription(perm.getPermission(), null, this.bootstrap.getPluginContainer()); } - } - public void lateEnable() { - if (this.lateLoad) { - getLogger().info("Providing late registration of PermissionService..."); - this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LPPermissionService.class, this.service); - this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, PermissionService.class, this.service.sponge()); + // register sponge command list updater + if (getConfiguration().get(ConfigKeys.UPDATE_CLIENT_COMMAND_LIST)) { + getApiProvider().getEventBus().subscribe(new SpongeCommandListUpdater(this)); } } @@ -229,6 +272,22 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { this.service.invalidateAllCaches(); } + private Path resolveConfig() { + Path path = this.bootstrap.getConfigDirectory().resolve("luckperms.conf"); + if (!Files.exists(path)) { + try { + MoreFiles.createDirectoriesIfNotExists(this.bootstrap.getConfigDirectory()); + try (InputStream is = getClass().getClassLoader().getResourceAsStream("luckperms.conf")) { + Files.copy(is, path); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + return path; + } + @Override public Optional getQueryOptionsForUser(User user) { return this.bootstrap.getPlayer(user.getUniqueId()).map(player -> this.contextManager.getQueryOptions(player)); @@ -238,26 +297,28 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin { public Stream getOnlineSenders() { return Stream.concat( Stream.of(getConsoleSender()), - this.bootstrap.getServer().map(server -> server.getOnlinePlayers().stream().map(s -> this.senderFactory.wrap(s))).orElseGet(Stream::empty) + this.bootstrap.getServer().map(server -> server.onlinePlayers().stream().map(s -> this.senderFactory.wrap(s))).orElseGet(Stream::empty) ); } @Override public Sender getConsoleSender() { if (this.bootstrap.getGame().isServerAvailable()) { - return this.senderFactory.wrap(this.bootstrap.getGame().getServer().getConsole()); + return this.senderFactory.wrap(this.bootstrap.getGame().systemSubject()); } else { return new DummyConsoleSender(this) { @Override public void sendMessage(Component message) { - LPSpongePlugin.this.getLogger().info(LegacyComponentSerializer.legacySection().serialize(TranslationManager.render(message))); + for (Component line : AbstractSender.splitNewlines(TranslationManager.render(message))) { + LPSpongePlugin.this.bootstrap.getPluginLogger().info(PlainTextComponentSerializer.plainText().serialize(line)); + } } }; } } @Override - public List> getExtraCommands() { + public List> getExtraCommands() { return Collections.singletonList(new SpongeParentCommand(this)); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeClassPathAppender.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeClassPathAppender.java new file mode 100644 index 000000000..efd521c50 --- /dev/null +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeClassPathAppender.java @@ -0,0 +1,64 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * 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.sponge; + +import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; +import me.lucko.luckperms.common.plugin.classpath.ReflectionClassPathAppender; + +import java.lang.reflect.Field; +import java.net.URLClassLoader; + +public class SpongeClassPathAppender extends ReflectionClassPathAppender { + + private static URLClassLoader extractClassLoaderFromBootstrap(LuckPermsBootstrap bootstrap) { + ClassLoader classLoader = bootstrap.getClass().getClassLoader(); + + // try to cast directly to URLClassLoader in case things change in the future + if (classLoader instanceof URLClassLoader) { + return (URLClassLoader) classLoader; + } + + Class classLoaderClass = classLoader.getClass(); + + if (!classLoaderClass.getName().equals("cpw.mods.modlauncher.TransformingClassLoader")) { + throw new IllegalStateException("ClassLoader is not instance of TransformingClassLoader: " + classLoaderClass.getName()); + } + + try { + Field delegatedClassLoaderField = classLoaderClass.getDeclaredField("delegatedClassLoader"); + delegatedClassLoaderField.setAccessible(true); + Object delegatedClassLoader = delegatedClassLoaderField.get(classLoader); + return (URLClassLoader) delegatedClassLoader; + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public SpongeClassPathAppender(LuckPermsBootstrap bootstrap) throws IllegalStateException { + super(extractClassLoaderFromBootstrap(bootstrap)); + } + +} diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeCommandExecutor.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeCommandExecutor.java index 92b04bd60..3467d539b 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeCommandExecutor.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeCommandExecutor.java @@ -30,23 +30,23 @@ import me.lucko.luckperms.common.command.utils.ArgumentTokenizer; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.sender.Sender; +import net.kyori.adventure.text.Component; + import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.command.CommandCallable; +import org.spongepowered.api.command.Command; +import org.spongepowered.api.command.CommandCause; +import org.spongepowered.api.command.CommandCompletion; import org.spongepowered.api.command.CommandResult; -import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.command.parameter.ArgumentReader; +import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.selector.Selector; -import org.spongepowered.api.world.Location; -import org.spongepowered.api.world.World; import java.util.List; import java.util.ListIterator; import java.util.Optional; import java.util.stream.Collectors; -public class SpongeCommandExecutor extends CommandManager implements CommandCallable { +public class SpongeCommandExecutor extends CommandManager implements Command.Raw { private final LPSpongePlugin plugin; public SpongeCommandExecutor(LPSpongePlugin plugin) { @@ -55,41 +55,44 @@ public class SpongeCommandExecutor extends CommandManager implements CommandCall } @Override - public @NonNull CommandResult process(@NonNull CommandSource source, @NonNull String args) { - Sender wrapped = this.plugin.getSenderFactory().wrap(source); - List arguments = resolveSelectors(source, ArgumentTokenizer.EXECUTE.tokenizeInput(args)); + public @NonNull CommandResult process(@NonNull CommandCause source, ArgumentReader.@NonNull Mutable args) { + Sender wrapped = this.plugin.getSenderFactory().wrap(source.audience()); + List arguments = resolveSelectors(source, ArgumentTokenizer.EXECUTE.tokenizeInput(args.input())); executeCommand(wrapped, "lp", arguments); return CommandResult.success(); } @Override - public @NonNull List getSuggestions(@NonNull CommandSource source, @NonNull String args, @Nullable Location location) { - Sender wrapped = this.plugin.getSenderFactory().wrap(source); - List arguments = resolveSelectors(source, ArgumentTokenizer.TAB_COMPLETE.tokenizeInput(args)); - return tabCompleteCommand(wrapped, arguments); + public List complete(@NonNull CommandCause source, ArgumentReader.@NonNull Mutable args) { + Sender wrapped = this.plugin.getSenderFactory().wrap(source.audience()); + List arguments = resolveSelectors(source, ArgumentTokenizer.TAB_COMPLETE.tokenizeInput(args.input())); + return tabCompleteCommand(wrapped, arguments) + .stream() + .map(CommandCompletion::of) + .collect(Collectors.toList()); } @Override - public boolean testPermission(@NonNull CommandSource source) { + public boolean canExecute(CommandCause cause) { return true; // we run permission checks internally } @Override - public @NonNull Optional getShortDescription(@NonNull CommandSource source) { - return Optional.of(Text.of("Manage permissions")); + public Optional shortDescription(CommandCause cause) { + return Optional.of(Component.text("Manage permissions")); } @Override - public @NonNull Optional getHelp(@NonNull CommandSource source) { - return Optional.of(Text.of("Run /luckperms to view usage.")); + public Optional extendedDescription(CommandCause cause) { + return Optional.empty(); } @Override - public @NonNull Text getUsage(@NonNull CommandSource source) { - return Text.of("/luckperms"); + public Component usage(CommandCause cause) { + return Component.text("/luckperms"); } - private List resolveSelectors(CommandSource source, List args) { + private List resolveSelectors(CommandCause source, List args) { if (!this.plugin.getConfiguration().get(ConfigKeys.RESOLVE_COMMAND_SELECTORS)) { return args; } @@ -102,7 +105,7 @@ public class SpongeCommandExecutor extends CommandManager implements CommandCall List matchedPlayers; try { - matchedPlayers = Selector.parse(arg).resolve(source).stream() + matchedPlayers = Selector.parse(arg).select(source).stream() .filter(e -> e instanceof Player) .map(e -> (Player) e) .collect(Collectors.toList()); @@ -122,7 +125,7 @@ public class SpongeCommandExecutor extends CommandManager implements CommandCall } Player player = matchedPlayers.get(0); - it.set(player.getUniqueId().toString()); + it.set(player.uniqueId().toString()); } return args; diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeEventBus.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeEventBus.java index 55e498d09..105eae51d 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeEventBus.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeEventBus.java @@ -29,15 +29,11 @@ import me.lucko.luckperms.common.api.LuckPermsApiProvider; import me.lucko.luckperms.common.event.AbstractEventBus; import org.spongepowered.api.Sponge; -import org.spongepowered.api.plugin.PluginContainer; +import org.spongepowered.plugin.PluginContainer; public class SpongeEventBus extends AbstractEventBus { public SpongeEventBus(LPSpongePlugin plugin, LuckPermsApiProvider apiProvider) { super(plugin, apiProvider); - - // register listener - LPSpongeBootstrap bootstrap = plugin.getBootstrap(); - bootstrap.getGame().getEventManager().registerListeners(bootstrap, this); } @Override @@ -46,7 +42,7 @@ public class SpongeEventBus extends AbstractEventBus { return (PluginContainer) plugin; } - PluginContainer pluginContainer = Sponge.getPluginManager().fromInstance(plugin).orElse(null); + PluginContainer pluginContainer = Sponge.pluginManager().fromInstance(plugin).orElse(null); if (pluginContainer != null) { return pluginContainer; } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java index 4d5e5e318..ba73077da 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java @@ -25,34 +25,45 @@ package me.lucko.luckperms.sponge; +import com.google.common.base.Suppliers; + import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter; import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask; import me.lucko.luckperms.common.util.Iterators; +import org.spongepowered.api.Game; +import org.spongepowered.api.scheduler.ScheduledTask; import org.spongepowered.api.scheduler.Scheduler; -import org.spongepowered.api.scheduler.SpongeExecutorService; import org.spongepowered.api.scheduler.Task; +import org.spongepowered.api.scheduler.TaskExecutorService; +import org.spongepowered.plugin.PluginContainer; import java.util.Collections; import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Supplier; public class SpongeSchedulerAdapter implements SchedulerAdapter { - private final LPSpongeBootstrap bootstrap; - - private final Scheduler scheduler; - private final SpongeExecutorService sync; - private final SpongeExecutorService async; - - private final Set tasks = Collections.newSetFromMap(new WeakHashMap<>()); - public SpongeSchedulerAdapter(LPSpongeBootstrap bootstrap, Scheduler scheduler, SpongeExecutorService sync, SpongeExecutorService async) { - this.bootstrap = bootstrap; - this.scheduler = scheduler; - this.sync = sync; - this.async = async; + private final Game game; + private final PluginContainer pluginContainer; + + private final Scheduler asyncScheduler; + private final Supplier sync; + private final TaskExecutorService async; + + private final Set tasks = Collections.newSetFromMap(new WeakHashMap<>()); + + public SpongeSchedulerAdapter(Game game, PluginContainer pluginContainer) { + this.game = game; + this.pluginContainer = pluginContainer; + + this.asyncScheduler = game.asyncScheduler(); + this.async = this.asyncScheduler.executor(pluginContainer); + this.sync = Suppliers.memoize(() -> getSyncScheduler().executor(this.pluginContainer)); } @Override @@ -62,47 +73,40 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter { @Override public Executor sync() { - return this.sync; + return this.sync.get(); } - @Override - public void executeAsync(Runnable runnable) { - this.scheduler.createTaskBuilder().async().execute(runnable).submit(this.bootstrap); + public Scheduler getSyncScheduler() { + return this.game.server().scheduler(); } - @Override - public void executeSync(Runnable runnable) { - this.scheduler.createTaskBuilder().execute(runnable).submit(this.bootstrap); + private SchedulerTask submitAsyncTask(Runnable runnable, Consumer config) { + Task.Builder builder = Task.builder(); + config.accept(builder); + + Task task = builder + .execute(runnable) + .plugin(this.pluginContainer) + .build(); + + ScheduledTask scheduledTask = this.asyncScheduler.submit(task); + this.tasks.add(scheduledTask); + return scheduledTask::cancel; } @Override public SchedulerTask asyncLater(Runnable task, long delay, TimeUnit unit) { - Task t = this.scheduler.createTaskBuilder() - .async() - .delay(delay, unit) - .execute(task) - .submit(this.bootstrap); - - this.tasks.add(t); - return t::cancel; + return submitAsyncTask(task, builder -> builder.delay(delay, unit)); } @Override public SchedulerTask asyncRepeating(Runnable task, long interval, TimeUnit unit) { - Task t = this.scheduler.createTaskBuilder() - .async() - .interval(interval, unit) - .delay(interval, unit) - .execute(task) - .submit(this.bootstrap); - - this.tasks.add(t); - return t::cancel; + return submitAsyncTask(task, builder -> builder.delay(interval, unit).interval(interval, unit)); } @Override public void shutdownScheduler() { - Iterators.tryIterate(this.tasks, Task::cancel); + Iterators.tryIterate(this.tasks, ScheduledTask::cancel); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java index 7f7c9a517..06bc24700 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSenderFactory.java @@ -30,50 +30,61 @@ import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.sender.SenderFactory; import me.lucko.luckperms.sponge.service.CompatibilityUtil; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.luckperms.api.util.Tristate; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.command.source.ConsoleSource; +import org.spongepowered.api.SystemSubject; +import org.spongepowered.api.command.exception.CommandException; import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.serializer.TextSerializers; +import org.spongepowered.api.service.permission.Subject; +import java.util.Locale; import java.util.UUID; -public class SpongeSenderFactory extends SenderFactory { +public class SpongeSenderFactory extends SenderFactory { public SpongeSenderFactory(LPSpongePlugin plugin) { super(plugin); } @Override - protected String getName(CommandSource source) { + protected String getName(Audience source) { if (source instanceof Player) { - return source.getName(); + return ((Player) source).name(); } return Sender.CONSOLE_NAME; } @Override - protected UUID getUniqueId(CommandSource source) { + protected UUID getUniqueId(Audience source) { if (source instanceof Player) { - return ((Player) source).getUniqueId(); + return ((Player) source).uniqueId(); } return Sender.CONSOLE_UUID; } @Override - protected void sendMessage(CommandSource source, Component message) { - source.sendMessage(toNativeText(TranslationManager.render(message, source.getLocale()))); + protected void sendMessage(Audience source, Component message) { + Locale locale = null; + if (source instanceof Player) { + locale = ((Player) source).locale(); + } + Component rendered = TranslationManager.render(message, locale); + + source.sendMessage(rendered); } @Override - protected Tristate getPermissionValue(CommandSource source, String node) { - Tristate result = CompatibilityUtil.convertTristate(source.getPermissionValue(source.getActiveContexts(), node)); + protected Tristate getPermissionValue(Audience source, String node) { + if (!(source instanceof Subject)) { + throw new IllegalStateException("Source is not a subject"); + } + + final Subject subject = (Subject) source; + Tristate result = CompatibilityUtil.convertTristate(subject.permissionValue(node)); // check the permdefault - if (result == Tristate.UNDEFINED && source.hasPermission(node)) { + if (result == Tristate.UNDEFINED && subject.hasPermission(node)) { result = Tristate.TRUE; } @@ -81,22 +92,30 @@ public class SpongeSenderFactory extends SenderFactory { public ParentAdd() { super(CommandSpec.SPONGE_PARENT_ADD, "add", CommandPermission.SPONGE_PARENT_ADD, Predicates.inRange(0, 1)); @@ -52,7 +50,7 @@ public class ParentAdd extends ChildCommand { String name = args.get(1); ImmutableContextSet contextSet = args.getContextOrEmpty(2); - LPPermissionService service = Sponge.getServiceManager().provideUnchecked(LPPermissionService.class); + LPPermissionService service = subjectData.getParentSubject().getService(); if (service.getLoadedCollections().keySet().stream().map(String::toLowerCase).noneMatch(s -> s.equalsIgnoreCase(collection))) { SpongeCommandUtils.sendPrefixed(sender, "Warning: SubjectCollection '&4" + collection + "&c' doesn't already exist."); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java index f1126f9d1..4c8455fcb 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/ParentRemove.java @@ -39,8 +39,6 @@ import me.lucko.luckperms.sponge.service.model.LPSubjectData; import net.luckperms.api.context.ImmutableContextSet; -import org.spongepowered.api.Sponge; - public class ParentRemove extends ChildCommand { public ParentRemove() { super(CommandSpec.SPONGE_PARENT_REMOVE, "remove", CommandPermission.SPONGE_PARENT_REMOVE, Predicates.inRange(0, 1)); @@ -52,7 +50,7 @@ public class ParentRemove extends ChildCommand { String name = args.get(1); ImmutableContextSet contextSet = args.getContextOrEmpty(2); - LPPermissionService service = Sponge.getServiceManager().provideUnchecked(LPPermissionService.class); + LPPermissionService service = subjectData.getParentSubject().getService(); if (service.getLoadedCollections().keySet().stream().map(String::toLowerCase).noneMatch(s -> s.equalsIgnoreCase(collection))) { SpongeCommandUtils.sendPrefixed(sender, "Warning: SubjectCollection '&4" + collection + "&c' doesn't exist."); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeCommandUtils.java b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeCommandUtils.java index e976b518d..c6b943038 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeCommandUtils.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/commands/SpongeCommandUtils.java @@ -94,9 +94,9 @@ public final class SpongeCommandUtils { StringBuilder sb = new StringBuilder(); for (LPSubjectReference s : parents) { sb.append("&3> &a") - .append(s.getSubjectIdentifier()) + .append(s.subjectIdentifier()) .append(" &bfrom collection &a") - .append(s.getCollectionIdentifier()) + .append(s.collectionIdentifier()) .append("&b.\n"); } return sb.toString(); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongeContextManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongeContextManager.java index 25b47dca2..371d96c52 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongeContextManager.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongeContextManager.java @@ -28,33 +28,66 @@ package me.lucko.luckperms.sponge.context; import com.github.benmanes.caffeine.cache.LoadingCache; import me.lucko.luckperms.common.context.manager.ContextManager; -import me.lucko.luckperms.common.context.manager.QueryOptionsCache; +import me.lucko.luckperms.common.context.manager.InlineQueryOptionsSupplier; import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier; import me.lucko.luckperms.common.util.CaffeineFactory; import me.lucko.luckperms.sponge.LPSpongePlugin; +import me.lucko.luckperms.sponge.service.model.ContextCalculatorProxy; +import me.lucko.luckperms.sponge.service.model.TemporaryCauseHolderSubject; +import net.luckperms.api.context.ContextCalculator; +import net.luckperms.api.context.ContextConsumer; import net.luckperms.api.context.ImmutableContextSet; +import net.luckperms.api.context.StaticContextCalculator; import net.luckperms.api.query.QueryOptions; -import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.event.Cause; import org.spongepowered.api.service.permission.Subject; import java.util.UUID; import java.util.concurrent.TimeUnit; -public class SpongeContextManager extends ContextManager { +public class SpongeContextManager extends ContextManager { - private final LoadingCache> subjectCaches = CaffeineFactory.newBuilder() - .expireAfterAccess(1, TimeUnit.MINUTES) - .build(key -> new QueryOptionsCache<>(key, this)); + private final LoadingCache contextsCache = CaffeineFactory.newBuilder() + .expireAfterWrite(50, TimeUnit.MILLISECONDS) + .build(this::calculate); public SpongeContextManager(LPSpongePlugin plugin) { - super(plugin, Subject.class, Player.class); + super(plugin, Subject.class, ServerPlayer.class); } @Override - public UUID getUniqueId(Player player) { - return player.getUniqueId(); + protected void callContextCalculator(ContextCalculator calculator, Subject subject, ContextConsumer consumer) { + if (subject instanceof TemporaryCauseHolderSubject) { + Cause cause = ((TemporaryCauseHolderSubject) subject).getCause(); + Subject actualSubject = ((TemporaryCauseHolderSubject) subject).getSubject(); + + if (calculator instanceof ContextCalculatorProxy) { + ((ContextCalculatorProxy) calculator).calculate(cause, consumer); + } else if (actualSubject != null) { + calculator.calculate(actualSubject, consumer); + } else if (calculator instanceof StaticContextCalculator) { + ((StaticContextCalculator) calculator).calculate(consumer); + } /* else { + // we just have to fail... + // there's no way to call a LuckPerms ContextCalculator if a Subject instance + // doesn't exist for the cause. + } */ + } else { + Object associatedObject = subject.associatedObject().orElse(null); + if (associatedObject instanceof Subject) { + calculator.calculate((Subject) associatedObject, consumer); + } else { + calculator.calculate(subject, consumer); + } + } + } + + @Override + public UUID getUniqueId(ServerPlayer player) { + return player.uniqueId(); } @Override @@ -63,15 +96,23 @@ public class SpongeContextManager extends ContextManager { throw new NullPointerException("subject"); } - return this.subjectCaches.get(subject); + return new InlineQueryOptionsSupplier<>(subject, this.contextsCache); + } + + // override getContext, getQueryOptions and invalidateCache to skip the QueryOptionsSupplier + @Override + public ImmutableContextSet getContext(Subject subject) { + return getQueryOptions(subject).context(); + } + + @Override + public QueryOptions getQueryOptions(Subject subject) { + return this.contextsCache.get(subject); } @Override protected void invalidateCache(Subject subject) { - QueryOptionsCache cache = this.subjectCaches.getIfPresent(subject); - if (cache != null) { - cache.invalidate(); - } + this.contextsCache.invalidate(subject); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongePlayerCalculator.java b/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongePlayerCalculator.java index 92af5d750..56f255bdf 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongePlayerCalculator.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/context/SpongePlayerCalculator.java @@ -37,81 +37,57 @@ import net.luckperms.api.context.DefaultContextKeys; import net.luckperms.api.context.ImmutableContextSet; import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.CatalogType; -import org.spongepowered.api.CatalogTypes; import org.spongepowered.api.Game; -import org.spongepowered.api.command.CommandSource; -import org.spongepowered.api.data.key.Keys; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.data.Keys; import org.spongepowered.api.data.value.ValueContainer; import org.spongepowered.api.entity.Entity; -import org.spongepowered.api.entity.living.Humanoid; -import org.spongepowered.api.entity.living.player.gamemode.GameMode; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; -import org.spongepowered.api.event.entity.MoveEntityEvent; -import org.spongepowered.api.event.entity.living.humanoid.ChangeGameModeEvent; +import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; +import org.spongepowered.api.registry.RegistryTypes; import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.world.DimensionType; import org.spongepowered.api.world.Locatable; import org.spongepowered.api.world.World; - -import java.util.Set; +import org.spongepowered.api.world.server.ServerWorld; public class SpongePlayerCalculator implements ContextCalculator { private final LPSpongePlugin plugin; - private final boolean gamemode; - private final boolean world; - private final boolean dimensionType; - - public SpongePlayerCalculator(LPSpongePlugin plugin, Set disabled) { + public SpongePlayerCalculator(LPSpongePlugin plugin) { this.plugin = plugin; - this.gamemode = !disabled.contains(DefaultContextKeys.GAMEMODE_KEY); - this.world = !disabled.contains(DefaultContextKeys.WORLD_KEY); - this.dimensionType = !disabled.contains(DefaultContextKeys.DIMENSION_TYPE_KEY); } @Override public void calculate(@NonNull Subject subject, @NonNull ContextConsumer consumer) { - CommandSource source = subject.getCommandSource().orElse(null); - if (source == null) { - return; - } - - if (source instanceof Locatable) { - World world = ((Locatable) source).getWorld(); - if (this.dimensionType) { - consumer.accept(DefaultContextKeys.DIMENSION_TYPE_KEY, getCatalogTypeName(world.getDimension().getType())); - } - if (this.world) { - this.plugin.getConfiguration().get(ConfigKeys.WORLD_REWRITES).rewriteAndSubmit(world.getName(), consumer); + if (subject instanceof Locatable) { + World world = ((Locatable) subject).world(); + consumer.accept(DefaultContextKeys.DIMENSION_TYPE_KEY, getContextKey(world.worldType().key(RegistryTypes.WORLD_TYPE))); + if (world instanceof ServerWorld) { + this.plugin.getConfiguration().get(ConfigKeys.WORLD_REWRITES).rewriteAndSubmit(getContextKey(((ServerWorld) world).key()), consumer); } } - if (this.gamemode && source instanceof ValueContainer) { - ValueContainer valueContainer = (ValueContainer) source; - valueContainer.get(Keys.GAME_MODE).ifPresent(mode -> consumer.accept(DefaultContextKeys.GAMEMODE_KEY, getCatalogTypeName(mode))); + if (subject instanceof ValueContainer) { + ValueContainer valueContainer = (ValueContainer) subject; + valueContainer.get(Keys.GAME_MODE).ifPresent(mode -> consumer.accept(DefaultContextKeys.GAMEMODE_KEY, getContextKey(mode.key(RegistryTypes.GAME_MODE)))); } } @Override - public @NonNull ContextSet estimatePotentialContexts() { + public ContextSet estimatePotentialContexts() { ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl(); Game game = this.plugin.getBootstrap().getGame(); - if (this.gamemode) { - for (GameMode mode : game.getRegistry().getAllOf(CatalogTypes.GAME_MODE)) { - builder.add(DefaultContextKeys.GAMEMODE_KEY, getCatalogTypeName(mode)); - } - } - if (this.dimensionType) { - for (DimensionType dim : game.getRegistry().getAllOf(CatalogTypes.DIMENSION_TYPE)) { - builder.add(DefaultContextKeys.DIMENSION_TYPE_KEY, getCatalogTypeName(dim)); - } - } - if (this.world && game.isServerAvailable()) { - for (World world : game.getServer().getWorlds()) { - String worldName = world.getName(); + game.registry(RegistryTypes.GAME_MODE).stream().forEach(mode -> { + builder.add(DefaultContextKeys.GAMEMODE_KEY, getContextKey(mode.key(RegistryTypes.GAME_MODE))); + }); + game.registry(RegistryTypes.WORLD_TYPE).stream().forEach(dim -> { + builder.add(DefaultContextKeys.DIMENSION_TYPE_KEY, getContextKey(dim.key(RegistryTypes.WORLD_TYPE))); + }); + if (game.isServerAvailable()) { + for (ServerWorld world : game.server().worldManager().worlds()) { + String worldName = getContextKey(world.key()); if (Context.isValidValue(worldName)) { builder.add(DefaultContextKeys.WORLD_KEY, worldName); } @@ -121,37 +97,29 @@ public class SpongePlayerCalculator implements ContextCalculator { return builder.build(); } - private static String getCatalogTypeName(CatalogType type) { - String id = type.getId(); - if (id.startsWith("minecraft:")){ - return id.substring("minecraft:".length()); + private static String getContextKey(ResourceKey key) { + if (key.namespace().equals("minecraft")) { + return key.value(); } - return id; + return key.formatted(); } @Listener(order = Order.LAST) - public void onWorldChange(MoveEntityEvent.Teleport e) { - if (!(this.world || this.dimensionType)) { - return; - } - - Entity targetEntity = e.getTargetEntity(); + public void onWorldChange(ChangeEntityWorldEvent.Post e) { + Entity targetEntity = e.entity(); if (!(targetEntity instanceof Subject)) { return; } - if (e.getFromTransform().getExtent().equals(e.getToTransform().getExtent())) { - return; - } - this.plugin.getContextManager().signalContextUpdate((Subject) targetEntity); } - @Listener(order = Order.LAST) - public void onGameModeChange(ChangeGameModeEvent e) { - Humanoid targetEntity = e.getTargetEntity(); - if (this.gamemode && targetEntity instanceof Subject) { - this.plugin.getContextManager().signalContextUpdate((Subject) targetEntity); - } - } + // TODO: find replacement + //@Listener(order = Order.LAST) + //public void onGameModeChange(ChangeGameModeEvent e) { + // Humanoid targetEntity = e.getHumanoid(); + // if (targetEntity instanceof Subject) { + // this.plugin.getContextManager().signalContextUpdate((Subject) targetEntity); + // } + //} } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeCommandListUpdater.java b/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeCommandListUpdater.java new file mode 100644 index 000000000..8f0a28bef --- /dev/null +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeCommandListUpdater.java @@ -0,0 +1,108 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * 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.sponge.listeners; + +import com.github.benmanes.caffeine.cache.LoadingCache; + +import me.lucko.luckperms.common.cache.BufferedRequest; +import me.lucko.luckperms.common.event.LuckPermsEventListener; +import me.lucko.luckperms.common.util.CaffeineFactory; +import me.lucko.luckperms.sponge.LPSpongePlugin; + +import net.luckperms.api.event.EventBus; +import net.luckperms.api.event.context.ContextUpdateEvent; +import net.luckperms.api.event.user.UserDataRecalculateEvent; + +import org.spongepowered.api.command.manager.CommandManager; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * Calls {@link CommandManager#updateCommandTreeForPlayer(ServerPlayer)} + * when a players permissions change. + */ +public class SpongeCommandListUpdater implements LuckPermsEventListener { + + private final LPSpongePlugin plugin; + private final LoadingCache sendingBuffers = CaffeineFactory.newBuilder() + .expireAfterAccess(10, TimeUnit.SECONDS) + .build(SendBuffer::new); + + public SpongeCommandListUpdater(LPSpongePlugin plugin) { + this.plugin = plugin; + } + + @Override + public void bind(EventBus bus) { + bus.subscribe(UserDataRecalculateEvent.class, this::onUserDataRecalculate); + bus.subscribe(ContextUpdateEvent.class, this::onContextUpdate); + } + + private void onUserDataRecalculate(UserDataRecalculateEvent e) { + requestUpdate(e.getUser().getUniqueId()); + } + + private void onContextUpdate(ContextUpdateEvent e) { + e.getSubject(ServerPlayer.class).ifPresent(p -> requestUpdate(p.uniqueId())); + } + + private void requestUpdate(UUID uniqueId) { + if (!this.plugin.getBootstrap().isPlayerOnline(uniqueId)) { + return; + } + + // Buffer the request to send a commands update. + this.sendingBuffers.get(uniqueId).request(); + } + + // Called when the buffer times out. + private void sendUpdate(UUID uniqueId) { + this.plugin.getBootstrap().getScheduler().sync().execute(() -> { + ServerPlayer player = this.plugin.getBootstrap().getPlayer(uniqueId).orElse(null); + if (player != null) { + CommandManager commandManager = this.plugin.getBootstrap().getGame().server().commandManager(); + commandManager.updateCommandTreeForPlayer(player); + } + }); + } + + private final class SendBuffer extends BufferedRequest { + private final UUID uniqueId; + + SendBuffer(UUID uniqueId) { + super(500, TimeUnit.MILLISECONDS, SpongeCommandListUpdater.this.plugin.getBootstrap().getScheduler()); + this.uniqueId = uniqueId; + } + + @Override + protected Void perform() { + sendUpdate(this.uniqueId); + return null; + } + } +} diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeConnectionListener.java b/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeConnectionListener.java index ac6e9fbe6..3a929ed7a 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeConnectionListener.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongeConnectionListener.java @@ -31,14 +31,11 @@ import me.lucko.luckperms.common.locale.TranslationManager; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener; import me.lucko.luckperms.sponge.LPSpongePlugin; -import me.lucko.luckperms.sponge.SpongeSenderFactory; - -import net.kyori.adventure.text.Component; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; import org.spongepowered.api.event.filter.IsCancelled; -import org.spongepowered.api.event.network.ClientConnectionEvent; +import org.spongepowered.api.event.network.ServerSideConnectionEvent; import org.spongepowered.api.profile.GameProfile; import org.spongepowered.api.util.Tristate; @@ -60,22 +57,22 @@ public class SpongeConnectionListener extends AbstractConnectionListener { @Listener(order = Order.EARLY) @IsCancelled(Tristate.UNDEFINED) - public void onClientAuth(ClientConnectionEvent.Auth e) { + public void onClientAuth(ServerSideConnectionEvent.Auth e) { /* Called when the player first attempts a connection with the server. Listening on AFTER_PRE priority to allow plugins to modify username / UUID data here. (auth plugins) Also, give other plugins a chance to cancel the event. */ - final GameProfile profile = e.getProfile(); - final String username = profile.getName().orElseThrow(() -> new RuntimeException("No username present for user " + profile.getUniqueId())); + final GameProfile profile = e.profile(); + final String username = profile.name().orElseThrow(() -> new RuntimeException("No username present for user " + profile.uniqueId())); if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) { - this.plugin.getLogger().info("Processing auth event for " + profile.getUniqueId() + " - " + profile.getName()); + this.plugin.getLogger().info("Processing auth event for " + profile.uniqueId() + " - " + profile.name()); } if (e.isCancelled()) { // another plugin has disallowed the login. - this.plugin.getLogger().info("Another plugin has cancelled the connection for " + profile.getUniqueId() + " - " + username + ". No permissions data will be loaded."); - this.deniedAsyncLogin.add(profile.getUniqueId()); + this.plugin.getLogger().info("Another plugin has cancelled the connection for " + profile.uniqueId() + " - " + username + ". No permissions data will be loaded."); + this.deniedAsyncLogin.add(profile.uniqueId()); return; } @@ -89,34 +86,32 @@ public class SpongeConnectionListener extends AbstractConnectionListener { - creating a user instance in the UserManager for this connection. - setting up cached data. */ try { - User user = loadUser(profile.getUniqueId(), username); - recordConnection(profile.getUniqueId()); - this.plugin.getEventDispatcher().dispatchPlayerLoginProcess(profile.getUniqueId(), username, user); + User user = loadUser(profile.uniqueId(), username); + recordConnection(profile.uniqueId()); + this.plugin.getEventDispatcher().dispatchPlayerLoginProcess(profile.uniqueId(), username, user); } catch (Exception ex) { - this.plugin.getLogger().severe("Exception occurred whilst loading data for " + profile.getUniqueId() + " - " + profile.getName(), ex); + this.plugin.getLogger().severe("Exception occurred whilst loading data for " + profile.uniqueId() + " - " + profile.name(), ex); - this.deniedAsyncLogin.add(profile.getUniqueId()); + this.deniedAsyncLogin.add(profile.uniqueId()); e.setCancelled(true); - e.setMessageCancelled(false); - Component reason = TranslationManager.render(Message.LOADING_DATABASE_ERROR.build()); - e.setMessage(SpongeSenderFactory.toNativeText(reason)); - this.plugin.getEventDispatcher().dispatchPlayerLoginProcess(profile.getUniqueId(), username, null); + e.setMessage(TranslationManager.render(Message.LOADING_DATABASE_ERROR.build())); + this.plugin.getEventDispatcher().dispatchPlayerLoginProcess(profile.uniqueId(), username, null); } } @Listener(order = Order.LAST) @IsCancelled(Tristate.UNDEFINED) - public void onClientAuthMonitor(ClientConnectionEvent.Auth e) { + public void onClientAuthMonitor(ServerSideConnectionEvent.Auth e) { /* Listen to see if the event was cancelled after we initially handled the connection If the connection was cancelled here, we need to do something to clean up the data that was loaded. */ // Check to see if this connection was denied at LOW. - if (this.deniedAsyncLogin.remove(e.getProfile().getUniqueId())) { + if (this.deniedAsyncLogin.remove(e.profile().uniqueId())) { // This is a problem, as they were denied at low priority, but are now being allowed. if (e.isCancelled()) { - this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getProfile().getUniqueId()); + this.plugin.getLogger().severe("Player connection was re-allowed for " + e.profile().uniqueId()); e.setCancelled(true); } } @@ -124,59 +119,57 @@ public class SpongeConnectionListener extends AbstractConnectionListener { @Listener(order = Order.FIRST) @IsCancelled(Tristate.UNDEFINED) - public void onClientLogin(ClientConnectionEvent.Login e) { + public void onClientLogin(ServerSideConnectionEvent.Login e) { /* Called when the player starts logging into the server. At this point, the users data should be present and loaded. Listening on LOW priority to allow plugins to further modify data here. (auth plugins, etc.) */ - final GameProfile profile = e.getProfile(); + final GameProfile profile = e.profile(); if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) { - this.plugin.getLogger().info("Processing login event for " + profile.getUniqueId() + " - " + profile.getName()); + this.plugin.getLogger().info("Processing login event for " + profile.uniqueId() + " - " + profile.name()); } - final User user = this.plugin.getUserManager().getIfLoaded(profile.getUniqueId()); + final User user = this.plugin.getUserManager().getIfLoaded(profile.uniqueId()); /* User instance is null for whatever reason. Could be that it was unloaded between asyncpre and now. */ if (user == null) { - this.deniedLogin.add(profile.getUniqueId()); + this.deniedLogin.add(profile.uniqueId()); - if (!getUniqueConnections().contains(profile.getUniqueId())) { - this.plugin.getLogger().warn("User " + profile.getUniqueId() + " - " + profile.getName() + + if (!getUniqueConnections().contains(profile.uniqueId())) { + this.plugin.getLogger().warn("User " + profile.uniqueId() + " - " + profile.name() + " doesn't have data pre-loaded, they have never been processed during pre-login in this session." + " - denying login."); } else { - this.plugin.getLogger().warn("User " + profile.getUniqueId() + " - " + profile.getName() + + this.plugin.getLogger().warn("User " + profile.uniqueId() + " - " + profile.name() + " doesn't currently have data pre-loaded, but they have been processed before in this session." + " - denying login."); } e.setCancelled(true); - e.setMessageCancelled(false); - Component reason = TranslationManager.render(Message.LOADING_STATE_ERROR.build()); - e.setMessage(SpongeSenderFactory.toNativeText(reason)); + e.setMessage(TranslationManager.render(Message.LOADING_STATE_ERROR.build())); } } @Listener(order = Order.LAST) @IsCancelled(Tristate.UNDEFINED) - public void onClientLoginMonitor(ClientConnectionEvent.Login e) { + public void onClientLoginMonitor(ServerSideConnectionEvent.Login e) { /* Listen to see if the event was cancelled after we initially handled the login If the connection was cancelled here, we need to do something to clean up the data that was loaded. */ // Check to see if this connection was denied at LOW. Even if it was denied at LOW, their data will still be present. - if (this.deniedLogin.remove(e.getProfile().getUniqueId())) { + if (this.deniedLogin.remove(e.profile().uniqueId())) { // This is a problem, as they were denied at low priority, but are now being allowed. if (!e.isCancelled()) { - this.plugin.getLogger().severe("Player connection was re-allowed for " + e.getProfile().getUniqueId()); + this.plugin.getLogger().severe("Player connection was re-allowed for " + e.profile().uniqueId()); e.setCancelled(true); } } } @Listener(order = Order.POST) - public void onClientLeave(ClientConnectionEvent.Disconnect e) { - handleDisconnect(e.getTargetEntity().getUniqueId()); + public void onClientLeave(ServerSideConnectionEvent.Disconnect e) { + handleDisconnect(e.player().uniqueId()); } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongePlatformListener.java b/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongePlatformListener.java index 0ca6d58e5..6184d10ca 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongePlatformListener.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/listeners/SpongePlatformListener.java @@ -28,9 +28,9 @@ package me.lucko.luckperms.sponge.listeners; import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.sponge.LPSpongePlugin; -import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.command.CommandCause; import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.command.SendCommandEvent; +import org.spongepowered.api.event.command.ExecuteCommandEvent; import java.util.Locale; @@ -42,13 +42,12 @@ public class SpongePlatformListener { } @Listener - public void onSendCommand(SendCommandEvent e) { - CommandSource source = e.getCause().first(CommandSource.class).orElse(null); - if (source == null) return; + public void onSendCommand(ExecuteCommandEvent e) { + CommandCause source = e.commandCause(); - final String name = e.getCommand().toLowerCase(Locale.ROOT); - if ((name.equals("op") || name.equals("minecraft:op")) && source.hasPermission("minecraft.command.op") || (name.equals("deop") || name.equals("minecraft:deop")) && source.hasPermission("minecraft.command.deop")) { - Message.OP_DISABLED_SPONGE.send(this.plugin.getSenderFactory().wrap(source)); + final String name = e.command().toLowerCase(Locale.ROOT); + if (((name.equals("op") || name.equals("minecraft:op")) && source.hasPermission("minecraft.command.op")) || ((name.equals("deop") || name.equals("minecraft:deop")) && source.hasPermission("minecraft.command.deop"))) { + Message.OP_DISABLED_SPONGE.send(this.plugin.getSenderFactory().wrap(source.audience())); } } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/PluginMessageMessenger.java b/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/PluginMessageMessenger.java index ca2707277..609a70d71 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/PluginMessageMessenger.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/messaging/PluginMessageMessenger.java @@ -34,12 +34,14 @@ import net.luckperms.api.messenger.Messenger; import net.luckperms.api.messenger.message.OutgoingMessage; import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.Platform; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.network.ChannelBinding; -import org.spongepowered.api.network.ChannelBuf; -import org.spongepowered.api.network.RawDataListener; -import org.spongepowered.api.network.RemoteConnection; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.network.EngineConnectionSide; +import org.spongepowered.api.network.ServerSideConnection; +import org.spongepowered.api.network.channel.ChannelBuf; +import org.spongepowered.api.network.channel.raw.RawDataChannel; +import org.spongepowered.api.network.channel.raw.play.RawPlayDataHandler; +import org.spongepowered.api.scheduler.Task; import java.util.Collection; import java.util.concurrent.TimeUnit; @@ -47,13 +49,13 @@ import java.util.concurrent.TimeUnit; /** * An implementation of {@link Messenger} using the plugin messaging channels. */ -public class PluginMessageMessenger implements Messenger, RawDataListener { - private static final String CHANNEL = "luckperms:update"; +public class PluginMessageMessenger implements Messenger, RawPlayDataHandler { + private static final ResourceKey CHANNEL = ResourceKey.of("luckperms", "update"); private final LPSpongePlugin plugin; private final IncomingMessageConsumer consumer; - private ChannelBinding.RawDataChannel channel = null; + private RawDataChannel channel = null; public PluginMessageMessenger(LPSpongePlugin plugin, IncomingMessageConsumer consumer) { this.plugin = plugin; @@ -61,37 +63,43 @@ public class PluginMessageMessenger implements Messenger, RawDataListener { } public void init() { - this.channel = this.plugin.getBootstrap().getGame().getChannelRegistrar().createRawChannel(this.plugin.getBootstrap(), CHANNEL); - this.channel.addListener(Platform.Type.SERVER, this); + this.channel = this.plugin.getBootstrap().getGame().channelManager().ofType(CHANNEL, RawDataChannel.class); + this.channel.play().addHandler(EngineConnectionSide.SERVER, this); } @Override public void close() { if (this.channel != null) { - this.plugin.getBootstrap().getGame().getChannelRegistrar().unbindChannel(this.channel); + this.channel.play().removeHandler(this); } } @Override public void sendOutgoingMessage(@NonNull OutgoingMessage outgoingMessage) { - this.plugin.getBootstrap().getSpongeScheduler().createTaskBuilder().interval(10, TimeUnit.SECONDS).execute(task -> { - if (!this.plugin.getBootstrap().getGame().isServerAvailable()) { - return; - } + Task t = Task.builder() + .interval(10, TimeUnit.SECONDS) + .execute(task -> { + if (!this.plugin.getBootstrap().getGame().isServerAvailable()) { + return; + } - Collection players = this.plugin.getBootstrap().getGame().getServer().getOnlinePlayers(); - Player p = Iterables.getFirst(players, null); - if (p == null) { - return; - } + Collection players = this.plugin.getBootstrap().getGame().server().onlinePlayers(); + ServerPlayer p = Iterables.getFirst(players, null); + if (p == null) { + return; + } - this.channel.sendTo(p, buf -> buf.writeUTF(outgoingMessage.asEncodedString())); - task.cancel(); - }).submit(this.plugin.getBootstrap()); + this.channel.play().sendTo(p, buf -> buf.writeUTF(outgoingMessage.asEncodedString())); + task.cancel(); + }) + .plugin(this.plugin.getBootstrap().getPluginContainer()) + .build(); + + this.plugin.getBootstrap().getScheduler().getSyncScheduler().submit(t); } @Override - public void handlePayload(@NonNull ChannelBuf buf, @NonNull RemoteConnection connection, Platform.@NonNull Type type) { + public void handlePayload(ChannelBuf buf, ServerSideConnection connection) { String msg = buf.readUTF(); this.consumer.consumeIncomingMessageAsString(msg); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeGroupManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeGroupManager.java index 735ebe38f..5c9c351b6 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeGroupManager.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeGroupManager.java @@ -59,7 +59,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; @@ -160,7 +159,7 @@ public class SpongeGroupManager extends AbstractGroupManager implem } @Override - public CompletableFuture> loadSubjects(Set identifiers) { + public CompletableFuture> loadSubjects(Iterable identifiers) { return CompletableFuture.supplyAsync(() -> { ImmutableSet.Builder subjects = ImmutableSet.builder(); for (String id : identifiers) { diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeUserManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeUserManager.java index 330dd9913..10d6aa60f 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeUserManager.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/model/manager/SpongeUserManager.java @@ -58,7 +58,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -170,7 +169,7 @@ public class SpongeUserManager extends AbstractUserManager implement } @Override - public CompletableFuture> loadSubjects(Set identifiers) { + public CompletableFuture> loadSubjects(Iterable identifiers) { return CompletableFuture.supplyAsync(() -> { ImmutableSet.Builder subjects = ImmutableSet.builder(); for (String id : identifiers) { diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java index 8e87e41bf..8a47af6d1 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/LuckPermsService.java @@ -39,19 +39,25 @@ import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; import me.lucko.luckperms.sponge.service.model.LPPermissionService; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; +import me.lucko.luckperms.sponge.service.model.LPSubjectData; import me.lucko.luckperms.sponge.service.model.LPSubjectReference; import me.lucko.luckperms.sponge.service.model.SimplePermissionDescription; +import me.lucko.luckperms.sponge.service.model.SubjectDataUpdateEventImpl; +import me.lucko.luckperms.sponge.service.model.TemporaryCauseHolderSubject; import me.lucko.luckperms.sponge.service.model.persisted.DefaultsCollection; import me.lucko.luckperms.sponge.service.model.persisted.PersistedCollection; import me.lucko.luckperms.sponge.service.model.persisted.SubjectStorage; import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory; -import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.plugin.PluginContainer; +import net.kyori.adventure.text.Component; +import net.luckperms.api.context.ImmutableContextSet; + +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.api.event.Cause; +import org.spongepowered.api.event.permission.SubjectDataUpdateEvent; import org.spongepowered.api.service.context.ContextCalculator; -import org.spongepowered.api.service.permission.PermissionService; import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.api.text.Text; +import org.spongepowered.plugin.PluginContainer; import java.util.HashMap; import java.util.Locale; @@ -74,7 +80,7 @@ public class LuckPermsService implements LPPermissionService { /** * A cached proxy of this instance */ - private final PermissionService spongeProxy; + private final PermissionAndContextService spongeProxy; /** * Reference factory, used to obtain {@link LPSubjectReference}s. @@ -135,7 +141,7 @@ public class LuckPermsService implements LPPermissionService { } @Override - public PermissionService sponge() { + public PermissionAndContextService sponge() { return this.spongeProxy; } @@ -145,7 +151,7 @@ public class LuckPermsService implements LPPermissionService { } @Override - public ContextManager getContextManager() { + public ContextManager getContextManager() { return this.plugin.getContextManager(); } @@ -195,7 +201,7 @@ public class LuckPermsService implements LPPermissionService { } @Override - public LPPermissionDescription registerPermissionDescription(String id, Text description, PluginContainer owner) { + public LPPermissionDescription registerPermissionDescription(String id, Component description, PluginContainer owner) { Objects.requireNonNull(id, "id"); SimplePermissionDescription desc = new SimplePermissionDescription(this, id, description, owner); this.permissionDescriptions.put(id, desc); @@ -225,11 +231,30 @@ public class LuckPermsService implements LPPermissionService { } @Override - public void registerContextCalculator(ContextCalculator calculator) { + public void registerContextCalculator(ContextCalculator calculator) { Objects.requireNonNull(calculator); this.plugin.getContextManager().registerCalculator(new ContextCalculatorProxy(calculator)); } + @Override + public ImmutableContextSet getContextsForCause(Cause cause) { + Objects.requireNonNull(cause, "cause"); + return this.plugin.getContextManager().getContext(new TemporaryCauseHolderSubject(cause)); + } + + @Override + public ImmutableContextSet getContextsForCurrentCause() { + return getContextsForCause(this.plugin.getBootstrap().getGame().server().causeStackManager().currentCause()); + } + + @Override + public void fireUpdateEvent(LPSubjectData subjectData) { + this.plugin.getBootstrap().getScheduler().executeAsync(() -> { + SubjectDataUpdateEvent event = new SubjectDataUpdateEventImpl(this.plugin, subjectData); + this.plugin.getBootstrap().getGame().eventManager().post(event); + }); + } + @Override public void invalidateAllCaches() { for (LPSubjectCollection collection : this.collections.values()) { diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/ProxyFactory.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/ProxyFactory.java index f72b2aa4b..5bec3ce32 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/ProxyFactory.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/ProxyFactory.java @@ -27,16 +27,19 @@ package me.lucko.luckperms.sponge.service; import me.lucko.luckperms.sponge.service.model.LPPermissionDescription; import me.lucko.luckperms.sponge.service.model.LPPermissionService; +import me.lucko.luckperms.sponge.service.model.LPProxiedSubject; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; import me.lucko.luckperms.sponge.service.model.LPSubjectData; -import me.lucko.luckperms.sponge.service.model.ProxiedSubject; +import me.lucko.luckperms.sponge.service.proxy.api8.PermissionDescriptionProxy; +import me.lucko.luckperms.sponge.service.proxy.api8.PermissionServiceProxy; +import me.lucko.luckperms.sponge.service.proxy.api8.SubjectCollectionProxy; +import me.lucko.luckperms.sponge.service.proxy.api8.SubjectDataProxy; +import me.lucko.luckperms.sponge.service.proxy.api8.SubjectProxy; import net.luckperms.api.model.data.DataType; import org.spongepowered.api.service.permission.PermissionDescription; -import org.spongepowered.api.service.permission.PermissionService; -import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.SubjectCollection; import org.spongepowered.api.service.permission.SubjectData; @@ -46,51 +49,25 @@ import org.spongepowered.api.service.permission.SubjectData; public final class ProxyFactory { private ProxyFactory() {} - private static final boolean IS_API_7 = isApi7(); - private static boolean isApi7() { - try { - Subject.class.getDeclaredMethod("asSubjectReference"); - return true; - } catch (NoSuchMethodException e) { - return false; - } - } - - public static PermissionService toSponge(LPPermissionService luckPerms) { - return IS_API_7 ? - new me.lucko.luckperms.sponge.service.proxy.api7.PermissionServiceProxy(luckPerms) : - new me.lucko.luckperms.sponge.service.proxy.api6.PermissionServiceProxy(luckPerms); + public static PermissionAndContextService toSponge(LPPermissionService luckPerms) { + return new PermissionServiceProxy(luckPerms); } public static SubjectCollection toSponge(LPSubjectCollection luckPerms) { - return IS_API_7 ? - new me.lucko.luckperms.sponge.service.proxy.api7.SubjectCollectionProxy(luckPerms) : - new me.lucko.luckperms.sponge.service.proxy.api6.SubjectCollectionProxy(luckPerms.getService(), luckPerms); + return new SubjectCollectionProxy(luckPerms); } - public static ProxiedSubject toSponge(LPSubject luckPerms) { - return IS_API_7 ? - new me.lucko.luckperms.sponge.service.proxy.api7.SubjectProxy(luckPerms.getService(), luckPerms.toReference()) : - new me.lucko.luckperms.sponge.service.proxy.api6.SubjectProxy(luckPerms.getService(), luckPerms.toReference()); + public static LPProxiedSubject toSponge(LPSubject luckPerms) { + return new SubjectProxy(luckPerms.getService(), luckPerms.toReference()); } public static SubjectData toSponge(LPSubjectData luckPerms) { LPSubject parentSubject = luckPerms.getParentSubject(); - return IS_API_7 ? - new me.lucko.luckperms.sponge.service.proxy.api7.SubjectDataProxy(parentSubject.getService(), parentSubject.toReference(), luckPerms.getType() == DataType.NORMAL) : - new me.lucko.luckperms.sponge.service.proxy.api6.SubjectDataProxy(parentSubject.getService(), parentSubject.toReference(), luckPerms.getType() == DataType.NORMAL); + return new SubjectDataProxy(parentSubject.getService(), parentSubject.toReference(), luckPerms.getType() == DataType.NORMAL); } public static PermissionDescription toSponge(LPPermissionDescription luckPerms) { - return IS_API_7 ? - new me.lucko.luckperms.sponge.service.proxy.api7.PermissionDescriptionProxy(luckPerms.getService(), luckPerms) : - new me.lucko.luckperms.sponge.service.proxy.api6.PermissionDescriptionProxy(luckPerms.getService(), luckPerms); - } - - public static LPPermissionDescription registerDescription(LPPermissionService service, PermissionDescription description) { - return IS_API_7 ? - me.lucko.luckperms.sponge.service.proxy.api7.DescriptionBuilder.registerDescription(service, description) : - me.lucko.luckperms.sponge.service.proxy.api6.DescriptionBuilder.registerDescription(service, description); + return new PermissionDescriptionProxy(luckPerms.getService(), luckPerms); } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/ContextCalculatorProxy.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/ContextCalculatorProxy.java index 8deb8f9e3..a7d2d089a 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/ContextCalculatorProxy.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/ContextCalculatorProxy.java @@ -30,24 +30,37 @@ import me.lucko.luckperms.common.context.calculator.ForwardingContextCalculator; import net.luckperms.api.context.ContextConsumer; import org.checkerframework.checker.nullness.qual.NonNull; +import org.spongepowered.api.event.Cause; +import org.spongepowered.api.event.EventContext; +import org.spongepowered.api.event.EventContextKeys; import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.ContextCalculator; import org.spongepowered.api.service.permission.Subject; -import java.util.Collection; -import java.util.Iterator; -import java.util.Set; +import java.util.function.Consumer; public class ContextCalculatorProxy implements ForwardingContextCalculator { - private final ContextCalculator delegate; + private final ContextCalculator delegate; - public ContextCalculatorProxy(ContextCalculator delegate) { + public ContextCalculatorProxy(ContextCalculator delegate) { this.delegate = delegate; } @Override public void calculate(@NonNull Subject subject, @NonNull ContextConsumer consumer) { - this.delegate.accumulateContexts(subject, new ForwardingContextSet(consumer)); + EventContext eventContext = EventContext.builder() + .add(EventContextKeys.SUBJECT, subject) + .build(); + + Cause cause = Cause.builder() + .append(subject) + .build(eventContext); + + calculate(cause, consumer); + } + + public void calculate(@NonNull Cause cause, @NonNull ContextConsumer consumer) { + this.delegate.accumulateContexts(cause, new ForwardingContextConsumer(consumer)); } @Override @@ -55,42 +68,20 @@ public class ContextCalculatorProxy implements ForwardingContextCalculator { + private static final class ForwardingContextConsumer implements Consumer { private final ContextConsumer consumer; - private ForwardingContextSet(ContextConsumer consumer) { + private ForwardingContextConsumer(ContextConsumer consumer) { this.consumer = consumer; } @Override - public boolean add(Context context) { - if (!net.luckperms.api.context.Context.isValidKey(context.getKey()) || - !net.luckperms.api.context.Context.isValidValue(context.getValue())) { - return false; + public void accept(Context context) { + if (net.luckperms.api.context.Context.isValidKey(context.getKey()) && + net.luckperms.api.context.Context.isValidValue(context.getValue())) { + this.consumer.accept(context.getKey(), context.getValue()); } - this.consumer.accept(context.getKey(), context.getValue()); - return true; } - - @Override - public boolean addAll(@NonNull Collection c) { - for (Context context : c) { - add(context); - } - return true; - } - - @Override public int size() { throw new UnsupportedOperationException(); } - @Override public boolean isEmpty() { throw new UnsupportedOperationException(); } - @Override public boolean contains(Object o) { throw new UnsupportedOperationException(); } - @Override public @NonNull Iterator iterator() { throw new UnsupportedOperationException(); } - @Override public @NonNull Object[] toArray() { throw new UnsupportedOperationException(); } - @Override public @NonNull T[] toArray(@NonNull T[] a) { throw new UnsupportedOperationException(); } - @Override public boolean remove(Object o) { throw new UnsupportedOperationException(); } - @Override public boolean containsAll(@NonNull Collection c) { throw new UnsupportedOperationException(); } - @Override public boolean retainAll(@NonNull Collection c) { throw new UnsupportedOperationException(); } - @Override public boolean removeAll(@NonNull Collection c) { throw new UnsupportedOperationException(); } - @Override public void clear() { throw new UnsupportedOperationException(); } } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/SimplePermissionDescription.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/SimplePermissionDescription.java index a297af14f..a2af9021f 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/SimplePermissionDescription.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/SimplePermissionDescription.java @@ -27,10 +27,11 @@ package me.lucko.luckperms.sponge.service.model; import me.lucko.luckperms.sponge.service.ProxyFactory; +import net.kyori.adventure.text.Component; + import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.service.permission.PermissionDescription; -import org.spongepowered.api.text.Text; +import org.spongepowered.plugin.PluginContainer; import java.util.Map; import java.util.Objects; @@ -41,12 +42,12 @@ public final class SimplePermissionDescription implements LPPermissionDescriptio private final LPPermissionService service; private final String id; - private final @Nullable Text description; + private final @Nullable Component description; private final @Nullable PluginContainer owner; private PermissionDescription spongeProxy = null; - public SimplePermissionDescription(LPPermissionService service, String id, @Nullable Text description, @Nullable PluginContainer owner) { + public SimplePermissionDescription(LPPermissionService service, String id, @Nullable Component description, @Nullable PluginContainer owner) { this.service = service; this.id = Objects.requireNonNull(id, "id"); this.description = description; @@ -72,7 +73,7 @@ public final class SimplePermissionDescription implements LPPermissionDescriptio } @Override - public Optional getDescription() { + public Optional getDescription() { return Optional.ofNullable(this.description); } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/events/LPSubjectDataUpdateEvent.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/SubjectDataUpdateEventImpl.java similarity index 81% rename from sponge/src/main/java/me/lucko/luckperms/sponge/service/events/LPSubjectDataUpdateEvent.java rename to sponge/src/main/java/me/lucko/luckperms/sponge/service/model/SubjectDataUpdateEventImpl.java index b2aaa353c..68f736a26 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/events/LPSubjectDataUpdateEvent.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/SubjectDataUpdateEventImpl.java @@ -23,30 +23,29 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.events; +package me.lucko.luckperms.sponge.service.model; import me.lucko.luckperms.sponge.LPSpongePlugin; -import me.lucko.luckperms.sponge.service.model.LPSubjectData; import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.event.cause.Cause; -import org.spongepowered.api.event.cause.EventContext; -import org.spongepowered.api.event.cause.EventContextKeys; +import org.spongepowered.api.event.Cause; +import org.spongepowered.api.event.EventContext; +import org.spongepowered.api.event.EventContextKeys; import org.spongepowered.api.event.impl.AbstractEvent; import org.spongepowered.api.event.permission.SubjectDataUpdateEvent; import org.spongepowered.api.service.permission.SubjectData; -public class LPSubjectDataUpdateEvent extends AbstractEvent implements SubjectDataUpdateEvent { +public class SubjectDataUpdateEventImpl extends AbstractEvent implements SubjectDataUpdateEvent { private final LPSpongePlugin plugin; private final LPSubjectData subjectData; - public LPSubjectDataUpdateEvent(LPSpongePlugin plugin, LPSubjectData subjectData) { + public SubjectDataUpdateEventImpl(LPSpongePlugin plugin, LPSubjectData subjectData) { this.plugin = plugin; this.subjectData = subjectData; } @Override - public SubjectData getUpdatedData() { + public SubjectData updatedData() { return this.subjectData.sponge(); } @@ -55,7 +54,7 @@ public class LPSubjectDataUpdateEvent extends AbstractEvent implements SubjectDa } @Override - public @NonNull Cause getCause() { + public @NonNull Cause cause() { EventContext eventContext = EventContext.builder() .add(EventContextKeys.PLUGIN, this.plugin.getBootstrap().getPluginContainer()) .build(); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/TemporaryCauseHolderSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/TemporaryCauseHolderSubject.java new file mode 100644 index 000000000..a84c5f91f --- /dev/null +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/TemporaryCauseHolderSubject.java @@ -0,0 +1,108 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * 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.sponge.service.model; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.event.Cause; +import org.spongepowered.api.event.EventContextKeys; +import org.spongepowered.api.service.context.Context; +import org.spongepowered.api.service.permission.Subject; +import org.spongepowered.api.service.permission.SubjectCollection; +import org.spongepowered.api.service.permission.SubjectData; +import org.spongepowered.api.service.permission.SubjectReference; +import org.spongepowered.api.util.Tristate; + +import java.util.List; +import java.util.Optional; +import java.util.Set; + +public class TemporaryCauseHolderSubject implements Subject { + private final @NonNull Cause cause; + private final @Nullable Subject subject; + + public TemporaryCauseHolderSubject(@NonNull Cause cause) { + this.cause = cause; + this.subject = subjectFromCause(this.cause); + } + + private static Subject subjectFromCause(Cause cause) { + Subject subject = cause.context().get(EventContextKeys.SUBJECT).orElse(null); + if (subject != null) { + return subject; + } + + return cause.first(Subject.class).orElse(null); + } + + public @NonNull Cause getCause() { + return this.cause; + } + + public @Nullable Subject getSubject() { + return this.subject; + } + + @Override + public String toString() { + return "CauseSubject(cause=" + this.cause + ')'; + } + + @Override + public boolean equals(Object o) { + return o == this || (o instanceof TemporaryCauseHolderSubject && this.cause.equals(((TemporaryCauseHolderSubject) o).cause)); + } + + @Override + public int hashCode() { + return this.cause.hashCode(); + } + + @Override public SubjectCollection containingCollection() { throw new UnsupportedOperationException(); } + @Override public SubjectReference asSubjectReference() { throw new UnsupportedOperationException(); } + @Override public Optional associatedObject() { throw new UnsupportedOperationException(); } + @Override public Cause contextCause() { throw new UnsupportedOperationException(); } + @Override public boolean isSubjectDataPersisted() { throw new UnsupportedOperationException(); } + @Override public SubjectData subjectData() { throw new UnsupportedOperationException(); } + @Override public SubjectData transientSubjectData() { throw new UnsupportedOperationException(); } + @Override public boolean hasPermission(String permission) { throw new UnsupportedOperationException(); } + @Override public boolean hasPermission(String permission, Cause cause) { throw new UnsupportedOperationException(); } + @Override public boolean hasPermission(String permission, Set contexts) { throw new UnsupportedOperationException(); } + @Override public Tristate permissionValue(String permission) { throw new UnsupportedOperationException(); } + @Override public Tristate permissionValue(String permission, Cause cause) { throw new UnsupportedOperationException(); } + @Override public Tristate permissionValue(String permission, Set contexts) { throw new UnsupportedOperationException(); } + @Override public boolean isChildOf(SubjectReference parent) { throw new UnsupportedOperationException(); } + @Override public boolean isChildOf(SubjectReference parent, Cause cause) { throw new UnsupportedOperationException(); } + @Override public boolean isChildOf(SubjectReference parent, Set contexts) { throw new UnsupportedOperationException(); } + @Override public List parents() { throw new UnsupportedOperationException(); } + @Override public List parents(Cause cause) { throw new UnsupportedOperationException(); } + @Override public List parents(Set contexts) { throw new UnsupportedOperationException(); } + @Override public Optional option(String key) { throw new UnsupportedOperationException(); } + @Override public Optional option(String key, Cause cause) { throw new UnsupportedOperationException(); } + @Override public Optional option(String key, Set contexts) { throw new UnsupportedOperationException(); } + @Override public String identifier() { throw new UnsupportedOperationException(); } + @Override public Optional friendlyIdentifier() { throw new UnsupportedOperationException(); } +} diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java index 00113d9db..d738042bd 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/GroupSubject.java @@ -31,8 +31,6 @@ import me.lucko.luckperms.sponge.model.SpongeGroup; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; -import org.spongepowered.api.command.CommandSource; - import java.util.Optional; /** @@ -53,11 +51,6 @@ public class GroupSubject extends PermissionHolderSubject implement return this.parent.getDisplayName(); } - @Override - public Optional getCommandSource() { - return Optional.empty(); - } - @Override public LPSubjectCollection getParentCollection() { return this.plugin.getService().getGroupSubjects(); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java index 40d3dd50c..98b307876 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubject.java @@ -40,10 +40,9 @@ import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.model.SpongeGroup; import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.ProxyFactory; -import me.lucko.luckperms.sponge.service.events.UpdateEventHandler; +import me.lucko.luckperms.sponge.service.model.LPProxiedSubject; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectReference; -import me.lucko.luckperms.sponge.service.model.ProxiedSubject; import net.luckperms.api.context.ImmutableContextSet; import net.luckperms.api.model.data.DataType; @@ -64,7 +63,7 @@ public abstract class PermissionHolderSubject implem private final PermissionHolderSubjectData subjectData; private final PermissionHolderSubjectData transientSubjectData; - private ProxiedSubject spongeSubject = null; + private LPProxiedSubject spongeSubject = null; PermissionHolderSubject(LPSpongePlugin plugin, T parent) { this.parent = parent; @@ -74,8 +73,8 @@ public abstract class PermissionHolderSubject implem } public void fireUpdateEvent() { - UpdateEventHandler.fireUpdateEvent(this.plugin, this.subjectData); - UpdateEventHandler.fireUpdateEvent(this.plugin, this.transientSubjectData); + this.plugin.getService().fireUpdateEvent(this.subjectData); + this.plugin.getService().fireUpdateEvent(this.transientSubjectData); } public T getParent() { @@ -83,7 +82,7 @@ public abstract class PermissionHolderSubject implem } @Override - public synchronized ProxiedSubject sponge() { + public synchronized LPProxiedSubject sponge() { if (this.spongeSubject == null) { this.spongeSubject = ProxyFactory.toSponge(this); } @@ -123,8 +122,8 @@ public abstract class PermissionHolderSubject implem @Override public boolean isChildOf(ImmutableContextSet contexts, LPSubjectReference parent) { - return parent.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP) && - getPermissionValue(contexts, Inheritance.key(parent.getSubjectIdentifier())).asBoolean(); + return parent.collectionIdentifier().equals(PermissionService.SUBJECTS_GROUP) && + getPermissionValue(contexts, Inheritance.key(parent.subjectIdentifier())).asBoolean(); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java index 39f07e578..f6a19f8e3 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java @@ -184,11 +184,11 @@ public class PermissionHolderSubjectData implements LPSubjectData { Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(subject, "subject"); - if (!subject.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) { + if (!subject.collectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) { return CompletableFuture.completedFuture(false); } - Node node = Inheritance.builder(subject.getSubjectIdentifier()) + Node node = Inheritance.builder(subject.subjectIdentifier()) .withContext(contexts) .build(); @@ -204,11 +204,11 @@ public class PermissionHolderSubjectData implements LPSubjectData { Objects.requireNonNull(contexts, "contexts"); Objects.requireNonNull(subject, "subject"); - if (!subject.getCollectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) { + if (!subject.collectionIdentifier().equals(PermissionService.SUBJECTS_GROUP)) { return CompletableFuture.completedFuture(false); } - Node node = Inheritance.builder(subject.getSubjectIdentifier()) + Node node = Inheritance.builder(subject.subjectIdentifier()) .withContext(contexts) .build(); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java index 4706033d2..921c9a394 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/UserSubject.java @@ -30,18 +30,17 @@ import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.model.SpongeUser; import me.lucko.luckperms.sponge.service.model.LPSubject; import me.lucko.luckperms.sponge.service.model.LPSubjectCollection; +import me.lucko.luckperms.sponge.service.model.LPSubjectUser; import org.spongepowered.api.Sponge; -import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; import java.util.Optional; -import java.util.UUID; -import java.util.function.Function; /** * Implements {@link LPSubject} for a {@link SpongeUser}. */ -public final class UserSubject extends PermissionHolderSubject implements LPSubject { +public final class UserSubject extends PermissionHolderSubject implements LPSubject, LPSubjectUser { public UserSubject(LPSpongePlugin plugin, SpongeUser parent) { super(plugin, parent); } @@ -57,9 +56,12 @@ public final class UserSubject extends PermissionHolderSubject imple } @Override - public Optional getCommandSource() { - final UUID uuid = this.parent.getUniqueId(); - return Sponge.getServer().getPlayer(uuid).map(Function.identity()); + public Optional resolvePlayer() { + if (!Sponge.isServerAvailable()) { + return Optional.empty(); + } + + return Sponge.server().player(this.parent.getUniqueId()); } @Override diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedCollection.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedCollection.java index c88252895..859d8b23b 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedCollection.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedCollection.java @@ -49,7 +49,6 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; @@ -143,7 +142,7 @@ public class PersistedCollection implements LPSubjectCollection { } @Override - public CompletableFuture> loadSubjects(Set identifiers) { + public CompletableFuture> loadSubjects(Iterable identifiers) { ImmutableSet.Builder subjects = ImmutableSet.builder(); for (String id : identifiers) { subjects.add(Objects.requireNonNull(this.subjects.get(id.toLowerCase(Locale.ROOT)))); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java index 9fb681159..bc15b38a2 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/PersistedSubject.java @@ -30,20 +30,15 @@ import me.lucko.luckperms.common.model.PermissionHolderIdentifier; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.ProxyFactory; -import me.lucko.luckperms.sponge.service.events.UpdateEventHandler; +import me.lucko.luckperms.sponge.service.model.LPProxiedSubject; import me.lucko.luckperms.sponge.service.model.LPSubject; -import me.lucko.luckperms.sponge.service.model.LPSubjectData; -import me.lucko.luckperms.sponge.service.model.ProxiedSubject; import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubject; import me.lucko.luckperms.sponge.service.model.calculated.CalculatedSubjectData; import me.lucko.luckperms.sponge.service.model.calculated.MonitoredSubjectData; import net.luckperms.api.model.data.DataType; -import org.spongepowered.api.command.CommandSource; - import java.io.IOException; -import java.util.Optional; import java.util.concurrent.TimeUnit; /** @@ -66,7 +61,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { private final PersistedSubjectData subjectData; private final CalculatedSubjectData transientSubjectData; - private ProxiedSubject spongeSubject = null; + private LPProxiedSubject spongeSubject = null; /** * The save buffer instance for saving changes to disk @@ -89,7 +84,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { protected void onUpdate(boolean success) { super.onUpdate(success); if (success) { - fireUpdateEvent(this); + PersistedSubject.this.service.fireUpdateEvent(this); } } }; @@ -97,7 +92,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { @Override protected void onUpdate(boolean success) { if (success) { - fireUpdateEvent(this); + PersistedSubject.this.service.fireUpdateEvent(this); } } }; @@ -105,15 +100,6 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { this.saveBuffer = new SaveBuffer(service.getPlugin()); } - /** - * Calls the subject data update event for the given {@link LPSubjectData} instance. - * - * @param subjectData the subject data - */ - private void fireUpdateEvent(LPSubjectData subjectData) { - UpdateEventHandler.fireUpdateEvent(this.service.getPlugin(), subjectData); - } - /** * Loads data into this {@link PersistedSubject} from the given * {@link SubjectDataContainer} container @@ -149,7 +135,7 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { } @Override - public ProxiedSubject sponge() { + public LPProxiedSubject sponge() { if (this.spongeSubject == null) { this.spongeSubject = ProxyFactory.toSponge(this); } @@ -181,11 +167,6 @@ public class PersistedSubject extends CalculatedSubject implements LPSubject { return this.transientSubjectData; } - @Override - public Optional getCommandSource() { - return Optional.empty(); - } - private final class SaveBuffer extends BufferedRequest { public SaveBuffer(LuckPermsPlugin plugin) { super(1, TimeUnit.SECONDS, plugin.getBootstrap().getScheduler()); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectDataContainer.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectDataContainer.java index a26626aac..3d8808c75 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectDataContainer.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/persisted/SubjectDataContainer.java @@ -256,8 +256,8 @@ public class SubjectDataContainer { JsonArray data = new JsonArray(); for (LPSubjectReference ref : e.getValue()) { JsonObject parent = new JsonObject(); - parent.addProperty("collection", ref.getCollectionIdentifier()); - parent.addProperty("subject", ref.getSubjectIdentifier()); + parent.addProperty("collection", ref.collectionIdentifier()); + parent.addProperty("subject", ref.subjectIdentifier()); data.add(parent); } section.add("data", data); diff --git a/sponge/src/main/resources/META-INF/sponge_plugins.json b/sponge/src/main/resources/META-INF/sponge_plugins.json new file mode 100644 index 000000000..324073eb2 --- /dev/null +++ b/sponge/src/main/resources/META-INF/sponge_plugins.json @@ -0,0 +1,31 @@ +{ + "loader": { + "name": "java_plain", + "version": "1.0" + }, + "license": "MIT", + "plugins": [ + { + "id": "luckperms", + "name": "LuckPerms", + "version": "${pluginVersion}", + "entrypoint": "me.lucko.luckperms.sponge.LPSpongeBootstrap", + "description": "A permissions plugin", + "links": { + "homepage": "https://luckperms.net" + }, + "contributors": [ + { + "name": "Luck", + "description": "Developer" + } + ], + "dependencies": [ + { + "id": "spongeapi", + "version": "8.0.0" + } + ] + } + ] +} \ No newline at end of file diff --git a/sponge/src/main/resources/luckperms.conf b/sponge/src/main/resources/luckperms.conf index 0828a3789..fafe26803 100644 --- a/sponge/src/main/resources/luckperms.conf +++ b/sponge/src/main/resources/luckperms.conf @@ -619,6 +619,9 @@ disable-bulkupdate = false # - When this happens, the plugin will set their primary group back to default. prevent-primary-group-removal = false +# If LuckPerms should update the list of commands sent to the client when permissions are changed. +update-client-command-list = true + # If LuckPerms should attempt to resolve Vanilla command target selectors for LP commands. # See here for more info: https://minecraft.gamepedia.com/Commands#Target_selectors resolve-command-selectors = false