Health float comparing for AFK system
#1

Im making an AFK check, basically if the player is in the same position for 3 seconds, their health is then checked.

If they move from that position, then they wont be checked again for another 3 seconds.

The position part is working perfectly, the problem im having is with the health part of it.

I want to check the players health, save it. Then lower their health by 1hp.

Then check it again to see if there was any change. If there wasn't a change, set their health back to the original amount, and don't check them again for another 3 seconds, because they're not AFk.

Im having trouble though comparing them. Because when i minimize the game, health can't be changed. So in theory it would show im AFK.

But it isnt...

So in each check, i want to check the position, if they're standing idle, then check their health. Decrease their health by 1hp. Check their health again to see if there was a decrease.

So how can i accuratly check their health, set their health and check it again.. All in one AFK check (1 second).
Reply
#2

Is this actually possible? I mean. AFK by a players position isnt hard, but it isnt exactly accurate, since the player may not have the game minamized.


I've been testing health, setting it lower, and then using a command to get and display a players health.

If they have their game minimized, then theres no visable health decreases, and the command returns their health value as it was before i decreased their health.

So in theory this should work to detect if a player has their game minimized.

I'm not having much luck with it though.

Any ideas how it would be possible to determine if a player has their game minamized?
Reply
#3

When they minimize the game, it doesn't send the data to the server, i.e. OnPlayerUpdate won't be called for them (I've tested it recently). So if you check the time between two packets are sent (use timer to do this) and it is over than some value, e.g. one second, then you know that the player paused his game.

Edit:
Here is implementation of my idea:
pawn Code:
#include <a_samp>

#define abs(%1) \
            ((%1 < 0) ? (-(%1)) : (%1))

new
    gPlayerTicks[MAX_PLAYERS],
    gPlayerIsAFK[MAX_PLAYERS];

#define UPDATE_TIMEOUT  10000

public OnPlayerUpdate(playerid)
{
    new
        ticks = GetTickCount();
    if (playerid < MAX_PLAYERS)
    {  
        if (gPlayerIsAFK[playerid])
        {
            gPlayerIsAFK[playerid] = false;
            printf("player #%d is back", playerid);
        }  
        else
        {
            SetTimerEx("OnPlayerUpdate", UPDATE_TIMEOUT + 1000, false, "i", playerid + MAX_PLAYERS);
        }
        gPlayerTicks[playerid] = ticks;
    }  
    else
    {
        playerid -= MAX_PLAYERS;
        if (!gPlayerIsAFK[playerid])
        {
            if (abs(gPlayerTicks[playerid] - ticks) > UPDATE_TIMEOUT)
            {
                gPlayerIsAFK[playerid] = true;
                printf("player #%d is AFK now", playerid);
            }
        }
    }
    return 1;
}

public OnPlayerConnect(playerid)
{
    gPlayerIsAFK[playerid] = false;
    return 1;
}
Reply
#4

supposing the player's old health is 95.0
pawn Code:
new Float:health;
SetPlayerHealth(playerid, 50.0);
GetPlayerHealth(playerid, health);
Guess what that will return? 95.0. i know, annoying, but it is what it is. (note: this may be cause because of the gamemode i ran for testing (gf non-edited))
Reply
#5

Quote:
Originally Posted by ZeeX
When they minimize the game, it doesn't send the data to the server, i.e. OnPlayerUpdate won't be called for them (I've tested it recently). So if you check the time between two packets are sent (use timer to do this) and it is over than some value, e.g. one second, then you know that the player paused his game.

Edit:
Here is implementation of my idea:
pawn Code:
#include <a_samp>

#define abs(%1) \
            ((%1 < 0) ? (-(%1)) : (%1))

new
    gPlayerTicks[MAX_PLAYERS],
    gPlayerIsAFK[MAX_PLAYERS];

#define UPDATE_TIMEOUT  10000

public OnPlayerUpdate(playerid)
{
    new
        ticks = GetTickCount();
    if (playerid < MAX_PLAYERS)
    {  
        if (gPlayerIsAFK[playerid])
        {
            gPlayerIsAFK[playerid] = false;
            printf("player #%d is back", playerid);
        }  
        else
        {
            SetTimerEx("OnPlayerUpdate", UPDATE_TIMEOUT + 1000, false, "i", playerid + MAX_PLAYERS);
        }
        gPlayerTicks[playerid] = ticks;
    }  
    else
    {
        playerid -= MAX_PLAYERS;
        if (!gPlayerIsAFK[playerid])
        {
            if (abs(gPlayerTicks[playerid] - ticks) > UPDATE_TIMEOUT)
            {
                gPlayerIsAFK[playerid] = true;
                printf("player #%d is AFK now", playerid);
            }
        }
    }
    return 1;
}

public OnPlayerConnect(playerid)
{
    gPlayerIsAFK[playerid] = false;
    return 1;
}
Code doesn't work, you never see the print.
Reply
#6

Quote:
Originally Posted by ZeeX
When they minimize the game, it doesn't send the data to the server, i.e. OnPlayerUpdate won't be called for them (I've tested it recently). So if you check the time between two packets are sent (use timer to do this) and it is over than some value, e.g. one second, then you know that the player paused his game.

Edit:
Here is implementation of my idea:
pawn Code:
#include <a_samp>

#define abs(%1) \
            ((%1 < 0) ? (-(%1)) : (%1))

new
    gPlayerTicks[MAX_PLAYERS],
    gPlayerIsAFK[MAX_PLAYERS];

#define UPDATE_TIMEOUT  10000

public OnPlayerUpdate(playerid)
{
    new
        ticks = GetTickCount();
    if (playerid < MAX_PLAYERS)
    {  
        if (gPlayerIsAFK[playerid])
        {
            gPlayerIsAFK[playerid] = false;
            printf("player #%d is back", playerid);
        }  
        else
        {
            SetTimerEx("OnPlayerUpdate", UPDATE_TIMEOUT + 1000, false, "i", playerid + MAX_PLAYERS);
        }
        gPlayerTicks[playerid] = ticks;
    }  
    else
    {
        playerid -= MAX_PLAYERS;
        if (!gPlayerIsAFK[playerid])
        {
            if (abs(gPlayerTicks[playerid] - ticks) > UPDATE_TIMEOUT)
            {
                gPlayerIsAFK[playerid] = true;
                printf("player #%d is AFK now", playerid);
            }
        }
    }
    return 1;
}

public OnPlayerConnect(playerid)
{
    gPlayerIsAFK[playerid] = false;
    return 1;
}
I'll give it a go, with a few changes... I think Y_Less would castrate you for using SetTimerEx with OnPlayerUpdate...


EDIT:

Just tested it, works perfect... Nice job... And when i took a better look at it i realised why you used SetTimerEx and OnPlayerUpdate, so my bad for not noticing.

This should hopefully make it a lot easier manage certain parts of the anti cheat im making, mainly the money detections. Normally if a player comes back from being AFK, and has earned money during the AFK time, admins get spammed with money messages

Thanks for the help..

Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)