NexiusTailer / Nex-AC

Anticheat system
https://pawn.wiki/index.php?/topic/27641-nex-ac/
GNU Lesser General Public License v3.0
213 stars 155 forks source link

Use tick-difference #246

Closed Fairuz-Afdhal closed 2 years ago

Fairuz-Afdhal commented 2 years ago

Having tick-difference(https://github.com/ScavengeSurvive/tick-difference) built in would be good

NexiusTailer commented 2 years ago

Such implementation does not make sense because it is no different from the usual "newtick - oldtick". A few years ago I saw some tests that prove this, trying to find it now.

NexiusTailer commented 2 years ago

This test will identify the difference in results between GetTickDifference and basic "newtick - oldtick". It iterates over the entire range of possible values of oldtick, while newtick is 10 more than oldtick in the first cycle and 10 less in the second. If the results of the function and simple subtraction are different, a message is printed to the console. Outputting iteration numbers multiple of 100000000 is done to make sure that the code is executing.

stock GetTickDifference(newtick, oldtick)
{
    if(oldtick < 0 && newtick >= 0)
        return newtick - oldtick;
    else if(oldtick >= 0 && newtick < 0 || oldtick > newtick)
        return (cellmax - oldtick + 1) - (cellmin - newtick);
    return newtick - oldtick;
}

#define GetTickDiff_simplified(%0,%1) ((%0)-(%1))

main()
{
    printf("testing...");
    static newtick = 10, oldtick = 0;
    static diff1, diff2;
    do
    {
        if(oldtick % 100000000 == 0) printf("%d", oldtick);

        diff1 = GetTickDifference(newtick, oldtick);
        diff2 = GetTickDiff_simplified(newtick, oldtick);
        if(diff1 != diff2) printf("result for (%d, %d) differ: %d, %d", newtick, oldtick, diff1, diff2);
    }
    while((++newtick, ++oldtick) != 0);

    newtick = -10;
    do
    {
        if(oldtick % 100000000 == 0) printf("%d", oldtick);

        diff1 = GetTickDifference(newtick, oldtick);
        diff2 = GetTickDiff_simplified(newtick, oldtick);
        if(diff1 != diff2) printf("result for (%d, %d) differ: %d, %d", newtick, oldtick, diff1, diff2);
    }
    while((++newtick, ++oldtick) != 0);
    printf("done");
}

Output:

testing...
0
100000000
200000000
300000000
400000000
500000000
600000000
700000000
800000000
900000000
1000000000
1100000000
1200000000
1300000000
1400000000
1500000000
1600000000
1700000000
1800000000
1900000000
2000000000
2100000000
-2100000000
-2000000000
-1900000000
-1800000000
-1700000000
-1600000000
-1500000000
-1400000000
-1300000000
-1200000000
-1100000000
-1000000000
-900000000
-800000000
-700000000
-600000000
-500000000
-400000000
-300000000
-200000000
-100000000
0
100000000
200000000
300000000
400000000
500000000
600000000
700000000
800000000
900000000
1000000000
1100000000
1200000000
1300000000
1400000000
1500000000
1600000000
1700000000
1800000000
1900000000
2000000000
2100000000
-2100000000
-2000000000
-1900000000
-1800000000
-1700000000
-1600000000
-1500000000
-1400000000
-1300000000
-1200000000
-1100000000
-1000000000
-900000000
-800000000
-700000000
-600000000
-500000000
-400000000
-300000000
-200000000
-100000000
done

Not a single print of a difference, so the results of the function are identical with just "newtick - oldtick".

The reasons for this behavior is described here (in Russian). May also be related to @Southclaws

Southclaws commented 2 years ago

This difference checking code was originally written by either Slice or Y_Less, I can't remember who.

rt-2 commented 2 years ago

Sometimes on my server the anticheat is late a bit. I had to implement this(https://github.com/NexiusTailer/Nex-AC/pull/42) into my code because sometimes players would be kicked because the ticks would not be accurate. Explained here(https://github.com/NexiusTailer/Nex-AC/issues/29#issuecomment-306055167).

I think it depends on the server load and/or how efficient and well written a gamemode is. Some of my code is neither.

NexiusTailer commented 2 years ago

@rt-2 So your players still get kicked by anti-airbreak or what? At the moment, in cases with server lags it is impossible situations where the timer is triggered more than once per second, only cases of longer delays between timer calls are possible. Thus, the only anticheats that can be affected are those where any internal warnings is regularly reset (anti-speedhack in vehicle, anti-flyhack in vehicle, anti-teleport onfoot, anti-carshot and anti-airbreaks). Anti-airbreak onfoot is one of those cases, but it's set up with a pretty large margin for such cases at the moment. Would be great on your part to attach detailed debug logs of all false detections when the server is lagging, so that we can see exactly what might be behaving wrong this time.

rt-2 commented 2 years ago

Those are exactly the affected anti cheats. In #29 I would just lag my server with lots of NPCs and could trigger airbreak on nearby players. You fixed it, but still happens with lag I think. This was observed and fixed in my version a long time ago.

I will add some debug at some point and check if it happens. I think it will take some time to be able tobdeliver good data.

NexiusTailer commented 2 years ago

@rt-2 yeah, that was fixed from my side and if we still talk about adding return 0 to drop executing a timer when it was called after too long delay, this will not be a solution of any problem and instead could create new problems (in case of any lags there will be working money/weapon/ammo cheat which checked in the timer, and also troubles with internal warnings resetting for other anticheat codes).

By the way, did you try timer fix solutions to make them more precise?

rt-2 commented 2 years ago

Hello @NexiusTailer,

I also think returning 0 in the timer is a bad idea.

I dont use timerFix because it could break a lot of timers who take into account and need that lag.

Did you think about using YSI for timers?

Thank you

NexiusTailer commented 2 years ago

I'd rather choose this, this or that. The first and the second one will surely work without any changes on the anticheat side, so, I would prefer something like that if I needed it.