OldCombatMechanics

OldCombatMechanics

46.1k Downloads

Fishing rods can be used in PvP off areas

iMaarten opened this issue · 34 comments

commented

Info

  • Server version: Paper version git-Paper-"591b2777" (MC: 1.12.2) (Implementing API version 1.12.2-R0.1-SNAPSHOT)
  • OldCombatMechanics version: 1.6.6
  • WorldGuard version 6.2.2-SNAPSHOT;63edfbf
  • Server log file: N/A
  • OldCombatMechanics config file: https://pastebin.com/ve8K3umT

Problem Description

Fishing rods can be used even when pvp is turned of in regions.

commented

Sorry I had forgotten about this but I have now merged your commit @I-Al-Istannen. @iMaarten please check if the issues are still there.

commented

Please try out the latest development build and let us know if this has solved your issue. Thanks :)

commented

Is the PVP disabled in the area due to WorldGuard? If not, what plugin is disabling the PVP in that area?

commented

It is the WorldGuard pvp flag

commented

Just checking whether the event is cancelled (or setting ignoreCancelled = true) on the onRodLand listener might be enough.

commented

Shouldn't this be as simple as firing our own EntityDamageEvent, checking if it's cancelled, and if it's not cancelled then only then doing damage with the fishing rod?

commented

I misread the name, they use DamageEntityEvent not EntityDamageEvent, which is their own one. I will have to dig deeper into that one.

