The online racing simulator
Searching in All forums
(921 results)
DarkTimes
S2 licensed
Quote from SimulatorRental.com :Because 1IL font issues, is my guess.

LFS 0.6L

Looks fine to me. Smile
DarkTimes
S2 licensed
Thanks for all these updates Scawen, especially all the love paid to InSim.

However, I do need to ask, why did it go from K to M? I know school was never my strong point but I'm pretty sure there is another letter inbetween. Big grin
Last edited by DarkTimes, .
DarkTimes
S2 licensed
One valid complaint I've received in the past is that there aren't many good example InSim.NET programs, so I've written a small one. It is a Windows Forms app that connects to either a local client or a host and outputs all the laps which are completed. As I say very simple stuff. I'll probably try and write some more examples at some point, with more involved stuff like commands and buttons.

You can find the code on GitHub: https://github.com/alexmcbride/insimdotnetexamples
Last edited by DarkTimes, .
DarkTimes
S2 licensed
InSim.NET 2.3.0 release out on GitHub and NuGet.
  • Updated for LFS 0.6M - a very large number of new packets and changes (see lfs\docs\insim.txt for details)
  • Library now uses InSim version 7
  • InSim object no longer throws ObjectDisposed exception when being reused to connect to LFS
  • Fixed encoding issue that occasionally caused garbled strings to be sent to LFS
  • Changed InSim.Send(IEnumerable<ISendable>) method to InSim.Send(params ISendable[]) which provides better syntax
  • Fixed missing VIEW_ANOTHER identifier in ViewIdentifiers
  • Added new StringHelpers: StripLanguage(string), Strip(string), Unescape(string), and Escape(string)
  • Added Rockingham to TrackHelper
Does anyone actually use the GitHub release? I can't see why anyone would use that instead of NuGet, but anyway it doesn't take any effort to put it out. Let me know about any problems. Smile
Last edited by DarkTimes, .
DarkTimes
S2 licensed
OK - another small update. I have implemented something I had intended to for a long time, namely InSim.NET now fully supports the .NET async/await pattern.

So you can do:

await insim.InitializeAsync(new InSimSettings {
// init settings
});

And you can do:

await insim.SendAsync(new IS_TINY { ReqI=1, SubT=TinyType.TINY_NCN });

The async methods are non blocking and useful when doing things like making GUI apps. All the send methods have been updated to optionally use this pattern.
DarkTimes
S2 licensed
Release Plan

I should probably talk about the release plan a bit more fully. Basically whenever Scawen brings out the next patch for LFS I will bring out InSim.NET 2.3.0.

After that I will have to stop working on the library for a bit. I am at college at the moment and I have numerous essays and assessment to complete, as well as having to create working prototypes for two android apps by the end of the month.

I have messed around with a lot of things over the last couple of weeks (EventHelper, BatchHelper etc..), but truth is all that stuff needs much more testing and I don't have the time to do it. So I will remove those classes from the library at the moment. The next release will just be all the new InSim updates.

String Encoding Update

One thing I've not mentioned is the string encoding, I'm happy with my new way of encoding strings but it's complicated at not tested fully, so I don't want to drop it into the library proper yet. Instead what I've done is made it so people can implement their own string encoding. It's always been a large area of contention, everyone seems to think I'm doing it wrong in some way, so I figured I'd let people make their own.

So: LfsEncoding is now an abstract class that implements two abstract methods, GetString and GetBytes. GetString is called when packets are received and converts an array of bytes into a unicode string. GetBytes gets called when packets are being sent and converts a unicode string into an array of bytes.

Once you have implemented your own encoding you can make InSim.NET use it by assigning it to the new LfsEncoding.Current static property.

LfsEncoding.Current = new MyCustomEncoding();

You should probably do this at the start of your program before you init InSim. All this is optional, if you don't supply a custom encoding InSim.NET defaults to the old one.

The default encoding is called LfsUnicodeEncoding, that's the one people have been using for years (albeit with the big bug fix I talked about last week). However, I also added LfsUnicodeEncoding2 which is my new reworked string handling, so that's there if people want to try it out.

