From e7c2b5be7b7dcced29a65f2d5cad6c6102fdc1a6 Mon Sep 17 00:00:00 2001
From: Xyntexx <mnuuja@gmail.com>
Date: Tue, 20 Jul 2021 19:26:45 +0300
Subject: [PATCH 1/2] fix errors during startup and shutdown when fresh configs
 version bump

---
 pom.xml                                       |   4 +-
 .../co/angrybee/joe/DiscordWhitelister.java   | 193 +++++++++---------
 .../joe/commands/minecraft/CommandReload.java |   2 +
 .../co/angrybee/joe/configs/MainConfig.java   |   6 +-
 4 files changed, 101 insertions(+), 104 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5183140..19e7a97 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 
   <groupId>uk.co.angrybee.joe</groupId>
   <artifactId>discord-whitelister</artifactId>
-  <version>1.4.8</version>
+  <version>1.4.9</version>
 
   <name>discord-whitelister</name>
   <url>https://github.com/JoeShimell/DiscordWhitelisterSpigot</url>
@@ -49,7 +49,7 @@
     <dependency>
       <groupId>org.spigotmc</groupId>
       <artifactId>spigot-api</artifactId>
-      <version>1.17-R0.1-SNAPSHOT</version>
+      <version>1.17.1-R0.1-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
 
diff --git a/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java b/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java
index a138955..66131a5 100755
--- a/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java
+++ b/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java
@@ -25,12 +25,12 @@ import java.util.List;
 import java.util.logging.Logger;
 import java.util.stream.Stream;
 
