InSim
InSim är ett protokoll som tillåter ett externt program för att kommunicera med Live For Speed. Det låter dig skapa en socket-anslutning med spelet och skicka och ta emot paket med data. InSim-protokollet beskriver hur vart och ett av dessa paket formateras, och alla programmeringsspråk som kan skapa en nätverksanslutning och skicka och ta emot strängar av binär data kan samverka med det.
den officiella dokumentationen ingår i filen InSim.txt, finns i mappen Spel doc. Den består av en C++ header-fil som innehåller definitionen för varje paket, samt kommentarer från Scawen om hur varje ska användas. Dokumentationen här är avsedd som ett tillägg till den här filen.
UDP vs TCP
InSim stöder både UDP-och TCP-anslutningar. I UDP-läge kan endast en enda anslutning göras, men upp till åtta anslutningar kan göras till spelet i TCP. Oavsett om det är anslutet i TCP eller UDP är det möjligt att ange ett separat UDP-uttag för att ta emot bilpositionsuppdateringar, till exempel IS_MCI och IS_NLP.
InSim exempel
hur du går om att skapa en InSim-anslutning är naturligtvis beroende av vilket programmeringsspråk du använder, men här gör vi ett försök att dokumentera processen med några exempel från det populära Python-programmeringsspråket. Som nämnts ovan kan alla språk som kan göra en uttagsanslutning användas för att samverka med LFS, men principen förblir densamma oavsett.
skapa en anslutning
först och främst måste vi upprätta en socket-anslutning med spelet, i detta fall i 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))
initiera InSim
efter att ha upprättat anslutningen måste vi initiera InSim-systemet genom att skicka IS_ISI-paketet. Innan vi kan göra detta måste vi dock först intitailse InSim inom LFS själv. För att göra detta starta spelet och ange chattkommandot ”/insim 29999”. Portnumret som används kan vara vilken giltig port som helst, men 29999 tenderar i allmänhet att vara den accepterade standard.
här är definitionen för is_isi-paketet från 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};
varje InSim-paket börjar med en rubrik som består av 4 byte. Den första byten är paketets storlek, följt av pakettypen från isp_-uppräkningen och sedan ReqI (står för Request Id). När en begäran görs till aku måste värdet på ReqI ställas in till icke-noll, varvid aku kommer att svara med samma värde som anges i ReqI för det begärda paketet. Slutligen varierar den fjärde byten beroende på typen av paket i fråga, vilket i detta fall är tomt.
som du kan se innehåller IS_ISI-paketet olika alternativ och flaggor som används vid initiering av InSim-systemet. Vi måste packa dessa data i en binär formaterad sträng för att skicka den till 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)
ta emot Data
när du har skapat anslutningen och initialiserat InSim måste vi sedan ställa in paketmottagningsslingan. Eftersom data i TCP-läge skickas som en konstant ström av data kan flera paket komma fram i ett enda mottagningssamtal och vissa paket kan komma ofullständiga. Det betyder att vi måste lagra all inkommande data i en buffert och sedan läsa ut varje paket när vi är säkra på att det är klart.
# 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()
packa upp paket
när vi har fått paketdata som en binär formaterad sträng måste vi sedan packa upp dessa data till ett format som är användbart för oss. I vårt tidigare exempel när vi skickade is_isi initailisation-paketet satte vi ReqI till icke-noll, vilket innebär att LFS svarade med ett IS_VER-versionspaket, men vi gjorde ingenting med det. För det första kan vi titta på definitionen för IS_VER-paketet från 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};
nu kan vi titta på hur vi skulle packa upp data i 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
för att hålla anslutningen öppen kommer LFS att skicka ett ”keep alive” – paket var 30: e sekund. Detta paket är en IS_TINY med en SubT (subtyp) av TINY_NONE. Vi måste svara på detta paket varje gång det tas emot för att förhindra att anslutningen till InSim tas ut.
# 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)
ytterligare exempel
du kan se det fullständiga exemplet på denna kod såväl som andra på InSim-exempelsidan.
InSim-Bibliotek
naturligtvis som det gamla ordspråket går bör du inte försöka återuppfinna hjulet (om du inte försöker lära dig mer om hjul) och det finns flera mogna InSim-bibliotek tillgängliga för användning i din egen kod.
InSim-Bibliotek | ||||
---|---|---|---|---|
Bibliotek | plattform | licens | webb | |
LFSLib | . Net Framework | GPL | projektsida | |
LFS_External | .NET Framework | gratisprogram | lfsforum tråd | |
JInSim | Java | Mozilla | lfsforum tråd | |
pyinsim | Python | LGPL | lfsforum tråd | |
CInSim | C / C++ | gratisprogram | lfsforum tråd | |
phplfs | PHP5 | Apache licens V2.0 | projektsida | |
prisma | PHP7 | MIT | lfsforum avsnitt | |
InSim.NET Framework | . Net Framework | LGPL | lfsforum tråd |
InSim-referens
här är ett försök att referera till hela InSim-protokollet.
Paketreferens | ||
---|---|---|
paket | beskrivning | Typ |
initialisering | ||
IS_ISI | initiering av InSim | instruktion |
allmänt ändamål | ||
IS_TINY | allmänt ändamål 4 byte paket | båda |
IS_SMALL | allmänt ändamål 8 byte paket | båda |
begäran om Version | ||
IS_VER | versionsinformation | Info |
Statlig rapportering och förfrågningar | ||
Is_sta | skickas när speltillståndet ändras | Info |
IS_SFP | Skicka för att ställa in olika tillståndsalternativ | instruktion |
skärmläge | ||
IS_MOD | Skicka för att ändra skärmläge | instruktion |
textmeddelanden och knapptryckningar | ||
IS_MSO | System-och användarmeddelanden skickade från aku | Info |
IS_III | användarmeddelanden till värd InSim | Info |
IS_MST | skicka LFS ett meddelande eller kommando (64 tecken) | instruktion |
IS_MSX | utökad version av IS_MST (96 tecken), inte för kommandon | instruktion |
IS_MSL | Skicka meddelande till lokal spelklient | instruktion |
IS_MTC | Skicka meddelande till specifik anslutning eller spelare | instruktion |
IS_SCH | skicka enstaka tecken eller knapptryckning | instruktion |
Multiplayer anmälan | ||
Is_ism | skickas när du startar eller går med i en värd | Info |
IS_NCI | skickas när värd admin lösenord är inställd, innehåller användar IP och språkdata | Info |
rösta meddela | ||
IS_VTN | meddela om spelarens Röst(Starta om race, kvalificera etc..) | Info |
Race Tracking | ||
IS_RST | Race startar eller startar om | Info |
IS_NCN | ny anslutning ansluter server | Info |
IS_SLC | för att rapportera ändringar i bilstatus (för närvarande starta eller stoppa) | Info |
IS_CSC | rapporterar en anslutnings valda bil | Info |
IS_CNL | anslutning vänster server | Info |
IS_CPR | spelare bytt namn | Info |
IS_NPL | ny spelare gå race, eller lämnar gropar | Info |
IS_PLP | spelar gropar (gått till garage skärm) | Info |
IS_PLL | spelare vänster race (gått till åskådare) | Info |
IS_CRS | bilåterställning (tryckt mellanslag) | Info |
IS_JRR | kan användas för att återställa eller starta en bil på en viss plats | instruktion |
IS_LAP | varvtid avslutad | Info |
IS_SPX | delad tid avslutad | Info |
IS_PIT | Pit stop startade (vid pit box) | Info |
IS_PSF | depåstopp färdig | Info |
IS_PLA | spelaren gick in i gropbanan (för att gropa eller tjäna straff) | Info |
IS_CHH | kameravyn ändras(chase view, anpassad vy etc..) | Info |
IS_PEN | straff ges eller klyvs | Info |
IS_TOC | spelare tagit över en annan bil (förare swap) | Info |
is_flg | spelare som visas flagga (gul eller blå) | Info |
IS_PFL | Spelarflaggor ändras(auto-växlar, auto-koppling etc..) | Info |
IS_FIN | spelare avslutat lopp (korsad mållinje) | Info |
IS_RES | Spelarresultat tilldelas, bekräftad finish | Info |
IS_REO | ordna om startnätet | båda |
Autocross | ||
IS_AXI | autocross layout laddad | Info |
IS_AXO | spelare slå autocross objekt | Info |
IS_OCO | kan användas för att åsidosätta specifika eller alla startljus | instruktion |
IS_UCO | skickar information om InSim kontrollpunkter och cirklar | Info |
Bilspårning | ||
IS_NLP | spelare nuvarande nod, varv och race position | Info |
IS_MCI | mer detaljerad version av IS_NLP, världskoordinater, hastighet, vinkel och rubrik | Info |
kamera kontroll | ||
IS_SCC | Ställ in visad bil och välj kamera | instruktion |
IS_CPP | Ställ in fullständig kameraposition | instruktion |
Replay Control | ||
IS_RIP | ladda uppspelningen och flytta till en specifik destination | instruktion |
skärmbilder | ||
IS_SSH | ta en skärmdump | instruktion |
InSim knappar | ||
IS_BFN | ta bort en knapp eller alla knappar | instruktion |
IS_BTN | skicka en knapp till skärmen | instruktion |
IS_BTC | skickas när en knapp klickas | Info |
Is_btt | skickas när text skrivs in | Info |