The online racing simulator
Insim: Once And For All!
(52 posts, started )
Why don't you start with C#? It's much easier to start with.
Quote from T-RonX :Why don't you start with C#? It's much easier to start with.

I will, I just wanted to start in C++ because I had some experience in it.

I got Visual C#, and I had a good look at your base. It seems really easy to understand, easier than C++ anyway. It's much shorter and to-the-point. Thanks for pointing it out to me.
Yay I got a real simple insim program done. Basically it just displays a message (x has joined the game) when someone connects, and says other messages when stuff happens in-game. It only took a couple of hours, but at least I know how it works now!

Thanks to T-RonX for the C# insim base, its perfect!

But I really think a sub-forum could be made for learning insim. I have a few questions about it, which would be out-of-context here, and there's no point making a new thread for each one...

Anyway, Thanks to all who posted, this thread has helped me to finally get started!
OK, I've gotten pretty in to this now, and I have a burning question. First of all, let me explain my predicament...

I'm using the IS_MSO class to look for a specific message said by the players in the server. I then want to do a specific action based upon what they said (eg, (taken from a cruise server as an example) they say "!pitlane" and insim responds with /pitlane "username"). However, to do that, I need the Uname function, which isn't in the MSO class...

I need the Uname function for lots of other classes too, but it's only in the NCN and RES classes...

Any help?
hi, this is how you pitlane some 1



InSim.Send_MST_Message("/pitlane " + Connections[GetConnIdx(MSO.UCID)].Username);

or if you need the UserName specific then you just use this part Connections[GetConnIdx(MSO.UCID)].Username, what that does basically is search the connections list till it finds a connection with that UCID, then returns what you asked


hope that helps
Quote from mcgas001 :hi, this is how you pitlane some 1



InSim.Send_MST_Message("/pitlane " + Connections[GetConnIdx(MSO.UCID)].Username);

or if you need the UserName specific then you just use this part Connections[GetConnIdx(MSO.UCID)].Username, what that does basically is search the connections list till it finds a connection with that UCID, then returns what you asked


hope that helps

Thanks for your quick reply. Hmm, i tried that, but still nothing...

public void MSO(Packets.IS_MSO MSO)
{
if ((MSO.Msg) == ("!pitlane"))
InSim.Send_MST_Message("/pitlane " + (Connections[GetConnIdx(MSO.UCID)].Username));
}

is the piece of code. When I type the !pitlane command, it does not appear on-screen, as normal, but does appear on the dedi window. However, it doesn't seem to pitlane me...I tried the admin command "/pitlane dougie-lampkin" however and that worked...
Firsty you should debug the MSO.Msg to see but thats a different story, this code below works but isnt very good, but its only a very basic example just to show you......


if (MSO.Msg.Contains("!pitlane"))
{
InSim.Send_MST_Message("/pitlane " + Connections[GetConnIdx(MSO.UCID)].Username);
}
Quote from mcgas001 :Firsty you should debug the MSO.Msg to see but thats a different story, this code below works but isnt very good, but its only a very basic example just to show you......


if (MSO.Msg.Contains("!pitlane"))
{
InSim.Send_MST_Message("/pitlane " + Connections[GetConnIdx(MSO.UCID)].Username);
}

Weird, I just tried that and that didn't work either...Have you tried it?

EDIT: I tried

if (MSO.Msg.Contains("!pitlane"))
{
InSim.Send_MST_Message("pitlane ");
}

and it seems that there is no response...
Quote from dougie-lampkin :Weird, I just tried that and that didn't work either...Have you tried it?

EDIT: I tried

if (MSO.Msg.Contains("!pitlane"))
{
InSim.Send_MST_Message("pitlane ");
}

and it seems that there is no response...

did you uncomment the event handler for MSO? if you havnt the insim wont bother reciving MSO
Quote from mcgas001 :did you uncomment the event handler for MSO? if you havnt the insim wont bother reciving MSO

What do you mean? (sorry, I'm new to C#, so I'm learning as I go!)
ok basically look at this., this is the "Form1.cs" from that insim base basically theres a "reigion" called Default mothods. In order for you to recive MSO you must uncomment a event handler


like this




