LandSandBoat / server

:sailboat: LandSandBoat - a server emulator for Final Fantasy XI
https://landsandboat.github.io/server/
GNU General Public License v3.0
294 stars 587 forks source link

🔨 Validate knockback & attempt to catch cheaters #4035

Open zach2good opened 1 year ago

zach2good commented 1 year ago

I affirm:

Describe the feature

I was looking around at some things and I established that knockback is entirely clientside and not enforced by the server. This means that clients can use 3rd party tools to block the bits of action packets that tell the client knockback is happening - therefore they never get knocked back.

It would be possible to:

atom0s commented 9 months ago

Knockback is entirely client sided in terms of how it is handled. I recently outlined how knockback works inside of the action packet which can be found here:

https://github.com/atom0s/XiPackets/tree/main/world/server/0x0028#scale

Due to this being client-sided, and the way the client is coded, it is possible for players to completely avoid animations from playing out on their character. This is generally referred to animation cancelling or animation blocking/skipping. It can be used to gain an advantage in more than one way but is entirely legal and part of the client itself. This can be done on a fully stock FFXI client without Ashita or Windower, no modifications needed at all.

When an incoming action is being received, it is possible for the local player to time a gear change/swap to force their character to blink. If timed properly, the scheduler task that was intended to play the animation and additional changes to the players entity will be cancelled. This can be done to avoid several things such as:

A popular addon/cheat for FFXI is ja0wait which removes the animation locks on the client when performing a job ability, casting a spell, engaging a monster, etc. While this addon is useful to just automatically remove all of these kinds of locks, it is 100% possible for the client to do the same thing simply by well-timed gear swaps.

Attached is an example of animation-blocking Empty Seed which is a guaranteed knock-back if you are hit.

https://github.com/LandSandBoat/server/assets/1422090/58aad37b-9d33-425f-a044-ba62ff7b5b0f

TeoTwawki commented 9 months ago

Attached is an example of animation-blocking Empty Seed which is a guaranteed knock-back if you are hit.

I knew you could cancel animation lock with blinling (essential kitting tool! Once watched a cor run+shoot for an hr without taking a hit, added it to my rdm after)

But I never knew you could gear swap cancel knockbacks too. Blocking knockback still feels kinda cheaty compared to blinking but I've never seen a reasonable way to police this by anyone yet.

zach2good commented 9 months ago

(out of the house right now)

My thought process for this was sort of expensive: the server knows when we're meant to be applying knock back, and we also know (or we could, with a little maths) how far that knock back should be. We can also work out whether or not it would have been blocked by terrain with a navmesh "raycast".

I would have wanted to reconsile the next player position update with where we're expecting them to be after we do the knockback enabled action to them.

No punitive action to start with, because the system would be loose to begin with, but crank it over time - as people should have been doing with their pos hacking detection systems thay auto jailed whole servers :D

On Sat, 9 Dec 2023, 10:10 TeoTwawki, @.***> wrote:

Attached is an example of animation-blocking Empty Seed which is a guaranteed knock-back if you are hit.

I knee you could cancel animation lock with blinling (essential kitting tool! Once watched a cor run+shoot for an hr without taking a hit, added it to my rdm after)

But I never knew you could gear swap cancel knockbacks too. Blocking knockback still feels kinda cheaty compared to blinking but I've never seen a reasonable way to police this by anyone yet.

— Reply to this email directly, view it on GitHub https://github.com/LandSandBoat/server/issues/4035#issuecomment-1848360698, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKTJIOHRUE7XYHYZZS2MQTYIQ2IJAVCNFSM6AAAAAAZYONOB2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNBYGM3DANRZHA . You are receiving this because you authored the thread.Message ID: @.***>

atom0s commented 9 months ago

Blocking knockback still feels kinda cheaty compared to blinking but I've never seen a reasonable way to police this by anyone yet.

