mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2025-03-02 11:31:13 +01:00
SpongeAPI 8 (#2728)
This commit is contained in:
parent
d3029a8467
commit
ee79f53612
@ -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<ProxiedPlayer, ProxiedP
|
||||
throw new NullPointerException("subject");
|
||||
}
|
||||
|
||||
return new InlineQueryOptionsSupplier(subject, this.contextsCache);
|
||||
return new InlineQueryOptionsSupplier<>(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<ProxiedPlayer, ProxiedP
|
||||
return formQueryOptions(contextSet);
|
||||
}
|
||||
|
||||
private static final class InlineQueryOptionsSupplier implements QueryOptionsSupplier {
|
||||
private final ProxiedPlayer key;
|
||||
private final LoadingCache<ProxiedPlayer, QueryOptions> cache;
|
||||
|
||||
private InlineQueryOptionsSupplier(ProxiedPlayer key, LoadingCache<ProxiedPlayer, QueryOptions> cache) {
|
||||
this.key = key;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryOptions getQueryOptions() {
|
||||
return this.cache.get(this.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<Void> overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||
CompletableFuture<Void> overallFuture = CompletableFutures.allOf(futures);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
|
@ -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<Void> overallFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
||||
CompletableFuture<Void> 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."));
|
||||
|
||||
|
@ -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<Void> reload() {
|
||||
Set<QueryOptions> keys = this.cache.keySet();
|
||||
return CompletableFuture.allOf(keys.stream().map(this::reload).toArray(CompletableFuture[]::new));
|
||||
return CompletableFutures.allOf(keys.stream().map(this::reload));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -135,16 +135,28 @@ public abstract class ContextManager<S, P extends S> {
|
||||
this.calculators.remove(calculator);
|
||||
}
|
||||
|
||||
protected void callContextCalculator(ContextCalculator<? super S> 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<? super S> 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<S, P extends S> {
|
||||
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());
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<T> implements QueryOptionsSupplier {
|
||||
private final T key;
|
||||
private final LoadingCache<T, QueryOptions> cache;
|
||||
|
||||
public InlineQueryOptionsSupplier(T key, LoadingCache<T, QueryOptions> cache) {
|
||||
this.key = key;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryOptions getQueryOptions() {
|
||||
return this.cache.get(this.key);
|
||||
}
|
||||
}
|
@ -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<T extends User> extends AbstractManage
|
||||
Set<UUID> 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
|
||||
|
@ -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 {
|
||||
|
@ -130,7 +130,7 @@ public final class AbstractSender<T> implements Sender {
|
||||
// A small utility method which splits components built using
|
||||
// > join(newLine(), components...)
|
||||
// back into separate components.
|
||||
private static Iterable<Component> splitNewlines(Component message) {
|
||||
public static Iterable<Component> splitNewlines(Component message) {
|
||||
if (message instanceof TextComponent && message.style().isEmpty() && !message.children().isEmpty() && ((TextComponent) message).content().isEmpty()) {
|
||||
LinkedList<List<Component>> split = new LinkedList<>();
|
||||
split.add(new ArrayList<>());
|
||||
|
@ -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 <T extends CompletableFuture<?>> Collector<T, ImmutableList.Builder<T>, CompletableFuture<Void>> collector() {
|
||||
return Collector.of(
|
||||
ImmutableList.Builder::new,
|
||||
ImmutableList.Builder::add,
|
||||
(l, r) -> l.addAll(r.build()),
|
||||
builder -> allOf(builder.build())
|
||||
);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> allOf(Stream<? extends CompletableFuture<?>> futures) {
|
||||
CompletableFuture<?>[] arr = futures.toArray(CompletableFuture[]::new);
|
||||
return CompletableFuture.allOf(arr);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Void> allOf(Collection<? extends CompletableFuture<?>> futures) {
|
||||
CompletableFuture<?>[] arr = futures.toArray(new CompletableFuture[0]);
|
||||
return CompletableFuture.allOf(arr);
|
||||
}
|
||||
|
||||
}
|
@ -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'
|
||||
)
|
||||
|
@ -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'
|
||||
|
@ -1,142 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<String, Tristate> 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<String, Tristate> 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 + ")";
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<Subject, Boolean> 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 + ")";
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<String, SubjectCollection> getKnownSubjects() {
|
||||
return this.handle.getLoadedCollections().entrySet().stream()
|
||||
.collect(ImmutableCollectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> e.getValue().sponge()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PermissionDescription.Builder> newDescriptionBuilder(@NonNull Object o) {
|
||||
Optional<PluginContainer> 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<PermissionDescription> getDescription(@NonNull String s) {
|
||||
return this.handle.getDescription(s).map(LPPermissionDescription::sponge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Collection<PermissionDescription> getDescriptions() {
|
||||
return this.handle.getDescriptions().stream().map(LPPermissionDescription::sponge).collect(ImmutableCollectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerContextCalculator(@NonNull ContextCalculator<Subject> 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 + ")";
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<Subject> 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<Subject, Boolean> 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<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> 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 + ")";
|
||||
}
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<LPSubjectData> handle() {
|
||||
return this.enduring ?
|
||||
this.ref.resolveLp().thenApply(LPSubject::getSubjectData) :
|
||||
this.ref.resolveLp().thenApply(LPSubject::getTransientSubjectData);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull Map<Set<Context>, Map<String, Boolean>> 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<String, Boolean> getPermissions(@NonNull Set<Context> contexts) {
|
||||
return handle().thenApply(handle -> handle.getPermissions(CompatibilityUtil.convertContexts(contexts))).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPermission(@NonNull Set<Context> 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<Context> contexts) {
|
||||
handle().thenCompose(handle -> handle.clearPermissions(CompatibilityUtil.convertContexts(contexts)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull Map<Set<Context>, List<Subject>> 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<Subject> getParents(@NonNull Set<Context> 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<Context> 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<Context> 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<Context> contexts) {
|
||||
handle().thenCompose(handle -> handle.clearParents(CompatibilityUtil.convertContexts(contexts)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull Map<Set<Context>, Map<String, String>> 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<String, String> getOptions(@NonNull Set<Context> contexts) {
|
||||
return handle().thenApply(handle -> handle.getOptions(CompatibilityUtil.convertContexts(contexts))).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOption(@NonNull Set<Context> 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<Context> 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 + ")";
|
||||
}
|
||||
}
|
@ -1,187 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<LPSubject> 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<CommandSource> 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<Context> 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<Context> 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<Context> 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<Subject> 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<Subject> getParents(@NonNull Set<Context> 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<String> getOption(@NonNull Set<Context> contexts, @NonNull String key) {
|
||||
return handle().thenApply(handle -> handle.getOption(CompatibilityUtil.convertContexts(contexts), key)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<String> 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<Context> 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 + ")";
|
||||
}
|
||||
}
|
@ -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')
|
||||
}
|
||||
}
|
@ -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')
|
@ -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<String, Tristate> 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
|
@ -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<Text> getDescription() {
|
||||
public @NonNull Optional<Component> description() {
|
||||
return this.handle.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<PluginContainer> getOwner() {
|
||||
public @NonNull Optional<PluginContainer> owner() {
|
||||
return this.handle.getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Map<Subject, Boolean> getAssignedSubjects(@NonNull String s) {
|
||||
public Tristate defaultValue() {
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Map<Subject, Boolean> 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<Map<SubjectReference, Boolean>> 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 + ")";
|
||||
}
|
||||
}
|
@ -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<String> getIdentifierValidityPredicate() {
|
||||
public @NonNull Predicate<String> identifierValidityPredicate() {
|
||||
return this.handle.getIdentifierValidityPredicate();
|
||||
}
|
||||
|
||||
@ -85,7 +88,7 @@ public final class PermissionServiceProxy implements PermissionService, ProxiedS
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<SubjectCollection> getCollection(String s) {
|
||||
public @NonNull Optional<SubjectCollection> 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<String, SubjectCollection> getLoadedCollections() {
|
||||
public @NonNull Map<String, SubjectCollection> 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<Set<String>> getAllIdentifiers() {
|
||||
public CompletableFuture<? extends Set<String>> 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<PluginContainer> 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<PermissionDescription> getDescription(@NonNull String s) {
|
||||
public @NonNull Optional<PermissionDescription> description(@NonNull String s) {
|
||||
return this.handle.getDescription(s).map(LPPermissionDescription::sponge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Collection<PermissionDescription> getDescriptions() {
|
||||
public @NonNull Collection<PermissionDescription> descriptions() {
|
||||
return this.handle.getDescriptions().stream().map(LPPermissionDescription::sponge).collect(ImmutableCollectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerContextCalculator(@NonNull ContextCalculator<Subject> contextCalculator) {
|
||||
public Set<Context> contexts() {
|
||||
return CompatibilityUtil.convertContexts(this.handle.getContextsForCurrentCause());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Context> 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 + ")";
|
||||
}
|
||||
}
|
@ -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<String> getIdentifierValidityPredicate() {
|
||||
public @NonNull Predicate<String> identifierValidityPredicate() {
|
||||
return this.handle.getIdentifierValidityPredicate();
|
||||
}
|
||||
|
||||
@ -69,7 +68,7 @@ public final class SubjectCollectionProxy implements SubjectCollection, ProxiedS
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<Subject> getSubject(@NonNull String s) {
|
||||
public @NonNull Optional<Subject> 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<Map<String, Subject>> loadSubjects(@NonNull Set<String> set) {
|
||||
public @NonNull CompletableFuture<Map<String, Subject>> loadSubjects(@NonNull Iterable<String> set) {
|
||||
return this.handle.loadSubjects(set).thenApply(subs -> subs.stream().collect(ImmutableCollectors.toMap(lpSubject -> lpSubject.getIdentifier().getName(), LPSubject::sponge)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Collection<Subject> getLoadedSubjects() {
|
||||
public @NonNull Collection<Subject> loadedSubjects() {
|
||||
return this.handle.getLoadedSubjects().stream().map(LPSubject::sponge).collect(ImmutableCollectors.toSet());
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull CompletableFuture<Set<String>> getAllIdentifiers() {
|
||||
public @NonNull CompletableFuture<Set<String>> 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<Map<SubjectReference, Boolean>> getAllWithPermission(@NonNull String s) {
|
||||
public @NonNull CompletableFuture<Map<SubjectReference, Boolean>> allWithPermission(@NonNull String s) {
|
||||
return (CompletableFuture) this.handle.getAllWithPermission(s);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull CompletableFuture<Map<SubjectReference, Boolean>> getAllWithPermission(@NonNull Set<Context> set, @NonNull String s) {
|
||||
return (CompletableFuture) this.handle.getAllWithPermission(CompatibilityUtil.convertContexts(set), s);
|
||||
public @NonNull CompletableFuture<Map<SubjectReference, Boolean>> allWithPermission(@NonNull String s, @NonNull Cause cause) {
|
||||
return (CompletableFuture) this.handle.getAllWithPermission(this.handle.getService().getContextsForCause(cause), s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Map<Subject, Boolean> getLoadedWithPermission(@NonNull String s) {
|
||||
public @NonNull Map<Subject, Boolean> 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<Subject, Boolean> getLoadedWithPermission(@NonNull Set<Context> set, @NonNull String s) {
|
||||
return this.handle.getLoadedWithPermission(CompatibilityUtil.convertContexts(set), s).entrySet().stream()
|
||||
public @NonNull Map<Subject, Boolean> 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 + ")";
|
||||
}
|
||||
|
||||
}
|
@ -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<Set<Context>, Map<String, Boolean>> getAllPermissions() {
|
||||
public @NonNull Map<Set<Context>, Map<String, Boolean>> 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<String, Boolean> getPermissions(@NonNull Set<Context> contexts) {
|
||||
public @NonNull Map<String, Boolean> permissions(@NonNull Set<Context> 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<Boolean> setPermissions(Set<Context> contexts, Map<String, Boolean> permissions, TransferMethod method) {
|
||||
CompletableFuture<Boolean> 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<Context> contexts) {
|
||||
// TODO: check subject type here to return a more appropriate value?
|
||||
return Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Set<Context>, Tristate> allFallbackPermissionValues() {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> setFallbackPermissionValue(Set<Context> contexts, Tristate fallback) {
|
||||
throw new UnsupportedOperationException("LuckPerms does not support setting fallback permission values");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> clearFallbackPermissionValues() {
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CompletableFuture<Boolean> clearPermissions() {
|
||||
return handle().thenCompose(LPSubjectData::clearPermissions);
|
||||
@ -98,7 +152,7 @@ public final class SubjectDataProxy implements SubjectData, ProxiedServiceObject
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull Map<Set<Context>, List<org.spongepowered.api.service.permission.SubjectReference>> getAllParents() {
|
||||
public @NonNull Map<Set<Context>, List<org.spongepowered.api.service.permission.SubjectReference>> 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<org.spongepowered.api.service.permission.SubjectReference> getParents(@NonNull Set<Context> contexts) {
|
||||
public @NonNull List<org.spongepowered.api.service.permission.SubjectReference> parents(@NonNull Set<Context> contexts) {
|
||||
return (List) handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts))).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> setParents(Set<Context> contexts, List<? extends SubjectReference> parents, TransferMethod method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CompletableFuture<Boolean> addParent(@NonNull Set<Context> 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<Set<Context>, Map<String, String>> getAllOptions() {
|
||||
public @NonNull Map<Set<Context>, Map<String, String>> 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<String, String> getOptions(@NonNull Set<Context> contexts) {
|
||||
public @NonNull Map<String, String> options(@NonNull Set<Context> 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<Boolean> setOptions(Set<Context> contexts, Map<String, String> options, TransferMethod method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CompletableFuture<Boolean> 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<Boolean> copyFrom(SubjectData other, TransferMethod method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> 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 + ")";
|
||||
}
|
||||
}
|
@ -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<CommandSource> 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<Context> 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<Context> contexts, @NonNull String permission) {
|
||||
public @NonNull Tristate permissionValue(@NonNull String permission, @NonNull Set<Context> 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<Context> contexts, @NonNull SubjectReference parent) {
|
||||
public boolean isChildOf(@NonNull SubjectReference parent, @NonNull Set<Context> contexts) {
|
||||
return handle().thenApply(handle -> handle.isChildOf(CompatibilityUtil.convertContexts(contexts), this.service.getReferenceFactory().obtain(parent))).join();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull List<SubjectReference> getParents() {
|
||||
return (List) handle().thenApply(handle -> handle.getParents(queryOptionsCache().getContextSet())).join();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public @NonNull List<SubjectReference> getParents(@NonNull Set<Context> contexts) {
|
||||
return (List) handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts))).join();
|
||||
public List<? extends SubjectReference> parents(@NonNull Cause cause) {
|
||||
return handle().thenApply(handle -> handle.getParents(this.service.getContextsForCause(cause))).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<String> getOption(@NonNull Set<Context> contexts, @NonNull String key) {
|
||||
public @NonNull List<? extends SubjectReference> parents(@NonNull Set<Context> contexts) {
|
||||
return handle().thenApply(handle -> handle.getParents(CompatibilityUtil.convertContexts(contexts))).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> option(@NonNull String key, @NonNull Cause cause) {
|
||||
return handle().thenApply(handle -> handle.getOption(this.service.getContextsForCause(cause), key)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<String> option(@NonNull String key, @NonNull Set<Context> contexts) {
|
||||
return handle().thenApply(handle -> handle.getOption(CompatibilityUtil.convertContexts(contexts), key)).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<String> 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<String> getFriendlyIdentifier() {
|
||||
public @NonNull Optional<String> friendlyIdentifier() {
|
||||
return handle().thenApply(LPSubject::getFriendlyIdentifier).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Set<Context> 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 + ")";
|
||||
}
|
||||
}
|
@ -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')
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
@ -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<Text> getDescription();
|
||||
Optional<Component> getDescription();
|
||||
|
||||
Optional<PluginContainer> getOwner();
|
||||
|
||||
|
@ -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<Subject, Player> getContextManager();
|
||||
ContextManager<Subject, ServerPlayer> getContextManager();
|
||||
|
||||
SubjectReferenceFactory getReferenceFactory();
|
||||
|
||||
PermissionService sponge();
|
||||
PermissionAndContextService sponge();
|
||||
|
||||
LPSubjectCollection getUserSubjects();
|
||||
|
||||
@ -69,13 +73,19 @@ public interface LPPermissionService {
|
||||
|
||||
ImmutableMap<String, LPSubjectCollection> getLoadedCollections();
|
||||
|
||||
LPPermissionDescription registerPermissionDescription(String id, Text description, PluginContainer owner);
|
||||
LPPermissionDescription registerPermissionDescription(String id, Component description, PluginContainer owner);
|
||||
|
||||
Optional<LPPermissionDescription> getDescription(String permission);
|
||||
|
||||
ImmutableCollection<LPPermissionDescription> getDescriptions();
|
||||
|
||||
void registerContextCalculator(ContextCalculator<Subject> calculator);
|
||||
void registerContextCalculator(ContextCalculator calculator);
|
||||
|
||||
ImmutableContextSet getContextsForCause(Cause cause);
|
||||
|
||||
ImmutableContextSet getContextsForCurrentCause();
|
||||
|
||||
void fireUpdateEvent(LPSubjectData subjectData);
|
||||
|
||||
void invalidateAllCaches();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
}
|
@ -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();
|
@ -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<CommandSource> getCommandSource() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
LPSubjectCollection getParentCollection();
|
||||
|
||||
LPSubjectData getSubjectData();
|
||||
|
@ -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<Boolean> hasRegistered(String identifier);
|
||||
|
||||
CompletableFuture<ImmutableCollection<LPSubject>> loadSubjects(Set<String> identifiers);
|
||||
CompletableFuture<ImmutableCollection<LPSubject>> loadSubjects(Iterable<String> identifiers);
|
||||
|
||||
ImmutableCollection<LPSubject> getLoadedSubjects();
|
||||
|
||||
|
@ -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<ServerPlayer> resolvePlayer();
|
||||
|
||||
CompletableFuture<Subject> resolve();
|
||||
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<Server> event) {
|
||||
this.plugin.disable();
|
||||
}
|
||||
|
||||
@ -207,22 +181,22 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap {
|
||||
}
|
||||
|
||||
public Optional<Server> 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<Player> getPlayer(UUID uniqueId) {
|
||||
return getServer().flatMap(s -> s.getPlayer(uniqueId));
|
||||
public InputStream getResourceStream(String path) {
|
||||
return getClass().getClassLoader().getResourceAsStream(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ServerPlayer> getPlayer(UUID uniqueId) {
|
||||
return getServer().flatMap(s -> s.player(uniqueId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> 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<String> 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<String> getPlayerList() {
|
||||
return getServer().map(server -> {
|
||||
Collection<Player> players = server.getOnlinePlayers();
|
||||
Collection<ServerPlayer> players = server.onlinePlayers();
|
||||
List<String> 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<UUID> getOnlinePlayers() {
|
||||
return getServer().map(server -> {
|
||||
Collection<Player> players = server.getOnlinePlayers();
|
||||
Collection<ServerPlayer> players = server.onlinePlayers();
|
||||
List<UUID> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<Dependency> getGlobalDependencies() {
|
||||
Set<Dependency> 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<Command.Raw> 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<PermissionDescription> 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<PermissionDescription> 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<PermissionService> event) {
|
||||
event.suggest(this.service::sponge);
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onContextServiceProvide(ProvideServiceEvent.EngineScoped<ContextService> 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<LuckPerms> 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<QueryOptions> 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<Sender> 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<Command<?>> getExtraCommands() {
|
||||
public List<me.lucko.luckperms.common.command.abstraction.Command<?>> getExtraCommands() {
|
||||
return Collections.singletonList(new SpongeParentCommand(this));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<? extends ClassLoader> 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));
|
||||
}
|
||||
|
||||
}
|
@ -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<String> 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<String> arguments = resolveSelectors(source, ArgumentTokenizer.EXECUTE.tokenizeInput(args.input()));
|
||||
executeCommand(wrapped, "lp", arguments);
|
||||
return CommandResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull List<String> getSuggestions(@NonNull CommandSource source, @NonNull String args, @Nullable Location<World> location) {
|
||||
Sender wrapped = this.plugin.getSenderFactory().wrap(source);
|
||||
List<String> arguments = resolveSelectors(source, ArgumentTokenizer.TAB_COMPLETE.tokenizeInput(args));
|
||||
return tabCompleteCommand(wrapped, arguments);
|
||||
public List<CommandCompletion> complete(@NonNull CommandCause source, ArgumentReader.@NonNull Mutable args) {
|
||||
Sender wrapped = this.plugin.getSenderFactory().wrap(source.audience());
|
||||
List<String> 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<Text> getShortDescription(@NonNull CommandSource source) {
|
||||
return Optional.of(Text.of("Manage permissions"));
|
||||
public Optional<Component> shortDescription(CommandCause cause) {
|
||||
return Optional.of(Component.text("Manage permissions"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<Text> getHelp(@NonNull CommandSource source) {
|
||||
return Optional.of(Text.of("Run /luckperms to view usage."));
|
||||
public Optional<Component> 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<String> resolveSelectors(CommandSource source, List<String> args) {
|
||||
private List<String> resolveSelectors(CommandCause source, List<String> args) {
|
||||
if (!this.plugin.getConfiguration().get(ConfigKeys.RESOLVE_COMMAND_SELECTORS)) {
|
||||
return args;
|
||||
}
|
||||
@ -102,7 +105,7 @@ public class SpongeCommandExecutor extends CommandManager implements CommandCall
|
||||
|
||||
List<Player> 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;
|
||||
|
@ -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<PluginContainer> {
|
||||
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<PluginContainer> {
|
||||
return (PluginContainer) plugin;
|
||||
}
|
||||
|
||||
PluginContainer pluginContainer = Sponge.getPluginManager().fromInstance(plugin).orElse(null);
|
||||
PluginContainer pluginContainer = Sponge.pluginManager().fromInstance(plugin).orElse(null);
|
||||
if (pluginContainer != null) {
|
||||
return pluginContainer;
|
||||
}
|
||||
|
@ -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<Task> 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<TaskExecutorService> sync;
|
||||
private final TaskExecutorService async;
|
||||
|
||||
private final Set<ScheduledTask> 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<Task.Builder> 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
|
||||
|
@ -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<LPSpongePlugin, CommandSource> {
|
||||
public class SpongeSenderFactory extends SenderFactory<LPSpongePlugin, Audience> {
|
||||
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<LPSpongePlugin, CommandSo
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasPermission(CommandSource source, String node) {
|
||||
return source.hasPermission(node);
|
||||
protected boolean hasPermission(Audience source, String node) {
|
||||
if (!(source instanceof Subject)) {
|
||||
throw new IllegalStateException("Source is not a subject");
|
||||
}
|
||||
|
||||
final Subject subject = (Subject) source;
|
||||
return subject.hasPermission(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performCommand(CommandSource source, String command) {
|
||||
getPlugin().getBootstrap().getGame().getCommandManager().process(source, command);
|
||||
protected void performCommand(Audience source, String command) {
|
||||
if (!(source instanceof Subject)) {
|
||||
throw new IllegalStateException("Source is not a subject");
|
||||
}
|
||||
|
||||
try {
|
||||
getPlugin().getBootstrap().getGame().server().commandManager().process(((Subject) source), source, command);
|
||||
} catch (CommandException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConsole(CommandSource sender) {
|
||||
return sender instanceof ConsoleSource;
|
||||
protected boolean isConsole(Audience sender) {
|
||||
return sender instanceof SystemSubject;
|
||||
}
|
||||
|
||||
public static Text toNativeText(Component component) {
|
||||
return TextSerializers.JSON.deserialize(GsonComponentSerializer.gson().serialize(component));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 ParentAdd extends ChildCommand<LPSubjectData> {
|
||||
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<LPSubjectData> {
|
||||
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.");
|
||||
}
|
||||
|
@ -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<LPSubjectData> {
|
||||
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<LPSubjectData> {
|
||||
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.");
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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<Subject, Player> {
|
||||
public class SpongeContextManager extends ContextManager<Subject, ServerPlayer> {
|
||||
|
||||
private final LoadingCache<Subject, QueryOptionsCache<Subject>> subjectCaches = CaffeineFactory.newBuilder()
|
||||
.expireAfterAccess(1, TimeUnit.MINUTES)
|
||||
.build(key -> new QueryOptionsCache<>(key, this));
|
||||
private final LoadingCache<Subject, QueryOptions> 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<? super Subject> 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<Subject, Player> {
|
||||
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<Subject> cache = this.subjectCaches.getIfPresent(subject);
|
||||
if (cache != null) {
|
||||
cache.invalidate();
|
||||
}
|
||||
this.contextsCache.invalidate(subject);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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<Subject> {
|
||||
private final LPSpongePlugin plugin;
|
||||
|
||||
private final boolean gamemode;
|
||||
private final boolean world;
|
||||
private final boolean dimensionType;
|
||||
|
||||
public SpongePlayerCalculator(LPSpongePlugin plugin, Set<String> 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<Subject> {
|
||||
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);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<UUID, SendBuffer> 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<Void> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ServerSideConnection> {
|
||||
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<Player> players = this.plugin.getBootstrap().getGame().getServer().getOnlinePlayers();
|
||||
Player p = Iterables.getFirst(players, null);
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
Collection<ServerPlayer> 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);
|
||||
}
|
||||
|
@ -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<SpongeGroup> implem
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ImmutableCollection<LPSubject>> loadSubjects(Set<String> identifiers) {
|
||||
public CompletableFuture<ImmutableCollection<LPSubject>> loadSubjects(Iterable<String> identifiers) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
ImmutableSet.Builder<LPSubject> subjects = ImmutableSet.builder();
|
||||
for (String id : identifiers) {
|
||||
|
@ -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<SpongeUser> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<ImmutableCollection<LPSubject>> loadSubjects(Set<String> identifiers) {
|
||||
public CompletableFuture<ImmutableCollection<LPSubject>> loadSubjects(Iterable<String> identifiers) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
ImmutableSet.Builder<LPSubject> subjects = ImmutableSet.builder();
|
||||
for (String id : identifiers) {
|
||||
|
@ -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<Subject, Player> getContextManager() {
|
||||
public ContextManager<Subject, ServerPlayer> 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<Subject> 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()) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<Subject> {
|
||||
private final ContextCalculator<Subject> delegate;
|
||||
private final ContextCalculator delegate;
|
||||
|
||||
public ContextCalculatorProxy(ContextCalculator<Subject> 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<Subje
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
private static final class ForwardingContextSet implements Set<Context> {
|
||||
private static final class ForwardingContextConsumer implements Consumer<Context> {
|
||||
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<? extends Context> 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<Context> iterator() { throw new UnsupportedOperationException(); }
|
||||
@Override public @NonNull Object[] toArray() { throw new UnsupportedOperationException(); }
|
||||
@Override public <T> @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(); }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<Text> getDescription() {
|
||||
public Optional<Component> getDescription() {
|
||||
return Optional.ofNullable(this.description);
|
||||
}
|
||||
|
||||
|
@ -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();
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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<Context> 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<Context> 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<Context> contexts) { throw new UnsupportedOperationException(); }
|
||||
@Override public List<? extends SubjectReference> parents() { throw new UnsupportedOperationException(); }
|
||||
@Override public List<? extends SubjectReference> parents(Cause cause) { throw new UnsupportedOperationException(); }
|
||||
@Override public List<? extends SubjectReference> parents(Set<Context> contexts) { throw new UnsupportedOperationException(); }
|
||||
@Override public Optional<String> option(String key) { throw new UnsupportedOperationException(); }
|
||||
@Override public Optional<String> option(String key, Cause cause) { throw new UnsupportedOperationException(); }
|
||||
@Override public Optional<String> option(String key, Set<Context> contexts) { throw new UnsupportedOperationException(); }
|
||||
@Override public String identifier() { throw new UnsupportedOperationException(); }
|
||||
@Override public Optional<String> friendlyIdentifier() { throw new UnsupportedOperationException(); }
|
||||
}
|
@ -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<SpongeGroup> implement
|
||||
return this.parent.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CommandSource> getCommandSource() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LPSubjectCollection getParentCollection() {
|
||||
return this.plugin.getService().getGroupSubjects();
|
||||
|
@ -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<T extends PermissionHolder> 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<T extends PermissionHolder> 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<T extends PermissionHolder> 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<T extends PermissionHolder> 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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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<SpongeUser> implements LPSubject {
|
||||
public final class UserSubject extends PermissionHolderSubject<SpongeUser> implements LPSubject, LPSubjectUser {
|
||||
public UserSubject(LPSpongePlugin plugin, SpongeUser parent) {
|
||||
super(plugin, parent);
|
||||
}
|
||||
@ -57,9 +56,12 @@ public final class UserSubject extends PermissionHolderSubject<SpongeUser> imple
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<CommandSource> getCommandSource() {
|
||||
final UUID uuid = this.parent.getUniqueId();
|
||||
return Sponge.getServer().getPlayer(uuid).map(Function.identity());
|
||||
public Optional<ServerPlayer> resolvePlayer() {
|
||||
if (!Sponge.isServerAvailable()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Sponge.server().player(this.parent.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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<ImmutableCollection<LPSubject>> loadSubjects(Set<String> identifiers) {
|
||||
public CompletableFuture<ImmutableCollection<LPSubject>> loadSubjects(Iterable<String> identifiers) {
|
||||
ImmutableSet.Builder<LPSubject> subjects = ImmutableSet.builder();
|
||||
for (String id : identifiers) {
|
||||
subjects.add(Objects.requireNonNull(this.subjects.get(id.toLowerCase(Locale.ROOT))));
|
||||
|
@ -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<CommandSource> getCommandSource() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private final class SaveBuffer extends BufferedRequest<Void> {
|
||||
public SaveBuffer(LuckPermsPlugin plugin) {
|
||||
super(1, TimeUnit.SECONDS, plugin.getBootstrap().getScheduler());
|
||||
|
@ -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);
|
||||
|
31
sponge/src/main/resources/META-INF/sponge_plugins.json
Normal file
31
sponge/src/main/resources/META-INF/sponge_plugins.json
Normal file
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user