28/09/2020 21:17
(Esta mensagem foi modificada pela última vez a: 28/09/2020 21:50 por BrunoBM16.)
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):
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.
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...
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.