InSim

InSim

InSim est un protocole qui permet à un programme externe de communiquer avec Live pour plus de vitesse. Il vous permet de créer une connexion socket avec le jeu et d’envoyer et de recevoir des paquets de données. Le protocole InSim décrit comment chacun de ces paquets est formaté, et tout langage de programmation capable de créer une connexion réseau et d’envoyer et de recevoir des chaînes de données binaires peut s’interfacer avec lui.

La documentation officielle est incluse dans le fichier InSim.txt, trouvé dans le dossier doc des jeux. Il se compose d’un fichier d’en-tête C++ qui contient la définition de chaque paquet, ainsi que des commentaires de Scawen sur la façon dont chacun doit être utilisé. La documentation ici est conçue comme un accessoire à ce fichier.

UDP vs TCP

InSim prend en charge les connexions UDP et TCP. En mode UDP, une seule connexion peut être établie, mais jusqu’à huit connexions peuvent être effectuées au jeu en TCP. Qu’il soit connecté en TCP ou en UDP, il est possible de spécifier un socket UDP distinct pour recevoir les mises à jour de position de la voiture, telles que IS_MCI et IS_NLP.

Exemple d’InHim

La façon dont vous créez une connexion InHim dépend bien sûr du langage de programmation que vous utilisez, mais nous essayons ici de documenter le processus avec quelques exemples du langage de programmation Python populaire. Comme mentionné ci-dessus, tout langage capable d’établir une connexion socket peut être utilisé pour s’interfacer avec LFS, mais le principe reste le même malgré tout.

Création d’une connexion

Tout d’abord, il faut établir une connexion socket avec le jeu, dans ce cas 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))

Initialisation d’InSim

Après avoir établi la connexion, nous devons initialiser le système InSim en envoyant le paquet IS_ISI. Avant de pouvoir le faire, nous devons d’abord intituler InSim au sein de l’EPA elle-même. Pour ce faire, démarrez le jeu et entrez la commande de chat « /insim 29999 ». Le numéro de port utilisé peut être n’importe quel port valide, mais 29999 a généralement tendance à être la valeur par défaut acceptée.

Voici la définition du paquet IS_ISI d’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};

Chaque paquet InSim commence par un en-tête, composé de 4 octets. Le premier octet est la taille du paquet, suivi du type de paquet de l’énumération ISP_, puis du ReqI (pour Request Id). Chaque fois qu’une demande est faite à LFS, la valeur du ReqI doit être définie sur non nulle, LFS répondra avec la même valeur définie dans le ReqI du paquet demandé. Enfin le quatrième octet varie en fonction du type de paquet considéré, qui dans ce cas est vide.

Comme vous pouvez le voir, le paquet IS_ISI contient diverses options et indicateurs utilisés lors de l’initialisation du système InSim. Nous devons emballer ces données dans une chaîne au format binaire pour les envoyer à 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)

Réception des données

Après avoir créé la connexion et initialisé InSim, nous devons ensuite configurer la boucle de réception des paquets. Comme les données en mode TCP sont envoyées sous la forme d’un flux constant de données, plusieurs paquets peuvent arriver en un seul appel de réception et certains paquets peuvent arriver incomplets. Cela signifie que nous devons stocker toutes les données entrantes dans un tampon, puis lire chaque paquet lorsque nous sommes sûrs qu’il est terminé.

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

Déballage des paquets

Une fois que nous avons reçu les données du paquet sous forme de chaîne au format binaire, nous devons ensuite décompresser ces données dans un format qui nous est utile. Dans notre exemple précédent, lorsque nous avons envoyé le paquet d’initialisation IS_ISI, nous avons défini le ReqI sur non nul, ce qui signifie que LFS a répondu avec un paquet de version IS_VER, mais nous n’avons rien fait avec. Regardons d’abord la définition du paquet IS_VER d’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};

Voyons maintenant comment nous décompresserions ces données 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

Afin de garder la connexion ouverte, LFS enverra un paquet « keep alive » toutes les 30 secondes environ. Ce paquet est un IS_TINY avec un SubT (sous-type) de TINY_NONE. Nous devons répondre à ce paquet chaque fois qu’il est reçu afin d’empêcher la connexion avec InSim de s’arrêter.

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

Autres exemples

Vous pouvez voir l’exemple complet de ce code ainsi que d’autres sur la page exemples d’InSim.

Bibliothèques InSim

Bien sûr, comme le dit le vieil adage, vous ne devriez pas essayer de réinventer la roue (sauf si vous essayez d’en savoir plus sur les roues) et plusieurs bibliothèques InSim matures sont disponibles pour être utilisées dans votre propre code.

