InSim
InSim je protokol, který umožňuje externímu programu komunikovat s Live for Speed. To vám umožní vytvořit připojení socket s hrou a odesílat a přijímat pakety dat. Protokol InSim popisuje, jak je každý z těchto paketů formátován, a jakýkoli programovací jazyk, který může vytvořit síťové připojení a odesílat a přijímat řetězce binárních dat, se s ním může spojit.
oficiální dokumentace je součástí souboru InSim.txt, který se nachází ve složce hry doc. Skládá se z hlavičkového souboru C++, který obsahuje definici pro každý paket, stejně jako komentáře od Scawena, jak by měl být každý použit. Dokumentace zde je určena jako doplněk k tomuto souboru.
UDP vs TCP
InSim podporuje připojení UDP i TCP. V režimu UDP lze provést pouze jedno připojení, avšak v TCP lze do hry navázat až osm připojení. Ať už je připojen v TCP nebo UDP, je možné zadat samostatný UDP socket pro příjem aktualizací polohy vozu, například IS_MCI a IS_NLP.
příklad InSim
způsob vytváření připojení InSim samozřejmě závisí na tom, který programovací jazyk používáte, ale zde se pokusíme dokumentovat proces pomocí několika příkladů z populárního programovacího jazyka Python. Jak bylo uvedeno výše, jakýkoli jazyk schopný vytvořit připojení soketu může být použit pro rozhraní s LFS, nicméně princip zůstává stejný bez ohledu na to.
vytvoření připojení
nejprve musíme vytvořit soketové spojení s hrou, v tomto případě v 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))
inicializace InSim
po navázání spojení musíme inicializovat systém InSim zasláním paketu IS_ISI. Než to však můžeme udělat, musíme nejprve intitailse InSim v samotném LFS. Chcete-li to provést, spusťte hru a zadejte příkaz chatu „/ insim 29999“. Použité Číslo portu může být jakýkoli platný port, ale 29999 obvykle bývá akceptovaným výchozím nastavením.
zde je definice paketu IS_ISI od 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};
každý paket InSim začíná hlavičkou sestávající ze 4 bajtů. První bajt je velikost paketu, následovaný typem paketu z výčtu ISP_ a pak ReqI (standing for Request Id). Při každém požadavku na LFS musí být hodnota ReqI nastavena na nenulovou hodnotu, přičemž LFS odpoví stejnou hodnotou nastavenou v ReqI požadovaného paketu. Nakonec se čtvrtý bajt liší v závislosti na typu dotyčného paketu, který je v tomto případě prázdný.
jak vidíte, paket IS_ISI obsahuje různé možnosti a příznaky, které se používají při inicializaci systému InSim. Tato data musíme zabalit do binárního formátovaného řetězce a odeslat je do 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)
příjem dat
po vytvoření spojení a inicializaci InSim musíme nastavit smyčku pro příjem paketů. Vzhledem k tomu, že data v režimu TCP jsou odesílána jako konstantní tok dat, může při jednom přijímacím hovoru dorazit více paketů a některé pakety mohou dorazit neúplné. To znamená, že musíme uložit všechna příchozí data do vyrovnávací paměti a poté přečíst každý paket, když jsme si jisti, že je kompletní.
# 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()
rozbalení paketů
Jakmile obdržíme paketová data jako binární formátovaný řetězec, musíme tato data rozbalit do formátu, který je pro nás užitečný. V našem předchozím příkladu, když jsme odeslali initailisation paket IS_ISI, nastavili jsme ReqI na nenulovou hodnotu, což znamená, že LFS odpověděl paketem verze IS_VER, ale nic jsme s ním neudělali. Nejprve se podívejme na definici paketu IS_VER od 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};
nyní se podívejme, jak bychom tato data rozbalili v Pythonu.
# 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
aby bylo připojení otevřené, LFS pošle paket „keep alive“ každých 30 sekund. Tento paket je is_tiny s SubT (sub-type) TINY_NONE. Na tento paket musíme reagovat pokaždé, když je přijat, abychom zabránili načasování spojení s 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)
další příklady
úplný příklad tohoto kódu a další můžete vidět na stránce příklady InSim.
knihovny InSim
samozřejmě, jak říká staré pořekadlo, neměli byste se pokoušet znovu objevit kolo (pokud se nesnažíte dozvědět více o kolech) a existuje několik zralých knihoven InSim, které jsou k dispozici pro použití ve vašem vlastním kódu.
InSim knihovny | ||||
---|---|---|---|---|
Knihovna | platforma | Licence | web | |
LFSLib | . NET Framework | GPL | stránka projektu | |
LFS_External | .NET Framework | Freeware | lfsforum thread | |
JInSim | Java | Mozilla | lfsforum vlákno | |
pyinsim | Python | LGPL | lfsforum vlákno | |
CInSim | C / C++ | Freeware | lfsforum thread | |
phplfs | PHP5 | Apache License V2. 0 | stránka projektu | |
PRISM | PHP7 | MIT | lfsforum sekce | |
InSim.NET | . NET Framework | LGPL | lfsforum vlákno |
Insim Reference
zde je pokus o odkaz na kompletní protokol InSim.
odkaz na Paket | ||
---|---|---|
Paket | popis | Typ |
inicializace | ||
IS_ISI | inicializace InSim | instrukce |
obecný účel | ||
IS_TINY | General purpose 4 byte paket | oba |
IS_SMALL | General purpose 8 byte paket | oboje |
žádost o verzi | ||
IS_VER | informace o verzi | informace |
státní hlášení a žádosti | ||
IS_STA | odesláno vždy, když se změní stav hry | informace |
IS_SFP | Odeslat pro nastavení různých možností stavu | instrukce |
Režim obrazovky | ||
IS_MOD | Odeslat ke změně režimu obrazovky | instrukce |
textové zprávy a stisknutí kláves | ||
IS_MSO | systémové a uživatelské zprávy odeslané z LFS | informace |
IS_III | uživatelské zprávy hostiteli InSim | informace |
IS_MST | odeslat LFS zprávu nebo příkaz (64 znaků) | instrukce |
IS_MSX | rozšířená verze IS_MST (96 znaků), nikoli pro příkazy | instrukce |
IS_MSL | odeslat zprávu lokálnímu hernímu klientovi | instrukce |
IS_MTC | odeslat zprávu konkrétnímu připojení nebo přehrávači | instrukce |
IS_SCH | poslat jeden znak nebo stiskněte tlačítko | instrukce |
oznámení pro více hráčů | ||
IS_ISM | odesláno při spuštění nebo připojení k hostiteli | informace |
IS_NCI | odesláno při nastavení hesla správce hostitele, obsahuje uživatelská IP a jazyková data | informace |
Hlasujte | ||
IS_VTN | oznamte hlasování hráče (restartujte závod, Kvalifikujte se atd..) | informace |
sledování závodu | ||
IS_RST | Start nebo restart závodu | informace |
IS_NCN | nové připojení Připojovací server | informace |
IS_SLC | pro hlášení změn ve stavu vozu (aktuálně start nebo stop) | informace |
IS_CSC | hlásí aktuálně vybrané auto připojení | informace |
IS_CNL | připojení levý server | informace |
IS_CPR | hráč změnil jméno | informace |
IS_NPL | nový hráč se připojuje k závodu nebo opouští jámy | informace |
IS_PLP | hráč pits (gone to garage screen) | Info |
IS_PLL | hráč left race (gone to spectate) | Info |
IS_CRS | Car reset (lisovaný mezerník) | informace |
IS_JRR | lze použít k resetování nebo nastartování automobilu na určeném místě | instrukce |
IS_LAP | čas kola dokončen | informace |
IS_SPX | Split time dokončeno | informace |
IS_PIT | Pit stop Start (v boxech) | Info |
IS_PSF | Pit stop dokončeno | informace |
IS_PLA | hráč vstoupil do pit lane (Do pit nebo sloužit trestu) | Info |
IS_CHH | změnil se pohled kamery (chase view, custom view atd..) | informace |
IS_PEN | trest udělený nebo udělený | Info |
IS_TOC | hráč převzal jiné auto (výměna řidiče) | informace |
IS_FLG | přehrávač zobrazen příznak (žlutá nebo modrá) | informace |
IS_PFL | vlajky hráče změněny (automatické převody, Automatická spojka atd..) | informace |
IS_FIN | hráč dokončil závod (překročil cílovou čáru) | informace |
IS_RES | hráč výsledek udělen, potvrzeno finish | Info |
IS_REO | Změna pořadí startovní mřížky | obojí |
autokros | ||
IS_AXI | Autocross layout loaded | Info |
IS_AXO | hráč hit autokros objekt | Info |
IS_OCO | lze použít k přepsání specifických nebo všechna startovací světla | instrukce |
IS_UCO | odesílá informace o kontrolních bodech InSim a kruzích | informace |
Sledování vozu | ||
IS_NLP | hráči aktuální uzel, kolo a závod pozice | informace |
IS_MCI | podrobnější verze IS_NLP, svět-souřadnice, rychlost, úhel a nadpis | informace |
ovládání kamery | ||
IS_SCC | nastavit prohlížené auto a vybrat kameru | instrukce |
IS_CPP | Nastavení plné polohy kamery | instrukce |
ovládání přehrávání | ||
IS_RIP | načíst replay a přesunout na konkrétní cíl | instrukce |
ukázky | ||
IS_SSH | pořídit snímek obrazovky | instrukce |
tlačítka InSim | ||
IS_BFN | Smazat tlačítko nebo všechna tlačítka | instrukce |
IS_BTN | Odeslat tlačítko na obrazovku | instrukce |
IS_BTC | odesláno po kliknutí na tlačítko | Info |
IS_BTT | odesláno při zadávání textu | Info |