[REQ] DOT plugin w/ multiworld support

Discussion in 'Archived: Plugin Requests' started by Avarice, Apr 28, 2012.

  1. Offline

    Avarice

    Looking for a plugin that creates a DOT effect (damage over time) for different worlds with configurable reasons for my RP server.

    Would love to see a configuration similar to this, also the best way that I can explain it:

    Code:
    #worldname:
    #    damage: damage in hearts
    #    interval: time inbetween damage in ticks
    #    msg: message shown when damage is taken from 'environmental factor'
    #    protectionitemid: equippable item to mitigate damage
    world1:
        damage: 1.5
        interval: 50
        msg: '&bYou feel the cold seeping into your bones...'
        protectionitemid: 311
    world2:
        damage: 2.0
        interval: 20
        msg: '&4Your blood is boiling'
        protectionitemid: 315
    Permissions desired:

    plugin.damage
    plugin.allowprotect
    plugin.reload

    What I would REALLY love to see, though, is the ability for items to be used as protection that are in the player's inventory, and to be consumed.

    i.e blaze rods in world1 to protect against cold damage that are consumed every time that damage would be taken.

    But for the sake of simplicity the example given is very satisfactory. :)

    If anyone is interested, please send me a pm!
     
  2. Offline

    Deathmarine

    Damage over time per world.... I got this... Might take a little time... and I hook into vault if that is not a problem
     
  3. Offline

    Avarice

    Not a problem at all! Thank you. ^^ Nice tatt, btw.
     
  4. Offline

    Deathmarine

    Thanks it took 6 hours in the chair to get it done. Now I got really close to what you were looking for. The configuration you gave me wouldn't had to work to well only for the fact of threading.. The interval will be for all worlds also I just noticed your items. I coded this for the item in hand(when I read blaze rod I thought of holding). Which might work for your situation. So I have questions now. Considering this you could make it where you hold ice or snow to cool down (you take damage if it is not in your hand) just the same with holding a torch and not dying by the cold. But I've debugged tested and it works great. Just unsure if this will work for you.
    https://github.com/deathmarine/Enviroffect

    Let me know if there is anything else you need so I can add it in and put up a dload link.

    Code:
    #worldname:
    #    damage: damage in whole hearts
    #    interval: time inbetween damage in secs
    #    msg: message shown when damage is taken from 'environmental factor'
    #    protectionitemid: equippable item to mitigate damage
    world:
        damage: 1
        msg: '&bYou feel the cold seeping into your bones...'
        protectionitemid: 311
    world_nether:
        damage: 2
        msg: '&4Your blood is boiling'
        protectionitemid: 315
    interval: 60
    
     
  5. Offline

    dkabot

    I don't know your code, but I would imagine it's easy enough to change if(player.getItemInHand() == item) to if(player.getInventory().contains(item)).
    At least, using if statements like that is how I would have done it, allowing this. Your code may vary.
     
  6. Offline

    Deathmarine

    I usually don't sync or async threads unless its absolutely necessary considering if a thread fails sync'd to the main thread the server becomes unresponsive.
     
  7. Sync or async threads? You mean using synchronized methods? That's a completely different topic but there's a side note about that at the link, too... Have fun with ConcurrentModificationExceptions and other, really hard to track and reproduceable bugs. Did you even read the link? Some quotes:
    "don't call API methods from other threads (with some exceptions)"
    "Using the wrong thread type can cause intermittent problems that can be very hard to replicate. These problems may only occur on heavily used servers and not on a test server."
    "Very few Bukkit API calls are thread-safe. Unless you have checked that the API call you are making is thread-safe, it is best to assume that it isn't."
    "The main thread MUST be used for
    Tasks which call Bukkit API methods (except thread safe method, see below)"
    Also there was a "nice" thread of bergerkiller explaining why using bukkit API calls from another thread can be a shoot in the foot of other plugins devs. You seem to have no idea about threading (in Java) and why bukkit has (needs) a scheduler API to be able to take some advantages of a new thread without really creating one.
     
  8. Offline

    Deathmarine

    I agree its not that hard, I just don't know what she needs. I'm thinking about using everything considering I think she was talking about wearing armor.
    Code:
    int itemid = config.getInt(world + ".protectionitemid");
    int itemtest = players[i].getItemInHand().getTypeId();
    ItemStack[] testitem = players[i].getInventory().getArmorContents();
    Boolean testarmor = true;
    for (int ii=0; ii<testitem.length; ii++){
    if(testitem[ii].getTypeId() == itemtest) testarmor = false;
    }
    if(itemtest != itemid || !players[i].getInventory().contains(itemtest) || testarmor){
    int dam = config.getInt(world + ".damage");
    players[i].damage(dam);
    players[i].sendMessage(formatMessage(config.getString(world + ".msg")));
    }
    
     
  9. Avarice As Deathmarine doesn't listen and as such will give you a buggy plugin, take this one instead: <Edit by Moderator: Redacted mediafire url>
    It will not create a default config, but the config has to look exactly like in your example, with one exception: damage has to be a integer where 1 = 1/2 heart. Also it has some more features: If you don't set protectionitemid (or set it to -1) there will be no protecting item. Same for msg (and don't wonder that players in creative mode won't see the message and that the item won't be taken away: It's not a bug, it's a feature ;)).

    Reload the config with /AerialTime

    Permissions:
    aerialtime.damage - default: true
    aerialtime.allowprotect - default: true
    aerialtime.reload - default: op
     
    Last edited by a moderator: Nov 10, 2016
  10. Offline

    Deathmarine

    "Tasks which call Bukkit API methods" that actually do something regularly, not pulling information and using a void. I'm not modifying an object, not setting up listeners, working with server ticks, fire ticks, sleep ticks, events, server timing, ect. in a separate thread. So setting the method up async all other tasks, or setting the method sync'd is pointless. But your kind of right I learned java by staring at it.

    Either way compile it and load it up and try it.

    Edit: I just noticed I forgot to push my commit before you saw the source. So the version you saw was buggy. The one that is up now works like a champ.

    If you want to try its posted here. Either way I know it works, But I'm not going to trash your forum thread when I was trying to help not fighting for attention. lol...
    https://github.com/downloads/deathmarine/Enviroffect/Enviroffect.jar

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 25, 2016
  11. Who told you that bs? Look: You:
    Player[] players = plugin.getServer().getOnlinePlayers();
    plugin.getServer() is save, but what does getOnlinePlayers() do? Let's have a look:
    Code:java
    1. public Player[] getOnlinePlayers() {
    2. List<EntityPlayer> online = server.players;
    3. Player[] players = new Player[online.size()];
    4.  
    5. for (int i = 0; i < players.length; i++) {
    6. players[i] = online.get(i).netServerHandler.getPlayer();
    7. }
    8.  
    9. return players;
    10. }[/i]

    So it's reading a list and executing get() on it. Guess what happens if a user loggs on/out in the same moment this executes get()? The list is readed and written at the same time -> ConcurrentModificationException.
    Next:
    int itemtest = players.getItemInHand().getTypeId();
    guess what happens if the player changes a item in a inventory slot while you excute getItemInHand() - what happens if you call getTypeId() while he changes that slot?
    players.damage(dam);
    guess what happens if the player got damage at the same time? What happens if another thing (a plugin for example) reads the damage while you modify it?

    All this may occur very, very rarely but sometimes it will...

    Yes you do, see above. And you're even firering a event:
    players.damage(dam); calls damage at https://github.com/Bukkit/CraftBukk...kit/craftbukkit/entity/CraftLivingEntity.java which calls entityDamage at https://github.com/Bukkit/CraftBukk...n/java/net/minecraft/server/EntityPlayer.java which calls entityDamage (super) at https://github.com/Bukkit/CraftBukk...in/java/net/minecraft/server/EntityHuman.java which calls entityDamage (super) at

    which does this:
    Code:java
    1. // CraftBukkit start
    2. if (damagesource instanceof EntityDamageSource) {
    3. org.bukkit.event.entity.EntityDamageEvent event = CraftEventFactory.handleEntityDamageEvent(this, damagesource, i);
    4. if (event.isCancelled()) {
    5. return false;
    6. }
    7. i = event.getDamage();
    8. }
    9. // CraftBukkit end

    This event will be handled to all plugins which listen for it and that's why you shoot other plugin devs in the foot: The onPlayerDamageEvent() in their listener get's executed in your new thread, which may bring them to access the bukkit API in a non-threadsave way and as such printing a stacktrace which shows that their listener has a bug, even if this isn't the case. I spended hours trying to fix such an error in one of my plugins till I realized that it was not the fault of my plugin: http://forums.bukkit.org/threads/solved-iterator-next-throws-concurrentmodificationexception.52470/

    The sources are included in the plugin I linked for Avarice - feel free to have a look at them to see how to use the scheduler...
     
  12. Offline

    Deathmarine

    lol your way late buddy. I forgot to push the commit. Calm down.
     
  13. What the...? I gave you examples and explained you what you're doing wrong! I wanted to help you understand important things to develop better plugins... But know what: F*ck you!
     
  14. Offline

    Deathmarine

    K? Like I said only trying to help.
     
  15. Deathmarine Instead of reading the text at the link I gave you in my first post you decided that you know it better than the guys who wrote that article (which are guys who know java for many years: They even coded at hmod and then created the Bukkit API) and called me some random guy fighting for attention. I'm not a java expert, too, but if somebody warns me that I may be doing something wrong and sends me a link that explains it I read it and if I have any more questions after that I ask them instead of ignoring the link completely and assuming that I know everything and the link must be wrong.

    Anyway: There are two plugins Avarice can choose from and this goes way off topic. I just hope you'll change your mind soon and realize that nobody knows everything and that a community is there to share experiences (sharing means not only give, but also accept).
     
  16. Offline

    Avarice

    Deathmarine V10lator I appreciate help from both of you. ^_^

    I apologize for the lack of communication, my server was completely wiped on the 27th, I've been working on and off the last few days on trying to get it back up and polish it up.

    What I'm looking for is basically a plugin that just does damage over time with a provided reason definable in the config.

    What's necessary is that there be some sort of item that can mitigate/prevent the damage. What I would love to have, however, is for that item to be configurable as to whether or not the damage prevention object be worn equipment, in the player's hand, or in their inventory. If that item/equipment can be consumed/damaged upon each protection instance, even better!

    The desire for this arises from wanting to add a bit more depth to my slowly progressing RPG server, which has four 'races' for players to choose from, each race tied to a custom generated homeworld.

    Volca, which is a volcanic underworld with a nether environment is going to have heat damage to players who are not of that race. They can, however, carry ice blocks with them to cool down their body temperature and not take damage.

    Aetha is a world with large floating landmasses with air containing a deadly pollen which does not affect the natives, but will harm any individual from other worlds unless they wear an iron helmet.

    Aquis has a polluted water supply which the inhabitants have developed an immunity to, but it will poison visitors unless they carry coal.

    Solum is a frozen world that the locals have no issue with, but anyone else would need to wear a leather chest or carry blaze rods with them to stave off hypothermia.

    Like I said, if my request is too complicated, or just plain ridiculous, the minimal "damage every x seconds on world y unless wearing item z" is totally okay with me, or feel free to say screw it or slap me with java and send me on my way. ^^

    Btw, I have immensely enjoyed plugins that both of you have created; V10Overlap and BukkitSpeak are dead sexy, and my users would not shut UP when we didn't have Identify or RideThaDragon after updating to 1.2.x. Keep up the good work!
     
  17. Avarice The plugin which I linked does exactly this. It is based upon your OP and followed all the rules you mentioned there. It misses only one thing: If you define a damageable item as protectionitemid it will still consume the item instead of damaging it. I'll fix that if you want me to.
     
  18. Offline

    bergerkiller

    V10lator digged my thread up to support you :)

    Deathmarine please don't neglect the fact that cross-thread access can crash the server and cause a lot of headaches for other plugin devs. Concurrent modification exceptions are a true pain, and since pretty much every Bukkit call does something with collection objects (lists, sets, maps), there are very little 'safe' functions you can use. By default never assume a function is 'safe', because even this is unsafe:
    Code:
    public class Test {
        public boolean value = false;
        public String text = null;
       
        public void set(String value) {
            this.text = value;
            this.value = value != null;
        }
     
        public void executeAsync() {
            if (this.value) {
                System.out.println(this.text.contains("test"));
            }
        }
     
    }
    Why? Well, if someone fires set(null) and another thread already passed the value check, it will throw an NPE. This is the case with the entity.remove() function. If someone did a dead check and right after this check you fire remove(), it can cause confusion in the other plugin. Async access is a problematic issue in all languages, though Java tried to make it simple. Unfortunately Bukkit is not thread-safe.
     
    Deathmarine and V10lator like this.
  19. bergerkiller In thought even that was dangerous:
    Code:java
    1. public class Test {
    2. private boolean value = false;
    3.  
    4. public void set(boolean value) {
    5. this.value = value;
    6. }
    7.  
    8. public void get() {
    9. return boolean;
    10. }
    11.  
    12. public void executeAsync() {
    13. value = !value
    14. }
    15. }
    16. }

    As one thread could execute set(true/false) or get() while another executes executeAsync() at exactly the same time. If not, what's the reason for AtomicBoolean (and all the other things in java.util.concurrent.atomic) ?
     
  20. Offline

    Avarice

    V10lator

    That would be lovely, thank you. :)
    Also, it doesn't seem that the protections work with equipped items.

    And thanks for making the damage and protect perms default, makes it super simple. =) Forgot about it after I had added it, watched players start dropping like flies before I could add permissions for their homeworld groups, heh.
     
  21. Offline

    Deathmarine

    bergerkiller I understand your guys point, and honestly I learned abit more, however that dude's attitude is horrible in the fact of attacking me cause I'm trying to help out? Kind of pissed me off. So I gave him a little something to rage about. In all seriousness I now know that rolling methods outside of the main thread is a bad idea. I originally was assuming that those methods I was firing were saved locally instead of having to process each request. I guess my assumption was wrong.

    V10lator Dude if I'm wrong don't point a finger and say I have no clue what I'm talking about. However I really did honestly learn java by staring at it. Thanks for the examples just don't blow up on the guy when your trying to prove a point.
     
    Avarice likes this.
  22. Deathmarine I attacked you? Well, yes, I did:
    1. I'm telling you that you are doing bad things by using bukkit API calls outside of the main thread and linking you the wiki article wchich tells you hy you shouldn't do that and what you should have done instead.
    2. You're telling me something about you only use sync or async threads if the thread fails to sync.
    3. I'm asking you what you mean by that? synchrinized methods? And I again try to get you to read the wiki article, quoting some of the content and giving some other notes why it's bad.
    4. you completely ignore my post.
    5. As a result to your ignoring I decide to write the plugin by using the bukkit scheduler, give it to the OP and try to ignore your ignoring (:confused:)
    6. You stop ignoring me and tell some things that are simply wrong ("that actually do something regularly, not pulling information and using a void." and so on).
    7. You pull out your version of the plugin and call me somebody who's "fighting for attention. lol..."
    8. I give you real-world examples which show what you're doing wrong.
    9. You tell me that I'm late with my post, which again showed me that you didn't read the link from 1.
    10. NOW I'm raging. But not because of 9., because of 7. (while I was writing the long post mentioned in 8. you wroted 9.)
    11. You post that you just want to help.
    12. I say that I just want to help, too and refer to 1. 2. and 4. - Also I try to stop the discussion as I got the feeling you're still ignoring what I try to tell you and still didn't read the link at 1.
    13. The OP tries to stop "the war".

    So you understand why I'm pissed off?

    BTT:
    Avarice I'll look into it tomorrow. It's late here (1:25 am) and I didn't sleep last night.
     
    Avarice likes this.
  23. Offline

    Avarice

    Noooo worries, I'm no stranger to late nights or no nights at all. ^^Know how it goes. Take your time. :)
     
  24. Offline

    Deathmarine

    Man I just spent two hours trying to damage items in the armorslots without removing the items. No Dice.
     
  25. Offline

    Avarice

    Further along than I am :D
     
  26. Avarice <Edit by Moderator: Redacted mediafire url>

    Deathmarine The items won't get removed automatically, look at this code example:
    Code:java
    1. PlayerInventory pi = player.getInventory();
    2. if(armor.contains(item)) // Armor is a HashSet containing all armor item IDs. item is the ID from the config.
    3. {
    4. ItemStack[] isa = pi.getArmorContents();
    5. for(int i = 0; i < isa.length; i++)
    6. {
    7. ItemStack is = isa;
    8. if(is.getTypeId() == item)
    9. {
    10. short dura = is.getDurability();
    11. dura += 10;
    12. if(dura > Material.getMaterial(item).getMaxDurability()) // If the damage value is higher than it's maximum...
    13. isa = null; // ...remove it...
    14. else // ...else...
    15. is.setDurability(dura); // ...set the new damage value.
    16. pi.setArmorContents(isa);
    17. }
    18. }
    19. }

    :)
     
    Last edited by a moderator: Nov 10, 2016
    Deathmarine and Avarice like this.
  27. Offline

    Deathmarine

    [quote uid=92350 name="V10lator" post=1100133]Avarice <Edit by Moderator: Redacted mediafire url>

    Deathmarine The items won't get removed automatically, look at this code example:

    :)[/quote]
    Nice I like it. I kept going for this. But couldn't set the damage.
    Code:java
    1.  
    2. ItemStack[] armour = Player.getInventory().getArmorContents();
    3. for (int i=0; i<armour.length; i++){
    4. if(armour.getTypeId() == config.getInt(Player.getWorld().getName()+".protectionitemid")){
    5. armour.setDurability((short) (armour.getDurability() - 10));
    6. }
    7. }
    8.  
     
    Last edited by a moderator: Nov 10, 2016
  28. armour.setDurability((short) (armour.getDurability() - 10));
    durability starts by 0 (no damage) and goes up to the MaxDurability for the item.
    So you have to use + 10, not - ;)
     
    Deathmarine likes this.
  29. Offline

    Deathmarine

    I see now it makes more sense.

    V10lator you should add

    *TINK* when the armor maxes out durability.

    Player.playEffect(new Location(Player.getLocation()), Effect.CLICK1, 0);

    It maybe CLICK2 but I'm unsure which is sound is which.
    This is bukkit's definition. ;)
    CLICK2
    An alternate click sound.
    CLICK1
    A click sound.

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

Share This Page