InSim
InSim is een protocol waarmee een extern programma kan communiceren met Live For Speed. Hiermee kunt u een socket verbinding met het spel te maken en te verzenden en te ontvangen pakketten met gegevens. Het InSim-protocol beschrijft hoe elk van deze pakketten wordt geformatteerd, en elke programmeertaal die een netwerkverbinding kan maken en reeksen binaire gegevens kan verzenden en ontvangen, kan ermee communiceren.
de officiële documentatie is opgenomen in het bestand InSim.txt, gevonden in de games doc map. Het bestaat uit Een C++ header bestand dat de definitie voor elk pakket bevat, evenals opmerkingen van Scawen over hoe elk zou moeten worden gebruikt. De documentatie hier is bedoeld als een aanvulling op dit bestand.
UDP vs TCP
InSim ondersteunt zowel UDP-als TCP-verbindingen. In UDP modus kan slechts een enkele verbinding gemaakt worden, maar er kunnen wel acht verbindingen gemaakt worden met het spel in TCP. Of het nu verbonden is in TCP of UDP, het is mogelijk om een aparte UDP-socket op te geven voor het ontvangen van auto positie-updates, zoals IS_MCI en IS_NLP.
InSim voorbeeld
hoe u een InSim verbinding maakt is natuurlijk afhankelijk van welke programmeertaal u gebruikt, maar hier proberen we het proces te documenteren met enkele voorbeelden uit de populaire programmeertaal Python. Zoals hierboven vermeld kan elke taal die een socket verbinding kan maken worden gebruikt om te communiceren met LFS, maar het principe blijft hetzelfde ongeacht.
een verbinding maken
Allereerst moeten we een socket verbinding maken met het spel, in dit geval in 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))
initialiseren InSim
na het tot stand brengen van de verbinding moeten we het InSim-systeem initialiseren door het is_isi-pakket te verzenden. Voordat we dit echter kunnen doen, moeten we eerst InSim binnen de LFS zelf intitailse. Om dit te doen start het spel en voer het chat Commando “/insim 29999”. Het gebruikte poortnummer kan elke geldige poort zijn, maar 29999 is over het algemeen de geaccepteerde standaard.
hier is de definitie voor het is_isi-pakket van 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};
elk InSim-pakket begint met een header, bestaande uit 4 bytes. De eerste byte is de grootte van het pakket, gevolgd door het pakkettype uit de ISP_ enumeration, en dan de ReqI (staat voor Request Id). Wanneer een verzoek wordt gedaan aan LFS moet de waarde van de ReqI worden ingesteld op niet-nul, waarbij LFS zal antwoorden met dezelfde waarde die is ingesteld in de ReqI van het gevraagde pakket. Ten slotte varieert de vierde byte afhankelijk van het type pakket in kwestie, die in dit geval leeg is.
zoals u kunt zien bevat het is_isi-pakket verschillende opties en vlaggen die worden gebruikt bij het initialiseren van het InSim-systeem. We moeten deze gegevens verpakken in een binaire opgemaakte string om het naar LFS te sturen.
# 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)
data ontvangen
na het maken van de verbinding en het initialiseren van InSim moeten we dan de packet receive loop instellen. Aangezien gegevens in de TCP-modus worden verzonden als een constante stroom van gegevens, kunnen meerdere pakketten aankomen in een enkele receive call en sommige pakketten kunnen onvolledig aankomen. Dit betekent dat we alle inkomende gegevens in een buffer moeten opslaan en dan elk pakket moeten uitlezen als we zeker zijn dat het compleet is.
# 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()
pakketten uitpakken
zodra we de pakketgegevens als een binaire opgemaakte string hebben ontvangen, moeten we deze gegevens uitpakken in een formaat dat nuttig is voor ons. In ons vorige voorbeeld toen we het is_isi initailisation pakket stuurden, zetten we de ReqI op niet-nul, wat betekent dat LFS reageerde met een is_ver versie pakket, maar we hebben er niets mee gedaan. Laten we eerst kijken naar de definitie voor het is_ver pakket van 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};
laten we nu eens kijken hoe we die gegevens in Python zouden uitpakken.
# 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
om de verbinding open te houden zal LFS elke 30 seconden een “keep alive” – pakket sturen. Dit pakket is een IS_TINY met een SubT (subtype) van TINY_NONE. We moeten op dit pakket reageren elke keer dat het wordt ontvangen om te voorkomen dat de verbinding met InSim van timing-out.
# 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)
verdere voorbeelden
u kunt het volledige voorbeeld van deze code evenals andere zien op de InSim-voorbeeldpagina.
InSim Libraries
natuurlijk, zoals het oude gezegde luidt, moet u niet proberen het wiel opnieuw uit te vinden (tenzij u meer wilt weten over wielen) en er zijn verschillende volwassen InSim libraries beschikbaar voor gebruik in uw eigen code.
InSim Bibliotheken | ||||
---|---|---|---|---|
Bibliotheek | Platform | Licentie | web | |
LFSLib | .NET Framework | GPL | project pagina | |
LFS_External | .NET Framework | Freeware | lfsforum draad | |
JInSim | Java | Mozilla | lfsforum draad | |
pyinsim | Python | LGPL | lfsforum draad | |
CInSim | C/C++ | Freeware | lfsforum draad | |
phplfs | PHP5 | Apache License V2.0 | project pagina | |
PRISM | PHP7 | MIT | lfsforum sectie | |
InSim.NET | . NET Framework | LGPL | lfsforum thread |
InSim referentie
hier is een poging om te verwijzen naar het volledige InSim protocol.
Packet-Verwijzing | ||
---|---|---|
Pakket | Beschrijving | Type |
Initialisatie | ||
IS_ISI | InSim initialisatie | Instructie |
Algemeen Doel | ||
IS_TINY | Algemene doel 4 byte pakket | Beide |
IS_SMALL | Algemene doel 8 byte pakket | Beide |
Versie aanvraag | ||
IS_VER | Versie-informatie | Info |
Staat Rapporteren en Verzoeken | ||
IS_STA | Verzonden wanneer het spel staat wijzigingen | Info |
IS_SFP | Verzenden om de diverse state-opties | Instructie |
Scherm-Modus | ||
IS_MOD | Stuur wijzigen scherm modus | Instructie |
Sms-Berichten en toetsaanslagen | ||
IS_MSO | Systeem-en gebruikers-berichten verzonden vanuit LFS | Info |
IS_III | Gebruiker berichten te hosten InSim | Info |
IS_MST | Stuur LFS een boodschap of opdracht (64 tekens) | Instructie |
IS_MSX | Uitgebreide versie van IS_MST (96 tekens), niet voor commando ‘ s | Instructie |
IS_MSL | bericht Verzenden naar de lokale game client | Instructie |
IS_MTC | bericht Verzenden naar specifieke verbinding of speler | Instructie |
IS_SCH | Verzenden van één enkel karakter of toets druk op | Instructie |
Multiplayer Melding | ||
IS_ISM | Verzonden bij het starten of lid worden van een host | Info |
IS_NCI | Verzonden wanneer de host admin-wachtwoord is ingesteld, bevat door de gebruiker IP-en taal-gegevens | Info |
Stem de Hoogte | ||
IS_VTN | de Hoogte van speler stemmen (restart race, in aanmerking komen enz..) | Info |
Race Bijhouden | ||
IS_RST | Race starten of herstarten | Info |
IS_NCN | Nieuwe verbinding joining server | Info |
IS_SLC | om de wijzigingen op in de auto staat (op dit moment starten of stoppen) | Info |
IS_CSC | rapporten een verbinding is momenteel geselecteerde auto | Info |
IS_CNL | Verbinding links server | Info |
IS_CPR | Speler van naam veranderd | Info |
IS_NPL | Nieuwe speler die aan de race, of het verlaten van putten | Info |
IS_PLP | Speler putten (weg naar de garage scherm) | Info |
IS_PLL | Speler links race (weg naar toeschouwer) | Info |
IS_CRS | Auto reset (ingedrukt ruimte bar) | Info |
IS_JRR | kan worden gebruikt voor het herstellen of het starten van een auto bij een opgegeven locatie | Instructie |
IS_LAP | Rondetijd is voltooid | Info |
IS_SPX | Split time ingevuld | Info |
IS_PIT | Pitstop gestart (in pitbox) | Info |
IS_PSF | Pitstop klaar | Info |
IS_PLA | Speler ingevoerd pit lane (pit of dienen boete) | Info |
IS_CHH | bekijk de Camera veranderd (chase weergave, aangepaste weergave enz..) | Info |
IS_PEN | Penalty gegeven of cleated | Info |
IS_TOC | Speler overgenomen van een andere auto (bestuurder swap) | Info |
IS_FLG | Speler die vlag (geel of blauw) | Info |
IS_PFL | Speler vlaggen veranderd (auto-versnellingen, automatische koppeling, etc..) | Info |
IS_FIN | Speler klaar race (finish) | Info |
IS_RES | Speler resultaat toegekend, bevestigd finish | Info |
IS_REO | de Volgorde van starting grid | Beide |
Autocross | ||
IS_AXI | Autocross lay-out geladen | Info |
IS_AXO | Speler hit autocross object | Info |
IS_OCO | kan worden gebruikt voor het overschrijven van specifieke of alle startlichten | Instructie |
IS_UCO | stuurt info over InSim checkpoints en cirkels | Info |
Auto Volgen | ||
IS_NLP | Spelers van de huidige knoop, ronde en race positie | Info |
IS_MCI | Meer gedetailleerde versie van IS_NLP, wereld-coördinaten, snelheid, hoek en richting | Info |
Camera Control | ||
IS_SCC | Set bekeken auto en selecteer camera | Instructie |
IS_CPP | volledige camera positie | Instructie |
Replay Controle | ||
IS_RIP | Laden van de replay en verplaatsen naar een specifieke bestemming | Instructie |
Screenshots | ||
IS_SSH | een schermafbeelding maken | Instructie |
InSim Knoppen | ||
IS_BFN | Verwijderen van een knop of alle knoppen | Instructie |
IS_BTN | Verzenden-knop om het scherm | Instructie |
IS_BTC | verzonden wanneer op een knop wordt geklikt | Info |
IS_BTT | verzonden wanneer tekst wordt ingevoerd | Info |