Anyway, that's the plan. Smile
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Whenever Scawen releases the new patch. Probably this weekend.
DarkTimes
S2 licensed
The IS_OCO packet works fine, I tested all aspects of it. I don't know what your issue is so you might need to go into more detail. The problem I was having was that I wasn't optimising the layout before trying to use the lights.
DarkTimes
S2 licensed
Quote from Degats :You don't have to reload, just press the optimise button (or set the flag if loading via insim). That was mentioned a few posts ago.

OK sorry, I didn't understand that bit.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Yes, I meant those little portable start light things.

Anyway, I figured out the problem, you need to add the AXO_START_LIGHTS objects to a layout, save the layout and then reload it for them to start working. Maybe this was common knowledge, I don't know much about AutoX or the layout editor.
DarkTimes
S2 licensed
Can I get some clarification on how the IS_OCO packet is supposed to work, as I can't get it to change the AutoX start lights. The main start lights work OK.

I set the Data to the bulb bits I want to show, I set the Index to AXO_START_LIGHTS (149), I set the Identifier to whatever its set to in the editor, and I set the Action to OCO_LIGHTS_SET (5). However I cannot get the AutoX lights to change. If I set the Index to OCO_INDEX_MAIN then the main start lights change fine.

Can else someone else check that they can get the AutoX lights to work?
Last edited by DarkTimes, .
DarkTimes
S2 licensed
OK thanks, I just had a quick glance at it, but it looks fine. You missed one little thing though, before InSim.NET will handle that packet you need to add it to the PacketFactory. I'll look at it in more detail when I get home this evening.

I reckon the BulbInfo works fine, if you set Red1 it enables the innermost light, Red2 turns on the middle light, Red3 turns on the outermost light, and Green turns on the green light. You need to remember that these are bit flags, so if you want to combine lights you'll need to combine flags.

So if you wanted to turn on all lights at once you'd do:

Data = BulbInfo.Red1 | BulbInfo.Red2 | BulbInfo.Red3 | BulbInfo.Green;

If you wanted to turn on just the inner and outermost red lights you'd do:

Data = BulbInfo.Red1 | BulbInfo.Red3;

That's how it seems to work for me anyway. I'm not sure about the AutoX lights, I might need to ask Scawen to explain exactly how they're supposed to work.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Sure feel free to have a go. Smile

If not then I'll do it tomorrow.
DarkTimes
S2 licensed
Yes, I read that, that's not the problem.
DarkTimes
S2 licensed
I can change the main start lights but not the AutoX ones. I don't know if I'm doing something wrong. I set the data bits correctly, I set index to AXM_START_LIGHTS, I set the action to OCO_SET_LIGHTS and the identifier to the correct one for my start light object. But I can't get it to work.
DarkTimes
S2 licensed
OK - I fixed the BulbInfo issue. I can change the main start lights, I'll need to look into the other layout stuff.

This packet will set the main start lights to red for instance.

insim.Send(new IS_OCO {
Data = BulbInfo.Red1,
Index = IS_OCO.OCO_INDEX_MAIN,
OCOAction = OCOAction.OCO_LIGHTS_SET,
});

DarkTimes
S2 licensed
I have decided, along with others on this forum, to stop responding to requests from demo users. People without an account who actually need to email me will be able to figure out how. From now on I will only answer support requests from people who have an S1 license or higher.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
OK - I've looked into those two options and they seem to work fine for me. I can send a TINY_SEL and LFS replies with a IS_AXM containing only the objects that are currently selected. I can send a IS_AXM with PMO_SELECTION set and it will select the specified objects.

Exactly what issue are you having?
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Sorry about the missing PMOFlags cast, I updated the code quickly last night, I forgot about that bit.

That text issue does look like the bug PeterN is describing. I don't see those dots on my LFS. I attached a screenshot with the result of sending a button with those characters to my local LFS instance. I tried messing with the language and font selection but I couldn't reproduce it.

