InSim
InSim este un protocol care permite unui program extern să comunice cu Live for Speed. Vă permite să creați o conexiune socket cu jocul și să trimiteți și să primiți pachete de date. Protocolul InSim descrie modul în care fiecare dintre aceste pachete este formatat și orice limbaj de programare care poate crea o conexiune la rețea și trimite și primi șiruri de date binare poate interfața cu acesta.
documentația oficială este inclusă în fișierul InSim.txt, găsit în folderul Jocuri doc. Se compune dintr-un fișier antet C++ care conține definiția pentru fiecare pachet, precum și comentarii de la Scawen cu privire la modul în care fiecare ar trebui să fie utilizat. Documentația de aici este destinată ca un accesoriu la acest fișier.
UDP vs TCP
InSim acceptă atât conexiuni UDP și TCP. În modul UDP se poate face o singură conexiune, cu toate acestea până la opt conexiuni pot fi făcute la joc în TCP. Indiferent dacă este conectat în TCP sau UDP, este posibil să specificați un soclu UDP separat pentru primirea actualizărilor poziției mașinii, cum ar fi IS_MCI și IS_NLP.
exemplu InSim
modul în care creați o conexiune InSim depinde desigur de limbajul de programare pe care îl utilizați, dar aici facem o încercare de a documenta procesul cu câteva exemple din popularul limbaj de programare Python. După cum sa menționat mai sus, orice limbă capabilă să realizeze o conexiune socket poate fi utilizată pentru a interfața cu LFS, totuși principiul rămâne același indiferent.
crearea unei conexiuni
în primul rând trebuie să stabilim o conexiune socket cu jocul, în acest caz în 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))
inițializarea InSim
după stabilirea conexiunii trebuie să inițializăm sistemul InSim prin trimiterea pachetului IS_ISI. Înainte de a putea face acest lucru, totuși, trebuie mai întâi să intitailse InSim în cadrul LFS în sine. Pentru a face acest lucru, începeți jocul și introduceți comanda de chat „/insim 29999”. Numărul portului utilizat poate fi orice port valid, dar 29999 tinde în general să fie implicit acceptat.
iată definiția pachetului IS_ISI de la 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};
fiecare pachet InSim începe cu un antet, format din 4 octeți. Primul octet este dimensiunea pachetului, urmat de tipul de pachet din enumerarea ISP_ și apoi ReqI (în picioare pentru ID-ul cererii). Ori de câte ori se face o cerere către LFS, valoarea ReqI trebuie setată la zero, prin care LFS va răspunde cu aceeași valoare setată în reqi a pachetului solicitat. În cele din urmă, al patrulea octet variază în funcție de tipul de pachet în cauză, care în acest caz este gol.
după cum puteți vedea pachetul IS_ISI conține diferite opțiuni și steaguri care sunt utilizate la inițializarea sistemului InSim. Trebuie să împachetăm aceste date într-un șir formatat binar pentru a le trimite la 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)
primirea datelor
după crearea conexiunii și inițializarea InSim, trebuie să configurăm bucla de primire a pachetului. Deoarece datele în modul TCP sunt trimise ca un flux constant de date, mai multe pachete pot ajunge într-un singur apel de primire și unele pachete pot ajunge incomplete. Aceasta înseamnă că trebuie să stocăm toate datele primite într-un tampon și apoi să citim fiecare pachet când suntem siguri că este complet.
# 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()
despachetarea pachetelor
odată ce am primit datele de pachete ca șir formatat binar, trebuie să despachetăm aceste date într-un format care ne este util. În exemplul nostru anterior când am trimis pachetul de inițializare IS_ISI, am setat ReqI la zero, ceea ce înseamnă că LFS a răspuns cu un pachet de versiune IS_VER, cu toate acestea nu am făcut nimic cu el. În primul rând vă permite să se uite la definiția pentru pachetul IS_VER de la 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};
acum să ne uităm la modul în care am despacheta aceste date în 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
pentru a menține conexiunea deschisă, LFS va trimite un pachet „keep alive” la fiecare 30 de secunde. Acest pachet este un IS_TINY cu un SubT (sub-Tip) de TINY_NONE. Trebuie să răspundem la acest pachet de fiecare dată când este primit pentru a împiedica sincronizarea conexiunii cu InSim.
# 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)
alte exemple
puteți vedea exemplul complet al acestui cod, precum și altele pe pagina de exemple InSim.
biblioteci InSim
desigur, așa cum spune vechea zicală, nu ar trebui să încercați să reinventați roata (cu excepția cazului în care încercați să aflați mai multe despre roți) și există mai multe biblioteci InSim mature disponibile pentru utilizare în propriul cod.
bibliotecile InSim | ||||
---|---|---|---|---|
Biblioteca | platformă | Licență | web | |
LFSLib | . NET Framework | GPL | pagina proiectului | |
LFS_External | .Cadru NET | Freeware | fir lfsforum | |
JInSim | Java | Mozilla | fir lfsforum | |
pyinsim | Python | LGPL | fir lfsforum | |
CInSim | C / C++ | Freeware | fir lfsforum | |
phplfs | PHP5 | licență Apache V2. 0 | pagina proiectului | |
PRISM | PHP7 | MIT | secțiunea lfsforum | |
InSim.NET | . NET Framework | LGPL | fir lfsforum |
referința InSim
Iată o încercare de a face referire la Protocolul InSim complet.
pachet de referință | ||
---|---|---|
pachet | descriere | Tip |
inițializare | ||
IS_ISI | inițializare InSim | instrucțiuni |
scop General | ||
IS_TINY | uz General pachet de 4 octeți | ambele |
IS_SMALL | scop general 8 octet pachet | ambele |
cerere versiune | ||
IS_VER | informații despre versiune | informatii |
raportarea și cererile de Stat | ||
IS_STA | trimis ori de câte ori starea jocului se schimbă | Info |
IS_SFP | Trimite pentru a seta diferite opțiuni de stare | instrucțiuni |
modul ecran | ||
IS_MOD | Trimite pentru a schimba modul ecran | instrucțiuni |
mesaje Text și apăsări de taste | ||
IS_MSO | Mesaje de sistem și utilizator trimise de la LFS | Info |
IS_III | mesaje utilizator pentru a găzdui InSim | Info |
IS_MST | trimite LFS un mesaj sau o comandă (64 caractere) | instrucțiuni |
IS_MSX | versiune extinsă a IS_MST (96 caractere), nu pentru comenzi | instrucțiuni |
IS_MSL | trimite un mesaj la client de joc local | instrucțiuni |
IS_MTC | trimite un mesaj la conexiune specifică sau jucător | instrucțiuni |
IS_SCH | trimite un singur caracter sau apăsați tasta | instrucțiuni |
notificare Multiplayer | ||
IS_ISM | trimis la pornirea sau aderarea la o gazdă | Info |
IS_NCI | trimis când este setată parola de administrator gazdă, conține date IP și Limbă utilizator | Info |
votează Notificarea | ||
IS_VTN | notificați votul jucătorului (reporniți cursa, calificați etc..) | Info |
urmărirea cursei | ||
IS_RST | Cursa de pornire sau repornire | Info |
IS_NCN | conectare nouă server de conectare | Info |
IS_SLC | pentru a raporta modificările în starea mașinii (în prezent porni sau opri) | Info |
IS_CSC | raportează mașina selectată curent a unei conexiuni | Info |
IS_CNL | conexiune server stânga | Info |
IS_CPR | jucător schimbat numele | Info |
IS_NPL | jucător nou care se alătură cursei sau iese din gropi | Info |
IS_PLP | gropi jucător(plecat la ecran garaj) | Info |
IS_PLL | jucător stânga rasă(plecat la spectate) | Info |
IS_CRS | Resetare mașină(bara de spațiu apăsată) | Info |
IS_JRR | poate fi folosit pentru a reseta sau porni o mașină într-o locație specificată | instrucțiune |
IS_LAP | timp tur finalizat | Info |
IS_SPX | timp divizat finalizat | Info |
IS_PIT | Pit stop a început (la pit box) | Info |
IS_PSF | Pit stop terminat | Info |
IS_PLA | jucător intrat pit lane(la groapă sau servi penalizare) | Info |
IS_CHH | vizualizarea camerei a fost modificată (vizualizare chase, vizualizare personalizată etc..) | Info |
IS_PEN | penalizare dată sau lipită | Info |
IS_TOC | jucător preluat o altă mașină(schimb șofer) | Info |
IS_FLG | steagul afișat de jucător (galben sau albastru) | Info |
is_pfl | steaguri jucător schimbat (auto-unelte, auto-ambreiaj etc..) | Info |
IS_FIN | jucător terminat cursa(linia de sosire trecut) | Info |
IS_RES | rezultatul jucătorului acordat, final confirmat | Info |
IS_REO | reordonați grila de pornire | ambele |
Autocross | ||
IS_AXI | Autocross layout încărcat | Info |
IS_AXO | jucător lovit autocross obiect | Info |
IS_OCO | poate fi utilizat pentru a înlocui anumite sau toate luminile de pornire | instrucțiuni |
IS_UCO | trimite informații despre punctele de control și cercurile InSim | Info |
urmărirea mașinii | ||
IS_NLP | jucători curent nod, tur și poziția cursa | Info |
IS_MCI | versiune mai detaliată a IS_NLP, lume-coordonate, viteza, unghiul și poziția | Info |
controlul camerei | ||
IS_SCC | setați mașina vizualizată și selectați camera | instrucțiuni |
IS_CPP | setați poziția completă a camerei | instrucțiuni |
controlul reluării | ||
IS_RIP | încărcați reluarea și mutați la destinație specifică | instrucțiuni |
imagini | ||
IS_SSH | faceți o captură de ecran | instrucțiune |
butoane InSim | ||
Is_bfn | ștergeți un buton sau toate butoanele | instrucțiuni |
IS_BTN | trimite un buton pe ecran | instrucțiuni |
IS_BTC | trimis când se face clic pe un buton | Info |
IS_BTT | trimis la introducerea textului | Info |