nopjmp / Dionysus

Minecraft 1.12.2 Paper Fork designed for high player counts and anarchy.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fixes instant killing of a player with an arrow

opened this issue · comments

package f3f5.bowbombpatch;

import org.bukkit.entity.Arrow;
import org.bukkit.entity.SpectralArrow;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.plugin.java.JavaPlugin;

public final class BowBombPatch extends JavaPlugin implements Listener {
@eventhandler
public void onArrow(ProjectileLaunchEvent evt) {
if (evt.getEntity() instanceof Arrow || evt.getEntity() instanceof SpectralArrow) {
evt.setCancelled(true);
}

}
}
Additional context
Add any other context or screenshots about the feature request here.

This just.. disables using arrows?

This just.. disables using arrows?

yes((((((((((

Clamp the velocity

Can't we clamp the damage and velocity?

commented

What causes this is the ability for a player to increase their server-side motX and motZ far beyond legitimate amounts by sprinting and then triggering the Spigot jump event over and over in the course of one tick.
image
image
image
This then gets added to the velocity of any projectiles thrown by they player when they are thrown.
image

A more effective way to patch this exploit would be to simply not add these motX and motZ values if the entity firing the projectile is a player.

A more effective way to patch this exploit would be to simply not add these motX and motZ values if the entity firing the projectile is a player.

Wouldn't this affect damage from sprint-jumping when firing an arrow? I know it's a small thing but that is vanilla behavior.
Simply clamping them at their theoretical "normal" maximums would be sufficient.

    public void onProjectileLaunch(ProjectileLaunchEvent event) {
        if (event.getEntity().getShooter() instanceof CraftPlayer) {
            Vector velocity = event.getEntity().getVelocity();

            if (velocity.lengthSquared() > plugin.getConfig().getInt("BowExploit.maxBowSquaredVelocity", 15)) {
                event.setCancelled(true);

                Log.info("Cancelled high velocity " + event.getEntityType().name() + " of " + ((CraftPlayer) event.getEntity().getShooter()).getName() + ".", getClass(), false);
            }
        }
    }

While this could easily be done with plugins, too, there are multiple problems:

P1) If multiple plugins cancel the velocity by subtracting the shooter's velocity
from the projectile's velocity, the projectile's velocity would be different.
As there's no way to detect whether the projectile's velocity has already been
adjusted to ignore the player's velocity, plugins can't not do it if it's not
necessary.

P2) I've noticed some inconsistencies, e.g. weird velocity when shooting while
using an elytra. Checking for those inconsistencies is possible, but not as
efficient as just not applying the velocity in the first place.
P3) Solutions for 1) and especially 2) might not be future-proof, while this
server-internal fix makes this change future-proof.

commented

@5HT2 @RemainingToast I find that this is resolved in PaperMC/Paper@bb397ba, maybe it is these lines that solved the problem?

diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 1018f4640bab5876c5e0afb5b88f71437fb79662..cbdff14b26f67b5040c13659f9d64d9ec4c7eaed 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2571,15 +2571,27 @@ public abstract class LivingEntity extends Entity {
         return this.hasEffect(MobEffects.JUMP) ? (double) (0.1F * (float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1)) : 0.0D;
     }

+    protected long lastJumpTime = 0L; // Paper - add critical damage API
     protected void jumpFromGround() {
         double d0 = (double) this.getJumpPower() + this.getJumpBoostPower();
         Vec3 vec3d = this.getDeltaMovement();
+        // Paper start - add critical damage API
+        long time = System.nanoTime();
+        boolean canCrit = true;
+        if (this instanceof net.minecraft.world.entity.player.Player) {
+            canCrit = false;
+            if (time - this.lastJumpTime > (long)(0.250e9)) {
+                this.lastJumpTime = time;
+                canCrit = true;
+            }
+        }
+        // Paper end - add critical damage API

         this.setDeltaMovement(vec3d.x, d0, vec3d.z);
         if (this.isSprinting()) {
             float f = this.getYRot() * 0.017453292F;

-            this.setDeltaMovement(this.getDeltaMovement().add((double) (-Mth.sin(f) * 0.2F), 0.0D, (double) (Mth.cos(f) * 0.2F)));
+            if (canCrit) this.setDeltaMovement(this.getDeltaMovement().add((double) (-Mth.sin(f) * 0.2F), 0.0D, (double) (Mth.cos(f) * 0.2F))); // Paper - add critical damage API
         }

         this.hasImpulse = true;

Likely because the exploit is from spamming jump packets

using real system time

ew