Quote :Changes from 0.6K17 to 0.6K18 :

InSim :

Added TINY_SEL to request an IS_AXM with layout editor selection
New IS_AXM option PMO_SELECTION to set the current editor selection

I'll look into it this evening.
DarkTimes
S2 licensed
Quote from sicotange :I hate to bring you the bad news, I hope it is an easy fix (?) (see attachment).

The strings above give the following output (EXIT_BUTTON_RED should have been a red cross in upper right corner):

OK - I have figured this out. I've only looked at the first one but the others are the same.

The reason you're seeing the wrong text is because you're actually using a bit of a weird hack to get the Chinese multiplication symbol × to show. I will explain that hack in detail below, but for now you should remember that InSim.NET uses unicode to represent strings. Then when you send packets to LFS the library converts the unicode into a format that LFS can understand.

The solution then is to just use the actual unicode versions of the characters that you want to send, so to display that Chinese multiplication symbol you would just send that character:

<?php 
public const string EXIT_BUTTON_RED "^1^S×";
?>

Or you can even specify its unicode codepoint precisely.

<?php 
public const string EXIT_BUTTON_RED "^1^S\u00D7";
?>

Now I will explain the reason that this hack sort of worked. If you don't know much about character encodings and unicode then read this first.

The string ¡Á that you were sending is made up of two characters. At first this confused me, why would you be sending two seemingly random characters and expecting to get one Simplifed Chinese one? Of course Simplfied Chinese is a DBCS (double byte character set), each character above 127 is represented by two bytes, a lead byte that defines a page within that codepage and a trailing byte that defines the specific character.

I looked up the byte values for the two ASCII characters ¡Á and they came to 0xA1 and 0xC0 respectively. I then looked up the those bytes in the Simplified Chinese charset (cp936). So if you take 0xA1 as the lead byte it takes you to this page, then if you lookup 0xC0 you'll see it takes you to the unicode codepoint \u00D7, which is the Chinese multiplication symbol.

So basically by putting in the ASCII chars ¡Á and forcing the codepage to Simplified Chinese you were able to display the character ×.

And that's why that worked. But you don't need to do that, just use unicode.

Edit: OK - just to help you out these are the three unicode characters you're using.
  • \u00D7
  • \u25B2
  • \u25BC
Last edited by DarkTimes, .
DarkTimes
S2 licensed
OK - thanks. I'll look into all these issues.
DarkTimes
S2 licensed
OK - I have rewritten the LfsEncoding class. It still converts the LFS encoded string to unicode, but it also now leaves the language tags intact. Then when converting from unicode back into LFS strings it tries first to use the encoding specified in the tags, only when it doesn't find the codepoint in that encoding does it look up its own.

I've been messing around with this today and I think it's a much better solution than how it was handled before, which was difficult to understand and the root of many bugs. The string encoding stuff is now very simplified, it converts the strings to unicode but it tries to leave everything else untouched.

Because of this I have reworked the StringHelper class to add more stuff.
  • StringHelper.StripColors(string) - removes colour codes from a string
  • StringHelper.StripLanguage(string) - remove language codes from a string
  • StringHelper.Escape(string) - Escapes all LFS special characters (e.g. ^, |, ? etc..)
  • StringHelper.Unescape(string) - Unescapes the LFS special characters (e.g. ^v, ^q etc..)
  • StringHelper.Strip(string) - Strips colour and language tags, and also unescapes the string. This is what you would use if you were going to display the string in your own UI.
All of this code is freshly written, there was a lot to change, and almost certainly it will have bugs.

This quite a big change to the library. For now all you need to know is that InSim.NET no longer tries to hide language tags (^L, ^J etc..) from you. These will appear in strings sent from LFS but also you can use them to hint to InSim.NET what the correct encoding for a string is.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I know about the issue with the string encoding not being lossless. The bug I have fixed was one where sometimes stray language tags could sneak in to the output and that would cause strings to be garbled in LFS. The solution was to make sure there were no existing tags in the string before Insim.NET started to convert it.

