Plugin YAML - Main: error

Discussion in 'Plugin Development' started by Classy, Nov 12, 2014.

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

    Classy

    Hey guys, I have just finished making my first nice plugin; cEssentials. After I exported it into the \plugins directory and ran the server, I was immediately sent an error message telling me "Couldn't find main class 'me.ClassyCoconut.cEssentials'". I was devastated by this text and instantly tried to find a solution to it. Alas, I couldn't find any fixes which is why I came here as my last hope.

    Plugin.YML - http://hastebin.com/otaxiwugir.sm

    Code:
    name: cEssentials
    main: me.ClassyCoconut.cEssentials
    version: 1.0
    commands:
      admin:
      teleport:
      vanish:
      ban:
      check:
      unban:
      clearchat:
      heal:
      clear:
      broadcast:
      kill:
      killall:
      inventory:
      message:
      reply:
      join:
      leave:
      fly:
      skull:
      help:

    Main.class - http://hastebin.com/atuvaruxuq.avrasm

    Code:java
    1. package me.ClassyCoconut.cEssentials;
    2.  
    3. import java.io.File;
    4. import java.util.ArrayList;
    5.  
    6. import me.ClassyCoconut.cEssentials.Commands.CommandAdmin;
    7. import me.ClassyCoconut.cEssentials.Commands.CommandBan;
    8. import me.ClassyCoconut.cEssentials.Commands.CommandBroadcast;
    9. import me.ClassyCoconut.cEssentials.Commands.CommandCheck;
    10. import me.ClassyCoconut.cEssentials.Commands.CommandClearChat;
    11. import me.ClassyCoconut.cEssentials.Commands.CommandClearInventory;
    12. import me.ClassyCoconut.cEssentials.Commands.CommandDeop;
    13. import me.ClassyCoconut.cEssentials.Commands.CommandHeal;
    14. import me.ClassyCoconut.cEssentials.Commands.CommandInvSee;
    15. import me.ClassyCoconut.cEssentials.Commands.CommandJoin;
    16. import me.ClassyCoconut.cEssentials.Commands.CommandKill;
    17. import me.ClassyCoconut.cEssentials.Commands.CommandKillAll;
    18. import me.ClassyCoconut.cEssentials.Commands.CommandLeave;
    19. import me.ClassyCoconut.cEssentials.Commands.CommandMe;
    20. import me.ClassyCoconut.cEssentials.Commands.CommandMessage;
    21. import me.ClassyCoconut.cEssentials.Commands.CommandReply;
    22. import me.ClassyCoconut.cEssentials.Commands.CommandSkull;
    23. import me.ClassyCoconut.cEssentials.Commands.CommandTeleport;
    24. import me.ClassyCoconut.cEssentials.Commands.CommandUnban;
    25.  
    26. import org.bukkit.Bukkit;
    27. import org.bukkit.Material;
    28. import org.bukkit.configuration.file.FileConfiguration;
    29. import org.bukkit.configuration.file.YamlConfiguration;
    30. import org.bukkit.entity.Player;
    31. import org.bukkit.event.EventHandler;
    32. import org.bukkit.event.Listener;
    33. import org.bukkit.event.player.AsyncPlayerChatEvent;
    34. import org.bukkit.event.player.PlayerJoinEvent;
    35. import org.bukkit.event.player.PlayerLoginEvent;
    36. import org.bukkit.inventory.ItemStack;
    37. import org.bukkit.inventory.meta.SkullMeta;
    38. import org.bukkit.plugin.PluginManager;
    39. import org.bukkit.plugin.java.JavaPlugin;
    40.  
    41. public class Main extends JavaPlugin implements Listener {
    42.  
    43. public ArrayList<String> admin = new ArrayList<String>();
    44. public ArrayList<String> vanished = new ArrayList<String>();
    45.  
    46. public void onEnable() {
    47. System.out.println("cEssentials was enabled!");
    48. PluginManager pm = Bukkit.getPluginManager();
    49. pm.registerEvents(this, this);
    50. connectCommands();
    51. }
    52.  
    53. public void onDisable() {
    54. System.out.println("cEssentials was disabled!");
    55. }
    56.  
    57. @SuppressWarnings("deprecation")
    58. @EventHandler
    59. public void onPlayerJoin(PlayerJoinEvent event) {
    60. Player player = event.getPlayer();
    61. for(String players : vanished) {
    62. Player vanishedPlayers = Bukkit.getPlayer(players);
    63. vanishedPlayers.hidePlayer(player);
    64. }
    65. }
    66.  
    67. @EventHandler
    68. public void onLogin(PlayerLoginEvent event) {
    69. Player player = event.getPlayer();
    70. if(player.isBanned()) {
    71. FileConfiguration config = null;
    72. File file = new File("plugins" + File.separator + "cEssentials" + File.separator + "players" + File.separator + player.getName());
    73. config = YamlConfiguration.loadConfiguration(file);
    74. String banreason = config.getString("ban_reason");
    75. String bannedby = config.getString("ban_sender");
    76. event.disallow(PlayerLoginEvent.Result.KICK_BANNED, "§7You were banned for " + banreason);
    77.  
    78. }
    79. }
    80.  
    81. public void clearInv(Player p)
    82. {
    83. for(int j=0; j<38; j++)
    84. {
    85. p.getInventory().setItem(j, null);
    86. }
    87. p.getInventory().setHelmet(null);
    88. p.getInventory().setChestplate(null);
    89. p.getInventory().setLeggings(null);
    90. p.getInventory().setBoots(null);
    91. }
    92.  
    93. public void connectCommands() {
    94. getCommand("admin").setExecutor(new CommandAdmin());
    95. getCommand("teleport").setExecutor(new CommandTeleport());
    96. getCommand("ban").setExecutor(new CommandBan());
    97. getCommand("check").setExecutor(new CommandCheck());
    98. getCommand("unban").setExecutor(new CommandUnban());
    99. getCommand("clearchat").setExecutor(new CommandClearChat());
    100. getCommand("heal").setExecutor(new CommandHeal());
    101. getCommand("clear").setExecutor(new CommandClearInventory());
    102. getCommand("broadcast").setExecutor(new CommandBroadcast());
    103. getCommand("kill").setExecutor(new CommandKill());
    104. getCommand("killall").setExecutor(new CommandKillAll());
    105. getCommand("inventory").setExecutor(new CommandInvSee());
    106. getCommand("reply").setExecutor(new CommandReply());
    107. getCommand("message").setExecutor(new CommandMessage());
    108. getCommand("skull").setExecutor(new CommandSkull());
    109. getCommand("deop").setExecutor(new CommandDeop());
    110. getCommand("me").setExecutor(new CommandMe());
    111. getCommand("join").setExecutor(new CommandJoin());
    112. getCommand("leave").setExecutor(new CommandLeave());
    113. }
    114. }


    Please, people of Bukkit, save my plugin.
     
  2. Offline

    teej107

    Taken from http://wiki.bukkit.org/Plugin_YAML
     
  3. Offline

    mythbusterma

    Classy

    Use the proper access modifier (private) and use proper case in your packages, that's awful to look at.
     
  4. Offline

    Classy

    Could you give me a example of those two things? I have never heard of proper case. mythbusterma

    EDIT: Nevermind I fixed it up :)

    I just received errors with my main class after I tried to use the command /vanish. Can anyone help by telling me what I failed at in the main?

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

    ColonelHedgehog

    Could you post your error log please?
     
  6. Offline

    Classy

  7. Offline

    ColonelHedgehog

    I'm guessing in your CommandAdmin class, you have a "Main" variable that you assigned a value of "new Main()" to? Can you post that class please?
     
  8. Offline

    Classy

    ColonelHedgehog Sure,
    Code:java
    1. package me.ClassyCoconut.cEssentials.Commands;
    2.  
    3. import me.ClassyCoconut.cEssentials.Main;
    4.  
    5. import org.bukkit.GameMode;
    6. import org.bukkit.command.Command;
    7. import org.bukkit.command.CommandExecutor;
    8. import org.bukkit.command.CommandSender;
    9. import org.bukkit.entity.Player;
    10.  
    11. public class CommandAdmin extends Main implements CommandExecutor {
    12.  
    13. public boolean onCommand(CommandSender sender, Command cmd, String tag, String[] args) {
    14. if(!(sender instanceof Player)) {
    15. sender.sendMessage("§cYou can not use this command via Console!");
    16. return true;
    17. }
    18. Player player = (Player) sender;
    19. if(sender.hasPermission("cess.admin"));
    20. if(admin.contains(player.getName())) {
    21. player.showPlayer(player);
    22. player.setGameMode(GameMode.SURVIVAL);
    23. player.sendMessage("§7You are now in PLAY mode!");
    24. admin.remove(player.getName());
    25. } else {
    26. player.setGameMode(GameMode.CREATIVE);
    27. player.hidePlayer(player);
    28. player.sendMessage("§7You are now in ADMIN mode!");
    29. admin.add(player.getName());
    30. }
    31. return false;
    32. }
    33.  
    34. }
    35.  
     
  9. Offline

    AzureDev

    Classy
    CommandAdmin shouldn't extend Main, which is why it's saying "Plugin already initialized!"
     
  10. Offline

    Classy

    AzureDev so should I just change that line to

    EDIT: If I do this (Under this Text) the whole cmd won't work as it has an ArrayList in the Main class
    1. public class CommandAdmin implements CommandExecutor{
     
  11. Offline

    AzureDev

    Classy
    Make a static method/variable for Main in the Main class and then implement it into CommandAdmin?
     
  12. Offline

    Classy

  13. Offline

    Relicum

    AzureDev why recommend that if the only place he needs to use the array is in the command class. Move the array and the PlayerJoinEvent into that class as well.
     
  14. Offline

    AzureDev

  15. Offline

    Classy

    Relicum So would I just remove the Extends Main and place the array into it? btw I do not have a PlayerJoinEvent for CommandAdmin.
     
  16. Offline

    Relicum

    The reason why vanish doesn't work is you never assign it its executor, see the list in your Main class. Just because vanish is in your plugin.yml how does it know that its executor is the admin class ??

    Also do not save the players using their names as player reference as they are no longer its unique identifier, use the UUID of the player as that is what its indexed under locally. Depending on what version of craftbukkit your using when you try and do player lookup by names it has to send a web request to mojang to get the UUID for that name, this can become a blocking method if mojang is busy.

    Also the Arraylist is not syncronised and your run into loads of issues with concurrentmodification errors. As the bare minimum create the Arraylist like this.

    Code:java
    1. private List<UUID> players = Collections.synchronizedList(new ArrayList<>());


    Google what it all means.

    PS Also the if/else statement in the CommandsAdmin never returns true and will always fall through to the return false statement below it. This will cause you confusion as it will keep showing the command usage.

    Regards


    That is correct, but think about it if you could not access the array from CommandAdmin as it was in main if you move it into CommandsAdmin, how is the playerJoinEvent going to now access the array ???

    Also I can't actually see what the difference between you Admin and Vanish command, as there is no logic specific to Vanish in CommandsAdmin. Yes you update the vanish status. But that's not a different command to admin. Can you explain the difference between the 2 ??

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

    mythbusterma

    Relicum

    Why does that need to be synchronized, it's never used in more than one thread so what would cause it to need to be synchronized? All you're doing with that is slowing it down. Furthermore, requesting an online Player's UUID is never "blocking," it is always (nearly) instantaneous .
     
  18. Offline

    Classy

    Relicum I have two different classes, CommandAdmin and CommandVanish. Also after I added Vanish to the list of executing cmds, It still hadn't worked.
    This is the vanish code

    Code:
    package me.ClassyCoconut.cEssentials.Commands;
     
    import java.util.ArrayList;
     
    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
     
    public class CommandVanish implements CommandExecutor {
       
        public ArrayList<String> vanished = new ArrayList<String>();
       
        public boolean onCommand(CommandSender sender, Command cmd, String tag, String[] args) {
            if(!(sender instanceof Player)) {
                sender.sendMessage("§cYou can not use this command via Console!");
                return false;
            }
            return false;
        }
        public void vanish(Player player) {
        if(player.hasPermission("cess.vanish"));
            if(isVanished(player)) {
                for (Player players : Bukkit.getOnlinePlayers()) {
                    players.hidePlayer(player);
                    vanished.add(player.getName());
                    player.sendMessage("§7You are now invisible.");
                }
            } else {
                for (Player players : Bukkit.getOnlinePlayers()) {
                    players.hidePlayer(player);
                    vanished.remove(player.getName());
                    player.sendMessage("§7You are now visible.");
                }
            }
        }
       
        public void vanishPlayer(Player player) {
        if(player.hasPermission("cess.vanish"));
            if (isVanished(player)) {
                player.sendMessage("§7You are already invisible.");
                return;
            }
            for (Player players : Bukkit.getOnlinePlayers()) {
                players.hidePlayer(player);
                vanished.add(player.getName());
            }
        }
           
     
        public void unvanishPlayer(Player player) {
        if(player.hasPermission("cess.vanish"));
            if (isVanished(player)) {
                player.sendMessage("§7You are already visible.");
                return;
            }
            for (Player players : Bukkit.getOnlinePlayers()) {
                players.hidePlayer(player);
                vanished.remove(player.getName());
                player.sendMessage("§7You are now invisible.");
            }
        }
       
        public boolean isVanished(Player player) {
            if(vanished.contains(player.getName()));
            return false;
        }
    }
    
     
  19. Offline

    mythbusterma

    Classy

    Because your "vanish" method is apparently not being invoked?
     
  20. Offline

    Relicum


    haha funniest thing I have heard in a long time, of course its blocking for a start when ever the login servers are down its blocking and its near instant "most" of the time give to cached conditions. When will you people learn, regardless of access time to lookup the UUID using the player name, this is adding latency, when if storing by uuid it can return the way in the fastest possible time due to it being an index.

    How can you possible know what the rest of his code is doing in regards to that array. Also just because its "running" on the main thread doesn't stop to objects trying to access it at the same time. Do you homework.
     
  21. Offline

    Classy

    mythbusterma Relicum How do I invoke it?
     
  22. Offline

    Relicum

  23. Offline

    mythbusterma

    Relicum

    The objects it's accessing are unmodifiable fields stored in the base player class that is created when the user joins the server, the only time the lookup is done is when the user joins the server. There is absolutely zero latency when accessing a field from a series of getters, only the time it takes to execute the instruction (possibly the time it takes to lookup the value in memory). If the login servers are down, it won't even let the player join the game, assuming the server isn't cracked. Also, as long as none of his objects are trying to access it from a different thread, then nothing will. Nobody writing the JVM was stupid enough to ignore thread safety to the point where you would need to synchronize lists for no reason.
     
    Rocoty likes this.
  24. Offline

    glasseater

    Classy Do not use
    Code:
    §7
    use
    Code:java
    1. (ChatColor.GRAY + " ");
    instead. It is a bad habit get into. Good luck! :)
     
  25. Offline

    ColonelHedgehog

    Says who? The ChatColor enum has always been a waste of time for me.
     
  26. Offline

    Rocoty

    ColonelHedgehog Probably won't happen, but hypothetically, what if the underlying chat formatting format changed? All that would have to be updated would be the ChatColor enum, and assuming you used the enums ypu wouldn't have to change your code at all. Not such a waste of time now, is it? This is the whole point of abstraction. Further it makes your code a lot more readable.
     
    AdamQpzm likes this.
  27. Offline

    glasseater

    Rocoty Beat me to it! Well said! :)
     
  28. Offline

    ColonelHedgehog

    Most IDEs have a replace-all-in-project command. That's a very specific instance which will most likely never happen. Besides, wouldn't that mean the ChatColor enum would, in theory, have to be changed too?
     
  29. Offline

    Rocoty

    ColonelHedgehog That's what I said, yes. The ChatColor enum would have to change, but not your code (assuming you use the ChatColor enum), or any other code for that matter. Because the ChatColor enum serves as a layer of abstraction between the chat format and your code. Using replace-all would still mean you'd have to recompile your code, which in most cases isn't desirable.

    It basically means you wouldn't have to release new versions of your plugin so long as Bukkit follows up with the change. What the users of your plugin would have to do is simply to update Bukkit, and your plugin will work just as well as it's always done. But, yes. I agree ChatColor is a bad example.
     
  30. Offline

    ColonelHedgehog

    And of course the flaw with Bukkit updating is that we're not sure it ever will. It takes way less time to update your plugin than it does for Bukkit to update. ;)
     
Thread Status:
Not open for further replies.

Share This Page