khalidahmedshalabi/SAMPBulletproof

Lag issue (on/after player connected to the server)

Closed this issue · 9 comments

There's noticeable lag (server freezes for 0.5 to 2 seconds most of the times) when a player connects. This needs investigation~~, however I guess it's the GetPlayerCountry; @Whitetigerswt must know more about this since he's the one who developed it.~~

https://youtu.be/Tp5YMxUYYfM

First is a host on my vps, second is localhost.
There's a difference in speed but not sure if it's geoip.

Well, this means our testing should not be done on home hosts. Run this on the same vps @ApplePieLife:

public OnPlayerConnect(playerid)
{
    printf("OnPlayerConnect(%d): init", playerid);
    new tick = GetTickCount();
    // Check if version is out-dated and if server owners are forced to use newest version
    if(VersionReport == VERSION_IS_BEHIND && ForceUserToNewestVersion == true)
    {
        SendClientMessageToAll(-1, sprintf(""COL_PRIM"Version checker: {FFFFFF}the version used in this server is out-dated. You can visit "COL_PRIM"%s {FFFFFF}to get the latest version", GM_WEBSITE));
        SendClientMessageToAll(-1, sprintf(""COL_PRIM"Server version: {FFFFFF}%s "COL_PRIM"| Newest version: {FFFFFF}%s", GM_NAME, LatestVersionStr));
        SetTimerEx("OnPlayerKicked", 500, false, "i", playerid);
        return 0;
    }
    printf("OnPlayerConnect(%d): Version check: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();
    if(DatabaseLoading == true)
    {
        ClearChatForPlayer(playerid);
        SendClientMessage(playerid, -1, "Please wait! Database loading, you will be connected when it's loaded successfully.");
        SetTimerEx("OnPlayerConnect", 1000, false, "i", playerid);
        return 0; // If database is still loading, disable the player from spawning
    }
    printf("OnPlayerConnect(%d): Database load check: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();
    // Check if players count exceeded the limit
    if(Iter_Count(Player) == MAX_PLAYERS)
    {
        SendClientMessageToAll(-1, sprintf(""COL_PRIM"ID %d could't connect to the server properly. Maximum players limit exceeded!", playerid));
        SendClientMessageToAll(-1, sprintf("MAX PLAYERS LIMIT: %d | Ask for a special and increased limit | %s", MAX_PLAYERS, GM_WEBSITE));
        SetTimerEx("OnPlayerKicked", 500, false, "i", playerid);
        return 0;
    }
    printf("OnPlayerConnect(%d): Players limit check: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();
    // Send them welcome messages
    SendClientMessage(playerid, -1, ""COL_PRIM"It's {FFFFFF}Bulletproof"COL_PRIM". Your bullets are fruitless. You can't take it down!");
    SendClientMessage(playerid, -1, ""COL_PRIM"Get started: {FFFFFF}/help "COL_PRIM"and {FFFFFF}/cmds");
    SendClientMessage(playerid, -1, ""COL_PRIM"Don't miss our updates: {FFFFFF}/checkversion");
    SendClientMessage(playerid, -1, ""COL_PRIM"Check {FFFFFF}/changelog "COL_PRIM"out to see what's up with this version!");
    SendClientMessage(playerid, -1, ""COL_PRIM"Developers: {FFFFFF}Whitetiger"COL_PRIM" & {FFFFFF}[KHK]Khalid"COL_PRIM"");
    printf("OnPlayerConnect(%d): welcome message: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();
    new str[128];
    format(str,sizeof(str),""COL_PRIM"Server limits:  Min FPS = {FFFFFF}%d "COL_PRIM"| Max Ping = {FFFFFF}%d "COL_PRIM"| Max PL = {FFFFFF}%.2f", Min_FPS, Max_Ping, Float:Max_Packetloss);
    SendClientMessage(playerid, -1, str);
    printf("OnPlayerConnect(%d): server limit message: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();

    // Initialize the new player
    InitPlayer(playerid);
    printf("OnPlayerConnect(%d): InitPlayer: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();
    #if defined _league_included
    CheckPlayerLeagueRegister(playerid);
    #endif
    CheckPlayerAKA(playerid);
    printf("OnPlayerConnect(%d): AKA check: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();

    // Tell everyone that he's connected
    str = "";
    GetPlayerCountry(playerid, str, sizeof(str));
    printf("OnPlayerConnect(%d): GetPlayerCountry: took approx. %d ms since last print", playerid, GetTickCount() - tick);
    tick = GetTickCount();
    format(str, sizeof(str), "{FFFFFF}%s {757575}(ID: %d) has connected [{FFFFFF}%s{757575}]", Player[playerid][Name], playerid, str);
    SendClientMessageToAll(-1, str);
    printf("OnPlayerConnect(%d): Connected message: took approx. %d ms since last print", playerid, GetTickCount() - tick);

    if(AllMuted) // If everyone is muted (global mute, /muteall?), this player should be muted too
        Player[playerid][Mute] = true;
    return 1;
}
[22:50:41] OnPlayerConnect(0): init
[22:50:41] OnPlayerConnect(0): Version check: took approx. 0 ms since last print
[22:50:41] OnPlayerConnect(0): Database load check: took approx. 0 ms since last print
[22:50:41] OnPlayerConnect(0): Players limit check: took approx. 0 ms since last print
[22:50:41] OnPlayerConnect(0): welcome message: took approx. 0 ms since last print
[22:50:41] OnPlayerConnect(0): server limit message: took approx. 0 ms since last print
[22:50:41] OnPlayerConnect(0): InitPlayer: took approx. 0 ms since last print
[22:50:41] OnPlayerConnect(0): AKA check: took approx. 0 ms since last print
[22:50:41] OnPlayerConnect(0): GetPlayerCountry: took approx. 1 ms since last print
[22:50:41] OnPlayerConnect(0): Connected message: took approx. 0 ms since last print

@KHKKhalid Doesn't really seem to lag.

You got this result and the game still lagged when you connected (like the video), @ApplePieLife? If so, it's likely not OnPlayerConnect then.

It's the login code under OnPlayerRequestClass then I guess. Could you benchmark and test it on your VPS again @ApplePieLife? Here's a sample code...

printf("Player logged-in status: %b", Player[playerid][Logged]);
new tick = GetTickCount();
if(Player[playerid][Logged] == false)
{
....
....
....
}
printf("Login code took approx. %d ms", GetTickCount() - tick);
[16:51:00] [join] ThatBoyCBUG148 has joined the server (0:HIDDEN)
[16:51:00] START:ForgetSpectator(0)
[16:51:00] END:ForgetSpectator(0)
[16:51:01] Player logged-in status: 0
[16:51:01] Login code took approx. 0 ms
[16:51:08] START:StopSpectate(0, 1)
[16:51:08] [part] ThatBoyCBUG148 has left the server (0:1)

Well, I'm not sure if you edited anything with login codes but I've noticed it's way faster now.
(( or we both simply had bad ping in that day ))

Some general benchmarking...

[22:34:49] Login code took approx. 5060 ms to execute
[22:34:49] SpawnConnectedPlayer code took approx. 0 ms to execute
[22:37:22] Login code took approx. 4422 ms to execute
[22:37:22] SpawnConnectedPlayer code took approx. 0 ms to execute

It is the login code. I'll probably add more benchmarks to find the root of this lag/delay later.

Found it! It's this code under LoginPlayer

// Update players table with new IP address for auto login if they reconnect.
format(iString, sizeof(iString), "UPDATE `Players` SET `IP` = '%s' WHERE `Name` = '%s'", IP, Player[playerid][Name]);
db_free_result(db_query(sqliteconnection, iString));