Difference between revisions of "InSim"

From LFS Manual
Jump to: navigation, search
m (Minor formatting crap)
m (A few corrections.)
Line 3: Line 3:
 
InSim is a protocol which allows an external program to communicate with Live for Speed. It allows you to create a socket connection with the game and to send and receive packets of data. The InSim protocol describes how each of these packets is formatted, and any programming language which can create a network connection and send and receive strings of binary data can interface with it.  
 
InSim is a protocol which allows an external program to communicate with Live for Speed. It allows you to create a socket connection with the game and to send and receive packets of data. The InSim protocol describes how each of these packets is formatted, and any programming language which can create a network connection and send and receive strings of binary data can interface with it.  
  
The official documentation is included in the file InSim.txt, found in the games doc folder. It consists of a C++ header file that contains the definition for each packet, as well as comments from Scawen as to how each should be used. The documentation here is intended as an ancillary to this file.
+
The official documentation is included in the file [[InSim.txt]], found in the games doc folder. It consists of a C++ header file that contains the definition for each packet, as well as comments from Scawen as to how each should be used. The documentation here is intended as an ancillary to this file.
  
 
== UDP vs TCP ==
 
== UDP vs TCP ==
  
InSim supports both UDP and TCP connections. In UDP mode only a single connection can be made, however up to eight connections can be made to a single game client in TCP. Whether connected in TCP or UDP, it's possible to specify a separate UDP socket for receiving car position updates, such as MCI and NLP.
+
InSim supports both UDP and TCP connections. In UDP mode only a single connection can be made, however up to eight connections can be made to the game client in TCP. Whether connected in TCP or UDP, it's possible to specify a separate UDP socket for receiving car position updates, such as [[IS_MCI]] and [[IS_NLP]].
  
 
== Creating a connection ==
 
== Creating a connection ==
  
How you go about creating an connection is of course dependent on which programming language you are using, but here will make an attempt to document the process with some examples in the popular [http://www.python.org/ Python programming language].
+
How you go about creating a connection is of course dependent on which programming language you are using, but here will make an attempt to document the process with some examples in the popular [http://www.python.org/ Python programming language].
  
 
First of all we must establish a socket connection with the game.
 
First of all we must establish a socket connection with the game.
Line 26: Line 26:
 
== Initialising InSim ==
 
== Initialising InSim ==
  
After establishing the connection, we must initialise the InSim system by sending the IS_ISI packet. Before you can initialise InSim from our program, it must be initialised first in LFS. To do this start the program and enter the chat command "/insim 29999". The port number used can be any valid port, but 29999 generally tends to be the accepted default.
+
After establishing the connection, we must initialise the InSim system by sending the [[IS_ISI]] packet. Before we can do this however, we must first intitailse the InSim system within LFS itself. To do this start the game and enter the chat command "/insim 29999". The port number used can be any valid port, but 29999 generally tends to be the accepted default.
  
Here is the definition for the IS_ISI from InSim.txt.
+
Here is the definition for the [[IS_ISI]] packet from [[InSim.txt]].
  
 
<big><pre>struct IS_ISI // InSim Init - packet to initialise the InSim system
 
<big><pre>struct IS_ISI // InSim Init - packet to initialise the InSim system
Line 48: Line 48:
 
};</pre></big>
 
};</pre></big>
  
As you can see contains various options and flags that are used when initialising the system. We must pack this data into a binary formatted string which we can then send across our socket to LFS.  
+
As you can see the packet contains various options and flags that are used when initialising the system. We must pack this data into a binary formatted string which we can then send to LFS using our socket.  
  
 
<big><pre># Import Python's struct module, which allows us to pack and unpack strings.
 
<big><pre># Import Python's struct module, which allows us to pack and unpack strings.
Line 105: Line 105:
 
== InSim Libraries ==
 
== InSim Libraries ==
  
Of course as the old adage goes, you shouldn't try to reinvent the wheel (unless you're trying to learn more about wheels), and there are currently several InSim libraries available for use in your own code.
+
Of course as the old adage goes you shouldn't try to reinvent the wheel (unless you're trying to learn more about wheels) and there are several mature InSim libraries available for use in your own code.
 
