The online racing simulator
InSim Relay client information
(63 posts, started )
Yup, works now thanks!
Stick it please.
Hi, my name is Luis, I´m new at this and I´m from Mexico y just found this post ,could anyone tell me where can I get information about the extraction of the varaibles from OutSim, I think the UDP package that is sent from LFS has to be read by a programm in VB, C# or python am I right? and then I have to do the communication whit USB or serial port.

I´d like to do a simulator and any information would be nice.

Thanks and regards
I'm not sure how relevant it is to anyone, but I've added the WebSocket protocol (this one) to the relay, making it possible to connect to the relay with a browser directly.
At first I assumed that WebSockets would be following cross domain policies, but it appears they don't, so anyone can use it if they'd want to.

The url to connect to is : ws://isrelay.lfs.net:47474/connect (yep same port as the usual binary protocol).

Another update is that I'm using PHP Sockets now in the relay, rather than Streams, allowing me to use TCP_NODELAY, with the result that packets arrive at the client a bit more in time.

These updates introduced a weird bug that caused hosts to disconnect a few times a day. If you have noticed this, then worry no more as this has been fixed now and the relay should work better than before.
Quote from Victor :I'm not sure how relevant it is to anyone, but I've added the WebSocket protocol (this one) to the relay, making it possible to connect to the relay with a browser directly.
At first I assumed that WebSockets would be following cross domain policies, but it appears they don't, so anyone can use it if they'd want to.

The url to connect to is : ws://isrelay.lfs.net:47474 (yep same port as the usual binary protocol).

Another update is that I'm using PHP Sockets now in the relay, rather than Streams, allowing me to use TCP_NODELAY, with the result that packets arrive at the client a bit more in time.

These updates introduced a weird bug that caused hosts to disconnect a few times a day. If you have noticed this, then worry no more as this has been fixed now and the relay should work better than before.

Very cool Vic.

Ill take a play around when I have some free programming time and try this out. The Websockets sound most interesting.
Do you mean you couldn't connect to the relay with your JS client? Or do you mean you had trouble setting up your own server and couldn't connect to that?
What happened when you tried?

EDIT - i tried your server and it ended with a failed socket_bind.
oh but that was because it tried to bind port 80 while my user wasn't root (oh and port 80 was in use already). So I chose a higher port and that made things work. I could connect with a client, but i haven't tested it further than that.
oops, I missed one part of the websocket uri you should connect to. It's a kind of precaution to prevent most obvious rubbish connections.

The full websocket uri that you must use to connect with a WebSocket is :

ws://isrelay.lfs.net:47474/connect
Quote from Victor :Do you mean you couldn't connect to the relay with your JS client? Or do you mean you had trouble setting up your own server and couldn't connect to that?
What happened when you tried?

No, I mean, my WebSocket server is sending some garbage data that is throwing the connection off, as like time it get's a packet after the handshake the client disconnections or something. I really don't know at this point. I'm so delirious after Hurricane Sandy, this area is a disaster and I could not tell you what I did yesterday yet alone 4 months ago.
Hm yeah, saying you're busy at the moment is kind of an understatement I think.
Good luck with that man.
I'll be happy to show you a solution when you have time again. But it's more than a quick fix and will require a rewrite of your class. But we can talk about that another time.
Well.. Sorta OT but useful. In my first ever attempt at dealing with raw TCP data, I've managed to code (very bad JavaScript) a rough WebSocket connection to the Relay and gathering a HostList. It definitely made me realize too that Javascript is crazy with dealing with binary data. Needing to use ArrayBuffer and DataView to build out a new ArrayBuffer to send or even parse nested packets.

If anyone wants my (crappy) code, I'll be willing to show them, although I concede it's not my best Javascript.


EDIT: I decided to attach my html file to this post. My disclaimer is: It's bad Javascript. I used someone's demo and built off that. It's poorly structured and in some cases very messy. It does however work, which may be its truly greatest asset. I don't handle or deal with any packets other than the initial hostList packet. It refreshes every 10 seconds via a setTimeout.

