The online racing simulator
Here is some extra debugging.

-Spectating(shift+s)-
1st Line: Im going into spectate
2nd Line: PLL packet for spectating
-Joining(shift+j)
3rd Line: MCI error comes up. Object not set is the "Player" collection.
4th Line: Message that I joined comes up.
5th Line: Calling NPL
6th Line: Finished the call of NPL.
Attached images
lfs_00000225.PNG
This isn't an InSim.NET bug and not an issue InSim.NET can deal with by itself.
LFS will always send CompCars for all cars on the playerlist and occasionally an MCI is due and sent after the player is added to the list but before the NPL is sent.
Hey all, my internet has been down since Thursday, so I've not been able to get on. It's fixed now so I'll look into these bugs!

In terms of the MCI issue, as Morpha says sometimes you can get a MCI before all the NPL packets have been received, so your internal connection list won't be complete.

Edit: You simply need to check that the player for that CompCar exists in your connection list before processing it. This is nothing to do with InSim.NET, it's just an artefact of the way InSim works. InSim.NET does not track the state of LFS (except whether the socket is connected), so you need to handle these sorts of synchronisation issues in your own code.

This is what I normally do in my MCI handler.

void MultiCarInfo(InSim insim, IS_MCI mci) {
foreach (var car in mci.Info) {
IS_NPL npl;
if (_players.TryGetValue(car.PLID, out npl)) {
// Deal with CompCar
}
}
}

Quote from misiek08 :Maybe packet are not queued

What do you mean 'queued'? InSim.NET does not queue packets, it raises the packet event the second the packet is received. Any synchronisation issues like this need to be handled in your own code. As I say above, InSim.NET does not have any knowledge of the state of LFS.
Quote from Whiskey :This piece of code is returning me rear tyres and then front tyres. Is it me misunderstanding something or is it really inverted?

static void PitStop(InSim insim, IS_PIT pit)
{
Console.WriteLine(pit.Tyres.FrontLeft);
Console.WriteLine(pit.Tyres.FrontRight);
Console.WriteLine(pit.Tyres.RearLeft);
Console.WriteLine(pit.Tyres.RearRight);
}


I must have gotten them mixed up, I've fixed it.
Updated 2.0.11 beta to CodePlex.
  • Renamed AutoXActionFlags to just ActionFlags
  • REO and AXM now throw an exception when too many PLIDs or objects added
  • AXM and REO now accept an IEnumerable with their sub-packet thingies
  • Added ReplayOptions.RIPOPT_FULL_PHYS
  • Changed AXM.Info from ICollection to IList
  • Added PLID property to OutGaugeEventArgs
  • Size field in BTN and MTC now updates to correct size after those packets are sent
  • Fixed error with index in EncodingHelper.GetBytes
  • Fixed crash when string was too long and was at the end of a packet
  • Fixed bug in Tyres class
Great work as always! Everything is working great for me.

By far one of the best InSim libraries available!
I've been working on InSim.NET 3.0, that I intend to use to clear up certain annoyances I have with the library currently.

The main issue is that, when InSim.NET 1.0 was written, it was intended to be used with InSimSniffer, which put certain constraints on its design. Firstly it had to match the original InSim protocol as closely as possible, this meant using Scawen's naming conventions and other stuff like that. The rest of the library, stuff what I made, was written to .NET naming conventions. This means the library currently mixes naming conventions, which is an annoyance to me. It also means that some things are harder to do that they could be, which has really come to forefront recently with values containing low/high bits, such as the RST Timing. So I first of all want to clear all that up and rewrite the InSim stuff to .NET conventions, and also add lots of stuff to make using the actual packets much simpler. Obviously this means breaking backwards compatibility.

I've also got very tried of having to laboriously type out the packet handlers each time, and while of course you can write a codesnippet to do it for you, they would work better as events. So the second thing I plan to do is to make each packet a proper .NET event.

Basically the plan is to make InSim.NET 3.0 a higher level library, where appropriate. I think a balance between low and high level, in terms of the API, is what I'm looking for these days.

I've already written most of this, and might try to release a beta/alpha version soon, but I just thought I'd mention it now so as no one is surprised when it comes out. I'm going to fork the CodePlex repository at some point (I'm just working off local repositories at the moment), so the existing codebase and releases will remain, so you won't need to upgrade if you don't want to.
That looks promising, good luck with that!
Quote from DarkTimes :I've been working on InSim.NET 3.0, that I intend to use to clear up certain annoyances I have with the library currently.