commented
diff --git a/src/main/java/gvlfm78/plugin/OldCombatMechanics/module/ModuleFishingKnockback.java b/src/main/java/gvlfm78/plugin/OldCombatMechanics/module/ModuleFishingKnockback.java
index 3dde337..02745f2 100644
--- a/src/main/java/gvlfm78/plugin/OldCombatMechanics/module/ModuleFishingKnockback.java
+++ b/src/main/java/gvlfm78/plugin/OldCombatMechanics/module/ModuleFishingKnockback.java
@@ -73,6 +73,10 @@ public class ModuleFishingKnockback extends Module {
 
         EntityDamageEvent event = makeEvent(rodder, player, damage);
         Bukkit.getPluginManager().callEvent(event);
+        if(event.isCancelled()) {
+            System.out.println("NO!");
+            return;
+        }
 
         if(module().getBoolean("checkCancelled") && event.isCancelled()){

Seems to be enough.

You already fire an event, you just ignore the result currently.

He said, while the next line showed it was just behind a config option... Smart guy

commented

I'll do that now 😄

commented

@iMaarten Wait, do you really have checkCancelled enabled in the config (under fishing)?

If yes, can you enable the debug mode of OCM in the config and see if it sends you any message in the chat, if you rod somebody in a no-pvp area?

commented

Okay, I see the problem. You have useEntityDamageEvent enabled in the config and this causes OCM to (rightfully) use just that. The problem is that the pure damage event does not contain information about the attacker, so worldguard thinks it is just some damage — not that another player rodded you, but more like walking into a cactus. Logically the pvp check doesn't do anything then, as it wasn't player induced damage.

Try setting this value to false and see if the error persists. If this causes errors with NCP, we will have to look into that.

commented

That fixes the WorldGuard issue, however, Only some of the hits will actually register and the whole knockback seems a bit off
https://i.imgur.com/bc4qfOT.png <- Debug of being hit
https://www.youtube.com/watch?v=9WJYiSio0-k <- Video of hitting

commented

IIRC checkCancelled is an option in the config because EssentialsX seemed to cancel the event about 3 out of 4 times it fired, for some reason I was not able to figure out.

commented

The problems seems to indeed to be EssentialsX, knockback still seems about the same.

commented

Hm. I can't reproduce it with EssentialsX. Do you need some special config settings?

Knockback is interesting though. Does this build attached here is closer to it? It's mostly equal to the knockback from 1.8.8 based on the decompiled minecraft code.
OCM.zip

commented

Knockbac seems to work great now!
Here is my Essentials
EssentialsX.zip

commented

Made a small error in not removing enough of the old knockback code. This one fixes a too high Y Velocity (actually a teleport up) which allowed for far too great upwards momentum.

OCM.zip

But I can not reproduce the issue:

See here

You said it was EssentialsX, is there anything else that needs to be present for you to reproduce the bug?

commented

Then I guess we'll have to bisect his list of plugins… Or do you have a better idea to find out what plugin cancelled it?

The chat was a bit too fast to see what plugins were listening when it was cancelled sadly.

@iMaarten
Can you post the full output of that (i.e. all plugins that are listening), then I can try to bisect it. Or you do that, by removing all plugins (on a test server), and see if it works. If yes, then some plugin prevents it.
In that case just throw all plugins back on and remove half of them, see if it works and then continue to halve the part with the problem.

EDIT: The knockback direction is dependent on the relative location of the two players to each other. I guess the vanilla behaviour is using the location of the bobber instead. Let me change that and provide a build with that, so you can see if that feels more natural.
OCM.zip

commented

When I was revising this module and came across this issue it had been EssentialsX that was cancelling the event, however I don't know if that was a bug that has now been fixed or a conflict of sorts.

commented

Can not find anything else interfering. My apologies for the late reply.

commented

I'd love to fix that, but I can not reproduce it. EssentialsX by itself only ever cancels the EntityDamageEvent under a few special circumstances and nothing you should have had happen in that video.

So it might be another one of your plugins or some settings are different? I used your config though, which is weird.

Can you, @rayzr522 or @gvlfm78 or anybody else reproduce it?

commented

Seems to be fixed in the latest dev build however getting this error when hitting players/mobs getting this error https://pastebin.com/HjXYsfb0

commented

1.12:

    public Fish getHook() {
        return this.hookEntity;
    }

1.13:

    public FishHook getHook() {
        return this.hookEntity;
    }

I will have a look at it tomorrow if nobody else has taken it up by then. I am way too tired right now sadly.

commented

I don't believe it should be an issue, as they are both implementations of Entity. Perhaps we just need to cast e.getHook() to Entity?

commented

Any chance it can be fixed that players can basically fly up https://i.imgur.com/PWKd0R0.gifv

commented

@iMaarten I have added a configurable fishing rod knockback cooldown which appears to have fixed the issue.

To @rayzr522 @I-Al-Istannen: however, I am not sure whether it will be an issue if the HashMap I used fills up with an entry for each player that has been on the server and hit somebody else with a fishing rod since the server start. Could become a problem for larger servers due to memory usage. Currently, the list is cleared only if the module is reloaded. Maybe scheduling tasks to clear it periodically? (If this is even an issue at all)

commented

You could have just used Player#setNoDamageTicks to prevent further damage within the configured delay (it is how it normally works with damaging entities --- they are granted a small period of nearly invincibility). For this to work correctly you likely need to delay applying the noDamageTick value by a tick, so do that it in a runnable that runs on the next tick.

If you really only want to prevent rod damage, then that sounds like a way to do it, but adding a listener to clear it out on PlayerQuitEvent should be easy and help somewhat.
Another way would be using a google guava cache and to set the expiration to the one specified in the config (though then you'd need to handle config reloads).

A cleaning task would work too, but might be a bit overkill, if you just remove them in on player quit. A Long is larger than a long (object header and such garbage), but still not incredibly so, so I am not sure if it is worth it.

The cleanest solution would be using the noDamageTicks, though that applies to all kinds of damage and not just rod usage.

commented

@iMaarten there is already an issue for that here: #139. I might have a look at it now.

commented

@gvlfm78 The concept of noDamageTicks is old and exists for all kinds of damage. You could spam the rod when using the plugin, as the plugin did not check the noDamageTicks and directly called Player#damage, which doesn't care about them.

If you add a check for noDamageTicks in the listener, it will mirror the vanilla behavior and not allow spamming it:

// ....
if(player.getGameMode() == GameMode.CREATIVE) return;

// Check if cooldown time has elapsed
if(player.getNoDamageTicks() > player.getMaximumNoDamageTicks() / 2f){
    return;
}

You can see the diff here.

commented

@I-Al-Istannen This begs the question, in 1.8, did getting hit with a fishing rod grant you a short time of invincibility from all weapons or did it only apply to fishing rods?

commented

@gvlfm78 noDamageTicks is used with everything, including fishing rods. Sorry if that was not clear enough.

Minecraft sets the noDamageTicks automatically to LivingEntity#maxNoDamageTicks when the entity is damaged, so you should not need to set it yourself, if you want the default vanilla behaviour of 20 ticks.

commented

@I-Al-Istannen I was asking whether noDamageTicks was used specifically with fishing rods in 1.8. If that is the case, then using noDamageTicks would be the best solution.

Furthermore, previously you stated that we should use Player#setNoDamageTicks, however your code diff simply compares the damage ticks but never sets them. Would that then still be sufficient?

commented

How did you configure the island? I find the plugin's protection system to be a bit confusing, as I can not find a PVP flag in the settings.