InSim
o InSim é um protocolo que permite que um programa externo se comunique com o Live For Speed. Ele permite que você crie uma conexão de soquete com o jogo e envie e receba pacotes de dados. O protocolo InSim descreve como cada um desses pacotes é formatado, e qualquer linguagem de programação que pode criar uma conexão de rede e enviar e receber strings de dados binários pode interagir com ele.
a documentação oficial está incluída no arquivo InSim.txt, encontrado na pasta games doc. Consiste em um arquivo de cabeçalho C++ que contém a definição para cada pacote, bem como comentários de Scawen sobre como cada um deve ser usado. A documentação aqui destina-se a auxiliar este arquivo.
UDP vs TCP
o InSim suporta conexões UDP e TCP. No modo UDP, apenas uma única conexão pode ser feita, no entanto, até oito conexões podem ser feitas no jogo em TCP. Seja conectado em TCP ou UDP, é possível especificar um soquete UDP separado para receber atualizações de posição do carro, como IS_MCI e IS_NLP.
InSim exemplo
Como você ir sobre como criar um InSim ligação é claro, depende de qual linguagem de programação você está usando, mas aqui podemos fazer uma tentativa de documentar o processo com alguns exemplos da popular linguagem de programação Python. Como mencionado acima, qualquer idioma capaz de fazer uma conexão de soquete pode ser usado para fazer interface com o LFS, no entanto, o princípio permanece o mesmo independentemente.
criando uma conexão
Antes de tudo, devemos estabelecer uma conexão de soquete com o jogo, neste caso em TCP.
# Import Python's socket module.import socket# Initialise the socket in TCP mode. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# Connect to LFS.sock.connect(('localhost', 29999))
Inicializando o InSim
depois de estabelecer a conexão, devemos inicializar o sistema InSim enviando o pacote IS_ISI. Antes que possamos fazer isso, no entanto, devemos primeiro intitailse InSim dentro do próprio LFS. Para fazer isso, inicie o jogo e digite o comando de bate-papo “/insim 29999”. O número da porta usado pode ser qualquer porta válida, mas 29999 geralmente tende a ser o padrão aceito.
aqui está a definição para o pacote IS_ISI do InSim.txt.
struct IS_ISI // InSim Init - packet to initialise the InSim system{byteSize;// 44byteType;// ISP_ISIbyteReqI;// If non-zero LFS will send an IS_VER packetbyteZero;// 0wordUDPPort;// Port for UDP replies from LFS (0 to 65535)wordFlags;// Bit flags for options (see below)byteSp0;// 0bytePrefix;// Special host message prefix characterwordInterval;// Time in ms between NLP or MCI (0 = none)charAdmin;// Admin password (if set in LFS)charIName;// A short name for your program};
cada pacote InSim começa com um cabeçalho, composto por 4 bytes. O primeiro byte é o tamanho do pacote, seguido pelo tipo de pacote da enumeração ISP_ e, em seguida, o ReqI (que significa ID de solicitação). Sempre que uma solicitação é feita ao LFS, o valor do ReqI deve ser definido como diferente de zero, pelo que o LFS responderá com o mesmo valor definido no ReqI do pacote solicitado. Finalmente, o quarto byte varia dependendo do tipo de pacote em questão, que neste caso está em branco.
como você pode ver, o pacote IS_ISI contém várias opções e sinalizadores que são usados ao inicializar o sistema InSim. Devemos embalar esses dados em uma string formatada binária para enviá-los para o LFS.
# Import Python's struct module, which allows us to pack and unpack strings.import struct# Pack the IS_ISI data into a string.isi = struct.pack('BBBBHHBcH16s16s', 44, # Size 1, # Type 1, # ReqI 0, # Zero 0, # UDPPort 0, # Flags 0, # Sp0 ' ', # Prefix 0, # Interval 'password', # Admin 'MyProgram',) # IName# Send the string to InSimsock.send(isi)
receber dados
depois de criar a conexão e inicializar o InSim, devemos configurar o loop de recebimento de pacotes. Como os dados no modo TCP são enviados como um fluxo constante de dados, vários pacotes podem chegar em uma única chamada de recebimento e alguns pacotes podem chegar incompletos. Isso significa que devemos armazenar todos os dados recebidos em um buffer e, em seguida, ler cada pacote quando tivermos certeza de que está completo.
# We use a string as the buffer.buffer = ''while True: # Receive up to 1024 bytes of data. data = sock.recv(1024) # If no data is received the connection has closed. if data: # Append received data onto the buffer. buffer += data # Loop through each completed packet in the buffer. The first byte of # each packet is the packet size, so check that the length of the # buffer is at least the size of the first packet. while len(buffer) > 0 and len(buffer) > ord(buffer): # Copy the packet from the buffer. packet = buffer)] # Remove the packet from the buffer. buffer = buffer):] # The packet is now complete! :) # doSomethingWithPacket(packet) else: break# Release the socket.sock.close()
descompactar pacotes
uma vez que recebemos os dados do pacote como uma string formatada binária, temos que descompactar esses dados em um formato que é útil para nós. Em nosso exemplo anterior, quando enviamos o pacote de initailização IS_ISI, definimos o ReqI como diferente de zero, o que significa que o LFS respondeu com um pacote de versão IS_VER, no entanto, não fizemos nada com ele. Em primeiro lugar, vamos olhar para a definição do pacote IS_VER do InSim.txt.
struct IS_VER // VERsion{byteSize;// 20byteType;// ISP_VERSIONbyteReqI;// ReqI as received in the request packetbyteZero;charVersion;// LFS version, e.g. 0.3GcharProduct;// Product : DEMO or S1wordInSimVer;// InSim Version : increased when InSim packets change};
agora vamos ver como descompactaríamos esses dados em Python.
# Import Python's struct module.import struct# Unpack the binary formatted packet data into the values we need.size, type, reqi, zero, version, product, insimver = struct.unpack('BBBB8s6sH', packet)# Check the InSim version.if insimver != 4: print 'Invalid InSim version!' sock.close()
Keep Alive
para manter a conexão aberta, o LFS enviará um pacote “keep alive” a cada 30 ou mais segundos. Este pacote é um IS_TINY com um SubT (sub-tipo) de TINY_NONE. Devemos responder a este pacote toda vez que ele for recebido para evitar que a conexão com o InSim seja interrompida.
# Some constants.ISP_TINY = 3TINY_NONE = 0# Check the packet type.if ord(packet) == ISP_TINY: # Unpack the packet data. tiny = struct.unpack('BBBB', packet) # Check the SubT. if tiny == TINY_NONE: # Send the keep alive packet back to LFS. sock.send(packet)
outros exemplos
você pode ver o exemplo completo deste código, bem como outros na página exemplos InSim.
InSim Bibliotecas
é claro que, como diz o velho ditado, você não deve tentar reinventar a roda (a menos que você está tentando aprender mais sobre rodas) e existem vários maduro InSim bibliotecas disponíveis para uso em seu próprio código.
InSim Bibliotecas | ||||
---|---|---|---|---|
Biblioteca | Plataforma | Licença | web | |
LFSLib | .NET Framework | GPL | página do projeto | |
LFS_External | .NET Framework | Freeware | lfsforum thread | |
JInSim | Java | Mozilla | lfsforum thread | |
pyinsim | Python | LGPL | lfsforum thread | |
CInSim | C/C++ | Freeware | lfsforum thread | |
phplfs | PHP5 | Licença Apache V2.0 | página do projeto | |
PRISMA | PHP7 | MIT | lfsforum seção | |
InSim.NET | .NET Framework | LGPL | lfsforum thread |
InSim Referência
Aqui é uma tentativa de fazer referência a completa InSim protocolo.
Pacote de Referência | ||
---|---|---|
Pacote | Descrição | Tipo de |
Inicialização | ||
IS_ISI | InSim inicialização | Instrução |
de Propósito Geral | ||
IS_TINY | Geral finalidade de 4 bytes de pacotes | Ambos |
IS_SMALL | propósito Geral de 8 bytes de pacotes | Ambos |
Versão pedido | ||
IS_VER | informações de Versão | Info |
Estado de Relatórios e Pedidos | ||
IS_STA | Enviado sempre que o jogo alterações de estado | Info |
IS_SFP | Enviar para definir várias opções de estado | Instrução |
Modo de Ecrã | ||
IS_MOD | Enviar para alterar o modo de ecrã | Instrução |
Mensagens de Texto e Pressiona Tecla | ||
IS_MSO | Sistema e do usuário mensagens enviadas a partir do LFS | Info |
IS_III | mensagens do Usuário para o host InSim | Info |
IS_MST | Enviar LFS uma mensagem ou comando (64 caracteres) | Instrução |
IS_MSX | versão Estendida do IS_MST (96 caracteres), e não para comandos | Instrução |
IS_MSL | Enviar mensagem para o local do cliente de jogo | Instrução |
IS_MTC | Enviar mensagem para conexão específica ou jogador | Instrução |
IS_SCH | Enviar único caractere ou prima a tecla | Instrução |
Multiplayer de Notificação | ||
IS_ISM | Enviado quando iniciar ou participar de um host | Info |
IS_NCI | Enviada ao host admin palavra-passe estiver definida, contém o IP do usuário e o idioma de dados | Info |
Voto Notificar | ||
IS_VTN | Notificar o jogador voto (reiniciar a corrida, qualifica etc..) | Info |
Corrida de Rastreamento | ||
IS_RST | Corrida de iniciar ou reiniciar o | Info |
IS_NCN | Nova ligação de ingressar servidor | Info |
IS_SLC | para informar sobre as mudanças no carro do estado (atualmente iniciar ou parar) | Info |
IS_CSC | relatórios de uma ligação carro atualmente selecionado | Info |
IS_CNL | Conexão de esquerda servidor | Info |
IS_CPR | Jogador mudou de nome | Info |
IS_NPL | Novo jogador de ingressar na corrida, ou deixando poços | Info |
IS_PLP | Leitor de poços (ido para a garagem) | Info |
IS_PLL | Jogador à esquerda de corrida (ido para o espectador) | Info |
IS_CRS | Carro reset premido (barra de espaço), | Info |
IS_JRR | pode ser utilizado para reiniciar ou iniciar um carro em um local especificado | Instruções |
IS_LAP | tempo de Volta concluído | Info |
IS_SPX | Dividir vez concluído | Info |
IS_PIT | Pit stop iniciado (em box) | Info |
IS_PSF | Pit stop terminado | Info |
IS_PLA | Jogador entrou no pit lane (para poço ou servir de pênalti) | Info |
IS_CHH | Câmera de visão mudou (chase vista, modo de exibição personalizado, etc..) | Info |
IS_PEN | punição ou calçado | Info |
IS_TOC | Jogador tomado outro carro (motorista de swap) | Info |
IS_FLG | Jogador bandeira (amarelo ou azul) | Info |
IS_PFL | Leitor de bandeiras alterado (auto-marchas, automático de embreagem, etc..) | Info |
IS_FIN | Jogador terminou a corrida (cruzar a linha de chegada) | Info |
IS_RES | Leitor de resultado adjudicado, confirmou concluir | Info |
IS_REO | Reordenar grelha de partida | Ambos |
Autocross | ||
IS_AXI | Autocross layout carregado | Info |
IS_AXO | Jogador atingido autocross objeto | Info |
IS_OCO | pode ser usada para substituir específica ou todas as luzes se | Instrução |
IS_UCO | envia informações sobre InSim pontos de verificação e círculos | Info |
o Seguimento do Carro | ||
IS_NLP | Jogadores do nó atual, volta e corrida de posição | Info |
IS_MCI | versão Mais detalhada de IS_NLP, o mundo coordenadas, velocidade, ângulo e título | Info |
o Controle da Câmera | ||
IS_SCC | Definir vistos carro e a câmera selecionar | Instruções |
IS_CPP | Conjunto completo de câmara de posição | Instrução |
Repetição de Controle | ||
IS_RIP | Carga de repetição e de mover para o destino específico | Instrução |
Capturas de tela | ||
IS_SSH | Tirar um screenshot | Instrução |
InSim Botões | ||
IS_BFN | Excluir um botão ou todos os botões | Instrução |
IS_BTN | Enviar um botão para a tela | Instruções |
IS_BTC | Enviado quando um botão é clicado | Info |
IS_BTT | Enviado quando o texto é inserido | Info |