Portal SAMP
[Ajuda] Lidar com pacotes perdidos - Versão de Impressão

+- Portal SAMP (https://portalsamp.com)
+-- Fórum: SA-MP (https://portalsamp.com/forumdisplay.php?fid=5)
+--- Fórum: Área de suporte (https://portalsamp.com/forumdisplay.php?fid=6)
+--- Tópico: [Ajuda] Lidar com pacotes perdidos (/showthread.php?tid=262)



Lidar com pacotes perdidos - annety - 31/10/2020

Aquele famoso tempo parado, quando o GM, o HOST ou o PLAYER da uma lagadinha...

Nunca tive que lidar com isso até o SAMP ANDROID, a galera tem muitos problemas de conexão, seja por 4G ou WIFI OSCILANDO...

Agora sem o forum antigo não tenho material (exemplos de uso reais) pra ver como a galera lida com isso, mas lembro de ver na wiki umas funções de conexão

Vocês de alguma forma conseguem resincronizar os players que lagam?

O máximo que eu consegui foi kickar os players de tempo parado, mas isso tá me fazendo perder boa parte dos players de celular Sad

Código:
new PacketAltoAvisos[MAX_PLAYERS];

OnPlayerUpdate
Código:
    new Float:Pocket;
    GetPlayerPacketloss(playerid,Pocket);
    if(Pocket >= 10.0)
    {
        PacketAltoAvisos[playerid] ++;
        if(PacketAltoAvisos[playerid] >= 30)
        {
            new PlayerIP[20];
            GetPlayerIp(playerid, PlayerIP, sizeof PlayerIP);
            if(idiom[playerid] == 1) SendClientMessage(playerid, -1, "Você foi desconectado por 3 min estar dessincronizado (Relogio Travado) para evitar problemas. Ajuste sua conexão!");
            else if(idiom[playerid] == 2) SendClientMessage(playerid, -1, "You have been disconnected for 3 min because you are out of sync (Clock Locked) to avoid problems. Adjust your connection!");
            else if(idiom[playerid] == 3) SendClientMessage(playerid, -1, "Se ha desconectado por 3 min porque no está sincronizado (Reloj Bloqueado) para evitar problemas. ¡Ajusta tu conexión!");
            BlockIpAddress(PlayerIP, 3 * 60 * 1000);
        }
    }


Código:
stock GetPlayerPacketloss(playerid,&Float:packetloss)
{
    /* Returns the packetloss percentage of the given playerid - Made by Fusez */

    if(!IsPlayerConnected(playerid)) return 0;

    new nstats[400+1], nstats_loss[20], start, end;
    GetPlayerNetworkStats(playerid, nstats, sizeof(nstats));

    start = strfind(nstats,"packetloss",true);
    end = strfind(nstats,"%",true,start);

    strmid(nstats_loss, nstats, start+12, end, sizeof(nstats_loss));
    packetloss = floatstr(nstats_loss);
    return 1;
}


Alguém me da uma luz? Uma ideia melhor pra melhorar? Um jeito melhor de lidar com isso?


RE: Lidar com pacotes perdidos - xbruno1000x - 01/11/2020

Caso precise de algo da WIKI, está tudo na wiki.open.mp. Quanto a conexão dos players, o que se pode fazer quanto a algo do client side? nada. O que você pode fazer é otimizar seu código. Por onde começar? evite usar a onplayerupdate, é uma public que é chamada milhares de vezes por minuto e que pode gerar instabilidade na resposta do player ao server.


RE: Lidar com pacotes perdidos - annety - 01/11/2020

Com as funções de NetStats da wiki não teria como pegar quando o cara tá de tempo parado ou não está respondendo, colocar os pacotes de volta pra ele, pra não ter que kickar ele e não ferrar a jogabiilidade de geral?

https://wiki.open.mp/docs/scripting/functions/NetStats_PacketLossPercent
https://wiki.open.mp/docs/scripting/functions/NetStats_MessagesSent
https://wiki.open.mp/docs/scripting/functions/NetStats_MessagesRecvPerSecond
https://wiki.open.mp/docs/scripting/functions/NetStats_MessagesReceived
https://wiki.open.mp/docs/scripting/functions/NetStats_GetIpPort
https://wiki.open.mp/docs/scripting/functions/NetStats_GetConnectedTime
https://wiki.open.mp/docs/scripting/functions/NetStats_ConnectionStatus
https://wiki.open.mp/docs/scripting/functions/NetStats_BytesSent
https://wiki.open.mp/docs/scripting/functions/NetStats_BytesReceived


RE: Lidar com pacotes perdidos - RodrigoMSR - 02/11/2020

Esse problema é conhecido como RT (relógio travado) e não tem volta quando acontece.

Uma forma de detectar quando o jogador está dessincronizado (talvez não funcione, dependendo do APK):
https://portalsamp.com/showthread.php?tid=49


RE: Lidar com pacotes perdidos - annety - 05/11/2020

(02/11/2020 22:05)RodrigoMSR Escreveu: Esse problema é conhecido como RT (relógio travado) e não tem volta quando acontece.

Uma forma de detectar quando o jogador está dessincronizado (talvez não funcione, dependendo do APK):
https://portalsamp.com/showthread.php?tid=49

Rodrigo,

Eu fiz algo errado?
Eu do PC to tomando kick por RT:

inicio da GM
Código:
// tempo parado 1
static
    bool:IsPlayerSynced[MAX_PLAYERS],
    PlayerAmmo[MAX_PLAYERS],
    PlayerUpdateTick[MAX_PLAYERS];


OnPlayerUpdate
Código:
// tempo parado 2
if(LogadoRec[playerid] == false)
{
    // detect if player is synced
    if(gettime() > PlayerUpdateTick[playerid]) {
        static current_weapon, current_ammo;
        PlayerUpdateTick[playerid] = gettime() + 2;
        GetPlayerWeaponData(playerid, 0, current_weapon, current_ammo);
        IsPlayerSynced[playerid] = (current_ammo != PlayerAmmo[playerid]);
        SetPlayerAmmo(playerid, current_weapon, !current_ammo);
        PlayerAmmo[playerid] = current_ammo;
    }
    // tempo parado 3
    // punish player unsynced
    if(IsPlayerSynced[playerid] == false) {
        SendClientMessage(playerid, COLOR_LIGHTRED, "TEMPO PARADO, DESCONECTADO!");
        new PlayerIP[20];
        GetPlayerIp(playerid, PlayerIP, sizeof PlayerIP);
        BlockIpAddress(PlayerIP, 3 * 60 * 1000);
    }
}

OnPlayerConnect
Código:
IsPlayerSynced[playerid] = true; // tempo parado 4



RE: Lidar com pacotes perdidos - RodrigoMSR - 07/11/2020

Quando comecei a usar este sistema ano passado também tive esses problemas, eu havia feito uma correção e está funcionando bem.

Aqui está o código:

Código PHP:
static bool:s_pSynced[MAX_PLAYERS];
static 
s_pAmmo[MAX_PLAYERS];
static 
s_pUpdateTime[MAX_PLAYERS];
static 
s_pDesyncTime[MAX_PLAYERS];
static 
s_pBugCount[MAX_PLAYERS];

public 
OnPlayerConnect(playerid)
{
    s_pDesyncTime[playerid] = 0;
    return 
1;
}

public 
OnPlayerSpawn(playerid)
{
    s_pDesyncTime[playerid] = 0;
    return 
1;
}

public 
OnPlayerUpdate(playerid)
{
    if(gettime() > s_pUpdateTime[playerid]) 
    {
        
s_pUpdateTime[playerid] = gettime() + 2;
        
        static current_weaponcurrent_ammonew_ammo;
        GetPlayerWeaponData(playerid0current_weaponcurrent_ammo); 
        
        s_pSynced
[playerid] = (current_ammo != s_pAmmo[playerid]);
        
        
s_pAmmo[playerid] = current_ammo;
        
new_ammo = !current_ammo;
        
        if(!
s_pSynced[playerid])
        {
            if(
s_pDesyncTime[playerid] == 0s_pDesyncTime[playerid] = gettime();
            
            if(++
s_pBugCount[playerid] >= 2)
            {
                
//mudar munição não funciona algumas vezes por algum motivo desconhecido (talvez valor invertido vindo de GetPlayerWeaponData)
                //setando para a mesma munição volta a funcionar
                
new_ammo current_ammo;
                
                
s_pBugCount[playerid] = 0;
            }
        }
        else
        {
            
s_pDesyncTime[playerid] = 0;
        }

        SetPlayerAmmo(playeridcurrent_weaponnew_ammo);        
    }
    return 
1;
}

stock IsPlayerSynced(playerid)
{
    return 
s_pSynced[playerid];
}

stock GetDesyncTime(playerid)
{
    return (
gettime() - s_pDesyncTime[playerid]);


Recomendo kickar o jogador somente se ele já estiver dessincronizado há algum tempo (ex: 20 segundos).

Código PHP:
if(!IsPlayerSynced(playerid) && GetDesyncTime(playerid) >= 20)
{
    
//kick




RE: Lidar com pacotes perdidos - annety - 14/11/2020

(07/11/2020 17:51)RodrigoMSR Escreveu: Quando comecei a usar este sistema ano passado também tive esses problemas, eu havia feito uma correção e está funcionando bem.

Aqui está o código:

Código PHP:
static bool:s_pSynced[MAX_PLAYERS];
static 
s_pAmmo[MAX_PLAYERS];
static 
s_pUpdateTime[MAX_PLAYERS];
static 
s_pDesyncTime[MAX_PLAYERS];
static 
s_pBugCount[MAX_PLAYERS];

public 
OnPlayerConnect(playerid)
{
    s_pDesyncTime[playerid] = 0;
    return 
1;
}

public 
OnPlayerSpawn(playerid)
{
    s_pDesyncTime[playerid] = 0;
    return 
1;
}

public 
OnPlayerUpdate(playerid)
{
    if(gettime() > s_pUpdateTime[playerid]) 
    {
        
s_pUpdateTime[playerid] = gettime() + 2;
        
        static current_weaponcurrent_ammonew_ammo;
        GetPlayerWeaponData(playerid0current_weaponcurrent_ammo); 
        
        s_pSynced
[playerid] = (current_ammo != s_pAmmo[playerid]);
        
        
s_pAmmo[playerid] = current_ammo;
        
new_ammo = !current_ammo;
        
        if(!
s_pSynced[playerid])
        {
            if(
s_pDesyncTime[playerid] == 0s_pDesyncTime[playerid] = gettime();
            
            if(++
s_pBugCount[playerid] >= 2)
            {
                
//mudar munição não funciona algumas vezes por algum motivo desconhecido (talvez valor invertido vindo de GetPlayerWeaponData)
                //setando para a mesma munição volta a funcionar
                
new_ammo current_ammo;
                
                
s_pBugCount[playerid] = 0;
            }
        }
        else
        {
            
s_pDesyncTime[playerid] = 0;
        }

        SetPlayerAmmo(playeridcurrent_weaponnew_ammo);        
    }
    return 
1;
}

stock IsPlayerSynced(playerid)
{
    return 
s_pSynced[playerid];
}

stock GetDesyncTime(playerid)
{
    return (
gettime() - s_pDesyncTime[playerid]);


Recomendo kickar o jogador somente se ele já estiver dessincronizado há algum tempo (ex: 20 segundos).

Código PHP:
if(!IsPlayerSynced(playerid) && GetDesyncTime(playerid) >= 20)
{
    
//kick


Mt obg! Vou testar aqui!


RE: Lidar com pacotes perdidos - manow6523 - 15/06/2023

(07/11/2020 17:51)RodrigoMSR Escreveu: Quando comecei a usar este sistema ano passado também tive esses problemas, eu havia feito uma correção e está funcionando bem.

Aqui está o código:

Código PHP:
static bool:s_pSynced[MAX_PLAYERS];
static 
s_pAmmo[MAX_PLAYERS];
static 
s_pUpdateTime[MAX_PLAYERS];
static 
s_pDesyncTime[MAX_PLAYERS];
static 
s_pBugCount[MAX_PLAYERS];

public 
OnPlayerConnect(playerid)
{
    s_pDesyncTime[playerid] = 0;
    return 
1;
}

public 
OnPlayerSpawn(playerid)
{
    s_pDesyncTime[playerid] = 0;
    return 
1;
}

public 
OnPlayerUpdate(playerid)
{
    if(gettime() > s_pUpdateTime[playerid]) 
    {
        
s_pUpdateTime[playerid] = gettime() + 2;
        
        static current_weaponcurrent_ammonew_ammo;
        GetPlayerWeaponData(playerid0current_weaponcurrent_ammo); 
        
        s_pSynced
[playerid] = (current_ammo != s_pAmmo[playerid]);
        
        
s_pAmmo[playerid] = current_ammo;
        
new_ammo = !current_ammo;
        
        if(!
s_pSynced[playerid])
        {
            if(
s_pDesyncTime[playerid] == 0s_pDesyncTime[playerid] = gettime();
            
            if(++
s_pBugCount[playerid] >= 2)
            {
                
//mudar munição não funciona algumas vezes por algum motivo desconhecido (talvez valor invertido vindo de GetPlayerWeaponData)
                //setando para a mesma munição volta a funcionar
                
new_ammo current_ammo;
                
                
s_pBugCount[playerid] = 0;
            }
        }
        else
        {
            
s_pDesyncTime[playerid] = 0;
        }

        SetPlayerAmmo(playeridcurrent_weaponnew_ammo);        
    }
    return 
1;
}

stock IsPlayerSynced(playerid)
{
    return 
s_pSynced[playerid];
}

stock GetDesyncTime(playerid)
{
    return (
gettime() - s_pDesyncTime[playerid]);


Recomendo kickar o jogador somente se ele já estiver dessincronizado há algum tempo (ex: 20 segundos).

Código PHP:
if(!IsPlayerSynced(playerid) && GetDesyncTime(playerid) >= 20)
{
    
//kick


Mesmo utilizando essa correção, sigo sendo detectado como dessincronizado. Alguém tem alguma solução?

OBS: desculpa reviver um tópico tão antigo.