If anyone uses this in "production".. they are a bad bad person
Attached files
lfsWebSocketTest.html.zip - 3.2 KB - 620 views
Take a look at jspack. It doesn't use any of the new typed buffers, and thus isn't as efficient, but it does give you a very graceful API to work with and it's reliable. It means you can concentrate on making your actual app work

Admittedly I am a little biased on advocating jspack - I use the node-ified version in xi4n and also in the client side MPR parser demo
Here's two JS classes I've just put on GitHub to share.
They are both based on TAA's nodejs versions, so a big credit goes to him.

https://github.com/VictorVanV/ ... ob/master/InsimPackets.js
The Insim packets (structs). I think it currently supports all the racing related packets. There are a bunch like camera packets that I have not implemented yet. Feel free to update it and send me a patch (generic comment to anyone).
I am using my own "pack" and "unpack" methods, based on TypedArrays.

https://github.com/VictorVanV/ ... /blob/master/LfsString.js
Converted to JS, completed the codepage conversion tables to include all characters LFS can use. It's a big file (800KB), so you'll have to apply minification and compression after which it's around 250KB, which is kinda acceptable.
Leave it to the smarter people to produce something awesome :P. Although it does make me contemplate actually making my own packet handler, but making it more "modular". So defining a Global object, which has "register" method exposed, which will just add to its internals any packet that's passed. Makes for nicer organization too, because these could be seperate files.

Looking through Vic/Karl's sweet packet system though is pretty great.
there's one annoyance though imo :

If you use this insim packet stuff inside a worker, then you have to detach all the function properties before the object can be serialized for transfer to the parent thread.
I'm still thinking about this and maybe will remove all the function property assignments in each packet and instead keep those as separate (static) functions. But then the part I'm still thinking about is how to handle combined packets, like MCI.
The result is "less cool packet handling", but it should be quicker if you can avoid the function property assignments and unassignments. And packets can then be moved to another thread without preprocessing them.
If that's the case, I would leave the packet struts as packets and use another class where I would pass the packets as a struct when I wanted to work on it. Or nest the packet struct into the class and let the class act on it's nested data.
What about prototypes? Creating a "Packet" object with function definitions on the prototype rather than the object directly?

Not that I know much about web workers as JavaScript with events is sufficient for me.
then the object will still contains functions (methods) and as such cannot be serialized.
In other words, for an object to be serializable it may only have value properties. It may not have functions of any sort.
It may have nested arrays, typed arrays and nested objects, as long as those don't contain functions either.

btw, it's not really a big deal atm. Only chrome supports websockets in workers, for now. It'll be somewhere next year when the majority supports that combination. Dunno about ie10 though.
Hm. I'd need to test it. But shouldn't hasOwnProperty filter out any inherited methods via prototypical inheritance? That way you could "filter" the object into its actual data and exclude inherited methofs
Quote from dawesdust_12 :Hm. I'd need to test it. But shouldn't hasOwnProperty filter out any inherited methods via prototypical inheritance? That way you could "filter" the object into its actual data and exclude inherited methofs

well, could be that I don't know what that means There are several aspects of JS that I never really looked into much, so if you think you've got an easy solution, give it a try and let us know. Or give a small example perhaps to illustrate.
Well, the theory is that you can loop an object by going
for(property in obj){
//this is the has own property.. It should (if I'm correct) filter out properties that are inherited.
if(!obj.hasOwnProperty(property)){
continue;
}
//logic to handle the property that is actually a real property, not inherited
}

That's how you would check an object, without it, you'd collect other things off an object like push for an array and such.

Karl: feel free to correct me if I'm wrong, I think I'm correct with prototypes, but I can't quite test it right now (not at computer).

EDIT
I just tested it with this code:

var x = Object; //Possibly wrong way.. but works.
x.prototype.test1 = function(){console.log('test1 WAS CALLED')};

