First batch:
* Initialize blocks somehow, so no errors nor missing blocks happen
during startup.
Possibly Missing:
* There might be references of removed/renamed material (blocks/items)
throughout the code.
* Some blocks may behave different now/then.
Missing:
* Block#getData may not reflect (all?) properties anymore.
* Block shape getting is missing. Block shapes are now (potentially)
more complex to process. Concept might be to keep a double array for the
rough bounds, and add an (optional +- null) array of arrays for sub
shapes, if present (IBlockCacheNode). So a first rough update is more
simple/compatible.
Likely incomplete/broken somewhere.
Implement/extend/use/fix new data caches and factories.
(+) Fixes related to recent commits (e.g. log listener exceptions
properly, fight.wrongturn).
Missing:
* Debug logging (registry), consider a registry log file.
* Proper naming/tags for listeners.
* Consistency: ICheckData should probably be used with
removeData(CheckType)? Registration is arbitrary though.
* Consistency: clearData() vs clearData(CheckType.ALL) - should check
type related data be ICheckData only ?
* Data expiration stages and PlayerOfflineData - impact on memory...
* (...)
Further:
* WorldData inheritance issue: implement passing on changes to children.
(Current line of thought: rather extend IWorldDataManager to allow
change default+inherited only.)
* Shrink exposed API - uncertain: rather have a registration context
object or expose individual methods for factory registration and
grouping types?
* (...)
* Planned breakage: Project + package organization redone: move stuff
where it is best for having an API (components -> split to top level or
name it api, utilities ... parts belong into API, and the like...,
possibly split project further: commons, api(+-bukkit), core/checks,
plugin-bukkit).
In case a player is above the void (no ground / liquid / web / climbable
underneath), they're teleported directly to the void.
Further adjustments:
* A flag for cobweb has been added.
* MovingUtil.getApplicableSetBackLocation / signature.
Missing:
* Precise scan (and set back policy down-to-ground, and what not).
* Special cases: illegal move, passable, morepackets. Some need an extra
policy.
* Standing on entities? Quite testing with scannning down to the void,
perhaps it'll be "ok" with a more complex scanning result, scanning for
entities near start and end only.
(SAFETY COMMIT)
Largely breaking change.
* Interfaces in front of data types (and 'managers'), some interfaces
removed.
* Data and configuration fetching.
* Check activation checking (config flags, isEnabled, hasBypass).
* CheckType (activation checks, factories removed).
* Lots of collateral signature changes, including IPlayerData.
The (I)WorldDataManager stores per-world data (+ per world per check
type).
* Raw configurations.
* Typical flags: check activation, debug, lag adaption.
* Generic data, such as check configurations or per world check data.
The (I)PlayerDataManager stores per player data.
* Check Data.
* Typical flags: debug
* Exemption
* Check data (and config cache).
* Further mappings and later OfflinePlayerData.
* The registration interface will allow defining, how instances are
handled for registered types (factory, proxy, what on world change, what
on logout, global removal handler, per player removal handler).
(I)PlayerData is intended to be/become the central access point.
* External interface is IPlayerData now.
* Per player debug flags, exemptions.
* Fetching configuration and data: local cache, relaying fetching to
registered factories and proxy-registries/storage (e.g. fetching
configuration from per world storage).
Other fixes/changes:
(+) Extend the debug player command (set true/false, reset to world
default, arbitrary check types).
(+) PlayerData maintains a currentWorldIdentifier (to be used instead of
ChatData in future).
(+) The WorldConfigProvider getAll implementation returns a
LinkedHashSet now, avoiding duplicates.
(+) Move DefaultGenericInstanceRegistry to NCPCore.
(+) Thread-safety considerations for DefaultGenericInstanceRegistry.
(+) Don't log errors on hasBypass checking. TBD: Instead intercept
during listener methods (or even as a feature within the listener node:
e.g. @ThreadContext(primaryThread=true, skipOffContext=true,
cancelOffContext=true).
(+) Add fight.wrongturn permissions to plugin.yml.
(+) Missing GPLv3 headers.
Broken/Missing:
* WorldData inheritance from default: propagate all changes done
directly to the default config to children (all worlds that don't have
an explicit world_config.yml set) - possibly add an OverrideState or
similar, (NONE, FROM_DEFAULT, EXPLICIT) and don't override EXPLICIT if
coming from the default. Calling override on the default WorldData is
not to be confused with calling override for WorldDataManager (override
for all worlds as EXPLICIT).
* Organize overriding for special circumstances (version dependent
activation and the like). Might want to add registered override
handlers to be called on reload automatically.
* Store generic per check type per world data in the WorldDataManager,
such as configurations and per-world check data. TBD: Factories, cleanup
(!).
* Most efficient referencing (IWorldCheckTypeNode, IHandle<something>?).
* All the registry stuff (see PlayerData).
* Use interfaces for auto registry (and a flag within
RegistrationContext?) - world unload, world change, player join / leave.
* (Data expiration handling including transition to IOfflinePlayerData,
because now data is a little heavier.)
* Further details.
Only count the fall height below the set back y from lift-off (rather).
Breaking:
* Adjust method signatures and public visibility / interface for NoFall.
Issues with bunny hopping remain (...), but this might help with
elevators.
Use of velocity entries has been made more strict (directly use, remove
previously queued ones).
Benefits:
* Improves performance, where permission lookup has major impact, with
timeout based lookup, static permissions (skip permission check
entirely), and world/offline based invalidation. (Once fully
implemented.)
* Hopefully more efficient: use Bukkit Permission for faster defaults.
* (Allows control over how which permission is to be
updated/invalidated, which is useful per se.)
Risks:
* Complex changes yield bugs.
* Other plugins depending on NCP might break.
* Cache incoherence might happen (permissions are changed dynamically +-
unintended malconfiguration, or in case of bugs).
* (Endless loops certainly have all been fixed.)
Breaking:
* Lots of more or less internal API has been changed or removed: Check,
CheckType, CheckUtils, TickTask, ...
* Permission checking behavior has been altered.
Rough points:
* Implement a permission cache within PlayerData.
* Remove the player tasks and permission updates in favour of handling
those within DataManager and PlayerData.
* Adjust everything else to it (partly TBD).
* Updating sets of permissions (e.g. for CHAT) is done more lazily now,
i.e. one per 10 ticks). An actual permission check would still yield an
update next tick (asynchronous).
* Fixed/extended random spots (DualCollection, MiniListener registration
support, StringUtil).
Missing:
* Basic implementation
* Cleanup after logout (stages: 1. non-essential like permissions,
2. unrecoverable like set-back location, 3. complete data removal).
* Coverage
* Might have missed spots.
* NoCheatPlus.nameSetPerms should be replaced by caching + default
config for world-wise updating.
* Command permissions are always checked. At least for players,
cache based lookup should get implemented.
* More unit tests.
* Extended configurability: Per-world settings/policies.
* Efficiency
* Not all parts of the implementation are 100%/optimal yet.
Yes
* Remove the UNKNOWN type.
* All types except ALL have a parent now.
* All types have a type now.
* APIUtils: Add getDirectChildren for distinction.
No
* APIUtils doesn't collect the descendants in a generic way yet.
* Lift-off side conditions.
* Force stop gliding for some side conditions, to avoid freezing.
* Set maxheight to 128 for elytra and levitation too (mods/plugins/etc)
- better refine checks to catch stuff.
* Fix special flags not getting set with initializing ModelFlying from
config.
* Debug log exceeding the maxheight setting.
* Mostly harmless: Add interfaces and access methods, including
convenience methods.
* Don't store methods in Bridge1_9.
Issues left, not limited to:
* Boost not recognized on occasion.
* Gliding state kept when submerged in water and moving normally like
when not gliding, e.g. ascending (head in water / fully submerged).
* Elytra lift off not accepted: Gliding state set near the water
surface, but survivalfly check runs. Might be fixed already, though.
Breaks what used ModelFlying in any other way than setting up by config.
Use setters with chaining and a lock() method to lock against changes,
provide copy-constructor.
This is incomplete, as some pre-checks are still done with the full
bounds (flying just under web will put you to sf). Efficiency-wise there
could also be a more light-weight adjustment.
Attack areas are left too, e.g. flying (with or without boost) to
underwater, then end gliding to effectively clip with the head into
/through the block above.
With the lowered height it's also possible to get into odd spots, so
after stopping to glide you'll not be able to get out anymore.
* Count all events/packets regardless of settings.
* MovingListener: Remove pos/look counting for move events.
* MovingFlying: Call the counter method according to primaryThread flag.
This way, you can calculate a more interesting set-back location from
within a hook during violation handling. All you need to do to adjust
the set-back location is to call MovingData.setTeleported(newSetBack)
and NoCheatPlus should recognize this as the location to set back to.
Please do:
* Test if the check in question would set back at all
(IViolationData.wilCancel() returns true).
Please in such a case do not:
* Don't call setTeleported if IViolationData.willCancel() returns false
:).
* Cancel violation processing.
* Teleport the player.
* Do something complicated with MovingData otherwise :).
* lostGroundAscend: new condition.
* lostGroundStill: some precondition checks moved inside, new condition.
* vdistrel: Extra case with decreased lift-off gain, but second move as
if normal lift off.
* With from being on ground, and last move not having touched ground,
setSetBack(from).
Where it's known that it's the primary thread, that test should be
omitted.
A remaining problem is the Check class, where the convenience methods
all will lead to testing for Bukkit.isPrimaryThread(). This needs to be
done differently.
It'll be hard/impossible to work around, if we have to check permissions
and meta data. For permissions we could do some kind of bulk/context
dependent caching and updating policy and check via PlayerData, but meta
data needs the Bukkit API to state thread safety. Future design could
also do without knowledge of the thread, if permissions are cached and
exemption by meta data is turned off (or also cached, but this only
works if other plugins don't use it for temporary exemption), a lazy
approach could pass on an AlmostBoolean isPrimaryThread.
For now, at least some of the frequently run moving checks use the
optimized approach.
Instead of maps for each individual purpose, and the rather expensive
TickListener adding and removing, player specific task will be done via
one PlayerTickListener that can be registered with the TickTask. Thus
PlayerData has the access methods requestUpdateInventory and
requestPlayerSetBack, and so on, later more. For the
DataManager.playerData map it'll be UUID first now.
Consequently some calls have been altered to prefer passing Player or
UUID for PlayerData getting.
We do need to fix behavior to move on, so the intention rather is to
react more flexibly towards debugging results, rather than having people
use random configurations early on. Still this does allow for fall-back
configuration, e.g. for live servers.
NOTES:
* Later we will make the configuration set at 'default' adjust to server
mod and version.
* Overriding checks.moving.setback.method with SET_TO can lead to
PlayerTeleportEvents with TeleportCause.PLUGIN on newer versions of
Spigot, which may conflict with other plugins assuming feature-based
teleportation (possibly resulting in /back locations getting overridden
wrongly). For legacy setups this will be similar to restoring the state
of build 1066 for most.
There could still be places where distinction of the used method is
necessary, which would mean bugs.
* Don't unset teleported, if event.getTo is the same position as the
teleported (set back) location.
* Prepare (with) comments.
(Main driver is to be able to adjust quickly without shifting code
to-fro legacy etc., while dealing with much differing side conditions
for server mod + version, client versions with multi protocol support,
and other like bungee or not bungee.)
* MovingListener.prepareSetBack makes more sense than the previous
ambiguous naming.
* On confirming a set back, don't update the setBack field, only set if
null.
The aim is to have a more consistent handling and naming for set back
stages.
Both schedule a set back and update PlayerMoveEvent.getFrom() with the
set back location coordinates. This way, either the next incoming move
or a teleport event can confirm the set back location.
When a set back is scheduled:
* Cancel other teleports early. (x)
* Prevent Portal use. (x)
* Vehicle enter (not on vehicle set back). (x)
* Prevent attacking.
* Interact block. (x)
* Break block.
* Damage block. (x)
* Launch projectile.
* Place Block.
* Interact entity.
* Open inventory. (x)
The list is incomplete and adding/removing items remains subject to
discussion, having differing impact/severity for different actions. As
long as setting back rolls back to last ground, it might be better to
prevent some type of actions. Not all cancelling is logged.
(x) Probably most important for consistency, avoiding some types of
potential abuse.
A common framework
for "prevent types of action" during whatever-handling also is something
to consider.
Optimizations:
* Move handling some rare cases to methods (MovingListener,
PlayerTeleportEvent handling).
Because Spigot changed to fire the teleport following an altered move
end point with TeleportCause.PLUGIN, we have to alter set back handling,
so we can ensure to keep TeleportCause.UNKNOWN for setting back players.
Instead of altering the move end point, the event is just cancelled, and
a teleport is scheduled (with a dedicated TickTask method). Uncancelled
moving events mean removing scheduled teleports.
[BLEEDING]
* Comparably simple change - more places and special cases may still be
uncovered.
[BREAKING]
* Plugins that may rely on the exact sequence of things within NCP, as
it used to be.
Random
* Change "set-back" to "set back" everywhere for simplicity, and to
obfuscate the actual code changes.
* Set backs are now going through MovingListener.onCancelledMove instead
of MovingListener.onMoveMonitorNotCancelled.
* Illegal move handling would still use event.setTo.
Players and vehicles:
Instead always use UNKNOWN, as that is what results from
PlayerMoveEvent.setTo(newTo), as we use it for setting back players.
This should break functionality that relies on TeleportCause.PLUGIN
being used, possibly more likely with vehicles.
Lots of issues remain with elytra, with and without boost. Selection:
* maxheight will trigger with the rocket feature, naturally. Mendable by
increasing it via configuration
(checks.moving.creativelfly.model.elytra.vertical.maxheight). Not sure
we'll just increase the limit or alter how it's dealt with (e.g. also
for sf: lock to a max / high slope value, independently of the set-back
and world height, alter as necessary).
* All sorts of transitions, e.g. onto ground, into water.
* Loss of boost right after adding (not sure if already fixed).
* What with hover, actually?
* Is the flight duration infinite with power 127?
* Issues with ascending after descending, even without boost?
Changes contain:
* MCAccess.dealFallDamageFiresAnEvent -> true
* Always log basic data on (handled) fall damage events.
* Add a tag for the cancel reason with NoFall. Alter the default alert
message.
* Move 3.0 to Magic.
* Set the skipping flag correctly on allowFlight being set.
Fall damage is adjusted or cancelled, if the Minecraft fall distance is
greater than the distance(s) tracked by NCP (per move diffs, maximum y).
Intention is to prevent (speeding by) self damage by abusing Minecraft
dealing fall for untracked moves.
Issue: https://github.com/NoCheatPlus/Issues/issues/338