The main issue is that, when InSim.NET 1.0 was written, it was intended to be used with InSimSniffer, which put certain constraints on its design. Firstly it had to match the original InSim protocol as closely as possible, this meant using Scawen's naming conventions and other stuff like that. The rest of the library, stuff what I made, was written to .NET naming conventions. This means the library currently mixes naming conventions, which is an annoyance to me. It also means that some things are harder to do that they could be, which has really come to forefront recently with values containing low/high bits, such as the RST Timing. So I first of all want to clear all that up and rewrite the InSim stuff to .NET conventions, and also add lots of stuff to make using the actual packets much simpler. Obviously this means breaking backwards compatibility.

I've also got very tried of having to laboriously type out the packet handlers each time, and while of course you can write a codesnippet to do it for you, they would work better as events. So the second thing I plan to do is to make each packet a proper .NET event.

Basically the plan is to make InSim.NET 3.0 a higher level library, where appropriate. I think a balance between low and high level, in terms of the API, is what I'm looking for these days.

I've already written most of this, and might try to release a beta/alpha version soon, but I just thought I'd mention it now so as no one is surprised when it comes out. I'm going to fork the CodePlex repository at some point (I'm just working off local repositories at the moment), so the existing codebase and releases will remain, so you won't need to upgrade if you don't want to.

Will the OutSim Packet handlers still be overridable? I haven't got around to building it yet, but it looked like the best way to handle other games was simply to override and parse the packets myself. In theory, it would be a tidy implementation.
Yes, still overridable, the OutSim and OutGauge stuff's not really changing.
I noticed a bug on my little program, that buttons are not showing up when playing online.

Its a local InSim program and when typing /o friends it should pop up the buttons shown in this image.

I was using UCID = MSO.UCID at my code, to create the buttons as by typing /o friends it should create them, but even with UCID = 0 or UCID = 255 it is not working either.

While at SinglePlayer UCID = MSO.UCID was working fine. Is it a bug of my code or what?
I don't know the answer. You might need to add ISF_LOCAL to the initialization flags.

insim.Initialize(new InSimSettings {
Flags = InSimFlags.ISF_LOCAL,
});

Thank you DarkTimes it worked! Uploading a new version soon.
On a separate note, there is a new free disassembler from Telerik called JustDecompile. It's a nice alternative to Reflector, which is no longer free. I've been using it quite a bit recently and it's quite good.

http://www.telerik.com/products/decompiling.aspx
I was thinking of creating a new project called InSim.NET Contrib, where people could contribute helper classes to the library. I would first of all move the current helper classes to the new project, then let other people join as contributors, so they could add their own extensions.

Often people need to reuse a lot of the same code over and over in their programs, such as connection managers and button managers, but at the same time this sort of code doesn't belong in the library itself. By creating a contrib lib it would allow people to contribute commonly used helpers, plus pick and choose which helpers they wanted, all without messing with the integrity of the base library. It would also mean that people would all be using the same 'best possible' versions of the code they need, instead of having to write it again from scratch each time.

A good example of a similar project is ASP.NET MVC Contrib, that adds tonnes of extra functionality to Microsoft's excellent Web toolkit. Anyway it was just an idea, and would require input from other programmers, but I think it would be nice to be able to add lots of high-level helper classes without having to mess with the library itself.

Let me know if anyone would be interested in this, as there is no point me doing it if I'm the only person who cares.
I think this is a brilliant idea. It would be so awesome! I don't even know what else to say... IMO - go for it!
Pushed InSim.NET 2.0.12 to release.

Changes
  • TcpSocket and UdpSocket now deal better with corrupted packets
  • Fixed bug in TcpSocket.Send when full buffer isn't sent
You can find the latest release on CodePlex. As always let me know of any issues!
Quote from DarkTimes :

<?php 
CarFlags GetCarsFlags
(IEnumerable<stringcars) {
    
CarFlags flags 0;
    foreach (
string car in cars) {
        
flags |= (CarFlags)Enum.Parse(typeof(CarFlags), cartrue);
    }
    return 
flags;
}

// Use it like this.
CarFlags c GetCarsFlags(new string[] { "UF1""XFG""FBM" });

// Or like...
insim.Send(new IS_PLC {
    
UCID ucid,
    
Cars GetCarFlags(new string[] { "UF1""XFG""FBM" } ),
});
?>


Of course it's probably easier to just send an IS_MST /cars command, and it's simpler code as well.


<?php 
string GetCarString
(IEnumerable<stringcars) {
    return 
String.Format("/cars={0}"String.Join("+"cars));
}

