Compare commits

..

No commits in common. "e8c73ead9043e1b9bd4d79c5f47917735a52ce68" and "fd5f89c7556bab192d487c9316cdafdbe1293752" have entirely different histories.

15 changed files with 71 additions and 249 deletions

20
Jenkinsfile vendored
View File

@ -1,20 +0,0 @@
pipeline {
agent any
stages {
stage('Gradle') {
steps {
sh 'bash gradlew shadowJar -x test'
}
}
stage('Archive') {
steps {
archiveArtifacts artifacts: 'build/libs/', followSymlinks: false
}
}
stage('discord') {
steps {
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
}
}
}
}

View File

@ -7,6 +7,7 @@ plugins {
allprojects { allprojects {
val build = System.getenv("BUILD_NUMBER") ?: "SNAPSHOT" val build = System.getenv("BUILD_NUMBER") ?: "SNAPSHOT"
group = "com.alttd.proxydiscordlink" group = "com.alttd.proxydiscordlink"
version = "1.0.0-BETA-$build"
description = "A velocity plugin to link Discord and Minecraft accounts." description = "A velocity plugin to link Discord and Minecraft accounts."
apply(plugin = "java") apply(plugin = "java")
@ -53,8 +54,14 @@ dependencies {
tasks { tasks {
shadowJar { shadowJar {
archiveFileName.set("discordLink.jar") archiveFileName.set("${project.name}-${project.version}.jar")
// exclude("net.kyori.adventure")
// exclude("net.kyori.examination")
minimize {
//exclude(dependency("net.kyori:.*:.*"))
}
listOf( listOf(
// "net.kyori",
"net.dv8tion.jda" "net.dv8tion.jda"
).forEach { relocate(it, "${rootProject.group}.lib.$it") } ).forEach { relocate(it, "${rootProject.group}.lib.$it") }
} }

View File

@ -51,10 +51,6 @@ public class DiscordLink {
cache = new Cache(); cache = new Cache();
} }
//TODO set up a repeating task that checks if ppl with the link role are really linked
//TODO fix unlinking in game not unlinking in discord
//TODO fix nitro booster role not being removed in game (set up a command to force check?)
//TODO fix &sync
@Subscribe @Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) { public void onProxyInitialization(ProxyInitializeEvent event) {
ALogger.init(logger); ALogger.init(logger);

View File

@ -1,9 +1,8 @@
package com.alttd.proxydiscordlink.bot; package com.alttd.proxydiscordlink.bot;
import com.alttd.proxydiscordlink.JDAListener; import com.alttd.proxydiscordlink.JDAListener;
import com.alttd.proxydiscordlink.DiscordLink; import com.alttd.proxydiscordlink.bot.commandManager.CommandManager;
import com.alttd.proxydiscordlink.bot.listeners.DiscordRoleListener; import com.alttd.proxydiscordlink.bot.listeners.DiscordRoleListener;
import com.alttd.proxydiscordlink.bot.tasks.CheckLinkSync;
import com.alttd.proxydiscordlink.config.BotConfig; import com.alttd.proxydiscordlink.config.BotConfig;
import com.alttd.proxydiscordlink.util.ALogger; import com.alttd.proxydiscordlink.util.ALogger;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
@ -16,12 +15,10 @@ import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.exceptions.HierarchyException; import net.dv8tion.jda.api.exceptions.HierarchyException;
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.MemberCachePolicy;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -37,15 +34,10 @@ public class Bot {
.enableIntents(GatewayIntent.GUILD_MEMBERS) .enableIntents(GatewayIntent.GUILD_MEMBERS)
.build(); .build();
jda.setAutoReconnect(true); jda.setAutoReconnect(true);
jda.awaitReady();
jda.addEventListener( jda.addEventListener(
new DiscordRoleListener(), new DiscordRoleListener(),
new JDAListener(jda)); new JDAListener(jda)); //This executes code after jda is done loading
DiscordLink.getPlugin().getProxy().getScheduler().buildTask(DiscordLink.getPlugin(), new CheckLinkSync()) } catch (Exception e) {
.delay(120, TimeUnit.SECONDS)
.repeat(12, TimeUnit.HOURS)
.schedule();
} catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -239,20 +231,4 @@ public class Bot {
ALogger.warn("Unable to ban " + member.getAsMention() + " : " + member.getId() + " from Discord they might be above me."); ALogger.warn("Unable to ban " + member.getAsMention() + " : " + member.getId() + " from Discord they might be above me.");
} }
} }
public List<Member> getMembersWithRole(long guildId, long roleId) {
Guild guild = jda.getGuildById(guildId);
Role role = jda.getRoleById(roleId);
if (guild == null) {
//TODO error
return null;
}
if (role == null) {
//TODO error
return null;
}
return guild.getMembers().stream().filter(member -> member.getRoles().contains(role)).toList();
}
} }

View File

@ -0,0 +1,40 @@
package com.alttd.proxydiscordlink.bot;
import com.alttd.proxydiscordlink.bot.commands.*;
import net.dv8tion.jda.api.entities.Message;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class DiscordCommand {
private static List<DiscordCommand> commands;
public abstract String getCommand();
public abstract String getPermission();// TODO discord and LP permissions
public abstract String getDescription();
public abstract String getSyntax();
public abstract long getChannel();
public abstract void handleCommand(Message message, String sender, String command, String[] args);
public static void loadCommands() {
commands = new ArrayList<>();
loadCommand(new DiscordLinkCommand(),
new DiscordUnlink(),
new DiscordNick(),
new DiscordStaffList(),
new DiscordServerList()
);
}
private static void loadCommand(DiscordCommand ... discordCommands) {
Collections.addAll(commands, discordCommands);
}
public static List<DiscordCommand> getCommands() {
return commands;
}
}

View File

@ -37,6 +37,13 @@ public class CommandManager extends ListenerAdapter {
.filter(discordCommand -> discordCommand.getName().equalsIgnoreCase(commandName)) .filter(discordCommand -> discordCommand.getName().equalsIgnoreCase(commandName))
.findFirst(); .findFirst();
if (first.isEmpty()) { if (first.isEmpty()) {
event.replyEmbeds(new EmbedBuilder()
.setTitle("Invalid command")
.setDescription("We couldn't find a command called [" + commandName + "], please report this issue to a Teri")
.setColor(Color.RED)
.build())
.setEphemeral(true)
.queue();
return; return;
} }
first.get().execute(event); first.get().execute(event);

View File

@ -28,7 +28,7 @@ public class CommandLink extends DiscordCommand {
private final CommandData commandData; private final CommandData commandData;
public CommandLink(JDA jda) { public CommandLink(JDA jda) {
commandData = Commands.slash(getName(), "Link your Discord and Altitude Minecraft accounts") commandData = Commands.slash(getName(), "Link your Discord and Altitude Minecraft accounts")
.addOption(OptionType.STRING, "code", "The code you got from doing /discord link on Altitude in Minecraft", true) .addOption(OptionType.NUMBER, "code", "The code you got from doing /discord link on Altitude in Minecraft", true)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED); .setDefaultPermissions(DefaultMemberPermissions.ENABLED);
Utilities.registerCommand(jda, commandData); Utilities.registerCommand(jda, commandData);
@ -47,7 +47,7 @@ public class CommandLink extends DiscordCommand {
return; return;
} }
UUID uuid = getUUID(event.getOption("code", OptionMapping::getAsString)); UUID uuid = getUUID(event.getOption("link", OptionMapping::getAsInt));
if (uuid == null) { if (uuid == null) {
Utilities.commandErrAutoRem("This is not a valid link code, please check Minecraft and try again", event); Utilities.commandErrAutoRem("This is not a valid link code, please check Minecraft and try again", event);
return; return;
@ -127,10 +127,10 @@ public class CommandLink extends DiscordCommand {
return "No User"; return "No User";
} }
private UUID getUUID(String code) { private UUID getUUID(Integer code) {
if (code == null || !code.matches("[0-9]{6}")) if (code == null)
return null; return null;
return DiscordLink.getPlugin().getCache().getUUID(code); return DiscordLink.getPlugin().getCache().getUUID(String.valueOf(code));
} }
@Override @Override

View File

@ -13,7 +13,6 @@ import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands; import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import java.util.HashMap; import java.util.HashMap;
@ -21,10 +20,8 @@ public class CommandNick extends DiscordCommand {
CommandData commandData; CommandData commandData;
private final HashMap<String, SubOption> subOptionsMap = new HashMap<>(); private final HashMap<String, SubOption> subOptionsMap = new HashMap<>();
public CommandNick(JDA jda) { public CommandNick(JDA jda) {
commandData = Commands.slash(getName(), "Change your nickname to be your mc name/nickname") commandData = Commands.slash(getName(), "Create an auction")
.addSubcommands(new SubcommandData("username", "Change your name to your Minecraft username"), .addOption(OptionType.NUMBER, "code", "The code you got from doing /discord link on Altitude in Minecraft", true)
new SubcommandData("nickname", "Change your name to your Minecraft nickname")
)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED); .setDefaultPermissions(DefaultMemberPermissions.ENABLED);
Utilities.registerSubOptions(subOptionsMap, Utilities.registerSubOptions(subOptionsMap,
new SubCommandUserName(null,this), new SubCommandUserName(null,this),

View File

@ -1,77 +0,0 @@
package com.alttd.proxydiscordlink.bot.tasks;
import com.alttd.proxydiscordlink.DiscordLink;
import com.alttd.proxydiscordlink.bot.Bot;
import com.alttd.proxydiscordlink.config.BotConfig;
import com.alttd.proxydiscordlink.util.ALogger;
import net.dv8tion.jda.api.entities.Member;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class CheckLinkSync implements Runnable {
private final DiscordLink plugin;
private final Bot bot;
public CheckLinkSync() {
plugin = DiscordLink.getPlugin();
bot = plugin.getBot();
}
@Override
public void run() {
List<Member> members = bot.getMembersWithRole(BotConfig.DISCORD.GUILD_ID, BotConfig.DISCORD.LINKED_ROLE_ID);
HashSet<Long> dbIdSet = plugin.getDatabase().getLinkedUsers();
HashSet<Long> membersIdSet = members.stream().map(Member::getIdLong).collect(Collectors.toCollection(HashSet::new));
//give these people the link role in discord, if they are not in the discord unlink them in game
HashSet<Long> noRoleIds = dbIdSet.stream().filter(id -> !membersIdSet.contains(id)).collect(Collectors.toCollection(HashSet::new));
//remove the linked role from these people
HashSet<Long> notInDbIds = membersIdSet.stream().filter(id -> !dbIdSet.contains(id)).collect(Collectors.toCollection(HashSet::new));
fixNotInDb(members, notInDbIds);
fixNoLinkRole(members, noRoleIds);
}
private void fixNotInDb(List<Member> members, Set<Long> notInDbIds) {
for (Long id : notInDbIds) {
members.stream()
.filter(member -> member.getIdLong() == id)
.findAny()
.ifPresent(member -> {
ALogger.info("Removing linked role from user with discord id: [" + id + "] due to them not being in the database.");
// bot.removeRole(id, BotConfig.LINKED_ROLE_ID, member.getGuild().getIdLong());
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private void fixNoLinkRole(List<Member> members, Set<Long> noRoleIds) {
for (Long id : noRoleIds) {
members.stream()
.filter(member -> member.getIdLong() == id)
.findAny()
.ifPresentOrElse(
member -> {
ALogger.info("Adding role to user with discord id: [" + id + "] due to them being in the database without having a role in discord.");
// bot.addRole(id, BotConfig.LINKED_ROLE_ID, member.getGuild().getIdLong());
}, () -> {
ALogger.info("Removing user with discord id: [" + id + "] from the database due to them not being in the discord.");
// plugin.getDatabase().removeLinkedAccount(id);
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@ -1,7 +0,0 @@
package com.alttd.proxydiscordlink.bot.tasks;
public class CheckNitroSync {
//TODO copy CheckLinkSync but for nitro
}

View File

@ -35,7 +35,7 @@ public class BotConfig {
public static File CONFIGPATH; public static File CONFIGPATH;
public static void init() { // todo setup share for the config public static void init() { // todo setup share for the config
CONFIGPATH = new File(File.separator + "mnt" + File.separator + "configs" + File.separator + "DiscordLink"); CONFIGPATH = new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "DiscordLink");
CONFIG_FILE = new File(CONFIGPATH, "bot-config.yml"); CONFIG_FILE = new File(CONFIGPATH, "bot-config.yml");
configLoader = YAMLConfigurationLoader.builder() configLoader = YAMLConfigurationLoader.builder()

View File

@ -31,7 +31,7 @@ public final class Config {
public static File CONFIGPATH; public static File CONFIGPATH;
public static void init() { // todo setup share for the config public static void init() { // todo setup share for the config
CONFIGPATH = new File(File.separator + "mnt" + File.separator + "configs" + File.separator + "DiscordLink"); CONFIGPATH = new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "DiscordLink");
CONFIG_FILE = new File(CONFIGPATH, "config.yml"); CONFIG_FILE = new File(CONFIGPATH, "config.yml");
configLoader = YAMLConfigurationLoader.builder() configLoader = YAMLConfigurationLoader.builder()
@ -215,7 +215,7 @@ public final class Config {
public static String HELP_RELOAD = "<yellow><gold>/discord reload</gold>: Reload the config.</yellow>"; public static String HELP_RELOAD = "<yellow><gold>/discord reload</gold>: Reload the config.</yellow>";
public static String HELP_SYNC = "<yellow><gold>/discord sync</gold>: Manually synchronize your roles across Discord and Minecraft.</yellow>"; public static String HELP_SYNC = "<yellow><gold>/discord sync</gold>: Manually synchronize your roles across Discord and Minecraft.</yellow>";
public static List<String> DISCORD_MESSAGE = new ArrayList<>(List.of("Invite code here.")); public static List<String> DISCORD_MESSAGE = new ArrayList<>(List.of("Invite code here."));
public static String DISCORD_LINK = "<click:run_command:'/discord link'><yellow>Your Minecraft and Discord accounts aren't linked yet, to link them click this message!</yellow></click>"; public static String DISCORD_LINK = "<click:run:command:discord link:><yellow>Your Minecraft and Discord accounts aren't linked yet, to link them click this message!</yellow></click>";
public static String GIVE_CODE = "<yellow>Your code is <gold><code></gold>, To link your accounts do <gold>&link <code></gold> in the Discord #link channel.</yellow>"; public static String GIVE_CODE = "<yellow>Your code is <gold><code></gold>, To link your accounts do <gold>&link <code></gold> in the Discord #link channel.</yellow>";
private static void loadMessages() { private static void loadMessages() {

View File

@ -1,14 +1,13 @@
package com.alttd.proxydiscordlink.database; package com.alttd.proxydiscordlink.database;
import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer;
import com.velocitypowered.api.proxy.Player;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.UUID; import java.util.UUID;
public class Database { public class Database {
@ -104,19 +103,6 @@ public class Database {
} }
} }
public void removeRole(UUID uuid, String roleName) {
try {
String sql = "DELETE FROM account_roles WHERE uuid = ? AND role_name = ?";
PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(sql);
statement.setString(1, uuid.toString());
statement.setString(2, roleName);
statement.execute();
} catch (SQLException exception) {
exception.printStackTrace();
}
}
public boolean playerIsLinked(UUID uuid) { //TODO maybe this can be using the discord api instead? (or a cache idk) public boolean playerIsLinked(UUID uuid) { //TODO maybe this can be using the discord api instead? (or a cache idk)
try { try {
PreparedStatement statement = DatabaseConnection.getConnection() PreparedStatement statement = DatabaseConnection.getConnection()
@ -163,17 +149,7 @@ public class Database {
} catch (SQLException var2) { } catch (SQLException var2) {
var2.printStackTrace(); var2.printStackTrace();
} }
}
public void removeLinkedAccount(Long id) {
try {
PreparedStatement statement = DatabaseConnection.getConnection()
.prepareStatement("DELETE FROM linked_accounts WHERE discord_id = ?");
statement.setLong(1, id);
statement.executeUpdate();
} catch (SQLException var2) {
var2.printStackTrace();
}
} }
public String uuidFromName(String playerName) { public String uuidFromName(String playerName) {
@ -293,20 +269,4 @@ public class Database {
exception.printStackTrace(); exception.printStackTrace();
} }
} }
public HashSet<Long> getLinkedUsers() {
String sql = "SELECT discord_id FROM linked_accounts";
try {
PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(sql);
ResultSet resultSet = statement.executeQuery();
HashSet<Long> results = new HashSet<>();
while (resultSet.next()) {
results.add(resultSet.getLong("discord_id"));
}
return results;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
} }

View File

@ -3,14 +3,9 @@ package com.alttd.proxydiscordlink.minecraft.listeners;
import com.alttd.proxydiscordlink.DiscordLink; import com.alttd.proxydiscordlink.DiscordLink;
import com.alttd.proxydiscordlink.config.BotConfig; import com.alttd.proxydiscordlink.config.BotConfig;
import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer;
import com.alttd.proxydiscordlink.util.ALogger;
import com.alttd.proxydiscordlink.util.Utilities;
import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.ServerConnectedEvent; import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.proxy.Player;
import java.util.UUID;
public class PlayerJoin { public class PlayerJoin {
@ -18,16 +13,14 @@ public class PlayerJoin {
public void playerConnected(ServerConnectedEvent event) { public void playerConnected(ServerConnectedEvent event) {
if (event.getPreviousServer().isPresent()) if (event.getPreviousServer().isPresent())
return; return;
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
DiscordLinkPlayer discordLinkPlayer = DiscordLinkPlayer.getDiscordLinkPlayer(uuid); DiscordLinkPlayer discordLinkPlayer = DiscordLinkPlayer.getDiscordLinkPlayer(event.getPlayer().getUniqueId());
if (discordLinkPlayer == null) if (discordLinkPlayer == null)
return; return;
boolean sync = false; boolean sync = false;
String username = player.getUsername(); String username = event.getPlayer().getUsername();
if (!discordLinkPlayer.getUsername().equals(username)) { //Update username if needed if (!discordLinkPlayer.getUsername().equals(username)) { //Update username if needed
discordLinkPlayer.setUsername(username); discordLinkPlayer.setUsername(username);
@ -46,18 +39,6 @@ public class PlayerJoin {
DiscordLink.getPlugin().getBot().changeNick(BotConfig.DISCORD.GUILD_ID, discordLinkPlayer.getUserId(), nick); DiscordLink.getPlugin().getBot().changeNick(BotConfig.DISCORD.GUILD_ID, discordLinkPlayer.getUserId(), nick);
} }
boolean hasMinecraftNitro = Utilities.hasMinecraftNitro(player);
boolean hasDatabaseNitro = Utilities.hasDatabaseNitro(discordLinkPlayer);
if (hasMinecraftNitro != hasDatabaseNitro) {
if (hasMinecraftNitro) {
//Utilities.removeRole(uuid, "nitro"); //TODO add nitro to config
ALogger.info("Removing nitro role from [" + player.getUsername() + "] since they shouldn't have it");
} else {
//Utilities.addRole(uuid, "nitro"); //TODO add nitro to config
ALogger.info("Added nitro role to [" + player.getUsername() + "] since they should have it");
}
}
if (sync) //Sync if needed if (sync) //Sync if needed
DiscordLink.getPlugin().getDatabase().syncPlayer(discordLinkPlayer); DiscordLink.getPlugin().getDatabase().syncPlayer(discordLinkPlayer);
} }

View File

@ -5,7 +5,6 @@ import com.alttd.proxydiscordlink.bot.commandManager.SubOption;
import com.alttd.proxydiscordlink.bot.objects.DiscordRole; import com.alttd.proxydiscordlink.bot.objects.DiscordRole;
import com.alttd.proxydiscordlink.config.BotConfig; import com.alttd.proxydiscordlink.config.BotConfig;
import com.alttd.proxydiscordlink.config.Config; import com.alttd.proxydiscordlink.config.Config;
import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.ProxyServer;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
@ -85,16 +84,6 @@ public class Utilities {
return false; return false;
} }
public static boolean hasDatabaseNitro(DiscordLinkPlayer player) {
List<String> groups = player.getRoles();
for (String group : Config.DISCORD_GROUPS) {
if (groups.contains(group)) {
return true;
}
}
return false;
}
public static String getAuthKey() { public static String getAuthKey() {
String randChars = "1234567890"; String randChars = "1234567890";
StringBuilder salt = new StringBuilder(); StringBuilder salt = new StringBuilder();
@ -217,31 +206,4 @@ public class Utilities {
.setEphemeral(true) .setEphemeral(true)
.queue(res -> res.deleteOriginal().queueAfter(5, TimeUnit.SECONDS)); .queue(res -> res.deleteOriginal().queueAfter(5, TimeUnit.SECONDS));
} }
public static boolean removeRole(UUID uuid, String group) {
User user = getLuckPerms().getUserManager().getUser(uuid);
if (user == null)
return false;
user.getNodes(NodeType.INHERITANCE)
.stream()
.filter(inheritanceNode -> inheritanceNode.getGroupName().equalsIgnoreCase(group))
.findAny()
.ifPresent(node ->
getLuckPerms().getUserManager().modifyUser(uuid, result -> result.data().remove(node)));
return true;
}
public static boolean addRole(UUID uuid, String group) {
User user = getLuckPerms().getUserManager().getUser(uuid);
if (user == null)
return false;
user.getNodes(NodeType.INHERITANCE)
.stream()
.filter(inheritanceNode -> inheritanceNode.getGroupName().equalsIgnoreCase(group))
.findAny()
.ifPresent(node ->
getLuckPerms().getUserManager().modifyUser(uuid, result -> result.data().add(node)));
return true;
}
} }