yourmnbbn / smext-fakequeries

Return custom A2S_INFO and A2S_PLAYER response
GNU General Public License v3.0
24 stars 5 forks source link

Fake players are marked as bot in Gametracker #18

Open SH4ZZY opened 2 years ago

SH4ZZY commented 2 years ago

Hello, I've set this extension on my test server, everything works fine in server browser/fav but at https://www.gametracker.com every fakeplayer is flagged is bot, is it my fault or extension doesen't support this type of sites?

Thank you in advance and i must admit ext in overall is pretty neat.

yourmnbbn commented 2 years ago

I'm not so familiar with the gametracker website but I've checked some of the kz servers with replay bots, and haven't found where those bots were flagged as bot. The information of those bots in both player list and profile page seems to be identical with the normal players. Maybe I've missed something, I'm willing to take a look at this problem if you could provide further information.

SH4ZZY commented 2 years ago

So, I'm adding players like this:

`public void AddFakePlayers()
{
    FQ_ResetA2sInfo();
    FQ_RemoveAllFakePlayer();

    float randomTime = GetRandomFloat(120.0, 420.0);
    CreateTimer(randomTime, TimeFakePlayers, _, TIMER_FLAG_NO_MAPCHANGE);

    int randomCount = GetRandomInt(20, 32);
    int randomScore;
    int nameIndex;
    char randomName[256];

    for (int i = 1; i < randomCount; i++) {
        randomScore = GetRandomInt(5, 95);
        nameIndex = GetRandomInt(0, 500);
        g_sPlayerNames.GetString(nameIndex, randomName, 256);

        FQ_AddFakePlayer(i, randomName, randomScore, GetEngineTime());
    }

    FQ_ToggleStatus(true);
}`

And that's an output from game tracker: obraz

I'm not sure how gametracker is fetching players tho cause like i said in server browser everything looks legit

yourmnbbn commented 2 years ago

Seems that you're not setting the corresponding player count of the fake player's you've added. You should use the function shown below to let player count in the A2S_INFO response to be changed accordingly just as the example, otherwise the gametracker will receive conflict information from the A2S_INFO and A2S_PLAYER response so it thinks the fake players are bots.

https://github.com/yourmnbbn/smext-fakequeries/blob/eefeb292f7ca402a12b9ab7e841a7156d54a9e97/fakequeries.inc#L206-L214

Example:

public void AddFakePlayers()
{
    FQ_ResetA2sInfo();
    FQ_RemoveAllFakePlayer();
    FQ_InfoResponseAutoPlayerCount(true);

    float randomTime = GetRandomFloat(120.0, 420.0);
    CreateTimer(randomTime, TimeFakePlayers, _, TIMER_FLAG_NO_MAPCHANGE);

    int randomCount = GetRandomInt(20, 32);
    int randomScore;
    int nameIndex;
    char randomName[256];

    for (int i = 1; i < randomCount; i++) {
        randomScore = GetRandomInt(5, 95);
        nameIndex = GetRandomInt(0, 500);
        g_sPlayerNames.GetString(nameIndex, randomName, 256);

        FQ_AddFakePlayer(i, randomName, randomScore, GetEngineTime());
    }

    FQ_ToggleStatus(true);
}
SH4ZZY commented 2 years ago

I've done what you said and still gt treats them as bots.

url: https://www.gametracker.com/server_info/54.37.142.34:23016

obraz

yourmnbbn commented 2 years ago

I've registered an account and add my test server to check the actual behavior of the extension, it turned out to work fine. No fake players were marked as bot. Can you post the full source code of your plugin so I can try to reproduce this problem?

SH4ZZY commented 2 years ago

Yep, here you are:

#include <sourcemod>
#include <fakequeries>

ArrayList g_sPlayerNames;

public Plugin myinfo = 
{
    name = "Example - Fake players", 
    author = "yourmnbbn", 
    description = "Create fake players by returning fake AS2_INFO and A2S_PLAYER response", 
    version = "1.3.2", 
    url = "URL"
};

//int g_iFakePlayerCount = 0;

public void OnPluginStart()
{
    g_sPlayerNames = new ArrayList();
    ParsePlayerNames();

    AddFakePlayers();
    float randomTime = GetRandomFloat(120.0, 420.0);
    CreateTimer(randomTime, TimeFakePlayers, _, TIMER_FLAG_NO_MAPCHANGE);
}

public Action TimeFakePlayers(Handle timer, int client)
{
    AddFakePlayers();
}

public void AddFakePlayers()
{
    FQ_ResetA2sInfo();
    FQ_RemoveAllFakePlayer();
    FQ_InfoResponseAutoPlayerCount(true);

    float randomTime = GetRandomFloat(120.0, 420.0);
    CreateTimer(randomTime, TimeFakePlayers, _, TIMER_FLAG_NO_MAPCHANGE);

    int randomCount = GetRandomInt(20, 32);
    int randomScore;
    int nameIndex;
    char randomName[256];

    for (int i = 1; i < randomCount; i++) {
        randomScore = GetRandomInt(5, 95);
        nameIndex = GetRandomInt(0, 500);
        g_sPlayerNames.GetString(nameIndex, randomName, 256);

        FQ_AddFakePlayer(i, randomName, randomScore, GetEngineTime());
    }

    FQ_ToggleStatus(true);
}

