New RB breaks my plugin?

Discussion in 'Plugin Development' started by ChrizC, May 21, 2011.

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

    ChrizC

    Hey guys,

    I updated to the new RB, and now my plugin is broken.
    My plugin (NetherrackDamage) damages the player when they are in contact with Netherrack.

    The event fires (I print out to the console fine) but it doesn't start damaging the player (which is dealt via a scheduler.)

    Also, when I reload the plugins, I get this about 30 times:
    Code:
    13:15:07 [SEVERE] Nag author: 'ChrizC' of 'NetherrackDamage' about the following
    : This plugin is not properly shutting down its async tasks when it is being rel
    oaded.  This may cause conflicts with the newly loaded version of the plugin
    Any ideas?

    Chris
     
  2. Offline

    Raphfrk

    That means that you are starting async tasks using the scheduler and then they are not ending for some reason.

    I has a look at the source, and it looks like you are using async tasks to damage the player. Interactions with Player objects should be handled by the sync queue.

    You are then clearing all tasks if the player moves off the rock.

    I am not sure that is the best way to handle it.

    One option would be to set up a single task that does all the damage and have that tick once per second.

    In onMove, you can then check if a player has changed block. Use getBlockX() etc. for the from and to location.

    If there is a difference, you can then check if the player is walking on netherrack.

    If so, add the player to a ConcurrentHashMap. If the player leaves, then you remove the player from the map.

    The damage task then checks if the map is empty and if not, it goes through all the players and damages them.

    You can then create a hash map in your plugin class:

    Code:
    ConcurrentHashMap<String,Integer> playersToDamage = new ConcurrentHashMap<String,Integer>();
    
    The Runnable would be something like the following and you pass it the playersToDamage map in its constructor.

    You can then submit it to the scheduler as a sync task.

    Code:
    public class DamagePlayer implements Runnable {
    
        ConcurrentHashMap<String,Integer> playersToDamage;
    
        public DamagePlayerRunnable(ConcurrentHashMap<String,Integer> playersToDamage) {
            this.playersToDamage = playersToDamage;
        }
    
        public void run() {
    
            if(playersToDamage.isEmpty()) {
                return;
            }
    
            for(String current : playersToDamage.keySet.iterator()) {
                Integer damage = playersToDamage.get(current);
                if(damage != null) {
                    Player player = getServer().getPlayer(current);
                    player.damage(damage);
                }
            }
        }
    
    }
    
     
  3. Offline

    ChrizC

    Hi,

    thanks for your reply. I managed to fix it. It seems my configuration file had been incorrectly generated.

    That code sounds like a lot of over-complication. My current method works well enough so I'm not likely to change any time soon.

    Thanks anyway.

    Chris
     
  4. Offline

    Raphfrk

    Fair enough, though I think my method is actually simpler. You are creating a ton of async tasks, when you only need 1 sync task.

    Also, using an async task to access Player objects could cause problems (though some of the methods are thread safe).
     
Thread Status:
Not open for further replies.

Share This Page