Due to how movement is implemented in general, it's not an easy thing to really police with any kind of accuracy that wouldn't also hit legit players. To even begin to really handle even just triggering a warning, the server side would need to be able to fully and accurately handle the navmesh data of the client. Not using Recast either, it'd need to be retail-accurate handling to ensure proper usage of the mesh and allowing for server-sided 'projections' of movement.

There are a lot of edge cases that can cause the player to not move as far as expected or to actually move farther. It is also common place for players to 'game' the system in certain fights and situations to avoid being knocked back such as backing themselves up to a wall/tree. (ie. During Khimaira's retail debut, it was common for tanks to fight with their backs against the tree while the rest of the alliance would stand up on the hill to avoid being hit by the various TP moves.)

It's possible to put yourself in positions that would also not push you back by clipping against other parts of the terrain such as small rocks, ledges, boxes, etc. But the biggest issue is the fact that the client can legit cancel the animation altogether.

TeoTwawki commented 9 months ago

@zach2good i have a mob with a 50 yalm knockback that I simply chained position updates into so even if the blocked the actual knckback they still get moved to the coordinates. I break them up in 5 yalm incrementss a few ms apart so if they block it 3rd party observers seem them as running away. This can still be cheated tho : shifts the burden from knockback cancelling to pos hacking.

I only did it for that single mob, for the lols. It wad just a prank.

atom0s commented 9 months ago

My thought process for this was sort of expensive: the server knows when we're meant to be applying knock back, and we also know (or we could, with a little maths) how far that knock back should be.

There's a few factors that can heavily break/skew the results of the server doing those calculations:

When Direct3D8 creates the actual IDirect3DDevice8 device, there is a flag that can be passed called D3DCREATE_FPU_PRESERVE:

Indicates that the application needs either double precision floating-point unit (FPU) or FPU exceptions enabled. Direct3D sets the FPU state each time it is called.
Setting the flag will reduce Direct3D performance. 

This can cause those calculations to return with different results simply by editing a flag.

Next, Recast/Detour is not the proper method of handling FFXI's navigation mesh data and causes incorrect handling of certain bits of terrain. This is proven with private tooling and bots that make use of navmesh data to work/move around the world. Extra care is required to not get stuck on things because of how Recast handles navigation meshes vs. what the actual stock FFXI client does. When using non-modified mesh data dumped from FFXI within Recast/Detour, it is possible to generate invalid paths because of the way R/D works with heightfields. This is generally why most of the meshes require human touchups currently with private server meshes to cleanup and fix various things that are known problems with using R/D.

I would have wanted to reconsile the next player position update with where we're expecting them to be after we do the knockback enabled action to them.

Along with the ability for a legit player to cancel the knockback, it's also possible to not move the full distance that the knockback is capable of pushing the player. This can be based on various factors of additional collisions. For example, being knocked back against / into a wall will stop the forward progression of movement and can instead result in moving sideways for part of that pathing. The design of the terrain in cases like that will alter how much/little you will move as well as if you get stuck on something mid-knockback. Same for when you hit a tree, rock, etc.

Another factor is objects in your path when being knocked back such as other entities. You don't move through them freely all the time, only if they've sat idle long enough to enable their 'ghosting' mode which was something more recently added to the game. If they have moved or are hostile, then you will still 'stutter-clip' through them which will reduce the pushback distance.

There are various other potential conditions like this that can lead to the projected distance not matching what the actual distance moved will be.

No punitive action to start with, because the system would be loose to begin with, but crank it over time - as people should have been doing with their pos hacking detection systems thay auto jailed whole servers :D

For sure, not against the idea of this system being implemented as a 'warning'. I don't personally think it should ever be implemented in the actual codebase to be setup to automatically jail or punish (ie. ban) a player though. Aside from being able to legitimately completely animation block the knockback on a fully stock client, there are way too many other conditions a normal player can cause that will skew the calculated position on the server side to trigger a false positive.