Solved Can't reference plugin object outside of main class

Discussion in 'Plugin Development' started by Maurdekye, Jan 8, 2014.

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

    Maurdekye

    Without running into static issues, at least. This is more of a Java problem than a Bukkit problem, but I need help nonetheless.

    I'm currently making a plugin that turns certain tools into guns that fire arrows. In order to change the damage that each arrow does, I tried to attach Metadata to each arrow fired to determine how much damage it does on impact. As such, I wrote the following methods:
    Code:java
    1. public void playerShootArrow(Player ply, float velocity, float spread, String type, Plugin plug) {
    2. Arrow arrow = ply.getWorld().spawnArrow(ply.getEyeLocation(), ply.getLocation().getDirection(), velocity, spread);
    3. arrow.setShooter(ply);
    4. arrow.setMetadata("type", new FixedMetadataValue(plug, type));
    5. }
    6.  
    7. public String getArrowType(Arrow ent, Plugin plug) {
    8. List<MetadataValue> values = ent.getMetadata("type");
    9. for(MetadataValue value : values){
    10. if(value.getOwningPlugin().getDescription().getName().equals(plug.getDescription().getName())){
    11. return value.asString();
    12. }
    13. }
    14. return null;
    15. }

    The main problem I have is passing the plugin object to the functions. From within the main class, I have no problems,
    Code:java
    1. playerShootArrow(ply, 4, 2, "sniper", this);
    but what I want is to find the arrow type when damage is dealt, so I have to call the proper method from within the listener class. But whenever I try that,
    Code:java
    1. MainFile.getArrowType(arrow, /*???*/);
    I don't know how to reference the main plugin object within the listener class. So, I created a generic plugin variable in the main class,
    Code:java
    1. Plugin plug = this;
    but whenever I plug it into the empty space in the method above,
    Code:java
    1. MainFile.getArrowType(arrow, MainFile.plug);
    it tells me I can't make a static reference to a non-static field. But when I add a static modifier to the 'plug' variable, I can't define it with the word 'this' anymore. I'm not the best Java programmer, if anyone can help please do.
     
  2. Offline

    Pizza371

    Maurdekye
    you can pass an instance of your main class through the constructor
    Code:
    public <YourListenerClass>(Main m) { //in your listener class, the constrctor, main is your Main class
    this.mainInstance = m;
    }
    or use getPlugin method which requires a String
     
  3. Offline

    Maurdekye

    Thanks, I don't quite understand your first suggestion, but MainFile.getPlugin(MainFile.class) seems to get rid of the nasty red lines in my listener class.

    Now, if only I could figure out how to actually deal damage to the player being hit... the ProjectileHitEvent doesn't return the entity being hit within the event variable.

    Nope, didn't work. I got an error when starting my server up;
    Code:
    [10:42:36] [Server thread/ERROR]: Could not load 'plugins\Gunslingers.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidPluginException: java.lang.IllegalStateException: Cannot get plugin for class mainpackage.MainFile from a static initializer
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:137) ~[craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:308) ~[craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:231) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at org.bukkit.craftbukkit.v1_7_R1.CraftServer.loadPlugins(CraftServer.java:255) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at org.bukkit.craftbukkit.v1_7_R1.CraftServer.<init>(CraftServer.java:233) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at net.minecraft.server.v1_7_R1.PlayerList.<init>(PlayerList.java:63) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at net.minecraft.server.v1_7_R1.DedicatedPlayerList.<init>(SourceFile:14) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at net.minecraft.server.v1_7_R1.DedicatedServer.init(DedicatedServer.java:126) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at net.minecraft.server.v1_7_R1.MinecraftServer.run(MinecraftServer.java:424) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at net.minecraft.server.v1_7_R1.ThreadServerApplication.run(SourceFile:617) [craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
    Caused by: java.lang.IllegalStateException: Cannot get plugin for class mainpackage.MainFile from a static initializer
        at org.bukkit.plugin.java.JavaPlugin.getPlugin(JavaPlugin.java:442) ~[craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at mainpackage.MainFile.<init>(MainFile.java:32) ~[?:?]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.7.0_45]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.7.0_45]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.7.0_45]
        at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:1.7.0_45]
        at java.lang.Class.newInstance(Unknown Source) ~[?:1.7.0_45]
        at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:52) ~[craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:133) ~[craftbukkit_1.7.2.jar:git-Bukkit-1.7.2-R0.2-3-g530fcb7-b2979jnks]
        ... 9 more
    
    Seems to be something about a static initializer. I still have no idea what it means nor how to fix it.

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

    Pizza371

    Is your code big? If not can you post it
     
  5. Offline

    nichiatu

    If you're having trouble referencing your plugin from outside of your main class, this is what a constructor is:

    Code:java
    1. public class arbitrary_event {
    2.  
    3. private MainClass plugin;
    4.  
    5. public arbitrary_event (MainClass mainInstance) {
    6. this.plugin = mainInstance;
    7. }
    8.  
    9. }


    What this code does, is first it defines a class called arbitrary_event. A constructor is built by appending the class name (arbitrary_event in this case) to the keyword public.

    This allows you to use variables and methods from your main class in your listener. Let's say that you have a boolean debug which you fetch from your default config file.

    Code:java
    1. public class arbitrary_event {
    2.  
    3. private MainClass plugin;
    4.  
    5. private boolean debug;
    6.  
    7. public arbitrary_event (MainClass mainInstance) {
    8. this.plugin = mainInstance;
    9.  
    10. // This is the debug variable from your main class
    11. this.debug = plugin.debug;
    12. }
    13.  
    14. }


    In your main class you would do the logic required to get the boolean from your config file.

    Code:java
    1. public class MyPlugin extends JavaPlugin {
    2.  
    3. public boolean debug;
    4.  
    5.  
    6. public void onEnable() {
    7.  
    8. this.debug = this.getConfig().getBoolean("debug");
    9.  
    10. }
    11. }


    To make the listener actually listen, you get the plugin manager, and register the event(s) using the Bukkit API methods.

    Code:java
    1. this.getPluginManager().registerEvents(new arbitrary_event(this), this);


    As you can see, when you're registering the event, you pass in the class of the Event you're listening for, together with the "this" keyword, which specifies the current instance of the main class
     
  6. Offline

    Maurdekye

    Huh, I think I understand that better. I'll see if that works.

    I think I'm getting somewhere. I feel like it's working moreso now, but I still get errors when I try to pull metadata.

    Hah! Success!! It was something completely different, but it works now.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 6, 2016
Thread Status:
Not open for further replies.

Share This Page