From e4f2462c0c451f23e528a3e4a9592fd6dd496890 Mon Sep 17 00:00:00 2001 From: HypherionMC Date: Sun, 29 Oct 2023 15:42:58 +0200 Subject: [PATCH] [FEAT] Access control denied roles, and ban members from discord/mc on ban --- .../core/accounts/MinecraftAccount.java | 30 +++++++++++++++++++ .../sdlink/core/config/SDLinkConfig.java | 2 +- .../core/config/impl/AccessControl.java | 16 ++++++++++ .../discord/events/DiscordEventHandler.java | 4 ++- .../core/managers/PermissionChecker.java | 6 +++- .../sdlink/core/managers/RoleManager.java | 13 ++++++++ 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/hypherionmc/sdlink/core/accounts/MinecraftAccount.java b/src/main/java/com/hypherionmc/sdlink/core/accounts/MinecraftAccount.java index b942026..7e7f3cb 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/accounts/MinecraftAccount.java +++ b/src/main/java/com/hypherionmc/sdlink/core/accounts/MinecraftAccount.java @@ -6,6 +6,7 @@ package com.hypherionmc.sdlink.core.accounts; import com.hypherionmc.sdlink.core.config.SDLinkConfig; import com.hypherionmc.sdlink.core.database.SDLinkAccount; +import com.hypherionmc.sdlink.core.discord.BotController; import com.hypherionmc.sdlink.core.managers.CacheManager; import com.hypherionmc.sdlink.core.managers.RoleManager; import com.hypherionmc.sdlink.core.messaging.Result; @@ -33,6 +34,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static com.hypherionmc.sdlink.core.managers.DatabaseManager.sdlinkDatabase; @@ -269,6 +271,9 @@ public class MinecraftAccount { case "rolesNotLoaded" -> { return Result.error("Server has required roles configured, but no discord roles were loaded. Please notify the server owner"); } + case "accessDeniedByRole" -> { + return Result.error(SDLinkConfig.INSTANCE.accessControl.verificationMessages.roleDenied); + } case "rolesNotFound" -> { return Result.error(SDLinkConfig.INSTANCE .accessControl @@ -308,9 +313,15 @@ public class MinecraftAccount { Profiler profiler = Profiler.getProfiler("checkRequiredRoles"); profiler.start("Checking Required Roles"); AtomicBoolean anyFound = new AtomicBoolean(false); + AtomicBoolean deniedFound = new AtomicBoolean(false); Optional member = CacheManager.getDiscordMembers().stream().filter(m -> m.getId().equals(account.getDiscordID())).findFirst(); member.ifPresent(m -> m.getRoles().forEach(r -> { + if (RoleManager.getDeniedRoles().stream().anyMatch(role -> r.getIdLong() == role.getIdLong())) { + if (!deniedFound.get()) + deniedFound.set(true); + } + if (RoleManager.getVerificationRoles().stream().anyMatch(role -> role.getIdLong() == r.getIdLong())) { if (!anyFound.get()) { anyFound.set(true); @@ -319,6 +330,9 @@ public class MinecraftAccount { })); profiler.stop(); + if (deniedFound.get()) + return Result.error("accessDeniedByRole"); + if (!anyFound.get()) return Result.error("rolesNotFound"); @@ -329,6 +343,22 @@ public class MinecraftAccount { return Result.success("pass"); } + public void banDiscordMember() { + if (!SDLinkConfig.INSTANCE.accessControl.banMemberOnMinecraftBan) + return; + + DiscordUser user = getDiscordUser(); + + if (user == null) + return; + + try { + BotController.INSTANCE.getJDA().getGuilds().get(0).ban(UserSnowflake.fromId(user.getUserId()), 7, TimeUnit.DAYS).queue(); + } catch (Exception e) { + e.printStackTrace(); + } + } + public String getUsername() { return username; } diff --git a/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java b/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java index b7aa03c..09ca0b1 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java +++ b/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java @@ -24,7 +24,7 @@ public class SDLinkConfig extends ModuleConfig { // DO NOT REMOVE TRANSIENT HERE... OTHERWISE, THE STUPID CONFIG LIBRARY // WILL TRY TO WRITE THESE TO THE CONFIG public transient static SDLinkConfig INSTANCE; - public transient static int configVer = 11; + public transient static int configVer = 12; @Path("general") @SpecComment("General Mod Config") diff --git a/src/main/java/com/hypherionmc/sdlink/core/config/impl/AccessControl.java b/src/main/java/com/hypherionmc/sdlink/core/config/impl/AccessControl.java index 1d74bc3..71dd297 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/config/impl/AccessControl.java +++ b/src/main/java/com/hypherionmc/sdlink/core/config/impl/AccessControl.java @@ -24,6 +24,10 @@ public class AccessControl { @SpecComment("Optional: The player requires any of these roles to be able to join your server") public List requiredRoles = new ArrayList<>(); + @Path("deniedRoles") + @SpecComment("Optional: Players with these roles will never be allowed access to your server") + public List deniedRoles = new ArrayList<>(); + @Path("verifiedRole") @SpecComment("Optional: Role name or ID to assign to verified player accounts") public String verifiedRole = ""; @@ -32,6 +36,14 @@ public class AccessControl { @SpecComment("Configure messages shown to players when they don't meet verification requirements") public AccessMessages verificationMessages = new AccessMessages(); + @Path("banPlayerOnDiscordBan") + @SpecComment("Should players with verified accounts, be banned from Minecraft if they get banned on discord") + public boolean banPlayerOnDiscordBan = false; + + @Path("banMemberOnMinecraftBan") + @SpecComment("Should members with verified accounts, be banned from discord when they are banned on Minecraft") + public boolean banMemberOnMinecraftBan = false; + public static class AccessMessages { @Path("accountVerification") @@ -46,6 +58,10 @@ public class AccessControl { @SpecComment("Message to show when player doesn't have one of the required roles. Use {roles} to display the names of configured roles") public String requireRoles = "Sorry, but you require any of the following roles: {roles}"; + @Path("roleDenied") + @SpecComment("Message to show when player has a role from the deniedRoles list") + public String roleDenied = "Sorry, but you are not allowed to access this server."; + } } diff --git a/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java b/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java index cd1bba5..c50ace6 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java +++ b/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java @@ -160,7 +160,9 @@ public class DiscordEventHandler extends ListenerAdapter { if (acc != null) { sdlinkDatabase.remove(a, SDLinkAccount.class); - SDLinkPlatform.minecraftHelper.banPlayer(acc); + if (SDLinkConfig.INSTANCE.accessControl.banPlayerOnDiscordBan) { + SDLinkPlatform.minecraftHelper.banPlayer(acc); + } sdlinkDatabase.reloadCollection("verifiedaccounts"); } }); diff --git a/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java b/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java index ee71d3f..4b01e7a 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java +++ b/src/main/java/com/hypherionmc/sdlink/core/managers/PermissionChecker.java @@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger; public class PermissionChecker { // Invite URL for bot shown in server logs - private static final String DISCORD_INVITE = "https://discord.com/api/oauth2/authorize?client_id={bot_id}&permissions=2953276432&scope=bot%20applications.commands"; + private static final String DISCORD_INVITE = "https://discord.com/api/oauth2/authorize?client_id={bot_id}&permissions=2953276436&scope=bot%20applications.commands"; // Base Permissions required by the bot to operate private static final List BOT_PERMS = new ArrayList<>() {{ @@ -49,6 +49,10 @@ public class PermissionChecker { * Run the permission checker to see if the bot has all the required permissions */ public static void checkBotSetup() { + if (SDLinkConfig.INSTANCE.accessControl.banMemberOnMinecraftBan) { + BOT_PERMS.add(Permission.BAN_MEMBERS); + } + StringBuilder builder = new StringBuilder(); builder.append("\r\n").append("******************* Simple Discord Link Errors *******************").append("\r\n"); AtomicInteger errCount = new AtomicInteger(); diff --git a/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java b/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java index d8818f2..dc9458e 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java +++ b/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java @@ -22,6 +22,8 @@ import java.util.concurrent.atomic.AtomicInteger; public class RoleManager { private static final Set verificationRoles = new HashSet<>(); + private static final Set deniedRoles = new HashSet<>(); + private static Role verifiedRole = null; /** @@ -38,6 +40,13 @@ public class RoleManager { verificationRoles.add(role); }); + SDLinkConfig.INSTANCE.accessControl.deniedRoles.forEach(r -> { + Role role = getRole(errCount, builder, "Access Control Role", r); + + if (role != null) + deniedRoles.add(role); + }); + if (!SDLinkUtils.isNullOrEmpty(SDLinkConfig.INSTANCE.accessControl.verifiedRole)) { verifiedRole = getRole(errCount, builder, "Verified Player Role", SDLinkConfig.INSTANCE.accessControl.verifiedRole); } @@ -87,4 +96,8 @@ public class RoleManager { public static Role getVerifiedRole() { return verifiedRole; } + + public static Set getDeniedRoles() { + return deniedRoles; + } }