Eu tenho trabalhado em uma arquitetura P2P para jogos seguros e dividi o problema em cinco subproblemas:
- Modificação ilegal do estado do jogo enviado
- Solte trapaceiros com precisão
- Concordando em um estado de jogo
- Evitando fraudes do tipo "olhar à frente"
- Ocultando informações confidenciais dos oponentes
Os quatro primeiros que eu praticamente resolvi, mas é o último com o qual estou tendo problemas.
Antes de entrar em detalhes, só quero perguntar se há algo que eu tenha perdido na minha lista de criação de uma rede p2p "à prova de trapaças". Não estou interessado em truques, como usar aimbots, apenas em tornar a rede p2p tão segura quanto um servidor centralizado.
Portanto, em meu esforço até agora em ocultar informações confidenciais, concentrei-me na posição dos jogadores em um jogo em que a posição do seu oponente nem sempre deve ser conhecida. O problema passa a ser como determinar se você deve enviar sua posição ao seu oponente sem saber a posição do seu oponente.
Eu descartei métodos como o oponente enviando várias posições falsas para você comparar a sua também, pois seu oponente pode facilmente abusar de um sistema desse tipo, pois ele conseguirá sua posição se uma dessas posições falsas for "visível" da sua posição.
O método que eu tenho focado em um em que você recebe um "campo visual" do seu oponente e pode assim determinar se você deve enviar sua posição ou não. No entanto, isso é um problema em jogos como League of Legends, onde o campo visual do seu oponente também é uma informação altamente sensível. Tentei resolver isso transformando o campo visual usando uma matriz singular, o que significa que você não pode passar da versão transformada do campo visual para a versão original, mas, como é uma transformação linear, ainda é possível descobrir se sua posição está dentro o campo visual ou não.
No entanto, isso não funciona perfeitamente, o campo visual exato não pode ser restaurado após a transformação, mas as informações sobre as "inclinações" no campo visual (o campo visual é construído por várias linhas e a inclinação de cada linha pode ser determinada) pode ser restaurado e isso pode ser usado para reconstruir relativamente barato o campo visual original.
Em essência, o que eu preciso é de uma função que possa determinar se uma posição é "visível" ou não, e a reconstrução dessa função / campo visual deve ser tão exigente em termos computacionais que, quando você terminar de reconstruir o campo visual, não será mais relevante para o jogo em ação. Existe alguma pessoa super inteligente por aí que conhece esse método?
Editar Pessoas costura tipo de confuso sobre todo o "campo de visão", então eu como objectivo dar uma explicação mais detalhada aqui. O campo de visão consiste em grupos de um conjunto de linhas. Você pode verificar facilmente se uma posição está dentro de um desses grupos apenas verificando qual lado da linha está sua posição, se está do mesmo lado para todas as linhas desse grupo que você conhece. está dentro desse grupo e, portanto, dentro do campo de visão.
As informações enviadas, no entanto, não são essa linha, mas uma transformação da linha e da transformação (matriz 2 por 2 no singular), você ainda pode verificar em qual lado da linha sua posição está, transformando-a primeiro usando a transformação que você recebeu e comparando esse valor com a linha transformada. A chave aqui é que a transformação é singular, o que significa que é impossível encontrar um inverso para voltar à linha original. No entanto, é possível determinar a inclinação da linha que torna a reconstrução da linha apenas verificando em que lado da linha transformada muitos pontos se encontram até que você identifique a origem da linha muito mais computacionalmente mais barata do que se você não soubesse a inclinação da linha.
O que estou procurando é um método para determinar se um ponto está dentro de uma área, onde a reconstrução da área a partir do método é impossível (o que duvido que exista, já que você sempre pode fazer força bruta) ou muito computacionalmente pesada.
fonte
Respostas:
Eu acho que mesmo se você tivesse um algoritmo irreversível para um campo de visão, as pessoas ainda poderiam obter vantagem calculando se pontos próximos a eles resultariam em uma interseção desse local e um campo visual do oponente se cruzaria. Em um caso ruim (de um campo de visão grande o suficiente para mapear a proporção), você pode calcular, por processo de eliminação, o ponto exato do seu inimigo.
Penso que, em vez disso, talvez todos os colegas conectados devam anunciar em que parte do mapa estão, para determinar se é possível que se vejam ou não. Primeiro divida o mapa em 2x2 ou 2x2x2 se a 3ª dimensão for importante. Então todos dizem um ao outro se estão em 1,0 1,1 0,1 ou 0,0. Se eles não estiverem no mesmo quadrante, a conversa terminará até a próxima verificação. Isso protege sua localização exata. Se eles existirem no mesmo quadrante, dividirão esse espaço em quatro novos quadríceps e continuarão até que determinem que estão perto o suficiente para serem vistos um pelo outro.
É claro que existem problemas com as fronteiras dos quadrantes, mas deve ser solucionável com consultas adicionais aos quadrantes vizinhos.
fonte
Não tome isso como uma resposta definitiva, o tópico é realmente amplo (não ficarei surpreso se alguém sinalizar sua pergunta de fato).
Você pode resolvê-lo usando alguns jogadores como servidor e , quando um jogador é usado como servidor, ele não pode participar do jogo de jogadores que realmente estão jogando nesse servidor .
Se o seu jogo não for muito exigente, você também pode executar vários servidores na mesma máquina de jogador (é claro que seria útil, pois nem todos os jogadores podem rodar como servidor devido a problemas de NAT, obrigado IPv6 !!).
O principal problema aqui é que, como um jogador aleatório será usado como servidor, há uma pequena chance de ser um jogador "comprometido" ou de passar a simulação a um jogador "comprometido", permitindo que informações confidenciais sejam transmitidas ( bem, na realidade, nesse ponto, o servidor poderia enviar dados arbitrários e forçar a vitória de qualquer maneira).
Se você usar um servidor central para verificar autorizações e logins, poderá organizar melhor os jogos e banir jogadores facilmente (no entanto, isso não seria mais uma rede P2P pura).
Você também pode dividir o mundo em fatias e calcular um hash das fatias visíveis, mas isso pode ser facilmente enganado, pois as fatias visíveis mais comuns permitirão criar uma tabela de hashes rapidamente.
Para mim, sua pergunta é como tentar procurar uma função criptográfica. O teste deve ser rápido, mas a força bruta deve ser lenta.
A coisa mais simples que me vem à cabeça (também relacionada ao meu trabalho) é usar algum algoritmo de reconhecimento rápido da visão (como realidade aumentada).
Se você conseguir fazer um "instantâneo" rápido da sua localização (semelhante às fatias), só poderá ser reconhecido quando colocado em torno de algo visível, e você poderá obtê-lo. Especialmente se houver elementos temporizados no mapa que permitam gerar padrões de reconhecimento de descarte rápido.
No entanto, mesmo que esses algoritmos se tornem bastante rápidos, mesmo em dispositivos móveis, não acho que sejam rápidos o suficiente para um jogo de tiro em primeira pessoa.
Além disso, se você os fizer rápido demais, terá falsos positivos! E um jogador pode, de qualquer maneira, criar um jogo que tente alguns "visuais comuns", para que um dos visuais corresponda positivo ao algoritmo de detecção de recursos.
Não ficarei surpreso que a única solução possível para o seu problema seja possível na Computação Quântica e, em alguns anos, alguém publique um documento que comprove esse limite intrínseco nas redes P2P.
fonte
Quando você diz 'Ocultando informações confidenciais dos oponentes', quer dizer que deseja evitar que pessoas com farejadores de pacotes ouçam seu tráfego e obtenham informações sobre seu jogo?
Nesse caso, há uma resposta fácil para isso; a maioria dos jogos AAA (e certamente jogos de console) usam criptografia. De fato, é tão comum que muitos dos middlewares de rede usados em jogos já possuem criptografia de pacotes embutida.
Normalmente, funciona assim: Quando você abre uma conexão com outra máquina, antes que o soquete se torne ativo, ocorre uma troca de chaves. Eu sei que no XBox costumava ser a troca de chaves Diffie-Hellman; Não faço ideia se eles ainda o usam agora. Depois que você tiver suas chaves, todos os dados enviados serão criptografados usando as chaves e não criptografados no recebimento. Se alguém usar um sniffer para ler seus pacotes, eles parecerão sem sentido e é improvável que eles possam descriptografá-los, pois não possuem as chaves. (Os hackers avançados podem obtê-los acessando a memória do processo do jogo em execução, mas isso é raro e improvável.)
A única exceção à regra de criptografia são os dados do VoiceChat; por lei nos EUA, o bate-papo por voz deve ser enviado de maneira clara, para que a CIA possa ouvir se quiser. Os consoles geralmente fornecem uma maneira de marcar dados de voz para que não sejam criptografados.
fonte