I've been thinking about the string stuff this morning and I may have had an idea. Up until now I've been converting the strings to unicode and removing the language tags (^C, ^J etc..). But what if I just left those in? That way when concerting back to LFS strings I could use those as hints for which codepage to use.

For instance if you had this unicode string:

"^Ltesting testing ^J捨捦べ 裃壎 ず愦ひ嶥鄥"

It could see that the Japanese codepage is being suggested, so it will look for the codepoint in that codepage first, if it didn't find it then it would search the rest.

The only drawback is that any program that displayed strings in its own UI would need to remove language tags before displaying them, however I could just add a new StringHelper.StripTags(string) method.

I might have a go at implementing this today.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I think I might have just figured out a very large bug in the string encoding class that's beset InSim.NET for a long time. It is the bug that was reported in this post a few months ago. It's hard to say right now but this might be the root cause of a lot of the string encoding problems people have been experiencing. Whatever the results I think I've definitely fixed that bug that I linked. I've not uploaded the fix yet as I'll need to rewrite my hacky fix into nice neat efficient code. However, I'm cautiously optimistic that I've taken a big step forward.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from sicotange :I have a note somewhere about this. I will get back to you once I can give you info on how to reproduce it easily.

OK - thanks! It's possible I've looked at this before and don't remember, but if you could find some steps to reproduce the error that would be great.

Quote :For example, you have a panel of 200 buttons. All 47 players of a full server should be shown this panel at the same time. I'm looking for the best & fastest way to do this. Same for buttons who get updated often (text updates every 100ms of several buttons for example). Basically a way to queue packets, making batches and send them at appropriate intervals. You master this stuff. I don't have enough knowledge about sockets & netcode to implement this well.

This may be a silly question, but what's the problem that occurs when you send all those buttons to all those players? Is it that there is an error, does the connection close, does LFS grumble, or is it just really slow? I know we may have talked about this before, but I don't work on the library often and so will forget things. The main problem is that I don't have a server with 47 players to test it on, I just test on my own machine, and in that case I can send 239 buttons each with 240 characters of text over and over again and it works fine.

Quote :Thanks for the library updates (EventHelper & 0.6K13). I will test EventHelper once I'm done updating my program with IS_UCO & IS_JRR.

I was going to post about the EventHelper, it's an experimental thing I knocked together in a short while. Basically, I thought the best way to deal with multiple hosts was just to be able to think of them as one host. So EventHelper is a wrapper that wraps a collection of InSim objects, when you bind a packet or send a packet, it loops through the collection of hosts and performs the operation on all of them. Here is some code to demonstrate:


<?php 
void Test
() {
    var 
hosts = new EventHelper();

    
// Add the settings for each host you want to connect to
    
hosts.AddInSim(new InSimSettings {
        
// host 1 settings
    
});
    
hosts.AddInSim(new InSimSettings {
        
// host 2 settings
    
});
    
hosts.AddInSim(new InSimSettings {
        
// host 3 settings
    
});

    
// Bind packets and events as normal
    
hosts.InSimError += hosts_InSimError;

    
// when you bind a packet or event it's bound to all the InSim objects
    
hosts.Bind<IS_STA>(StateChanged);

    
// Initialize all the hosts you added earlier.
    
hosts.Initialize();

    
// You can send a packet to all hosts.
    
hosts.Send(new IS_TINY ReqI 1SubT TinyType.TINY_SST });
}

void hosts_InSimError(object senderInSimErrorEventArgs e) {
    
// the sender object is the host that raised the event.
    
InSim insim = (InSim)sender;
}

void StateChanged(InSim insimIS_STA packet) {
    
// the insim parameter is the host that received the packet, so you can use it to send a packet back
    
insim.Send("got yer state"); 
}
?>

I hope that makes sense. As I say I put it together this morning, it just a rough idea right now. I may well change the name to HostsHelper, or something else. I don't think EventHelper is very descriptive.
Last edited by DarkTimes, .
FGED GREDG RDFGDR GSFDG