The online racing simulator
Searching in All forums
(921 results)
DarkTimes
S2 licensed
Quote from PoVo :Can anyone confirm this please?

Yes each pixel corresponds to one meter. The track environments are 2560 meters square, the same in pixels.
DarkTimes
S2 licensed
The way you are doing it seems over-complicated to me, what I would do is..

1. select set to timeout every 0.01 seconds (or other suitably low value)
2. when select returns check if any timers have elapsed and call their callbacks
3. handle all read, write, error sockets
4. Goto 1

In badly written weird made-up code:

function main() {
while (any_sockets_are_connected) {
rlist, wlist, elist = get_socket_lists()

select(rlist, wlist, elist, 0.01)

handle_timers()
handle_sockets(rlist, wlist, elist)
}
}

function handle_timers() {
foreach (timer in timer_list) {
if (time_now > timer.due_time) {
timer.execute_callback()

if (timer.is_only_to_elapse_once) {
timer_list.remove(timer)
} else {
timer.set_next_due_time()
}
}
}
}

DarkTimes
S2 licensed
Quote from Dygear :How the select calls works with timers and packets within PRISM.
  1. Sort the list of timers, with the timer to expire next at the top.
  2. Get the time to expire, and subtract that from now.
  3. Make the delta of this time the timeout for the select_timeout function.
  4. Call socket_select with the read, write, and exception socket arrays, and the timeout delta.
    • A packet is received before the timeout expires.
    • The timeout is reached.
  5. Handle any packets as needed.
  6. Execute any expired timers.
  7. Goto Item 1.
Best part? If there are no timers, PRISM will wait until there is a packet making it very efficient in this state.

There seems to be a bug in the code that figures out the sleep value, as it appears to always be set to 1, no matter what the timers are doing.
DarkTimes
S2 licensed
If you are using select to synchronize the whole system (which there is nothing wrong with), then you should set the timeout to as low a value as you can without saturating the CPU. This is something I learned when developing pyinsim. Frankly the way you have implemented the timer is the way I would have done it too, but the whole one sec timeout thing is hurting you for this kind of operation (as I say it took a stack overflow question for me to figure this out myself).
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from morpha :Should probably check that out sometime, I'm still running 1.5.3

