Insim

InSim

InSim jest protokołem, który pozwala zewnętrznemu programowi komunikować się z Live For Speed. Pozwala na tworzenie połączenia z grą oraz wysyłanie i odbieranie pakietów danych. Protokół InSim opisuje sposób formatowania każdego z tych pakietów, a każdy język programowania, który może utworzyć połączenie sieciowe i wysyłać i odbierać ciągi danych binarnych, może się z nim łączyć.

oficjalna dokumentacja znajduje się w pliku InSim.txt, znaleziony w folderze games doc. Składa się z pliku nagłówkowego C++, który zawiera definicję każdego pakietu, a także komentarze Scawena dotyczące tego, jak każdy z nich powinien być używany. Niniejsza dokumentacja jest przeznaczona jako pomocnicza dla tego pliku.

UDP vs TCP

InSim obsługuje zarówno połączenia UDP, jak i TCP. W trybie UDP można nawiązać tylko jedno połączenie, jednak do gry można nawiązać do ośmiu połączeń w TCP. Niezależnie od tego, czy jest podłączony w TCP, czy UDP, można określić oddzielne gniazdo UDP do odbierania aktualizacji pozycji samochodu, takie jak IS_MCI i IS_NLP.

przykład InSim

sposób tworzenia połączenia InSim jest oczywiście zależny od języka programowania, którego używasz, ale tutaj podejmujemy próbę udokumentowania procesu za pomocą przykładów z popularnego języka programowania Python. Jak wspomniano powyżej, każdy język zdolny do połączenia z gniazdem może być użyty do interfejsu z LFS, jednak zasada pozostaje taka sama niezależnie od tego.

Tworzenie połączenia

przede wszystkim musimy ustanowić połączenie gniazda z grą, w tym przypadku w 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))

Inicjalizacja InSim

po nawiązaniu połączenia musimy zainicjować system InSim wysyłając pakiet IS_ISI. Zanim jednak to zrobimy, musimy najpierw intitailse InSim w samym LFS. Aby to zrobić, uruchom grę i wprowadź komendę czatu „/ insim 29999”. Użyty numer portu może być dowolnym poprawnym portem, ale 29999 zazwyczaj jest akceptowanym domyślnym.

oto definicja pakietu IS_ISI z 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żdy pakiet InSim zaczyna się nagłówkiem, składającym się z 4 bajtów. Pierwszy bajt to Rozmiar pakietu, następnie typ pakietu z wyliczenia ISP_, a następnie ReqI (skrót od Request Id). Za każdym razem, gdy żądanie jest wysyłane do LFS, wartość ReqI musi być ustawiona na niezerową, przy czym LFS odpowie z tą samą wartością ustawioną w ReqI żądanego pakietu. Wreszcie czwarty bajt różni się w zależności od typu danego pakietu, który w tym przypadku jest pusty.

jak widać pakiet IS_ISI zawiera różne opcje i flagi, które są używane podczas inicjalizacji systemu InSim. Musimy spakować te dane do binarnego sformatowanego ciągu znaków, aby wysłać 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)

odbieranie danych

po utworzeniu połączenia i zainicjowaniu InSim musimy ustawić pętlę odbioru pakietów. Ponieważ dane w trybie TCP są wysyłane jako stały strumień Danych, wiele pakietów może dotrzeć w jednym wywołaniu odbiorczym, a niektóre pakiety mogą dotrzeć niekompletne. Oznacza to, że musimy przechowywać wszystkie przychodzące dane w buforze, a następnie odczytywać każdy pakiet, gdy jesteśmy pewni, że jest kompletny.

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

rozpakowywanie pakietów

po otrzymaniu danych pakietu jako binarnego sformatowanego ciągu znaków, musimy rozpakować te dane do formatu, który jest dla nas przydatny. W poprzednim przykładzie, kiedy wysłaliśmy pakiet inicjalizacji IS_ISI, ustawiliśmy ReqI na niezerową, co oznacza, że LFS odpowiedział pakietem w wersji IS_VER, jednak nic z nim nie zrobiliśmy. Najpierw przyjrzyjmy się definicji pakietu IS_VER z 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};

teraz spójrzmy, jak rozpakowalibyśmy te dane w Pythonie.

# 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 utrzymać otwarte połączenie, LFS wyśle pakiet „keep alive” co około 30 sekund. Pakiet ten jest pakietem IS_TINY z podtypem TINY_NONE. Musimy odpowiadać na ten pakiet za każdym razem, gdy jest on odbierany, aby zapobiec przerwaniu połączenia z 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)

dalsze przykłady

możesz zobaczyć pełny przykład tego kodu, a także inne na stronie przykładów InSim.

Biblioteki InSim

oczywiście, jak mówi stare przysłowie, nie powinieneś próbować odkrywać koła na nowo (chyba że próbujesz dowiedzieć się więcej o kołach) i istnieje kilka dojrzałych bibliotek InSim dostępnych do użycia we własnym kodzie.

