Fix NCP incompatibility
This commit is contained in:
1 parent
6c629e3a5b
commit
e3fd3e3f06
3 files changed
+34
-19
No files matched your search
@@ -11,10 +11,10 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.spigotmc.event.entity.EntityDismountEvent;
|
||||
|
||||
// Single cleanup point for the NoCheatPlus MOVING_CREATIVEFLY exemption taken in
|
||||
// Single cleanup point for the NoCheatPlus MOVING exemption taken in
|
||||
// OnEntityShootBowEvent. EntityDismountEvent fires for every way a ride ends -- the
|
||||
// arrow landing and being removed, the self-hit removal, manual dismount, or death --
|
||||
// so restoring the check here guarantees the exemption never leaks past the ride.
|
||||
// so restoring the checks here guarantees the exemption never leaks past the ride.
|
||||
public class OnEntityDismountEvent implements Listener {
|
||||
|
||||
@EventHandler
|
||||
@@ -32,7 +32,7 @@ public class OnEntityDismountEvent implements Listener {
|
||||
if (arrow.getBasePotionData().getType() != PotionType.UNCRAFTABLE)
|
||||
return;
|
||||
|
||||
NCPHook.unexemptCreativeFly(player);
|
||||
NCPHook.unexemptMoving(player);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -77,9 +77,10 @@ public class OnEntityShootBowEvent implements Listener {
|
||||
|
||||
rideArrow.addPassenger(shooter);
|
||||
|
||||
// Stop NoCheatPlus from flagging the arrow ride as illegal flight
|
||||
// (MOVING_CREATIVEFLY). Cleared on dismount in OnEntityDismountEvent.
|
||||
NCPHook.exemptCreativeFly(shooter);
|
||||
// Stop NoCheatPlus from flagging the arrow ride as illegal movement
|
||||
// (exempts the whole MOVING group: vehicle, survivalfly, nofall, ...).
|
||||
// Cleared on dismount in OnEntityDismountEvent.
|
||||
NCPHook.exemptMoving(shooter);
|
||||
|
||||
}, 1L);
|
||||
|
||||
|
||||
@@ -7,9 +7,22 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
// Soft integration with NoCheatPlus. While a player rides a Flying Bow arrow they
|
||||
// move through the air faster than survival movement allows, and NCP's CreativeFly
|
||||
// check (MOVING_CREATIVEFLY) flags that as illegal flight, setting the player back or
|
||||
// kicking them. We exempt that single check for the duration of the ride.
|
||||
// move through the air faster than survival movement allows. NCP would flag that as
|
||||
// illegal movement and set the player back or kick them, so we exempt them from the
|
||||
// whole MOVING check group for the duration of the ride.
|
||||
//
|
||||
// We exempt the MOVING group, not a single leaf check, because the arrow ride trips
|
||||
// more than one moving check and the leaf that fires changes with player state:
|
||||
// * While the player is a passenger of the arrow, NCP early-returns out of the
|
||||
// player-move path and runs its VEHICLE checks (MOVING_VEHICLE*) instead.
|
||||
// * Any player-move not inside the vehicle (launch frame, dismount momentum) is
|
||||
// handled by SURVIVALFLY, not CREATIVEFLY, since the rider has no creative
|
||||
// flight. NoFall also applies on the way down.
|
||||
// NCP exemption is hierarchical only downward -- exempting a parent visits all of
|
||||
// its descendants, but isExempted() reads a single node without walking up. So
|
||||
// exempting the MOVING group is the one call that covers every sub-check the ride
|
||||
// can hit; exempting only MOVING_CREATIVEFLY (as this hook used to) exempted a leaf
|
||||
// the ride never reaches.
|
||||
//
|
||||
// NCP is an optional dependency (softdepend). The exemption API is reached by
|
||||
// reflection rather than a compile-time dependency: NoCheatPlus publishes a broken
|
||||
@@ -20,27 +33,26 @@ import org.bukkit.entity.Player;
|
||||
public final class NCPHook {
|
||||
|
||||
// Cached reflection handles, resolved once on first use. ready == true means
|
||||
// all
|
||||
// handles bound and exemption calls will be attempted.
|
||||
// all handles bound and exemption calls will be attempted.
|
||||
private static boolean resolved = false;
|
||||
private static boolean ready = false;
|
||||
private static Method exemptMethod;
|
||||
private static Method unexemptMethod;
|
||||
private static Object creativeFlyCheckType;
|
||||
private static Object movingCheckType;
|
||||
|
||||
private NCPHook() {
|
||||
|
||||
}
|
||||
|
||||
// Exempt the player from MOVING_CREATIVEFLY while riding a Flying Bow arrow.
|
||||
public static void exemptCreativeFly(Player player) {
|
||||
// Exempt the player from all MOVING checks while riding a Flying Bow arrow.
|
||||
public static void exemptMoving(Player player) {
|
||||
|
||||
if (!resolve())
|
||||
return;
|
||||
|
||||
try {
|
||||
|
||||
exemptMethod.invoke(null, player, creativeFlyCheckType);
|
||||
exemptMethod.invoke(null, player, movingCheckType);
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
@@ -49,15 +61,15 @@ public final class NCPHook {
|
||||
|
||||
}
|
||||
|
||||
// Restore MOVING_CREATIVEFLY checking once the ride ends.
|
||||
public static void unexemptCreativeFly(Player player) {
|
||||
// Restore MOVING checking once the ride ends.
|
||||
public static void unexemptMoving(Player player) {
|
||||
|
||||
if (!resolve())
|
||||
return;
|
||||
|
||||
try {
|
||||
|
||||
unexemptMethod.invoke(null, player, creativeFlyCheckType);
|
||||
unexemptMethod.invoke(null, player, movingCheckType);
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
@@ -81,7 +93,9 @@ public final class NCPHook {
|
||||
Class<?> checkType = Class.forName("fr.neatmonster.nocheatplus.checks.CheckType");
|
||||
Class<?> exemptionManager = Class.forName("fr.neatmonster.nocheatplus.hooks.NCPExemptionManager");
|
||||
|
||||
creativeFlyCheckType = Enum.valueOf(checkType.asSubclass(Enum.class), "MOVING_CREATIVEFLY");
|
||||
// MOVING is the parent group of SURVIVALFLY, CREATIVEFLY, VEHICLE, NOFALL,
|
||||
// etc. Exempting it cascades to all of them for the duration of the ride.
|
||||
movingCheckType = Enum.valueOf(checkType.asSubclass(Enum.class), "MOVING");
|
||||
exemptMethod = exemptionManager.getMethod("exemptPermanently", Player.class, checkType);
|
||||
unexemptMethod = exemptionManager.getMethod("unexempt", Player.class, checkType);
|
||||
|
||||
|
||||
Reference in new issue
Block a user