-public class DiscordWhitelister extends JavaPlugin
-{
+public class DiscordWhitelister extends JavaPlugin {
     public static String botToken;
 
     private static boolean configCreated = false;
 
+    public static boolean initialized = false;
     public static boolean useCustomMessages = false;
     public static boolean useIdForRoles = false;
     public static boolean useCustomPrefixes = false;
@@ -70,8 +70,7 @@ public class DiscordWhitelister extends JavaPlugin
 
 
     @Override
-    public void onEnable()
-    {
+    public void onEnable() {
         thisPlugin = this;
         thisServer = thisPlugin.getServer();
         pluginLogger = thisPlugin.getLogger();
@@ -84,19 +83,20 @@ public class DiscordWhitelister extends JavaPlugin
 
         int initSuccess = InitBot(true);
 
-        if(initSuccess == 0)
-        {
+        if (initSuccess == 0) {
             pluginLogger.info("Successfully initialized Discord client");
-        }
-        else if(initSuccess == 1)
-        {
+            initialized = true;
+        } else if (initSuccess == 1) {
             pluginLogger.severe("Discord Client failed to initialize, please check if your config file is valid");
+            initialized = false;
             return;
         }
 
         // Check for leavers if enabled
-        DiscordClient.ServerLeaveStartupCheck();
-        DiscordClient.RequiredRoleStartupCheck();
+        if (botEnabled) {
+            DiscordClient.ServerLeaveStartupCheck();
+            DiscordClient.RequiredRoleStartupCheck();
+        }
 
         this.getCommand("discordwhitelister").setExecutor(new CommandStatus());
         this.getCommand("discordwhitelisterabout").setExecutor(new CommandAbout());
@@ -104,33 +104,46 @@ public class DiscordWhitelister extends JavaPlugin
     }
 
     @Override
-    public void onDisable()
-    {
-        DiscordClient.javaDiscordAPI.shutdownNow();
+    public void onDisable() {
+        if (initialized ) {
+            DiscordClient.javaDiscordAPI.shutdownNow();
+        }
     }
 
-    public static JavaPlugin getPlugin()
-    {
+    public static JavaPlugin getPlugin() {
         return thisPlugin;
     }
 
-    public static FileConfiguration getCustomMessagesConfig() { return customMessagesConfig.getFileConfiguration(); }
+    public static FileConfiguration getCustomMessagesConfig() {
+        return customMessagesConfig.getFileConfiguration();
+    }
 
-    public static Logger getPluginLogger() { return pluginLogger; }
+    public static Logger getPluginLogger() {
+        return pluginLogger;
+    }
 
-    public static boolean getUseCustomPrefixes() { return useCustomPrefixes; }
+    public static boolean getUseCustomPrefixes() {
+        return useCustomPrefixes;
+    }
 
-    public static void addVanishedPlayer() { vanishedPlayersCount++; }
+    public static void addVanishedPlayer() {
+        vanishedPlayersCount++;
+    }
 
-    public static void removeVanishedPlayer() { vanishedPlayersCount--; }
+    public static void removeVanishedPlayer() {
+        vanishedPlayersCount--;
+    }
 
-    public static int getOnlineUsers() { return thisPlugin.getServer().getOnlinePlayers().size() - vanishedPlayersCount; }
+    public static int getOnlineUsers() {
+        return thisPlugin.getServer().getOnlinePlayers().size() - vanishedPlayersCount;
+    }
 
-    public static int getMaximumAllowedPlayers() { return thisPlugin.getServer().getMaxPlayers(); }
+    public static int getMaximumAllowedPlayers() {
+        return thisPlugin.getServer().getMaxPlayers();
+    }
 
-    public static int InitBot(boolean firstInit)
-    {
-        if(firstInit)
+    public static int InitBot(boolean firstInit) {
+        if (firstInit)
             vanishedPlayersCount = 0;
 
         ConfigSetup();
@@ -146,59 +159,47 @@ public class DiscordWhitelister extends JavaPlugin
         removeMessageWaitTime = mainConfig.getFileConfiguration().getInt("seconds-to-remove-message-from-whitelist-channel");
         useOnWhitelistCommands = mainConfig.getFileConfiguration().getBoolean("use-on-whitelist-commands");
 
-        // Check for LuckPerms first
-        if(mainConfig.getFileConfiguration().getBoolean("assign-perms-with-luck-perms"))
-        {
-            if(getPlugin().getServer().getPluginManager().getPlugin("LuckPerms") != null)
-            {
-                useLuckPerms = true;
-                getPluginLogger().info("LuckPerms found!");
-            }
-            else
-            {
-                getPluginLogger().warning("LuckPerms was not found but is enabled in the config. Doing nothing...");
-                useLuckPerms = false;
-            }
-        }
-        if(mainConfig.getFileConfiguration().getBoolean("assign-perms-with-ultra-perms"))
-        {
-            if(getPlugin().getServer().getPluginManager().getPlugin("UltraPermissions") != null)
-            {
-                useUltraPerms = true;
-                getPluginLogger().info("Ultra Permissions found!");
-            }
-            else
-            {
-                getPluginLogger().warning("Ultra Permissions was not found but is enabled in the config. Doing nothing...");
-                useUltraPerms = false;
-            }
-        }
-
-        // TODO: remove in favour of split versions
-        DiscordClient.customWhitelistAddPrefix = customPrefixConfig.getFileConfiguration().getString("whitelist-add-prefix").toLowerCase();
-        DiscordClient.customWhitelistRemovePrefix = customPrefixConfig.getFileConfiguration().getString("whitelist-remove-prefix").toLowerCase();
-        DiscordClient.customClearNamePrefix = customPrefixConfig.getFileConfiguration().getString("clear-name-prefix").toLowerCase();
-        DiscordClient.customLimitedWhitelistClearPrefix = customPrefixConfig.getFileConfiguration().getString("limited-whitelist-clear-prefix").toLowerCase();
-        DiscordClient.customClearBanPrefix = customPrefixConfig.getFileConfiguration().getString("clear-ban-prefix").toLowerCase();
-
-        // Split versions
-        DiscordClient.customWhitelistAddPrefixSplit = customPrefixConfig.getFileConfiguration().getString("whitelist-add-prefix").toLowerCase().trim().split(" ");
-        DiscordClient.customWhitelistRemovePrefixSplit = customPrefixConfig.getFileConfiguration().getString("whitelist-remove-prefix").toLowerCase().trim().split(" ");
-        DiscordClient.customClearNamePrefixSplit = customPrefixConfig.getFileConfiguration().getString("clear-name-prefix").toLowerCase().trim().split(" ");
-        DiscordClient.customLimitedWhitelistClearPrefixSplit = customPrefixConfig.getFileConfiguration().getString("limited-whitelist-clear-prefix").toLowerCase().trim().split(" ");
-        DiscordClient.customClearBanPrefixSplit = customPrefixConfig.getFileConfiguration().getString("clear-ban-prefix").toLowerCase().trim().split(" ");
-        DiscordClient.customWhoIsPrefix = customPrefixConfig.getFileConfiguration().getString("whitelist-whois-prefix").toLowerCase().trim().split(" ");
-
-        if(!botEnabled)
-        {
+        if (!botEnabled) {
             pluginLogger.info("Bot is disabled as per the config, doing nothing");
-        }
-        else if(configCreated)
-        {
-            pluginLogger.info("Config newly created, please paste your bot token into the config file, doing nothing until next server start");
-        }
-        else
-        {
+        } else if (configCreated || botToken.equals(MainConfig.default_token)) {
+            pluginLogger.warning("Config newly created. Please paste your bot token into the config file, doing nothing until next server start");
+        } else {
+            // Check for LuckPerms first
+            if (mainConfig.getFileConfiguration().getBoolean("assign-perms-with-luck-perms")) {
+                if (getPlugin().getServer().getPluginManager().getPlugin("LuckPerms") != null) {
+                    useLuckPerms = true;
+                    getPluginLogger().info("LuckPerms found!");
+                } else {
+                    getPluginLogger().warning("LuckPerms was not found but is enabled in the config. Doing nothing...");
+                    useLuckPerms = false;
+                }
+            }
+            if (mainConfig.getFileConfiguration().getBoolean("assign-perms-with-ultra-perms")) {
+                if (getPlugin().getServer().getPluginManager().getPlugin("UltraPermissions") != null) {
+                    useUltraPerms = true;
+                    getPluginLogger().info("Ultra Permissions found!");
+                } else {
+                    getPluginLogger().warning("Ultra Permissions was not found but is enabled in the config. Doing nothing...");
+                    useUltraPerms = false;
+                }
+            }
+
+            // TODO: remove in favour of split versions
+            DiscordClient.customWhitelistAddPrefix = customPrefixConfig.getFileConfiguration().getString("whitelist-add-prefix").toLowerCase();
+            DiscordClient.customWhitelistRemovePrefix = customPrefixConfig.getFileConfiguration().getString("whitelist-remove-prefix").toLowerCase();
+            DiscordClient.customClearNamePrefix = customPrefixConfig.getFileConfiguration().getString("clear-name-prefix").toLowerCase();
+            DiscordClient.customLimitedWhitelistClearPrefix = customPrefixConfig.getFileConfiguration().getString("limited-whitelist-clear-prefix").toLowerCase();
+            DiscordClient.customClearBanPrefix = customPrefixConfig.getFileConfiguration().getString("clear-ban-prefix").toLowerCase();
+
+            // Split versions
+            DiscordClient.customWhitelistAddPrefixSplit = customPrefixConfig.getFileConfiguration().getString("whitelist-add-prefix").toLowerCase().trim().split(" ");
+            DiscordClient.customWhitelistRemovePrefixSplit = customPrefixConfig.getFileConfiguration().getString("whitelist-remove-prefix").toLowerCase().trim().split(" ");
+            DiscordClient.customClearNamePrefixSplit = customPrefixConfig.getFileConfiguration().getString("clear-name-prefix").toLowerCase().trim().split(" ");
+            DiscordClient.customLimitedWhitelistClearPrefixSplit = customPrefixConfig.getFileConfiguration().getString("limited-whitelist-clear-prefix").toLowerCase().trim().split(" ");
+            DiscordClient.customClearBanPrefixSplit = customPrefixConfig.getFileConfiguration().getString("clear-ban-prefix").toLowerCase().trim().split(" ");
+            DiscordClient.customWhoIsPrefix = customPrefixConfig.getFileConfiguration().getString("whitelist-whois-prefix").toLowerCase().trim().split(" ");
+
+
             pluginLogger.info("Initializing Discord client...");
 
             // TODO: below role section could be moved to DiscordClient class
@@ -206,40 +207,34 @@ public class DiscordWhitelister extends JavaPlugin
 
             // set add & remove roles
             DiscordClient.allowedToAddRemoveRoles = new String[mainConfig.getFileConfiguration().getList("add-remove-roles").size()];
-            for(int roles = 0; roles < DiscordClient.allowedToAddRemoveRoles.length; ++roles)
-            {
+            for (int roles = 0; roles < DiscordClient.allowedToAddRemoveRoles.length; ++roles) {
                 DiscordClient.allowedToAddRemoveRoles[roles] = mainConfig.getFileConfiguration().getList("add-remove-roles").get(roles).toString();
             }
 
             // set add roles
             DiscordClient.allowedToAddRoles = new String[mainConfig.getFileConfiguration().getList("add-roles").size()];
-            for(int roles = 0; roles < DiscordClient.allowedToAddRoles.length; ++roles)
-            {
+            for (int roles = 0; roles < DiscordClient.allowedToAddRoles.length; ++roles) {
                 DiscordClient.allowedToAddRoles[roles] = mainConfig.getFileConfiguration().getList("add-roles").get(roles).toString();
             }
 
             // set limited add roles
             DiscordClient.allowedToAddLimitedRoles = new String[mainConfig.getFileConfiguration().getList("limited-add-roles").size()];
-            for(int roles = 0; roles < DiscordClient.allowedToAddLimitedRoles.length; ++roles)
-            {
+            for (int roles = 0; roles < DiscordClient.allowedToAddLimitedRoles.length; ++roles) {
                 DiscordClient.allowedToAddLimitedRoles[roles] = mainConfig.getFileConfiguration().getList("limited-add-roles").get(roles).toString();
             }
 
             // Get banned roles
-            if(useOnBanEvents)
-            {
+            if (useOnBanEvents) {
                 List<String> tempBannedRoles = mainConfig.getFileConfiguration().getStringList("banned-roles");
                 bannedRoles = new String[tempBannedRoles.size()];
-                for(int i = 0; i < tempBannedRoles.size(); i++)
-                {
+                for (int i = 0; i < tempBannedRoles.size(); i++) {
                     bannedRoles[i] = tempBannedRoles.get(i);
                 }
             }
 
             // Allowed to clear name roles
             DiscordClient.allowedToClearNamesRoles = new String[mainConfig.getFileConfiguration().getStringList("clear-command-roles").size()];
-            for(int roles = 0; roles < DiscordClient.allowedToClearNamesRoles.length; roles++)
-            {
+            for (int roles = 0; roles < DiscordClient.allowedToClearNamesRoles.length; roles++) {
                 DiscordClient.allowedToClearNamesRoles[roles] = mainConfig.getFileConfiguration().getStringList("clear-command-roles").get(roles);
             }
 
@@ -254,15 +249,14 @@ public class DiscordWhitelister extends JavaPlugin
 
             int initSuccess = DiscordClient.InitializeClient(botToken);
 
-            if(initSuccess == 1)
+            if (initSuccess == 1)
                 return 1;
 
 
             // No need for an if here statement anymore as this code will not run if the client has not been initialized
             // Only attempt to set player count if the bot successfully initialized
-            if(mainConfig.getFileConfiguration().getBoolean("show-player-count"))
-            {
-                if(firstInit) {
+            if (mainConfig.getFileConfiguration().getBoolean("show-player-count")) {
+                if (firstInit) {
                     // Register events if enabled
                     thisServer.getPluginManager().registerEvents(new JoinLeaveEvents(), thisPlugin);
                     //pluginLogger.info("Registered join/leave events!");
@@ -270,7 +264,7 @@ public class DiscordWhitelister extends JavaPlugin
                         thisServer.getPluginManager().registerEvents(new SuperVanishEvents(), thisPlugin);
                         //pluginLogger.info("Registered SuperVanish events!");
                     }
-                    if(vanishNoPacketPlugin != null) {
+                    if (vanishNoPacketPlugin != null) {
                         thisServer.getPluginManager().registerEvents(new VanishNoPacketEvents(), thisPlugin);
                         //pluginLogger.info("Registered VanishNoPacket events!");
                     }
@@ -285,21 +279,20 @@ public class DiscordWhitelister extends JavaPlugin
             }
 
             // Register whitelist events if enabled
-            if(useInGameAddRemoves)
+            if (useInGameAddRemoves)
                 thisServer.getPluginManager().registerEvents(new OnWhitelistEvents(), thisPlugin);
 
             // Register ban events if enabled
-            if(useOnBanEvents)
+            if (useOnBanEvents)
                 thisServer.getPluginManager().registerEvents(new OnBanEvent(), thisPlugin);
 
             return 0;
         }
 
-        return 0;
+        return 1;
     }
 
-    public static void ConfigSetup()
-    {
+    public static void ConfigSetup() {
         mainConfig = new MainConfig();
         customPrefixConfig = new CustomPrefixConfig();
         customMessagesConfig = new CustomMessagesConfig();
diff --git a/src/main/java/uk/co/angrybee/joe/commands/minecraft/CommandReload.java b/src/main/java/uk/co/angrybee/joe/commands/minecraft/CommandReload.java
index 87c3bee..e5b3e9b 100644
--- a/src/main/java/uk/co/angrybee/joe/commands/minecraft/CommandReload.java
+++ b/src/main/java/uk/co/angrybee/joe/commands/minecraft/CommandReload.java
@@ -39,8 +39,10 @@ public class CommandReload implements CommandExecutor
         {
             pluginLogger.info("Failed to re-initialize client");
             sender.sendMessage("[DW] Failed to reload Discord client (Reason: Failed to re-initialize client)");
+            DiscordWhitelister.initialized = false;
             return false;
         }
+        DiscordWhitelister.initialized = true;
 
         if(!DiscordWhitelister.botEnabled)
         {
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 d5163a5..12eaf11 100644
--- a/src/main/java/uk/co/angrybee/joe/configs/MainConfig.java
+++ b/src/main/java/uk/co/angrybee/joe/configs/MainConfig.java
@@ -9,8 +9,10 @@ import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
 
+
 // discord-whitelister.yml
 public class MainConfig extends Config {
+    public static String default_token = "Discord bot token goes here, you can find it here: https://discordapp.com/developers/applications/";
     public MainConfig() {
         fileName = "discord-whitelister.yml";
         file = new File(DiscordWhitelister.getPlugin().getDataFolder(), fileName);
@@ -32,7 +34,7 @@ public class MainConfig extends Config {
 
         if (!file.exists()) {
             CreateConfig();
-            DiscordWhitelister.getPluginLogger().info("Configuration file created at: " + file.getPath() +
+            DiscordWhitelister.getPluginLogger().warning("Configuration file created at: " + file.getPath() +
                     ", please edit this else the plugin will not work!");
         }
         LoadConfigFile();
@@ -45,7 +47,7 @@ public class MainConfig extends Config {
         CheckEntry("bot-enabled", true);
 
         CheckEntry("discord-bot-token",
-                "Discord bot token goes here, you can find it here: https://discordapp.com/developers/applications/");
+                default_token);
 
         CheckEntry("use-id-for-roles", false);
 

From 4e843db351516209148b76b92058eec9e4fd63ca Mon Sep 17 00:00:00 2001
From: Xyntexx <mnuuja@gmail.com>
Date: Thu, 22 Jul 2021 22:31:08 +0300
Subject: [PATCH 2/2] Stop using !commands start using /commands add /whitelist
 whois @discorduser 1.17.1 version update

---
 .../uk/co/angrybee/joe/AuthorPermissions.java |  106 ++
 .../uk/co/angrybee/joe/DiscordClient.java     | 1174 ++++-----------
 .../co/angrybee/joe/DiscordWhitelister.java   |   44 +-
 .../joe/commands/discord/CommandAdd.java      | 1263 ++++++++++-------
 .../joe/commands/discord/CommandClear.java    |  119 ++
 .../joe/commands/discord/CommandClearban.java |  101 ++
 .../commands/discord/CommandClearname.java    |  120 ++
 .../joe/commands/discord/CommandInfo.java     |   13 +-
 .../joe/commands/discord/CommandRemove.java   |  200 ++-
 .../joe/commands/discord/CommandWhoIs.java    |   89 +-
 .../commands/discord/CommandWhoIsDiscord.java |   79 ++
 .../joe/configs/CustomMessagesConfig.java     |    2 +-
 .../joe/configs/CustomPrefixConfig.java       |   10 +-
 13 files changed, 1814 insertions(+), 1506 deletions(-)
 create mode 100644 src/main/java/uk/co/angrybee/joe/commands/discord/CommandClear.java
 create mode 100644 src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearban.java
 create mode 100644 src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearname.java
 create mode 100644 src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIsDiscord.java

diff --git a/src/main/java/uk/co/angrybee/joe/AuthorPermissions.java b/src/main/java/uk/co/angrybee/joe/AuthorPermissions.java
index f00ccc2..856da4f 100644
--- a/src/main/java/uk/co/angrybee/joe/AuthorPermissions.java
+++ b/src/main/java/uk/co/angrybee/joe/AuthorPermissions.java
@@ -1,6 +1,7 @@
 package uk.co.angrybee.joe;
 
 import net.dv8tion.jda.api.entities.Role;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
 import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
 
 import java.util.Arrays;
@@ -13,6 +14,111 @@ public class AuthorPermissions
     private boolean userIsBanned = false;
     private boolean userCanUseClear = false;
 
+    public AuthorPermissions(SlashCommandEvent event) {
+        for (Role role : event.getMember().getRoles())
+        {
+            if(!DiscordWhitelister.useIdForRoles)
+            {
+                if (Arrays.stream(DiscordClient.allowedToAddRemoveRoles).parallel().anyMatch(role.getName()::equalsIgnoreCase))
+                {
+                    userCanAddRemove = true;
+                    break;
+                }
+            }
+            else
+            {
+                if (Arrays.stream(DiscordClient.allowedToAddRemoveRoles).parallel().anyMatch(role.getId()::equalsIgnoreCase))
+                {
+                    userCanAddRemove = true;
+                    break;
+                }
+            }
+        }
+
+        for (Role role : event.getGuild().getMember(event.getUser()).getRoles())
+        {
+            if (!DiscordWhitelister.useIdForRoles)
+            {
+                if (Arrays.stream(DiscordClient.allowedToAddRoles).parallel().anyMatch(role.getName()::equalsIgnoreCase))
+                {
+                    userCanAdd = true;
+                    break;
+                }
+            }
+            else
+            {
+                if (Arrays.stream(DiscordClient.allowedToAddRoles).parallel().anyMatch(role.getId()::equalsIgnoreCase))
+                {
+                    userCanAdd = true;
+                    break;
+                }
+            }
+        }
+
+        for (Role role : event.getGuild().getMember(event.getUser()).getRoles())
+        {
+            if(!DiscordWhitelister.useIdForRoles)
+            {
+                if (Arrays.stream(DiscordClient.allowedToAddLimitedRoles).parallel().anyMatch(role.getName()::equalsIgnoreCase))
+                {
+                    userHasLimitedAdd = true;
+                    break;
+                }
+            }
+            else
+            {
+                if (Arrays.stream(DiscordClient.allowedToAddLimitedRoles).parallel().anyMatch(role.getId()::equalsIgnoreCase))
+                {
+                    userHasLimitedAdd = true;
+                    break;
+                }
+            }
+        }
+
+        if(DiscordWhitelister.useOnBanEvents)
+        {
+            for(Role role : event.getGuild().getMember(event.getUser()).getRoles())
+            {
+                if(!DiscordWhitelister.useIdForRoles)
+                {
+                    if (Arrays.stream(DiscordWhitelister.bannedRoles).parallel().anyMatch(role.getName()::equalsIgnoreCase))
+                    {
+                        userIsBanned = true;
+                        break;
+                    }
+                }
+                else
+                {
+                    if (Arrays.stream(DiscordWhitelister.bannedRoles).parallel().anyMatch(role.getId()::equalsIgnoreCase))
+                    {
+                        userIsBanned = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        for(Role role : event.getGuild().getMember(event.getUser()).getRoles())
+        {
+            if(!DiscordWhitelister.useIdForRoles)
+            {
+                if(Arrays.stream(DiscordClient.allowedToClearNamesRoles).parallel().anyMatch(role.getName()::equalsIgnoreCase))
+                {
+                    userCanUseClear = true;
+                    break;
+                }
+            }
+            else
+            {
+                if(Arrays.stream(DiscordClient.allowedToClearNamesRoles).parallel().anyMatch(role.getId()::equalsIgnoreCase))
+                {
+                    userCanUseClear = true;
+                    break;
+                }
+            }
+        }
+    }
+
     public boolean isUserCanAddRemove() {
         return userCanAddRemove;
     }
diff --git a/src/main/java/uk/co/angrybee/joe/DiscordClient.java b/src/main/java/uk/co/angrybee/joe/DiscordClient.java
index 1d6c024..cb69b6e 100644
--- a/src/main/java/uk/co/angrybee/joe/DiscordClient.java
+++ b/src/main/java/uk/co/angrybee/joe/DiscordClient.java
@@ -6,9 +6,15 @@ import net.dv8tion.jda.api.JDABuilder;
 import net.dv8tion.jda.api.entities.*;
 import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
 import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
 import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
 import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import net.dv8tion.jda.api.interactions.commands.OptionMapping;
+import net.dv8tion.jda.api.interactions.commands.build.CommandData;
+import net.dv8tion.jda.api.interactions.commands.build.OptionData;
+import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
 import net.dv8tion.jda.api.requests.GatewayIntent;
+import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
 import net.dv8tion.jda.api.utils.ChunkingFilter;
 import net.dv8tion.jda.api.utils.MemberCachePolicy;
 import net.dv8tion.jda.api.utils.cache.CacheFlag;
@@ -16,13 +22,8 @@ import org.bukkit.configuration.file.FileConfiguration;
 import org.json.simple.JSONObject;
 import org.json.simple.JSONValue;
 import org.json.simple.parser.ParseException;
-import uk.co.angrybee.joe.commands.discord.CommandAdd;
-import uk.co.angrybee.joe.commands.discord.CommandWhoIs;
-import uk.co.angrybee.joe.configs.*;
-import uk.co.angrybee.joe.commands.discord.CommandInfo;
+import uk.co.angrybee.joe.commands.discord.*;
 import uk.co.angrybee.joe.events.ShutdownEvents;
-import uk.co.angrybee.joe.stores.InGameRemovedList;
-import uk.co.angrybee.joe.stores.RemovedList;
 import uk.co.angrybee.joe.stores.UserList;
 import uk.co.angrybee.joe.stores.WhitelistedPlayers;
 
@@ -34,9 +35,10 @@ import java.net.URL;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 
+import static net.dv8tion.jda.api.interactions.commands.OptionType.*;
+
 // handles Discord interaction
-public class DiscordClient extends ListenerAdapter
-{
+public class DiscordClient extends ListenerAdapter {
     public static String[] allowedToAddRemoveRoles;
     public static String[] allowedToAddRoles;
     public static String[] allowedToAddLimitedRoles;
@@ -60,15 +62,6 @@ public class DiscordClient extends ListenerAdapter
     public static String[] customClearBanPrefixSplit;
     public static String[] customWhoIsPrefix;
 
-    // TODO: move to own class, references to non custom prefix
-    public static final String[] whitelistInfoPrefix = {"!whitelist"};
-    public static final String[] whitelistAddPrefix = {"!whitelist", "add"};
-    public static final String[] whitelistRemovePrefix = {"!whitelist", "remove"};
-    public static final String[] whitelistClearPrefix = {"!whitelist", "clear"};
-    public static final String[] whitelistWhoIsPrefix = {"!whitelist", "whois"};
-    public static final String[] clearNamePrefix = {"!clearname"};
-    public static final String[] clearBanPrefix = {"!clearban"};
-
     public static MessageEmbed botInfo;
     public static MessageEmbed addCommandInfo;
     public static MessageEmbed removeCommandInfo;
@@ -93,13 +86,11 @@ public class DiscordClient extends ListenerAdapter
 
     public static JDA javaDiscordAPI;
 
-    public static int InitializeClient(String clientToken)
-    {
+    public static int InitializeClient(String clientToken) {
         AssignVars();
         BuildStrings();
 
-        try
-        {
+        try {
             javaDiscordAPI = JDABuilder.createDefault(clientToken)
                     .setMemberCachePolicy(MemberCachePolicy.ALL)
                     .setBulkDeleteSplittingEnabled(false)
@@ -113,38 +104,57 @@ public class DiscordClient extends ListenerAdapter
 
             javaDiscordAPI.awaitReady();
 
+
+            CommandListUpdateAction commands = javaDiscordAPI.updateCommands();
+
+            commands.addCommands(
+                    new CommandData("whitelist", "Edit the whitelist.")
+                            .addSubcommands(
+                                    new SubcommandData("add", "Add a user to the whitelist")
+                                            .addOption(STRING, "minecraft_username", "Minecraft username to add", true)
+                                            .addOption(USER, "discord_user", "Discord user to bind to", false),
+                                    new SubcommandData("remove", "Remove user from the whitelist")
+                                            .addOption(STRING, "minecraft_username", "Minecraft username to remove", true),
+                                    new SubcommandData("clear", "Clear whitelists assigned to your account"),
+                                    new SubcommandData("whois", "Find the Discord name linked to a Minecraft name")
+                                            .addOption(STRING, "minecraft_username", "Minecraft name to search", false)
+                                            .addOption(USER, "discord_user", "Minecraft name to search", false)),
+
+                    new CommandData("clearname", "Clear name from all lists")
+                            .addOption(STRING, "minecraft_username", "Minecraft username to clear", true),
+                    new CommandData("clearban", "Clear ban from user")
+                            .addOption(STRING, "minecraft_username", "Minecraft username to unban", true),
+                    new CommandData("help", "Show bot info"))
+                    .queue();
+
+            // Send the new set of commands to discord, this will override any existing global commands with the new set provided here
+
+
             return 0;
-        }
-        catch (LoginException | InterruptedException e)
-        {
+        } catch (LoginException | InterruptedException e) {
             e.printStackTrace();
             return 1;
-        }
-        catch (IllegalStateException e)
-        {
+        } catch (IllegalStateException e) {
             // Don't print exception related to disallowed intents, already handled
-            if(!e.getMessage().startsWith("Was shutdown trying to await status"))
+            if (!e.getMessage().startsWith("Was shutdown trying to await status"))
                 e.printStackTrace();
 
             return 1;
         }
     }
 
-    public static boolean ShutdownClient()
-    {
+    public static boolean ShutdownClient() {
         javaDiscordAPI.shutdownNow();
 
         return javaDiscordAPI.getStatus() == JDA.Status.SHUTTING_DOWN || javaDiscordAPI.getStatus() == JDA.Status.SHUTDOWN;
     }
 
-    private static void AssignVars()
-    {
+    private static void AssignVars() {
         FileConfiguration mainConfig = DiscordWhitelister.mainConfig.getFileConfiguration();
 
         // assign vars here instead of every time a message is received, as they do not change
         targetTextChannels = new String[mainConfig.getList("target-text-channels").size()];
-        for (int i = 0; i < targetTextChannels.length; ++i)
-        {
+        for (int i = 0; i < targetTextChannels.length; ++i) {
             targetTextChannels[i] = mainConfig.getList("target-text-channels").get(i).toString();
         }
 
@@ -158,8 +168,7 @@ public class DiscordClient extends ListenerAdapter
 
 
         whitelistedRoleNames = new String[mainConfig.getList("whitelisted-roles").size()];
-        for(int i = 0; i < whitelistedRoleNames.length; i++)
-        {
+        for (int i = 0; i < whitelistedRoleNames.length; i++) {
             whitelistedRoleNames[i] = mainConfig.getList("whitelisted-roles").get(i).toString();
         }
 
@@ -169,78 +178,68 @@ public class DiscordClient extends ListenerAdapter
         hideInfoCommandReplies = mainConfig.getBoolean("hide-info-command-replies");
     }
 
-    private static void BuildStrings()
-    {
+    private static void BuildStrings() {
         // build here instead of every time a message is received, as they do not change
         EmbedBuilder embedBuilderBotInfo = new EmbedBuilder();
         embedBuilderBotInfo.setTitle("Discord Whitelister for Spigot");
         embedBuilderBotInfo.addField("Version", VersionInfo.getVersion(), false);
         embedBuilderBotInfo.addField("Links", ("https://www.spigotmc.org/resources/discord-whitelister.69929/\nhttps://github.com/JoeShimell/DiscordWhitelisterSpigot"), false);
-        embedBuilderBotInfo.addField("Commands", ("**Add:** !whitelist add minecraftUsername\n**Remove:** !whitelist remove minecraftUsername"), false);
+        embedBuilderBotInfo.addField("Commands", ("**Add:** /whitelist add minecraftUsername\n**Remove:** /whitelist remove minecraftUsername"), false);
         embedBuilderBotInfo.addField("Experiencing issues?", "If you encounter an issue, please report it here: https://github.com/JoeShimell/DiscordWhitelisterSpigot/issues", false);
         embedBuilderBotInfo.setColor(infoColour);
         botInfo = embedBuilderBotInfo.build();
 
         addCommandInfo = CreateEmbeddedMessage("Whitelist Add Command",
-                "!whitelist add minecraftUsername\n\nIf you encounter any issues, please report them here: https://github.com/JoeShimell/DiscordWhitelisterSpigot/issues",
+                "/whitelist add minecraftUsername\n\nIf you encounter any issues, please report them here: https://github.com/JoeShimell/DiscordWhitelisterSpigot/issues",
                 EmbedMessageType.INFO).build();
 
         removeCommandInfo = CreateEmbeddedMessage("Whitelist Remove Command",
-                "!whitelist remove minecraftUsername\n\nIf you encounter any issues, please report them here: https://github.com/JoeShimell/DiscordWhitelisterSpigot/issues",
+                "/whitelist remove minecraftUsername\n\nIf you encounter any issues, please report them here: https://github.com/JoeShimell/DiscordWhitelisterSpigot/issues",
                 EmbedMessageType.INFO).build();
 
         whoIsInfo = CreateEmbeddedMessage("Whitelist WhoIs Command",
-                "!whitelist whois minecraftUsername\n\nIf you encounter any issues, please report them here: https://github.com/JoeShimell/DiscordWhitelisterSpigot/issues",
+                "/whitelist whois minecraftUsername\n\nIf you encounter any issues, please report them here: https://github.com/JoeShimell/DiscordWhitelisterSpigot/issues",
                 EmbedMessageType.INFO).build();
     }
 
-    public static String getOnlineStatus()
-    {
-        try
-        {
+    public static String getOnlineStatus() {
+        try {
             return javaDiscordAPI.getStatus().name();
-        }
-        catch(NullPointerException ex)
-        {
+        } catch (NullPointerException ex) {
             return "OFFLINE";
         }
     }
 
-    public static void SetPlayerCountStatus(int playerCount)
-    {
+    public static void SetPlayerCountStatus(int playerCount) {
         javaDiscordAPI.getPresence().setActivity(Activity.watching(playerCount + "/" + DiscordWhitelister.getMaximumAllowedPlayers() + " players."));
     }
 
-    public enum EmbedMessageType { INFO, SUCCESS, FAILURE }
-    private static Color infoColour = new Color(104, 109,224);
-    private static Color successColour = new Color(46, 204, 113);
-    private static Color failureColour = new Color(231, 76, 60);
+    public enum EmbedMessageType {INFO, SUCCESS, FAILURE}
 
-    public static EmbedBuilder CreateEmbeddedMessage(String title, String message, EmbedMessageType messageType)
-    {
+    private static final Color infoColour = new Color(104, 109, 224);
+    private static final Color successColour = new Color(46, 204, 113);
+    private static final Color failureColour = new Color(231, 76, 60);
+
+    public static EmbedBuilder CreateEmbeddedMessage(String title, String message, EmbedMessageType messageType) {
         EmbedBuilder newMessageEmbed = new EmbedBuilder();
         newMessageEmbed.addField(title, message, false);
 
-        if(messageType == EmbedMessageType.INFO)
+        if (messageType == EmbedMessageType.INFO)
             newMessageEmbed.setColor(infoColour);
         else if (messageType == EmbedMessageType.SUCCESS)
             newMessageEmbed.setColor(successColour);
         else if (messageType == EmbedMessageType.FAILURE)
             newMessageEmbed.setColor(failureColour);
         else
-            newMessageEmbed.setColor(new Color(255,255,255));
+            newMessageEmbed.setColor(new Color(255, 255, 255));
 
         return newMessageEmbed;
     }
 
-    public static EmbedBuilder AddWhitelistRemainingCount(EmbedBuilder embedBuilder, int timesWhitelisted)
-    {
-        if(!DiscordWhitelister.useCustomMessages)
-        {
+    public static EmbedBuilder AddWhitelistRemainingCount(EmbedBuilder embedBuilder, int timesWhitelisted) {
+        if (!DiscordWhitelister.useCustomMessages) {
             embedBuilder.addField("Whitelists Remaining", ("You have **" + (maxWhitelistAmount - timesWhitelisted) + " out of " + maxWhitelistAmount + "** whitelists remaining."), false);
-        }
-        else
-        {
+        } else {
             String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelists-remaining-title");
             String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelists-remaining");
             customMessage = customMessage.replaceAll("\\{RemainingWhitelists}", String.valueOf((maxWhitelistAmount - timesWhitelisted)));
@@ -252,16 +251,12 @@ public class DiscordClient extends ListenerAdapter
         return embedBuilder;
     }
 
-    public static MessageEmbed CreateInsufficientPermsMessage(User messageAuthor)
-    {
+    public static MessageEmbed CreateInsufficientPermsMessage(User messageAuthor) {
         MessageEmbed insufficientMessageEmbed;
 
-        if(!DiscordWhitelister.useCustomMessages)
-        {
+        if (!DiscordWhitelister.useCustomMessages) {
             insufficientMessageEmbed = CreateEmbeddedMessage("Insufficient Permissions", (messageAuthor.getAsMention() + ", you do not have permission to use this command."), EmbedMessageType.FAILURE).build();
-        }
-        else
-        {
+        } else {
             String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("insufficient-permissions-title");
             String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("insufficient-permissions");
             customMessage = customMessage.replaceAll("\\{Sender}", messageAuthor.getAsMention()); // Only checking for {Sender}
@@ -273,21 +268,17 @@ public class DiscordClient extends ListenerAdapter
     }
 
     // TODO can be placed in BuildStrings()
-    public static MessageEmbed CreateInstructionalMessage()
-    {
+    public static MessageEmbed CreateInstructionalMessage() {
         MessageEmbed instructionalMessageEmbed;
 
-        if(!DiscordWhitelister.useCustomMessages)
-        {
-            String addCommandExample = "!whitelist add";
-            if(DiscordWhitelister.useCustomPrefixes)
+        if (!DiscordWhitelister.useCustomMessages) {
+            String addCommandExample = "/whitelist add";
+            if (DiscordWhitelister.useCustomPrefixes)
                 addCommandExample = DiscordWhitelister.customPrefixConfig.getFileConfiguration().getString("whitelist-add-prefix").trim();
 
             instructionalMessageEmbed = CreateEmbeddedMessage("How to Whitelist", ("Use `" + addCommandExample + " <minecraftUsername>` to whitelist yourself.\n" +
                     "In the case of whitelisting an incorrect name, please contact a staff member to clear it from the whitelist."), EmbedMessageType.INFO).build();
-        }
-        else
-        {
+        } else {
             String customTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("instructional-message-title");
             String customMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("instructional-message");
 
@@ -298,25 +289,22 @@ public class DiscordClient extends ListenerAdapter
     }
 
     // returns true if the target string initially contains the prefix or is identical to the prefix
-    public static boolean CheckForPrefix(String[] prefixToCheck, String[] targetString)
-    {
-        if(prefixToCheck == null || targetString == null)
+    public static boolean CheckForPrefix(String[] prefixToCheck, String[] targetString) {
+        if (prefixToCheck == null || targetString == null)
             return false;
 
-        if(targetString.length < prefixToCheck.length)
+        if (targetString.length < prefixToCheck.length)
             return false;
 
         String[] tempCompareArray = new String[prefixToCheck.length];
-        if(targetString.length > prefixToCheck.length)
+        if (targetString.length > prefixToCheck.length)
             System.arraycopy(targetString, 0, tempCompareArray, 0, prefixToCheck.length);
         else
             tempCompareArray = targetString;
 
         boolean isIdentical = true;
-        for(int i = 0; i < prefixToCheck.length; i++)
-        {
-            if (!prefixToCheck[i].equals(tempCompareArray[i]))
-            {
+        for (int i = 0; i < prefixToCheck.length; i++) {
+            if (!prefixToCheck[i].equals(tempCompareArray[i])) {
                 isIdentical = false;
                 break;
             }
@@ -326,746 +314,224 @@ public class DiscordClient extends ListenerAdapter
     }
 
     @Override
-    public void onMessageReceived(MessageReceivedEvent messageReceivedEvent)
-    {
-        if (messageReceivedEvent.isFromType(ChannelType.TEXT))
-        {
-            // Check if message should be handled
-            if (!Arrays.asList(targetTextChannels).contains(messageReceivedEvent.getTextChannel().getId()))
-                return;
+    public void onSlashCommand(SlashCommandEvent event) {
 
-            if(messageReceivedEvent.getAuthor().getIdLong() == javaDiscordAPI.getSelfUser().getIdLong())
-                return;
+        // Todo: add help: CommandInfo.ExecuteCommand(messageReceivedEvent);
+        // Todo: add remove message thing
+        // Only accept commands from guilds
 
-            String messageContents = messageReceivedEvent.getMessage().getContentRaw();
-            String[] splitMessage = messageContents.toLowerCase().trim().split(" ");
-            String[] splitMessageCaseSensitive = messageContents.trim().split(" ");
 
-            if(splitMessage.length <= 0)
-                return;
+        if (event.getGuild() == null) {
+            MessageEmbed messageEmbed = CreateEmbeddedMessage("Sorry!",
+                    ("This bot can only used in the specified guild."), EmbedMessageType.FAILURE).build();
+            ReplyAndRemoveAfterSeconds(event, messageEmbed);
+            return;
+        }
 
-            // TODO remove, use in command classes when complete
-            AuthorPermissions authorPermissions = new AuthorPermissions(messageReceivedEvent);
-            User author = messageReceivedEvent.getAuthor();
-            TextChannel channel = messageReceivedEvent.getTextChannel();
+        String subcommand = event.getSubcommandName();
+        OptionMapping mc_name_op = event.getOption("minecraft_username");
+        String mc_name = null;
+        if (mc_name_op != null) {
+            mc_name = mc_name_op.getAsString();
+        }
+        OptionMapping dc_name_op = event.getOption("discord_user"); // the "user" option is required so it doesn't need a null-check here
+        Member dc_name = null;
+        if (dc_name_op != null) {
+            dc_name = dc_name_op.getAsMember();
+        }
 
-            // determine which command to run
-            if (splitMessage.length == 1 && CheckForPrefix(whitelistInfoPrefix, splitMessage))
-            {
-                if(hideInfoCommandReplies)
-                    return;
-
-                CommandInfo.ExecuteCommand(messageReceivedEvent);
-
-                if(DiscordWhitelister.removeUnnecessaryMessages)
-                    RemoveMessageAfterSeconds(messageReceivedEvent, DiscordWhitelister.removeMessageWaitTime);
-                return;
+        switch (event.getName()) {
+            case "whitelist": {
+                if (subcommand != null) {
+                    switch (subcommand) {
+                        case "add": {
+                            //!whitelist add command:
+                            if (dc_name != null) {
+                                CommandAdd.ExecuteCommand(event, mc_name, dc_name);
+                            } else {
+                                CommandAdd.ExecuteCommand(event, mc_name);
+                            }
+                        }
+                        break;
+                        case "remove": {
+                            // Remove Command
+                            CommandRemove.ExecuteCommand(event, mc_name);
+                        }
+                        break;
+                        case "clear": {
+                            CommandClear.ExecuteCommand(event);
+                        }
+                        break;
+                        case "whois": {
+                            if (dc_name != null) {
+                                CommandWhoIsDiscord.ExecuteCommand(event, dc_name);
+                            }else if (mc_name != null){
+                                CommandWhoIs.ExecuteCommand(event, mc_name);
+                            }else{
+                                EmbedBuilder msg = CreateEmbeddedMessage("Sorry...","You either need to provide a Minecraft username or a discord user",EmbedMessageType.FAILURE);
+                                ReplyAndRemoveAfterSeconds(event, msg.build());
+                            }
+                        }
+                        break;
+                    }
+                }
             }
-            //!whitelist add command:
-            if(!DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length >= whitelistAddPrefix.length  && CheckForPrefix(whitelistAddPrefix, splitMessage)
-                || DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length >= customWhitelistAddPrefixSplit.length && CheckForPrefix(customWhitelistAddPrefixSplit, splitMessage))
-            {
-                CommandAdd.ExecuteCommand(messageReceivedEvent, splitMessageCaseSensitive);
+            break;
+            case "clearname": {
+                CommandClearname.ExecuteCommand(event, mc_name);
 
-                if(DiscordWhitelister.removeUnnecessaryMessages)
-                    RemoveMessageAfterSeconds(messageReceivedEvent, DiscordWhitelister.removeMessageWaitTime);
-                return;
             }
-
-            // Remove Command
-            if (messageContents.toLowerCase().startsWith("!whitelist remove") && !DiscordWhitelister.getUseCustomPrefixes()
-                    || DiscordWhitelister.getUseCustomPrefixes() && messageContents.toLowerCase().startsWith(customWhitelistRemovePrefix))
-            {
-                if (authorPermissions.isUserCanAddRemove())
-                {
-                    messageContents = messageContents.toLowerCase();
-
-                    String messageContentsAfterCommand = "";
-                    if(!DiscordWhitelister.useCustomPrefixes)
-                    {
-                        if(messageContents.length() >  ("!whitelist remove".length() + 1))
-                        {
-                            messageContentsAfterCommand = messageContents.substring("!whitelist remove".length() + 1); // get everything after !whitelist remove[space]
-                        }
-                    }
-                    else
-                    {
-                        if(messageContents.length() >  (customWhitelistRemovePrefix.length() + 1))
-                        {
-                            messageContentsAfterCommand = messageContents.substring(customWhitelistRemovePrefix.length() + 1); // get everything after whitelistRemovePrefix[space]
-                        }
-                    }
-
-                    final String finalNameToRemove = messageContentsAfterCommand.replaceAll(" .*", ""); // The name is everything up to the first space
-
-                    if (finalNameToRemove.isEmpty())
-                    {
-                        if(!hideInfoCommandReplies)
-                            QueueAndRemoveAfterSeconds(channel, removeCommandInfo);
-
-                        TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                        return;
-                    }
-                    else
-                    {
-                        DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to remove " + finalNameToRemove + " from the whitelist");
-
-                        boolean notOnWhitelist = false;
-
-                        if (WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToRemove) || !WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayer(finalNameToRemove))
-                        {
-                            notOnWhitelist = true;
-
-                            if(!DiscordWhitelister.useCustomMessages)
-                            {
-                                MessageEmbed messageEmbed = CreateEmbeddedMessage("This user is not on the whitelist",
-                                        (author.getAsMention() + ", cannot remove user as `" + finalNameToRemove + "` is not on the whitelist!"), EmbedMessageType.INFO).build();
-                                QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                                TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                                // Return below
-                            }
-                            else
-                            {
-                                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-not-on-whitelist-title");
-                                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-not-on-whitelist");
-                                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                                customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToRemove);
-
-                                MessageEmbed messageEmbed = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.INFO).build();
-                                QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                                TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                            }
-                        }
-
-                        // not not on whitelist, nice
-                        if (!notOnWhitelist) // aka on the whitelist
-                        {
-                            UnWhitelist(finalNameToRemove);
-                            // Configure message here instead of on the main thread - this means this will run even if the message is never sent, but is a good trade off (I think)
-                            EmbedBuilder embedBuilderSuccess;
-
-                            if(!DiscordWhitelister.useCustomMessages)
-                            {
-                                if(!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("set-removed-message-colour-to-red"))
-                                    embedBuilderSuccess = CreateEmbeddedMessage((finalNameToRemove + " has been removed"), (author.getAsMention() + " has removed `" + finalNameToRemove + "` from the whitelist."), EmbedMessageType.SUCCESS);
-                                else
-                                    embedBuilderSuccess = CreateEmbeddedMessage((finalNameToRemove + " has been removed"), (author.getAsMention() + " has removed `" + finalNameToRemove + "` from the whitelist."), EmbedMessageType.FAILURE);
-                            }
-                            else
-                            {
-                                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("remove-success-title");
-                                customTitle = customTitle.replaceAll("\\{MinecraftUsername}", finalNameToRemove);
-
-                                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("remove-success");
-                                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                                customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToRemove);
-
-                                if(!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("set-removed-message-colour-to-red"))
-                                    embedBuilderSuccess = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.SUCCESS);
-                                else
-                                    embedBuilderSuccess = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.FAILURE);
-                            }
-
-                            if(DiscordWhitelister.showPlayerSkin)
-                            {
-                                String playerUUID = DiscordClient.minecraftUsernameToUUID(finalNameToRemove);
-
-                                if(!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-crafatar-for-avatars"))
-                                    embedBuilderSuccess.setThumbnail("https://minotar.net/armor/bust/" + playerUUID + "/100.png");
-                                else
-                                    embedBuilderSuccess.setThumbnail("https://crafatar.com/avatars/" + playerUUID + "?size=100&default=MHF_Steve&overlay.png");
-                            }
-
-                            EmbedBuilder embedBuilderFailure;
-
-                            // No custom message needed
-                            embedBuilderFailure = CreateEmbeddedMessage(("Failed to remove " + finalNameToRemove + " from the whitelist"), (author.getAsMention() + ", failed to remove `" + finalNameToRemove + "` from the whitelist. " +
-                                    "This should never happen, you may have to remove the player manually and report the issue."), EmbedMessageType.FAILURE);
-
-                            DiscordWhitelister.getPlugin().getServer().getScheduler().callSyncMethod(DiscordWhitelister.getPlugin(), () ->
-                            {
-                                if(WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToRemove)
-                                        || !WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayer(finalNameToRemove))
-                                {
-                                    channel.sendMessage(embedBuilderSuccess.build()).queue();
-                                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-
-                                    if (whitelistedRoleAutoRemove) {
-                                        List<String> whitelistRoles = new LinkedList<>();
-
-                                        Collections.addAll(whitelistRoles, whitelistedRoleNames);
-
-                                        // Find the Discord Id linked to the removed name
-                                        boolean idFound = false;
-                                        String targetDiscordId = "";
-                                        Set<String> keys = UserList.getUserList().getKeys(false);
-                                        for (String userId : keys) {
-                                            List<?> registeredUsers = UserList.getRegisteredUsers(userId);
-                                            for (Object wUser : registeredUsers) {
-                                                if (wUser.equals(finalNameToRemove)) {
-                                                    // Found the ban target, assign the corresponding Discord id
-                                                    targetDiscordId = userId;
-                                                    boolean namesRemainingAfterRemoval = false;
-
-                                                    if ((registeredUsers.size() - 1) > 0) {
-                                                        namesRemainingAfterRemoval = true;
-                                                        DiscordWhitelister.getPluginLogger().info("The Discord ID (" + targetDiscordId + ") linked to " + finalNameToRemove + " contains "
-                                                                + (registeredUsers.size() - 1) + " more whitelisted user(s), not removing whitelisted roles...");
-                                                    }
-
-                                                    // Find all servers bot is in, remove whitelisted roles
-                                                    if (!whitelistRoles.isEmpty() && !namesRemainingAfterRemoval) {
-                                                        for (Guild guild : DiscordClient.javaDiscordAPI.getGuilds()) {
-                                                            // Remove the whitelisted role(s)
-                                                            RemoveRolesFromUser(guild, targetDiscordId, whitelistRoles);
-                                                            DiscordWhitelister.getPluginLogger().info("Successfully removed whitelisted roles from "
-                                                                    + targetDiscordId + "(" + finalNameToRemove + ") in guild: " + guild.getName());
-                                                        }
-                                                    } else if (whitelistRoles.isEmpty()) {
-                                                        DiscordWhitelister.getPluginLogger().warning("Cannot remove any whitelisted roles from: " + targetDiscordId + "(" + finalNameToRemove + ") as there are none specified in the config");
-                                                    }
-                                                    idFound = true;
-                                                    break;
-                                                }
-                                            }
-                                        }
-
-                                        if (!idFound) {
-                                            DiscordWhitelister.getPluginLogger().warning("Could not find any Discord id linked to Minecraft name: " + finalNameToRemove + ", therefore cannot remove any roles");
-                                        }
-                                        ClearPlayerFromUserList(finalNameToRemove);
-                                    }
-
-                                    // if the name is not on the removed list
-                                    if (!RemovedList.CheckStoreForPlayer(finalNameToRemove)) {
-                                        RemovedList.getRemovedPlayers().set(finalNameToRemove, author.getId());
-                                        RemovedList.SaveStore();
-                                    }
-                                } else {
-                                    QueueAndRemoveAfterSeconds(channel, embedBuilderFailure.build());
-                                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                                }
-
-                                return null;
-                            });
-                            return;
-                        }
-                        return;
-                    }
-
-                }
-
-                if (authorPermissions.isUserCanAdd() && !authorPermissions.isUserCanAddRemove())
-                {
-                    String higherPermRoles = DiscordWhitelister.mainConfig.getFileConfiguration().getList("add-remove-roles").toString();
-                    higherPermRoles = higherPermRoles.replaceAll("\\[", "");
-                    higherPermRoles = higherPermRoles.replaceAll("]", "");
-
-                    EmbedBuilder embedBuilderInfo;
-
-                    if(!DiscordWhitelister.useCustomMessages)
-                    {
-                        embedBuilderInfo = CreateEmbeddedMessage("Insufficient Permissions", (author.getAsMention() + ", you only have permission to add people to the whitelist. To remove people from the whitelist you must be moved to the following roles: "
-                                + higherPermRoles + "; or get the owner to move your role to 'add-remove-roles' in the config."), EmbedMessageType.INFO);
-                    }
-                    else
-                    {
-                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("insufficient-permissions-remove-title");
-                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("insufficient-permissions-remove");
-                        customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                        customMessage = customMessage.replaceAll("\\{AddRemoveRoles}", higherPermRoles);
-
-                        embedBuilderInfo = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.INFO);
-                    }
-
-                    QueueAndRemoveAfterSeconds(channel, embedBuilderInfo.build());
-                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                    return;
-                }
-
-                // if the user doesn't have any allowed roles
-                QueueAndRemoveAfterSeconds(channel, CreateInsufficientPermsMessage(author));
-                //TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
+            break;
+            case "clearban": {
+                CommandClearban.ExecuteCommand(event, mc_name);
             }
+            break;
 
-            // Clear Whitelists command
-            if (messageContents.toLowerCase().startsWith("!clearname") && !DiscordWhitelister.getUseCustomPrefixes()
-                    || DiscordWhitelister.getUseCustomPrefixes() && messageContents.toLowerCase().startsWith(customClearNamePrefix)) {
-                // !clearname <targetName>
-                // TODO: !clearnames <@DiscordID>
+            case "help":
+                CommandInfo.ExecuteCommand(event);
+                break;
+            default:
+                event.reply("I can't handle that command right now :(").setEphemeral(true).queue();
+        }
 
-                // Check permissions
-                if (!authorPermissions.isUserCanUseClear()) {
-                    QueueAndRemoveAfterSeconds(channel, CreateInsufficientPermsMessage(author));
-                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                    return;
-                }  // Don't have permission
-
-                if (messageContents.toLowerCase().trim().equals("!clearname") && !DiscordWhitelister.getUseCustomPrefixes()
-                        || messageContents.toLowerCase().trim().equals(customClearNamePrefix) && DiscordWhitelister.getUseCustomPrefixes()) {
-                    if (hideInfoCommandReplies) {
-                        TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                        return;
-                    }
-
-                    MessageEmbed messageEmbed;
-                    if (!DiscordWhitelister.getUseCustomPrefixes()) {
-                        messageEmbed = CreateEmbeddedMessage("Clear Name Command", "Usage: `!clearname <minecraftUsername>`\n", EmbedMessageType.INFO).build();
-                    } else {
-                        messageEmbed = CreateEmbeddedMessage("Clear Name Command", "Usage: `" + customClearNamePrefix + " <minecraftUsername>`\n", EmbedMessageType.INFO).build();
-                    }
-                    QueueAndRemoveAfterSeconds(channel, messageEmbed);
-
-                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                    return;
-                }
-
-                // If command is not empty check for args
-                // String[] splitMessage = messageContents.toLowerCase().trim().split(" "); // TODO
-
-                int userNameIndex = 1;
-
-                if (DiscordWhitelister.getUseCustomPrefixes()) {
-                    String[] customPrefixCount = customClearNamePrefix.trim().split(" ");
-                    userNameIndex = customPrefixCount.length; // Don't + 1 as index starts at 0, length doesn't
-                }
-                String NameToRemove = splitMessage[userNameIndex];
-                DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to clear " + NameToRemove + " from the whitelist");
-
-                // Search for target name & linked ID
-                boolean nameFound = false;
-                String targetDiscordId = "";
-                Set<String> keys = UserList.getUserList().getKeys(false);
-                // Make sure the user list is not empty
-                if (keys.size() > 0) {
-                    for (String userid : keys) {
-                        List<?> registeredUsers = UserList.getRegisteredUsers(userid);
-                        if (registeredUsers.contains(NameToRemove)) {
-                            nameFound = true;
-                            targetDiscordId = userid;
-                            if (registeredUsers.size() > 1) {
-                                registeredUsers.remove(NameToRemove); // Clear name
-                                // Set the updated list in the config
-                                UserList.getUserList().set(userid, registeredUsers);
-                            } else { // Remove entirely
-
-                                UserList.getUserList().set(userid, null);
-                            }
-                            UserList.SaveStore();
-                            if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("unwhitelist-and-clear-perms-on-name-clear")) {
-                                // Remove name from the whitelist
-                                UnWhitelist(splitMessage[userNameIndex]);
-                            }
-                            break;
-                        }
-                    }
-                }
-                if (nameFound) {
-                    // Success message
-                    if (DiscordWhitelister.useCustomMessages) {
-                        String clearNameTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-success-title");
-                        String clearNameMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-success-message");
-
-                        clearNameMessage = clearNameMessage.replaceAll("\\{Sender}", author.getAsMention());
-                        clearNameMessage = clearNameMessage.replaceAll("\\{MinecraftUsername}", splitMessage[userNameIndex]);
-                        clearNameMessage = clearNameMessage.replaceAll("\\{DiscordID}", "<@" + targetDiscordId + ">");
-
-                        clearNameTitle = clearNameTitle.replaceAll("\\{MinecraftUsername}", splitMessage[userNameIndex]);
-
-                        MessageEmbed messageEmbed = CreateEmbeddedMessage(clearNameTitle, clearNameMessage, EmbedMessageType.SUCCESS).build();
-                        QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                    } else {
-                        MessageEmbed messageEmbed = CreateEmbeddedMessage("Successfully Cleared Name", (author.getAsMention() + " successfully cleared username `" + splitMessage[userNameIndex] +
-                                "` from <@" + targetDiscordId + ">'s whitelisted users."), EmbedMessageType.SUCCESS).build();
-                        QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                    }
-
-                } else {
-                    // Name not found
+        // Warn if enabled
+                /*if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("show-warning-in-command-channel")) {
                     if (!DiscordWhitelister.useCustomMessages) {
-                        MessageEmbed messageEmbed =
-                                CreateEmbeddedMessage((splitMessage[userNameIndex] + " not Found"),
-                                        (author.getAsMention() + ", could not find name " + splitMessage[userNameIndex] + " to clear in user list."), EmbedMessageType.FAILURE).build();
+                        MessageEmbed messageEmbed = CreateEmbeddedMessage("This Channel is for Commands Only", (author.getAsMention() + ", this channel is for commands only, please use another channel."),
+                                EmbedMessageType.FAILURE).build();
                         QueueAndRemoveAfterSeconds(channel, messageEmbed);
                     } else {
-                        String customTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-failure-title");
-                        String customMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-failure-message");
+                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("command-channel-title");
+
+                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("command-channel-message");
                         customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                        customMessage = customMessage.replaceAll("\\{MinecraftUsername}", splitMessage[userNameIndex]);
-                        customTitle = customTitle.replaceAll("\\{MinecraftUsername}", splitMessage[userNameIndex]);
 
-                        MessageEmbed messageEmbed = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.FAILURE).build();
+                        MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
                         QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                    }
+                    }*/
 
-                }
-                TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                return;
 
-            }
-            // Clear whitelists for limited-whitelisters
-            else if (messageContents.toLowerCase().startsWith("!whitelist clear") && !DiscordWhitelister.getUseCustomPrefixes()
-                    || DiscordWhitelister.getUseCustomPrefixes() && messageContents.toLowerCase().startsWith(customLimitedWhitelistClearPrefix)) {
-                if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("allow-limited-whitelisters-to-unwhitelist-self"))
-                    return;
+    }
 
-                // just inform staff, can add custom messages later if really needed
-                if (authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserIsBanned() || authorPermissions.isUserCanAdd() && !authorPermissions.isUserIsBanned()) {
-                    MessageEmbed messageEmbed = CreateEmbeddedMessage("This Command is Only Available for Limited Whitelister Roles",
-                            "If staff members need to clear a name from the whitelist please use `!clearname <mcName>`.", EmbedMessageType.INFO).build();
-                    QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                    return;
-                }
+    @Override
+    public void onMessageReceived(MessageReceivedEvent messageReceivedEvent) {
+        if (!messageReceivedEvent.isFromType(ChannelType.TEXT)) {
+            return;
+        }
+        // Check if message should be handled
+        if (!Arrays.asList(targetTextChannels).contains(messageReceivedEvent.getTextChannel().getId()))
+            return;
 
-                if (authorPermissions.isUserHasLimitedAdd() && !authorPermissions.isUserIsBanned()) {
-                    List<?> ls = UserList.getRegisteredUsers(author.getId());
+        if (messageReceivedEvent.getAuthor().getIdLong() == javaDiscordAPI.getSelfUser().getIdLong())
+            return;
 
-                    // check for names whitelisted
-                    if (ls != null) {
-                        for (Object minecraftNameToRemove : ls) {
-                            UnWhitelist(minecraftNameToRemove.toString());
-                        }
+        String messageContents = messageReceivedEvent.getMessage().getContentRaw();
+        String[] splitMessage = messageContents.toLowerCase().trim().split(" ");
 
-                        try {
-                            UserList.resetRegisteredUsers(author.getId());
-                        } catch (IOException e) {
-                            DiscordWhitelister.getPluginLogger().severe("Failed to remove" + author.getId() + "'s entries.");
-                            e.printStackTrace();
-                            return;
-                        }
 
-                        DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") triggered whitelist clear. " +
-                                "Successfully removed their whitelisted entries from the user list.");
+        // TODO remove, use in command classes when complete
+        User author = messageReceivedEvent.getAuthor();
+        TextChannel channel = messageReceivedEvent.getTextChannel();
 
-                        // Log in Discord channel
-                        if (!DiscordWhitelister.useCustomMessages) {
-                            String message = author.getAsMention() + " successfully removed the following users from the whitelist: \n";
-                            for (Object minercaftName : ls) {
-                                message += "- " + minercaftName.toString() + "\n";
-                            }
-                            message += "\n You now have **" + maxWhitelistAmount + " whitelist(s) remaining**.";
+        // if no commands are executed, delete the message, if enabled
+        if (DiscordWhitelister.removeUnnecessaryMessages) {
+            RemoveMessageAfterSeconds(messageReceivedEvent, DiscordWhitelister.removeMessageWaitTime);
+        }
 
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage(("Successfully Removed " + author.getName() + "'s Whitelisted Entries"),
-                                    message, EmbedMessageType.FAILURE).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        } else {
-                            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-success-title");
-                            customTitle = customTitle.replaceAll("\\{Sender}", author.getName());
+        // Warn if enabled
+        if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("show-warning-in-command-channel")) {
+            if (!DiscordWhitelister.useCustomMessages) {
+                MessageEmbed messageEmbed = CreateEmbeddedMessage("This Channel is for Commands Only", (author.getAsMention() + ", this channel is for commands only, please use another channel."),
+                        EmbedMessageType.FAILURE).build();
+                QueueAndRemoveAfterSeconds(channel, messageEmbed);
+            } else {
+                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("command-channel-title");
 
-                            String removedNames = "";
-                            for (Object minercaftName : ls) {
-                                removedNames += "- " + minercaftName.toString() + "\n";
-                            }
+                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("command-channel-message");
+                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
 
-                            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-success-message");
-                            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                            customMessage = customMessage.replaceAll("\\{RemovedEntries}", removedNames);
-                            customMessage = customMessage.replaceAll("\\{MaxWhitelistAmount}", String.valueOf(maxWhitelistAmount));
-
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.SUCCESS).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-
-                        if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("whitelisted-role-auto-remove")) {
-                            // Find all servers bot is in, remove whitelisted roles
-                            for (int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) {
-                                // Remove the whitelisted role(s)
-                                RemoveRolesFromUser(javaDiscordAPI.getGuilds().get(i), author.getId(), Arrays.asList(whitelistedRoleNames));
-                            }
-                        }
-
-                        TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                        return;
-                    } else {
-                        DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") triggered whitelist clear. " +
-                                "Could not remove any whitelisted entries as they do not have any.");
-
-                        // Log in Discord channel
-                        if (!DiscordWhitelister.useCustomMessages) {
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage("No Entries to Remove",
-                                    (author.getAsMention() + ", you do not have any whitelisted entries to remove."), EmbedMessageType.FAILURE).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        } else {
-                            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-failure-title");
-                            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-failure-message");
-                            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.FAILURE).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-
-                        TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                        return;
-                    }
-                }
-
-                if (!authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd() && !authorPermissions.isUserHasLimitedAdd() || authorPermissions.isUserIsBanned()) {
-                    QueueAndRemoveAfterSeconds(channel, CreateInsufficientPermsMessage(author));
-                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                    return;
-                }
-            }
-            else if (messageContents.toLowerCase().startsWith("!clearban") && !DiscordWhitelister.getUseCustomPrefixes()
-                    || DiscordWhitelister.getUseCustomPrefixes() && messageContents.toLowerCase().startsWith(customClearBanPrefix))
-            {
-                if(authorPermissions.isUserCanUseClear())
-                {
-                    // Check if empty command
-                    if(messageContents.toLowerCase().trim().equals("!clearban") && !DiscordWhitelister.getUseCustomPrefixes()
-                            || messageContents.toLowerCase().trim().equals(customClearBanPrefix) && DiscordWhitelister.getUseCustomPrefixes())
-                    {
-                        if(!hideInfoCommandReplies)
-                        {
-                            TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                            return;
-                        }
-
-                        // Send info message
-                        if(!DiscordWhitelister.getUseCustomPrefixes())
-                        {
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage("Clear Ban Command", "Usage: `!clearban <minecraftUsername>`\n", EmbedMessageType.INFO).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-                        else
-                        {
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage("Clear Ban Command", "Usage: `" + customClearBanPrefix + " <minecraftUsername>`\n", EmbedMessageType.INFO).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-
-                        TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                        return;
-                    }
-
-                    // If command is not empty check for args
-                    // String[] splitMessage = messageContents.toLowerCase().trim().split(" ");
-
-                    int userNameIndex = 1;
-
-                    if(DiscordWhitelister.getUseCustomPrefixes())
-                    {
-                        String[] customPrefixCount = customClearBanPrefix.trim().split(" ");
-                        userNameIndex = customPrefixCount.length; // Don't + 1 as index starts at 0, length doesn't
-                    }
-
-                    String targetName = splitMessage[userNameIndex];
-
-                    // Check both removed lists for target name
-                    boolean nameFoundInLists = false;
-
-                    // Remove name from removed list if found
-                    if(RemovedList.CheckStoreForPlayer(targetName))
-                    {
-                        RemovedList.getRemovedPlayers().set(targetName, null);
-                        RemovedList.SaveStore();
-
-                        nameFoundInLists = true;
-                    }
-
-                    if(InGameRemovedList.CheckStoreForPlayer(targetName))
-                    {
-                        InGameRemovedList.RemoveUserFromStore(targetName);
-
-                        nameFoundInLists = true;
-                    }
-
-                    if(nameFoundInLists)
-                    {
-                        EmbedBuilder clearBanSuccessEmbed;
-
-                        if(!DiscordWhitelister.useCustomMessages)
-                        {
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage(("Successfully Cleared `" + targetName + "`"),
-                                    (author.getAsMention() + " has successfully cleared `" + targetName + "` from the removed list(s)."), EmbedMessageType.SUCCESS).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-                        else
-                        {
-                            String customTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-success-title");
-                            String customMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-success-message");
-                            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                            customMessage = customMessage.replaceAll("\\{MinecraftUsername}", targetName);
-                            customTitle = customTitle.replaceAll("\\{MinecraftUsername}", targetName);
-
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.INFO).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-
-                        TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                        return;
-                    }
-                    else
-                    {
-                        if(!DiscordWhitelister.useCustomMessages)
-                        {
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage(("Failed to Clear `" + targetName + "`"),
-                                    (author.getAsMention() + ", `" + targetName + "` cannot be found in any of the removed lists!"), EmbedMessageType.FAILURE).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-                        else
-                        {
-                            String customTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-failure-title");
-                            String customMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-failure-message");
-                            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                            customMessage = customMessage.replaceAll("\\{MinecraftUsername}", targetName);
-                            customTitle = customTitle.replaceAll("\\{MinecraftUsername}", targetName);
-
-                            MessageEmbed messageEmbed = CreateEmbeddedMessage(customTitle, customMessage, EmbedMessageType.FAILURE).build();
-                            QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                        }
-
-                        TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                        return;
-                    }
-                }
-                else
-                {
-                    QueueAndRemoveAfterSeconds(channel, CreateInsufficientPermsMessage(author));
-                    TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
-                    return;
-                }
-            }
-
-            if(!DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length >= whitelistWhoIsPrefix.length && CheckForPrefix(whitelistWhoIsPrefix, splitMessage)
-                    || DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length >= customWhoIsPrefix.length && CheckForPrefix(customWhoIsPrefix, splitMessage))
-            {
-                CommandWhoIs.ExecuteCommand(messageReceivedEvent, splitMessage);
-
-                if(DiscordWhitelister.removeUnnecessaryMessages)
-                    RemoveMessageAfterSeconds(messageReceivedEvent, DiscordWhitelister.removeMessageWaitTime);
-                return;
-            }
-
-            // if no commands are executed, delete the message, if enabled
-            if(DiscordWhitelister.removeUnnecessaryMessages)
-            {
-                RemoveMessageAfterSeconds(messageReceivedEvent, DiscordWhitelister.removeMessageWaitTime);
-            }
-
-            // Warn if enabled
-            if(DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("show-warning-in-command-channel"))
-            {
-                if(!DiscordWhitelister.useCustomMessages)
-                {
-                    MessageEmbed messageEmbed = CreateEmbeddedMessage("This Channel is for Commands Only", (author.getAsMention() + ", this channel is for commands only, please use another channel."),
-                            EmbedMessageType.FAILURE).build();
-                    QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                }
-                else
-                {
-                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("command-channel-title");
-
-                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("command-channel-message");
-                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-
-                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
-                    QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                }
+                MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
+                QueueAndRemoveAfterSeconds(channel, messageEmbed);
             }
         }
     }
 
     @Override
-    public void onGuildMemberRemove(@Nonnull GuildMemberRemoveEvent event)
-    {
-        if(!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("un-whitelist-on-server-leave"))
+    public void onGuildMemberRemove(@Nonnull GuildMemberRemoveEvent event) {
+        if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("un-whitelist-on-server-leave"))
             return;
 
         String discordUserToRemove = event.getMember().getId();
         DiscordWhitelister.getPlugin().getLogger().info(discordUserToRemove + " left. Removing their whitelisted entries...");
-        List<?> ls =  UserList.getRegisteredUsers(discordUserToRemove);
+        List<?> ls = UserList.getRegisteredUsers(discordUserToRemove);
 
-        if(ls != null)
-        {
-            for (Object minecraftNameToRemove : ls)
-            {
+        if (ls != null) {
+            for (Object minecraftNameToRemove : ls) {
                 DiscordWhitelister.getPlugin().getLogger().info(minecraftNameToRemove.toString() + " left. Removing their whitelisted entries.");
                 UnWhitelist(minecraftNameToRemove.toString());
             }
 
-            try
-            {
+            try {
                 UserList.resetRegisteredUsers(discordUserToRemove);
-            }
-            catch (IOException e)
-            {
+            } catch (IOException e) {
                 e.printStackTrace();
                 return;
             }
             DiscordWhitelister.getPlugin().getLogger().info(discordUserToRemove + " left. Successfully removed their whitelisted entries from the user list.");
-        }
-        else
-        {
+        } else {
             DiscordWhitelister.getPlugin().getLogger().warning(discordUserToRemove + " left. Could not remove any whitelisted entries as they did not whitelist through this plugin.");
         }
     }
 
     @Override
-    public void onGuildMemberRoleRemove(@Nonnull GuildMemberRoleRemoveEvent e)
-    {
+    public void onGuildMemberRoleRemove(@Nonnull GuildMemberRoleRemoveEvent e) {
         CheckForRequiredRole(e);
     }
 
-    private static void CheckForRequiredRole(GuildMemberRoleRemoveEvent e)
-    {
-        if(!checkForMissingRole)
+    private static void CheckForRequiredRole(GuildMemberRoleRemoveEvent e) {
+        if (!checkForMissingRole)
             return;
 
         String disName = e.getMember().getEffectiveName();
         String disId = e.getMember().getId();
         String nameForLogger = disName + "(" + disId + ")";
 
-        if(checkAllRoles)
-        {
+        if (checkAllRoles) {
             List<Role> removedRoles = e.getRoles();
             boolean limitedRoleRemoved = false;
 
             // Check if removed roles contain a limited-add role
-            for(Role role:removedRoles)
-            {
-                if(DiscordWhitelister.useIdForRoles)
-                {
-                    if(Arrays.asList(allowedToAddLimitedRoles).contains(role.getId()))
-                    {
+            for (Role role : removedRoles) {
+                if (DiscordWhitelister.useIdForRoles) {
+                    if (Arrays.asList(allowedToAddLimitedRoles).contains(role.getId())) {
                         limitedRoleRemoved = true;
                         break;
                     }
-                }
-                else
-                {
-                    if(Arrays.asList(allowedToAddLimitedRoles).contains(role.getName()))
-                    {
+                } else {
+                    if (Arrays.asList(allowedToAddLimitedRoles).contains(role.getName())) {
                         limitedRoleRemoved = true;
                         break;
                     }
                 }
             }
 
-            if(!limitedRoleRemoved)
+            if (!limitedRoleRemoved)
                 return;
 
             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++)
-            {
+            boolean rolesRemaining = false;
+            for (int i = 0; i < javaDiscordAPI.getGuilds().size(); i++) {
                 Member member = javaDiscordAPI.getGuilds().get(i).getMemberById(disId);
-                if(member != null)
-                {
+                if (member != null) {
                     List<Role> roles = member.getRoles();
-                    for(Role role:roles)
-                    {
-                        if(DiscordWhitelister.useIdForRoles)
-                        {
-                            if(Arrays.asList(combinedRoles).contains(role.getId()))
-                            {
+                    for (Role role : roles) {
+                        if (DiscordWhitelister.useIdForRoles) {
+                            if (Arrays.asList(combinedRoles).contains(role.getId())) {
                                 rolesRemaining = true;
                                 break;
                             }
-                        }
-                        else
-                        {
-                            if(Arrays.asList(combinedRoles).contains(role.getName()))
-                            {
+                        } else {
+                            if (Arrays.asList(combinedRoles).contains(role.getName())) {
                                 rolesRemaining = true;
                                 break;
                             }
@@ -1074,57 +540,40 @@ public class DiscordClient extends ListenerAdapter
                 }
             }
 
-            if(!rolesRemaining)
-            {
+            if (!rolesRemaining) {
                 DiscordWhitelister.getPlugin().getLogger().info(nameForLogger + " has no roles remaining. Removing their whitelisted entries...");
 
-                List<?> ls =  UserList.getRegisteredUsers(disId);
-                if(ls != null)
-                {
-                    for (Object minecraftNameToRemove : ls)
-                    {
+                List<?> ls = UserList.getRegisteredUsers(disId);
+                if (ls != null) {
+                    for (Object minecraftNameToRemove : ls) {
                         UnWhitelist(minecraftNameToRemove.toString());
                     }
 
-                    try
-                    {
+                    try {
                         UserList.resetRegisteredUsers(disId);
-                    }
-                    catch (IOException ex)
-                    {
+                    } catch (IOException ex) {
                         ex.printStackTrace();
                     }
-                }
-                else
-                {
+                } else {
                     DiscordWhitelister.getPlugin().getLogger().warning(nameForLogger + " does not have any whitelisted entries doing nothing...");
                 }
-            }
-            else
-            {
+            } else {
                 DiscordWhitelister.getPlugin().getLogger().info(nameForLogger + " has role(s) remaining. Doing nothing...");
             }
-        }
-        else
-        {
-            if(roleToCheck == null || roleToCheck.equals(""))
-            {
+        } 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())
-            {
+            for (Role r : e.getMember().getRoles()) {
                 // required role found, no need to proceed
-                if(DiscordWhitelister.useIdForRoles)
-                {
-                    if(r.getId().equals(roleToCheck))
+                if (DiscordWhitelister.useIdForRoles) {
+                    if (r.getId().equals(roleToCheck))
                         return;
-                }
-                else
-                {
-                    if(r.getName().equals(roleToCheck))
+                } else {
+                    if (r.getName().equals(roleToCheck))
                         return;
                 }
             }
@@ -1133,25 +582,19 @@ public class DiscordClient extends ListenerAdapter
                     "role (" + roleToCheck + "). Attempting to remove their whitelisted entries...");
 
             List<?> regUsers = UserList.getRegisteredUsers(disId);
-            if(regUsers != null)
-            {
-                if(regUsers.size() <= 0)
-                {
+            if (regUsers != null) {
+                if (regUsers.size() <= 0) {
                     DiscordWhitelister.getPluginLogger().info(nameForLogger + "'s entries are empty, doing nothing");
                     return;
                 }
 
-                for(Object mcName : regUsers)
-                {
+                for (Object mcName : regUsers) {
                     UnWhitelist(mcName.toString());
                 }
 
-                try
-                {
+                try {
                     UserList.resetRegisteredUsers(disId);
-                }
-                catch (IOException ex)
-                {
+                } catch (IOException ex) {
                     DiscordWhitelister.getPluginLogger().severe("Failed to remove whitelisted users from " +
                             nameForLogger);
                     ex.printStackTrace();
@@ -1160,9 +603,7 @@ public class DiscordClient extends ListenerAdapter
 
                 DiscordWhitelister.getPluginLogger().info("Successfully removed " + nameForLogger +
                         "'s whitelisted entries due to missing required role (" + roleToCheck + ")");
-            }
-            else
-            {
+            } else {
                 DiscordWhitelister.getPluginLogger().warning("Failed to remove whitelisted entries from " +
                         nameForLogger + " as they did not whitelist through this plugin");
             }
@@ -1170,8 +611,8 @@ public class DiscordClient extends ListenerAdapter
     }
 
     public static void RequiredRoleStartupCheck() {
-            if (!checkForMissingRole)
-                return;
+        if (!checkForMissingRole)
+            return;
 
         // Don't attempt to remove roles if not connected
         if (javaDiscordAPI.getStatus() != JDA.Status.CONNECTED)
@@ -1330,7 +771,7 @@ public class DiscordClient extends ListenerAdapter
     }
 
     // Find all occurrences of the target player and remove them
-    private static void ClearPlayerFromUserList(String targetName) {
+    public static void ClearPlayerFromUserList(String targetName) {
         // Just in-case
         targetName = targetName.toLowerCase();
 
@@ -1376,8 +817,7 @@ public class DiscordClient extends ListenerAdapter
     }
 
 
-    public static String minecraftUsernameToUUID(String minecraftUsername)
-    {
+    public static String minecraftUsernameToUUID(String minecraftUsername) {
         URL playerURL;
         String inputStream;
         BufferedReader bufferedReader;
@@ -1400,28 +840,26 @@ public class DiscordClient extends ListenerAdapter
         return playerUUID;
     }
 
-    public static void ExecuteServerCommand(String command)
-    {
+    public static void ExecuteServerCommand(String command) {
         DiscordWhitelister.getPlugin().getServer().getScheduler().callSyncMethod(DiscordWhitelister.getPlugin(), ()
                 -> DiscordWhitelister.getPlugin().getServer().dispatchCommand(
                 DiscordWhitelister.getPlugin().getServer().getConsoleSender(), command));
     }
 
-    private enum SenderType { CONSOLE, PLAYER, UNKNOWN }
-    public static void CheckAndExecuteCommand(String configInput, String playerTargetName)
-    {
+    private enum SenderType {CONSOLE, PLAYER, UNKNOWN}
+
+    public static void CheckAndExecuteCommand(String configInput, String playerTargetName) {
         SenderType senderType;
 
         // Check command sender type
-        if(configInput.startsWith("CONSOLE"))
+        if (configInput.startsWith("CONSOLE"))
             senderType = SenderType.CONSOLE;
-        else if(configInput.startsWith("PLAYER"))
+        else if (configInput.startsWith("PLAYER"))
             senderType = SenderType.PLAYER;
         else
             senderType = SenderType.UNKNOWN;
 
-        if(senderType.equals(SenderType.UNKNOWN))
-        {
+        if (senderType.equals(SenderType.UNKNOWN)) {
             DiscordWhitelister.getPluginLogger().warning("Unknown command sender type (should be one of the following: CONSOLE, PLAYER), offending line: " + configInput);
             return;
         }
@@ -1431,123 +869,99 @@ public class DiscordClient extends ListenerAdapter
         // Set player name if %PLAYER% is used
         final String commandToSendFinal = commandToSend.replaceAll("%PLAYER%", playerTargetName);
 
-        if(senderType.equals(SenderType.CONSOLE))
-        {
+        if (senderType.equals(SenderType.CONSOLE)) {
             DiscordWhitelister.getPlugin().getServer().getScheduler().callSyncMethod(DiscordWhitelister.getPlugin(),
                     () -> DiscordWhitelister.getPlugin().getServer().dispatchCommand(DiscordWhitelister.getPlugin().getServer().getConsoleSender(), commandToSendFinal));
-        }
-        else
-        {
+        } else {
             DiscordWhitelister.getPlugin().getServer().getPlayer(playerTargetName).performCommand(commandToSendFinal);
         }
     }
 
     // use this multiple times when checking all guilds
     // Accepts a single role in the form of a singleton list
-    public static void AssignRolesToUser(Guild targetGuild, String targetUserId, List<String> targetRole)
-    {
+    public static void AssignRolesToUser(Guild targetGuild, String targetUserId, List<String> targetRole) {
         // Check if the user is in the targetGuild
-        if(targetGuild.getMemberById(targetUserId) == null)
-        {
+        if (targetGuild.getMemberById(targetUserId) == null) {
             DiscordWhitelister.getPluginLogger().warning("User cannot be found in Guild " + targetGuild.getName()
-                    + "(" + targetGuild.getId() + ")" +". Will not attempt to assign role(s)");
+                    + "(" + targetGuild.getId() + ")" + ". Will not attempt to assign role(s)");
 
             return;
         }
 
         // Locate target role(s)
         LinkedList<Role> rolesFound = new LinkedList<>();
-        for(int i = 0; i < targetRole.size(); i++)
-        {
+        for (String s : targetRole) {
             List<Role> tempFoundRoles;
 
-            if(!DiscordWhitelister.useIdForRoles)
-                tempFoundRoles = targetGuild.getRolesByName(targetRole.get(i), false);
+            if (!DiscordWhitelister.useIdForRoles)
+                tempFoundRoles = targetGuild.getRolesByName(s, false);
             else
-                tempFoundRoles = Collections.singletonList(targetGuild.getRoleById(targetRole.get(i)));
+                tempFoundRoles = Collections.singletonList(targetGuild.getRoleById(s));
 
-            if(tempFoundRoles.size() > 0)
-            {
+            if (tempFoundRoles.size() > 0) {
                 rolesFound.addAll(tempFoundRoles);
-            }
-            else
-            {
+            } else {
                 String discordUserName = targetGuild.getMemberById(targetUserId).getEffectiveName();
-                DiscordWhitelister.getPluginLogger().warning("Failed to assign role " + targetRole.get(i)
+                DiscordWhitelister.getPluginLogger().warning("Failed to assign role " + s
                         + " to user " + discordUserName + "(" + targetUserId + ")" + " as it could not be found in "
                         + targetGuild.getName() + "(" + targetGuild.getId() + ")");
             }
         }
 
         // Check if any roles were found
-        if(rolesFound.size() > 0)
-        {
+        if (rolesFound.size() > 0) {
             // Assign the roles
-            for(int i = 0; i < rolesFound.size(); i++)
-            {
-                targetGuild.addRoleToMember(targetGuild.getMemberById(targetUserId), rolesFound.get(i)).queue();
+            for (Role role : rolesFound) {
+                targetGuild.addRoleToMember(targetGuild.getMemberById(targetUserId), role).queue();
             }
         }
     }
 
-    public static void RemoveRolesFromUser(Guild targetGuild, String targetUserId, List<String> targetRole)
-    {
+    public static void RemoveRolesFromUser(Guild targetGuild, String targetUserId, List<String> targetRole) {
         // Check if the user is in the targetGuild
-        if(targetGuild.getMemberById(targetUserId) == null)
-        {
+        if (targetGuild.getMemberById(targetUserId) == null) {
             DiscordWhitelister.getPluginLogger().warning("User cannot be found in Guild " + targetGuild.getName()
-                    + "(" + targetGuild.getId() + ")" +". Will not attempt to remove role(s)");
+                    + "(" + targetGuild.getId() + ")" + ". Will not attempt to remove role(s)");
 
             return;
         }
 
         // Locate target role(s)
         LinkedList<Role> rolesFound = new LinkedList<>();
-        for(int i = 0; i < targetRole.size(); i++)
-        {
+        for (String s : targetRole) {
             List<Role> tempFoundRoles;
 
-            if(!DiscordWhitelister.useIdForRoles)
-                tempFoundRoles = targetGuild.getRolesByName(targetRole.get(i), false);
+            if (!DiscordWhitelister.useIdForRoles)
+                tempFoundRoles = targetGuild.getRolesByName(s, false);
             else
-                tempFoundRoles = Collections.singletonList(targetGuild.getRoleById(targetRole.get(i)));
+                tempFoundRoles = Collections.singletonList(targetGuild.getRoleById(s));
 
-            if(tempFoundRoles.size() > 0)
-            {
+            if (tempFoundRoles.size() > 0) {
                 rolesFound.addAll(tempFoundRoles);
-            }
-            else
-            {
+            } else {
                 String discordUserName = targetGuild.getMemberById(targetUserId).getEffectiveName();
-                DiscordWhitelister.getPluginLogger().warning("Failed to remove role " + targetRole.get(i)
+                DiscordWhitelister.getPluginLogger().warning("Failed to remove role " + s
                         + " from user " + discordUserName + "(" + targetUserId + ")" + " as it could not be found in "
                         + targetGuild.getName() + "(" + targetGuild.getId() + ")");
             }
         }
 
         // Check if any roles were found
-        if(rolesFound.size() > 0)
-        {
+        if (rolesFound.size() > 0) {
             // Remove the roles
-            for(int i = 0; i < rolesFound.size(); i++)
-            {
-                targetGuild.removeRoleFromMember(targetGuild.getMemberById(targetUserId), rolesFound.get(i)).queue();
+            for (Role role : rolesFound) {
+                targetGuild.removeRoleFromMember(targetGuild.getMemberById(targetUserId), role).queue();
             }
         }
     }
 
-
-    public static void RemoveMessageAfterSeconds(MessageReceivedEvent messageReceivedEvent, Integer timeToWait)
-    {
+    public static void RemoveMessageAfterSeconds(MessageReceivedEvent messageReceivedEvent, Integer timeToWait) {
         Thread removeTimerThread = new Thread(() ->
         {
-            try
-            {
+            try {
                 TimeUnit.SECONDS.sleep(timeToWait);
                 messageReceivedEvent.getMessage().delete().queue();
-            }
-            catch (InterruptedException e)
-            {
+            } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         });
@@ -1555,46 +969,46 @@ public class DiscordClient extends ListenerAdapter
         removeTimerThread.start();
     }
 
-    public static void QueueAndRemoveAfterSeconds(TextChannel textChannel, MessageEmbed messageEmbed)
-    {
-        if(DiscordWhitelister.removeUnnecessaryMessages)
-            textChannel.sendMessage(messageEmbed).queue(message -> message.delete().queueAfter(DiscordWhitelister.removeMessageWaitTime, TimeUnit.SECONDS));
+
+    public static void ReplyAndRemoveAfterSeconds(SlashCommandEvent event, MessageEmbed messageEmbed) {
+        if (DiscordWhitelister.removeUnnecessaryMessages)
+            event.replyEmbeds(messageEmbed).queue(message -> message.deleteOriginal().queueAfter(DiscordWhitelister.removeMessageWaitTime, TimeUnit.SECONDS));
         else
-            textChannel.sendMessage(messageEmbed).queue();
+            event.replyEmbeds(messageEmbed).queue();
     }
 
-    public static void TempRemoveOriginalMessageAfterSeconds(MessageReceivedEvent messageReceivedEvent)
-    {
-        if(DiscordWhitelister.removeUnnecessaryMessages)
-            RemoveMessageAfterSeconds(messageReceivedEvent, DiscordWhitelister.removeMessageWaitTime);
+    public static void QueueAndRemoveAfterSeconds(TextChannel textChannel, MessageEmbed messageEmbed) {
+        if (DiscordWhitelister.removeUnnecessaryMessages)
+            textChannel.sendMessageEmbeds(messageEmbed).queue(message -> message.delete().queueAfter(DiscordWhitelister.removeMessageWaitTime, TimeUnit.SECONDS));
+        else
+            textChannel.sendMessageEmbeds(messageEmbed).queue();
     }
 
-
     // TODO: improve, not go through console commands
-    public static void AssignPerms(String targetPlayerName){
+    public static void AssignPerms(String targetPlayerName) {
         // For ultra perms:
-        if(DiscordWhitelister.useLuckPerms){
+        if (DiscordWhitelister.useLuckPerms) {
             for (String s : DiscordWhitelister.customPrefixConfig.getFileConfiguration().getStringList("perms-on-whitelist")) {
                 DiscordClient.ExecuteServerCommand("lp user " + targetPlayerName + " permission set " + s);
             }
         }
         // For LuckPerms:
-        if(DiscordWhitelister.useUltraPerms){
+        if (DiscordWhitelister.useUltraPerms) {
             for (String s : DiscordWhitelister.customPrefixConfig.getFileConfiguration().getStringList("perms-on-whitelist")) {
                 DiscordClient.ExecuteServerCommand("upc addPlayerPermission " + targetPlayerName + " " + s);
             }
         }
     }
 
-    public static void RemovePerms(String targetPlayerName){
+    public static void RemovePerms(String targetPlayerName) {
         // For ultra perms:
-        if(DiscordWhitelister.useLuckPerms){
+        if (DiscordWhitelister.useLuckPerms) {
             for (String s : DiscordWhitelister.customPrefixConfig.getFileConfiguration().getStringList("perms-on-whitelist")) {
                 DiscordClient.ExecuteServerCommand("lp user " + targetPlayerName + " permission unset " + s);
             }
         }
         // For LuckPerms:
-        if(DiscordWhitelister.useUltraPerms){
+        if (DiscordWhitelister.useUltraPerms) {
             for (String s : DiscordWhitelister.customPrefixConfig.getFileConfiguration().getStringList("perms-on-whitelist")) {
                 DiscordClient.ExecuteServerCommand("upc removePlayerPermission " + targetPlayerName + " " + s);
             }
diff --git a/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java b/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java
index 66131a5..8de3945 100755
--- a/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java
+++ b/src/main/java/uk/co/angrybee/joe/DiscordWhitelister.java
@@ -21,7 +21,10 @@ import uk.co.angrybee.joe.events.EssentialsVanishEvents;
 import uk.co.angrybee.joe.events.SuperVanishEvents;
 import uk.co.angrybee.joe.events.VanishNoPacketEvents;
 
+import java.lang.reflect.Array;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.logging.Logger;
 import java.util.stream.Stream;
 
@@ -138,6 +141,14 @@ public class DiscordWhitelister extends JavaPlugin {
         return thisPlugin.getServer().getOnlinePlayers().size() - vanishedPlayersCount;
     }
 
+
+    static String[] getConfigArray(String path){
+        List<String> list = mainConfig.getFileConfiguration().getStringList(path);
+        String[] array = new String[list.size()];
+        list.toArray(array);
+        return array;
+    }
+
     public static int getMaximumAllowedPlayers() {
         return thisPlugin.getServer().getMaxPlayers();
     }
@@ -205,38 +216,29 @@ public class DiscordWhitelister extends JavaPlugin {
             // TODO: below role section could be moved to DiscordClient class
             useIdForRoles = mainConfig.getFileConfiguration().getBoolean("use-id-for-roles");
 
+
+
+
+
             // set add & remove roles
-            DiscordClient.allowedToAddRemoveRoles = new String[mainConfig.getFileConfiguration().getList("add-remove-roles").size()];
-            for (int roles = 0; roles < DiscordClient.allowedToAddRemoveRoles.length; ++roles) {
-                DiscordClient.allowedToAddRemoveRoles[roles] = mainConfig.getFileConfiguration().getList("add-remove-roles").get(roles).toString();
-            }
+            DiscordClient.allowedToAddRemoveRoles = getConfigArray("add-remove-roles");
+
 
             // set add roles
-            DiscordClient.allowedToAddRoles = new String[mainConfig.getFileConfiguration().getList("add-roles").size()];
-            for (int roles = 0; roles < DiscordClient.allowedToAddRoles.length; ++roles) {
-                DiscordClient.allowedToAddRoles[roles] = mainConfig.getFileConfiguration().getList("add-roles").get(roles).toString();
-            }
+            DiscordClient.allowedToAddRoles = getConfigArray("add-roles");
+
 
             // set limited add roles
-            DiscordClient.allowedToAddLimitedRoles = new String[mainConfig.getFileConfiguration().getList("limited-add-roles").size()];
-            for (int roles = 0; roles < DiscordClient.allowedToAddLimitedRoles.length; ++roles) {
-                DiscordClient.allowedToAddLimitedRoles[roles] = mainConfig.getFileConfiguration().getList("limited-add-roles").get(roles).toString();
-            }
+            DiscordClient.allowedToAddLimitedRoles = getConfigArray("limited-add-roles");
+
 
             // Get banned roles
             if (useOnBanEvents) {
-                List<String> tempBannedRoles = mainConfig.getFileConfiguration().getStringList("banned-roles");
-                bannedRoles = new String[tempBannedRoles.size()];
-                for (int i = 0; i < tempBannedRoles.size(); i++) {
-                    bannedRoles[i] = tempBannedRoles.get(i);
-                }
+                bannedRoles = getConfigArray("banned-roles");
             }
 
             // Allowed to clear name roles
-            DiscordClient.allowedToClearNamesRoles = new String[mainConfig.getFileConfiguration().getStringList("clear-command-roles").size()];
-            for (int roles = 0; roles < DiscordClient.allowedToClearNamesRoles.length; roles++) {
-                DiscordClient.allowedToClearNamesRoles[roles] = mainConfig.getFileConfiguration().getStringList("clear-command-roles").get(roles);
-            }
+            DiscordClient.allowedToClearNamesRoles = getConfigArray("clear-command-roles");
 
             // All roles combined for role check
             DiscordClient.combinedRoles = Stream.of(DiscordClient.allowedToAddRemoveRoles, DiscordClient.allowedToAddRoles,
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandAdd.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandAdd.java
index 2e2facd..0fd656b 100644
--- a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandAdd.java
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandAdd.java
@@ -2,6 +2,7 @@ package uk.co.angrybee.joe.commands.discord;
 
 import net.dv8tion.jda.api.EmbedBuilder;
 import net.dv8tion.jda.api.entities.*;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
 import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
 import uk.co.angrybee.joe.AuthorPermissions;
 import uk.co.angrybee.joe.DiscordClient;
@@ -17,191 +18,129 @@ import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-public class CommandAdd
-{
-    public static void ExecuteCommand(MessageReceivedEvent messageReceivedEvent, String[] splitMessageCaseSensitive)
-    {
-        AuthorPermissions authorPermissions = new AuthorPermissions(messageReceivedEvent);
-        User author = messageReceivedEvent.getAuthor();
-        TextChannel channel = messageReceivedEvent.getTextChannel();
-        Member member = messageReceivedEvent.getMember();
+public class CommandAdd {
+    public static void ExecuteCommand(SlashCommandEvent event, String mc_user, Member target) {
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+        TextChannel channel = event.getTextChannel();
+        Member member = event.getMember();
 
-        if(DiscordWhitelister.useOnBanEvents && authorPermissions.isUserIsBanned())
-        {
-            if(!DiscordWhitelister.useCustomMessages)
-            {
-                MessageEmbed messageEmbed =
-                        DiscordClient.CreateEmbeddedMessage("You have been banned!", (author.getAsMention() + ", you cannot use this bot as you have been banned!"), DiscordClient.EmbedMessageType.FAILURE).build();
+        int timesWhitelisted =0;
+        final String finalNameToAdd = mc_user;
+        final char[] finalNameToWhitelistChar = finalNameToAdd.toLowerCase().toCharArray(); // Lower case for char check
+        final Member suppliedMember = target;
+        boolean onlyHasLimitedAdd = false;
+        if (DiscordClient.usernameValidation) {
+            // Invalid char check
+            for (char c : finalNameToWhitelistChar) {
+                if (new String(DiscordClient.validCharacters).indexOf(c) == -1) {
+                    EmbedBuilder embedBuilderInvalidChar;
 
-                DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
+                    if (!DiscordWhitelister.useCustomMessages) {
+                        embedBuilderInvalidChar = DiscordClient.CreateEmbeddedMessage("Invalid Username", (author.getAsMention() + ", the username you have specified contains invalid characters. **Only letters, numbers and underscores are allowed**."), DiscordClient.EmbedMessageType.FAILURE);
+                    } else {
+                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-characters-warning-title");
+                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-characters-warning");
+                        customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+
+                        embedBuilderInvalidChar = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+                    }
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderInvalidChar.build());
+                    return;
+                }
             }
-            else
-            {
-                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("banned-title");
-                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("banned-message");
-                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention()); // Only checking for {Sender}
 
-                MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
-                DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
+            // Length check
+            if (finalNameToAdd.length() < 3 || finalNameToAdd.length() > 16) {
+                EmbedBuilder embedBuilderLengthInvalid;
+
+                if (!DiscordWhitelister.useCustomMessages) {
+                    embedBuilderLengthInvalid = DiscordClient.CreateEmbeddedMessage("Invalid Username", (author.getAsMention() + ", the username you have specified either contains too few or too many characters. **Usernames can only consist of 3-16 characters**."), DiscordClient.EmbedMessageType.FAILURE);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-length-warning-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-length-warning");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+
+                    embedBuilderLengthInvalid = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+                }
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderLengthInvalid.build());
+                return;
             }
-            return;
         }
 
-        // Permission check
-        if (!(authorPermissions.isUserCanAddRemove() || authorPermissions.isUserCanAdd() || DiscordClient.limitedWhitelistEnabled && authorPermissions.isUserHasLimitedAdd()))
-        {
-            //todo: add a message to notify user
-            DiscordClient.QueueAndRemoveAfterSeconds(channel, DiscordClient.CreateInsufficientPermsMessage(author));
-            return;
-        }
+        if (authorPermissions.isUserCanAddRemove() || authorPermissions.isUserCanAdd()) {
 
-        /* if limited whitelist is enabled, check if the user is in the limited whitelister group and add the user to the list
-        which records how many times the user has successfully used the whitelist command */
-        if (DiscordClient.limitedWhitelistEnabled && authorPermissions.isUserHasLimitedAdd())
-        {
-            if (UserList.getUserList().getString(author.getId()) == null)
-            {
+
+            // runs after member null check
+            // Create a entry in the user list if needed for supplied id
+            if (UserList.getUserList().getString(suppliedMember.getId()) == null) {
+                UserList.getUserList().set(suppliedMember.getId(), new ArrayList<String>());
+                UserList.SaveStore();
+            }
+
+            DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to whitelist: " + finalNameToAdd);
+
+        } else if (authorPermissions.isUserHasLimitedAdd() && DiscordClient.limitedWhitelistEnabled) {
+            onlyHasLimitedAdd = true;
+            if (DiscordWhitelister.useOnBanEvents && authorPermissions.isUserIsBanned()) {
+                if (!DiscordWhitelister.useCustomMessages) {
+                    MessageEmbed messageEmbed =
+                            DiscordClient.CreateEmbeddedMessage("You have been banned!", (author.getAsMention() + ", you cannot use this bot as you have been banned!"), DiscordClient.EmbedMessageType.FAILURE).build();
+
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("banned-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("banned-message");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention()); // Only checking for {Sender}
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+                return;
+            }
+                /* if limited whitelist is enabled, check if the user is in the limited whitelister group and add the user to the list
+                which records how many times the user has successfully used the whitelist command */
+            if (UserList.getUserList().getString(author.getId()) == null) {
                 UserList.getUserList().set(author.getId(), new ArrayList<String>());
                 UserList.SaveStore();
             }
-        }
+            boolean usedAllWhitelists = false;
+            try {
+                usedAllWhitelists = UserList.getRegisteredUsersCount(author.getId()) >= DiscordClient.maxWhitelistAmount &&
+                        !authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd();
+            } catch (NullPointerException exception) {
+                exception.printStackTrace();
+            }
+            /*
+            todo:add this
+            MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Insufficient Permissions",
+                        (author.getAsMention() + ", only staff members can manually link Discord IDs. Please only enter your Minecraft name."), DiscordClient.EmbedMessageType.FAILURE).build();
 
-        boolean usedAllWhitelists = false;
-        try
-        {
-            usedAllWhitelists = UserList.getRegisteredUsersCount(author.getId()) >= DiscordClient.maxWhitelistAmount &&
-                    !authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd();
-        }
-        catch (NullPointerException exception)
-        {
-            exception.printStackTrace();
-        }
-
-        if (authorPermissions.isUserCanAddRemove() || authorPermissions.isUserCanAdd() || DiscordClient.limitedWhitelistEnabled && authorPermissions.isUserHasLimitedAdd())
-        {
-            if(DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length > (DiscordClient.customWhitelistAddPrefixSplit.length + 2)
-                    || !DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length > (DiscordClient.whitelistAddPrefix.length + 2))
-            {
-                int amountOfArgs = 0;
-                if(DiscordWhitelister.getUseCustomPrefixes())
-                    amountOfArgs = splitMessageCaseSensitive.length - (DiscordClient.customWhitelistAddPrefixSplit.length);
-                else
-                    amountOfArgs = splitMessageCaseSensitive.length - (DiscordClient.whitelistAddPrefix.length);
-
-                StringBuilder exampleCommand = new StringBuilder();
-                if(DiscordWhitelister.getUseCustomPrefixes())
-                {
-                    for(int i = 0; i < DiscordClient.customWhitelistAddPrefixSplit.length; i++)
-                    {
-                        exampleCommand.append(DiscordClient.customWhitelistAddPrefixSplit[i]).append(" ");
-                    }
-                }
-                else
-                {
-                    for(int i = 0; i < DiscordClient.whitelistAddPrefix.length; i++)
-                    {
-                        exampleCommand.append(DiscordClient.whitelistAddPrefix[i]).append(" ");
-                    }
-                }
-                exampleCommand.append("<minecraftUsername> <@discordMention>");
-
-                MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Too many arguments",
-                        (author.getAsMention() + ", expected 1 or 2 arguments but found " + amountOfArgs + ".\n" +
-                                "Example: " + exampleCommand.toString() + "\n\n **NOTE:** Only staff members may use the <@discordMention> parameter."),
-                                    DiscordClient.EmbedMessageType.FAILURE).build();
-
-                DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
                 return;
-            }
 
-            String nameToAddCaseSensitive = "";
-            if(DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length >= DiscordClient.customWhitelistAddPrefixSplit.length + 1)
-                nameToAddCaseSensitive = splitMessageCaseSensitive[DiscordClient.customWhitelistAddPrefixSplit.length];
-
-            if(!DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length >= DiscordClient.whitelistAddPrefix.length + 1)
-                nameToAddCaseSensitive = splitMessageCaseSensitive[DiscordClient.whitelistAddPrefix.length];
-
-            final String finalNameToAdd = nameToAddCaseSensitive;
-            final char[] finalNameToWhitelistChar = finalNameToAdd.toLowerCase().toCharArray(); // Lower case for char check
-
-            int timesWhitelisted = 0;
-
-            boolean onlyHasLimitedAdd = DiscordClient.limitedWhitelistEnabled && authorPermissions.isUserHasLimitedAdd() &&
-                    !authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd();
-
-            boolean discordIdProvided = false;
-            if(DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length == (DiscordClient.customWhitelistAddPrefixSplit.length + 2)
-                    || !DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length == (DiscordClient.whitelistAddPrefix.length + 2))
-            {
-                if(onlyHasLimitedAdd)
-                {
-                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Insufficient Permissions",
-                            (author.getAsMention() + ", only staff members can manually link Discord IDs. Please only enter your Minecraft name."), DiscordClient.EmbedMessageType.FAILURE).build();
-
-                    DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                    return;
+                if (onlyHasLimitedAdd) {
+                    DiscordClient.AddWhitelistRemainingCount(embedBuilderInvalidChar, timesWhitelisted);
                 }
-                else
-                {
-                    discordIdProvided = true;
+                if (onlyHasLimitedAdd) {
+                    DiscordClient.AddWhitelistRemainingCount(embedBuilderLengthInvalid, timesWhitelisted);
                 }
+
+             */
+
+            timesWhitelisted = UserList.getRegisteredUsersCount(author.getId());
+
+            // set to current max in case the max whitelist amount was changed
+            if (timesWhitelisted > DiscordClient.maxWhitelistAmount) {
+                timesWhitelisted = DiscordClient.maxWhitelistAmount;
             }
 
-            final boolean finalDiscordIdProvided = discordIdProvided;
-
-            String discordIdStripped = "";
-            if(finalDiscordIdProvided)
-            {
-                discordIdStripped = splitMessageCaseSensitive[DiscordClient.customWhitelistAddPrefixSplit.length + 1];
-                discordIdStripped = discordIdStripped.replaceAll("<@!","");
-                discordIdStripped = discordIdStripped.replaceAll(">","");
-            }
-
-            final String finalDiscordIdStripped = discordIdStripped;
-            final Member suppliedMember = (!finalDiscordIdStripped.isEmpty()) ? channel.getGuild().getMemberById(finalDiscordIdStripped) : null;
-
-            if(finalDiscordIdProvided && suppliedMember == null)
-            {
-                MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Discord ID not found in Guild or is incorrect",
-                        (author.getAsMention() + ", the ID supplied (`" + discordIdStripped + "`) could not be located in this Discord Server/Guild."),
-                                DiscordClient.EmbedMessageType.FAILURE).build();
-
-                DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                return;
-            }
-
-            // runs after member null check
-            if(finalDiscordIdProvided)
-            {
-                // Create a entry in the user list if needed for supplied id
-                if (UserList.getUserList().getString(suppliedMember.getId()) == null)
-                {
-                    UserList.getUserList().set(suppliedMember.getId(), new ArrayList<String>());
-                    UserList.SaveStore();
-                }
-            }
-
-            if (onlyHasLimitedAdd)
-            {
-                timesWhitelisted = UserList.getRegisteredUsersCount(author.getId());
-
-                // set to current max in case the max whitelist amount was changed
-                if (timesWhitelisted > DiscordClient.maxWhitelistAmount)
-                {
-                    timesWhitelisted = DiscordClient.maxWhitelistAmount;
-                }
-            }
-
-            if (onlyHasLimitedAdd && usedAllWhitelists)
-            {
-                if(!DiscordWhitelister.useCustomMessages)
-                {
+            if (usedAllWhitelists) {
+                if (!DiscordWhitelister.useCustomMessages) {
                     MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("No Whitelists Remaining", (author.getAsMention() + ", unable to whitelist. You have **" + (DiscordClient.maxWhitelistAmount - timesWhitelisted)
                             + " out of " + DiscordClient.maxWhitelistAmount + "** whitelists remaining."), DiscordClient.EmbedMessageType.INFO).build();
-                    DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                }
-                else
-                {
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
                     String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("no-whitelists-remaining-title");
                     String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("no-whitelists-remaining");
                     customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
@@ -209,419 +148,675 @@ public class CommandAdd
                     customMessage = customMessage.replaceAll("\\{MaxWhitelistAmount}", String.valueOf(DiscordClient.maxWhitelistAmount));
 
                     MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO).build();
-                    DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
                 }
 
                 return;
             }
 
-            // Command would only be executed if the prefix matched so no need to check contents just length
-            if (DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length == DiscordClient.customWhitelistAddPrefixSplit.length
-                    || !DiscordWhitelister.getUseCustomPrefixes() && splitMessageCaseSensitive.length == DiscordClient.whitelistAddPrefix.length
-                        || finalNameToAdd.isEmpty())
-            {
-                if(!DiscordClient.hideInfoCommandReplies)
-                    DiscordClient.QueueAndRemoveAfterSeconds(channel, DiscordClient.addCommandInfo);
+            DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to whitelist: " + finalNameToAdd + ", " + (DiscordClient.maxWhitelistAmount - timesWhitelisted) + " whitelists remaining");
+
+
+        } else {
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
+            return;
+        }
+
+
+
+
+        boolean alreadyOnWhitelist = false;
+
+        if (WhitelistedPlayers.usingEasyWhitelist) {
+            if (WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToAdd)) {
+                alreadyOnWhitelist = true;
             }
-            else
-            {
-                if (DiscordClient.usernameValidation)
-                {
-                    // Invalid char check
-                    for (int a = 0; a < finalNameToWhitelistChar.length; ++a)
-                    {
-                        if (new String(DiscordClient.validCharacters).indexOf(finalNameToWhitelistChar[a]) == -1)
-                        {
-                            EmbedBuilder embedBuilderInvalidChar;
+        } else if (WhitelistedPlayers.CheckForPlayer(finalNameToAdd)) {
+            alreadyOnWhitelist = true;
+        }
 
-                            if(!DiscordWhitelister.useCustomMessages)
-                            {
-                                embedBuilderInvalidChar = DiscordClient.CreateEmbeddedMessage("Invalid Username", (author.getAsMention() + ", the username you have specified contains invalid characters. **Only letters, numbers and underscores are allowed**."), DiscordClient.EmbedMessageType.FAILURE);
-                            }
-                            else
-                            {
-                                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-characters-warning-title");
-                                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-characters-warning");
-                                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+        if (alreadyOnWhitelist) {
+            if (!DiscordWhitelister.useCustomMessages) {
+                MessageEmbed messageEmbed =
+                        DiscordClient.CreateEmbeddedMessage("User already on the whitelist",
+                                (author.getAsMention() + ", cannot add user as `" + finalNameToAdd + "` is already on the whitelist!"), DiscordClient.EmbedMessageType.INFO).build();
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+            } else {
+                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("already-on-whitelist-title");
+                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("already-on-whitelist");
+                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
 
-                                embedBuilderInvalidChar = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
-                            }
+                MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO).build();
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+            }
+            return;
+        }
 
-                            if (onlyHasLimitedAdd)
-                            {
-                                DiscordClient.AddWhitelistRemainingCount(embedBuilderInvalidChar, timesWhitelisted);
-                            }
+        if (RemovedList.CheckStoreForPlayer(finalNameToAdd)) // If the user has been removed before
+        {
+            if (onlyHasLimitedAdd) {
+                EmbedBuilder embedBuilderRemovedByStaff;
 
-                            DiscordClient.QueueAndRemoveAfterSeconds(channel, embedBuilderInvalidChar.build());
-                            return;
-                        }
-                    }
+                if (!DiscordWhitelister.useCustomMessages) {
+                    embedBuilderRemovedByStaff = DiscordClient.CreateEmbeddedMessage("This user was previously removed by a staff member",
+                            (author.getAsMention() + ", this user was previously removed by a staff member (<@" + RemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ">).\n" +
+                                    "Please ask a user with higher permissions to add this user.\n"), DiscordClient.EmbedMessageType.FAILURE);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed");
+                    String staffMemberMention = "<@" + RemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ">";
 
-                    // Length check
-                    if (finalNameToAdd.length() < 3 || finalNameToAdd.length() > 16)
-                    {
-                        EmbedBuilder embedBuilderLengthInvalid;
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                    customMessage = customMessage.replaceAll("\\{StaffMember}", staffMemberMention);
 
-                        if(!DiscordWhitelister.useCustomMessages)
-                        {
-                            embedBuilderLengthInvalid = DiscordClient.CreateEmbeddedMessage("Invalid Username", (author.getAsMention() + ", the username you have specified either contains too few or too many characters. **Usernames can only consist of 3-16 characters**."), DiscordClient.EmbedMessageType.FAILURE);
-                        }
-                        else
-                        {
-                            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-length-warning-title");
-                            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-length-warning");
-                            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-
-                            embedBuilderLengthInvalid = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
-                        }
-
-                        if (onlyHasLimitedAdd)
-                        {
-                            DiscordClient.AddWhitelistRemainingCount(embedBuilderLengthInvalid, timesWhitelisted);
-                        }
-
-                        DiscordClient.QueueAndRemoveAfterSeconds(channel, embedBuilderLengthInvalid.build());
-                        return;
-                    }
+                    embedBuilderRemovedByStaff = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
                 }
 
-                if (onlyHasLimitedAdd)
-                    DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to whitelist: " + finalNameToAdd + ", " + (DiscordClient.maxWhitelistAmount - timesWhitelisted) + " whitelists remaining");
-                else
-                    DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to whitelist: " + finalNameToAdd);
+                DiscordClient.AddWhitelistRemainingCount(embedBuilderRemovedByStaff, timesWhitelisted);
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderRemovedByStaff.build());
+                return;
+            } else {
+                RemovedList.getRemovedPlayers().set(finalNameToAdd.toLowerCase(), null);
+                RemovedList.SaveStore();
 
-                boolean alreadyOnWhitelist = false;
+                DiscordWhitelister.getPlugin().getLogger().info(finalNameToAdd + " has been removed from the removed list by " + author.getName() + "(" + author.getId() + ")");
+            }
+        }
 
-                if(WhitelistedPlayers.usingEasyWhitelist)
-                {
-                    if (WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToAdd))
-                    {
-                        alreadyOnWhitelist = true;
-                    }
-                }
-                else if (WhitelistedPlayers.CheckForPlayer(finalNameToAdd))
-                {
-                    alreadyOnWhitelist = true;
-                }
+        // In-game list check
+        if (DiscordWhitelister.useInGameAddRemoves) {
+            if (InGameRemovedList.CheckStoreForPlayer(finalNameToAdd.toLowerCase())) {
+                if (onlyHasLimitedAdd) {
+                    EmbedBuilder embedBuilderRemovedByInGameStaff;
+
+                    if (!DiscordWhitelister.useCustomMessages) {
+                        embedBuilderRemovedByInGameStaff = DiscordClient.CreateEmbeddedMessage("This user was previously removed by a staff member",
+                                (author.getAsMention() + ", this user was previously removed by a staff member in-game (" + InGameRemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ").\n" +
+                                        "Please ask a user with higher permissions to add this user.\n"), DiscordClient.EmbedMessageType.FAILURE);
+                    } else {
+                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-in-game-title");
+                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-in-game");
+                        String inGameStaffMember = InGameRemovedList.getRemovedPlayers().getString(finalNameToAdd.toLowerCase());
 
-                if(alreadyOnWhitelist)
-                {
-                    if(!DiscordWhitelister.useCustomMessages)
-                    {
-                        MessageEmbed messageEmbed =
-                                DiscordClient.CreateEmbeddedMessage("User already on the whitelist",
-                                        (author.getAsMention() + ", cannot add user as `" + finalNameToAdd + "` is already on the whitelist!"), DiscordClient.EmbedMessageType.INFO).build();
-                        DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
-                    }
-                    else
-                    {
-                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("already-on-whitelist-title");
-                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("already-on-whitelist");
                         customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                        customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+                        customMessage = customMessage.replaceAll("\\{StaffMember}", inGameStaffMember);
 
-                        MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO).build();
-                        DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
+                        embedBuilderRemovedByInGameStaff = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
                     }
+
+                    DiscordClient.AddWhitelistRemainingCount(embedBuilderRemovedByInGameStaff, timesWhitelisted);
+
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderRemovedByInGameStaff.build());
                     return;
+                } else {
+                    InGameRemovedList.RemoveUserFromStore(finalNameToAdd.toLowerCase());
+
+                    DiscordWhitelister.getPlugin().getLogger().info(finalNameToAdd + " has been removed from in-game-removed-list.yml by " + author.getName() + "(" + author.getId() + ")");
                 }
-
-                if (RemovedList.CheckStoreForPlayer(finalNameToAdd)) // If the user has been removed before
-                {
-                    if (onlyHasLimitedAdd)
-                    {
-                        EmbedBuilder embedBuilderRemovedByStaff;
-
-                        if(!DiscordWhitelister.useCustomMessages)
-                        {
-                            embedBuilderRemovedByStaff = DiscordClient.CreateEmbeddedMessage("This user was previously removed by a staff member",
-                                    (author.getAsMention() + ", this user was previously removed by a staff member (<@" + RemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ">).\n" +
-                                            "Please ask a user with higher permissions to add this user.\n"), DiscordClient.EmbedMessageType.FAILURE);
-                        }
-                        else
-                        {
-                            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-title");
-                            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed");
-                            String staffMemberMention = "<@" + RemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ">";
-
-                            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                            customMessage = customMessage.replaceAll("\\{StaffMember}", staffMemberMention);
-
-                            embedBuilderRemovedByStaff = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
-                        }
-
-                        DiscordClient.AddWhitelistRemainingCount(embedBuilderRemovedByStaff, timesWhitelisted);
-                        DiscordClient.QueueAndRemoveAfterSeconds(channel, embedBuilderRemovedByStaff.build());
-                        return;
-                    }
-                    else
-                    {
-                        RemovedList.getRemovedPlayers().set(finalNameToAdd.toLowerCase(), null);
-                        RemovedList.SaveStore();
-
-                        DiscordWhitelister.getPlugin().getLogger().info(finalNameToAdd + " has been removed from the removed list by " + author.getName() + "(" + author.getId() + ")");
-                    }
-                }
-
-                // In-game list check
-                if(DiscordWhitelister.useInGameAddRemoves)
-                {
-                    if(InGameRemovedList.CheckStoreForPlayer(finalNameToAdd.toLowerCase()))
-                    {
-                        if(onlyHasLimitedAdd)
-                        {
-                            EmbedBuilder embedBuilderRemovedByInGameStaff;
-
-                            if(!DiscordWhitelister.useCustomMessages)
-                            {
-                                embedBuilderRemovedByInGameStaff = DiscordClient.CreateEmbeddedMessage("This user was previously removed by a staff member",
-                                        (author.getAsMention() + ", this user was previously removed by a staff member in-game (" + InGameRemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ").\n" +
-                                                "Please ask a user with higher permissions to add this user.\n"), DiscordClient.EmbedMessageType.FAILURE);
-                            }
-                            else
-                            {
-                                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-in-game-title");
-                                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-in-game");
-                                String inGameStaffMember = InGameRemovedList.getRemovedPlayers().getString(finalNameToAdd.toLowerCase());
-
-                                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                                customMessage = customMessage.replaceAll("\\{StaffMember}", inGameStaffMember);
-
-                                embedBuilderRemovedByInGameStaff = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
-                            }
-
-                            DiscordClient.AddWhitelistRemainingCount(embedBuilderRemovedByInGameStaff, timesWhitelisted);
-
-                            DiscordClient.QueueAndRemoveAfterSeconds(channel, embedBuilderRemovedByInGameStaff.build());
-                            return;
-                        }
-                        else
-                        {
-                            InGameRemovedList.RemoveUserFromStore(finalNameToAdd.toLowerCase());
-
-                            DiscordWhitelister.getPlugin().getLogger().info(finalNameToAdd + " has been removed from in-game-removed-list.yml by " + author.getName() + "(" + author.getId() + ")");
-                        }
-                    }
-                }
+            }
+        }
 
                 /* Do as much as possible off the main server thread.
                 convert username into UUID to avoid depreciation and rate limits (according to https://minotar.net/) */
-                String playerUUID = DiscordClient.minecraftUsernameToUUID(finalNameToAdd);
-                final boolean invalidMinecraftName = playerUUID == null;
+        String playerUUID = DiscordClient.minecraftUsernameToUUID(finalNameToAdd);
+        final boolean invalidMinecraftName = playerUUID == null;
 
                 /* Configure success & failure messages here instead of on the main server thread -
                 this will run even if the message is never sent, but is a good trade off */
-                EmbedBuilder embedBuilderWhitelistSuccess;
+        EmbedBuilder embedBuilderWhitelistSuccess;
 
-                if(!DiscordWhitelister.useCustomMessages)
-                {
-                    embedBuilderWhitelistSuccess = DiscordClient.CreateEmbeddedMessage((finalNameToAdd + " is now whitelisted!"), (author.getAsMention() + " has added `" + finalNameToAdd + "` to the whitelist.") , DiscordClient.EmbedMessageType.SUCCESS);
+        if (!DiscordWhitelister.useCustomMessages) {
+            embedBuilderWhitelistSuccess = DiscordClient.CreateEmbeddedMessage((finalNameToAdd + " is now whitelisted!"), (author.getAsMention() + " has added `" + finalNameToAdd + "` to the whitelist."), DiscordClient.EmbedMessageType.SUCCESS);
+        } else {
+            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-success-title");
+            customTitle = customTitle.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+
+            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-success");
+            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+            customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+
+            embedBuilderWhitelistSuccess = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.SUCCESS);
+        }
+
+        if (onlyHasLimitedAdd)
+            DiscordClient.AddWhitelistRemainingCount(embedBuilderWhitelistSuccess, (timesWhitelisted + 1));
+
+        if (DiscordWhitelister.showPlayerSkin) {
+            if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-crafatar-for-avatars"))
+                embedBuilderWhitelistSuccess.setThumbnail("https://minotar.net/armor/bust/" + playerUUID + "/100.png");
+            else
+                embedBuilderWhitelistSuccess.setThumbnail("https://crafatar.com/avatars/" + playerUUID + "?size=100&default=MHF_Steve&overlay.png");
+        }
+
+        EmbedBuilder embedBuilderWhitelistFailure;
+
+        if (!DiscordWhitelister.useCustomMessages) {
+            embedBuilderWhitelistFailure = DiscordClient.CreateEmbeddedMessage("Failed to whitelist",
+                    (author.getAsMention() + ", failed to add `" + finalNameToAdd + "` to the whitelist. This is most likely due to an invalid Minecraft username."), DiscordClient.EmbedMessageType.FAILURE);
+        } else {
+            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-failure-title");
+
+            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-failure");
+            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+            customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+
+            embedBuilderWhitelistFailure = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+        }
+
+        if (onlyHasLimitedAdd)
+            DiscordClient.AddWhitelistRemainingCount(embedBuilderWhitelistFailure, timesWhitelisted); // was timesWhitelisted + 1 for some reason, change back if it doesn't work correctly
+
+        int tempTimesWhitelisted = timesWhitelisted;
+        if (onlyHasLimitedAdd && tempTimesWhitelisted < DiscordClient.maxWhitelistAmount)
+            tempTimesWhitelisted = timesWhitelisted + 1;
+        final int finalTimesWhitelisted = tempTimesWhitelisted; // if successful
+
+        AtomicBoolean successfulWhitelist = new AtomicBoolean(false);
+
+        if (!WhitelistedPlayers.usingEasyWhitelist && authorPermissions.isUserCanUseCommand())
+            DiscordClient.ExecuteServerCommand("whitelist add " + finalNameToAdd);
+        if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-geyser/floodgate-compatibility")) {
+            addBedrockUser(finalNameToAdd);
+        }
+
+        // have to use !invalidMinecraftName else the easy whitelist plugin will add the name regardless of whether it is valid on not
+        if (WhitelistedPlayers.usingEasyWhitelist && !invalidMinecraftName && authorPermissions.isUserCanUseCommand())
+            DiscordClient.ExecuteServerCommand("easywl add " + finalNameToAdd);
+
+        DiscordWhitelister.getPlugin().getServer().getScheduler().callSyncMethod(DiscordWhitelister.getPlugin(), () ->
+        {
+            if (WhitelistedPlayers.usingEasyWhitelist && !invalidMinecraftName && WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToAdd)
+                    || !WhitelistedPlayers.usingEasyWhitelist && WhitelistedPlayers.CheckForPlayer(finalNameToAdd)) {
+                event.replyEmbeds(embedBuilderWhitelistSuccess.build()).queue();
+
+                // For instructional message
+                successfulWhitelist.set(true);
+
+                //Assign perms:
+                DiscordClient.AssignPerms(finalNameToAdd);
+
+                if (DiscordWhitelister.useOnWhitelistCommands) {
+                    List<String> commandsToExecute = DiscordWhitelister.onWhitelistCommandsConfig.getFileConfiguration().getStringList("on-whitelist-commands");
+                    for (String command : commandsToExecute) {
+                        DiscordClient.CheckAndExecuteCommand(command, finalNameToAdd);
+                    }
                 }
-                else
-                {
-                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-success-title");
-                    customTitle = customTitle.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
 
-                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-success");
+                if (DiscordClient.whitelistedRoleAutoAdd) {
+                    List<Role> whitelistRoles = new LinkedList<>();
+                    try {
+                        if (!DiscordWhitelister.useIdForRoles) {
+                            for (String whitelistedRoleName : DiscordClient.whitelistedRoleNames) {
+                                // Use channel, get guild instead of JDA so that it is guild specific
+                                List<Role> rolesFoundWithName = channel.getGuild().getRolesByName(whitelistedRoleName, false);
+                                whitelistRoles.addAll(rolesFoundWithName);
+                            }
+                        } else {
+                            for (String whitelistedRoleName : DiscordClient.whitelistedRoleNames) {
+                                if (channel.getGuild().getRoleById(whitelistedRoleName) != null)
+                                    whitelistRoles.add(channel.getGuild().getRoleById(whitelistedRoleName));
+                            }
+                        }
+
+                        if (!whitelistRoles.isEmpty()) {
+                            whitelistRoles.forEach(role ->
+                            {
+                                member.getGuild().addRoleToMember(suppliedMember, role).queue();
+                            });
+                        }
+                    } catch (Exception e) {
+                        DiscordWhitelister.getPlugin().getLogger().severe("Could not add role with name/id to " + suppliedMember.getEffectiveName() + ", check the config and that the bot has the Manage Roles permission");
+
+                        e.printStackTrace();
+                    }
+
+                    // Instructional message
+                    if (successfulWhitelist.get()) {
+                        if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("send-instructional-message-on-whitelist")) {
+                            if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-timer-for-instructional-message")) {
+                                event.replyEmbeds(DiscordClient.CreateInstructionalMessage()).queue();
+                            } else {
+                                int waitTime = DiscordWhitelister.mainConfig.getFileConfiguration().getInt("timer-wait-time-in-seconds");
+
+                                // Run on a new thread to not block main thread
+                                Thread whitelisterTimerThread = new Thread(() ->
+                                {
+                                    try {
+                                        TimeUnit.SECONDS.sleep(waitTime);
+                                        event.replyEmbeds(DiscordClient.CreateInstructionalMessage()).queue();
+                                    } catch (InterruptedException e) {
+                                        e.printStackTrace();
+                                    }
+                                });
+
+                                whitelisterTimerThread.start();
+                            }
+                        }
+                    }
+                }
+
+                UserList.addRegisteredUser(suppliedMember.getId(), finalNameToAdd.toLowerCase());
+
+                DiscordWhitelister.getPluginLogger().info(author.getName() + "(" + author.getId() + ") successfully added " + finalNameToAdd
+                        + " to the whitelist and linked " + finalNameToAdd + " to " + suppliedMember.getEffectiveName() + "(" + suppliedMember.getId() + ").");
+            } else {
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderWhitelistFailure.build());
+            }
+            return null;
+        });
+    }
+
+    public static void ExecuteCommand(SlashCommandEvent event, String mc_user) {
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+        TextChannel channel = event.getTextChannel();
+        Member member = event.getMember();
+
+        int timesWhitelisted =0;
+        final String finalNameToAdd = mc_user;
+        final char[] finalNameToWhitelistChar = finalNameToAdd.toLowerCase().toCharArray(); // Lower case for char check
+        boolean onlyHasLimitedAdd = false;
+        if (DiscordClient.usernameValidation) {
+            // Invalid char check
+            for (char c : finalNameToWhitelistChar) {
+                if (new String(DiscordClient.validCharacters).indexOf(c) == -1) {
+                    EmbedBuilder embedBuilderInvalidChar;
+
+                    if (!DiscordWhitelister.useCustomMessages) {
+                        embedBuilderInvalidChar = DiscordClient.CreateEmbeddedMessage("Invalid Username", (author.getAsMention() + ", the username you have specified contains invalid characters. **Only letters, numbers and underscores are allowed**."), DiscordClient.EmbedMessageType.FAILURE);
+                    } else {
+                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-characters-warning-title");
+                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-characters-warning");
+                        customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+
+                        embedBuilderInvalidChar = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+                    }
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderInvalidChar.build());
+                    return;
+                }
+            }
+
+            // Length check
+            if (finalNameToAdd.length() < 3 || finalNameToAdd.length() > 16) {
+                EmbedBuilder embedBuilderLengthInvalid;
+
+                if (!DiscordWhitelister.useCustomMessages) {
+                    embedBuilderLengthInvalid = DiscordClient.CreateEmbeddedMessage("Invalid Username", (author.getAsMention() + ", the username you have specified either contains too few or too many characters. **Usernames can only consist of 3-16 characters**."), DiscordClient.EmbedMessageType.FAILURE);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-length-warning-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("invalid-length-warning");
                     customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                    customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
 
-                    embedBuilderWhitelistSuccess = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.SUCCESS);
+                    embedBuilderLengthInvalid = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
                 }
-
-                if (onlyHasLimitedAdd)
-                    DiscordClient.AddWhitelistRemainingCount(embedBuilderWhitelistSuccess, (timesWhitelisted + 1));
-
-                if(DiscordWhitelister.showPlayerSkin)
-                {
-                    if(!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-crafatar-for-avatars"))
-                        embedBuilderWhitelistSuccess.setThumbnail("https://minotar.net/armor/bust/" + playerUUID + "/100.png");
-                    else
-                        embedBuilderWhitelistSuccess.setThumbnail("https://crafatar.com/avatars/" + playerUUID + "?size=100&default=MHF_Steve&overlay.png");
-                }
-
-                EmbedBuilder embedBuilderWhitelistFailure;
-
-                if(!DiscordWhitelister.useCustomMessages)
-                {
-                    embedBuilderWhitelistFailure = DiscordClient.CreateEmbeddedMessage("Failed to whitelist",
-                            (author.getAsMention() + ", failed to add `" + finalNameToAdd + "` to the whitelist. This is most likely due to an invalid Minecraft username."), DiscordClient.EmbedMessageType.FAILURE);
-                }
-                else
-                {
-                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-failure-title");
-
-                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-failure");
-                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
-                    customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
-
-                    embedBuilderWhitelistFailure = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
-                }
-
-                if (onlyHasLimitedAdd)
-                    DiscordClient.AddWhitelistRemainingCount(embedBuilderWhitelistFailure, timesWhitelisted); // was timesWhitelisted + 1 for some reason, change back if it doesn't work correctly
-
-                int tempTimesWhitelisted = timesWhitelisted;
-                if (onlyHasLimitedAdd && tempTimesWhitelisted < DiscordClient.maxWhitelistAmount)
-                    tempTimesWhitelisted = timesWhitelisted + 1;
-                final int finalTimesWhitelisted = tempTimesWhitelisted; // if successful
-
-                AtomicBoolean successfulWhitelist = new AtomicBoolean(false);
-
-                if (!WhitelistedPlayers.usingEasyWhitelist && authorPermissions.isUserCanUseCommand())
-                    DiscordClient.ExecuteServerCommand("whitelist add " + finalNameToAdd);
-                    if(DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-geyser/floodgate-compatibility")) {
-                        addBedrockUser(finalNameToAdd);
-                    }
-
-                // have to use !invalidMinecraftName else the easy whitelist plugin will add the name regardless of whether it is valid on not
-                if (WhitelistedPlayers.usingEasyWhitelist && !invalidMinecraftName && authorPermissions.isUserCanUseCommand())
-                    DiscordClient.ExecuteServerCommand("easywl add " + finalNameToAdd);
-
-                DiscordWhitelister.getPlugin().getServer().getScheduler().callSyncMethod(DiscordWhitelister.getPlugin(), () ->
-                {
-                    if(WhitelistedPlayers.usingEasyWhitelist && !invalidMinecraftName && WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToAdd)
-                            || !WhitelistedPlayers.usingEasyWhitelist && WhitelistedPlayers.CheckForPlayer(finalNameToAdd))
-                    {
-                        channel.sendMessage(embedBuilderWhitelistSuccess.build()).queue();
-
-                        // For instructional message
-                        successfulWhitelist.set(true);
-
-                        //Assign perms:
-                        DiscordClient.AssignPerms(finalNameToAdd);
-
-                        if(DiscordWhitelister.useOnWhitelistCommands)
-                        {
-                            List<String> commandsToExecute = DiscordWhitelister.onWhitelistCommandsConfig.getFileConfiguration().getStringList("on-whitelist-commands");
-                            for (String command : commandsToExecute)
-                            {
-                                DiscordClient.CheckAndExecuteCommand(command, finalNameToAdd);
-                            }
-                        }
-
-                        if(DiscordClient.whitelistedRoleAutoAdd)
-                        {
-                            List<Role> whitelistRoles = new LinkedList<>();
-                            try
-                            {
-                                if(!DiscordWhitelister.useIdForRoles)
-                                {
-                                    for (String whitelistedRoleName : DiscordClient.whitelistedRoleNames)
-                                    {
-                                        // Use channel, get guild instead of JDA so that it is guild specific
-                                        List<Role> rolesFoundWithName = channel.getGuild().getRolesByName(whitelistedRoleName, false);
-                                        whitelistRoles.addAll(rolesFoundWithName);
-                                    }
-                                }
-                                else
-                                {
-                                    for (String whitelistedRoleName : DiscordClient.whitelistedRoleNames)
-                                    {
-                                        if (channel.getGuild().getRoleById(whitelistedRoleName) != null)
-                                            whitelistRoles.add(channel.getGuild().getRoleById(whitelistedRoleName));
-                                    }
-                                }
-
-                                if(!whitelistRoles.isEmpty())
-                                {
-                                    if(!finalDiscordIdProvided)
-                                    {
-                                        whitelistRoles.forEach(role ->
-                                        {
-                                            member.getGuild().addRoleToMember(member, role).queue();
-                                        });
-                                    }
-                                    else
-                                    {
-                                        whitelistRoles.forEach(role ->
-                                        {
-                                            member.getGuild().addRoleToMember(suppliedMember, role).queue();
-                                        });
-                                    }
-                                }
-                            }
-                            catch (Exception e)
-                            {
-                                if(!finalDiscordIdProvided)
-                                    DiscordWhitelister.getPlugin().getLogger().severe("Could not add role with name/id to " + author.getName() + ", check the config and that the bot has the Manage Roles permission");
-                                else
-                                    DiscordWhitelister.getPlugin().getLogger().severe("Could not add role with name/id to " + suppliedMember.getEffectiveName() + ", check the config and that the bot has the Manage Roles permission");
-
-                                e.printStackTrace();
-                            }
-
-                            // Instructional message
-                            if(successfulWhitelist.get())
-                            {
-                                if(DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("send-instructional-message-on-whitelist"))
-                                {
-                                    if(!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-timer-for-instructional-message"))
-                                    {
-                                        channel.sendMessage(DiscordClient.CreateInstructionalMessage()).queue();
-                                    }
-                                    else
-                                    {
-                                        int waitTime = DiscordWhitelister.mainConfig.getFileConfiguration().getInt("timer-wait-time-in-seconds");
-
-                                        // Run on a new thread to not block main thread
-                                        Thread whitelisterTimerThread = new Thread(() ->
-                                        {
-                                            try
-                                            {
-                                                TimeUnit.SECONDS.sleep(waitTime);
-                                                channel.sendMessage(DiscordClient.CreateInstructionalMessage()).queue();
-                                            }
-                                            catch (InterruptedException e)
-                                            {
-                                                e.printStackTrace();
-                                            }
-                                        });
-
-                                        whitelisterTimerThread.start();
-                                    }
-                                }
-                            }
-                        }
-
-                        if (onlyHasLimitedAdd || finalDiscordIdProvided)
-                        {
-                            if(!finalDiscordIdProvided)
-                            {
-                                UserList.addRegisteredUser(author.getId(), finalNameToAdd.toLowerCase()); // convert to lower case for remove & clearname commands
-                            }
-                            else
-                            {
-                                UserList.addRegisteredUser(suppliedMember.getId(), finalNameToAdd.toLowerCase());
-                            }
-
-                            if(!finalDiscordIdProvided)
-                                DiscordWhitelister.getPluginLogger().info(author.getName() + "(" + author.getId() + ") successfully added " + finalNameToAdd
-                                        + " to the whitelist, " + (DiscordClient.maxWhitelistAmount - finalTimesWhitelisted) + " whitelists remaining.");
-                            else
-                                DiscordWhitelister.getPluginLogger().info(author.getName() + "(" + author.getId() + ") successfully added " + finalNameToAdd
-                                        + " to the whitelist and linked " + finalNameToAdd + " to "+ suppliedMember.getEffectiveName() + "(" + suppliedMember.getId() + ").");
-                        }
-                    }
-                    else
-                    {
-                        DiscordClient.QueueAndRemoveAfterSeconds(channel, embedBuilderWhitelistFailure.build());
-                    }
-                    return null;
-                });
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderLengthInvalid.build());
+                return;
             }
         }
+
+        if (authorPermissions.isUserCanAddRemove() || authorPermissions.isUserCanAdd()) {
+
+
+            // runs after member null check
+
+            DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to whitelist: " + finalNameToAdd);
+
+        } else if (authorPermissions.isUserHasLimitedAdd() && DiscordClient.limitedWhitelistEnabled) {
+            onlyHasLimitedAdd = true;
+            if (DiscordWhitelister.useOnBanEvents && authorPermissions.isUserIsBanned()) {
+                if (!DiscordWhitelister.useCustomMessages) {
+                    MessageEmbed messageEmbed =
+                            DiscordClient.CreateEmbeddedMessage("You have been banned!", (author.getAsMention() + ", you cannot use this bot as you have been banned!"), DiscordClient.EmbedMessageType.FAILURE).build();
+
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("banned-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("banned-message");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention()); // Only checking for {Sender}
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+                return;
+            }
+                /* if limited whitelist is enabled, check if the user is in the limited whitelister group and add the user to the list
+                which records how many times the user has successfully used the whitelist command */
+            if (UserList.getUserList().getString(author.getId()) == null) {
+                UserList.getUserList().set(author.getId(), new ArrayList<String>());
+                UserList.SaveStore();
+            }
+            boolean usedAllWhitelists = false;
+            try {
+                usedAllWhitelists = UserList.getRegisteredUsersCount(author.getId()) >= DiscordClient.maxWhitelistAmount &&
+                        !authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd();
+            } catch (NullPointerException exception) {
+                exception.printStackTrace();
+            }
+            /*
+            todo:add this
+            MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Insufficient Permissions",
+                        (author.getAsMention() + ", only staff members can manually link Discord IDs. Please only enter your Minecraft name."), DiscordClient.EmbedMessageType.FAILURE).build();
+
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                return;
+
+                if (onlyHasLimitedAdd) {
+                    DiscordClient.AddWhitelistRemainingCount(embedBuilderInvalidChar, timesWhitelisted);
+                }
+                if (onlyHasLimitedAdd) {
+                    DiscordClient.AddWhitelistRemainingCount(embedBuilderLengthInvalid, timesWhitelisted);
+                }
+
+             */
+
+            timesWhitelisted = UserList.getRegisteredUsersCount(author.getId());
+
+            // set to current max in case the max whitelist amount was changed
+            if (timesWhitelisted > DiscordClient.maxWhitelistAmount) {
+                timesWhitelisted = DiscordClient.maxWhitelistAmount;
+            }
+
+            if (usedAllWhitelists) {
+                if (!DiscordWhitelister.useCustomMessages) {
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("No Whitelists Remaining", (author.getAsMention() + ", unable to whitelist. You have **" + (DiscordClient.maxWhitelistAmount - timesWhitelisted)
+                            + " out of " + DiscordClient.maxWhitelistAmount + "** whitelists remaining."), DiscordClient.EmbedMessageType.INFO).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("no-whitelists-remaining-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("no-whitelists-remaining");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                    customMessage = customMessage.replaceAll("\\{RemainingWhitelists}", String.valueOf((DiscordClient.maxWhitelistAmount - timesWhitelisted)));
+                    customMessage = customMessage.replaceAll("\\{MaxWhitelistAmount}", String.valueOf(DiscordClient.maxWhitelistAmount));
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+
+                return;
+            }
+
+            DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to whitelist: " + finalNameToAdd + ", " + (DiscordClient.maxWhitelistAmount - timesWhitelisted) + " whitelists remaining");
+
+
+        } else {
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
+            return;
+        }
+
+
+
+
+        boolean alreadyOnWhitelist = false;
+
+        if (WhitelistedPlayers.usingEasyWhitelist) {
+            if (WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToAdd)) {
+                alreadyOnWhitelist = true;
+            }
+        } else if (WhitelistedPlayers.CheckForPlayer(finalNameToAdd)) {
+            alreadyOnWhitelist = true;
+        }
+
+        if (alreadyOnWhitelist) {
+            if (!DiscordWhitelister.useCustomMessages) {
+                MessageEmbed messageEmbed =
+                        DiscordClient.CreateEmbeddedMessage("User already on the whitelist",
+                                (author.getAsMention() + ", cannot add user as `" + finalNameToAdd + "` is already on the whitelist!"), DiscordClient.EmbedMessageType.INFO).build();
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+            } else {
+                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("already-on-whitelist-title");
+                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("already-on-whitelist");
+                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+
+                MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO).build();
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+            }
+            return;
+        }
+
+        if (RemovedList.CheckStoreForPlayer(finalNameToAdd)) // If the user has been removed before
+        {
+            if (onlyHasLimitedAdd) {
+                EmbedBuilder embedBuilderRemovedByStaff;
+
+                if (!DiscordWhitelister.useCustomMessages) {
+                    embedBuilderRemovedByStaff = DiscordClient.CreateEmbeddedMessage("This user was previously removed by a staff member",
+                            (author.getAsMention() + ", this user was previously removed by a staff member (<@" + RemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ">).\n" +
+                                    "Please ask a user with higher permissions to add this user.\n"), DiscordClient.EmbedMessageType.FAILURE);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed");
+                    String staffMemberMention = "<@" + RemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ">";
+
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                    customMessage = customMessage.replaceAll("\\{StaffMember}", staffMemberMention);
+
+                    embedBuilderRemovedByStaff = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+                }
+
+                DiscordClient.AddWhitelistRemainingCount(embedBuilderRemovedByStaff, timesWhitelisted);
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderRemovedByStaff.build());
+                return;
+            } else {
+                RemovedList.getRemovedPlayers().set(finalNameToAdd.toLowerCase(), null);
+                RemovedList.SaveStore();
+
+                DiscordWhitelister.getPlugin().getLogger().info(finalNameToAdd + " has been removed from the removed list by " + author.getName() + "(" + author.getId() + ")");
+            }
+        }
+
+        // In-game list check
+        if (DiscordWhitelister.useInGameAddRemoves) {
+            if (InGameRemovedList.CheckStoreForPlayer(finalNameToAdd.toLowerCase())) {
+                if (onlyHasLimitedAdd) {
+                    EmbedBuilder embedBuilderRemovedByInGameStaff;
+
+                    if (!DiscordWhitelister.useCustomMessages) {
+                        embedBuilderRemovedByInGameStaff = DiscordClient.CreateEmbeddedMessage("This user was previously removed by a staff member",
+                                (author.getAsMention() + ", this user was previously removed by a staff member in-game (" + InGameRemovedList.getRemovedPlayers().get(finalNameToAdd.toLowerCase()) + ").\n" +
+                                        "Please ask a user with higher permissions to add this user.\n"), DiscordClient.EmbedMessageType.FAILURE);
+                    } else {
+                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-in-game-title");
+                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-was-removed-in-game");
+                        String inGameStaffMember = InGameRemovedList.getRemovedPlayers().getString(finalNameToAdd.toLowerCase());
+
+                        customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                        customMessage = customMessage.replaceAll("\\{StaffMember}", inGameStaffMember);
+
+                        embedBuilderRemovedByInGameStaff = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+                    }
+
+                    DiscordClient.AddWhitelistRemainingCount(embedBuilderRemovedByInGameStaff, timesWhitelisted);
+
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderRemovedByInGameStaff.build());
+                    return;
+                } else {
+                    InGameRemovedList.RemoveUserFromStore(finalNameToAdd.toLowerCase());
+
+                    DiscordWhitelister.getPlugin().getLogger().info(finalNameToAdd + " has been removed from in-game-removed-list.yml by " + author.getName() + "(" + author.getId() + ")");
+                }
+            }
+        }
+
+                /* Do as much as possible off the main server thread.
+                convert username into UUID to avoid depreciation and rate limits (according to https://minotar.net/) */
+        String playerUUID = DiscordClient.minecraftUsernameToUUID(finalNameToAdd);
+        final boolean invalidMinecraftName = playerUUID == null;
+
+                /* Configure success & failure messages here instead of on the main server thread -
+                this will run even if the message is never sent, but is a good trade off */
+        EmbedBuilder embedBuilderWhitelistSuccess;
+
+        if (!DiscordWhitelister.useCustomMessages) {
+            embedBuilderWhitelistSuccess = DiscordClient.CreateEmbeddedMessage((finalNameToAdd + " is now whitelisted!"), (author.getAsMention() + " has added `" + finalNameToAdd + "` to the whitelist."), DiscordClient.EmbedMessageType.SUCCESS);
+        } else {
+            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-success-title");
+            customTitle = customTitle.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+
+            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-success");
+            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+            customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+
+            embedBuilderWhitelistSuccess = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.SUCCESS);
+        }
+
+        if (onlyHasLimitedAdd)
+            DiscordClient.AddWhitelistRemainingCount(embedBuilderWhitelistSuccess, (timesWhitelisted + 1));
+
+        if (DiscordWhitelister.showPlayerSkin) {
+            if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-crafatar-for-avatars"))
+                embedBuilderWhitelistSuccess.setThumbnail("https://minotar.net/armor/bust/" + playerUUID + "/100.png");
+            else
+                embedBuilderWhitelistSuccess.setThumbnail("https://crafatar.com/avatars/" + playerUUID + "?size=100&default=MHF_Steve&overlay.png");
+        }
+
+        EmbedBuilder embedBuilderWhitelistFailure;
+
+        if (!DiscordWhitelister.useCustomMessages) {
+            embedBuilderWhitelistFailure = DiscordClient.CreateEmbeddedMessage("Failed to whitelist",
+                    (author.getAsMention() + ", failed to add `" + finalNameToAdd + "` to the whitelist. This is most likely due to an invalid Minecraft username."), DiscordClient.EmbedMessageType.FAILURE);
+        } else {
+            String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-failure-title");
+
+            String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-failure");
+            customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+            customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToAdd);
+
+            embedBuilderWhitelistFailure = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+        }
+
+        if (onlyHasLimitedAdd)
+            DiscordClient.AddWhitelistRemainingCount(embedBuilderWhitelistFailure, timesWhitelisted); // was timesWhitelisted + 1 for some reason, change back if it doesn't work correctly
+
+        int tempTimesWhitelisted = timesWhitelisted;
+        if (onlyHasLimitedAdd && tempTimesWhitelisted < DiscordClient.maxWhitelistAmount)
+            tempTimesWhitelisted = timesWhitelisted + 1;
+        final int finalTimesWhitelisted = tempTimesWhitelisted; // if successful
+
+        AtomicBoolean successfulWhitelist = new AtomicBoolean(false);
+
+        if (!WhitelistedPlayers.usingEasyWhitelist && authorPermissions.isUserCanUseCommand())
+            DiscordClient.ExecuteServerCommand("whitelist add " + finalNameToAdd);
+        if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-geyser/floodgate-compatibility")) {
+            addBedrockUser(finalNameToAdd);
+        }
+
+        // have to use !invalidMinecraftName else the easy whitelist plugin will add the name regardless of whether it is valid on not
+        if (WhitelistedPlayers.usingEasyWhitelist && !invalidMinecraftName && authorPermissions.isUserCanUseCommand())
+            DiscordClient.ExecuteServerCommand("easywl add " + finalNameToAdd);
+
+        boolean finalOnlyHasLimitedAdd = onlyHasLimitedAdd;
+        DiscordWhitelister.getPlugin().getServer().getScheduler().callSyncMethod(DiscordWhitelister.getPlugin(), () ->
+        {
+            if (WhitelistedPlayers.usingEasyWhitelist && !invalidMinecraftName && WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToAdd)
+                    || !WhitelistedPlayers.usingEasyWhitelist && WhitelistedPlayers.CheckForPlayer(finalNameToAdd)) {
+                event.replyEmbeds(embedBuilderWhitelistSuccess.build()).queue();
+
+                // For instructional message
+                successfulWhitelist.set(true);
+
+                //Assign perms:
+                DiscordClient.AssignPerms(finalNameToAdd);
+
+                if (DiscordWhitelister.useOnWhitelistCommands) {
+                    List<String> commandsToExecute = DiscordWhitelister.onWhitelistCommandsConfig.getFileConfiguration().getStringList("on-whitelist-commands");
+                    for (String command : commandsToExecute) {
+                        DiscordClient.CheckAndExecuteCommand(command, finalNameToAdd);
+                    }
+                }
+
+                if (DiscordClient.whitelistedRoleAutoAdd) {
+                    List<Role> whitelistRoles = new LinkedList<>();
+                    try {
+                        if (!DiscordWhitelister.useIdForRoles) {
+                            for (String whitelistedRoleName : DiscordClient.whitelistedRoleNames) {
+                                // Use channel, get guild instead of JDA so that it is guild specific
+                                List<Role> rolesFoundWithName = channel.getGuild().getRolesByName(whitelistedRoleName, false);
+                                whitelistRoles.addAll(rolesFoundWithName);
+                            }
+                        } else {
+                            for (String whitelistedRoleName : DiscordClient.whitelistedRoleNames) {
+                                if (channel.getGuild().getRoleById(whitelistedRoleName) != null)
+                                    whitelistRoles.add(channel.getGuild().getRoleById(whitelistedRoleName));
+                            }
+                        }
+
+                        if (!whitelistRoles.isEmpty()) {
+                            whitelistRoles.forEach(role ->
+                            {
+                                member.getGuild().addRoleToMember(member, role).queue();
+                            });
+                        }
+                    } catch (Exception e) {
+                        DiscordWhitelister.getPlugin().getLogger().severe("Could not add role with name/id to " + author.getName() + ", check the config and that the bot has the Manage Roles permission");
+
+                        e.printStackTrace();
+                    }
+
+                    // Instructional message
+                    if (successfulWhitelist.get()) {
+                        if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("send-instructional-message-on-whitelist")) {
+                            if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-timer-for-instructional-message")) {
+                                channel.sendMessageEmbeds(DiscordClient.CreateInstructionalMessage()).queue();
+                            } else {
+                                int waitTime = DiscordWhitelister.mainConfig.getFileConfiguration().getInt("timer-wait-time-in-seconds");
+
+                                // Run on a new thread to not block main thread
+                                Thread whitelisterTimerThread = new Thread(() ->
+                                {
+                                    try {
+                                        TimeUnit.SECONDS.sleep(waitTime);
+                                        channel.sendMessageEmbeds(DiscordClient.CreateInstructionalMessage()).queue();
+                                    } catch (InterruptedException e) {
+                                        e.printStackTrace();
+                                    }
+                                });
+
+                                whitelisterTimerThread.start();
+                            }
+                        }
+                    }
+                }
+
+                if (finalOnlyHasLimitedAdd) {
+                    UserList.addRegisteredUser(author.getId(), finalNameToAdd.toLowerCase()); // convert to lower case for remove & clearname commands
+
+                    DiscordWhitelister.getPluginLogger().info(author.getName() + "(" + author.getId() + ") successfully added " + finalNameToAdd
+                            + " to the whitelist, " + (DiscordClient.maxWhitelistAmount - finalTimesWhitelisted) + " whitelists remaining.");
+                }
+            } else {
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderWhitelistFailure.build());
+            }
+            return null;
+        });
     }
 
     private static void addBedrockUser(String finalNameToAdd) {
         String bedrockPrefix = DiscordWhitelister.mainConfig.getFileConfiguration().getString("geyser/floodgate prefix");
         String bedrockName = bedrockPrefix + finalNameToAdd;
-        if(bedrockName.length() > 16) {
+        if (bedrockName.length() > 16) {
             bedrockName = bedrockName.substring(0, 16);
         }
         //check if we actually NEED to add
-        if(finalNameToAdd.length() < bedrockPrefix.length() || !finalNameToAdd.substring(0, bedrockPrefix.length() - 1).equals(bedrockPrefix)) {
+        if (finalNameToAdd.length() < bedrockPrefix.length() || !finalNameToAdd.substring(0, bedrockPrefix.length() - 1).equals(bedrockPrefix)) {
             DiscordClient.ExecuteServerCommand("whitelist add " + bedrockName);
         }
     }
-}
+
+    private static boolean checkMcUsername(String nameToCheck) {
+        if (DiscordClient.usernameValidation) {
+            // Length check
+            if (nameToCheck.length() < 3 || nameToCheck.length() > 16) {
+                return false;
+            }
+            // Invalid char check
+            for (char c : nameToCheck.toCharArray()) {
+                if (new String(DiscordClient.validCharacters).indexOf(c) == -1) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClear.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClear.java
new file mode 100644
index 0000000..426b693
--- /dev/null
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClear.java
@@ -0,0 +1,119 @@
+package uk.co.angrybee.joe.commands.discord;
+
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import uk.co.angrybee.joe.AuthorPermissions;
+import uk.co.angrybee.joe.DiscordClient;
+import uk.co.angrybee.joe.DiscordWhitelister;
+import uk.co.angrybee.joe.stores.UserList;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+public class CommandClear {
+    public static void ExecuteCommand(SlashCommandEvent event) {
+        // Clear whitelists for limited-whitelisters
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+        TextChannel channel = event.getTextChannel();
+
+        if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("allow-limited-whitelisters-to-unwhitelist-self")) {
+            MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("This Command is disabled",
+                    "If staff members need to clear a name from the whitelist please use `/clearname <mcName>`.", DiscordClient.EmbedMessageType.INFO).build();
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+            return;
+        }
+        // just inform staff, can add custom messages later if really needed
+        if (authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserIsBanned() || authorPermissions.isUserCanAdd() && !authorPermissions.isUserIsBanned()) {
+            MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("This Command is Only Available for Limited Whitelister Roles",
+                    "If staff members need to clear a name from the whitelist please use `/clearname <mcName>`.", DiscordClient.EmbedMessageType.INFO).build();
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+            return;
+        }
+
+        if (authorPermissions.isUserHasLimitedAdd() && !authorPermissions.isUserIsBanned()) {
+            List<?> ls = UserList.getRegisteredUsers(author.getId());
+
+            // check for names whitelisted
+            if (ls != null) {
+                for (Object minecraftNameToRemove : ls) {
+                    DiscordClient.UnWhitelist(minecraftNameToRemove.toString());
+                }
+
+                try {
+                    UserList.resetRegisteredUsers(author.getId());
+                } catch (IOException e) {
+                    DiscordWhitelister.getPluginLogger().severe("Failed to remove" + author.getId() + "'s entries.");
+                    e.printStackTrace();
+                    return;
+                }
+
+                DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") triggered whitelist clear. " +
+                        "Successfully removed their whitelisted entries from the user list.");
+
+                // Log in Discord channel
+                if (!DiscordWhitelister.useCustomMessages) {
+                    StringBuilder message = new StringBuilder(author.getAsMention() + " successfully removed the following users from the whitelist: \n");
+                    for (Object minercaftName : ls) {
+                        message.append("- ").append(minercaftName.toString()).append("\n");
+                    }
+                    message.append("\n You now have **").append(DiscordClient.maxWhitelistAmount).append(" whitelist(s) remaining**.");
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(("Successfully Removed " + author.getName() + "'s Whitelisted Entries"),
+                            message.toString(), DiscordClient.EmbedMessageType.FAILURE).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-success-title");
+                    customTitle = customTitle.replaceAll("\\{Sender}", author.getName());
+
+                    StringBuilder removedNames = new StringBuilder();
+                    for (Object minercaftName : ls) {
+                        removedNames.append("- ").append(minercaftName.toString()).append("\n");
+                    }
+
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-success-message");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                    customMessage = customMessage.replaceAll("\\{RemovedEntries}", removedNames.toString());
+                    customMessage = customMessage.replaceAll("\\{MaxWhitelistAmount}", String.valueOf(DiscordClient.maxWhitelistAmount));
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.SUCCESS).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+
+                if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("whitelisted-role-auto-remove")) {
+                    // Find all servers bot is in, remove whitelisted roles
+                    for (int i = 0; i < DiscordClient.javaDiscordAPI.getGuilds().size(); i++) {
+                        // Remove the whitelisted role(s)
+                        DiscordClient.RemoveRolesFromUser(DiscordClient.javaDiscordAPI.getGuilds().get(i), author.getId(), Arrays.asList(DiscordClient.whitelistedRoleNames));
+                    }
+                }
+            } else {
+                DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") triggered whitelist clear. " +
+                        "Could not remove any whitelisted entries as they do not have any.");
+
+                // Log in Discord channel
+                if (!DiscordWhitelister.useCustomMessages) {
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("No Entries to Remove",
+                            (author.getAsMention() + ", you do not have any whitelisted entries to remove."), DiscordClient.EmbedMessageType.FAILURE).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-failure-title");
+                    String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("whitelist-clear-failure-message");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+            }
+            return;
+        }
+
+        if (!authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd() && !authorPermissions.isUserHasLimitedAdd() || authorPermissions.isUserIsBanned()) {
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearban.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearban.java
new file mode 100644
index 0000000..fe8a6dc
--- /dev/null
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearban.java
@@ -0,0 +1,101 @@
+package uk.co.angrybee.joe.commands.discord;
+
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import uk.co.angrybee.joe.AuthorPermissions;
+import uk.co.angrybee.joe.DiscordClient;
+import uk.co.angrybee.joe.DiscordWhitelister;
+import uk.co.angrybee.joe.stores.InGameRemovedList;
+import uk.co.angrybee.joe.stores.RemovedList;
+
+public class CommandClearban {
+    public static void ExecuteCommand(SlashCommandEvent event, String mc_user) {
+
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+        TextChannel channel = event.getTextChannel();
+
+
+        if (authorPermissions.isUserCanUseClear()) {
+            // Check if empty command
+/*
+                if (!hideInfoCommandReplies) {
+                    return;
+                }
+
+                // Send info message
+                if (!DiscordWhitelister.getUseCustomPrefixes()) {
+                    MessageEmbed messageEmbed = CreateEmbeddedMessage("Clear Ban Command", "Usage: `!clearban <minecraftUsername>`\n", DiscordClient.EmbedMessageType.INFO).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    MessageEmbed messageEmbed = CreateEmbeddedMessage("Clear Ban Command", "Usage: `" + customClearBanPrefix + " <minecraftUsername>`\n", DiscordClient.EmbedMessageType.INFO).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+
+                return;
+*/
+
+            // If command is not empty check for args
+            // String[] splitMessage = messageContents.toLowerCase().trim().split(" ");
+
+            // Check both removed lists for target name
+            boolean nameFoundInLists = false;
+
+            // Remove name from removed list if found
+            if (RemovedList.CheckStoreForPlayer(mc_user)) {
+                RemovedList.getRemovedPlayers().set(mc_user, null);
+                RemovedList.SaveStore();
+
+                nameFoundInLists = true;
+            }
+
+            if (InGameRemovedList.CheckStoreForPlayer(mc_user)) {
+                InGameRemovedList.RemoveUserFromStore(mc_user);
+
+                nameFoundInLists = true;
+            }
+
+            if (nameFoundInLists) {
+
+                if (!DiscordWhitelister.useCustomMessages) {
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(("Successfully Cleared `" + mc_user + "`"),
+                            (author.getAsMention() + " has successfully cleared `" + mc_user + "` from the removed list(s)."), DiscordClient.EmbedMessageType.SUCCESS).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    String customTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-success-title");
+                    String customMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-success-message");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                    customMessage = customMessage.replaceAll("\\{MinecraftUsername}", mc_user);
+                    customTitle = customTitle.replaceAll("\\{MinecraftUsername}", mc_user);
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+
+            } else {
+                if (!DiscordWhitelister.useCustomMessages) {
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(("Failed to Clear `" + mc_user + "`"),
+                            (author.getAsMention() + ", `" + mc_user + "` cannot be found in any of the removed lists!"), DiscordClient.EmbedMessageType.FAILURE).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                } else {
+                    String customTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-failure-title");
+                    String customMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-ban-failure-message");
+                    customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                    customMessage = customMessage.replaceAll("\\{MinecraftUsername}", mc_user);
+                    customTitle = customTitle.replaceAll("\\{MinecraftUsername}", mc_user);
+
+                    MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                }
+
+            }
+        } else {
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
+        }
+    }
+}
+
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearname.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearname.java
new file mode 100644
index 0000000..dce318e
--- /dev/null
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandClearname.java
@@ -0,0 +1,120 @@
+package uk.co.angrybee.joe.commands.discord;
+
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import uk.co.angrybee.joe.AuthorPermissions;
+import uk.co.angrybee.joe.DiscordClient;
+import uk.co.angrybee.joe.DiscordWhitelister;
+import uk.co.angrybee.joe.stores.UserList;
+
+import java.util.List;
+import java.util.Set;
+
+public class CommandClearname {
+    public static void ExecuteCommand(SlashCommandEvent event, String mc_name) {
+
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+
+        // Clear Whitelists command
+        // /clearname <targetName>
+
+
+        // Check permissions
+        if (!authorPermissions.isUserCanUseClear()) {
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
+            return;
+        }  // Don't have permission
+
+
+
+        /*
+                if (DiscordClient.hideInfoCommandReplies) {
+            return;
+        }
+        MessageEmbed messageEmbed;
+
+        if (!DiscordWhitelister.getUseCustomPrefixes()) {
+            messageEmbed = DiscordClient.CreateEmbeddedMessage("Clear Name Command", "Usage: `/clearname <minecraftUsername>`\n", DiscordClient.EmbedMessageType.INFO).build();
+        } else {
+            messageEmbed = DiscordClient.CreateEmbeddedMessage("Clear Name Command", "Usage: `" + DiscordClient.customClearNamePrefix + " <minecraftUsername>`\n", DiscordClient.EmbedMessageType.INFO).build();
+        }
+        DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+
+        return;
+*/
+
+
+        DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to clear " + mc_name + " from the whitelist");
+
+        // Search for target name & linked ID
+        boolean nameFound = false;
+        String targetDiscordId = "";
+        Set<String> keys = UserList.getUserList().getKeys(false);
+        // Make sure the user list is not empty
+        if (keys.size() > 0) {
+            for (String userid : keys) {
+                List<?> registeredUsers = UserList.getRegisteredUsers(userid);
+                if (registeredUsers.contains(mc_name)) {
+                    nameFound = true;
+                    targetDiscordId = userid;
+                    if (registeredUsers.size() > 1) {
+                        registeredUsers.remove(mc_name); // Clear name
+                        // Set the updated list in the config
+                        UserList.getUserList().set(userid, registeredUsers);
+                    } else { // Remove entirely
+
+                        UserList.getUserList().set(userid, null);
+                    }
+                    UserList.SaveStore();
+                    if (DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("unwhitelist-and-clear-perms-on-name-clear")) {
+                        // Remove name from the whitelist
+                        DiscordClient.UnWhitelist(mc_name);
+                    }
+                    break;
+                }
+            }
+        }
+        MessageEmbed messageEmbed;
+        if (nameFound) {
+            // Success message
+            if (DiscordWhitelister.useCustomMessages) {
+                String clearNameTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-success-title");
+                String clearNameMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-success-message");
+
+                clearNameMessage = clearNameMessage.replaceAll("\\{Sender}", author.getAsMention());
+                clearNameMessage = clearNameMessage.replaceAll("\\{MinecraftUsername}", mc_name);
+                clearNameMessage = clearNameMessage.replaceAll("\\{DiscordID}", "<@" + targetDiscordId + ">");
+
+                clearNameTitle = clearNameTitle.replaceAll("\\{MinecraftUsername}", mc_name);
+                messageEmbed = DiscordClient.CreateEmbeddedMessage(clearNameTitle, clearNameMessage, DiscordClient.EmbedMessageType.SUCCESS).build();
+            } else {
+                messageEmbed = DiscordClient.CreateEmbeddedMessage("Successfully Cleared Name", (author.getAsMention() + " successfully cleared username `" + mc_name +
+                        "` from <@" + targetDiscordId + ">'s whitelisted users."), DiscordClient.EmbedMessageType.SUCCESS).build();
+            }
+
+        } else {
+            // Name not found
+            if (!DiscordWhitelister.useCustomMessages) {
+
+                messageEmbed =
+                        DiscordClient.CreateEmbeddedMessage((mc_name + " not Found"),
+                                (author.getAsMention() + ", could not find name " + mc_name + " to clear in user list."), DiscordClient.EmbedMessageType.FAILURE).build();
+            } else {
+                String customTitle = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-failure-title");
+                String customMessage = DiscordWhitelister.customMessagesConfig.getFileConfiguration().getString("clear-name-failure-message");
+                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                customMessage = customMessage.replaceAll("\\{MinecraftUsername}", mc_name);
+                customTitle = customTitle.replaceAll("\\{MinecraftUsername}", mc_name);
+
+                messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE).build();
+            }
+
+        }
+        DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+    }
+
+}
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandInfo.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandInfo.java
index 4184650..8c01c88 100644
--- a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandInfo.java
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandInfo.java
@@ -2,25 +2,26 @@ package uk.co.angrybee.joe.commands.discord;
 
 import net.dv8tion.jda.api.entities.TextChannel;
 import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
 import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
 import uk.co.angrybee.joe.AuthorPermissions;
 import uk.co.angrybee.joe.DiscordClient;
 
 public class CommandInfo
 {
-    public static void ExecuteCommand(MessageReceivedEvent messageReceivedEvent)
+    public static void ExecuteCommand(SlashCommandEvent event)
     {
-        AuthorPermissions authorPermissions = new AuthorPermissions(messageReceivedEvent);
-        User author = messageReceivedEvent.getAuthor();
-        TextChannel channel = messageReceivedEvent.getTextChannel();
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
 
         if (authorPermissions.isUserCanUseCommand())
         {
-            DiscordClient.QueueAndRemoveAfterSeconds(channel, DiscordClient.botInfo);
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.botInfo);
         }
         else
         {
-            DiscordClient.QueueAndRemoveAfterSeconds(channel, DiscordClient.CreateInsufficientPermsMessage(author));
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
         }
+        
     }
 }
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandRemove.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandRemove.java
index 058ec0f..cbd7bd3 100644
--- a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandRemove.java
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandRemove.java
@@ -1,6 +1,200 @@
 package uk.co.angrybee.joe.commands.discord;
 
-public class CommandRemove
-{
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.*;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import uk.co.angrybee.joe.AuthorPermissions;
+import uk.co.angrybee.joe.DiscordClient;
+import uk.co.angrybee.joe.DiscordWhitelister;
+import uk.co.angrybee.joe.stores.RemovedList;
+import uk.co.angrybee.joe.stores.UserList;
+import uk.co.angrybee.joe.stores.WhitelistedPlayers;
 
-}
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class CommandRemove {
+
+    public static void ExecuteCommand(SlashCommandEvent event, String mc_name) {
+
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+        TextChannel channel = event.getTextChannel();
+        Member member = event.getMember();
+
+        // Remove Command
+        if (authorPermissions.isUserCanAddRemove()) {
+
+
+            final String finalNameToRemove = mc_name.replaceAll(" .*", ""); // The name is everything up to the first space
+
+            if (finalNameToRemove.isEmpty()) {
+                if (!DiscordClient.hideInfoCommandReplies)
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.removeCommandInfo);
+                return;
+            } else {
+                DiscordWhitelister.getPlugin().getLogger().info(author.getName() + "(" + author.getId() + ") attempted to remove " + finalNameToRemove + " from the whitelist");
+
+                boolean notOnWhitelist = false;
+
+                if (WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToRemove) || !WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayer(finalNameToRemove)) {
+                    notOnWhitelist = true;
+
+                    if (!DiscordWhitelister.useCustomMessages) {
+                        MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("This user is not on the whitelist",
+                                (author.getAsMention() + ", cannot remove user as `" + finalNameToRemove + "` is not on the whitelist!"), DiscordClient.EmbedMessageType.INFO).build();
+                        DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                        // Return below
+                    } else {
+                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("user-not-on-whitelist-title");
+                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("user-not-on-whitelist");
+                        customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                        customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToRemove);
+
+                        MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO).build();
+                        DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+                    }
+                }
+
+                // not not on whitelist, nice
+                if (!notOnWhitelist) // aka on the whitelist
+                {
+                    DiscordClient.UnWhitelist(finalNameToRemove);
+                    // Configure message here instead of on the main thread - this means this will run even if the message is never sent, but is a good trade off (I think)
+                    EmbedBuilder embedBuilderSuccess;
+
+                    if (!DiscordWhitelister.useCustomMessages) {
+                        if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("set-removed-message-colour-to-red"))
+                            embedBuilderSuccess = DiscordClient.CreateEmbeddedMessage((finalNameToRemove + " has been removed"), (author.getAsMention() + " has removed `" + finalNameToRemove + "` from the whitelist."), DiscordClient.EmbedMessageType.SUCCESS);
+                        else
+                            embedBuilderSuccess = DiscordClient.CreateEmbeddedMessage((finalNameToRemove + " has been removed"), (author.getAsMention() + " has removed `" + finalNameToRemove + "` from the whitelist."), DiscordClient.EmbedMessageType.FAILURE);
+                    } else {
+                        String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("remove-success-title");
+                        customTitle = customTitle.replaceAll("\\{MinecraftUsername}", finalNameToRemove);
+
+                        String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("remove-success");
+                        customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                        customMessage = customMessage.replaceAll("\\{MinecraftUsername}", finalNameToRemove);
+
+                        if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("set-removed-message-colour-to-red"))
+                            embedBuilderSuccess = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.SUCCESS);
+                        else
+                            embedBuilderSuccess = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.FAILURE);
+                    }
+
+                    if (DiscordWhitelister.showPlayerSkin) {
+                        String playerUUID = DiscordClient.minecraftUsernameToUUID(finalNameToRemove);
+
+                        if (!DiscordWhitelister.mainConfig.getFileConfiguration().getBoolean("use-crafatar-for-avatars"))
+                            embedBuilderSuccess.setThumbnail("https://minotar.net/armor/bust/" + playerUUID + "/100.png");
+                        else
+                            embedBuilderSuccess.setThumbnail("https://crafatar.com/avatars/" + playerUUID + "?size=100&default=MHF_Steve&overlay.png");
+                    }
+
+                    EmbedBuilder embedBuilderFailure;
+
+                    // No custom message needed
+                    embedBuilderFailure = DiscordClient.CreateEmbeddedMessage(("Failed to remove " + finalNameToRemove + " from the whitelist"), (author.getAsMention() + ", failed to remove `" + finalNameToRemove + "` from the whitelist. " +
+                            "This should never happen, you may have to remove the player manually and report the issue."), DiscordClient.EmbedMessageType.FAILURE);
+
+                    DiscordWhitelister.getPlugin().getServer().getScheduler().callSyncMethod(DiscordWhitelister.getPlugin(), () ->
+                    {
+                        if (WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayerEasyWhitelist(finalNameToRemove)
+                                || !WhitelistedPlayers.usingEasyWhitelist && !WhitelistedPlayers.CheckForPlayer(finalNameToRemove)) {
+                            event.replyEmbeds(embedBuilderSuccess.build()).queue();
+
+                            if (DiscordClient.whitelistedRoleAutoRemove) {
+                                List<String> whitelistRoles = new LinkedList<>();
+
+                                Collections.addAll(whitelistRoles, DiscordClient.whitelistedRoleNames);
+
+                                // Find the Discord Id linked to the removed name
+                                boolean idFound = false;
+                                String targetDiscordId = "";
+                                Set<String> keys = UserList.getUserList().getKeys(false);
+                                for (String userId : keys) {
+                                    List<?> registeredUsers = UserList.getRegisteredUsers(userId);
+                                    for (Object wUser : registeredUsers) {
+                                        if (wUser.equals(finalNameToRemove)) {
+                                            // Found the ban target, assign the corresponding Discord id
+                                            targetDiscordId = userId;
+                                            boolean namesRemainingAfterRemoval = false;
+
+                                            if ((registeredUsers.size() - 1) > 0) {
+                                                namesRemainingAfterRemoval = true;
+                                                DiscordWhitelister.getPluginLogger().info("The Discord ID (" + targetDiscordId + ") linked to " + finalNameToRemove + " contains "
+                                                        + (registeredUsers.size() - 1) + " more whitelisted user(s), not removing whitelisted roles...");
+                                            }
+
+                                            // Find all servers bot is in, remove whitelisted roles
+                                            if (!whitelistRoles.isEmpty() && !namesRemainingAfterRemoval) {
+                                                for (Guild guild : DiscordClient.javaDiscordAPI.getGuilds()) {
+                                                    // Remove the whitelisted role(s)
+                                                    DiscordClient.RemoveRolesFromUser(guild, targetDiscordId, whitelistRoles);
+                                                    DiscordWhitelister.getPluginLogger().info("Successfully removed whitelisted roles from "
+                                                            + targetDiscordId + "(" + finalNameToRemove + ") in guild: " + guild.getName());
+                                                }
+                                            } else if (whitelistRoles.isEmpty()) {
+                                                DiscordWhitelister.getPluginLogger().warning("Cannot remove any whitelisted roles from: " + targetDiscordId + "(" + finalNameToRemove + ") as there are none specified in the config");
+                                            }
+                                            idFound = true;
+                                            break;
+                                        }
+                                    }
+                                }
+
+                                if (!idFound) {
+                                    DiscordWhitelister.getPluginLogger().warning("Could not find any Discord id linked to Minecraft name: " + finalNameToRemove + ", therefore cannot remove any roles");
+                                }
+                                DiscordClient.ClearPlayerFromUserList(finalNameToRemove);
+                            }
+
+                            // if the name is not on the removed list
+                            if (!RemovedList.CheckStoreForPlayer(finalNameToRemove)) {
+                                RemovedList.getRemovedPlayers().set(finalNameToRemove, author.getId());
+                                RemovedList.SaveStore();
+                            }
+                        } else {
+                            DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderFailure.build());
+                        }
+
+                        return null;
+                    });
+                    return;
+                }
+                return;
+            }
+
+        }
+
+        if (authorPermissions.isUserCanAdd() && !authorPermissions.isUserCanAddRemove()) {
+            String higherPermRoles = DiscordWhitelister.mainConfig.getFileConfiguration().getList("add-remove-roles").toString();
+            higherPermRoles = higherPermRoles.replaceAll("\\[", "");
+            higherPermRoles = higherPermRoles.replaceAll("]", "");
+
+            EmbedBuilder embedBuilderInfo;
+
+            if (!DiscordWhitelister.useCustomMessages) {
+                embedBuilderInfo = DiscordClient.CreateEmbeddedMessage("Insufficient Permissions", (author.getAsMention() + ", you only have permission to add people to the whitelist. To remove people from the whitelist you must be moved to the following roles: "
+                        + higherPermRoles + "; or get the owner to move your role to 'add-remove-roles' in the config."), DiscordClient.EmbedMessageType.INFO);
+            } else {
+                String customTitle = DiscordWhitelister.getCustomMessagesConfig().getString("insufficient-permissions-remove-title");
+                String customMessage = DiscordWhitelister.getCustomMessagesConfig().getString("insufficient-permissions-remove");
+                customMessage = customMessage.replaceAll("\\{Sender}", author.getAsMention());
+                customMessage = customMessage.replaceAll("\\{AddRemoveRoles}", higherPermRoles);
+
+                embedBuilderInfo = DiscordClient.CreateEmbeddedMessage(customTitle, customMessage, DiscordClient.EmbedMessageType.INFO);
+            }
+
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, embedBuilderInfo.build());
+            return;
+        }
+
+        // if the user doesn't have any allowed roles
+        DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
+        //TempRemoveOriginalMessageAfterSeconds(messageReceivedEvent);
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIs.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIs.java
index c3bb152..00f7e2d 100644
--- a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIs.java
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIs.java
@@ -1,8 +1,8 @@
 package uk.co.angrybee.joe.commands.discord;
 
-import com.sun.org.apache.xpath.internal.operations.Bool;
 import net.dv8tion.jda.api.EmbedBuilder;
 import net.dv8tion.jda.api.entities.*;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
 import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
 import net.dv8tion.jda.api.exceptions.AccountTypeException;
 import org.yaml.snakeyaml.Yaml;
@@ -19,68 +19,45 @@ import java.util.*;
 import java.util.concurrent.TimeUnit;
 
 public class CommandWhoIs {
-    public static void ExecuteCommand(MessageReceivedEvent messageReceivedEvent, String[] splitMessage) {
-        AuthorPermissions authorPermissions = new AuthorPermissions(messageReceivedEvent);
-        User author = messageReceivedEvent.getAuthor();
-        TextChannel channel = messageReceivedEvent.getTextChannel();
+    public static void ExecuteCommand(SlashCommandEvent event, String mc_name) {
+
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+        TextChannel channel = event.getTextChannel();
 
         if (!authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd()) {
-            DiscordClient.QueueAndRemoveAfterSeconds(channel, DiscordClient.CreateInsufficientPermsMessage(author));
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
             return;
         }
-
-        // TODO make 1 function like this that multiple commands can call on
-        if (DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length > (DiscordClient.customWhoIsPrefix.length + 1)
-                || !DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length > (DiscordClient.whitelistWhoIsPrefix.length + 1)) {
-            int amountOfArgs = 0;
-            if (DiscordWhitelister.getUseCustomPrefixes())
-                amountOfArgs = splitMessage.length - (DiscordClient.customWhoIsPrefix.length);
-            else
-                amountOfArgs = splitMessage.length - (DiscordClient.whitelistWhoIsPrefix.length);
-
-            StringBuilder exampleCommand = new StringBuilder();
-            if (DiscordWhitelister.getUseCustomPrefixes()) {
-                for (int i = 0; i < DiscordClient.customWhoIsPrefix.length; i++) {
-                    exampleCommand.append(DiscordClient.customWhoIsPrefix[i]).append(" ");
-                }
-            } else {
-                for (int i = 0; i < DiscordClient.whitelistWhoIsPrefix.length; i++) {
-                    exampleCommand.append(DiscordClient.whitelistWhoIsPrefix[i]).append(" ");
-                }
+/*
+        int amountOfArgs = 0;
+        StringBuilder exampleCommand = new StringBuilder();
+        if (DiscordWhitelister.getUseCustomPrefixes()) {
+            for (int i = 0; i < DiscordClient.customWhoIsPrefix.length; i++) {
+                exampleCommand.append(DiscordClient.customWhoIsPrefix[i]).append(" ");
+            }
+        } else {
+            for (int i = 0; i < DiscordClient.whitelistWhoIsPrefix.length; i++) {
+                exampleCommand.append(DiscordClient.whitelistWhoIsPrefix[i]).append(" ");
             }
-            exampleCommand.append("<minecraftUsername>");
-
-            MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Too many arguments",
-                    (author.getAsMention() + ", expected 1 argument but found " + amountOfArgs + ".\n" +
-                            "Example: " + exampleCommand.toString()), DiscordClient.EmbedMessageType.FAILURE).build();
-
-            DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
-            return;
         }
+        exampleCommand.append("<minecraftUsername>");
 
-        String nameToCheck = "";
-        if (DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length >= DiscordClient.customWhoIsPrefix.length + 1)
-            nameToCheck = splitMessage[DiscordClient.customWhoIsPrefix.length];
+        MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Too many arguments",
+                (author.getAsMention() + ", expected 1 argument but found " + amountOfArgs + ".\n" +
+                        "Example: " + exampleCommand.toString()), DiscordClient.EmbedMessageType.FAILURE).build();
 
-        if (!DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length >= DiscordClient.whitelistWhoIsPrefix.length + 1)
-            nameToCheck = splitMessage[DiscordClient.whitelistWhoIsPrefix.length];
-
-        if (DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length == DiscordClient.customWhoIsPrefix.length
-                || !DiscordWhitelister.getUseCustomPrefixes() && splitMessage.length == DiscordClient.whitelistWhoIsPrefix.length || nameToCheck.isEmpty()) {
-            if (!DiscordClient.hideInfoCommandReplies)
-                return;
-
-            DiscordClient.QueueAndRemoveAfterSeconds(channel, DiscordClient.whoIsInfo);
-            return;
-        }
+        DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+*/
 
         boolean idFound = false;
         // Find the Discord Id linked to the whitelisted player
         Set<String> keys = UserList.getUserList().getKeys(false);
-        for (String discordId : keys) {
+        for (
+                String discordId : keys) {
             List<?> registeredUsers = UserList.getRegisteredUsers(discordId);
-            for (Object mc_name : registeredUsers) {
-                if (mc_name.equals(nameToCheck)) {
+            for (Object name : registeredUsers) {
+                if (name.equals(mc_name)) {
                     String userAsMention = "<@!" + discordId + ">"; // use this in-case the user has left the discord ? over using fetched member
                     StringBuilder usersWhitelistedPlayers = new StringBuilder();
                     for (Object targetWhitelistedPlayer : registeredUsers) {
@@ -88,8 +65,8 @@ public class CommandWhoIs {
                             usersWhitelistedPlayers.append("- ").append((String) targetWhitelistedPlayer).append("\n");
                     }
 
-                    EmbedBuilder idFoundMessage = DiscordClient.CreateEmbeddedMessage(("Found account linked to `" + nameToCheck + "`"),
-                            (author.getAsMention() + ", the Minecraft username: `" + nameToCheck + "` is linked to " + userAsMention +
+                    EmbedBuilder idFoundMessage = DiscordClient.CreateEmbeddedMessage(("Found account linked to `" + mc_name + "`"),
+                            (author.getAsMention() + ", the Minecraft username: `" + mc_name + "` is linked to " + userAsMention +
                                     ".\n\n Here is a list of their whitelisted players:\n" + usersWhitelistedPlayers),
                             DiscordClient.EmbedMessageType.SUCCESS);
 
@@ -100,19 +77,19 @@ public class CommandWhoIs {
                     else
                         DiscordWhitelister.getPluginLogger().warning("Failed to fetch avatar linked to Discord ID: " + discordId);
 
-                    DiscordClient.QueueAndRemoveAfterSeconds(channel, idFoundMessage.build());
+                    DiscordClient.ReplyAndRemoveAfterSeconds(event, idFoundMessage.build());
                     idFound = true;
                     break;
                 }
             }
         }
         if (!idFound) {
-            MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(("Could not find an account linked to `" + nameToCheck + "`"),
-                    (author.getAsMention() + ", the name: `" + nameToCheck +
+            MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(("Could not find an account linked to `" + mc_name + "`"),
+                    (author.getAsMention() + ", the name: `" + mc_name +
                             "` could not be found in the users list. Please make sure that the Minecraft name is valid and whitelisted + linked to an ID before."),
                     DiscordClient.EmbedMessageType.FAILURE).build();
 
-            DiscordClient.QueueAndRemoveAfterSeconds(channel, messageEmbed);
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
         }
     }
 }
\ No newline at end of file
diff --git a/src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIsDiscord.java b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIsDiscord.java
new file mode 100644
index 0000000..07642c0
--- /dev/null
+++ b/src/main/java/uk/co/angrybee/joe/commands/discord/CommandWhoIsDiscord.java
@@ -0,0 +1,79 @@
+package uk.co.angrybee.joe.commands.discord;
+
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.entities.User;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import uk.co.angrybee.joe.AuthorPermissions;
+import uk.co.angrybee.joe.DiscordClient;
+import uk.co.angrybee.joe.DiscordWhitelister;
+import uk.co.angrybee.joe.stores.UserList;
+
+import java.util.List;
+import java.util.Set;
+
+public class CommandWhoIsDiscord {
+    public static void ExecuteCommand(SlashCommandEvent event, Member target) {
+
+        AuthorPermissions authorPermissions = new AuthorPermissions(event);
+        User author = event.getUser();
+
+        if (!authorPermissions.isUserCanAddRemove() && !authorPermissions.isUserCanAdd()) {
+            DiscordClient.ReplyAndRemoveAfterSeconds(event, DiscordClient.CreateInsufficientPermsMessage(author));
+            return;
+        }
+/*
+        int amountOfArgs = 0;
+        StringBuilder exampleCommand = new StringBuilder();
+        if (DiscordWhitelister.getUseCustomPrefixes()) {
+            for (int i = 0; i < DiscordClient.customWhoIsPrefix.length; i++) {
+                exampleCommand.append(DiscordClient.customWhoIsPrefix[i]).append(" ");
+            }
+        } else {
+            for (int i = 0; i < DiscordClient.whitelistWhoIsPrefix.length; i++) {
+                exampleCommand.append(DiscordClient.whitelistWhoIsPrefix[i]).append(" ");
+            }
+        }
+        exampleCommand.append("<minecraftUsername>");
+
+        MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage("Too many arguments",
+                (author.getAsMention() + ", expected 1 argument but found " + amountOfArgs + ".\n" +
+                        "Example: " + exampleCommand.toString()), DiscordClient.EmbedMessageType.FAILURE).build();
+
+        DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+*/
+
+        boolean idFound = false;
+        // Find the Discord Id linked to the whitelisted player
+        Set<String> keys = UserList.getUserList().getKeys(false);
+        String userAsMention = "<@!" + target.getId() + ">"; // use this in-case the user has left the discord ? over using fetched member
+        for (String discordId : keys) {
+            if (discordId.equals(target.getId())) {
+                List<?> registeredUsers = UserList.getRegisteredUsers(discordId);
+                StringBuilder usersWhitelistedPlayers = new StringBuilder();
+                for (Object targetWhitelistedPlayer : registeredUsers) {
+                    if (targetWhitelistedPlayer instanceof String)
+                        usersWhitelistedPlayers.append("- ").append((String) targetWhitelistedPlayer).append("\n");
+                }
+
+                EmbedBuilder idFoundMessage = DiscordClient.CreateEmbeddedMessage(("Found usernames linked to " + userAsMention),
+                        (author.getAsMention() + ", the user " + userAsMention + " has the following usernames linked to their account:\n" + usersWhitelistedPlayers),
+                        DiscordClient.EmbedMessageType.SUCCESS);
+
+                DiscordClient.ReplyAndRemoveAfterSeconds(event, idFoundMessage.build());
+                return;
+
+
+            }
+        }
+        MessageEmbed messageEmbed = DiscordClient.CreateEmbeddedMessage(("Could not find an usernames linked to " + target.getEffectiveName()),
+                (author.getAsMention() + ", the user " + userAsMention +
+                        " could not be found in the users list."),
+                DiscordClient.EmbedMessageType.FAILURE).build();
+
+        DiscordClient.ReplyAndRemoveAfterSeconds(event, messageEmbed);
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/uk/co/angrybee/joe/configs/CustomMessagesConfig.java b/src/main/java/uk/co/angrybee/joe/configs/CustomMessagesConfig.java
index 4758d9d..b3da870 100644
--- a/src/main/java/uk/co/angrybee/joe/configs/CustomMessagesConfig.java
+++ b/src/main/java/uk/co/angrybee/joe/configs/CustomMessagesConfig.java
@@ -89,7 +89,7 @@ public class CustomMessagesConfig extends Config
             CheckEntry("clear-ban-failure-message", "{Sender}, `{MinecraftUsername}` cannot be found in any of the removed lists!");
 
             CheckEntry("instructional-message-title", "How to Whitelist");
-            CheckEntry("instructional-message", "Use `!whitelist add <minecraftUsername>` to whitelist yourself. In the case of whitelisting an incorrect name, please contact a staff member to clear it from the whitelist.");
+            CheckEntry("instructional-message", "Use `/whitelist add <minecraftUsername>` to whitelist yourself. In the case of whitelisting an incorrect name, please contact a staff member to clear it from the whitelist.");
 
             CheckEntry("whitelist-clear-success-title",  "Successfully Removed {Sender}'s Whitelisted Entries");
             CheckEntry("whitelist-clear-success-message", "{Sender} successfully removed the following users from the whitelist: \n{RemovedEntries}\nYou now have **{MaxWhitelistAmount} whitelist(s) remaining**.");
diff --git a/src/main/java/uk/co/angrybee/joe/configs/CustomPrefixConfig.java b/src/main/java/uk/co/angrybee/joe/configs/CustomPrefixConfig.java
index 3192556..a063ac6 100644
--- a/src/main/java/uk/co/angrybee/joe/configs/CustomPrefixConfig.java
+++ b/src/main/java/uk/co/angrybee/joe/configs/CustomPrefixConfig.java
@@ -31,17 +31,17 @@ public class CustomPrefixConfig extends Config
     {
         if(file.exists())
         {
-            CheckEntry("whitelist-add-prefix", "!whitelist add");
+            CheckEntry("whitelist-add-prefix", "/whitelist add");
 
-            CheckEntry("whitelist-remove-prefix", "!whitelist remove");
+            CheckEntry("whitelist-remove-prefix", "/whitelist remove");
 
-            CheckEntry("clear-name-prefix", "!clearname");
+            CheckEntry("clear-name-prefix", "/clearname");
 
-            CheckEntry("limited-whitelist-clear-prefix", "!whitelist clear");
+            CheckEntry("limited-whitelist-clear-prefix", "/whitelist clear");
 
             CheckEntry("clear-ban-prefix", "!clearban");
 
-            CheckEntry("whitelist-whois-prefix", "!whitelist whois");
+            CheckEntry("whitelist-whois-prefix", "/whitelist whois");
         }
     }
 }