The online racing simulator
Very, very basic PHP
(52 posts, started )
Very, very basic PHP
Hello... I am trying to learn how to use InSim with PHP. First question - can I do this with XAMPP on Windows? I have tried using the example code from the wiki but nothing happens. InSim is set to port 30000.

I'm a complete n00b with PHP, so all I want to do right now is to connect to LFS and send a simple packet. I'm not even worried about even sending the ISI packet yet. Am I right in thinking that LFS should complain about what I am sending to it?

If that's right, then should I just be able to use fsockopen and then send a packet with fwrite? Something like this:


<?php 
$port 
"30000";
$tx fsockopen("udp://127.0.0.1"$port$errno$errstr);
$packet "aaa";
fwrite($tx$packet);
?>

Though that's probably completely wrong
@rooble
Thanks a lot, that's exactly what I wanted!

@st4lk3r
Yes, I have looked at your tutorial... but I'm trying to learn the absolute basics, just trying to get connected and send a simple packet for the moment. Now I've done that, your tutorial will be very helpful
Wheee, I sent 'hello world' to LFS

First problem - I'm trying to get the version from LFS:


<?php 
fwrite
($socketOut"VER\0" pack("i"intval(0)));
$packet fread($socketIn256);
$lfsV trim(substr($packet,  48));
echo 
$lfsV;
?>

but there is no output. Also echoing $packet itself gives nothing. The problem's probably obvious to you!
I use long ("L") instead of "i" and str_pad() the value to make exactly 32-bits:

<?php 
fwrite
($socketOut"VER\0" pack("L"str_pad(032"\0")));
?>

Read operation should be fine but to receive stuff on the inbound socket you really would need a loop that reads from the stream and then reacts to what it:

<?php 
while(TRUE) { // infinite loop to keep the reading from the in sock
    
$packet fread($socketIn1024); // get data
    
if(rtrim(substr($packet04)) == "VER") { // check if it's a VER packet
        
$ver rtrim(substr($packet48));
        die(
"$ver\r\n");

    }
    
usleep(100);
}
?>

Quote from NotAnIllusion :
Read operation should be fine but to receive stuff on the inbound socket you really would need a loop that reads from the stream and then reacts to what it:
...

Use socket_select instead of busy waiting. It saves a lot of CPU time for you.
A note from the php manual:
You should always try to use socket_select() without timeout. Your program should have nothing to do if there is no data available. Code that depends on timeouts is not usually portable and difficult to debug.
I gave up on getting socket_select to work ages ago, besides it's an advantage for me to do things in a (slightly) sub-optimal manner due to the way it affects my final year dissertation ;P
Quote from NotAnIllusion :besides it's an advantage for me to do things in a (slightly) sub-optimal manner due to the way it affects my final year dissertation ;P

Ha!, maybe this (looking for the optimal solutions) is the reason, why I didn't finish my disertation yet .
*wooshes over head*

NotAnIllusion - yes, it works! I am gradually understanding it. For the data types, for example the flags in the ISI packet, why in the line

<?php 
fwrite
($socketOut"ISI\0" pack("Scc"300001+8+16+321) . str_pad("aaa"16"\0"));
?>

is the pack format for the flags 'c'? According to InSim.txt, they are a byte - 1-byte unsigned integer - but in the PHP documentation the 'c' format is a signed char?

Also, so characters are okay just as strings, and integers need to be packed?
char = 1-byte unsigned integer.
Quote from andy29 :*wooshes over head*

NotAnIllusion - yes, it works! I am gradually understanding it. For the data types, for example the flags in the ISI packet, why in the line

<?php 
fwrite
($socketOut"ISI\0" pack("Scc"300001+8+16+321) . str_pad("aaa"16"\0"));
?>

is the pack format for the flags 'c'? According to InSim.txt, they are a byte - 1-byte unsigned integer - but in the PHP documentation the 'c' format is a signed char?

Also, so characters are okay just as strings, and integers need to be packed?

