Portal SAMP
[Tutorial] Jogadores dessincronizados e como lidar com eles - Versão de Impressão

+- Portal SAMP (https://portalsamp.com)
+-- Fórum: SA-MP (https://portalsamp.com/forumdisplay.php?fid=5)
+--- Fórum: Guias e Tutoriais (https://portalsamp.com/forumdisplay.php?fid=7)
+--- Tópico: [Tutorial] Jogadores dessincronizados e como lidar com eles (/showthread.php?tid=49)



Jogadores dessincronizados e como lidar com eles - BrunoBM16 - 28/09/2020

Jogadores dessincronizados e como lidar com eles

Você provavelmente já lidou com jogadores dessincronizados antes e sabe o quão problematico pode ser, especialmente por questão de falsos-positivos em sistemas de anti-cheat.

Vamos supor que seu anti-cheat expulsa jogadores se a arma não for dada pelo servidor. Se você fosse disarmar um jogador dessincronizado, suas armas não seriam removidas e o mesmo seria uma vítima de falso-positivo, sendo expulso por algo que não fez.

Em geral, você não pode "spawnar", mudar a vida/colete por funções, teleportar, dar/remover armas, mudar a munição, etc desses jogadores. Isso ocorre por que jogadores dessincronizados não reagem a alguns RPCs (chamadas de procedimento remoto) mandados pelo servidor, porém, client messages (SendClientMessage) e game texts ainda funcionam.

A callback OnPlayerUpdate

Esta callback ainda é executada. Isso por que esses jogadores ainda mandam pacotes de sincronização para o servidor, e esse é o motivo pelo qual você ainda pode vê-los movendo/disparando e interagindo com o servidor e possivelmente com outros jogadores.

Jogadores dessincronizados não reagem a alguns RPCs, como previamente dito. Eles ainda podem andar por ai, mandar comandos para o servidor, conversar, matar outros jogadores, etc, porém, eles também notam problemas em seu fim. Existem dois RPCs para fazer o processo de stream in/out com veículos e jogadores, e esses são alguns dos RPCs que não vão ser processados no cliente do jogador dessincronizado, então, outros jogadores não vão passar por esse processo, e isso significa que, jogadores que deveriam passar pelo processo de stream-out, não seram removidos do jogo, e aqueles que deveriam passar pelo processo de stream-in não vão ser adicionados, não se tornando visíveis no jogo do jogador dessincronizado, isso por que seus player-peds ainda não foram criados e não vão ser. Jogadores que deveriam ser removidos não teram seus player-peds destruidos e vão permanecer, porém, não serão sincronizados com o jogador novamente, isso por que o servidor já reconheçe que esses jogadores não estão na sua area de stream-in, não enviando os pacotes de sincronização para o jogador, então esses outros jogadores são vistos como se estivessem AFK, o que não é a realidade.

Os chamados de "laggers" ainda reagem a essas atualizações, mas ambos os casos são diferentes e não devem ser confundidos. De qualquer forma, eles também são vítimas de falsos-positivos e tem grandes chances de serem dessincronizados em algum momento.

Como detectar?

Agora que você sabe que esses jogadores não reagem a alguns RPCs, existem algumas coisas que você poderia tentar. Eu pessoalmente gosto e uso esta forma para saber de jogadores possivelmente dessincronizados (Leve em consideração que esta é apenas uma parte de meu sistema para que você tenha uma idéia de como funciona, não é algo pronto para você copiar e colar em seu script):

Código PHP:
static 
    bool
:IsPlayerSynced[MAX_PLAYERS char],
    PlayerAmmo[MAX_PLAYERS char],
    PlayerUpdateTick[MAX_PLAYERS];
    
public OnPlayerUpdate
(playerid)
{
    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;
    }
    return 1;
}

//Utilizando IsPlayerSynced{playerid} em algum lugar...  
Como isso funciona exatamente? Este pequeno sistema simplesmente muda a munição na slot 0 (punhos/soco inglês) entre 1 e 0 (antes que você me pergunte, a munição de armas brancas não importa, então não podem ser removidas mudando sua munição para 0), que não é notado pelos jogadores. Já que jogadores dessincronizados não podem ter sua munição mudada de alguma forma pelo servidor, ela continuara sendo a mesma, e é assim que funciona.

Por que a callback OnPlayerUpdate? Como previamente dito, jogadores dessincronizados ainda mandam pacotes de sincronização para o servidor, então a callback continua sendo executada. Logo, fazer a verificação ai é bom, especialmente por que jogadores AFK não seram "marcados" como dessincronizados, não interferindo com sua verificação.

O que fazer após confirmado?

Você pode expulsar o jogador com um aviso dizendo para conectar novamente. Por que? Por que mesmo que seu servidor não se constitua de sistemas onde jogadores dessincronizados são potenciais vítimas de falsos-positivos, isso só resulta em confusão e geralmente em denúncias falsas por parte de outros jogadores, especialmente pelo fato de que pessoas que deveriam passar pelo processo de stream-in, não vão aparecer no jogo do jogador dessincronizado, sendo impossível causar dano, pois o mesmo não vê esses jogadores e não vai registrar o dano por sua parte em seu cliente.


RE: Jogadores dessincronizados e como lidar com eles - Silva - 28/09/2020

Ótimo tutorial bruno, parabéns.


RE: Jogadores dessincronizados e como lidar com eles - Saturnov Padeiro - 28/09/2020

Boa noite Bruno, ótimo tutorial.


RE: Jogadores dessincronizados e como lidar com eles - Gabriel - 29/09/2020

Mano, com certeza sanou muitas dúvidas, ótimo tutorial!


RE: Jogadores dessincronizados e como lidar com eles - RodrigoMSR - 29/09/2020

Ótimo tutorial!


RE: Jogadores dessincronizados e como lidar com eles - JhonCavichioli - 30/09/2020

Tutorial muito bom!


RE: Jogadores dessincronizados e como lidar com eles - Sysner - 27/10/2021

Muito bom tutorial


RE: Jogadores dessincronizados e como lidar com eles - Jogador - 02/11/2021

(28/09/2020 21:17)BrunoBM16 Escreveu:
Código PHP:
static 
    bool
:IsPlayerSynced[MAX_PLAYERS char],
    PlayerAmmo[MAX_PLAYERS char],
    PlayerUpdateTick[MAX_PLAYERS];
    
public OnPlayerUpdate
(playerid)
{
    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;
    }
    return 1;
}

//Utilizando IsPlayerSynced{playerid} em algum lugar...  

Eu tenho umas dúvidas:

1° static bool:IsPlayerSynced[MAX_PLAYERS char]
Esse 'char' define o que?

2° PlayerAmmo{playerid} é a mesma coisa que PlayerAmmo[playerid] ?