Yeah, in the time between pyinsim 1.0 and pyinsim 2.0 I learnt to hate threads with a passion (not Python's fault really), so I rewrote the whole thing to use non-blocking sockets. You can still set the main loop to run on a background thread by setting pyinsim.run(background=True), but that's only if you need to use it from a GUI app, otherwise it's all blissfully single-threaded.

Quote :With just PHP and its most common extensions alone, it's impossible. Threading is obviously a very low priority item for what is still primarily a hypertext preprocessor.

I'm actually surprised that PHP doesn't have a proper timer library. Oh well, I'll just add it to my long list of PHP oddities.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
pyinsim 2.0 doesn't use threads at all, it uses the Python asyncore module, which is basically just a wrapper around select. Yes, if you just want to create a timer you can use the threading.Timer class, but all of the send/receive stuff in pyinsim is done on a single-thread with non-blocking sockets.

Quote :Even with a very low timeout the timer resolution will be limited and vary greatly depending on the complexity of the script, as it's all running in a single thread of execution.

Yeah, I realise this, but still changing the select timeout would improve things a lot, as looking at the current code for PRISM a 1.0 second timeout looks like a bug. A better solution would of course be to use a threaded timer for the timer events, but I don't remember enough about PHP to advise on how easy/hard that would be to implement.

Frankly I was just impressed I managed to figure out that there might be a timeout issue within 30 seconds of downloading the codebase.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from Dygear :To be quite honest I don't know if I can fix that. PHP just might be too slow. It just might not be possible with PHP. But I'll keep on trying.

I'm looking through the code and there's something I'm slightly unsure of. It seems you're executing the timers between select returns, which is fair enough, but it looks like your select timeout is almost always 1 second. Now I might be wrong on this (it's very likely, as I don't know the codebase or PHP), but wouldn't that mean your timers can only be fired at minimum once a second? From looking at T3's output it's likely that the timer is always elapsing after one second, which would bare my theory out. If I'm not wrong then you could try putting the select timeout to a very low value, such as a 0.01 seconds or something, basically just enough to prevent it from flooding the CPU. pyinsim uses select as well and in that I use a timeout of 0.05 seconds, but this is a pretty arbitrary value that I came to after a discussion on StackOverflow. I could of course be completely wrong about all of this, in which case just slap me with a big fish.

Quote from T3charmy :Will you be adding the new packets? (Collision ones coming in new test patch?)

No point adding them until the new patch is out, as it'll have to be tested, also hard to know the ins-and-outs without an updated InSim.txt. I've put the new packets into InSim.NET, but personally not going to release it until I have a chance to test it.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from PoVo :Yeah the reason for spectating would be useful. I needed to find a reason for spectating a couple of months ago, but ended up not doing anything at all

Yeah, it's something used a lot in cruise apps I think, as they give out fines to players spectated for various reasons, such as took the wrong route.
DarkTimes
S2 licensed
The only small suggestion I'd can think of right now is to add a leave reason to the PLL packet, that would inform you whether the player spectated of their own volition, were spectated by an admin, or if they were spectated by the game (e.g. took the wrong route, jumped the start etc..). However adding it to the PLL packet at this stage would be a breaking change, so it would probably have to be done with a new packet if done at all.

Just an aside, recently I noticed a small error in InSim.txt, in the comments for IS_REO. You mention a packet called IS_VTA, but this packet does not exist, it's actually a IS_SMALL with a SubT of SMALL_VTA. Not important but it made me scratch my head for a few seconds the other day.

I think this might be a throw-back to the old version of InSim.

// You can send one to LFS before a race start, to specify the starting order.
// It may be a good idea to avoid conflict by using /start=fixed (LFS setting).
// Alternatively, you can leave the LFS setting, but make sure you send your IS_REO
// AFTER you receive the [B]IS_VTA[/B]. LFS does its default grid reordering at the same time
// as it sends the [B]IS_VTA[/B] (VoTe Action) and you can override this by sending an IS_REO.

Last edited by DarkTimes, .
DarkTimes
S2 licensed
Whoever does rain dances can start doing rain dances now.
DarkTimes
S2 licensed
Uploaded 1.2.5 to CodePlex.

Changes
  • Added new text-based filter
  • Optimized string encoding code
I've replaced the old CheckedListBox filter tab with a new text-based one. The old filter tab has been removed and there is now a new TextBox at the top of the packet list that allows you type a packet name and filter the list on the fly.

I'm happy to receive feedback on the new filter, if you hate it or whatever. I think it's better overall but may need some tweaking. One issue is it might not scale well to having thousandths and thousandths of packets. I do maintain that InSimSniffer is a bad tool to use if you just want to do general logging, but the idea of having a standalone InSim event logging tool has been bought up before and perhaps it's time for someone to write one.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Pushed a small release out with a few corrections, mainly the documentation. I remembered I hadn't updated the help-file generator for a while, so I got the latest version with a bunch of fixes. I also improved the documentation generally and fixed a bunch of typos. In addition I cleaned-up some of the source code to make it 3.78% less crap overall.

http://insimdotnet.codeplex.com/releases/
DarkTimes
S2 licensed
Last edited by DarkTimes, .
DarkTimes
S2 licensed
Quote from Dygear :Once you learn one programming language, you know them all really. Except ASM, because that's some odd stuff right there.

Well, this is certainly true for the C-family of languages, such a *PHP, Java, and C# (even Ruby), but not so much for functional programming languages, such as a Lisp and Haskell. The functional languages do require you to think is a new and different way about your code, especially if you've been stuck in the C-world for a long time. It's an eye opening experience to go code a bunch of Haskell for a while... and also worthwhile doing.

It is a mistake a lot of novice programmers make to worry about which language they should learn, as opposed to which language they should learn first. Once you've learnt a programming language picking up others is normally just a case of doing a mental bit-shift to a different syntax. All the fundamental ideas that underlie them are the same.

* I should probably note that my issue with PHP is that it just doesn't make sense to me when I code it, it doesn't flow off my fingers the way C#, Python and *Ruby do. I find there are so many oddities, so many small things that interrupt my flow and make me scratch my head. I'm sure all that would go away if I had more (recent) practice at it. To me PHP just has no aesthetic, no vision and no consistency. It's the perfect example of a language designed by a committee that couldn't agree about anything. That being said, it is one of the most used programming languages ever, half the internet is built on it, so maybe I don't know what I'm talking about.

* Incidentally if I had half an impulse to write a new InSim library, Ruby would be a pretty sound bet. I don't though.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I released the final version of InSim.NET 2.0 to CodePlex.

It's finished, more or less.

http://insimdotnet.codeplex.com/

I also updated the first page of this thread and changed the title.

Fin.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
I released a quick revision of this to CodePlex, only a couple of small tweaks.

Been thinking about forking the codebase and finally creating a Python 3.0 port.
DarkTimes
S2 licensed
PyDev 2.0 out, for anyone interested.

http://pydev.org/
DarkTimes
S2 licensed
Quote from Dygear :I really wish you would just go ahead and learn PHP, and then help with PRISM . As always, great job.

Technically I do know PHP, I'm just really bad at it. PHP was one of the first languages I ever learnt, but I can't really remember much about it.
DarkTimes
S2 licensed
I like Firefox 4, it's pretty good, but frankly not good enough to turn me away from Chrome. I tried using FF4 for a day, but after about 30 seconds I missed the Chrome address bar, and how smart it is at figuring out which page I'm going to before I finish typing. I know that shouldn't be a game-breaker, but I'm so used to it now that going back is like losing a finger. I do like the new FF UI, even though it is embarrassingly close to Opera, like completely copied. I could make a big impassioned speech about how open-source is inherently derivative and never innovates, but I'll hold it in for your sake. All in all, I give it 4 out of 5. Good, but not OMG good.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
It's a bitwise operation, so in code it would be...

$result = 4 | 8 | 64;

echo $result; // Output '76'

So yup, it is indeed 76.

Edit: But anyway to detect a DISQ it would be something like this:

if ($onR_Confirm & CONF_DISQ) {
// Disqualified
}

Last edited by DarkTimes, .
DarkTimes
S2 licensed
I've started typing up the documentation for this, but it's still a work in progress. If someone would like something explained, or thinks something should be in the (In)FAQ, then give us a shout.

You can view the documentation as a work in progress here: http://insimdotnet.codeplex.com/documentation
DarkTimes
S2 licensed
Uploaded 2.0.4 Beta to CodePlex, this is one of the very, very last betas, honestly. As soon as I've finished the documentation it will go final.

Changes in this release
  • Support for double-byte character sets, for Japanese, Traditional Chinese, Simplified Chinese and Korean strings.
  • Fixed several bugs in OutGauge and OutSim support, plus cleaned up and improved reliability of the UDP timeout.
  • Can now save/load InSimSettings to/from XML (handy for implementing a quick config file)
  • Improved performance and reliability of packet binding (also improved packet binding for languages that do not support generics, like IronPython)
  • Added InSim.Send(IEnumerable<ISendable>) method that allows you to batch send packets (for improved network performance when sending lots of packets)
  • Improvements to PacketFactory, that now much better allows you to implement and configure your own packet-handling code
  • Changed the way InSim.NET handles CLS (Common Language Specification) compatibility, this means the return of bytes and short etc for many packets
  • Completely tweaked and improved documentation (fixed lots of typos and cleared up grammar)
  • Lots of small tweaks to packets to remove some oddities and generally cleanup the API
  • Lots, lots more!
DarkTimes
S2 licensed
Well yes, requests only get sent back to the connection that requested them, that makes sense really. I've remembered as well that InSimSniffer has a reserved ID of 254, so if a packet is sent with that same request ID InSimSniffer won't display it, because that's the ID it uses to maintain its own internal state*. That might indeed cause some confusion, as if you request a packet with an ID of 254, InSimSniffer won't display it. This was mentioned in the FAQ, although that seems to have disappeared somewhere. This might be a flaw that needs correcting :P.

* Although InSimSniffer is designed to show you exactly what InSim is doing, this is actually an illusion. It has to maintain its own internal state and does this by making its own series of InSim requests under the ReqI '254', which it then hides from the user. For some reason a long time ago I decided that 254 was a benign request ID that anyone else was unlikely to use, and while it used to be mentioned in the FAQ that 254 was a no-no, it seems the FAQ itself has gone bye-bye.

Note: You can see the ReservedId of 254 set in the source repository.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
If you need to you can completely reimplement the socket code, by implementing ISocket on your own custom class.

public class CustomSocket : ISocket{
// Custom implementation of ISocket.
}

InSim insim = new InSim();

// Set your custom socket.
insim.Socket = new CustomSocket();

// Whatever...

Your custom socket could read InSim data from a file, or from a Windows Service, if you so choose. You can create any source you like, so long as you inherit from ISocket. This is one of the many things that make InSim.NET very flexible, as although it's designed to work with zero configuration, it's also designed to let you reimplement stuff that's important to your app.

Maybe you need to access the raw byte data from InSim? InSim.NET lets you do that...

InSim insim = new InSim();

// You have complete access to underlying socket.
insim.Socket.PacketDataReceived += insim_PacketDataReceived;

private void insim_PacketDataReceived(object sender, PacketDataEventArgs e) {
// Now you have raw byte data...
byte[] data = e.GetData();
}

Or maybe you'd like to ignore InSim.NET and go straight to the TCP socket itself?

// You can access the underlying socket without the InSim abstraction
TcpSocket sock = new TcpSocket();

// It handles the TCP receive stream for you, basically makes TCP act like UDP...
sock.PacketDataReceived += insim_PacketDataReceived;

// You can create a connection.
sock.Connect("127.0.0.1", 29999);

// And send raw packets...
sock.Send(new IS_ISI {
Admin = String.Empty;
IName = "Test!",
}.Pack());

private void insim_PacketDataReceived(object sender, PacketDataEventArgs e) {
// And handle them however you like...
byte[] data = e.GetData();

}

This should give you an idea of just how flexible InSim.NET is.
Last edited by DarkTimes, .
DarkTimes
S2 licensed
As mentioned previously you can now set your own IPacketFactory, which allows you to reimplement the way packet are built.

public class CustomPacketFactory : IPacketFactory {
public IPacket BuildPacket(byte[] buffer) {
// Implement your own packet handling code here. You can
// create your own packets or do whatever you need to,
// so long as your new packet inherits from IPacket.
return null;
}
}

InSim insim = new InSim();

// Set your custom packet factory
insim.PacketFactory = new CustomPacketFactory();

// Exists here normal InSim.NET code...

FGED GREDG RDFGDR GSFDG