// Use it like this...
insim.Send(GetCarString(new string[] { "UF1""XFG""FBM" }));
?>

The InSim.Send(string) method detects that the string is a command and sends an IS_MST for you.
I would like to ask something related about efficiency..

I have a comand like !top , which shows best laps and bla bla. The problem is that sometimes, when an user request that list, got disconected.

The way i´m sending those buttons are:

insim.Send(new IS_BTN { Text = blanco + "Pista: " + amarillo + strArray[1] + "(" + strArray[2] + ") ", BStyle = ButtonStyles.ISB_LEFT | ButtonStyles.ISB_DARK, UCID = mso.UCID, H = 6, W = 70, T = 30, L = 15, ClickID = 8, ReqI = 8 });
insim.Send(new IS_BTN { Text = blanco + "Coches: " + amarillo + strArray[4], BStyle = ButtonStyles.ISB_LEFT | ButtonStyles.ISB_DARK, UCID = mso.UCID, H = 6, W = 70, T = 36, L = 15, ClickID = 9, ReqI = 9 });
and more BTNs, up to 30...

The question is, is this the correct way of doing this? Or there are better ways?
Try using ReqI = 255 to all buttons instead of being same with ClickID, although i dont think this is the problem.
Quote from NeOn_sp :I would like to ask something related about efficiency..

I have a comand like !top , which shows best laps and bla bla. The problem is that sometimes, when an user request that list, got disconected.

The way i´m sending those buttons are:

insim.Send(new IS_BTN { Text = blanco + "Pista: " + amarillo + strArray[1] + "(" + strArray[2] + ") ", BStyle = ButtonStyles.ISB_LEFT | ButtonStyles.ISB_DARK, UCID = mso.UCID, H = 6, W = 70, T = 30, L = 15, ClickID = 8, ReqI = 8 });
insim.Send(new IS_BTN { Text = blanco + "Coches: " + amarillo + strArray[4], BStyle = ButtonStyles.ISB_LEFT | ButtonStyles.ISB_DARK, UCID = mso.UCID, H = 6, W = 70, T = 36, L = 15, ClickID = 9, ReqI = 9 });
and more BTNs, up to 30...

The question is, is this the correct way of doing this? Or there are better ways?

Just so we're clear, the user disconnects from the host when you send too many buttons? That sounds like you are just sending someone more data than their connection can manage. When you send the buttons they first get sent to the host, then the host sends them to each player. It isn't really InSim.NETs fault if someone can't cope with all the data the dediserver is sending them.

One thing you could try is batch sending the buttons, but if the user is disconnecting from the dediserver then that probably won't help.


<?php 
// Create list of buttons.
var buttons = new List<IS_BTN> {
    new 
IS_BTN /* button 1 */ },
    new 
IS_BTN /* button 2 */ },
    new 
IS_BTN /* button 3 */ },
    
// Etc...
};

// Send list in one go.
insim.Send(buttons);
?>

When batch sending packets in this way the data is sent in a single send call, rather than making a separate call for each packet. This can be much more efficient when sending large amounts of packets. Still it would have little effect if the problem lies between the dedi-host and the client.
How can i make /rcm_ply to stay for example 2 seconds and then clear? I've been searching at google for "dynamic" timers or any example but nothing

For now i am using


insim.Send("/rcm ^1New PM from ^2" + _connections[BTT.UCID].PName);
insim.Send("/rcm_ply " + CurrentConnection.UName);

and after 2 or 3 seconds(not sure about the time yet) i want to make it do this insim.Send("/rcc_ply " + CurrentConnection.UName);
Based on my previous post, today i wanted to give one more try and search further about how to do it and i found a solution

Here is what i wanted to do

private void SendRCMToUsername(string Username, string Text, int Duration)
{
insim.Send("/rcm " + Text);
insim.Send("/rcm_ply " + Username);

Timer timer = new Timer { Interval = Duration, AutoReset = false };
timer.Interval = Duration;
timer.Elapsed += delegate { ClearRCMFromUsername(Username); };
timer.Start();
}

private void ClearRCMFromUsername(string Username)
{
insim.Send("/rcc_ply " + Username);
}

Usage:

SendRCMToUsername("DarkKostas", "^1Hi Mom", 5000);

I meant to reply to you and explain to use a timer, but I've been so busy lately I forgot. Still you figured it out yourself anyway. Sorry.
Its ok, thanks anyway. My first searching was failed because i was asleep and didnt think correctly. Then i understood what exactly i wanted to do and a way to parse parameters with timers, so that it worked!

FGED GREDG RDFGDR GSFDG