mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-01 08:39:31 +01:00
Vault & LuckPerms permission integrations
This commit is contained in:
parent
2ab83dfc28
commit
8fdd5e73e3
@ -24,6 +24,9 @@ dependencies {
|
||||
|
||||
// Adventure
|
||||
runtimeDownloadApi 'net.kyori:adventure-platform-bukkit:' + rootProject.adventurePlatformVersion
|
||||
|
||||
// Integrations
|
||||
compileOnly "com.github.MilkBowl:VaultAPI:1.7"
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
|
@ -24,6 +24,7 @@ import com.discordsrv.bukkit.config.main.BukkitConfig;
|
||||
import com.discordsrv.bukkit.config.manager.BukkitConfigManager;
|
||||
import com.discordsrv.bukkit.config.manager.BukkitConnectionConfigManager;
|
||||
import com.discordsrv.bukkit.console.BukkitConsole;
|
||||
import com.discordsrv.bukkit.integration.VaultIntegration;
|
||||
import com.discordsrv.bukkit.listener.BukkitChatListener;
|
||||
import com.discordsrv.bukkit.listener.BukkitDeathListener;
|
||||
import com.discordsrv.bukkit.listener.BukkitStatusMessageListener;
|
||||
@ -32,6 +33,7 @@ import com.discordsrv.bukkit.scheduler.BukkitScheduler;
|
||||
import com.discordsrv.common.config.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.manager.MainConfigManager;
|
||||
import com.discordsrv.common.logging.Logger;
|
||||
import com.discordsrv.common.module.ModuleInitializationFunction;
|
||||
import com.discordsrv.common.server.ServerDiscordSRV;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.Server;
|
||||
@ -137,5 +139,16 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<BukkitConfig, BukkitConne
|
||||
server().getPluginManager().registerEvents(BukkitChatListener.get(this), plugin());
|
||||
server().getPluginManager().registerEvents(new BukkitDeathListener(this), plugin());
|
||||
server().getPluginManager().registerEvents(new BukkitStatusMessageListener(this), plugin());
|
||||
|
||||
for (ModuleFunction function : new ModuleFunction[]{
|
||||
VaultIntegration::new
|
||||
}) {
|
||||
try {
|
||||
registerModule(function.initialize(this));
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
private interface ModuleFunction extends ModuleInitializationFunction<BukkitDiscordSRV> {}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* This file is part of DiscordSRV, licensed under the GPLv3 License
|
||||
* Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.discordsrv.bukkit.integration;
|
||||
|
||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||
import com.discordsrv.common.function.CheckedSupplier;
|
||||
import com.discordsrv.common.module.type.PermissionDataProvider;
|
||||
import com.discordsrv.common.module.type.PluginIntegration;
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class VaultIntegration extends PluginIntegration<BukkitDiscordSRV> implements PermissionDataProvider {
|
||||
|
||||
private Permission permission;
|
||||
private Chat chat;
|
||||
|
||||
public VaultIntegration(BukkitDiscordSRV discordSRV) {
|
||||
super(discordSRV);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
// Lower priority than default
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
try {
|
||||
Class.forName("net.milkbowl.vault.permission.Permission");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
ServicesManager servicesManager = discordSRV.plugin().getServer().getServicesManager();
|
||||
|
||||
RegisteredServiceProvider<Permission> permissionRSP = servicesManager.getRegistration(Permission.class);
|
||||
if (permissionRSP != null) {
|
||||
permission = permissionRSP.getProvider();
|
||||
}
|
||||
|
||||
RegisteredServiceProvider<Chat> chatRSP = servicesManager.getRegistration(Chat.class);
|
||||
if (chatRSP != null) {
|
||||
chat = chatRSP.getProvider();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
permission = null;
|
||||
chat = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOffline() {
|
||||
// Maybe
|
||||
return true;
|
||||
}
|
||||
|
||||
private <T> CompletableFuture<T> unsupported() {
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
future.completeExceptionally(new RuntimeException("Vault backend unavailable"));
|
||||
return future;
|
||||
}
|
||||
|
||||
private <T> CompletableFuture<T> supply(CheckedSupplier<T> supplier) {
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
discordSRV.scheduler().runFork(() -> {
|
||||
try {
|
||||
future.complete(supplier.get());
|
||||
} catch (Throwable e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
private OfflinePlayer offlinePlayer(UUID player) {
|
||||
return discordSRV.plugin().getServer().getOfflinePlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> hasGroup(UUID player, String groupName) {
|
||||
if (permission == null) {
|
||||
return unsupported();
|
||||
}
|
||||
|
||||
return supply(() -> {
|
||||
OfflinePlayer offlinePlayer = offlinePlayer(player);
|
||||
return permission.playerInGroup(null, offlinePlayer, groupName);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addGroup(UUID player, String groupName) {
|
||||
if (permission == null) {
|
||||
return unsupported();
|
||||
}
|
||||
|
||||
return supply(() -> {
|
||||
OfflinePlayer offlinePlayer = offlinePlayer(player);
|
||||
permission.playerAddGroup(null, offlinePlayer, groupName);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeGroup(UUID player, String groupName) {
|
||||
if (permission == null) {
|
||||
return unsupported();
|
||||
}
|
||||
|
||||
return supply(() -> {
|
||||
OfflinePlayer offlinePlayer = offlinePlayer(player);
|
||||
permission.playerRemoveGroup(null, offlinePlayer, groupName);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> hasPermission(UUID player, String permissionNode) {
|
||||
if (permission == null) {
|
||||
return unsupported();
|
||||
}
|
||||
|
||||
return supply(() -> {
|
||||
OfflinePlayer offlinePlayer = offlinePlayer(player);
|
||||
return permission.playerHas(null, offlinePlayer, permissionNode);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getPrefix(UUID player) {
|
||||
if (chat == null) {
|
||||
return unsupported();
|
||||
}
|
||||
|
||||
return supply(() -> {
|
||||
OfflinePlayer offlinePlayer = offlinePlayer(player);
|
||||
return chat.getPlayerPrefix(null, offlinePlayer);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getSuffix(UUID player) {
|
||||
if (chat == null) {
|
||||
return unsupported();
|
||||
}
|
||||
|
||||
return supply(() -> {
|
||||
OfflinePlayer offlinePlayer = offlinePlayer(player);
|
||||
return chat.getPlayerSuffix(null, offlinePlayer);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getMeta(UUID player, String key) throws UnsupportedOperationException {
|
||||
// :(
|
||||
throw new UnsupportedOperationException("Vault does not support this operation");
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ public abstract class ServerDiscordSRV<C extends MainConfig, CC extends Connecti
|
||||
protected void enable() throws Throwable {
|
||||
super.enable();
|
||||
|
||||
for (ModuleInitializationFunction function : new ModuleInitializationFunction[]{
|
||||
for (ModuleFunction function : new ModuleFunction[]{
|
||||
DeathMessageModule::new
|
||||
}) {
|
||||
try {
|
||||
@ -51,6 +51,8 @@ public abstract class ServerDiscordSRV<C extends MainConfig, CC extends Connecti
|
||||
}
|
||||
}
|
||||
|
||||
private interface ModuleFunction extends ModuleInitializationFunction<ServerDiscordSRV<?, ?>> {}
|
||||
|
||||
public final CompletableFuture<Void> invokeServerStarted() {
|
||||
return invokeLifecycle(this::serverStarted, "Failed to enable", true);
|
||||
}
|
||||
|
@ -183,12 +183,12 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerModule(AbstractModule module) {
|
||||
public void registerModule(AbstractModule<?> module) {
|
||||
moduleManager.register(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterModule(AbstractModule module) {
|
||||
public void unregisterModule(AbstractModule<?> module) {
|
||||
moduleManager.unregister(module);
|
||||
}
|
||||
|
||||
@ -302,7 +302,7 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
|
||||
|
||||
// Register modules
|
||||
moduleManager = new ModuleManager(this);
|
||||
for (ModuleInitializationFunction function : new ModuleInitializationFunction[]{
|
||||
for (ModuleFunction function : new ModuleFunction[]{
|
||||
ChannelUpdaterModule::new,
|
||||
GlobalChannelLookupModule::new,
|
||||
|
||||
@ -323,6 +323,8 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
|
||||
}
|
||||
}
|
||||
|
||||
private interface ModuleFunction extends ModuleInitializationFunction<DiscordSRV> {}
|
||||
|
||||
@OverridingMethodsMustInvokeSuper
|
||||
protected void disable() {
|
||||
Status status = this.status.get();
|
||||
|
@ -85,8 +85,8 @@ public interface DiscordSRV extends DiscordSRVApi {
|
||||
|
||||
// Modules
|
||||
<T extends Module> T getModule(Class<T> moduleType);
|
||||
void registerModule(AbstractModule module);
|
||||
void unregisterModule(AbstractModule module);
|
||||
void registerModule(AbstractModule<?> module);
|
||||
void unregisterModule(AbstractModule<?> module);
|
||||
|
||||
Locale locale();
|
||||
|
||||
|
@ -23,14 +23,19 @@ import com.discordsrv.common.module.type.PermissionDataProvider;
|
||||
import com.discordsrv.common.module.type.PluginIntegration;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.luckperms.api.model.data.DataMutateResult;
|
||||
import net.luckperms.api.model.data.NodeMap;
|
||||
import net.luckperms.api.model.group.Group;
|
||||
import net.luckperms.api.model.user.User;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.luckperms.api.node.types.InheritanceNode;
|
||||
import net.luckperms.api.query.QueryOptions;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class LuckPermsIntegration extends PluginIntegration implements PermissionDataProvider {
|
||||
public class LuckPermsIntegration extends PluginIntegration<DiscordSRV> implements PermissionDataProvider {
|
||||
|
||||
private LuckPerms luckPerms;
|
||||
|
||||
@ -46,7 +51,7 @@ public class LuckPermsIntegration extends PluginIntegration implements Permissio
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return super.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -59,24 +64,72 @@ public class LuckPermsIntegration extends PluginIntegration implements Permissio
|
||||
luckPerms = null;
|
||||
}
|
||||
|
||||
private CompletableFuture<User> user(UUID player) {
|
||||
return luckPerms.getUserManager().loadUser(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGroup(UUID player, String groupName) {
|
||||
User user = luckPerms.getUserManager().getUser(player);
|
||||
if (user == null) {
|
||||
public boolean supportsOffline() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> hasGroup(UUID player, String groupName) {
|
||||
return user(player).thenApply(user -> {
|
||||
for (Group inheritedGroup : user.getInheritedGroups(QueryOptions.defaultContextualOptions())) {
|
||||
if (inheritedGroup.getName().equalsIgnoreCase(groupName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addGroup(UUID player, String groupName) {
|
||||
return groupMutate(player, groupName, NodeMap::add);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeGroup(UUID player, String groupName) {
|
||||
return groupMutate(player, groupName, NodeMap::remove);
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> groupMutate(UUID player, String groupName, BiFunction<NodeMap, Node, DataMutateResult> function) {
|
||||
Group group = luckPerms.getGroupManager().getGroup(groupName);
|
||||
if (group == null) {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
future.completeExceptionally(new RuntimeException("Group does not exist"));
|
||||
return future;
|
||||
}
|
||||
|
||||
Collection<Group> groups = user.getInheritedGroups(QueryOptions.defaultContextualOptions());
|
||||
return groups.stream().anyMatch(group -> group.getName().equalsIgnoreCase(groupName));
|
||||
return user(player).thenApply(user -> {
|
||||
DataMutateResult result = function.apply(user.data(), InheritanceNode.builder(group).build());
|
||||
if (result != DataMutateResult.SUCCESS) {
|
||||
throw new RuntimeException(result.name());
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGroup(UUID player, String groupName) {
|
||||
|
||||
public CompletableFuture<Boolean> hasPermission(UUID player, String permission) {
|
||||
return user(player).thenApply(
|
||||
user -> user.getCachedData().getPermissionData().checkPermission(permission).asBoolean());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGroup(UUID player, String groupName) {
|
||||
public CompletableFuture<String> getPrefix(UUID player) {
|
||||
return user(player).thenApply(user -> user.getCachedData().getMetaData().getPrefix());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getSuffix(UUID player) {
|
||||
return user(player).thenApply(user -> user.getCachedData().getMetaData().getSuffix());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getMeta(UUID player, String key) throws UnsupportedOperationException {
|
||||
return user(player).thenApply(user -> user.getCachedData().getMetaData().getMetaValue(key));
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.module.type.AbstractModule;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ModuleInitializationFunction {
|
||||
public interface ModuleInitializationFunction<DT extends DiscordSRV> {
|
||||
|
||||
AbstractModule initialize(DiscordSRV discordSRV) throws Throwable;
|
||||
AbstractModule<DT> initialize(DT discordSRV) throws Throwable;
|
||||
|
||||
}
|
||||
|
@ -23,12 +23,12 @@ import com.discordsrv.api.event.events.Processable;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.event.util.EventUtil;
|
||||
|
||||
public abstract class AbstractModule implements Module {
|
||||
public abstract class AbstractModule<DT extends DiscordSRV> implements Module {
|
||||
|
||||
protected final DiscordSRV discordSRV;
|
||||
protected final DT discordSRV;
|
||||
private boolean hasBeenEnabled = false;
|
||||
|
||||
public AbstractModule(DiscordSRV discordSRV) {
|
||||
public AbstractModule(DT discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,21 @@
|
||||
package com.discordsrv.common.module.type;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface PermissionDataProvider extends Module {
|
||||
|
||||
boolean hasGroup(UUID player, String groupName);
|
||||
void addGroup(UUID player, String groupName);
|
||||
void removeGroup(UUID player, String groupName);
|
||||
boolean supportsOffline();
|
||||
|
||||
CompletableFuture<Boolean> hasGroup(UUID player, String groupName);
|
||||
CompletableFuture<Void> addGroup(UUID player, String groupName);
|
||||
CompletableFuture<Void> removeGroup(UUID player, String groupName);
|
||||
|
||||
CompletableFuture<Boolean> hasPermission(UUID player, String permission);
|
||||
|
||||
CompletableFuture<String> getPrefix(UUID player);
|
||||
CompletableFuture<String> getSuffix(UUID player);
|
||||
|
||||
CompletableFuture<String> getMeta(UUID player, String key) throws UnsupportedOperationException;
|
||||
|
||||
}
|
||||
|
@ -20,9 +20,17 @@ package com.discordsrv.common.module.type;
|
||||
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
|
||||
public abstract class PluginIntegration extends AbstractModule {
|
||||
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
||||
|
||||
public PluginIntegration(DiscordSRV discordSRV) {
|
||||
public abstract class PluginIntegration<DT extends DiscordSRV> extends AbstractModule<DT> {
|
||||
|
||||
public PluginIntegration(DT discordSRV) {
|
||||
super(discordSRV);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OverridingMethodsMustInvokeSuper
|
||||
public boolean isEnabled() {
|
||||
return super.isEnabled();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user