var y = new x;
y.dustin = 1;
y.test1();
for(prop in y){
var currProp = y[prop];
if(!y.hasOwnProperty(prop)){
continue;
}
console.log('HAS:' + prop);
}
console.log('y OBJECT');
console.log(y);
console.log('x OBJECT')
console.dir(x);

and I got out what I'd expect (an object with only declared properties, not prototypes).

The output with !y.hasOwnProperty looks like:

test1 WAS CALLED
HAS:dustin
y OBJECT
{ dustin: 1 }
x OBJECT
[Function: Object]

Without the !hasOwnProperty.. the prototypical method is exposed:


test1 WAS CALLED
HAS:dustin
HAS:test1
y OBJECT
{ dustin: 1 }
x OBJECT
[Function: Object]

right I think I get that. And the internet tells me you're correct about hasOwnProperty() only looking at the direct object, not any inherited properties.

But I do not see how that solves the multi-packet problem. Many of them require their own logic. MCI needs to loop through numc CompCars. The car CONtact packet needs to unpack two objects (of a specific type). The OBjectHit packet only needs to unpack one, and so on.
So those parent packets and their (un)pack logic need to know how to do their job.
If we don't want to put that logic inside the packets themselves, then it needs to move to the external (un)pack functions. Meaning, I think, that you'd just have to check the packet type and then switch() through them to see if they are of the type that has sub packets. So the logic to unpack those would be in the switch statement.
Or something ..

Really, it may not be worth thinking about much atm. The code when used in your main JS thread really isn't slow. It's just that I've been thinking about optimisations in a htmlremote experiment and feel that there's still some speed to be gained by doing the packets in another fashion. But I stopped thinking about it for now because I felt it's still too early to put these features (websocket, worker) into a production site. So there was not much point in trying to do the insim packets in a whole other way...
I was more thinking because then a Packet could be generic object with its pack/unpack attached to the prototype, and then instances can (when getting value however" would only return their actual data, without any of the prototypical methods attached (as methods are the thing that actually cause issues with serialization.

Just random thoughts I suppose.

Although I do think (for organization) that having a more modular Packet system would be nice. Instead of having 1 giant file, having smaller files that call "RegisterPacket" on some PacketManager type global object might be a nice thing. I think I'm gonna try to build that after my experiences last night as it seems nicer to manage in the global scope.
I've started throwing together an implementation for the relay over websockets - and popped the initial version onto github with an example of usage. The example only outputs to the console at the moment (and only supports 3 packets), but I'll put something better together tomorrow/wednesday night I'm happy to receive patches, etc. Competition is also welcome

The major downside (in my opinion) is that there's a fair bit of marshalling between different array types, which could potentially use a bit of memory in a long running app. That said it could easily be ported to use the native types without changing the API at all, but I'm lazy

@dustin the idea of a modular API sounds interesting.. Were you thinking of registering packets after an instance of the client has been created? Or before?
Quote from the_angry_angel :@dustin the idea of a modular API sounds interesting.. Were you thinking of registering packets after an instance of the client has been created? Or before?

Well... basically: If the client can't yet deal with a packet.. it ignores them. The packets would be registered as soon as they could (self-executing closure in seperate script files). I just hate Javascript for its messiness (especially browser JS. Node is easier with Require being standard).

My general idea is to break stuff up into separate files and have them basically call RegisterPacket on a PacketHandler Object to inject it's definition into the PacketHandler, which then PacketHandler could then use that packet type.

Maybe I'll try to do it tonight as a proof of concept. I am a total noob (my demo above is literally my first ever attempt at anything to do with Packets.. so my logic is super rigid and inflexible). SuperAwesomeRepository

I'll probably abstract the actual packing/unpacking as well, rather than hardcoding it like a noob :P

Also: Don't be lazy. The native types are awesome. DataView is pretty slick once you get familiar with it.

EDIT: What have I done.. My crappy hack of Javascript has managed to see all this code come out of the woodworks. What was I thinking :P

InSim Relay client information
(63 posts, started )
FGED GREDG RDFGDR GSFDG