InSim

InSim

InSim es un protocolo que permite a un programa externo comunicarse con Live for Speed. Permite crear una conexión de socket con el juego y enviar y recibir paquetes de datos. El protocolo InSim describe cómo se formatea cada uno de estos paquetes, y cualquier lenguaje de programación que pueda crear una conexión de red y enviar y recibir cadenas de datos binarios puede interactuar con él.

La documentación oficial se incluye en el archivo InSim.txt, que se encuentra en la carpeta de documentos de juegos. Consiste en un archivo de encabezado C++ que contiene la definición de cada paquete, así como comentarios de Scawen sobre cómo se debe usar cada uno. La documentación aquí está destinada a ser un complemento de este archivo.

UDP vs TCP

InSim admite conexiones UDP y TCP. En el modo UDP solo se puede hacer una sola conexión, sin embargo, se pueden hacer hasta ocho conexiones al juego en TCP. Ya sea que esté conectado en TCP o UDP, es posible especificar un socket UDP separado para recibir actualizaciones de posición del automóvil, como IS_MCI e IS_NLP.

Ejemplo de InSim

Cómo crear una conexión InSim depende, por supuesto, del lenguaje de programación que esté utilizando, pero aquí hacemos un intento de documentar el proceso con algunos ejemplos del popular lenguaje de programación Python. Como se mencionó anteriormente, cualquier lenguaje capaz de hacer una conexión de socket se puede usar para interactuar con LFS, sin embargo, el principio sigue siendo el mismo.

Crear una conexión

En primer lugar debemos establecer una conexión socket con el juego, en este caso en 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))

Inicializar InSim

Después de establecer la conexión, debemos inicializar el sistema InSim enviando el paquete IS_ISI. Antes de que podamos hacer esto, sin embargo, primero debemos inicializar InSim dentro de la propia LFS. Para hacer esto, inicie el juego e ingrese el comando de chat «/ insim 29999». El número de puerto utilizado puede ser cualquier puerto válido, pero 29999 generalmente tiende a ser el valor predeterminado aceptado.

Aquí está la definición para el paquete IS_ISI de 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 paquete InSim comienza con un encabezado, que consta de 4 bytes. El primer byte es el tamaño del paquete, seguido del tipo de paquete de la enumeración ISP_, y luego el ReqI (sinónimo de Request Id). Siempre que se realice una solicitud a LFS, el valor de la ReqI debe ser distinto de cero, por lo que LFS responderá con el mismo valor establecido en la ReqI del paquete solicitado. Finalmente, el cuarto byte varía dependiendo del tipo de paquete en cuestión, que en este caso está en blanco.

Como puede ver, el paquete IS_ISI contiene varias opciones y banderas que se utilizan al inicializar el sistema InSim. Debemos empaquetar estos datos en una cadena con formato binario para enviarlos a 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)

Recepción de datos

Después de crear la conexión e inicializar InSim, debemos configurar el bucle de recepción de paquetes. Como los datos en modo TCP se envían como un flujo constante de datos, pueden llegar varios paquetes en una sola llamada de recepción y algunos paquetes pueden llegar incompletos. Esto significa que debemos almacenar todos los datos entrantes en un búfer y luego leer cada paquete cuando estemos seguros 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()

Desempaquetar paquetes

Una vez que hemos recibido los datos del paquete como una cadena con formato binario, tenemos que desempaquetar estos datos en un formato que nos sea útil. En nuestro ejemplo anterior, cuando enviamos el paquete de inicialización IS_ISI, establecemos el ReqI a distinto de cero, lo que significa que LFS respondió con un paquete de versión IS_VER, sin embargo, no hicimos nada con él. Primero veamos la definición del paquete IS_VER de 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};

Ahora veamos cómo descomprimiríamos esos datos en 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 mantener abierta la conexión, LFS enviará un paquete «keep alive» cada 30 segundos aproximadamente. Este paquete es un IS_TINY con un SubT (subtipo) de TINY_NONE. Debemos responder a este paquete cada vez que se recibe para evitar que la conexión con InSim se agote.

# 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)

Más ejemplos

Puede ver el ejemplo completo de este código, así como otros en la página ejemplos de InSim.

Bibliotecas InSim

Por supuesto, como dice el viejo adagio, no debe intentar reinventar la rueda (a menos que esté tratando de aprender más sobre las ruedas) y hay varias bibliotecas InSim maduras disponibles para usar en su propio código.

InSim Bibliotecas
Biblioteca de la Plataforma Licencia web
LFSLib .NET Framework GPL página del proyecto
LFS_External .NET Framework Freeware lfsforum hilo
JInSim Java Mozilla lfsforum hilo
pyinsim Python LGPL lfsforum hilo
CInSim C/C++ Freeware lfsforum hilo
phplfs PHP5 Licencia Apache V2.0 página del proyecto
PRISMA PHP7 MIT lfsforum sección
InSim.NET . NET Framework LGPL hilo lfsforum

