Command executors for each command

Discussion in 'Plugin Development' started by davejavu, May 16, 2012.

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

    davejavu

    Yes, it sound simple, but I'm coding a plugin with 80+ commands, and want a quick an easy way to make commands register to the class file of their name, in a different package, for example, I'd want the command "derp" to register to me.davejavu.test.command.derp without having to make a private commandexecutor etc etc.. anyone?
     
  2. Offline

    ams2990

    For a String s that contains the name of the command...

    getCommand(s).setExecutor(Class.forName("me.davejavu.test.command."+s+"."+s).newInstance());
     
  3. Offline

    Ne0nx3r0

    Just out of curiosity, what do you need 80 commands for?
     
  4. Offline

    davejavu

    Error:
    Show Spoiler
    Code:
    2012-05-19 18:52:52 [SEVERE] Could not register command: creative
    2012-05-19 18:52:52 [SEVERE] java.lang.InstantiationException: me.davejavu.RandomStuff.command.cmdcreative
    2012-05-19 18:52:52 [SEVERE]     at java.lang.Class.newInstance0(Unknown Source)
    2012-05-19 18:52:52 [SEVERE]     at java.lang.Class.newInstance(Unknown Source)
    2012-05-19 18:52:52 [SEVERE]     at me.davejavu.RandomStuff.RandomStuff.onEnable(RandomStuff.java:86)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:215)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:336)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:381)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.craftbukkit.CraftServer.loadPlugin(CraftServer.java:250)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.craftbukkit.CraftServer.enablePlugins(CraftServer.java:232)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.craftbukkit.CraftServer.reload(CraftServer.java:543)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.Bukkit.reload(Bukkit.java:182)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:22)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:166)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:473)
    2012-05-19 18:52:52 [SEVERE]     at org.bukkit.craftbukkit.CraftServer.dispatchServerCommand(CraftServer.java:469)
    2012-05-19 18:52:52 [SEVERE]     at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:596)
    2012-05-19 18:52:52 [SEVERE]     at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:565)
    2012-05-19 18:52:52 [SEVERE]     at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:449)
    2012-05-19 18:52:52 [SEVERE]     at net.minecraft.server.ThreadServerApplication.run(SourceFile:492)



    Code:
    Show Spoiler
    Code:java
    1. for (String x : getConfig().getStringList("enabled-commands")){
    2. try{
    3. getCommand(x).setExecutor((CommandExecutor) Class.forName("me.davejavu.RandomStuff.command.cmd"+x).newInstance());
    4. }catch (Exception e){
    5. log.log(Level.SEVERE, "Could not register command: " + x);
    6. e.printStackTrace();
    7. }
    8.  
    9. }
    [/code]
    Any ideas?
     
  5. Show Spoiler


    I think your commands package is: me.davejavu.RandomStuff.command.cmd.*
    and you get an error because java searches for a class called me.davejavu.RandomStuff.command.cmdcreative
    instead of me.davejavu.RandomStuff.command.cmd.creative, which i think you want to use.
    greetz blackwolf12333
    PS: sorry for the spoiler, got no idea why that happens to me:p
     
  6. Offline

    Njol

    taken from the Javadoc of Class.newInstance():
    InstantiationException - if this Class represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.

    Your commands likely don't have a nullary constructor (i.e. a constructor which takes no arguments).
    If your commands e.g. take the plugin as argument, you have to change .newInstance() to .getConstructor(YourPlugin.class).newInstance(plugin).
     
  7. Offline

    davejavu

    The "YourPlugin.class", what would I change that to if the command was for example "creative"
     
  8. Offline

    Njol

    It would be YourPlugin.class for all commands, since it's the argument of the constructor, not the class of the command.
     
  9. Offline

    davejavu

    Okay, I did that, now I'm getting this error:
    Show Spoiler
    Code:
    2012-05-19 19:56:19 [SEVERE] Could not load 'plugins\RandomStuff.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidPluginException: java.lang.NoSuchMethodException: me.davejavu.RandomStuff.RandomStuff.<init>()
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:150)
        at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:305)
        at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:230)
        at org.bukkit.craftbukkit.CraftServer.loadPlugins(CraftServer.java:207)
        at org.bukkit.craftbukkit.CraftServer.<init>(CraftServer.java:183)
        at net.minecraft.server.ServerConfigurationManager.<init>(ServerConfigurationManager.java:53)
        at net.minecraft.server.MinecraftServer.init(MinecraftServer.java:156)
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:422)
        at net.minecraft.server.ThreadServerApplication.run(SourceFile:492)
    Caused by: java.lang.NoSuchMethodException: me.davejavu.RandomStuff.RandomStuff.<init>()
        at java.lang.Class.getConstructor0(Unknown Source)
        at java.lang.Class.getConstructor(Unknown Source)
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:142)
        ... 8 more
     
  10. Offline

    Njol

    As I said it depends on how the constructors of your commands look like. Can you post one example command class?
     
  11. Offline

    davejavu

    Show Spoiler
    Code:java
    1. package me.davejavu.RandomStuff.command;
    2.  
    3. import org.bukkit.ChatColor;
    4. import org.bukkit.Location;
    5. import org.bukkit.World;
    6. import org.bukkit.block.Block;
    7. import org.bukkit.command.Command;
    8. import org.bukkit.command.CommandExecutor;
    9. import org.bukkit.command.CommandSender;
    10. import org.bukkit.entity.Player;
    11.  
    12. public class cake implements CommandExecutor {
    13.  
    14. @Override
    15. public boolean onCommand(CommandSender sender, Command cmd, String arg2,
    16. String[] args) {
    17. Player player = (Player) sender;
    18. if(cmd.getName().equalsIgnoreCase("cake")){
    19. if (player.hasPermission("RandomStuff.cake")){
    20. Location loc = player.getLocation();
    21. World world = loc.getWorld();
    22. loc.setY(player.getLocation().getY() - 1);
    23. Block blockunderplayer = world.getBlockAt(loc);
    24. blockunderplayer.setTypeId(92);
    25. player.sendMessage(ChatColor.AQUA + "Look" + ChatColor.GOLD + "down" + ChatColor.DARK_PURPLE + "!");
    26. return true;
    27. }else{
    28. player.sendMessage(ChatColor.RED + "No permission!");
    29. return true;
    30. }
    31. }
    32. return false;
    33. }
    34.  
    35. }
    36.  

    The class used to be cmdcake.java, renamed it to cake.java for simplicity :p
     
  12. Offline

    Njol

    The class doesn't have a public constructor and thus can't be instantiated by your main class. Try to write new cmdcake() in your main class and you'll see the error.
    You have two possibilities:
    Either add a public constructor to all commands, or use some more reflection:
    Code:
    Constructor<?> con = Class.forName("me.davejavu.RandomStuff.command.cmd"+x).getConstructor();
    con.setAccessible(true);// this makes the constructor public
    getCommand(x).setExecutor((CommandExecutor) con.newInstance());
     
  13. Offline

    davejavu

    Njol the constructor thingy didn't work.
    What was the other option?
     
  14. Offline

    Njol

    To use the code in my previous post instead of simply class.newInstance().
     
  15. Offline

    ams2990

    Wrong. He has no explicit constructor, which means there is a implicit public no-args constructor.

    With the source code he posted, he should use getCommand(s).setExecutor(Class.forName("me.davejavu.test.command."+s).newInstance());
     
  16. Offline

    davejavu

    No I mean I already used the code in your last post, whats the other option?

    How to fix that?

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

    Njol

    You're right, I just tested it.
    He already did that and got an InstantiationException, which is thrown
    Do you have any idea what the "other reason" could be in this case?
     
  18. Offline

    davejavu

    Uhm.... >.>
    ams2990
     
  19. Offline

    davejavu

Thread Status:
Not open for further replies.

Share This Page