InSim System for Live for Speed : (Patch G Version : 1) ================================= InSim allows communication between an external program and LFS.exe. UDP packets can be sent in either direction, LFS reporting various things about its state, and the external program requesting info and controlling LFS with special packets, text commands or keypresses. Data types : (all multi-byte types are PC style - lowest byte first) ============ char 1-byte character byte 1-byte unsigned integer word 2-byte unsigned integer short 2-byte signed integer unsigned 4-byte unsigned integer int 4-byte signed integer float 4-byte float MSHT 4-byte minutes, seconds, hundredths, thousandths InSim initialisation ==================== To initialise the InSim system, type into LFS : /insim XXXXX - XXXXX is the UDP port you want LFS to open OR start LFS with the command line option : LFS /insim=XXXXX This will make LFS listen for packets on that UDP port. Now you must send a special UDP packet to LFS. struct InSimInit // UDP packet to initialise the InSim system { char Id [4]; // ISI + zero word Port; // Port for UDP replies from LFS (0...65535) byte Flags; // Bit flags for options - see below byte NodeSecs; // Number of seconds between NLP or MCI packets (0=none) char Admin [16]; // Admin password (required if set in LFS host options) }; Now you can send packets to control LFS, and LFS will be sending packets to you. Flags in InSimInit packet : set the relevant bits to turn on the option : #define ISF_RACE_TRACKING 1 // bit 0 : turns on race tracking #define ISF_GUARANTEE 2 // bit 1 : turns on guaranteed delivery #define ISF_SPLIT_MESSAGE 4 // bit 2 : use MSS, not MSO for user messages #define ISF_NO_WARNINGS 8 // bit 3 : turns off packet warnings #define ISF_KEEP_ALIVE 16 // bit 4 : makes lfs send keep alive packets #define ISF_NLP_MCI 32 // bit 5 : makes lfs send MCI instead of NLP Note : If Port is zero, LFS will send replies back to the port of the incoming packet InSimPack ========= InSimPack is used for various InSim requests (see below) struct InSimPack // General purpose 8 byte UDP packet { char Id [4]; // 3 character identifier followed by zero character int Value; // 32 bit value depending on the type of InSimPack }; Version Request =============== It is advisable to request version information as soon as you have connected, to avoid problems when connecting to a host with a later or earlier version. This small version packet can be sent on request : struct InSimVersion { char Id [4]; // VER + zero char Version [8]; // LFS version, e.g. 0.3G char Product [6]; // Product : DEMO or S1 word InSimVer; // InSim Version : increased when InSim packets change }; To request an InSimVersion packet, send an InSimPack like this : Id : "VER" (VERsion) Value : 0 Closing Insim ============= You can send a packet to ask InSim to return to its waiting / initialised / listening state by sending an InSimPack with Id = "ISC" (InSimClose) and Value = 0. It will then require another InSimInit packet to start operating again. You can shut down InSim completely and stop it listening at all by typing in /insim=0 into the connected LFS. Or send a MsgTypePack to do the same thing. Maintaining the connection - Important ====================================== If InSim does not receive a packet for 2 minutes, it will close the connection and return to its original waiting / initialised state. To open it again you would need to send another InSimInit packet. To avoid InSim closing in this way, you should send a packet every 20 - 30 seconds. One example of a "keep alive" packet is an "ACK" InSimPack with value = 0. This "blank acknowledgment packet" will have no other effect on LFS. Note 1 : If you set the ISF_KEEP_ALIVE option in the InSimInit packet, then LFS will send a blank acknowledgement packet whenever it has not sent anything for 20 seconds. If you don't receive anything for 2 minutes it may be safe to assume that you have lost the connection for some reason. This option is also useful if your program doesn't run at all while it is waiting for a packet to arrive. Note 2 : If you want to request a small reply from LFS to check the connection at any time, a good one to send is a "GTH" InSimPack - LFS returns a "RTP" InSimPack. This has no functional effect on LFS as it is simply a time reporting packet (see below). State Reporting and Request =========================== LFS will send a StatePack any time the info in the StatePack changes. struct StatePack { char Id [4]; // STA + zero float ReplaySpeed; // 4-byte float - 1.0 is normal speed word Flags; // State Flags (see below) byte InGameCam; // Which type of camera is selected (see below) byte ViewPlayer; // Player index of viewed car byte NumPlayers; // Num in race byte NumConns; // Num connections including host byte NumFinished; // Number finished or qualified byte RaceInProgress; // 0 - no / 1 - race / 2 - qualifying byte QualMins; byte RaceLaps; byte Spare2; byte Spare3; char Track [6]; // short name for track e.g. FE2R byte Weather; // 0,1,2... byte Wind; // 0=off 1=weak 2=strong }; The bits stored in "State Flags" are : -------------------------------------- #define ISS_GAME 1 // in game (or MPR) #define ISS_REPLAY 2 // in SPR #define ISS_PAUSED 4 // paused #define ISS_SHIFTU 8 // in SHIFT+U mode #define ISS_SHIFTU_HIGH 16 // HIGH view #define ISS_SHIFTU_FOLLOW 32 // following car #define ISS_SHIFTU_NO_OPT 64 // buttons are hidden #define ISS_SHOW_2D 128 // showing 2d display #define ISS_FRONT_END 256 // in front end screen #define ISS_MULTI 512 // multiplayer mode #define ISS_MPSPEEDUP 1024 // multiplayer speedup option #define ISS_WINDOWED 2048 // lfs is running in a window #define ISS_SOUND_MUTE 4096 // sound is switched off #define ISS_VIEW_OVERRIDE 8192 // override user view InGameCam shows the NOT SHIFT+U selected camera mode ---------------------------------------------------- 0 Arcade View 1 Helicopter View 2 TV Camera View 3 Driver View 4 Custom View To request a StatePack from LFS, send an InSimPack like this : -------------------------------------------------------------- Id : "SST" (Send State) Value : 0 Setting states -------------- These states can be controlled by a special packet : ISS_SHIFTU_FOLLOW // following car ISS_SHIFTU_NO_OPT // buttons are hidden ISS_SHOW_2D // showing 2d display ISS_MPSPEEDUP // multiplayer speedup option ISS_SOUND_MUTE // sound is mute struct StateFlagsPack { char Id [4]; // SFP + zero word Flag; // the state to set (ISS_xxx) byte OffOn; // 0 = off / 1 = on byte Sp3; // spare }; Other states must be set by using keypresses or messages (see below) Text Messages and Key Presses ============================= You can send 64-byte text messages to LFS as if the user had typed them in. Messages that appear on LFS screeen (up to 128 bytes) are reported to the external program. You can also send simulated keypresses to LFS. struct MsgTypePack // 64 chars - send to LFS to simulate typing message or command { char Id [4]; // MST + zero char Msg [64]; // text message or /command, must end with zero }; struct MsgToConn // 64 chars - send to LFS and on to a chosen connection (0 = host) { char Id [4]; // MTC + zero byte Conn; // connection byte UniqueId; // destination player UniqueId : if set, Conn is ignored byte Sp2; byte Sp3; char Msg [64]; // text message or /command, must end with zero }; struct MsgOutPack // 128 chars - LFS reporting displayed messages { char Id [4]; // MSO + zero char Msg [128]; // displayed message, with colours removed }; struct MsgOutSplit // 64 chars - user messages if ISF_SPLIT_MESSAGE flag is ON { char Id [4]; // MSS + zero char UName [24]; // user name char PName [24]; // player name char Msg [64]; // text message from user }; struct SingleCharPack // send to LFS to simulate single character { char Id [4]; // SCH + zero char Char; // key to press byte Flags; // bit 0 : SHIFT / bit 1 : CTRL byte Spare2; byte Spare3; }; Note 1 : you must set the "Flags" bits if you want to simulate a key that needs CTRL or SHIFT held down. Note 2 : a new command has been added to LFS : /mso Typing "/mso MESSAGE" into LFS will send a MSO packet to the external program. Multiplayer Notification ======================== LFS will send this packet when a host is started or joined : struct InSimMulti { char Id [4]; // ISM byte Host; // 0 = guest / 1 = host byte Sp1; byte Sp2; byte Sp3; char Name [32]; // the name of the host joined or started }; On ending or leaving a host, LFS will send this InSimPack : Id : "MPE" (MultiPlayerEnd) Value : 0 To request a InSimMulti packet at any time, send a InSimPack with Id = "ISM". - If LFS is not in multiplayer mode, the host name in the ISM will be empty. Vote Notify and Cancel ====================== LFS notifies the external program of any votes to restart or qualify The Vote Actions are defined as : VOTE_NONE 0 VOTE_END_RACE 1 VOTE_RESTART 2 VOTE_QUALIFY 3 struct InSimVote { char Id [4]; // VTN + zero (VoTe Notify) byte Conn; // connection (0 is host) byte Type; // VOTE_X (Vote Action as defined above) byte Spare2; byte Spare3; }; When a vote is cancelled, LFS sends this InSimPack to the control program Id : "VTC" (VoTe Cancel) Value : 0 When a vote is completed, LFS sends this InSimPack to the control program Id : "VTA" (VoTe Action) Value : action (V...
mitrix17