InSim examples

From LFS Manual
Jump to: navigation, search

Python

Example #1

How to connect, send a packet and receive the response.

# Dependencies.
import socket
import struct

# Some constants.
INSIM_VERSION = 4
BUFFER_SIZE = 2048

# Packet types.
ISP_ISI = 1
ISP_VER = 2
ISP_TINY = 3
TINY_NONE = 0

# Initailise the socket in TCP mode.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to LFS.
sock.connect(('localhost', 29999))

# Pack the ISI packet into a string.
isi = struct.pack('BBBBHHBBH16s16s', 
                  44,          # Size
                  ISP_ISI,     # Type
                  1,           # ReqI - causes LFS to send an IS_VER. 
                  0,           # Zero
                  0,           # UDPPort
                  0,           # Flags
                  0,           # Sp0
                  0,           # Prefix
                  0,           # Interval
                  'password',  # Admin 
                  '^3example') # IName
                 
# Send the ISI packet to InSim. 
sock.send(isi)

buffer = ''

while True:
    data = sock.recv(BUFFER_SIZE)
    if data:
        buffer += data
        
        # Loop through completed packets.
        while len(buffer) > 0 and len(buffer) >= ord(buffer[0]):
            
            # Copy the packet from the buffer.
            packet = buffer[:ord(buffer[0])]
            buffer = buffer[ord(buffer[0]):]
            
            # Check packet type.
            if ord(buffer[1]) == ISP_TINY:
                # Unpack the TINY packet and check it for keep-alive signal.
                size, type, reqi, subt = struct.unpack('BBBB', packet)
                if subt == TINY_NONE:
                    sock.send(packet) # Respond to keep-alive.
            elif ord(buffer[1]) == ISP_VER:
                # Unpack the VER packet and check the InSim version.
                size, type, reqi, _, version, product, insimver = struct.unpack('BBBB8s6sH')
                if insimver != INSIM_VERSION:
                    break # Invalid version, break loop.
    else: 
        break # Connection has closed.
        
# Release the socket.
sock.close()

Visual C#

Example #1

How to connect, send a packet and receive the response.

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;

class Program
{
    enum PacketType
    {
        ISP_ISI = 0,
        ISP_VER = 1,
        ISP_TINY = 2,
    }

    enum TinyType
    {
        TINY_NONE = 0,
    }

    const int BufferSize = 2048;
    const int InSimVersion = 4;

    static void Main()
    {
        // Initailise the Socket and connect to InSim.
        Socket sock = new Socket(
            AddressFamily.InterNetwork,
            SocketType.Stream,
            ProtocolType.Tcp);
        sock.Connect("localhost", 29999);

        // Create the ISI packet.
        byte[] isi = new byte[44];
        isi[0] = 44; // Size
        isi[1] = (byte)PacketType.ISP_ISI; // Type
        isi[2] = 1; // ReqI
        isi[3] = 0; // Zero
        isi[4] = 0; // UDPPort
        isi[5] = 0; // UDPPort
        isi[6] = 0; // Flags
        isi[7] = 0; // Flags
        isi[8] = 0; // Sp0
        isi[9] = (byte)'!'; // Prefix
        isi[10] = 0; // Interval
        isi[11] = 0; // Interval
        ASCIIEncoding.ASCII.GetBytes("password", 0, 8, isi, 12); // Admin
        ASCIIEncoding.ASCII.GetBytes("^3Example", 0, 9, isi, 28); // IName

        // Send the packet to InSim.
        sock.Send(isi);

        // Packet buffer.
        List<byte> buffer = new List<byte>();

        while (true)
        {
            // Receive data from socket.
            byte[] data = new byte[BufferSize];
            int received = sock.Receive(data);
            if (received > 0)
            {
                // Add the data to the packet buffer.
                byte[] temp = new byte[received];
                Array.Copy(data, temp, received);
                buffer.AddRange(temp);

                // Loop through all packets in the buffer.
                while (buffer.Count > 0 && buffer.Count >= buffer[0])
                {
                    // Copy packet from buffer.
                    byte[] packet = new byte[buffer[0]];
                    buffer.CopyTo(0, packet, 0, buffer[0]);
                    buffer.RemoveRange(0, buffer[0]);

                    // Check packet type.
                    if (PacketType.ISP_TINY == (PacketType)buffer[1])
                    {
                        // Unpack TINY and respond to keep-alive.
                        byte size = packet[0];
                        PacketType type = (PacketType)packet[1];
                        byte reqi = packet[2];
                        TinyType subt = (TinyType)packet[3];

                        if (subt == TinyType.TINY_NONE)
                        {
                            sock.Send(packet);
                        }
                    }
                    else if (PacketType.ISP_VER == (PacketType)buffer[1])
                    {
                        // Unpack VER and check InSim version.
                        byte size = packet[0];
                        PacketType type = (PacketType)packet[1];
                        byte reqi = packet[2];
                        byte zero = packet[3];
                        string version = ASCIIEncoding.ASCII.GetString(packet, 4, 8);
                        string product = ASCIIEncoding.ASCII.GetString(packet, 12, 6);
                        ushort insimver = BitConverter.ToUInt16(packet, 18);

                        if (insimver != InSimVersion)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                // Connection has closed.
                break;
            }
        }

        // Release the socket.
        sock.Close();
    }
}

PHP

Example #1

<?php
$InSim = new InSim();
class InSim {
    function __construct($AdminPass = '', $Address = '127.0.0.1', $Port = 29999, $PreFixChar = '!') {
        // Socket In;
        if ($this->skIn = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) {
            echo('Listen socket created!' . PHP_EOL);
            if (socket_bind($this->skIn, $Address, $Port + 1))
                echo('Binded to listen socket!' . PHP_EOL);
            else
                die('Could not bind to listen socket, address or port!' . PHP_EOL);
        } else
            die('Could not create listen socket!' . PHP_EOL);
        
        // Socket Out;
        if ($this->skOt = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) {
            echo('Send socket created!' . PHP_EOL);
            if (socket_connect($this->skOt, $Address, $Port))
                echo('Conneceted to send socket!' . PHP_EOL);
            else
                die('Could not connect to send socket, address or port!' . PHP_EOL);
        } else
            die('Could not create send socket!');
        
        # Connect To InSim;
        $this->send(pack('CCCxSSxCSa16a16', 44, 1, 1, $Port + 1, 4 | 8, 36, 0, $AdminPass, 'phpInSim'));
        $this->main();
    }
    function send($packet) {
        return socket_write($this->skOt, $packet, strlen($packet));
    }
    function main() {
        while (TRUE) {
            # Keep Alive;
            if (time() > $this->time) {
                $this->send(pack('CCCC', 4, 3, 0, 0));
                $this->time = time() + 30;
            }
            # Get Packet;
            if ($data = $this->recv()) {
                print_r($data);
            }
        }
    }
    function recv() {
        return socket_read($this->skIn, 256, PHP_BINARY_READ);
    }
    function __destruct() {
        $this->send(pack('CCCC', 4, 3, 0, 2));
    }
}
?>