/clearchat Plugin tutorial

Discussion in 'Plugin Development' started by chris8787878787, Jul 2, 2014.

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

    chris8787878787

    Hiya, I'm here to teach all of you that don't know, how to make a /clearchat plugin! Basically, /clearchat just clears the whole chat and leaves the message; "Chat has been cleared by a Staff member." I'll teach you the way I know how to do it, if I described something wrong, feel free to criticize me. You should know how to make a project, package, class, plugin.yml ETC. Alright so let's get started!

    So after you make your class, extend it to a JavaPlugin (If you don't know how to do this, you won't understand most of this, so if you want to learn anything, learn that first atleast.

    Alright so were gonna start with the obvious onEnable and disable stuff, here's how you do it, once again, if you don't know this, make sure to go back and learn this.
    Code:
    @Override
        public void onEnable() {
            getLogger().info("Plugin Enabled.");
        }
       
        @Override
        public void onDisable() {
           
        }
    I'm not explaining this because if you got here, you should know how this works.

    Ok, now the final obvious part, we need our public boolean, here you go.
    Code:
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    Again, not explaining this.

    So onto the interesting stuff,
    Code:
    if (cmd.getName().equalsIgnoreCase("clearchat")) {
                Player p = (Player) sender;
    So lets start with the first line. what
    Code:
    if (cmd.getName().equalsIgnoreCase("clearchat")) {
    means is, if the command inputted (capitals don't matter, .equalsIgnoreCase() is a charm.) is equal to clear chat then it will output the next line. Simple.

    Code:
    Player p = (Player) sender;
    As embarrassing as this is, I never fully understood this line, I get
    Code:
    Player p =
    is setting up a variable,
    Code:
    (Player) sender;
    always gets me. I'm guessing it means the player is now the sender I guess..

    Next line,
    Code:
    if(p.hasPermission("clearchat")) {
    So were saying if the player has permission (They need to be Op or have permission to use this command.) to use the command, then output the next lines within the closed bracket.

    Alright here's the 'fun' part :D, Were gonna clear the chat, and they way we do that is by broadcasting a BUNCH of " " and in chat that is just a blank line. So we'll use this code,
    Code:
    Bukkit.broadcastMessage("");
    And copy and paste that like, 50 times under it. so like this,
    Code:
    Bukkit.broadcastMessage("");
    Bukkit.broadcastMessage("");
    Bukkit.broadcastMessage("");
    ETC.
    Alright, if the chat just does that it looks ugly, so at the end make it say "The chat has been cleared like so
    Code:
    Bukkit.broadcastMessage("The chat has been cleared.");
    But in my eyes that's still ugly so I added some elegance to it. Check this out;
    Code:
    Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");
                    Bukkit.broadcastMessage(ChatColor.BOLD + " The chat has been cleared by a staff member.");
                    Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");
    Try using that in your code, see how it looks.

    underneath all that put return true; and in the midst of the closed brackets at the bottem, so return true. Now you're reading this like "HOW AM I SUPPOSED TO PUT THIS TOGETHER?!?!" Don't worry, i'm not like that, here's what the complete code looks like.


    Code:
    package me.chris8787878787;
     
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class clearchat extends JavaPlugin {
       
        @Override
        public void onEnable() {
            getLogger().info("Plugin Enabled.");
        }
       
        @Override
        public void onDisable() {
           
        }
       
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
           
            if (cmd.getName().equalsIgnoreCase("clearchat")) {
                Player p = (Player) sender;
               
                if(p.hasPermission("clearchat")) {
                   
                   
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                    Bukkit.broadcastMessage("");
                   
                    Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");
                    Bukkit.broadcastMessage(ChatColor.BOLD + " The chat has been cleared by a staff member.");
                    Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");
                   
                    return true;
                   
                }
               
            }
            return false;
           
        }
     
    }
    Have a good day and I hope you learned something! :)
     
  2. Offline

    jthort

    chris8787878787 You shouldn't cast the sender to a player without checking if it's an instance of a player in case the command is being executed through the console.

    Edit: Also why don't you just create a loop rather than spamming the code with print messages?

    Edit2: Also class names should be capitalized, it's good practice

    Edit3: Also doesn't the console already print out when the plugin was enabled?

    But not a big deal looks good
     
  3. Offline

    Heirteir

    chris8787878787
    instead of doing all those broadcasts why not
    Code:java
    1. for (int x = 0; x < 150; x++){
    2. Bukkit.broadcastMessage("");
    3. }


    Much quicker less work
     
  4. Offline

    The Fancy Whale

  5. Offline

    Gamecube762

    Heirteir instead of 150, why not go for the chat history limit (about 20), less chat packet spam.

    Or if you want to use only 1 method and no loop, use a string with about 20 "/n" in it.

    chris8787878787
    Also:
    • Checking the command name is not needed if it's the only command to the plugin
    • CommandSender has a .hasPermission() method, so converting it to a player is not needed
    • Bukkit already checks for permission if you defined the permission for the command in the plugin.yml
    Just a few tips for cleaner code. =P
     
  6. Offline

    Iroh

    Moved to resources.
     
  7. Offline

    Necrodoom

    In addition, plugin does not follow permission node guidelines, node should start with plugin name to prevent conflicts, so node needs to be clearchat.clearchat.

    Also, if you don't understand your own tutorial (not knowing what casting is), then you shouldn't make one, as you will end up misleading new players. This tutorial contains a lot of bad practice that should be removed.
     
  8. Offline

    Onlineids

    Gamecube762 The full chat history limit is 100 lines ;)

    Also Everyone who does this,
    Code:java
    1. getLogger().info("Plugin Enabled.");

    ^ Please stop doing this -_-

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 9, 2016
  9. Offline

    xTrollxDudex

    Eh, developers, not players.
     
    xTigerRebornx likes this.
  10. Offline

    Garris0n

    This section is doomed.
     
  11. Offline

    RawCode

    dont worry, nobody read tutorials anyway...
     
  12. Offline

    JBoss925

    So this a tutorial on how to copy and paste?
     
  13. Offline

    mbaxter ʇıʞʞnq ɐ sɐɥ ı

    Action reverted. The Resources subforum is for content that can help plugin developers with development. This resource is lacking in that department.
     
  14. Offline

    teej107

    chris8787878787 Thanks, but no thanks. I see problems with your code that would be great if you fixed which everyone one on this thread pointed out at least one. You should really learn more Java if you never heard of a for-loop.
     
  15. Offline

    CynutsBR

     
    JBoss925 likes this.
  16. Offline

    thomasb454



    Why? Bukkit only prints when the plugin is being enabled (loaded), simply stating the plugin has enabled does no harm. In many of my plugins, I print out (using current system time millis) plugin start up time.
     
  17. Offline

    AoH_Ruthless

    thomasb454
    It's one of those things that doesn't really matter and arguing over it won't solve. Just leave it and let each developer do his/her own thing regarding that subject.

    chris8787878787
    To reiterate what everyone else said, just incase you didn't get the memo, you need to learn Java.

    1. You don't follow naming conventions with your class name
    2. You have an empty onDisable method. It is inherited but isn't required... just remove it.
    3. You are missing the override annotation on your command. Again, this isn't life-threatening, but it's bad practice, at least in my opinion.
    4. You avoid instance checks on the Player, will result in exceptions at times. This is partly a Bukkit issue you have, but also a Java issue because you have no idea why it is an issue.
    5. Most importantly, for looping is a beautiful thing.
    Also, this doesn't effectively clear chat. What if while you are clearing chat, I type the letter 't' very quickly about 10 times (unlikely that many times ... but what if 50 players all typed 't' once, and you happened to be clearing :p ). Then the chat history will be riddled with a bunch of 't's in the midst of blank messages.
     
    JBoss925 and Traks like this.
  18. Offline

    Beno65Dev

    @chris8787878787
    maby a nice idea for at the end to make this:
    Code:java
    1. Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");
    2. Bukkit.broadcastMessage(ChatColor.BOLD + " The chat has been cleared by " + sender.getName());
    3. Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");


    now you can see who have clear the chat
     
  19. Offline

    thomasb454


    I wasn't going to continue; just wanted to point out you don't have to listen to every word thrown at you.
     
    AoH_Ruthless likes this.
  20. Offline

    teej107

    thomasb454 Yes that line of code is pretty harmless, but I feel like people (who don't know Java) just copy-paste a bunch of code from tutorials that aren't really that great/outdated and they really don't know why. That line of code is harmless but completely useless. The console already prints out what plugins are being loaded. Now if you have more than just saying "Plugin Enabled" like:
    That is fine because you aren't spamming the console with the same info basicly. (Even though the console does display the current system time as well.)
    Yes it's up to the OP to decide that but we are helping the OP for the better. Especially since this OP hasn't been using Java for that long, he should be taking suggestions from people who have a better knowledge of Java.
     
  21. Offline

    jthort

    Actually I would approach that a lot differently. I would create a method called something like print with dividers that takes in String and returns void. That way you can just call the method whenever you need that format.

    Just printing it out straight like that in the code looks bad in my opinion, always go for the method :)
     
  22. Offline

    chris8787878787

    As requested, if the thread is just gonna mislead players, requesting thread delete.
     
  23. Offline

    RawCode

    There is no reason to delete thread, i must be clearly marked as invalid and locked.
    Negative experience still experience and can be useful in some cases.
     
    xTigerRebornx and AoH_Ruthless like this.
  24. Needs to have a better structure.
    Also saying "not explaining this", do you actually understand what it is?

    You need to fully explain each and every line of code you are writing to some extent instead of writing a line of code and saying "I'm not explaining this" shows you do not know what you are talking about and just copying and pasting code.

    I say don't remove this thread instead rewrite it and put a better structure on it explaining each line as you go along :)
     
  25. Offline

    RawCode

    teozfrank
    There is no reason to explain every line of code, this always looks like "captain obvious was here".
    Generic logic should be explained, not "lines of code".

    Entire logic of this thread is "to clear chat you can flood it with other messages".
    There is nothing to explain, nothing to discuss, everyone with a bit of skill already knows this.
     
  26. Yes but it is supposed to be a tutorial. Which is for people that do not know this... Otherwise why would we look at it?
     
  27. Offline

    AoH_Ruthless

    teozfrank
    Yes, but Java concepts theoretically don't need to be explained in great detail; as developers working with 3rd Party API's in theory, should have a firm understanding of Java. Also, some things do not always warrant explanations. The code should be obvious, documentation and commenting should not make the code obvious. That is bad coding practice.

    For example, if I was making a minigame tutorial:
    Code:java
    1. int i = 10; // max player size
    2. int j = 2; // min player size

    The above is horrible coding and any decent OO Programmer avoids this. Edit: This is only really seen when developers are trying to obfuscate their code.
    What adept programmers do, or should be doing at least:
    Code:java
    1. int maxPlayerCount = 10;
    2. int minPlayerCount = 2;


    This is what RawCode I believe is referring to, and I honestly could not agree more.
     
    RawCode likes this.
  28. Offline

    myminecrafter01

    chris8787878787 this is a much more efficient version of your code and supports the command being run from the console.
    Code:java
    1. package me.chris8787878787;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.command.Command;
    6. import org.bukkit.command.CommandSender;
    7. import org.bukkit.entity.Player;
    8. import org.bukkit.plugin.java.JavaPlugin;
    9.  
    10. public class ClearChat extends JavaPlugin {
    11.  
    12. @Override
    13. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    14. if (cmd.getName().equalsIgnoreCase("clearchat")) {
    15. if (sender instanceof Player && !sender.hasPermission("clearchat.clear")) {
    16. sender.sendMessage("You do not have access to that command.");
    17. return true;
    18. }
    19.  
    20. for (int i = 0; i < 100; i++) {
    21. Bukkit.broadcastMessage("");
    22. }
    23.  
    24. Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");
    25. Bukkit.broadcastMessage(ChatColor.BOLD + " The chat has been cleared by a staff member.");
    26. Bukkit.broadcastMessage(ChatColor.GOLD + "|-------------------+====+-------------------|");
    27. }
    28. return true;
    29. }
    30. }
     
  29. Offline

    RawCode

    myminecrafter01

    still new developers unable to follow "tutorial" since no YML part explained.

    this section is doomed, "developers" post tutorials for noobs, noobs can't follow due bad design and large amount of flaws.
    developer wont follow due bad design and large amount of flaws...
     
  30. Offline

    unrealdesign

    I would actually post some libs and tutorials for the questions asked here, but I believe no one would actually look at them so I don't want to bother haha.
     
Thread Status:
Not open for further replies.

Share This Page