Allowing a plugin to load after another?

Discussion in 'Plugin Development' started by CRAZYxMUNK3Y, Jul 2, 2012.

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

    CRAZYxMUNK3Y

    I did a bit of research first but i couldn't really find anything...

    Is there anyway to check if another plugin has been enabled and loaded first before mine does?
    Eg:
    Mine goes to load > Checks if other is enabled > If it's not, wait's and checks later > If other is enabled, my plugin loads.

    Thanks
     
  2. Offline

    Codex Arcanum

    Can't you just set a dependency in plugin.yml?
     
  3. Offline

    CRAZYxMUNK3Y

    I could, but my plugin does not require Multiverse to load...

    The ticket that was made is here if you want to look at it.
     
  4. Offline

    EnvisionRed

    Set a softdependency?
     
  5. Offline

    sayaad

    You can just set the event priority to lowest because bukkit will load in order of descending prioritys and only plugins that checks for this priority is lowest.
     
  6. Offline

    CRAZYxMUNK3Y

    That won't work... What is happening is that as the plugins load, Multiverse loads all the worlds, then my plugin would load the worlds that have been loaded...

    So if my plugin loads first, it only works in default worlds, and not the extra ones that may have been made with Multiverse
     
  7. Offline

    desht

    To do this reliably, you can't load any world-dependent data until you know the world in question is available. There is an event for this: WorldLoadEvent.

    The best approach is probably to load as much as possible in your onEnable(), but for any data where the world isn't available (generally, you'll be trying to deserialize a World in some way, so Bukkit.getWorld() on the saved world name will return null), you need to mark that data as deferred, and then when you later get a WorldLoadEvent, you can go ahead and load the data.

    Do it this way, and you don't need to care when your plugin loads in relation to any world management plugin. Adding a dependency on Multiverse isn't a solution, because it's not the only world management plugin out there.

    Edit: there is another, simpler way: defer your data loading with a sync delayed task (delayed by a single tick). That task won't get called until all plugins are loaded and the server is up and running. However: if any other plugins use (depend on) yours, this approach is not an option, since your data won't be available to those plugins when they're starting up. Also, this approach will fail if world loading has been deferred by whatever world management plugin is in effect. The only truly reliable way to do it is in response to the WorldLoadEvent.
     
    ferrybig likes this.
  8. Offline

    CRAZYxMUNK3Y

    desht

    Sorry about the delay, been busy...

    I will try those two option when i get some more time, and thanks for the reply...
     
  9. Offline

    CRAZYxMUNK3Y

    This is my first time working like this with worlds...

    All i can currently really think of is;
    Code:java
    1.  
    2. public void checkForWorlds(World WorldLoadEvent){
    3. World world = ((WorldEvent) WorldLoadEvent).getWorld();
    4. if(world.isChunkLoaded((Chunk) world.getSpawnLocation())){
    5. return;
    6. }else{
    7. // Check till it can get spawn.
    8. }
    9.  


    Would something like that work or not?
    Thanks
     
  10. Offline

    desht

    I'm not sure why you need to check for loaded chunks, but the ticket you linked to doesn't make clear what the original problem is...

    Anyway, it is possible to do block operations on a loaded world without explicitly loading the block's chunk - Minecraft will load the chunk for you if necessary.
     
  11. Offline

    CRAZYxMUNK3Y

    The original problem is that when my plugin loads first, it only works on the default worlds, but when MultiVerse/another world management plugin loads first it will all work fine.

    Hopefully that makes sense.
     
  12. Offline

    desht

    Yeah, I got that - which is why I explained how you need to hook the WorldLoadEvent to know when a world is really loaded. You never mentioned anything about chunks being loaded, though, and I don't see the relevance.
     
  13. Offline

    CRAZYxMUNK3Y

    I used the chunk load as i couldn't find a world.isLoaded() type method and assumed that the spawn chunk would be loaded first.

    I'm just not sure on how it would be done(Code wise). If it's possible, a small code would go a long way!

    Thanks
     
  14. Offline

    desht

    The whole point of using the WorldLoadEvent is that you don't need to check if the world is loaded; once you get the event, you know for sure that it is.

    Not sure I can really provide a small code example, but here's one working example: https://github.com/desht/ScrollingM...me/desht/scrollingmenusign/views/SMSView.java
    • My view objects contain a list of zero or more Locations (actually my PersistableLocation class, but same idea) (line 60)
    • The thaw() method loads co-ordinate data in from a saved .yml file and tries to create a Location out of it (see around line 214)
    • If I get a IllegalStateException from pl.getLocation() (line 216), then I know the world for that particular location isn't available (yet), so I put that particular location onto a deferred list (line 220) . That IllegalStateException is thrown from my PersistableLocation class if the Bukkit.getWorld() call for the saved world name returned null.
    • In https://github.com/desht/ScrollingM...llingmenusign/listeners/SMSWorldListener.java I hook the WorldLoadEvent, and for the world that's just been loaded, I call SMSView.loadDeferred(event.getWorld());
    • That static method iterates through all known view objects and if any have deferred locations for the world that's just been loaded, it resolves them and registers the locations (SMSView lines 759-775)
    It's all a little involved but it works. I'm not sure there's really any much simpler way to do it.
     
Thread Status:
Not open for further replies.

Share This Page