Represents the first "simplistic" approach to block change tracking,
only attempting to make vertical push/pull work.
It seems that we need to add on-ground checking accounting for piston
moves as well, otherwise anything with pistons retracting will lead to
survivalfly violations. Pistons extending and retracting may also
randomly move around players, including dragging them into the piston
block with the bounding box (not center of player).
In order to make on-ground work, we might need to check in another
place, possibly check where resetFrom an resetTo are set. Performance
questions might remain, there might also be a slight redesign necessary,
in order to run some sub-routines more side-effect free, to check
several branches, including after-failure checking.
* Below 1.7 allow ground-to-ground hop with moderate speed. Might be
there is more speed possible, shortly tested on 1.6.4.
* From 1.7.10 on, hitting the jump envelope or having the head
obstructed is demanded.
* The GROUND_HEIGHT flag indicates, that players are on ground (and can
walk on) from getGroundMinHeight on, once a block collides. Thus an
extra case for isPassableWorkaround is necessary.
* Set GROUND_HEIGHT for ENDER_PORTAL_FRAME, return the minimal height of
the ENDER_PORTAL_FRAME block for getGroundMinHeight. (Also add XZ100,
just to be sure.)
This breaks testing for UNKNOWN_VERSION, if that is used externally.
Access methods are added for testing for unknown versions.
PR mentioning access methods:
94c4da3267
Vertical part first was ineffective due to yDiff never being > 0.0 and
<= 0.0 at the same time, beside vertical-first is what the client is
doing. Might want to check the full bounding box with the simplified
y-first model, also checking x and z parts in the right order, from
there on.
Mostly for legacy Player instance getting, future aims are:
* Efficient lookup by name.
* Efficient lookup by prefixes of names (e.g. for command use).
* Efficient lookup name->uuid and uuid->name.
* Keep name->uuid mappings for history lookup and similar.
Refactor
* Move hasBypass code to CheckUtils.
Efficiency
* Alter/add methods for testing with with optional check data/config.
* Use more efficient calls in several places (unfinished).
Consistency
* Log an error, if calling hasBypass off main thread unexpectedly.
* (Mostly irrelevant null checks.)
This should prevent bouncing higher and higher (cheat).
Missing:
* The bounce effect should be set considering the last yDistance, in
order to allow negative vertical velocity to work.
* Add workaorunds for gravity with exiting cobweb.
* Allow multiple times zero y-distance (cobweb several times, slime 2).
Cobweb may need adjusting the bounding box to check with, instead.
* The server might reset the fall distance with preceding micro-moves,
so use NoFall data already on checking pre-conditions for bounce.
* Cap the bounce effect slightly smaller.
* Renew the bounce effect under certain conditions.
* Gravity, odds.
Remaining:
* Two consecutive times yDist = 0 at the maximum of a jump.
MISSING:
* Micro move onto ground, fall distance resets before sf check is run.
Done:
* Split PlayerMoveEvent processing to from -> loc + from -> to. Just if
from isn't the same coordinates as player.getLocation. This
reduces the complexity of workarounds.
* You do take fall damage falling onto slime blocks while sneaking.
* Queue bounce effect, only if the move is valid. Skip NoFall then.
* Apply bounce effect once moving up, to allow overriding.
* Cover more odd cases.
Unrelated:
* Use data.debug instead of cc.debug.
Adjust workarounds, confine velocity activation to next tick.
Cases missing:
* Lost ground cases (yOnGround has been reduced, strikes here).
* Two consecutive yDist = 0.
This will preserve the order of debug messages sent from multiple
threads. As a side effect, this might be better for performance, given
that on constant input the logging task will stay registered, so there
is little overhead and the file-io is taken off the asynchronous packet
and chat handler threads.Hopefully the thread switching is less
expensive than the gain by not delaying chat/packet threads, in case of
servers with few cores. We might adapt the used policy later, based on
cores and/or config.
* Queue outgoing positions in order to detect ACK on incoming.
* Since we can't detect relative teleports, positions are only queued,
if they match an absolute location from a teleport event (Bukkit).
* The queue is kept simple: only store the latest position.
* Cancel incoming flying/pos/look until ACK is received.
Missing:
* Are yaw/pitch are ever sent back changed.
* Configuration to turn it off.
* Might use this to just skip all violation handling until ACK.
This is a quick go with little testing, roughly up to level 60. Above
that there may be more false positives, also "no jumping" is not
enforced there.
A suggestion for the future could be to just use/part-calculate an array
for all the typical effects.
Used to be 0.0625 for a while, but intentions are to cover ground-loss
as lostground workarounds. Later switch to calculate the distance to
ground (with a given max-distance).
For efficiency (several?) other cases will be removable, once we model
the per-move ground/medium properties more accurately also for the past
move(s). At least lostground_pyramid should be removed then.
Splits CoordMap into interface, abstract hash map, implementations.
Sketch Linked version, hinting at access order, e.g. with
tracking piston effects with timeouts.
Missing:
* Implementation of a linked version.
Cancelling redundant packets has to big problems:
* The normal case is to not run in the primary thread.
* For legit players a missed micro move could mean that survivalfly can
not detect ground properly.
Better approaches could be:
* Cancel asynchronous packets if they match the last sent one (only
simple hacks).
* Check for moves passing block borders, request block shapes and such
from the main thread.
* Detect actual cheating or unusual patterns instead.
* Queue packets for processing in the main thread.
Missing:
* Actually detect ACK packets for previous outgoing teleports.
* Do something upon detecting illegal coordinates (asynchronous
disconnect? queue kicking, config).
* In addition to the "distance from set-back" check, we have a check of
the per-move distance for in-air checks, taking account of friction.
* In-air and liquid checks should consume vertical velocity once needed.
* Model vertical velocity "exact", i.e. positive and negative, use an
entry once a sub-check fails, quite strict invalidation of not matching
values, matching against the y-distance directly.
* Vertical accounting has been sharpened for the moment. The new
per-move checking might make it superfluous.
* Remove MediumLiftOff in favor of a LiftOffEnvelope carrying basic
lift-off max-gain/max-height/max-phase, enabling to distinguish between
normal lift-off and liquid near ground.
* Rename others (e.g. sfLastYDist -> lastYDist). Thus breaking internal
naming, adding velocity via MovingData still works, but should behave
slightly differently.
* Fixes (waterwalk with head obstructed, resetting of sfDirty, possibly
others).
Issues.
* Edge cases with velocity, water.
* Lava needs friction, at least with velocity.
* Lostground_edge(ydist < 0.0) ->
bunny with yDistance > 0.0. Need more flags or better model for keeping
past moves information.
* Plain ground misses (layered snow).
* lostground with yDist == 0.0, then seemingly in-air yDist== 0.0, then
bunny/lifft-off (similar to above). Needs better modeling of past moves,
because several lostgorund cases mean "the move has been on ground".
Also includes geting the distance to ground for hack-proof set-back-y.
* Vertical velocity is now matched with a margin, because the client
seems to add randomly.
* Possibly new loopholes/exploits (extreme large moves?).
* Cleanup pending.
* Group selected classes into sub-packages of moving.
* Rename classes.
* Must use LinkedList for velocity entries.
* Prepare SimpleAxisVelocity + entry for use-once accounting.
(Might not be the final naming.)
* Use BlockProperties.collides to use the actual bounds of blocks.
* Don't test for sfLowJump to set allowHop.
* Set head bump margin to match 2-high spots and to prevent lowjump fps.
* Tighten conditions for actual hop.
* Don't x > 1.314 * x.
* Add height, eyeHeight, isHeadObstructed to PlayerLocation.
* lowjump detection: from is higher than to, test both locations.
* Remove bunny reset within lowjump detection (defeated flying bunny).
* Check isHeadObstructed directly in the bunnyHop method.
Issues remaining:
* Moderate acceleration ground to ground, after having landed (+1st).
* Possibly transitions between 2-high and other.
* More edge cases with slowness potion.
This seems to be the same value on ground as with slowness potion and
2-step acceleration. Not possible to squeeze into the ordinary bunny
envelope.
On the fly: add PlayerLocation.isOnGroundOrResetCond.
Slowness+bunny will still not fully work, because we need to model
closer to the client here, i.e. acceleration and friction. Remaining
issues in rough order of naughtiness:
* On-ground friction based speed decrease.
* Increasing of speed, above slowness sprinting speed but below normal
sprinting speed.
* Two-step bunnyhop, having h-speed increase to bunny with two packets.
Similarly acceleration effects when touching ground, not modeled right
by bunny.
* Possibly more.
* Remove early return, as we prefer to know what NCP would allow, at
least until sf changes have stabilized.
* Only count in speed effects for normal running/jumping, not
water/web/blocking/sneaking. Either check potion effects or attributes.
Mainly catches the instant ladder and too large moves, generalize step
to have general "reset" as condition instead of "ground", don't limit by
a distance.
* Not actually a fix for anything we encountered.
* Nailed down blockinteract.visible raytracing issues to bad end-points
for raytracing.
* Also test/prepare logging test-cases for raytracing in general. Not
enabled, because we should have some flag/permission/command to check
before logging ~ 5KB per interact event.
This makes logging all violations potentially useful to use alongside
with the "ncp debug player" command in production environments. The flag
debugonly must be set with at least one backend being activated.
Similar to TestNCP but reduced/different features:
* Config: trace for the log file and notify to send to notify channel.
* It's not possible to confine whose messages you receive (yet).
Meant for better local/quick testing in the first place.
* Make attribute methods consistent (remove the sprint boost modifier
from the generic speed multiplier, because it's inconsistent).
* Add missing implementations.
* Adjust default sprinting speed modifier.
* Add more guards for the latest compat module (1.8_R3).
* Add a reflection based compat module for CB, to cover minor updates.
* Possibly other minor fixes/changes.
[Hail "insufficient data written"!]
When the respawn/login location is obstructed, the respawn event shows
that location, but the first move will start at several blocks above,
without having a teleport event to rely on, thus this workaround.
Vertical velocity handling can be much simplified (and possibly extended
to including downwards velocity) with using a friction-based modeling.
Absolute envelopes can still be checked extra, where appropriate.
Not very efficient in terms of code-output, but enabling us to log test
cases for visible (and potentially passable too), using real-life
examples.
* Add the capability to log a FakeBlockCache as java code.
* Add utility to record map parts (cuboid, ray-tracing with margin) to a
FakeBlockCache.
Missing:
* Actually log stuff (visible).
This is not the thing (lots of yet), but it is a small step.
Refactor:
* Use access methods for several details on vertical velocity.
Fixes:
* Dont reset the current jump phase if there is vertical freedom left,
because the next jump might then cause a violation.
* Fix clearActiveVerVel (remainder used to clear hVel, yet unused).
* Clear vertical velocity on removeAllVelocity (!).
* Keep setting sfDirty if velocity is found, to prevent premature reset.
Missing:
* Some resetting conditions for sfDirty might be missing.
* Implement an error counter increasing with velocity-add by 1.0 or
slightly more , decreasing with violations, but undo violations if count
is > 0.0. Use at least for vertical accounting, in order to go stricter
on cheating with velocity.
* Revise setting sfDirty on horizontal velocity as well.
* Switch to AxisVelocity (vertical), accounting for + and -.
* Use a LinkedList for storing past locations (prevents overriding if
t_last = t_now, also allows storing differences there right away).
* Calculate the yaw difference vs. the maximally possible value (180).
* Add switching the target as an extra weight.
The workarounds in InteractRayTracing and using multiple
reference-targets in Visible have all been removed in favor of using the
actual looking direction for ray-tracing.
On quick testing, there remain false positives, allowing to somewhat
escalate violation levels, if intended to. On normal playering false
positives seem to happen very near the very edges between blocks on
occasion.
* More tests for PassableRayTracing (room, rays from outside).
* Alter InteractRayTracing to account for the block interacted with.
* Added tests for InteractRayTracing.
Problems:
* RayTracing may end x-th digit off target, thus in the wrong block.
Suggested fix is to keep correcting t by the absolute coordinates of the
blocks, i.e. calculate the absolute position rather than adding up.
* InteractRayTracing with strict set to false (like in the
blockinteract.visible check) will be too lenient with 1-thick wall
setups and fail test cases.
Previously only "random" transitions were taken, for simplicity. For the
sake of better debugging and consistency we check all combinations of
transitions now, calling the iteration with all transitions done at once
the "primary line", while calling step with a subset of transitions done
would be the "secondary line".
Currently an iteration might still end x-th digit off the target, so it
does not necessarily end on the target block itself. This is not a
problem for passable, but might be one for interaction and other
applications, thus this should be fixed at some point.
To avoid cheaters accumulating velocity dealt by damage, we skip dealing
fall damage, if they would not have received any, without taking the
current move into account. This is only for the case a player causes a
violation for which NoFall would usually have dealt fall damage.
* Update lastKeepAliveTime from KeepAliveFrequency (even if that is
disabled).
* Update lastKeepAliveTime from FlyingFrequency too.
* Allow to test for feature tags efficiently.
* lastUpdate is always set calling update().
* Negative diff can not affect update (time ran backwards).
* Use lastUpdate instead of lastAccess where appropriate.
* More comments/formatting.
While we can/could control which stream to log to within onDisable, we
should still assume that an asynchronous task could be using the logging
system. Since we don't have a clean entry to onDisable, we have to catch
the exception.
* Extend CheckConfigFactory with a remove-all method.
* DataManager.clearConfigs() now uses CheckType for getting factories.
* Split off Check.hasBypass method to check exemption + permission.
* Allow null permissions in CheckType (interpret as no bypass).
* Add Check types for FlyingFrequency and SoundDistance.
* Add exemption and actions to FlyingFrequency, alter defaults.
* Add a test for moving a simple config value (not sections).
* Add a flag to @Moved to allow explicitly skipping sections.
(Should enable moving values into a child path of the previous one.)
* Don't set values before inside of processMoved...
First attempt to detect if a moving event would fire. This might not be
100% accurate, as a) we can'T really know and b) lastTo is not minitored
in the most reliable way (e.g. teleport on highest priority, resetting
logic favors set-backs).
* Use a HashMap for data, as we intend to use the primary thread.
* Move redundant move checking into a method.
* Ignore on-ground, if it is sent too often.
* Log if redundant move checking has to be disabled.
Removes access by name and entity-id for now. Access by name might be
re-added, though any kind of mappings will likely be maintained
somewhere near DataManager.
Measuring the time from sprint to attack doesn't work well. The
ctrl-sprint thing also adds to it. Better would be measuring the
toggle-sprint frequency and possibly combine it with some other measure
(packet level attack frequency?) then rather deal attack penalty time.
We can now decide on base of the Minecraft version, which value to use,
with the config entry set to "default". Used with
pvp-knock-back-velocity and enforce-location (first move exploit).
Activated features are shown in the version info ("ncp version"). The
version info is now logged to the log file after post-enable and after
reloading the configuration.
* Add methods to NoCheatPlusAPI to add/set/get version tags.
* Display all tags in the ncp reload command.
* Alter test framework to set a dummy API.
* Add tags for blocks, net checks, FastConsume.
Contained changes:
- Melon and pumpkin block break timings: 1.8-specific, keep workaround.
- Don't run all horizontal move checking if no move.
- Utility method for checking for air.
- Some formatting.
A cheat client could move such that they are inside of a block, but
CraftBukkit will not fire an event, because the distance and looking
direction don't change enough. Teleporting other players or yourself to
that location would result in getting someone into a block. Consequently
we also have to block commands like /sethome at such locations.
Our first attempt to patch that will monitor teleports that use the
TeleportCause.COMMAND (might miss out on plugins that are not using the
appropriate cause, and on plugins that use items for teleportation), in
addition we monitor certain commands (configurable prefixes), to catch
things like "sethome" and "sethome2". The world spawn is exempted. Only
teleports into blocks are monitored.
This does not yet sanity-check the distance to the last tracked
location, but it will ignore if none is set.
Details:
* Only trim commands from the left side (both on feed and check).
* Ensure versions with and without leading '/' are fed into trees.
* Move methods to feed CharPrefixTree from configs to CommandUtil.
Potentially fixes (untested):
* Only deny the sub-commands for a prefix, example: feed 'version ' to
consoleonly, in order to allow 'version' but not 'version NoCheatplus'.
* Might fix some plugin/server specific prefixes not being detected,
example: feed "/version" and expect "/bukkit:version" to be blocked.
* Some cleanups (spaces, commented out references updated).
* LogManager implement INotifyReload, but gets processed extra (not
added with addComponent).
This is the first simple version, just setting debug for all checks for
the player(s). It can only be undone by removing the data, e.g. with
"ncp remove (player)", reloading does it too, but is much heavier.
For debug output now data.debug is used instead of config.debug, so the
data is initialized with the config.debug value. As an effect of this,
removing the data or reloading will override flags that have been set by
means of API-access only.
Affected:
* Adds getDebug and setDebug to ICheckData.
* Adds appropriate configs to all constructors of check data.
* Some per-check debug flags have been removed.
Extras:
* spaces
* import cleanup.
* Remove on-ground check.
* Always increase VL by 1, because clients could control it anyway.
* Skip if the player is in a vehicle.
* Remove adapting to lag.
* All logging is also going into the log file (always), debug output is
mostly/only going into the log file. File logging uses an asynchronously
processed queue now (!).
* Specify an existing directory (e.g. logs) and log files will named
after date + sequence number, changing with every reloading of the
configuration.
* Console and ingame logging remain within the primary thread.
* No extra configurability for customization, yet.
* Not all places have been cleaned up, concerning log levels. target
streams and package naming.
* Work in progress.