Skip to content

Commit

Permalink
Fix FastBreak, Remove Slimeblock check, Add basic glide check.
Browse files Browse the repository at this point in the history
  • Loading branch information
Vrekt committed Aug 9, 2021
1 parent 07efd75 commit 8d4f6fe
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 53 deletions.
2 changes: 2 additions & 0 deletions src/main/java/me/vrekt/arc/check/block/FastBreak.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public FastBreak() {
* @return the result
*/
public boolean check(Player player, BlockData data, Block block) {
if (exempt(player) || player.getGamemode() == 1) return false;

// the result.
final CheckResult result = new CheckResult();

Expand Down
131 changes: 79 additions & 52 deletions src/main/java/me/vrekt/arc/check/moving/Flight.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,7 @@ public final class Flight extends Check {
* Ascend cooldown work around.
* Max time allowed to b e hovering
*/
private int maxAscendTime, jumpBoostAscendAmplifier, ascendCooldown, maxInAirHoverTime;

/**
* The max difference allowed between a=(vertical speed - expected) then, (vertical speed - a)
*/
private double slimeblockMaxScoreDiff;
private int maxAscendTime, jumpBoostAscendAmplifier, ascendCooldown, maxInAirHoverTime, noGlideDifferenceMax;

public Flight() {
super(CheckType.FLIGHT);
Expand All @@ -66,7 +61,7 @@ public Flight() {
addConfigurationValue("ground-distance-threshold", 2.0);
addConfigurationValue("ground-distance-horizontal-cap", 0.50);
addConfigurationValue("max-in-air-hover-time", 6);
addConfigurationValue("slimeblock-max-score-difference", 0.42);
addConfigurationValue("no-glide-difference-max", 2);

if (enabled()) load();
}
Expand Down Expand Up @@ -109,15 +104,24 @@ public void check(Player player, MovingData data) {
&& !data.hasClimbable();

// check the vertical move of this player.
final double distanceToGround = MathUtil.vertical(ground, to);
if (validVerticalMove) {
// check vertical clip regardless of ascending or descending state.
// return here since we don't want the rest of the check interfering with setback.
// final boolean failed = checkIfMovedThroughSolidBlock(player, result, safe, from, to, vertical);
if (!hasVerticalModifier) {
checkVerticalMove(player, data, ground, from, to, vertical, data.ascendingTime(), result);
checkVerticalMove(player, data, ground, from, to, vertical, distanceToGround, data.ascendingTime(), result);
}
}

// check gliding, descending movement.
if (player.getRiding() == null
&& !data.inLiquid()
&& !data.hasClimbable()
&& !player.hasEffect(NukkitAccess.SLOW_FALLING_EFFECT)) {
checkGlide(player, data, ground, to, vertical, distanceToGround, result);
}

if (data.hasClimbable()) {
// the ascending cooldown, will need to be reversed if descending.
final double cooldown = climbingCooldown - (vertical * 2);
Expand All @@ -137,20 +141,17 @@ public void check(Player player, MovingData data) {
* @param from the from
* @param to movedTo
* @param vertical vertical
* @param distance distance from ground
* @param ascendingTime ascendingTime
* @param result result
*/
private void checkVerticalMove(Player player, MovingData data, Location ground, Location from, Location to, double vertical, int ascendingTime, CheckResult result) {
private void checkVerticalMove(Player player, MovingData data, Location ground, Location from, Location to, double vertical, double distance, int ascendingTime, CheckResult result) {
if (data.ascending()) {
// check ground distance.
final double distance = MathUtil.vertical(ground, to);

final boolean hasSlimeblock = data.hasSlimeblock();
if (hasSlimeblock && vertical > 0.42 && distance > 3f) {
if (hasSlimeblock && vertical > 0.42 && distance > 1f) {
data.setHasSlimeBlockLaunch(true);
}


if (distance >= groundDistanceThreshold) {
// high off ground (hopefully) check.
// make sure we are within the limits of the ground.
Expand All @@ -166,46 +167,12 @@ private void checkVerticalMove(Player player, MovingData data, Location ground,
}
}

// TODO: check if we have launch from a slime-block.
// TODO: Maybe in the future, watch slime-block movement.
// TODO: But for now, movement is too weird, and haven't seen any cheats yet.

// ensure we didn't walk up a block that modifies your vertical
final double maxJumpHeight = getJumpHeight(player);

if (hasSlimeblock) {
// player was launched, set state
final boolean launched = data.hasSlimeBlockLaunch();
if (launched) {
// get rough estimate of player fall distance
final double fallen = MathUtil.vertical(data.getFlightDescendingLocation() == null ? from
: data.getFlightDescendingLocation(), from);
if (data.getFlightDescendingLocation() != null) {
// decrease the modifier if we fall from a significant height, +
// to prevent one time abuse
final double modifier = fallen > 15 ? 0.11D : 0.18d;
final double rough = 0.4D + fallen * modifier;
final double diff = Math.abs(vertical - rough);
final double score = vertical - diff;
if (score >= slimeblockMaxScoreDiff) {
result.setFailed("Bounced too high from a slimeblock")
.withParameter("vertical", vertical)
.withParameter("rough", rough)
.withParameter("diff", diff)
.withParameter("score", score)
.withParameter("max", slimeblockMaxScoreDiff);
handleCheckViolationAndReset(player, result, ground);
}
}

// player is jumping really high with no velocity
if (distance <= 1f && vertical > maxJumpHeight && fallen <= 1f) {
result.setFailed("Vertical greater than max jump height on slimeblock")
.withParameter("groundDistance", distance)
.withParameter("vertical", vertical)
.withParameter("max", maxJumpHeight);
handleCheckViolationAndReset(player, result, ground);
}
}
}

// go back to where we were.
// maybe ground later.

Expand Down Expand Up @@ -237,6 +204,66 @@ private void checkVerticalMove(Player player, MovingData data, Location ground,
}
}

/**
* Generally check player gliding and flight movements.
*
* @param player the player
* @param data their data
* @param ground ground location
* @param to to
* @param vertical vertical
* @param distance the distance to ground
* @param result result
*/
private void checkGlide(Player player, MovingData data, Location ground, Location to, double vertical, double distance, CheckResult result) {

// check no ground stuff
// TODO: Can be bypassed, needs to be improved, see comment below.
if (!data.onGround() && (data.getNoResetDescendTime() >= 5 || data.getNoResetAscendTime() >= 5)) {
final double horizontal = MathUtil.horizontal(ground, to);
if (horizontal > 3f && data.getInAirTime() >= 15) {
// player is far from ground, so we should expect to be a certain distance by this point.
// This can still be abused here, so in the future calculate what we should expect.
// TODO: Bypassable by falling a greater amount over time.
if (distance < 1f) {
result.setFailed("Not gliding over-time (experimental)")
.withParameter("horizontal", horizontal)
.withParameter("min", 3f)
.withParameter("air", data.getInAirTime())
.withParameter("min", 15)
.withParameter("distance", distance)
.withParameter("min", 1f);
handleCheckViolationAndReset(player, result, ground);
}
}
}

// first, basic glide check
// ensure player is actually moving down when off the ground here.
if (!data.onGround() && !data.ascending()) {
// calculate how we moved since last time.
final double delta = Math.abs(vertical - data.lastVertical());

// player hasn't moved, increase 'time'
if (vertical == 0.0 || delta == 0.0) {
data.setNoGlideTime(data.getNoGlideTime() + 1);
} else {
// decrease / reward
data.setNoGlideTime(data.getNoGlideTime() - 1);
}

if (data.getNoGlideTime() > noGlideDifferenceMax) {
result.setFailed("No vertical difference while off ground")
.withParameter("vertical", vertical)
.withParameter("last", data.lastVertical())
.withParameter("delta", delta)
.withParameter("time", data.getNoGlideTime())
.withParameter("max", noGlideDifferenceMax);
handleCheckViolationAndReset(player, result, ground);
}
}
}

/**
* Check climbing movement.
*
Expand Down Expand Up @@ -361,6 +388,6 @@ public void load() {
groundDistanceThreshold = configuration.getDouble("ground-distance-threshold");
groundDistanceHorizontalCap = configuration.getDouble("ground-distance-horizontal-cap");
maxInAirHoverTime = configuration.getInt("max-in-air-hover-time");
slimeblockMaxScoreDiff = configuration.getDouble("slimeblock-max-score-difference");
noGlideDifferenceMax = configuration.getInt("no-glide-difference-max");
}
}
5 changes: 5 additions & 0 deletions src/main/java/me/vrekt/arc/compatibility/NukkitAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ public final class NukkitAccess {
*/
public static final int JUMP_BOOST_EFFECT = 8;

/**
* Slow falling effect.
*/
public static final int SLOW_FALLING_EFFECT = 40;

}
32 changes: 32 additions & 0 deletions src/main/java/me/vrekt/arc/data/moving/MovingData.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ public static MovingData retrieveTemporary() {
*/
private int inAirTime;

/**
* Player isn't moving down.
* <p>
* No reset times.
* <p>
*/
private int noGlideTime, noResetAscendTime, noResetDescendTime;

public Location from() {
return from;
}
Expand Down Expand Up @@ -418,4 +426,28 @@ public void setInAirTime(int inAirTime) {
this.inAirTime = MathUtil.clampInt(inAirTime, 0, 100);
}

public int getNoGlideTime() {
return noGlideTime;
}

public void setNoGlideTime(int noGlideTime) {
this.noGlideTime = MathUtil.clampInt(noGlideTime, 0, 100);
}

public int getNoResetAscendTime() {
return noResetAscendTime;
}

public void setNoResetAscendTime(int noResetAscendTime) {
this.noResetAscendTime = MathUtil.clampInt(noResetAscendTime, 0, 1000);
}

public int getNoResetDescendTime() {
return noResetDescendTime;
}

public void setNoResetDescendTime(int noResetDescendTime) {
this.noResetDescendTime = MathUtil.clampInt(noResetDescendTime, 0, 1000);
}

}
3 changes: 2 additions & 1 deletion src/main/java/me/vrekt/arc/listener/block/BlockListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ private void onBlockBreak(BlockBreakEvent event) {

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
private void onInteract(PlayerInteractEvent event) {
if (event.getAction() == PlayerInteractEvent.Action.LEFT_CLICK_BLOCK) {
if (event.getAction() == PlayerInteractEvent.Action.LEFT_CLICK_BLOCK
&& event.getPlayer().getGamemode() != 1) {
final Player player = event.getPlayer();
final BlockData data = BlockData.get(player);

Expand Down
18 changes: 18 additions & 0 deletions src/main/java/me/vrekt/arc/listener/player/PlayerListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.EventPriority;
import cn.nukkit.event.Listener;
import cn.nukkit.event.player.PlayerGameModeChangeEvent;
import cn.nukkit.event.player.PlayerItemConsumeEvent;
import me.vrekt.arc.Arc;
import me.vrekt.arc.check.CheckType;
import me.vrekt.arc.check.player.FastUse;
import me.vrekt.arc.data.moving.MovingData;
import me.vrekt.arc.data.player.PlayerData;

/**
Expand Down Expand Up @@ -40,4 +42,20 @@ public void onConsumeItem(PlayerItemConsumeEvent event) {
event.setCancelled(result);
}

/**
* Handle changing from creative -> survival for movement checks.
*
* @param event the event
*/
@EventHandler
private void onGameModeChange(PlayerGameModeChangeEvent event) {
final Player player = event.getPlayer();

if (event.getNewGamemode() == 0
&& player.getGamemode() == 1 || player.getGamemode() == 3) {
final MovingData data = MovingData.get(player);
data.setInAirTime(0);
}
}

}
2 changes: 2 additions & 0 deletions src/main/java/me/vrekt/arc/utility/MovingAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ public static void calculateMovement(MovingData data, Location from, Location to
data.setInAirTime(0);
data.ascendingTime(0);
data.descendingTime(0);
data.setNoResetDescendTime(0);
data.setNoResetAscendTime(0);
} else {
data.setInAirTime(data.getInAirTime() + 1);

Expand Down

0 comments on commit 8d4f6fe

Please sign in to comment.