Solved Getting if player can attack other player

Discussion in 'Plugin Development' started by 0ct0berBkkitPlgins, Aug 24, 2015.

Thread Status:
Not open for further replies.
  1. I know this has been achieved with multiple plugins before, two of which I use.

    Some plugins will block players from attacking other players, if they are in the same faction, in a minigame team, or are in the spawn. What I want to test is if Player A can physically attack Player B without it being cancelled, without actually attacking Player B.

    I'm using an AoE effect activated by a certain condition in my plugin, but if they activate it on a mob and another player is nearby, unfortunately they can teamkill that other player unless I add a check to see if Player A can physically attack Player B.
     
    Last edited: Aug 24, 2015
  2. Offline

    teej107

    @0ct0berBkkitPlgins You have to either hook into the plugin blocking the attacks or fire a dummy EntityDamageByEntity event and check if it's cancelled.
     
  3. Problematic events (open)
    Note that if you fire an EntityDamageByEntity event with the reason/cause ENTITY_ATTACK, other plugins such as anti-cheating plugins might interpret that as an attempt by the player to actually hit all the other players, which can easily result in flagging the player as cheater. This is a slight dilemma, because the implementation gets more and more complicated with all the compatibility stuff. A somewhat throrough way for the testing-events, would be to create a class extending EntityDamageByEntityEvent, so other plugins could in theory skip checking these by (package+) class name. But the problem continues with the Bukkit server firing an EntityDamageByEntity event with attack reason ENTITY_ATTACK, once you use the API to damage the player, adding the attacker to the call. Then the other plugins can not know where the damage comes from and have to assume a point-and-click hit, apart from the question if you really want to have events doubled here.


    So the above paragraph shows, that you need to also consider how you deal damage (which API call, does the damage method already lead to such an event firing?), because an additional event might fire by default.

    Problematic anti-cheating (open)
    Concerning anti cheating, apart from having plugin developers hook into 100 anti-cheating plugins APIs, i could imagine actually going for the metadata approach, because developers could agree upon some metadata tag to add, e.g. "skipnocheat" -> unspecified fixed value [later could be what to skip, or a nesting-count, or a string list/set of "who" wants this skipped, if feasible]. This way you would just add the metadata to the player, before unleashing all the area havoc, and the anti-cheating plugins could skip checking, but you do have to remove the metadata after running the effect (this is the part that is peculiar, considering that forgetting to remove the metadata would lead to permanent exemption from all checks... another minor question is if those exemptions might ever cascade/nest). I'd support this in NoCheatPlus, though that's probably not what you have been asking for :p.
     
  4. @teej107
    How do I fire a dummy event? I'm new to that. Also would I need to use a runnable or would it register as cancelled (if another plugin cancelled it) instantly?

    @asofold
    It is absolutely necessary for the check to run. I'd rather it be detected by an anti cheat plugin as hacking than have a possible exploit where players can kill each other by attacking the mob to deal AoE.
     
  5. Yes, but shouldn't anti cheating checks be skipped on the area damage events, because other targets can be in positions not reachable by the player, in addition to the potential "impossible" amount of targets you hit with such an attack. The anti-cheating stuff should run on the actual attack be the player, which then triggers your area damage (just to clarify). Of course other "checks" like no-pvp regions and such should still run.

    Question is how to make it possible to make anti-cheating plugins skip checking stuff that would virtually always fail otherwise, due to the nature of the skill...
     
  6. Is there a way to stop an event from being read? Higher priority plugin listeners will still read it, while lower ones won't

    I'm still wondering as to how you can fire a dummy event. Iv'e had basically none of my questions answered yet.

    <Edited by bwfcwalshy: Merged posts, please use the edit button rather than double posting.>
     
    Last edited by a moderator: Aug 25, 2015
  7. Code:
    EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(damager, yourEntity, DamageCause.ENTITY_ATTACK, 0.0);
    Bukkit.getPluginManager().callEvent(e);
    
    if (!e.isCancelled()) {
    //code
    It would be better to actually summon a simple entity (item drop or something, must not be a monster) at y = 0 so you have a damager instead of null (which can cause errors in other plugins)
     
  8. No, you can't prevent plugins from listening to events. The only half-baked exception is, if you cancel the events yourself, e.g. on HIGHEST priority, but most plugins decide on what to do/claim on a lower (earlier) level.

    I don't want to cmplicate it, i just wanted to indicate that damaging players/entiy will/might already lead to a damage event firing. So that's kind of what you get there.

    So i suggest first thinking about the region/zone-protection and similar plugins. I assume you want awareness for players causing damage to others, e.g. thinking of a pvp-prevention or "god mode" thing. In such a case you NEED an EntityDamageByEntityEvent firing. You can obtain that by calling damagedEntity.damage(amount, attacker) which will directly fire such an event not under your control, or you fire a custom EntityDamageByEntityEvent (i suggest making your own class like AreaAttackEvent extends ...), and if not cancelled you use damagedEntity.damage(amount) for "anonymous" damage (two kinds of events firing, but knowing if cancelled).

    Concerning anti-cheating, users will complain, and i'd put that on seconary priority for starters. Once that issue is of relevance (certainly will), you can deal with that then, i could assist with it (concerning NoCheatPlus).
     
    Last edited: Aug 24, 2015
  9. @asofold
    I am going to use DamageCause.MAGIC. Since this is damage from a splash harming potion, it shouldn't interfere with NoCheatPlus or any other AntiCheat plugins, but will still register as damage from a player in Factions/Safezones/Beta protection plugins

    @FisheyLP
    Thanks!

    Alright, I'm having some bugs. Here is my code, and here is my log:

    http://pastebin.com/NDca6kk6
    http://pastebin.com/gnNq2dhU

    <Edited by bwfcwalshy: Merged posts, please use the edit button rather than double posting.>
     
    Last edited by a moderator: Aug 25, 2015
  10. Something is null at line 42
     
  11. Offline

    teej107

    Before I start over complicating things, what's to stop you from checking to see if the affected player is on the same team with a simple method? ie: checking in a Map/Collection/etc....

    The other thing I just thought of is a little crazy that it just might work (as far as selective event calling). You may be able to stop certain events with certain priorities from being fired. What you do is you create your own RegisteredListener wrapper class, register it yourself (not the traditional way) and add in your logic in the wrapper. You may need to get the registered events before you unregister them and stuff each one in their own wrapper class before you register the wrapper. I have not tried this at all and I just thought of it just now. Someone may need to slap some sense into me.
     
    Last edited: Aug 24, 2015
  12. That seems most appropriate - i forgot that the thrower of a potion is recognized. Certainly a potion splash is not monitored by anti cheating plugins (the throwing would be). Edit: Other plugins might edit the affected players list/set, but that's easy to check extra to cancellation.
     
  13. By doing that you are overcomplicating things. I'm not just preventing teamkilling- I'm preventing PvP in spawn, faction members, truces, and allies from attacking, etc. Going and checking what "team" someone is on means also checking regions and configurations and making a mess- and I'll have to be constantly updating this plugin to make it compatible. It is both easier for me to code and more lightweight if I just run a dummy event.

    Nothing is null on line 42, I believe that is the bukkit class. At line 42 in my plugin I'm just activating a new global variable. I noticed there was a null in the console on line 175, which is the dummy event... The code you posted is outdated, so I had to find the latest format. Iv'e done something wrong, but don't know what went wrong.

    I removed the runnable, and ran the event without that. Now it is an event exception.

    <Edited by bwfcwalshy: Merged posts, please use the edit button rather than double posting.>
     
    Last edited by a moderator: Aug 25, 2015
  14. Which exception?
     
  15. @FisheyLP Asynchronous event exception.

    @Everybody
    I got it to work. The current format is rather buggy and confusing, and is mostly only for if damage modifiers are being used... I moved the whole code to a boolean and used the old code with suppress warnings. It has all run smoothly now and seems to show no bugs.
     
Thread Status:
Not open for further replies.

Share This Page