From 579c991e7519bcdfe8749be1f3f89ffe32cff4ce Mon Sep 17 00:00:00 2001 From: Xyntexx Date: Wed, 17 Mar 2021 22:40:28 +0200 Subject: [PATCH 1/2] feat: add ability to test for all limited roles --- .../uk/co/angrybee/joe/DiscordClient.java | 98 ++++++++++++++++++- .../co/angrybee/joe/configs/MainConfig.java | 2 + 2 files changed, 97 insertions(+), 3 deletions(-) diff --git a/src/main/java/uk/co/angrybee/joe/DiscordClient.java b/src/main/java/uk/co/angrybee/joe/DiscordClient.java index 48d87fb..d7925df 100644 --- a/src/main/java/uk/co/angrybee/joe/DiscordClient.java +++ b/src/main/java/uk/co/angrybee/joe/DiscordClient.java @@ -12,6 +12,7 @@ import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.utils.ChunkingFilter; import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.cache.CacheFlag; +import org.apache.commons.lang3.ArrayUtils; import org.bukkit.configuration.file.FileConfiguration; import org.json.simple.JSONObject; import org.json.simple.JSONValue; @@ -83,6 +84,7 @@ public class DiscordClient extends ListenerAdapter public static String[] whitelistedRoleNames; private static boolean checkForMissingRole = false; + private static boolean checkAllRoles = false; private static String roleToCheck; public static final char[] validCharacters = {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', @@ -161,6 +163,7 @@ public class DiscordClient extends ListenerAdapter } checkForMissingRole = mainConfig.getBoolean("un-whitelist-if-missing-role"); + checkAllRoles = mainConfig.getBoolean("check-all-roles"); roleToCheck = mainConfig.getString("role-to-check-for"); } @@ -1108,13 +1111,49 @@ public class DiscordClient extends ListenerAdapter CheckForRequiredRole(e); } - // TODO check users at startup for required role, in case it was removed while the bot was offline private static void CheckForRequiredRole(GuildMemberRoleRemoveEvent e) { if(!checkForMissingRole) return; + if(checkAllRoles){ + String[] allRoles = ArrayUtils.addAll(allowedToAddRemoveRoles, ArrayUtils.addAll(allowedToAddRoles, ArrayUtils.addAll(allowedToAddLimitedRoles, allowedToClearNamesRoles))); - if(roleToCheck == null || roleToCheck.equals("")) + String discordUserId= e.getMember().getId(); + List removedRoles = e.getRoles(); + boolean limitedRoleRemoved = false; + for(Role role:removedRoles){ + if(Arrays.asList(allowedToAddLimitedRoles).contains(role.getId())){ + limitedRoleRemoved = true; + break; + } + } + if(!limitedRoleRemoved){ + DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " unrelated role removed. Doing nothing..."); + return; + } + DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " weak role removed. Checking remaining roles..."); + boolean rolesRemaining= false; + for(int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) + { + Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(discordUserId); + if(member != null){ + List roles = member.getRoles(); + for(Role role:roles){ + if(Arrays.asList(allRoles).contains(role.getId())){ + rolesRemaining = true; + break; + } + } + } + } + if(!rolesRemaining){ + DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " has no roles remaining. Removing their whitelisted entries..."); + UnWhitelist(discordUserId); + } + else{ + DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " has role(s) remaining. Doing nothing..."); + } + }else if(roleToCheck == null || roleToCheck.equals("")) { DiscordWhitelister.getPluginLogger().warning("'un-whitelist-if-missing-role' is enabled but " + "'role-to-check-for' is null or empty, please double check the config"); @@ -1176,13 +1215,58 @@ public class DiscordClient extends ListenerAdapter if (!checkForMissingRole) return; + if (checkAllRoles) { + DiscordWhitelister.getPluginLogger().info("Checking Discord IDs for required roles..."); + String[] allRoles = ArrayUtils.addAll(allowedToAddRemoveRoles, ArrayUtils.addAll(allowedToAddRoles, ArrayUtils.addAll(allowedToAddLimitedRoles, allowedToClearNamesRoles))); + + Yaml idYaml = new Yaml(); + UserList.SaveStore(); + InputStream inputStream = new FileInputStream(UserList.getUserListFile()); + + PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream); + int b = pushbackInputStream.read(); + + if (b == -1) + return; + else + pushbackInputStream.unread(b); + + Map> userObject = idYaml.load(pushbackInputStream); + + for (Map.Entry> entry : userObject.entrySet()) { + // Check if the ID is in any guilds + + // Check all guilds + boolean rolesRemaining = false; + for (int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) { + Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(entry.getKey()); + if (member != null) { + List roles = member.getRoles(); + for (Role role : roles) { + if (Arrays.asList(allRoles).contains(role.getId())) { + rolesRemaining = true; + break; + } + } + } + } + if (!rolesRemaining) { + DiscordWhitelister.getPlugin().getLogger().info(entry.getKey() + " has no roles remaining. Removing their whitelisted entries..."); + UnWhitelist(entry.getKey()); + } + } + return; + } + + + if (roleToCheck == null || roleToCheck.equals("")) { DiscordWhitelister.getPluginLogger().warning("'un-whitelist-if-missing-role' is enabled but " + "'role-to-check-for' is null or empty, please double check the config"); return; } - DiscordWhitelister.getPluginLogger().info("Checking Discord IDs for required roles..."); + DiscordWhitelister.getPluginLogger().info("Checking Discord IDs for required role " + roleToCheck); Yaml idYaml = new Yaml(); UserList.SaveStore(); @@ -1222,6 +1306,14 @@ public class DiscordClient extends ListenerAdapter DiscordWhitelister.getPluginLogger().info("Removed " + entry.getValue().get(i) + " from the whitelist as Discord ID: " + entry.getKey() + " due to missing required role (" + roleToCheck + ")."); } + // Clear entries in user-list + if (userObject.get(entry.getKey()) != null) { + UserList.getUserList().set(entry.getKey(), null); + + UserList.SaveStore(); + + DiscordWhitelister.getPlugin().getLogger().info("Successfully removed " +entry.getKey() + " whitelisted entries from the user list."); + } } } } catch (IOException e) { diff --git a/src/main/java/uk/co/angrybee/joe/configs/MainConfig.java b/src/main/java/uk/co/angrybee/joe/configs/MainConfig.java index e52447b..e9b7afc 100644 --- a/src/main/java/uk/co/angrybee/joe/configs/MainConfig.java +++ b/src/main/java/uk/co/angrybee/joe/configs/MainConfig.java @@ -163,6 +163,8 @@ public class MainConfig CheckEntry("un-whitelist-if-missing-role", false); + CheckEntry("check-all-roles", false); + CheckEntry("role-to-check-for", "Twitch Subscriber"); // Remove old role entry if found, move role to new array (for people with v1.3.6 or below) From 6d147ce2b309b2e9e6c1f0178b1c74349c5ab3b1 Mon Sep 17 00:00:00 2001 From: Joe Shimell <49585339+JoeShimell@users.noreply.github.com> Date: Thu, 18 Mar 2021 02:08:05 +0000 Subject: [PATCH 2/2] combine all roles into array once at start up, added extra checks for role startup check, fixed sending the Unwhitelist function discord ID instead of their minecraft names, fixed role check not triggering due to checking for role id not role name --- .../uk/co/angrybee/joe/DiscordClient.java | 340 +++++++++++------- .../co/angrybee/joe/DiscordWhitelister.java | 6 + 2 files changed, 217 insertions(+), 129 deletions(-) diff --git a/src/main/java/uk/co/angrybee/joe/DiscordClient.java b/src/main/java/uk/co/angrybee/joe/DiscordClient.java index d7925df..e4379a2 100644 --- a/src/main/java/uk/co/angrybee/joe/DiscordClient.java +++ b/src/main/java/uk/co/angrybee/joe/DiscordClient.java @@ -12,7 +12,6 @@ import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.utils.ChunkingFilter; import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.cache.CacheFlag; -import org.apache.commons.lang3.ArrayUtils; import org.bukkit.configuration.file.FileConfiguration; import org.json.simple.JSONObject; import org.json.simple.JSONValue; @@ -44,6 +43,8 @@ public class DiscordClient extends ListenerAdapter public static String[] allowedToAddLimitedRoles; public static String[] allowedToClearNamesRoles; + public static String[] combinedRoles; + private static String[] targetTextChannels; // TODO: remove in favour of split versions @@ -1115,109 +1116,149 @@ public class DiscordClient extends ListenerAdapter { if(!checkForMissingRole) return; - if(checkAllRoles){ - String[] allRoles = ArrayUtils.addAll(allowedToAddRemoveRoles, ArrayUtils.addAll(allowedToAddRoles, ArrayUtils.addAll(allowedToAddLimitedRoles, allowedToClearNamesRoles))); - String discordUserId= e.getMember().getId(); + String disName = e.getMember().getEffectiveName(); + String disId = e.getMember().getId(); + String nameForLogger = disName + "(" + disId + ")"; + + if(checkAllRoles) + { List removedRoles = e.getRoles(); boolean limitedRoleRemoved = false; - for(Role role:removedRoles){ - if(Arrays.asList(allowedToAddLimitedRoles).contains(role.getId())){ + + // Check if removed roles contain a limited-add role + for(Role role:removedRoles) + { + if(Arrays.asList(allowedToAddLimitedRoles).contains(role.getName())) + { limitedRoleRemoved = true; break; } } - if(!limitedRoleRemoved){ - DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " unrelated role removed. Doing nothing..."); + + if(!limitedRoleRemoved) return; - } - DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " weak role removed. Checking remaining roles..."); + + DiscordWhitelister.getPlugin().getLogger().info(nameForLogger + "'s limited role(s) has been removed. Checking for remaining roles..."); boolean rolesRemaining= false; for(int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) { - Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(discordUserId); - if(member != null){ + Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(disId); + if(member != null) + { List roles = member.getRoles(); - for(Role role:roles){ - if(Arrays.asList(allRoles).contains(role.getId())){ + for(Role role:roles) + { + if(Arrays.asList(combinedRoles).contains(role.getName())) + { rolesRemaining = true; break; } } } } - if(!rolesRemaining){ - DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " has no roles remaining. Removing their whitelisted entries..."); - UnWhitelist(discordUserId); - } - else{ - DiscordWhitelister.getPlugin().getLogger().info(discordUserId + " has role(s) remaining. Doing nothing..."); - } - }else if(roleToCheck == null || roleToCheck.equals("")) - { - DiscordWhitelister.getPluginLogger().warning("'un-whitelist-if-missing-role' is enabled but " + - "'role-to-check-for' is null or empty, please double check the config"); - return; - } - for(Role r : e.getMember().getRoles()) - { - // required role found, no need to proceed - if(r.getName().equals(roleToCheck)) - return; - } - - String disName = e.getMember().getEffectiveName(); - String disId = e.getMember().getId(); - String nameForLogger = disName + "(" + disId + ")"; - - DiscordWhitelister.getPluginLogger().info(nameForLogger + " does not have the required " + - "role (" + roleToCheck + "). Attempting to remove their whitelisted entries..."); - - List regUsers = UserList.getRegisteredUsers(disId); - if(regUsers != null) - { - if(regUsers.size() <= 0) + if(!rolesRemaining) { - DiscordWhitelister.getPluginLogger().info(nameForLogger + "'s entries are empty, doing nothing"); - return; - } + DiscordWhitelister.getPlugin().getLogger().info(nameForLogger + " has no roles remaining. Removing their whitelisted entries..."); - for(Object mcName : regUsers) - { - UnWhitelist(mcName.toString()); - } + List ls = UserList.getRegisteredUsers(disId); + if(ls != null) + { + for (Object minecraftNameToRemove : ls) + { + UnWhitelist(minecraftNameToRemove.toString()); + } - try - { - UserList.resetRegisteredUsers(disId); + try + { + UserList.resetRegisteredUsers(disId); + } + catch (IOException ex) + { + ex.printStackTrace(); + } + } + else + { + DiscordWhitelister.getPlugin().getLogger().warning(nameForLogger + " does not have any whitelisted entries doing nothing..."); + } } - catch (IOException ex) + else { - DiscordWhitelister.getPluginLogger().severe("Failed to remove whitelisted users from " + - nameForLogger); - ex.printStackTrace(); - return; + DiscordWhitelister.getPlugin().getLogger().info(nameForLogger + " has role(s) remaining. Doing nothing..."); } - - DiscordWhitelister.getPluginLogger().info("Successfully removed " + nameForLogger + - "'s whitelisted entries due to missing required role (" + roleToCheck + ")"); } else { - DiscordWhitelister.getPluginLogger().warning("Failed to remove whitelisted entries from " + - nameForLogger + " as they did not whitelist through this plugin"); + if(roleToCheck == null || roleToCheck.equals("")) + { + DiscordWhitelister.getPluginLogger().warning("'un-whitelist-if-missing-role' is enabled but " + + "'role-to-check-for' is null or empty, please double check the config"); + return; + } + + for(Role r : e.getMember().getRoles()) + { + // required role found, no need to proceed + if(r.getName().equals(roleToCheck)) + return; + } + + DiscordWhitelister.getPluginLogger().info(nameForLogger + " does not have the required " + + "role (" + roleToCheck + "). Attempting to remove their whitelisted entries..."); + + List regUsers = UserList.getRegisteredUsers(disId); + if(regUsers != null) + { + if(regUsers.size() <= 0) + { + DiscordWhitelister.getPluginLogger().info(nameForLogger + "'s entries are empty, doing nothing"); + return; + } + + for(Object mcName : regUsers) + { + UnWhitelist(mcName.toString()); + } + + try + { + UserList.resetRegisteredUsers(disId); + } + catch (IOException ex) + { + DiscordWhitelister.getPluginLogger().severe("Failed to remove whitelisted users from " + + nameForLogger); + ex.printStackTrace(); + return; + } + + DiscordWhitelister.getPluginLogger().info("Successfully removed " + nameForLogger + + "'s whitelisted entries due to missing required role (" + roleToCheck + ")"); + } + else + { + DiscordWhitelister.getPluginLogger().warning("Failed to remove whitelisted entries from " + + nameForLogger + " as they did not whitelist through this plugin"); + } } } - public static void RequiredRoleStartupCheck() { - try { + public static void RequiredRoleStartupCheck() + { + try + { if (!checkForMissingRole) return; - if (checkAllRoles) { + // Don't attempt to remove roles if not connected + if (javaDiscordAPI.getStatus() != JDA.Status.CONNECTED) + return; + + if (checkAllRoles) + { DiscordWhitelister.getPluginLogger().info("Checking Discord IDs for required roles..."); - String[] allRoles = ArrayUtils.addAll(allowedToAddRemoveRoles, ArrayUtils.addAll(allowedToAddRoles, ArrayUtils.addAll(allowedToAddLimitedRoles, allowedToClearNamesRoles))); Yaml idYaml = new Yaml(); UserList.SaveStore(); @@ -1233,90 +1274,131 @@ public class DiscordClient extends ListenerAdapter Map> userObject = idYaml.load(pushbackInputStream); - for (Map.Entry> entry : userObject.entrySet()) { - // Check if the ID is in any guilds - + for (Map.Entry> entry : userObject.entrySet()) + { // Check all guilds boolean rolesRemaining = false; - for (int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) { + for (int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) + { Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(entry.getKey()); - if (member != null) { + + if (member != null) + { List roles = member.getRoles(); - for (Role role : roles) { - if (Arrays.asList(allRoles).contains(role.getId())) { + for (Role role : roles) + { + if (Arrays.asList(combinedRoles).contains(role.getName())) + { rolesRemaining = true; break; } } } } - if (!rolesRemaining) { + + if (!rolesRemaining) + { DiscordWhitelister.getPlugin().getLogger().info(entry.getKey() + " has no roles remaining. Removing their whitelisted entries..."); - UnWhitelist(entry.getKey()); - } - } - return; - } + if(entry.getValue() == null || entry.getValue().size() <= 0) + { + DiscordWhitelister.getPluginLogger().info("User ID: " + entry.getKey() + "has no whitelisted users, doing nothing..."); + } + else + { + for(String wUser : entry.getValue()) + { + UnWhitelist(wUser); + } + // Clear entries in user-list + if (userObject.get(entry.getKey()) != null) + { + UserList.getUserList().set(entry.getKey(), null); + UserList.SaveStore(); - if (roleToCheck == null || roleToCheck.equals("")) { - DiscordWhitelister.getPluginLogger().warning("'un-whitelist-if-missing-role' is enabled but " + - "'role-to-check-for' is null or empty, please double check the config"); - return; - } - - DiscordWhitelister.getPluginLogger().info("Checking Discord IDs for required role " + roleToCheck); - - Yaml idYaml = new Yaml(); - UserList.SaveStore(); - InputStream inputStream = new FileInputStream(UserList.getUserListFile()); - - PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream); - int b = pushbackInputStream.read(); - - if (b == -1) - return; - else - pushbackInputStream.unread(b); - - Map> userObject = idYaml.load(pushbackInputStream); - - for (Map.Entry> entry : userObject.entrySet()) { - // Check if the ID is in any guilds - boolean hasRole = false; - - // Check all guilds - boolean requiredRole = false; - for (int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) { - Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(entry.getKey()); - if (member != null) { - for (Role role : member.getRoles()) { - if (role.getId().equals(roleToCheck)) { - requiredRole = true; - break; + DiscordWhitelister.getPlugin().getLogger().info("Successfully removed " + entry.getKey() + " whitelisted entries from the user list."); } } } } - if (!requiredRole) { - for (int i = 0; i < entry.getValue().size(); i++) { - // un-whitelist - UnWhitelist(entry.getValue().get(i)); - DiscordWhitelister.getPluginLogger().info("Removed " + entry.getValue().get(i) - + " from the whitelist as Discord ID: " + entry.getKey() + " due to missing required role (" + roleToCheck + ")."); + } + else + { + if (roleToCheck == null || roleToCheck.equals("")) + { + DiscordWhitelister.getPluginLogger().warning("'un-whitelist-if-missing-role' is enabled but " + + "'role-to-check-for' is null or empty, please double check the config"); + return; + } + + DiscordWhitelister.getPluginLogger().info("Checking Discord IDs for required role " + roleToCheck); + + Yaml idYaml = new Yaml(); + UserList.SaveStore(); + InputStream inputStream = new FileInputStream(UserList.getUserListFile()); + + PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream); + int b = pushbackInputStream.read(); + + if (b == -1) + return; + else + pushbackInputStream.unread(b); + + Map> userObject = idYaml.load(pushbackInputStream); + + for (Map.Entry> entry : userObject.entrySet()) + { + // Check all guilds + boolean requiredRole = false; + for (int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) + { + Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(entry.getKey()); + if (member != null) + { + for (Role role : member.getRoles()) + { + if (role.getId().equals(roleToCheck)) + { + requiredRole = true; + break; + } + } + } } - // Clear entries in user-list - if (userObject.get(entry.getKey()) != null) { - UserList.getUserList().set(entry.getKey(), null); - UserList.SaveStore(); + if (!requiredRole) + { + if(entry.getValue() != null && entry.getValue().size() <= 0) + { + DiscordWhitelister.getPluginLogger().info("User ID: " + entry.getKey() + "has no whitelisted users, doing nothing..."); + } + else + { + for (int i = 0; i < entry.getValue().size(); i++) + { + // un-whitelist + UnWhitelist(entry.getValue().get(i)); + DiscordWhitelister.getPluginLogger().info("Removed " + entry.getValue().get(i) + + " from the whitelist as Discord ID: " + entry.getKey() + " due to missing required role (" + roleToCheck + ")."); + } + } - DiscordWhitelister.getPlugin().getLogger().info("Successfully removed " +entry.getKey() + " whitelisted entries from the user list."); + // Clear entries in user-list + if (userObject.get(entry.getKey()) != null) + { + UserList.getUserList().set(entry.getKey(), null); + UserList.SaveStore(); + + DiscordWhitelister.getPlugin().getLogger().info("Successfully removed " + entry.getKey() + " whitelisted entries from the user list."); + } } } } - } catch (IOException e) { + } + catch (IOException e) + { e.printStackTrace(); } } diff --git a/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java b/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java index f937a9a..6ca13d5 100755 --- a/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java +++ b/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java @@ -17,6 +17,7 @@ import uk.co.angrybee.joe.stores.WhitelistedPlayers; import java.util.List; import java.util.logging.Logger; +import java.util.stream.Stream; public class DiscordWhitelister extends JavaPlugin { @@ -219,6 +220,11 @@ public class DiscordWhitelister extends JavaPlugin DiscordClient.allowedToClearNamesRoles[roles] = MainConfig.getMainConfig().getStringList("clear-command-roles").get(roles); } + // All roles combined for role check + DiscordClient.combinedRoles = Stream.of(DiscordClient.allowedToAddRemoveRoles, DiscordClient.allowedToAddRoles, + DiscordClient.allowedToAddLimitedRoles, DiscordClient.allowedToClearNamesRoles) + .flatMap(Stream::of).toArray(String[]::new); + // Custom messages check useCustomMessages = MainConfig.getMainConfig().getBoolean("use-custom-messages"); useCustomPrefixes = MainConfig.getMainConfig().getBoolean("use-custom-prefixes");