+
  
 
{| border="0" style="border: 1px solid #000000; background-color: #FAFAFA;" width="500"
 
{| border="0" style="border: 1px solid #000000; background-color: #FAFAFA;" width="500"
Line 135: Line 134:
 
|  Freeware
 
|  Freeware
 
|}
 
|}
 
  
 
== InSim Reference ==
 
== InSim Reference ==

Revision as of 09:14, 22 June 2009

InSim

InSim is a protocol which allows an external program to communicate with Live for Speed. It allows you to create a socket connection with the game and to send and receive packets of data. The InSim protocol describes how each of these packets is formatted, and any programming language which can create a network connection and send and receive strings of binary data can interface with it.

The official documentation is included in the file InSim.txt, found in the games doc folder. It consists of a C++ header file that contains the definition for each packet, as well as comments from Scawen as to how each should be used. The documentation here is intended as an ancillary to this file.

UDP vs TCP

InSim supports both UDP and TCP connections. In UDP mode only a single connection can be made, however up to eight connections can be made to the game client in TCP. Whether connected in TCP or UDP, it's possible to specify a separate UDP socket for receiving car position updates, such as IS_MCI and IS_NLP.

Creating a connection

How you go about creating a connection is of course dependent on which programming language you are using, but here will make an attempt to document the process with some examples in the popular Python programming language.

First of all we must establish a socket connection with the game.

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

Initialising InSim

After establishing the connection, we must initialise the InSim system by sending the IS_ISI packet. Before we can do this however, we must first intitailse the InSim system within LFS itself. To do this start the game and enter the chat command "/insim 29999". The port number used can be any valid port, but 29999 generally tends to be the accepted default.

Here is the definition for the IS_ISI packet from InSim.txt.

struct IS_ISI // InSim Init - packet to initialise the InSim system
{
	byte	Size;		// 44
	byte	Type;		// ISP_ISI
	byte	ReqI;		// If non-zero LFS will send an IS_VER packet
	byte	Zero;		// 0

	word	UDPPort;	// Port for UDP replies from LFS (0 to 65535)
	word	Flags;		// Bit flags for options (see below)

	byte	Sp0;		// 0
	byte	Prefix;		// Special host message prefix character
	word	Interval;	// Time in ms between NLP or MCI (0 = none)

	char	Admin[16];	// Admin password (if set in LFS)
	char	IName[16];	// A short name for your program
};

As you can see the packet contains various options and flags that are used when initialising the system. We must pack this data into a binary formatted string which we can then send to LFS using our socket.

# Import Python's struct module, which allows us to pack and unpack strings.
import struct

# Pack the IS_ISI packet data into a string.
isi = struct.pack('BBBBHHBcH16s16s', 
                  44,           # Size
                  1,            # Type
                  0,            # ReqI
                  0,            # Zero
                  0,            # UDPPort
                  0,            # Flags
                  0,            # Sp0
                  ' ',          # Prefix
                  0,            # Interval
                  'password',   # Admin
                  'MyProgram',) # IName

# Send the string to InSim
sock.send(isi)

TCP Receive Loop

After creating the connection and initialising InSim, we must then setup the packet receive loop. As data in TCP mode is sent as a constant stream of data, multiple packets may arrive in a single receive call and some packets may be incomplete, this means we must store all incoming data in a buffer and then read each packet out as it is completed.

# We use a string as the buffer.
buffer = ''

# Infinite loop.
while True:
    # We receive up to 1024 bytes in each receive call.
    data = sock.recv(1024)

    # If no data is received the connection has closed.
    if data:
        # Append received data onto our buffer.
        buffer += data

        # Loop through each completed packet in the buffer. The first byte of
        # each packet is the packet size, so we 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[0]):
            # Copy the packet from the buffer.
            packet = buffer[:ord(buffer[0])]

            # Remove the packet from the buffer.
            buffer = buffer[ord(buffer[0]):]

            # Our packet is now complete! :)
            # doSomethingWithPacket(packet)
    else: 
        break

InSim Libraries

Of course as the old adage goes you shouldn't try to reinvent the wheel (unless you're trying to learn more about wheels) and there are several mature InSim libraries available for use in your own code.

InSim Libraries
Library Platform License
LFSLib .NET Framework GPL
LFS_External .NET Framework Freeware
JInSim Java Mozilla
pyinsim Python LGPL
CInSim C/C++ Freeware

InSim Reference

Here is an attempt to reference the complete InSim protocol.