The 'c' should probably be 'C' yeah, but I think it will work as long as the value isn't -ve. Chars don't need to be packed, everything else I do pack (I guess that's a yes then).
Ahh right, that makes sense then

So...
insim format
byte S
word C
short c
unsigned C
int c
float f

Have I got that right?
unsigned simply means it can't be a negative number.
for example, tiny int's could be -128 to 127, but as we tell it is unsigned it can only be 0 to 255.
char -> a
byte -> C
word -> S
short -> s
unsigned -> L
int -> l
float -> f
Thanks for your help guys. Now I know some of the basics I can do some fiddling and start to learn some more
Haha, thanks, I just had to choose now to do this didn't I!

Oh well, I'm learning PHP at the same time too. It's all good practice...
To be honest, it'll just be a case of changing the unpacking and how packets are recognised, oh and TCP - but thats not a big issue for you.
So I have a loop waiting for a chat message:


<?php 
while(TRUE) {
  
$packet fread($socketIn1024);
    if(
rtrim(substr($packet04)) == "MSO") {
     
$in substr($packet4128);
     
$out trim($in"\0");
     die(
$out);
     }
    
usleep(100);
}
?>

This works okay. But of course it will only show one message and then end the script. How do you keep it running? I've had a look around and tried print() (because echo() is not actually a function ), but it seems that without having die() there it never displays the message. I can't see why. I guess this should be going on a PHP forum really
die("....") ends your script even if you are inside a while(true) loop.
to force the output, put your script inside this:


<?php

if (ob_get_level() == 0) ob_start();

while(true){
.............................
ob_flush();
flush();
.............................
}
ob_end_flush();

?>

FWIW.. 'echo' is actually preferred over 'print'.. it's more efficient. Granted, you won't notice it, but it is.. the same as using single quotes rather than double-quotes as everything in double quotes is parsed, regardless of whether it contains $vars etc, and single quotes denote a literal string, thus no parsing is involved making it slightly more efficient Just some "useless infos"

The die($foo) function is the same as doing:

echo $foo;
exit;

hence it only displays the contents of $foo once.



Regards,

Ian
Fujiwara, Ian... thanks for the information. I am learning with every post

I don't think I really explained it right though. At the moment die is ending the script. What I want to do now is to change it so that it doesn't stop... I want it to keep looping and echoing any messages it gets, if that's possible. I have tried removing die and putting echo in its place, but it seems that it's not as simple as that.
Look into fuji's example of ob_flush() (check the syntax / examples on php.net etc if needed) as this will help solve your issue along with just using an echo statement.

The problem lies with how things are served to the browser. In basic terms, the server deals with _everything_ and _then_ sends the results to the browser. As the while() loop is endless, the server never completes it calculations thus never sends the info to the browser.. the ob_flush() etc calls will send the info to the browser as it happens and you'll see "progress" rather than the "end result" which should be what you're looking for



Regards,

Ian
Quote from andy29 :Fujiwara, Ian... thanks for the information. I am learning with every post

I don't think I really explained it right though. At the moment die is ending the script. What I want to do now is to change it so that it doesn't stop... I want it to keep looping and echoing any messages it gets, if that's possible. I have tried removing die and putting echo in its place, but it seems that it's not as simple as that.

Problem is, since you are running this script endlessly, you'll never see the output, unless you force it.
echo($out) works fine, problem is, you will only see the output after the script ends, wich never happens because you have a endless loop, to see the output, you have to force it.

Look at this 2 examples and you will understand:
No output forced...you see the result after the script ends.

<?php

//if (ob_get_level() == 0) ob_start();

while ($i < 10 )
{
echo "<br> Line number $i.";
sleep(1);
//ob_flush();
//flush();

$i++;
}

echo "Done.";

//ob_end_flush();

?>

With forced the output...

<?php

if (ob_get_level() == 0) ob_start();

while ($i < 10 )
{
echo "<br> Line number $i.";
sleep(1);
ob_flush();
flush();

$i++;
}

echo "<br>Done.";

ob_end_flush();

?>

Hope this helps.

Very, very basic PHP
(52 posts, started )
FGED GREDG RDFGDR GSFDG