Biblioteki InSim
Biblioteka Platforma Licencja web
LFSLib . NET Framework GPL strona projektu
LFS_External .NET Framework Freeware wątek lfsforum
JInSim Java Mozilla wątek lfsforum
pyinsim Python LGPL wątek lfsforum
CInSim C / C++ Freeware wątek lfsforum
phplfs PHP5 Licencja Apache V2.0 strona projektu
PRISM PHP7 MIT sekcja lfsforum
InSim.NET . NET Framework LGPL wątek lfsforum

Insim Reference

oto próba odniesienia się do pełnego protokołu InSim.

numer pakietu
Pakiet opis Typ
Inicjalizacja
IS_ISI inicjalizacja InSim Instrukcja
ogólnego przeznaczenia
IS_TINY Pakiet 4-bajtowy ogólnego przeznaczenia oba
IS_SMALL Pakiet 8 bajtowy ogólnego przeznaczenia oba
Prośba o wersję
IS_VER informacje o wersji Info
raportowanie stanu i wnioski
IS_STA wysyłana za każdym razem, gdy zmienia się stan gry Info
IS_SFP Wyślij, aby ustawić różne opcje stanu Instrukcja
tryb ekranu
IS_MOD Wyślij, aby zmienić tryb ekranu Instrukcja
wiadomości tekstowe i naciśnięcia klawiszy
IS_MSO wiadomości systemowe i użytkownika wysyłane z LFS informacje
IS_III wiadomości użytkownika do hosta InSim Info
IS_MST Wyślij LFS wiadomość lub polecenie (64 znaki) Instrukcja
Is_msx rozszerzona wersja IS_MST (96 znaków), nie dla poleceń Instrukcja
IS_MSL Wyślij wiadomość do lokalnego klienta gry Instrukcja
IS_MTC Wyślij wiadomość do konkretnego połączenia lub odtwarzacza Instrukcja
IS_SCH Wyślij pojedynczy znak lub klawisz naciśnij Instrukcja
powiadomienie Multiplayer
IS_ISM wysyłany podczas uruchamiania lub dołączania do hosta Info
IS_NCI wysłane po ustawieniu hasła administratora hosta, zawiera dane IP użytkownika i języka Info
głosuj powiadom
IS_VTN Powiadom o głosowaniu zawodników (restart wyścigu, Kwalifikacje itp.. Info
śledzenie wyścigu
IS_RST Start lub wznowienie wyścigu Info
IS_NCN nowe połączenie z serwerem Info
IS_SLC aby zgłosić zmiany stanu samochodu (obecnie start lub stop) Info
IS_CSC zgłasza aktualnie wybrany samochód Info
IS_CNL połączenie z serwerem Info
IS_CPR zmiana nazwy gracza Info
IS_NPL nowy gracz dołącza do wyścigu lub opuszcza pity Info
IS_PLP pity graczy (gone to garage screen) Info
IS_PLL zawodnik opuścił wyścig (odszedł do spectate) Info
IS_CRS reset samochodu (wciśnięty spacja) Info
IS_JRR może być używany do resetowania lub uruchamiania samochodu w określonej lokalizacji Instrukcja
IS_LAP czas okrążenia ukończony Info
IS_SPX Info
IS_PIT ruszył Pit stop (przy pit boxie) Info
IS_PSF pit stop zakończony Info
IS_PLA zawodnik wszedł na pit lane (do pit lub służyć karnie) Info
is_chh zmieniono widok kamery (widok pościgu, widok niestandardowy itp.. Info
IS_PEN kara podana lub wybita Info
IS_TOC gracz przejal inny samochod(Zamiana kierowcy) Info
IS_FLG pokazana flaga gracza (żółta lub niebieska) Info
is_pfl zmieniono flagi graczy (auto-biegi, auto-sprzęgło itp.. Info
IS_FIN zawodnik ukończył wyścig (przekroczył linię mety) Info
IS_RES wynik zawodnika przyznany, potwierdzony koniec Info
IS_REO Zmień kolejność oba
Autocross
IS_AXI autocross layout loaded Info
IS_AXO gracz uderzył w obiekt autocross Info
IS_OCO można użyć do nadpisania określonych lub wszystkie światła startowe Instrukcja
IS_UCO wysyła informacje o insim i okręgach Info
śledzenie samochodów
IS_NLP aktualna pozycja zawodnika, okrążenia i wyścigu Info
IS_MCI bardziej szczegółowa wersja IS_NLP, współrzędne świata, prędkość, kąt i kierunek Info
sterowanie kamerą
IS_SCC Ustaw oglądany samochód i wybierz kamerę Instrukcja
IS_CPP Ustaw pełną pozycję kamery Instrukcja
Kontrola powtórek
IS_RIP załaduj powtórkę i przejdź do określonego miejsca docelowego Instrukcja
zrzuty ekranu
IS_SSH Zrób zrzut ekranu Instrukcja
przyciski InSim
IS_BFN Usuń przycisk lub wszystkie przyciski Instrukcja
IS_BTN Wyślij przycisk na ekran Instrukcja
IS_BTC wysyłane po kliknięciu przycisku Info
IS_BTT wysłane po wpisaniu tekstu Info

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.