Reloading Config still not working!

Discussion in 'Plugin Development' started by InsertNameHere, Jul 10, 2019.

Thread Status:
Not open for further replies.
  1. Offline

    InsertNameHere

    Explanation: For practice, I am trying to make a plugin that just allows you to monitor the chat. I have a separate class with all the commands, an events class to listen to a chat event, and the main class called CleanChat. One feature of the plugin would be that it would automatically censor out certain words and prevent the player from saying it. There would be a List<String> in the config.yml that is constantly checked each time a player chats. The two commands: /chat add <word> and /chat remove <word> would add and remove a word from the List<String> respectively.

    However, I'm having difficulty reloading the config.yml in game without restarting the server. I tried plugin.reloadConfig() and it just doesn't work for me for some reason. I've spent about two days trying to find the problem in past posts, but still haven't figured it out. Either I haven't done enough research or am glossing over something minor.

    Here's the code in the main class:
    Code:
    public final class CleanChat extends JavaPlugin {
    
        @Overridepublic void onEnable() {
            saveDefaultConfig();
            registerCommands();
            registerEvents();
        }
    
        public void registerEvents() {
            getServer().getPluginManager().registerEvents(new ChatListener(this), this);
        }
    
        public void registerCommands() {
            getCommand("chat").setExecutor(new ChatCommands(this));
        }
    }
    
    This is the code in the event listener class. The ChatManager.getChatMuted() is simply a static method that checks what the Boolean value for chatMuted is. If chatMuted is true, that means the chat is muted and it cancels the event.
    Code:
    private CleanChat plugin;
    private List<String> banWords;
    private LinkedList<String> censoredWords;
    
    public ChatListener(CleanChat plugin) {
        this.plugin = plugin;
        censoredWords = new LinkedList<>();
        banWords = this.plugin.getConfig().getStringList("BannedWords");
    }
    
    @EventHandlerpublic void onChatEvent(AsyncPlayerChatEvent e) {
        String message = e.getMessage().toLowerCase().replaceAll("\\s+", "").replaceAll("[ .]", "");
        if (ChatManager.getChatMuted() && !e.getPlayer().hasPermission(Settings.BYPASS_MUTE)) {
            e.getPlayer().sendMessage(RED.toString() + BOLD + "The chat has been muted.");
            e.setCancelled(true);
        } else {
            checkMessages(e, message);
        }
    }
    
    private void checkMessages(AsyncPlayerChatEvent e, String message) {
        for (String word: banWords) {
            if (message.contains(word)) {
                censoredWords.add(word);
            }
        }
    
        if (!censoredWords.isEmpty()) {
            e.getPlayer().sendMessage(RED + "You are not allowed to say " + formatList(censoredWords) + ".");
            e.setCancelled(true);
            censoredWords.clear();
    
            for (Player player: Bukkit.getOnlinePlayers()) {
                if (player.hasPermission(Settings.NOTIFY))
                    player.sendMessage(DARK_PURPLE + "[Clear Chat]: " + RED + e.getPlayer().getName() + " attempted to say: " + e.getMessage());
            }
        }
    }
    
    private String formatList(LinkedList<String> list) {
        String message = "";
        if (list.size() == 1)
            return list.get(0);
        else if (list.size() == 2)
            return list.get(0) + " and " + list.get(1);
        else
            for (int i = 0; i < list.size(); i++) {
                message += (i != list.size() - 1) ? list.get(i) + ", " : "and " + list.get(i);
            }
    
        return message;
    }
    
    And here is the actual code for the Command class.

    Code:
    private CleanChat plugin;
    private List<String> banWords;
    
    public ChatCommands(CleanChat plugin) {
        this.plugin = plugin;
        ChatManager.setChatMuted(false);
        ChatManager.setChatSlowed(false);
        banWords = this.plugin.getConfig().getStringList("BannedWords");
    }
    
    @Overridepublic boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    
        if (!sender.hasPermission(Settings.ALL)) {
            sender.sendMessage(DARK_RED + "You do not have access to this command.");
            return true;
        }
    
        if (args.length == 0 || args.length > 2)
            sender.sendMessage(DARK_PURPLE + "[Clear Chat]: " + GREEN + "This command requires at least one argument.");
        else {
            if (args.length == 1) {
                if (args[0].equalsIgnoreCase("list")) {
                    if (!sender.hasPermission(Settings.LIST)) {
                        sender.sendMessage(DARK_RED + "You do not have permission.");
                        return true;
                    }
                    sender.sendMessage(DARK_PURPLE + "[Clear Chat]: " + GREEN + "Players cannot say: " + WHITE + formatList(banWords));
                } else if (args[0].equalsIgnoreCase("reload")) {
                    if (!sender.hasPermission(Settings.RELOAD)) {
                         sender.sendMessage(DARK_RED + "You do not have permission.");
                         return true;
                    }
                    plugin.reloadConfig();
                    sender.sendMessage(DARK_PURPLE + "[Clear Chat]: " + GREEN + "Reloaded config.yml");
                } else if (args[0].equalsIgnoreCase("mute")) {
                    muteGlobalChat();
                } elsesender.sendMessage(DARK_RED + "This command does not exist.");
            } else {
                if (args[0].equalsIgnoreCase("add")) {
                    if (!banWords.contains(args[1]))
                        banWords.add(args[1]);
                        sender.sendMessage(DARK_PURPLE + "[Clear Chat]: " + GREEN + "Players can no longer say " + WHITE + args[1]);
                        plugin.getConfig().set("BannedWords", banWords);
                        plugin.saveConfig();
                    } else if (args[0].equalsIgnoreCase("remove")) {
                        if (args[1].equalsIgnoreCase("all")) {
                            banWords.clear();
                            plugin.getConfig().set("BannedWords", banWords);
                            plugin.saveConfig();sender.sendMessage(DARK_PURPLE + "[Clear Chat]: " + GREEN + "Cleared the list of banned words!");
                            return true;
                        }
                        banWords.remove(args[1]);
                        sender.sendMessage(DARK_PURPLE + "[Clear Chat]: " + GREEN + "Players can now say " + WHITE + args[1]);
                        plugin.getConfig().set("BannedWords", banWords);
                        plugin.saveConfig();
                    } else if (args[0].equalsIgnoreCase("slow")) {
                        // To be finished later
                } else {
                    // To be done later
                }
            }
        }
    
    return true;
    }
    
    private String formatList(List<String> list) {
        String message = "";
        for (int i = 0; i < list.size(); i++) {
            if (list.size() == 1)
                message = list.get(i);
            else
                message += (i != list.size() - 1) ? list.get(i) + ", " : "and " + list.get(i);
        }
    
    return message;
    }
    
    private void muteGlobalChat() {
        if (ChatManager.getChatMuted())
            Bukkit.broadcastMessage(GREEN.toString() + BOLD + "The chat has been unmuted.");
        else
            Bukkit.broadcastMessage(GREEN.toString() + BOLD + "The chat has been muted.");
    
        ChatManager.setChatMuted(!ChatManager.getChatMuted());}
    
    Anyways, my main issue is when I run /chat reload. Each time I do so, the console prints out the message, "[Clear Chat]: Reloaded config.yml." However, whenever I check console, it isn't actually updated. I'm not sure what to do, I don't see anything wrong with my code. I tried adding and removing a plugin.saveConfig() to no avail. So far, the only thing that has gotten me remotely close to reloading the config was adding

    Code:
    plugin.getPluginLoader().disablePlugin(plugin);
    plugin.getPluginLoader().enablePlugin(plugin);
    
    to the reload command. But that only worked when I ran /chat add <word>. It didn't update the config whenever I removed a word. Any ideas?
     
  2. Offline

    KarimAKL

    @InsertNameHere When are you reloading? Is it after you've changed something in the file manually?
     
  3. Offline

    InsertNameHere

    @KarimAKL No, I'm reloading after I add a new word to List<String> banWords. Basically, let's say I'm an evil server owner and I don't want players to say hello. My original idea was to first run /chat add hello, which adds the word "hello" to banWords. Then when running /chat reload, which updates the config, players would no longer be able to say hello in chat.
     
  4. Offline

    KarimAKL

    @InsertNameHere Then you are going about it the wrong way, reloading is for loading the file after manual changes, it seems you want to save the config instead of load it. After you run '/chat add hello', it would already be added to the banWords, so there's no need to load it.
    Loading = from config
    Saving = to config
    Please let me know if i misunderstood you.
     
  5. Offline

    InsertNameHere

    @KarimAKL Okay, but I have a plugin.saveConfig() in the code. But whenever I run the command, players can still say the word.

    Using the previous example, if I run '/chat add hello' in game, it adds 'hello' to the config. But players can still say "Hello" in chat, it doesn't block them from doing so. Any ideas on how to fix then?
     
  6. Offline

    KarimAKL

    @InsertNameHere That's probably because you have two different 'banWords' lists; one in your 'ChatListener' class and one in your 'ChatCommands' class.
    You are adding it to the command one, but the chat one isn't getting set after that, meaning it's outdated.
     
  7. Offline

    InsertNameHere

    @KarimAKL Hm... okay, how do I fix that? Should I just add a public static ArrayList<String> in the class and have ChatsListener call the list? I'm trying to actively avoid using static variables but I don't really see a way around it...
     
  8. Offline

    KarimAKL

    @InsertNameHere You could make the list inside your main class, then make a getter (and setter) for it, then get (and set) when needed.
     
  9. Offline

    InsertNameHere

    @KarimAKL So then there isn't a way to have config.yml automatically update every time I add a new word?
     
  10. Offline

    KarimAKL

    @InsertNameHere Make the list i mentioned, then when you are adding/removing a value from it, add/remove it from the config as well, then save the config.
     
  11. Offline

    InsertNameHere

    @KarimAKL Uh, well, I've never really done that before, so can you walk me through how you would add getter, setter, and private variables to the main class? I thought you weren't supposed to add constructors into your main class... is this not the case?
     
  12. Offline

    KarimAKL

    @InsertNameHere Getters and setters are not constructors. Here are some links that might be helpful:
    Encapsulation: https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
    Getters/Setters: https://stackoverflow.com/questions/2036970/how-do-getters-and-setters-work
    When adding/removing a word, do something like the following:
    Code:Java
    1. // 'plugin' in this case would be an instance of your main class
    2. // 'getBannedWords' would be an example method for getting the words
    3. // I'm using a 'Set' in this case because we don't want duplicate words in the list
    4. Set<String> words = plugin.getBannedWords(); // Get all words
    5. words.add("word"); // Add word
    6. words.remove("word"); // Remove word
    7. // 'setBannedWords' would be an example method for setting the words to a new list
    8. plugin.setBannedWords(words); // Set list of words to your modified list
    9. // Create list to set in your config, containing the words
    10. List<String> list = new ArrayList<>(words);
    11. // Set the list in the config
    12. plugin.getConfig().set("Path.To.Your.List", list);
    13. // Save the config after changes
    14. plugin.saveConfig();

    Please let me know if there's anything you didn't understand, i tried my best to explain it in the code.
     
  13. Offline

    InsertNameHere

    @KarimAKL I watched a video on it, but thanks though! I wasn't trying to say getter and setter methods were constructors, sorry for the confusion.
     

    Attached Files:

    • F.PNG
      F.PNG
      File size:
      15.8 KB
      Views:
      5
    Last edited: Jul 13, 2019
  14. Offline

    InsertNameHere

    @KarimAKL Sorry to bother you again, but is there a way to list all the commands when you do /help <name of plugin>? At the moment, it just lists the only command I have which is /chat since in plugin.yml, I have the command set to 'chat:'

    Is there a way to have it show '/chat reload', '/chat ban <word>', '/chat mute', '/chat slow', etc?
     
  15. Offline

    Kars

    @InsertNameHere Yes add them as seperate commands in the yml and have seperate command handlers for them. The auto complete will show them as /chat:reload and /chat:ban etc.
     
  16. Offline

    InsertNameHere

    @Kars Can you elaborate? Do I add extra arguments after the setExecutor()?
     
  17. Offline

    Machine Maker

    @InsertNameHere What he is saying is that only commands that are listed in the plugins.yml will show up in /help PluginName.

    So you'd need to add separate entries in the plugin.yml for each of those commands.
     
  18. Offline

    InsertNameHere

    @Machine Maker Let me double-check to make sure I understand everything. Let's say I want to have two subcommands called "/chat reload" that reloads the config.yml file and "/chat mute" which just mutes the chat. So in the plugin.yml file, I would put them as separate commands
    Code:
    commands:
      chat:
        reload:
          description: Reloads config.yml
        mute:
          description: Mutes the chat
    
    Is that correct? Or do I have to redo the handlers as well? The only thing I have to register the commands is
    Code:
    getCommand("chat").setExecutor(new ChatCommands(this));
    
    since all the arguments are in the same class.
     
  19. Offline

    Machine Maker

    No, you only put the BASE command (aka the first word in the command). So in that case, only put "chat" in the plugin.yml
     
Thread Status:
Not open for further replies.

Share This Page