My First Plugin (Feeling accomplished)

Discussion in 'Bukkit Discussion' started by Music4lity, Oct 18, 2017.

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


    I just wrote my first plugin :D It's similar to the Hypixel reports plugin (in fact, probably nearly identical) but I just feel so accomplished that I had to share it with you <3

    Of course if anyone has any tips or suggestions, I'd love to hear them. I want to be as good and efficient as possible.
    1. package com.music4lity.wdr.commands;
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.command.Command;
    6. import org.bukkit.command.CommandExecutor;
    7. import org.bukkit.command.CommandSender;
    8. import org.bukkit.entity.Player;
    10. public class watchdogreport implements CommandExecutor {
    12. public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    13. command.getAliases();
    14. if (sender instanceof Player) {
    15. int length = args.length;
    16. if (length == 0) {
    17. sender.sendMessage(ChatColor.GREEN + "[WDR] " + ChatColor.YELLOW + "Please specify a player and the type of hacks to be looking for.");
    18. sender.sendMessage(ChatColor.GRAY + "Usage: " + ChatColor.WHITE + "/wdr <player> <type of hacks>");
    19. }
    20. else if (length == 1) {
    21. sender.sendMessage(ChatColor.GREEN + "[WDR] " + ChatColor.YELLOW + "Please specify the type of hacks to be looking for.");
    22. sender.sendMessage(ChatColor.GRAY + "Usage: " + ChatColor.WHITE + "/wdr <player> <type of hacks>");
    23. }
    24. else if (length == 2) {
    25. Player player = Bukkit.getPlayerExact(args[0]);
    26. if (player != null && player.getName() != sender.getName()) {
    27. sender.sendMessage(ChatColor.GREEN + "[WDR] " + ChatColor.GREEN + "Thank you for your report. We'll look into this matter.");
    28. for (Player reciever : Bukkit.getOnlinePlayers()) {
    29. if (reciever.hasPermission("watchdog.recieve")) {
    30. reciever.sendMessage(ChatColor.GOLD + "[WATCHDOG] " + ChatColor.RED + sender.getName() + ChatColor.AQUA + " has reported " + ChatColor.RED + player.getName() + ChatColor.AQUA + " for " + ChatColor.YELLOW + args[1]);
    31. }
    32. }
    33. }
    34. else if (player != null && player.getName() == sender.getName()) {
    35. sender.sendMessage(ChatColor.DARK_RED + "[ERROR] " + ChatColor.RED + "You cannot report yourself!");
    36. } else {
    37. sender.sendMessage(ChatColor.RED + "The specified player could not be found. Are they offline? Check your spelling.");
    38. }
    39. }
    40. else if (length > 2) {
    41. sender.sendMessage(ChatColor.DARK_RED + "[ERROR] " + ChatColor.RED + "Too many arguments!");
    42. }
    43. }
    44. else {
    45. sender.sendMessage(ChatColor.GREEN + "[WDR] " + ChatColor.RED + "You must be a player to use this command.");
    46. }
    47. return true;
    48. }
    50. }
    Last edited: Oct 18, 2017
  2. Offline

    timtower Administrator Administrator Moderator

    @Music4lity Why do you check for a player if you never use it?
  3. Offline


    @timtower At the end of the code, there's an else statement. If the sender isn't a player (ie. Console), then the plugin sends the sender a message saying that they must be a player.

    Attached Files:

    Last edited: Oct 18, 2017
  4. @Music4lity
    Well, why do you need to restrict the command to only players? I see no reason why the console can't use the command..

    Some other things:
    1. Class names should be UpperCase. The correct class name would be 'WatchdogReport'
    2. Do you own the domain ''? If you don't, you should change the package name to <country code where you live>.music4lity
    3. Why do you have the line at the top which says 'command.getAliases()'? It does nothing as far as I can see.
    4. Is there a reason you need to use Bukkit.getPlayerExact() instead of just Bukkit.getPlayer()? Bukkit.getPlayer() ignores case, which is useful when you have to get users to type in the names.
    5. You should not use '==' to compare strings, instead use .equals(). (If you want to get picky, that '==' statement probably will work, since the string instance returned would be the same for the two calls, but you should use '.equals()' just to be safe).
    Zombie_Striker likes this.
  5. Offline


    @AlvinB There would be no use in running a command from the console to alert online staff of a hacker that a player encountered.

    1. I'll take care of that. Thank you.
    2. As a matter of fact, I do own
    3. The command.getAliases(); line retrieves defined aliases in the plugin.yml file. Under the command defined there, you can define a different command that will replace the one defines in the code. So instead of putting in /watchdogreport, since the alias [wdr] is defines in the plugin.yml, one can use /wdr in it's place. I'll put the plugin.yml in a spoiler at the bottom.
    4. Bukkit.getPlayerExact() also ignores cases. It is just as user-friendly as Bukkit.getPlayer()
    5. The '==' equality operator works the same way and poses no threat to the code. Both work, but if something isn't deprecated and works the exact same, then why would one not use '==' if it works? The '==' operator is made to work with any instance be it doubles, integers, strings, what have you.
    plugin.yml (open)
    main: com.music4lity.wdr.main
    version: 1.0
    name: WatchdogReport
    description: Allows the player to report another player for using a hacked client.
    usage: /watchdogreport
    aliases: [wdr]​
  6. @Music4lity
    3. Yes, but you don't need to call command.getAliases() for those aliases to load. All you need to do is put them in the plugin.yml
    4. You're right, both ignore case, but Bukkit.getPlayer() includes a more complex matching mechanism to match parts of usernames aswell. My point was that Bukkit.getPlayer() had a more dynamic matching, which would make it easier on your user to select the right player name.
    5. No, the '==' compares memory addresses. This works for primitives (doubles, ints, chars, bytes) because all of those values have static memory addresses, but strings and all other objects can be in different instances, which means that even though two strings have the exact same value, it doesn't necessarily mean the '==' operator will return true for them. For that to be true, they would have to be the exact same instance.
  7. Offline


    I agree with Alvin on a few things.
    For one, he's right when concerning #3 of your arguments. command.getAliases() simply returns a value. Considering you aren't using it or altering it, the call of this getter method is doing nothing for you, and if you're trying to alter it, you should be using a setter method, but you're obviously not.
    Secondly, I'd use Bukkit.getPlayer(). Though both methods essentially do the same thing, Bukkit.getPlayer() is much more efficient, and will reduce your "problem count", so to speak.
    Lastly, I believe Alvin is right when talking about the '==' operand. I know you can use it to compare "doubles, ints, chars, bytes", as Alvin said, but here's why I remember why you should be using the #equals() or #equalsIgnoreCase() methods:
    As I recall, the '==' operand does actually compare memory addresses, as it can also be used to compare objects. Strings are objects, but they're not used like most objects that you'd create are. This is why those methods were created. You should be using either #equals(), or the one I recommend most out of the two, #equalsIgnoreCase().
  8. I wouldn't go around saying that this is an 'exact copy' of Hypixel's code. Their developers spent a long time making the server-wide Watchdog and report system that works across hundreds of their servers and in games and doesn't simply just send an alert to staff.

    Calling something like this an "exact replica" is a little bit of an insult to how complicated their code is.


    For the '==' situation - That works for primitive data types(doubles, ints, floats, booleans, etc..) but in Java, a String is an Object, they just get special treatment to be used similarly to primitive types. So .equals() or .equalsIgnoreCase() is better for strings even though '==' would technically work.

    Also, this wouldn't work if a user has multiple args to report someone like '/report Example Anti Knockback

    You force someone to make it one word when you can make a string with all the arguments that are 1 and above and send that
    Last edited: Nov 25, 2017
Thread Status:
Not open for further replies.

Share This Page