Author SHA1 Message Date
xaw3ep 009c8d00c6 ffffffffff
Done, but not work well with recent versions; packet inversion?
2021-07-26 20:26:23 +07:00
xaw3ep aee5ed158e Parts
Put it here, syncing with local
2021-07-26 09:57:25 +07:00
11 changed files with 427 additions and 50 deletions

No files matched your search

@@ -76,10 +76,12 @@ public enum CheckType {
FIGHT_DIRECTION(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_DIRECTION),
FIGHT_FASTHEAL(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_FASTHEAL),
FIGHT_GODMODE(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_GODMODE),
FIGHT_HITBOX(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_DIRECTION),
FIGHT_NOSWING(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_NOSWING),
FIGHT_REACH(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_REACH),
FIGHT_SELFHIT(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_SELFHIT),
FIGHT_SPEED(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_SPEED),
FIGHT_VISIBLE(CheckTypeType.CHECK, FIGHT, Permissions.FIGHT_VISIBLE),
FIGHT_WRONGTURN(CheckTypeType.CHECK, FIGHT, null),
INVENTORY(CheckTypeType.GROUP, CheckType.ALL, Permissions.INVENTORY),
@@ -86,12 +86,17 @@ public class FightConfig extends ACheckConfig {
public final float speedImprobableWeight;
public final ActionList speedActions;
public final ActionList visibleActions;
public final double hitBoxHorizontalExpansion;
public final double hitBoxVerticalExpansion;
// Special flags:
public final boolean cancelDead;
public final boolean knockBackVelocityPvP;
/** Maximum latency counted in ticks for the loop checks (reach, direction). */
public final long loopMaxLatencyTicks; // TODO: Configurable, sections for players and entities.
/** Maximum latency counted in ms for the loop checks (reach, direction). */
public final int loopMaxLatencyMs; // TODO: Configurable, sections for players and entities.
/**
* Instantiates a new fight configuration.
@@ -147,7 +152,10 @@ public class FightConfig extends ACheckConfig {
noSwingActions = config.getOptimizedActionList(ConfPaths.FIGHT_NOSWING_ACTIONS, Permissions.FIGHT_NOSWING);
reachSurvivalDistance = config.getDouble(ConfPaths.FIGHT_REACH_SURVIVALDISTANCE, 3.5, 6.0, 4.4);
hitBoxHorizontalExpansion = config.getDouble(ConfPaths.FIGHT_HITBOX_HORIZONTAL_EXPAND, 0.125);
hitBoxVerticalExpansion = config.getDouble(ConfPaths.FIGHT_HITBOX_VERTICAL_EXPAND, 0.125);
reachSurvivalDistance = config.getDouble(ConfPaths.FIGHT_REACH_SURVIVALDISTANCE, 3.0, 6.0, 4.4);
reachPenalty = config.getLong(ConfPaths.FIGHT_REACH_PENALTY);
reachPrecision = config.getBoolean(ConfPaths.FIGHT_REACH_PRECISION);
reachReduce = config.getBoolean(ConfPaths.FIGHT_REACH_REDUCE);
@@ -169,8 +177,10 @@ public class FightConfig extends ACheckConfig {
speedImprobableWeight = (float) config.getDouble(ConfPaths.FIGHT_SPEED_IMPROBABLE_WEIGHT);
speedActions = config.getOptimizedActionList(ConfPaths.FIGHT_SPEED_ACTIONS, Permissions.FIGHT_SPEED);
visibleActions = config.getOptimizedActionList(ConfPaths.FIGHT_VISIBLE_ACTIONS, Permissions.FIGHT_VISIBLE);
cancelDead = config.getBoolean(ConfPaths.FIGHT_CANCELDEAD);
loopMaxLatencyTicks = config.getInt(ConfPaths.FIGHT_MAXLOOPLETENCYTICKS, 1, 15, 8);
loopMaxLatencyMs = config.getInt(ConfPaths.FIGHT_MAXLOOPLETENCYMS, 500);
AlmostBoolean ref = config.getAlmostBoolean(ConfPaths.FIGHT_PVP_KNOCKBACKVELOCITY, AlmostBoolean.MAYBE);
knockBackVelocityPvP = ref == AlmostBoolean.MAYBE ? Bugs.shouldPvpKnockBackVelocity() : ref.decide();
}
@@ -42,6 +42,7 @@ public class FightData extends ACheckData implements IDataOnRemoveSubCheckData,
public double noSwingVL;
public double reachVL;
public double speedVL;
public double visibleVL;
// Shared
public String lastWorld = "";
@@ -127,6 +128,14 @@ public class FightData extends ACheckData implements IDataOnRemoveSubCheckData,
for (final CheckType checkType : checkTypes) {
switch(checkType) {
// TODO: case FIGHT: ...
case FIGHT_HITBOX:
directionVL = 0;
visibleVL = 0;
reachVL = 0;
break;
case FIGHT_VISIBLE:
visibleVL = 0;
break;
case FIGHT_DIRECTION:
directionVL = 0;
break;
@@ -51,8 +51,6 @@ import fr.neatmonster.nocheatplus.checks.moving.player.UnusedVelocity;
import fr.neatmonster.nocheatplus.checks.moving.util.AuxMoving;
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
import fr.neatmonster.nocheatplus.checks.moving.velocity.VelocityFlags;
import fr.neatmonster.nocheatplus.checks.net.NetConfig;
import fr.neatmonster.nocheatplus.checks.net.NetData;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.compat.BridgeEnchant;
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
@@ -100,6 +98,9 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
/** The god mode check. */
private final GodMode godMode = addCheck(new GodMode());
/** THe hit box check. */
private final HitBox hitBox = addCheck(new HitBox());
/** The no swing check. */
private final NoSwing noSwing = addCheck(new NoSwing());
@@ -112,6 +113,9 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
/** The speed check. */
private final Speed speed = addCheck(new Speed());
/** The visible check. */
private final Visible visible = addCheck(new Visible());
/** For temporary use: LocUtil.clone before passing deeply, call setWorld(null) after use. */
private final Location useLoc1 = new Location(null, 0, 0, 0);
@@ -249,7 +253,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// TODO: Problem with NPCs: data stays (not a big problem).
// (This is done even if the event has already been cancelled, to keep track, if the player is on a horse.)
damagedTrace = DataManager.getPlayerData(damagedPlayer).getGenericInstance(MovingData.class)
.updateTrace(damagedPlayer, damagedLoc, tick, damagedIsFake ? null : mcAccess.getHandle()); //.getTrace(damagedPlayer);
.updateTrace(damagedPlayer, damagedLoc, now, damagedIsFake ? null : mcAccess.getHandle()); //.getTrace(damagedPlayer);
}
else {
damagedPlayer = null; // TODO: This is a temporary workaround.
@@ -364,22 +368,31 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
if (!cancelled) {
final boolean reachEnabled = reach.isEnabled(player, pData);
final boolean directionEnabled = direction.isEnabled(player, pData) && mData.timeRiptiding + 3000 < now;
if (reachEnabled || directionEnabled) {
final boolean visibleEnabled = visible.isEnabled(player, pData);
final boolean hitboxEnabled = hitBox.isEnabled(player, pData);
if (reachEnabled || directionEnabled || visibleEnabled) {
if (damagedTrace != null) {
// Checks that use the LocationTrace instance of the attacked entity/player.
cancelled = locationTraceChecks(player, loc, data, cc, pData,
damaged, damagedIsFake, damagedLoc, damagedTrace, tick, now, debug,
reachEnabled, directionEnabled);
reachEnabled, directionEnabled, visibleEnabled, hitboxEnabled);
}
else {
// Still use the classic methods for non-players. maybe[]
if (reachEnabled && reach.check(player, loc, damaged, damagedIsFake, damagedLoc,
data, cc, pData)) {
cancelled = true;
}
if (directionEnabled && hitboxEnabled) {
if (hitBox.check(player, loc, damaged, damagedIsFake, damagedLoc, data, cc, pData,
reachEnabled, visibleEnabled)) {
cancelled = true;
}
} else {
if (reachEnabled && reach.check(player, loc, damaged, damagedIsFake, damagedLoc,
data, cc, pData)) {
cancelled = true;
}
if (directionEnabled && direction.check(player, loc, damaged, damagedIsFake, damagedLoc, data, cc)) {
cancelled = true;
if (directionEnabled && direction.check(player, loc, damaged, damagedIsFake, damagedLoc, data, cc)) {
cancelled = true;
}
}
}
}
@@ -473,6 +486,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
* @param tick
* @param reachEnabled
* @param directionEnabled
* @param hitboxEnabled
* @param visibleEnabled
* @return If to cancel (true) or not (false).
*/
private boolean locationTraceChecks(final Player player, final Location loc,
@@ -480,7 +495,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
final Entity damaged, final boolean damagedIsFake,
final Location damagedLoc, LocationTrace damagedTrace,
final long tick, final long now, final boolean debug,
final boolean reachEnabled, final boolean directionEnabled) {
final boolean reachEnabled, final boolean directionEnabled,
final boolean visibleEnabled, final boolean hitboxEnabled) {
// TODO: Order / splitting off generic stuff.
/*
* TODO: Abstract: interface with common setup/loop/post routine, only
@@ -493,8 +509,9 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// (Might pass generic context to factories, for shared + heavy properties.)
final ReachContext reachContext = reachEnabled ? reach.getContext(player, loc, damaged, damagedLoc, data, cc) : null;
final DirectionContext directionContext = directionEnabled ? direction.getContext(player, loc, damaged, damagedIsFake, damagedLoc, data, cc) : null;
final VisibleContext visibleContext = visibleEnabled ? visible.getContext(player, loc, damaged, damagedLoc, data, cc) : null;
final long traceOldest = tick - cc.loopMaxLatencyTicks; // TODO: Set by latency-window.
final long traceOldest = now - cc.loopMaxLatencyMs; // TODO: Set by latency-window.
// TODO: Iterating direction, which, static/dynamic choice.
final Iterator<ITraceEntry> traceIt = damagedTrace.maxAgeIterator(traceOldest);
@@ -510,23 +527,32 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// Simplistic just check both until end or hit.
// TODO: Other default distances/tolerances.
boolean thisPassed = true;
if (reachEnabled) {
if (reach.loopCheck(player, loc, damaged, entry, reachContext, data, cc)) {
if (directionEnabled && hitboxEnabled) {
if (hitBox.loopCheck(player, loc, entry,
directionContext, reachContext, visibleContext, data, cc,
directionEnabled, reachEnabled, visibleEnabled)) {
thisPassed = false;
}
else {
reachPassed = true;
}
}
// TODO: Efficiency: don't check at all, if strict and !thisPassed.
if (directionEnabled && (reachPassed || !directionPassed)) {
if (direction.loopCheck(player, loc, damaged, entry, directionContext, data, cc)) {
thisPassed = false;
}
else {
directionPassed = true;
} else {
if (reachEnabled) {
if (reach.loopCheck(player, loc, damaged, entry, reachContext, data, cc)) {
thisPassed = false;
}
else {
reachPassed = true;
}
}
// TODO: Efficiency: don't check at all, if strict and !thisPassed.
if (directionEnabled && (reachPassed || !directionPassed)) {
if (direction.loopCheck(player, loc, damaged, entry, directionContext, data, cc)) {
thisPassed = false;
}
else {
directionPassed = true;
}
}
}
if (thisPassed) {
// TODO: Log/set estimated latency.
violation = false;
@@ -535,20 +561,29 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
break;
}
}
// TODO: How to treat mixed state: violation && reachPassed && directionPassed [current: use min violation // thinkable: silent cancel, if actions have cancel (!)]
// TODO: Adapt according to strictness settings?
// TODO: violation vs. reachPassed + directionPassed (current: fail one = fail all).
if (reachEnabled) {
// TODO: Might ignore if already cancelled by mixed/silent cancel.
if (reach.loopFinish(player, loc, damaged, reachContext, successEntry, violation,
data, cc, pData)) {
if (directionEnabled && hitboxEnabled) {
if (hitBox.loopFinish(player, loc, damaged,
reachContext, directionContext, visibleContext,
successEntry, violation, data, cc,
reachEnabled, visibleEnabled, pData)) {
cancelled = true;
}
}
if (directionEnabled) {
// TODO: Might ignore if already cancelled.
if (direction.loopFinish(player, loc, damaged, directionContext, violation, data, cc)) {
cancelled = true;
} else {
// TODO: How to treat mixed state: violation && reachPassed && directionPassed [current: use min violation // thinkable: silent cancel, if actions have cancel (!)]
// TODO: Adapt according to strictness settings?
// TODO: violation vs. reachPassed + directionPassed (current: fail one = fail all).
if (reachEnabled) {
// TODO: Might ignore if already cancelled by mixed/silent cancel.
if (reach.loopFinish(player, loc, damaged, reachContext, successEntry, violation,
data, cc, pData)) {
cancelled = true;
}
}
if (directionEnabled) {
// TODO: Might ignore if already cancelled.
if (direction.loopFinish(player, loc, damaged, directionContext, violation, data, cc)) {
cancelled = true;
}
}
}
// TODO: Log exact state, probably record min/max latency (individually).
@@ -0,0 +1,215 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.fight;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace.ITraceEntry;
import fr.neatmonster.nocheatplus.players.IPlayerData;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.collision.CollideRayVsAABB;
import fr.neatmonster.nocheatplus.utilities.collision.ICollideRayVsAABB;
import fr.neatmonster.nocheatplus.utilities.collision.PassableRayTracing;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
import fr.neatmonster.nocheatplus.utilities.map.WrapBlockCache;
public class HitBox extends Check {
private final ICollideRayVsAABB boulder = new CollideRayVsAABB();
private final PassableRayTracing rayTracing = new PassableRayTracing();
private final WrapBlockCache wrapBlockCache;
public HitBox() {
super(CheckType.FIGHT_HITBOX);
wrapBlockCache = new WrapBlockCache();
rayTracing.setMaxSteps(30);
}
public boolean check(final Player player, final Location pLoc,
final Entity damaged, final boolean damagedIsFake, final Location dRef,
final FightData data, final FightConfig cc, final IPlayerData pData,
final boolean reachEnabled, final boolean visibleEnabled) {
boolean cancel = false;
final double eyeYLocation = pLoc.getY() + player.getEyeHeight() - (player.isSneaking() ? 0.08 : 0.0);
final double distanceLimit = cc.reachSurvivalDistance + (player.getGameMode() == GameMode.CREATIVE ? 2.0 : 0.0);
final double height = damagedIsFake ? (damaged instanceof LivingEntity ? ((LivingEntity) damaged).getEyeHeight() : 1.75) : mcAccess.getHandle().getHeight(damaged);
final double width = damagedIsFake ? 0.6 : mcAccess.getHandle().getWidth(damaged) / 2;
final Vector direction = pLoc.getDirection();
final BlockCache blockCache = wrapBlockCache.getBlockCache();
blockCache.setAccess(pLoc.getWorld());
boulder.setFindNearestPointIfNotCollide(false)
.setRay(pLoc.getX(), eyeYLocation, pLoc.getZ(), direction.getX(), direction.getY(), direction.getZ())
.setAABB(dRef.getX(), dRef.getY(), dRef.getZ(), width + cc.hitBoxHorizontalExpansion, height + cc.hitBoxVerticalExpansion)
.loop();
if (boulder.collides()) {
// Direction passed
data.directionVL *= 0.8D;
// Checking distance
final double distance = TrigUtil.distance(boulder.getX(), boulder.getY(), boulder.getZ(),
pLoc.getX(), eyeYLocation, pLoc.getZ());
if (reachEnabled) {
if (distance > distanceLimit) {
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance - distanceLimit, cc.reachActions);
vd.setParameter(ParameterName.REACH_DISTANCE, StringUtil.fdec3.format(distance));
cancel = executeActions(vd).willCancel();
} else {
data.reachVL *= 0.8D;
}
}
// Checking visible
if (visibleEnabled && !cancel) {
rayTracing.setBlockCache(blockCache);
rayTracing.setIgnoreInitiallyColliding(true);
rayTracing.set(pLoc.getX(), eyeYLocation, pLoc.getZ(), boulder.getX(), boulder.getY(), boulder.getZ());
rayTracing.loop();
if (rayTracing.collides()) {
data.visibleVL++;
cancel = executeActions(player, data.visibleVL, 1.0, cc.visibleActions).willCancel();
} else {
data.visibleVL *= 0.8D;
}
}
} else {
// Direction failed. Skipping distance, visible check
final Vector blockEyes = new Vector(dRef.getX() - pLoc.getX(), dRef.getY() + height / 2D - eyeYLocation, dRef.getZ() - pLoc.getZ());
final double distance = blockEyes.crossProduct(direction).length() / direction.length();
data.directionVL += distance;
cancel = executeActions(player, data.directionVL, distance, cc.directionActions).willCancel();
if (cancel) {
// Deal an attack penalty time.
data.attackPenalty.applyPenalty(cc.directionPenalty);
}
}
rayTracing.cleanup();
blockCache.cleanup();
return cancel;
}
public boolean loopCheck(final Player player, final Location loc, final ITraceEntry dLoc,
final DirectionContext dirContext, final ReachContext reachContext, final VisibleContext visibleContext,
final FightData data, final FightConfig cc,
final boolean directionEnabled, final boolean reachEnabled, final boolean visibleEnabled) {
boolean cancel = false;
final double eyeYLocation = loc.getY() + player.getEyeHeight() - (player.isSneaking() ? 0.08 : 0.0);
final double distanceLimit = cc.reachSurvivalDistance + (player.getGameMode() == GameMode.CREATIVE ? 2.0 : 0.0);
if (reachEnabled) reachContext.distanceLimit = distanceLimit;
boulder.setFindNearestPointIfNotCollide(false)
.setRay(loc.getX(), eyeYLocation, loc.getZ(),
dirContext.direction.getX(), dirContext.direction.getY(), dirContext.direction.getZ())
.setAABB(dLoc.getX(), dLoc.getY(), dLoc.getZ(),
dLoc.getBoxMarginHorizontal() + cc.hitBoxHorizontalExpansion, dLoc.getBoxMarginVertical() + cc.hitBoxVerticalExpansion)
.loop();
if (boulder.collides()) {
// Direction passed
// Checking distance
final double distance = TrigUtil.distance(boulder.getX(), boulder.getY(), boulder.getZ(),
loc.getX(), eyeYLocation, loc.getZ());
if (reachEnabled) {
if (distance > distanceLimit) {
reachContext.minViolation = Math.min(reachContext.minViolation, distance);
cancel = true;
}
reachContext.minResult = Math.min(reachContext.minResult, distance);
}
// Checking visible
if (visibleEnabled && !cancel) {
rayTracing.setBlockCache(visibleContext.cache);
rayTracing.setIgnoreInitiallyColliding(true);
rayTracing.set(loc.getX(), eyeYLocation, loc.getZ(), boulder.getX(), boulder.getY(), boulder.getZ());
rayTracing.loop();
if (rayTracing.collides()) {
visibleContext.collided = true;
cancel = true;
}
}
} else {
// Direction failed. Skipping distance, visible check
final Vector blockEyes = new Vector(dLoc.getX() - loc.getX(), dLoc.getY() + dLoc.getBoxMarginVertical() / 2D - eyeYLocation, dLoc.getZ() - loc.getZ());
final double distance = blockEyes.crossProduct(dirContext.direction).length() / dirContext.lengthDirection;
dirContext.minViolation = Math.min(dirContext.minViolation, distance);
cancel = true;
}
rayTracing.cleanup();
return cancel;
}
public boolean loopFinish(final Player player, final Location pLoc, final Entity damaged,
final ReachContext reachContext, final DirectionContext dirContext, final VisibleContext visibleContext,
final ITraceEntry traceEntry, final boolean forceViolation,
final FightData data, final FightConfig cc, final boolean reachEnabled, final boolean visibleEnabled, final IPlayerData pData) {
boolean cancel = false;
final double distance = reachEnabled ? forceViolation && reachContext.minViolation != Double.MAX_VALUE ? reachContext.minViolation : reachContext.minResult : Double.MAX_VALUE;
final double off = forceViolation && dirContext.minViolation != Double.MAX_VALUE ? dirContext.minViolation : dirContext.minResult;
final boolean collided = visibleEnabled ? forceViolation && visibleContext.collided : false;
if (visibleEnabled) visibleContext.cache.cleanup();
// Direction violation
if (off != Double.MAX_VALUE && off > 0) {
data.directionVL += off;
cancel = executeActions(player, data.directionVL, off, cc.directionActions).willCancel();
if (cancel) {
// Deal an attack penalty time.
data.attackPenalty.applyPenalty(cc.directionPenalty);
return cancel;
}
} else {
// Reward the player by lowering their violation level.
data.directionVL *= 0.8D;
}
// Reach violation
if (distance != Double.MAX_VALUE && distance > reachContext.distanceLimit) {
data.reachVL += distance - reachContext.distanceLimit;
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance - reachContext.distanceLimit, cc.reachActions);
vd.setParameter(ParameterName.REACH_DISTANCE, StringUtil.fdec3.format(distance));
cancel = executeActions(vd).willCancel();
if (cancel) {
// Apply an attack penalty time.
data.attackPenalty.applyPenalty(cc.reachPenalty);
return cancel;
}
} else {
// Player passed the check, reward them.
data.reachVL *= 0.8D;
}
// Visible violation
if (collided) {
data.visibleVL++;
cancel = executeActions(player, data.visibleVL, 1.0, cc.visibleActions).willCancel();
} else {
data.visibleVL *= 0.8D;
}
return cancel;
}
}
@@ -0,0 +1,65 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.fight;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.utilities.map.WrapBlockCache;
public class Visible extends Check {
private final WrapBlockCache wrapBlockCache;
public Visible() {
super(CheckType.FIGHT_VISIBLE);
wrapBlockCache = new WrapBlockCache();
}
public boolean check() {
return false;
}
public boolean loopCheck() {
return false;
}
public boolean loopFinish() {
return false;
}
/**
* Data context for iterating over ITraceEntry instances.
* @param player
* @param pLoc
* @param damaged
* @param damagedLoc
* @param data
* @param cc
* @return
*/
public VisibleContext getContext(final Player player, final Location pLoc,
final Entity damaged, final Location damagedLoc,
final FightData data, final FightConfig cc) {
final VisibleContext context = new VisibleContext();
context.pY = pLoc.getY() + player.getEyeHeight();
context.cache = wrapBlockCache.getBlockCache().setAccess(pLoc.getWorld());
return context;
}
}
@@ -0,0 +1,24 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.checks.fight;
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
public class VisibleContext {
/** Eye location y of the attacking player. */
public double pY;
public boolean collided = false;
public BlockCache cache;
}
@@ -1774,12 +1774,12 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final Location ref = player.getVehicle().getLocation(useLoc);
aux.resetPositionsAndMediumProperties(player, ref, mData, mCc); // TODO: Consider using to and intercept cheat attempts in another way.
useLoc.setWorld(null);
mData.updateTrace(player, to, tick, mcAccess.getHandle()); // TODO: Can you become invincible by sending special moves?
mData.updateTrace(player, to, now, mcAccess.getHandle()); // TODO: Can you become invincible by sending special moves?
}
else if (!from.getWorld().getName().equals(toWorldName)) {
// A teleport event should follow.
aux.resetPositionsAndMediumProperties(player, to, mData, mCc);
mData.resetTrace(player, to, tick, mcAccess.getHandle(), mCc);
mData.resetTrace(player, to, now, mcAccess.getHandle(), mCc);
}
else {
// TODO: Detect differing location (a teleport event would follow).
@@ -1791,7 +1791,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
else {
// Normal move, nothing to do.
}
mData.updateTrace(player, to, tick, mcAccess.getHandle());
mData.updateTrace(player, to, now, mcAccess.getHandle());
if (mData.hasTeleported()) onPlayerMoveMonitorNotCancelledHasTeleported(player, to, mData, pData, pData.isDebugActive(checkType));
}
}
@@ -483,7 +483,7 @@ public abstract class ConfPaths {
public static final String FIGHT_CANCELDEAD = FIGHT + "canceldead";
public static final String FIGHT_TOOLCHANGEPENALTY = FIGHT + "toolchangepenalty";
private static final String FIGHT_PVP = FIGHT + "pvp.";
public static final String FIGHT_MAXLOOPLETENCYTICKS = FIGHT + "maxloopletencyticks";
public static final String FIGHT_MAXLOOPLETENCYMS = FIGHT + "maxloopletencyms";
public static final String FIGHT_PVP_KNOCKBACKVELOCITY = FIGHT_PVP + "knockbackvelocity";
private static final String FIGHT_ANGLE = FIGHT + "angle.";
@@ -523,6 +523,11 @@ public abstract class ConfPaths {
public static final String FIGHT_GODMODE_LAGMAXAGE = FIGHT_GODMODE + "maxage";
public static final String FIGHT_GODMODE_ACTIONS = FIGHT_GODMODE + "actions";
private static final String FIGHT_HITBOX = FIGHT + "hitbox.";
public static final String FIGHT_HITBOX_CHECK = FIGHT_HITBOX + SUB_ACTIVE;
public static final String FIGHT_HITBOX_HORIZONTAL_EXPAND = FIGHT_HITBOX + "marginhorizontal";
public static final String FIGHT_HITBOX_VERTICAL_EXPAND = FIGHT_HITBOX + "marginvertical";
private static final String FIGHT_NOSWING = FIGHT + "noswing.";
public static final String FIGHT_NOSWING_CHECK = FIGHT_NOSWING + SUB_ACTIVE;
public static final String FIGHT_NOSWING_ACTIONS = FIGHT_NOSWING + "actions";
@@ -563,7 +568,11 @@ public abstract class ConfPaths {
public static final String FIGHT_SPEED_IMPROBABLE_FEEDONLY = FIGHT_SPEED_IMPROBABLE + "feedonly";
public static final String FIGHT_SPEED_IMPROBABLE_WEIGHT = FIGHT_SPEED_IMPROBABLE + "weight";
public static final String FIGHT_SPEED_ACTIONS = FIGHT_SPEED + "actions";
private static final String FIGHT_VISIBLE = FIGHT + "visible.";
public static final String FIGHT_VISIBLE_CHECK = FIGHT_VISIBLE + SUB_ACTIVE;
public static final String FIGHT_VISIBLE_ACTIONS = FIGHT_VISIBLE + "actions";
private static final String FIGHT_YAWRATE = FIGHT + "yawrate.";
public static final String FIGHT_YAWRATE_CHECK = FIGHT_YAWRATE + SUB_ACTIVE;
@@ -165,7 +165,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.BLOCKINTERACT_SPEED_ACTIONS, "cancel vl>10 cancel log:bspeed:5:4:i cancel vl>500 cancel log:bspeed:0:5:icf cmdc:kickbspeed:2:5", 1154);
// Visible
set(ConfPaths.BLOCKINTERACT_VISIBLE_CHECK, "default", 785);
set(ConfPaths.BLOCKINTERACT_VISIBLE_ACTIONS, "cancel vl>30 log:bvisible:8:5:if cancel", 1154);
set(ConfPaths.BLOCKINTERACT_VISIBLE_ACTIONS, "cancel vl>30 log:bvisible:8:5:if cancel", 1154);
/* BlockPlace */
@@ -333,8 +333,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.FIGHT_ACTIVE, "default", 1144);
// General
set(ConfPaths.FIGHT_CANCELDEAD, true, 785);
// TODO: Using System.currentTimeMillis() for timestamp not server tick?
set(ConfPaths.FIGHT_MAXLOOPLETENCYTICKS, 8, 1154);
set(ConfPaths.FIGHT_MAXLOOPLETENCYMS, 2000, 1154);
set(ConfPaths.FIGHT_TOOLCHANGEPENALTY, 0L, 1154); // Disabled for now, it interferes too much with pvp. 500L
set(ConfPaths.FIGHT_PVP_KNOCKBACKVELOCITY, "default", 785);
// YawRate activation flag
@@ -367,6 +366,10 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.FIGHT_GODMODE_LAGMINAGE, 1100, 785); // TODO: ndt/2 => 500-600.
set(ConfPaths.FIGHT_GODMODE_LAGMAXAGE, 5000, 785);
set(ConfPaths.FIGHT_GODMODE_ACTIONS, "cancel log:godmode:0:5:icf cmdc:kickgod:0:5", 1154);
// HitBox
set(ConfPaths.FIGHT_HITBOX_CHECK, "default", 1154);
set(ConfPaths.FIGHT_HITBOX_HORIZONTAL_EXPAND, 0.125, 1154);
set(ConfPaths.FIGHT_HITBOX_VERTICAL_EXPAND, 0.125, 1154);
// NoSwing
set(ConfPaths.FIGHT_NOSWING_CHECK, "default", 785);
set(ConfPaths.FIGHT_NOSWING_ACTIONS, "vl>2 cancel vl>10 log:noswing:2:5:i cancel", 1154);
@@ -401,6 +404,9 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.FIGHT_SPEED_SHORTTERM_LIMIT, 5, 1154);
set(ConfPaths.FIGHT_SPEED_IMPROBABLE_FEEDONLY, false, 1154);
set(ConfPaths.FIGHT_SPEED_IMPROBABLE_WEIGHT, 2.0, 1154);
// Visible
set(ConfPaths.FIGHT_VISIBLE_CHECK, "default", 1154);
set(ConfPaths.FIGHT_VISIBLE_ACTIONS, "cancel vl>30 log:fvisible:8:5:if cancel", 1154);
/* Inventory */
@@ -701,6 +707,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.STRINGS + ".freach", start + "tried to hit an entity from a suspicious distance (Reach: &6[reachdistance]&7)" + end, 1154);
set(ConfPaths.STRINGS + ".fselfhit", start + "tried to hit themselves" + end, 1154);
set(ConfPaths.STRINGS + ".fspeed", start + "clicked [violations] times over the established [limit] CPS limit" + end, 1154);
set(ConfPaths.STRINGS + ".fvisible", start + "tried to attack through a solid obstacle" + end, 1154);
set(ConfPaths.STRINGS + ".godmode", start + "tried to ignore inflicted damage (Health: &7[health]&7)" + end, 1154);
set(ConfPaths.STRINGS + ".gutenberg", start + "created a book with too many pages" + end, 785);
set(ConfPaths.STRINGS + ".improbable", start + "is exhibiting an erratic behaviour (Check: &6[tags]&7)" + end, 1154);
@@ -144,6 +144,7 @@ public class Permissions {
public static final RegisteredPermission FIGHT_REACH = add(FIGHT + ".reach");
public static final RegisteredPermission FIGHT_SELFHIT = add(FIGHT + ".selfhit");
public static final RegisteredPermission FIGHT_SPEED = add(FIGHT + ".speed");
public static final RegisteredPermission FIGHT_VISIBLE = add(FIGHT + ".visible");
public static final RegisteredPermission INVENTORY = add(CHECKS + ".inventory");
public static final RegisteredPermission INVENTORY_DROP = add(INVENTORY + ".drop");