void ParsePlayerNames() {
    File file = OpenFile("addons/sourcemod/data/names.txt", "r");

    if ((file == null)) {
        return;
    }

    char line[32];
    while (file.ReadLine(line, sizeof(line)) && !file.EndOfFile()) {
        if (StrContains(line, "//") != -1) {
            SplitString(line, "//", line, sizeof(line));
        }

        TrimString(line);

        g_sPlayerNames.PushString(line);
    }

    delete file;
}
yourmnbbn commented 2 years ago

So there are some logic problems in your code. The following functions should be executed in the OnPluginStart forward instead of the timer callback since they are the steps of initialization of the extension. Your current code is reinitializing the extension repeatedly, and might still cause the unexpected behavior you've mentioned after refreshing the plugin.

FQ_ResetA2sInfo();
FQ_InfoResponseAutoPlayerCount(true);
FQ_ToggleStatus(true);

I haven't tested this but it should work after the plugin and gametrack refresh.

#include <sourcemod>
#include <fakequeries>

ArrayList g_sPlayerNames;

public Plugin myinfo = 
{
    name = "Example - Fake players", 
    author = "yourmnbbn", 
    description = "Create fake players by returning fake AS2_INFO and A2S_PLAYER response", 
    version = "1.3.2", 
    url = "URL"
};

//int g_iFakePlayerCount = 0;

public void OnPluginStart()
{
    FQ_ResetA2sInfo();
    FQ_RemoveAllFakePlayer();
    FQ_InfoResponseAutoPlayerCount(true);
    FQ_ToggleStatus(true);

    g_sPlayerNames = new ArrayList();
    ParsePlayerNames();

    AddFakePlayers();
    float randomTime = GetRandomFloat(120.0, 420.0);
    CreateTimer(randomTime, TimeFakePlayers, _, TIMER_FLAG_NO_MAPCHANGE);
}

public Action TimeFakePlayers(Handle timer, int client)
{
    AddFakePlayers();
}

public void AddFakePlayers()
{
    FQ_RemoveAllFakePlayer();
    float randomTime = GetRandomFloat(120.0, 420.0);
    CreateTimer(randomTime, TimeFakePlayers, _, TIMER_FLAG_NO_MAPCHANGE);

    int randomCount = GetRandomInt(20, 32);
    int randomScore;
    int nameIndex;
    char randomName[256];

    for (int i = 1; i < randomCount; i++) {
        randomScore = GetRandomInt(5, 95);
        nameIndex = GetRandomInt(0, 500);
        g_sPlayerNames.GetString(nameIndex, randomName, 256);

        FQ_AddFakePlayer(i, randomName, randomScore, GetEngineTime());
    }
}

void ParsePlayerNames() {
    File file = OpenFile("addons/sourcemod/data/names.txt", "r");

    if ((file == null)) {
        return;
    }

    char line[32];
    while (file.ReadLine(line, sizeof(line)) && !file.EndOfFile()) {
        if (StrContains(line, "//") != -1) {
            SplitString(line, "//", line, sizeof(line));
        }

        TrimString(line);

        g_sPlayerNames.PushString(line);
    }

    delete file;
}
SH4ZZY commented 2 years ago

Oh, yea that makes sense, but still gametracker treats them as bots. However if your test server is working fine with gametracker i guess It's problem with my server or hosting, maybe it also depends on host_players_show 🤔

//edit: host_players_show is set to 2 so i guess that's not an issue

yourmnbbn commented 2 years ago

I've tested your implementation and confirmed the problem, but with my example plugin provided in this repo it works fine. Maybe there are still something wrong with it. You can try a different implementation. I'll take a look at this later.

SH4ZZY commented 2 years ago

Okey, thanks for your time.

toorisrael commented 2 years ago

GT treats players as bots when they have identical connection time.

wickedroid commented 2 years ago

With gametracker is easy to resolve but how to resolve the issue on internet server list . On favorite it appears the players but on internet list 0/32

sev4a commented 2 years ago

@yourmnbbn in order for the player to be displayed, you need to authorize it https://github.com/perilouswithadollarsign/cstrike15_src/blob/f82112a2388b841d72cb62ca48ab1846dfcc11c8/engine/sv_steamauth.cpp#L687

yourmnbbn commented 2 years ago

@sev4a Yeah this is a way. The function you’ve mentioned is a callback of this authentication interface in the sdk. As you can see the authentication requires a valid steamid. The auth implementation is on the master server side so we cannot change anything about it. If you want a successful authentication you have to give it a valid account. One fake player with one unique account is not a proper way at all.

The problem is not about the authentication, it's about how to proper authenticate the fake players.