Referencia InSim

Aquí hay un intento de hacer referencia al protocolo InSim completo.

Paquete de Referencia
Paquete Descripción Tipo de
Inicialización
IS_ISI InSim inicialización Enseñanza
Propósito General
IS_TINY de propósito General 4 bytes de paquete Tanto
IS_SMALL de propósito General de 8 bytes de paquete Tanto
petición de Versión
IS_VER información de la Versión Info
Presentación de Informes y Solicitudes de los Estados
IS_STA Enviado cada vez que cambia el estado del juego Info
IS_SFP Enviar para configurar varias opciones de estado Instrucción
Modo de Pantalla
IS_MOD Enviar para cambiar el modo de pantalla Instrucción
Mensajes de Texto y Pulsaciones de Teclas
IS_MSO Mensajes de sistema y usuario enviados desde LFS Info
IS_III Mensajes de usuario para alojar InSim Info
IS_MST Enviar a LFS un mensaje o comando(64 caracteres) Instrucción
IS_MSX Versión extendida de IS_MST (96 caracteres), no para instrucciones de comandos
IS_MSL Enviar mensaje al cliente de juego local Instrucción
IS_MTC Enviar mensaje a una conexión específica o instrucción de reproductor
IS_SCH Enviar un solo carácter o pulsar una tecla Instrucción
Notificación Multijugador
IS_ISM Enviado al iniciar o unirse a un host Info
IS_NCI Se envía cuando se establece la contraseña de administrador del host, contiene datos de idioma e IP del usuario Info
Notificación de Votación
IS_VTN Notificar el voto del jugador (reiniciar la carrera, calificar, etc..) Info
la regata
IS_RST Carrera de iniciar o reanudar el Info
IS_NCN Nueva conexión de unirse servidor Info
IS_SLC para informar de cambios en coche de estado (en la actualidad iniciar o detener) Info
IS_CSC informes de una conexión seleccionada actualmente coche Info
IS_CNL Conexión de la izquierda servidor Info
IS_CPR Jugador cambió de nombre Info
IS_NPL Nuevo jugador de unirse a la raza, o dejando hoyos Info
IS_PLP Reproductor de pozos de (ido a la pantalla garaje) Info
IS_PLL Jugador a la izquierda de la raza (ido a observar) Info
IS_CRS Auto reset (presiona la barra de espacio) Info
IS_JRR se puede utilizar para reiniciar o iniciar un coche en una ubicación especificada la Instrucción
IS_LAP tiempo de Vuelta completado Info
IS_SPX Dividir vez completado Info
IS_PIT parada en Boxes de introducción (en el pit box) Info
IS_PSF parada en Boxes terminado Info
IS_PLA Jugador entró en el pit lane (hoyo o servir de penalti) Info
IS_CHH vista de la Cámara cambiado (chase view, vista personalizada etc..) Info
IS_PEN Sanción o con apoyos de tracción Info
IS_TOC Jugador tomado otro coche (conductor de intercambio) Info
IS_FLG Reproductor muestra la bandera (amarillo o azul) Info
IS_PFL Reproductor de banderas cambiado (auto-marchas automático, embrague, etc..) Info
IS_FIN Jugador terminado la carrera (cruzado la meta) Info
IS_RES Reproductor de resultar adjudicado, confirmó acabado Info
IS_REO Reordenar parrilla de salida Tanto
de Autocross
IS_AXI Autocross de diseño cargado Info
IS_AXO Jugador golpea de autocross objeto Info
IS_OCO puede utilizarse para reemplazar específicos o todas las luces de arranque Instrucción
IS_UCO envía información sobre puntos de control y círculos InSim Info
Seguimiento de Coches
IS_NLP Jugadores posición actual del nodo, vuelta y carrera Info
IS_MCI Versión más detallada de IS_NLP, coordenadas del mundo, velocidad, ángulo y rumbo Info
Control de Cámara
IS_SCC Configure el automóvil visto y seleccione la cámara Instrucción
IS_CPP Set completo de la posición de la cámara Enseñanza
Control de Reproducción
IS_RIP Carga de reproducción y pasar a destino específico Enseñanza
Capturas de pantalla
IS_SSH Tomar una captura de pantalla Enseñanza
InSim Botones
IS_BFN Eliminar un botón o todos los botones Enseñanza
IS_BTN Enviar un botón a la pantalla de la Instrucción
IS_BTC Enviado cuando hace clic en un botón Info
IS_BTT Enviado cuando se escribe texto Info

Deja una respuesta

Tu dirección de correo electrónico no será publicada.