using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using LFS_External.InSim;
namespace LFS_External_Client
{
public partial class Form1 : Form
{
// InSim objects
InSimInterface InSim;
ConnectionSettings cfg;
// These are the main lists that contain all Players and Connections (Are already automatically being maintained)
List<clsConnection> Connections = new List<clsConnection>();
List<clsPlayer> Players = new List<clsPlayer>();
public Form1()
{
InitializeComponent();
InitializeInSimEvents(); // Event handlers (Uncoment a line in here to enable the event
}
[B]#region Default Methods[/B]
// Uncomment a line in this method to enable its event.
private void InitializeInSimEvents()
{
//LFS_External.InSim.Events.AXC_Received += new LFS_External.InSim.Events.AXC_EventHandler(AXC);
//LFS_External.InSim.Events.AXI_Received += new LFS_External.InSim.Events.AXI_EventHandler(AXI);
//LFS_External.InSim.Events.AXO_Received += new LFS_External.InSim.Events.AXO_EventHandler(AXO);
//LFS_External.InSim.Events.BTC_Received += new LFS_External.InSim.Events.BTC_EventHandler(BTC);
//LFS_External.InSim.Events.BTT_Received += new LFS_External.InSim.Events.BTT_EventHandler(BTT);
//LFS_External.InSim.Events.BFN_Received += new LFS_External.InSim.Events.BFN_EventHandler(BFN);
//LFS_External.InSim.Events.CCH_Received += new LFS_External.InSim.Events.CCH_EventHandler(CCH);
//LFS_External.InSim.Events.CLR_Received += new LFS_External.InSim.Events.CLR_EventHandler(CLR);
LFS_External.InSim.Events.CNL_Received += new LFS_External.InSim.Events.CNL_EventHandler(CNL);
//LFS_External.InSim.Events.CPP_Received += new LFS_External.InSim.Events.CPP_EventHandler(CPP);
//LFS_External.InSim.Events.CPR_Received += new LFS_External.InSim.Events.CPR_EventHandler(CPR);
//LFS_External.InSim.Events.CRS_Received += new LFS_External.InSim.Events.CRS_EventHandler(CRS);
//LFS_External.InSim.Events.FIN_Received += new LFS_External.InSim.Events.FIN_EventHandler(FIN);
//LFS_External.InSim.Events.FLG_Received += new LFS_External.InSim.Events.FLG_EventHandler(FLG);
//LFS_External.InSim.Events.III_Received += new LFS_External.InSim.Events.III_EventHandler(III);
//LFS_External.InSim.Events.ISM_Received += new LFS_External.InSim.Events.ISM_EventHandler(ISM);
//LFS_External.InSim.Events.LAP_Received += new LFS_External.InSim.Events.LAP_EventHandler(LAP);
//LFS_External.InSim.Events.MCI_Received += new LFS_External.InSim.Events.MCI_EventHandler(MCI);
//LFS_External.InSim.Events.MPE_Received += new LFS_External.InSim.Events.MPE_EventHandler(MPE);
[B]LFS_External.InSim.Events.MSO_Received += new LFS_External.InSim.Events.MSO_EventHandler(MSO);[/B]
LFS_External.InSim.Events.NCN_Received += new LFS_External.InSim.Events.NCN_EventHandler(NCN);
//LFS_External.InSim.Events.NLP_Received += new LFS_External.InSim.Events.NLP_EventHandler(NLP);
LFS_External.InSim.Events.NPL_Received += new LFS_External.InSim.Events.NPL_EventHandler(NPL);
//LFS_External.InSim.Events.PEN_Received += new LFS_External.InSim.Events.PEN_EventHandler(PEN);
//LFS_External.InSim.Events.PFL_Received += new LFS_External.InSim.Events.PFL_EventHandler(PFL);
//LFS_External.InSim.Events.PIT_Received += new LFS_External.InSim.Events.PIT_EventHandler(PIT);
//LFS_External.InSim.Events.PLA_Received += new LFS_External.InSim.Events.PLA_EventHandler(PLA);
LFS_External.InSim.Events.PLL_Received += new LFS_External.InSim.Events.PLL_EventHandler(PLL);
//LFS_External.InSim.Events.PLP_Received += new LFS_External.InSim.Events.PLP_EventHandler(PLP);
//LFS_External.InSim.Events.PSF_Received += new LFS_External.InSim.Events.PSF_EventHandler(PSF);
//LFS_External.InSim.Events.REN_Received += new LFS_External.InSim.Events.REN_EventHandler(REN);
//LFS_External.InSim.Events.REO_Received += new LFS_External.InSim.Events.REO_EventHandler(REO);
//LFS_External.InSim.Events.REPLY_Received += new LFS_External.InSim.Events.REPLY_EventHandler(REPLY);
//LFS_External.InSim.Events.RES_Received += new LFS_External.InSim.Events.RES_EventHandler(RES);
//LFS_External.InSim.Events.RST_Received += new LFS_External.InSim.Events.RST_EventHandler(RST);
//LFS_External.InSim.Events.RTP_Received += new LFS_External.InSim.Events.RTP_EventHandler(RTP);
//LFS_External.InSim.Events.SPX_Received += new LFS_External.InSim.Events.SPX_EventHandler(SPX);
//LFS_External.InSim.Events.STA_Received += new LFS_External.InSim.Events.STA_EventHandler(STA);
LFS_External.InSim.Events.TOC_Received += new LFS_External.InSim.Events.TOC_EventHandler(TOC);
//LFS_External.InSim.Events.VER_Received += new LFS_External.InSim.Events.VER_EventHandler(VER);
//LFS_External.InSim.Events.VTA_Received += new LFS_External.InSim.Events.VTA_EventHandler(VTA);
//LFS_External.InSim.Events.VTC_Received += new LFS_External.InSim.Events.VTC_EventHandler(VTC);
//LFS_External.InSim.Events.VTN_Received += new LFS_External.InSim.Events.VTN_EventHandler(VTN);
}
// Methods for automatically update Players[] and Connection[] lists (Called from NPL and NCN)
private void RemoveFromConnectionsList(Packets.IS_CNL CNL)
{
// Copy of item to remove
clsConnection RemoveItem = new clsConnection();
// Check what item the connection had
foreach (clsConnection Conn in Connections)
{
if (CNL.UCID == Conn.UniqueID)
{
// Copy item (Can't delete it here)
RemoveItem = Conn;
continue;
}
}
// Remove item
Connections.Remove(RemoveItem);
}
private void AddToConnectionsList(Packets.IS_NCN NCN)
{
bool InList = false;
// Check of connection is already in the list
foreach (clsConnection Conn in Connections)
{
if (Conn.UniqueID == NCN.UCID)
{
InList = true;
continue;
}
}

// If not, add it
if (!InList)
{
// Assign values of new connnnection.
clsConnection NewConn = new clsConnection();
NewConn.UniqueID = NCN.UCID;
NewConn.Username = NCN.UName;
NewConn.PlayerName = NCN.PName;
NewConn.IsAdmin = NCN.Admin;
NewConn.Flags = NCN.Flags;
Connections.Add(NewConn);
}
}
private void RemoveFromPlayersList(Packets.IS_PLL PLL)
{
// Copy of item to remove
clsPlayer RemoveItem = new clsPlayer();
// Check what item the player had
foreach (clsPlayer Player in Players)
{
if (PLL.PLID == Player.PlayerID)
{
// Copy item (Can't delete it here)
RemoveItem = Player;
continue;
}
}
// Remove item
Players.Remove(RemoveItem);
}
private bool AddToPlayersList(Packets.IS_NPL NPL)
{
bool InList = false;
// Check if player is already in the list
foreach (clsPlayer Player in Players)
{
if (Player.PlayerID == NPL.PLID)
{
Player.AddedMass = NPL.H_Mass;
Player.CarName = NPL.CName;
Player.Flags = NPL.Flags;
Player.Passengers = NPL.Pass;
Player.Plate = NPL.Plate;
Player.PlayerType = (clsPlayer.enuPType)NPL.PType;
Player.SkinName = NPL.SName;
Player.Tyre_FL = NPL.Tyre_FL;
Player.Tyre_FR = NPL.Tyre_FR;
Player.Tyre_RL = NPL.Tyre_RL;
Player.Tyre_RR = NPL.Tyre_RR;
return true;
}
}
// If not, add it
if (!InList)
{
// Assign values of new player.
clsPlayer NewPLayer = new clsPlayer();
NewPLayer.AddedMass = NPL.H_Mass;
NewPLayer.CarName = NPL.CName;
NewPLayer.Flags = NPL.Flags;
NewPLayer.Passengers = NPL.Pass;
NewPLayer.Plate = NPL.Plate;
NewPLayer.PlayerID = NPL.PLID;
NewPLayer.UniqueID = NPL.UCID;
NewPLayer.PlayerName = NPL.PName;
NewPLayer.PlayerType = (clsPlayer.enuPType)NPL.PType;
NewPLayer.SkinName = NPL.SName;
NewPLayer.Tyre_FL = NPL.Tyre_FL;
NewPLayer.Tyre_FR = NPL.Tyre_FR;
NewPLayer.Tyre_RL = NPL.Tyre_RL;
NewPLayer.Tyre_RR = NPL.Tyre_RR;
Players.Add(NewPLayer);
}
return false;
}
// Returns an index value for Connections[] that corresponds with the UniqueID of a connection
public int GetConnIdx(int UNID)
{
for (int i = 0; i < Connections.Count; i++)
{
if (Connections[i].UniqueID == UNID) { return i; }
}
return 0;
}
// Returns an index value for Players[] that corresponds with the UniqueID of a player
public int GetPlyIdx(int PLID)
{
for (int i = 0; i < Players.Count; i++)
{
if (Players[i].PlayerID == PLID) { return i; }
}
return 0;
}
#endregion
// Form load
private void Form1_Load(object sender, EventArgs e)
{
try
{
// Connect to InSim
cfg = new ConnectionSettings("127.0.0.1", 29999, 0, Flags.InSimFlags.ISF_MCI | Flags.InSimFlags.ISF_MSO_COLS, '!', 1000, "password", "My App");
InSim = new InSimInterface(cfg);
InSim.Connect();
// Leave this
Thread.Sleep(500);
// Request all players and connections
InSim.Send_TINY(Enums.Tiny.TINY_NPL, 255);
InSim.Send_TINY(Enums.Tiny.TINY_NCN, 255);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
// Close button
private void btnClose_Click(object sender, EventArgs e)
{
InSim.Close();
Application.Exit();
}
////////////////// PACKET ARRIVAL ////////////////// (Uncomment a line in InitializeInSimEvents to enable other events)
private void NPL(Packets.IS_NPL NPL)
{
bool LeavesPits = AddToPlayersList(NPL);
}
private void NCN(Packets.IS_NCN NCN)
{
AddToConnectionsList(NCN); // Adds new player to the Connections[] list (don't remove line!)
Debug.WriteLine(NCN.UCID.ToString() + " NCN");
}
private void CNL(Packets.IS_CNL CNL)
{
RemoveFromConnectionsList(CNL);
}
private void CPR(Packets.IS_CPR CPR)
{
foreach (clsConnection c in Connections)
if (c.UniqueID == CPR.UCID)
{
c.PlayerName = CPR.PName;
}
foreach (clsPlayer p in Players)
if (p.UniqueID == CPR.UCID)
{
p.PlayerName = CPR.PName;
p.Plate = CPR.Plate;
}
}
private void PLL(Packets.IS_PLL PLL)
{
RemoveFromPlayersList(PLL);
}
private void TOC(Packets.IS_TOC TOC)
{
Players[GetPlyIdx(TOC.OldUCID)].UniqueID = TOC.NewUCID;
Players[GetPlyIdx(TOC.OldUCID)].PlayerID = TOC.PLID;
}
}
}

if you do as the same as ive done there in your version you will have the !pitlane Command working
lol nice one mate . Never would've figured that on my own! Can I not uncomment all of them so that there won't be a need to do it each time I want to use one?

Pitlane works perfectly, nice one! One question though: If someone ingame advises someone else to use !pitlane, won't that be counted as them having said !pitlane?

EDIT: Is that the best way to make ! commands?
Well if you uncomment all of them its point less, because your making events and not using them also C# wont let you compile it, just uncomment what you need when you need, you will get the hang of it soon
-
(JasonJ) DELETED by JasonJ
Quote from dougie-lampkin :
EDIT: Is that the best way to make ! commands?

It's just matter of string parsing. You should test the first char for '!' (or whatever char you set for custom command) and split the rest of the string with a space as delimeter. Then get the first element which should be your command and the rest of the elements are parameters in case you need them. Then throw the command in a switch statement and perform the action you like.

There are a lot of 'C# string manipulation' tutorials on the web that can help you out.

Hope it helps.
I hate to ask again, but I can't find any event handler for the CompCar class (used for speed, direction, etc.) in that list. I presume it needs to be included as the function CompCar.speed won't work...

EDIT: Actually, I found that it's included in the IS_MCI event handler. But now it won't work because I don't know how to use the Speed function contained in struct CompCar. How do I access this? I tried

private void MCI(Packets.IS_MCI MCI)
{
string str1 = MCI.Speed.ToString();
InSim.Send_MST_Message(str1);
}

(first line is to convert the speed (ushort) into a a string. Don't know if thats the right method, but it's the best I could come up with...), but speed isn't contained directly in MCI. How do I tell it to go into struct CompCar (which contains speed)?

Much thanks
Use the MCI
Quote from dougie-lampkin :I hate to ask again, but I can't find any event handler for the CompCar class (used for speed, direction, etc.) in that list. I presume it needs to be included as the function CompCar.speed won't work...

EDIT: Actually, I found that it's included in the IS_MCI event handler. But now it won't work because I don't know how to use the Speed function contained in struct CompCar. How do I access this? I tried

private void MCI(Packets.IS_MCI MCI)
{
string str1 = MCI.Speed.ToString();
InSim.Send_MST_Message(str1);
}

(first line is to convert the speed (ushort) into a a string. Don't know if thats the right method, but it's the best I could come up with...), but speed isn't contained directly in MCI. How do I tell it to go into struct CompCar (which contains speed)?

Much thanks

MCI.speed doesnt exist MCI.Info is where you will find the speed and all the values the compcar has
Quote from mcgas001 :Use the MCI

lol i found that seconds after post (I really should read the writing around the function I need lol)! I know CompCar is contained in MCI.Info, but how do I use only the speed function?
Quote from dougie-lampkin :lol i found that seconds after post (I really should read the writing around the function I need lol)! I know CompCar is contained in MCI.Info, but how do I use only the speed function?

InSim.Send_MST_Message("Speed : " + MCI.Info[X].Speed);

try that but where X is will equal a player number from the players list, so if only you in the list (only you driving) it will be 1 or 0, but remember that the MCI.Info only carrys 8 players....
Quote from mcgas001 :InSim.Send_MST_Message("Speed : " + MCI.Info[X].Speed);

try that but where X is will equal a player number from the players list, so if only you in the list (only you driving) it will be 1 or 0, but remember that the MCI.Info only carrys 8 players....

Thanks for your help mate. What happens if there are more than 8? Are only the first 8 taken? And is there a class that will take more than 8? (Maybe use the PLID to tell it to take after PLID 8 somehow?)
nope if theres more than 8 there will be more compcars in the packet
Quote from mcgas001 :nope if theres more than 8 there will be more compcars in the packet

No, there will be more MCI packets, not just compcars. Lets say you have 18 clients in a host, then there will be sent 3 MCI packets in a row. And the first 2 elements of the .Info struct in the latest MCI packet are valid players. The other elements contain rubbish, you must ignore them. I have to fix this in the future.

EDIT: oh and btw, for additional info on the packets, you can read insim.txt located in you lfs/docs folder.
Quote from T-RonX :No, there will be more MCI packets, not just compcars. Lets say you have 18 clients in a host, then there will be sent 3 MCI packets in a row. And the first 2 elements of the .Info struct in the latest MCI packet are valid players. The other elements contain rubbish, you must ignore them. I have to fix this in the future.

EDIT: oh and btw, for additional info on the packets, you can read insim.txt located in you lfs/docs folder.

ok you know more then me LOL
LOL A couple more questions: The first one, I can't make any sense of it: I made a simple speed warning, where if the player goes over 62mph (9360 game units) then a message comes up saying "Speeding Alert : "players name" ". However, when I have it set the x set to 0, and I go over 63mph, it says "Speeding Alert: TEAM SPIRIT HOST" which is the name of the host connection. Here's the code:

if ((MCI.Info[0].Speed) > (9360))
{
InSim.Send_MST_Message(
"/msg ^7Speeding Alert! : ^1" + Connections[GetConnIdx(MCI.Info[0].PLID)].PlayerName);
}

I've had to use PLID for the connection ID scan because MCI doesn't send UCID (which IMO it should...). But they are both set to 0, so surely they should be watching the same connection?


Thanks for all the help guys, much appreciated! (This is why there should be a special sub-forum for those learning InSim IMHO)
Quote from dougie-lampkin :LOL A couple more questions: The first one, I can't make any sense of it: I made a simple speed warning, where if the player goes over 62mph (9360 game units) then a message comes up saying "Speeding Alert : "players name" ". However, when I have it set the x set to 0, and I go over 63mph, it says "Speeding Alert: TEAM SPIRIT HOST" which is the name of the host connection. Here's the code:

if ((MCI.Info[0].Speed) > (9360))
{
InSim.Send_MST_Message(
"/msg ^7Speeding Alert! : ^1" + Connections[GetConnIdx(MCI.Info[0].PLID)].PlayerName);
}

I've had to use PLID for the connection ID scan because MCI doesn't send UCID (which IMO it should...). But they are both set to 0, so surely they should be watching the same connection?


Thanks for all the help guys, much appreciated! (This is why there should be a special sub-forum for those learning InSim IMHO)

There is a Players list and a Connections list. The Connections list holds all clients in the server, while the Players list holds all cars on the track. The reason behind this is in the InSim.txt file.
But you have to use it like this:

Connections[GetConnIdx(Players[GetPlyIdx(MCI.Info[0].PLID)].UniqueID)].PlayerName

Insim: Once And For All!
(52 posts, started )
FGED GREDG RDFGDR GSFDG