Bibliothèques InSim
Bibliothèque Plateforme Licence web
LFSLib .NET Framework GPL page du projet
LFS_External .NET Framework Freeware thread lfsforum
JInSim Java Mozilla thread lfsforum
pyinsim Python LGPL fil lfsforum
CInSim C/C++ Freeware thread lfsforum
phplfs PHP5 Licence Apache V2.0 page du projet
PRISME PHP7 MIT section lfsforum
InSim.NET .NET Framework LGPL thread lfsforum

Référence InSim

Voici une tentative de référence du protocole InSim complet.

Référence de Paquet
Paquet Description Type
Initialisation
IS_ISI Initialisation d’InSim Instruction
Usage Général
IS_TINY Paquet de 4 octets à usage général Les deux
IS_SMALL Paquet de 8 octets à usage général Les deux
Demande de version
IS_VER Informations sur la version Info
Rapports et demandes des États
IS_STA Envoyé chaque fois que l’état du jeu change Info
IS_SFP Envoyer pour définir diverses options d’état Instruction
Mode Écran
IS_MOD Envoyer pour changer de mode d’écran Instruction
Messages Texte et Pressions sur les Touches
IS_MSO Messages système et utilisateur envoyés depuis LFS Info
IS_III Messages de l’utilisateur à héberger InSim Info
IS_MST Envoyer un message ou une commande LFS (64 caractères) Instruction
IS_MSX Version étendue d’IS_MST (96 caractères), pas pour les commandes Instruction
IS_MSL Envoyer un message au client de jeu local Instruction
IS_MTC Envoyer un message à une connexion ou un lecteur spécifique Instruction
IS_SCH Envoyer un seul caractère ou appuyer sur une touche Instruction
Notification Multijoueur
IS_ISM Envoyé lors du démarrage ou de la jonction d’un hôte Info
IS_NCI Envoyé lorsque le mot de passe administrateur de l’hôte est défini, contient l’adresse IP de l’utilisateur et les données de langue Info
Vote Notifier
IS_VTN Notifier le vote du joueur (redémarrer la course, se qualifier, etc..) Info
Suivi de Course
IS_RST Départ ou redémarrage de la course Info
IS_NCN Nouvelle connexion serveur de connexion Info
IS_SLC pour signaler les changements dans l’état de la voiture (actuellement démarrer ou arrêter) Info
IS_CSC signale la voiture actuellement sélectionnée par une connexion Info
IS_CNL Connexion serveur gauche Info
IS_CPR Nom du joueur changé Info
IS_NPL Nouveau joueur rejoignant la course ou quittant les stands Info
IS_PLP Fosses des joueurs (passé à l’écran du garage) Info
IS_PLL Joueur à gauche de la course (parti au spectateur) Info
IS_CRS Réinitialisation de la voiture (barre d’espace enfoncée) Info
IS_JRR peut être utilisé pour réinitialiser ou démarrer une voiture à un emplacement spécifié Instruction
IS_LAP Temps au tour terminé Info
IS_SPX Temps partiel terminé Info
IS_PIT Départ de l’arrêt au stand (au stand) Info
IS_PSF Arrêt au stand terminé Info
IS_PLA Le joueur est entré dans la voie des stands (pour piter ou purger une pénalité) Info
IS_CHH Vue de la caméra modifiée (vue de chasse, vue personnalisée, etc..) Info
IS_PEN Pénalité infligée ou cadenassée Info
IS_TOC Joueur repris une autre voiture (échange de conducteur) Info
IS_FLG Drapeau du joueur (jaune ou bleu) Info
IS_PFL Drapeaux du lecteur changés (engrenages automatiques, embrayage automatique, etc..) Info
IS_FIN Course terminée par le joueur (ligne d’arrivée franchie) Info
IS_RES Résultat du joueur attribué, finition confirmée Info
IS_REO Réorganiser la grille de départ Les deux
Autocross
IS_AXI Mise en page autocross chargée Info
IS_AXO Objet autocross atteint par le joueur Info
IS_OCO peut être utilisé pour remplacer des tous les feux de démarrage Instruction
IS_UCO envoie des informations sur les points de contrôle et les cercles InSim Info
Suivi De Voiture
IS_NLP Joueurs nœud actuel, tour et position de course Info
IS_MCI Version plus détaillée de IS_NLP, coordonnées du monde, vitesse, angle et cap Info
Contrôle de la Caméra
IS_SCC Réglez la voiture vue et sélectionnez la caméra Instruction
IS_CPP Régler la position complète de la caméra Instruction
Contrôle de Relecture
IS_RIP Charge la relecture et se déplace vers une destination spécifique Instruction
Captures d’écran
IS_SSH Prendre une capture d’écran Instruction
Boutons InSim
IS_BFN Supprimer un bouton ou tous les boutons Instruction
IS_BTN Envoyer un bouton à l’écran Instruction
IS_BTC Envoyé lorsqu’un bouton est cliqué Info
IS_BTT Envoyé lorsque le texte est entré Info

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.