PDA

View Full Version : PHP Script for Teamspeak


nesti
11-04-2006, 13:24
Hello guys, im a stuck for the moment...
I just tried to make my own TS Class in PHP instead of using prewritten ones. I really want to understand whats behind all these classes ;) But now I got a problem where I really can't see the error.

http://nes-t.com/TSTEST/
on this page you can see what command I'm sending and what i get as result...
Its a bit bizzare because i get teh result of the command pl when im query'ing cl....
Maybe anyone can help me THX

heres the script

<?php

class DisplayMyTS {

function setvar($IP, $TCP, $UDP) {
$this->socket = false;
$this->DATA = '';
$this->UDP = $UDP;
$this->TCP = $TCP;
$this->IP = $IP;
}

function send($socket, $query) {
fputs($socket, $query."\n");
}

function get($socket) {
return fgets($socket, 4096);
}

function disconnect($socket) {
fputs($socket, "quit");
fclose($socket);
$this->setvar("", "", "");
}

function selectserver($socket) {
fputs($socket, "sel ".$this->UDP."\n");
}

function connect($IP, $TCP, $UDP, $Timeout = 3) {
$this->setvar($IP, $TCP, $UDP);
if (!$this->socket = @fsockopen($IP, $TCP, $ErrNo, $ErrStr, $Timeout))
{
echo "Connection Failed";
}
}

function DisplayTeamspeak ($IP, $TCP, $UDP) {
$this->connect($IP, $TCP, $UDP, $Timeout = 3);
$this->selectserver($this->socket);

$this->send($this->socket, "pl 31044");
$playerlist = $this->get($this->socket);
echo "pl 31044 command (Playerlist): ".$playerlist."<BR />";

$this->send($this->socket, "ver");
$version = $this->get($this->socket);
echo "ver command (Version) : ".$version."<BR />";

$this->send($this->socket, "sl");
$serverlist = $this->get($this->socket);
echo "sl command (Serverlist) : ".$serverlist."<BR />";

$this->send($this->socket, "cl 31044");
$channellist = $this->get($this->socket);
echo "cl 31044 command (Channellist) : ".$channellist."<BR />";

$this->send($this->socket, "si 31044");
$serverinfo = $this->get($this->socket);
echo "si 31044 command (Serverinfo) : ".$serverinfo."<BR />";

$this->disconnect($this->socket);

}

} /* END CLASS DisplayMyTS*/
?>

Brain
11-04-2006, 13:57
It's obvious. You don't wait for the initial prompt, but instead just barf out commands. Logically the initial prompt is still in the buffers and you get the [TS] OK on your first two readline queries.
Well, and after issuing a command you don't wait for the OK but just throw out the next one.

nesti
11-04-2006, 14:48
ah ok I see now

thx for the help
couldnt really get whats going on with the fgets help on php.net

nesti
11-04-2006, 15:02
so with a


do {
} while ()


its working to read out the whole buffer...

Cyrus
11-04-2006, 15:38
but only with the right condition

nesti
11-04-2006, 15:43
hmm ok...
maybe anyone of you know a nice page (exept php.net) where i can read a little bit more information of this fgets


i made it now with

if ($this->socket) {
while (!feof($handle)) {
$data = fgets($this->socket, 4096);
$alldata = $alldata.' +++ '.$data;
echo $alldata;
}
}

Brain
11-04-2006, 15:43
Simple. First wait and read every character that comes from your TCP socket. It should form "[TS]\nOK". Then write your command, terminated with a newline of course. After that read every line. If it doesn't start with "OK\n" it's output from the command and should be buffered somewhere for processing. If it starts with "OK\n" you have reached the end of output and the query interface is ready for a new command.

Always keep in mind that even TCP connections should be regarded as fragile, meaning every time you have a do while waiting for input you should also have some kind of timeout to cover for lost/dropped connections. Nothing is more embarrassing than busy-waiting for something that will never come. I do that by saving the system time into a variable, then comparing the difference between system time and the variable and breaking off the loop after a certain time (2 seconds) has elapsed. I don't start any other activites besides trying to send a quit and waiting a bit longer (5 seconds). Regardless of the result of quit I return with an error.

Cyrus
11-04-2006, 15:58
In my current script I am using this for reading the output

$reply = $line = "";
do {
$line = fgets($this->socket);
$reply .= $line;
} while ($line != TS2_OK && strtolower(substr($line, 0, 6)) != TS2_ERR);

where the constants are defined as

define("TS2_OK", "OK\r\n");
define("TS2_ERR", "error,");

nesti
11-04-2006, 16:48
i'va done it now with

if ($this->socket) {
while (!feof($handle)) {
$data = fgets($this->socket, 4096);
$alldata = $alldata.' +++ '.$data;
}
echo $alldata;
}


but i still gett errors

Brain
11-04-2006, 17:47
What do you need those three +++ for?

nesti
11-04-2006, 18:02
these were just for a test, to look how hes putting everything togheter
i'm gonna delete them in the final script

Brain
11-04-2006, 18:20
Anyways, it's only natural that you would get errors if you use feof. EOF also occurs if you're at the current end of the input buffer of a TCP socket. This includes the condition between sending a command and receiving the response. If the server takes longer to answer than it takes your script to advance from "send the command" to "wait for reply with feof" then the retrieval of the reply will be simply skipped.
You will see that if you put a wait for one second or so before the while loop everything will be fine. However I strongly advise against that, it's a very, very, very, very dirty hack.

nesti
11-04-2006, 18:55
hmm ok

i got a little bit confused now...

theres so many gibberish in my code now that I can't see anymore whats right and whats wrong...

so what do you think is the best way to make it work

Cyrus
11-04-2006, 19:04
Depends on your skills.

If you don't know how your own code works hmm then you should rewrite from scratch and use comments.

nesti
11-04-2006, 19:07
i know my code, but i'm not really getting into this fgets thingy... I fwas now looking a bit @ php.net, but i need something where i get more specific informations about this buffer and about getting the informations from the buffer. 2 years ago i made a basic script for ts which was working, but now i can't remember anymore how i've done it...

think im gooling abit for this fgets function....

Cyrus
11-04-2006, 19:11
There is nothing special about this fgets thing.
It just reads one line of output if you call it.
And you should read the output as long as it does not start with
"error" or "OK".
Nothing more nothing less.

nesti
11-04-2006, 19:17
so with the first fgets u get an "OK\r\n" and you know that its ok

then u have to ask so many times till the next "OK\r\n" is coming and you know that it was the end of ur commands....

is it like that?

Cyrus
11-04-2006, 19:24
yeah mostly you send a command with fputs or fwrite like
fputs($socket, "cl\n");
and now you call fgets($socket); until you get the
"OK\r\n" thing.
To keep it complete you should not only check for "OK\r\n" but also for anything that begins with an "error".

Now you can do next command and then again fgets() until "OK\r\n" or "error..."

nesti
11-04-2006, 19:26
oh ok now i got it ...

so this script should normally work


function get($socket) {
$buffer = fgets($socket, 4096);
$result = array();
do {
$result .= fgets($socket, 4096);
} while (($buffer != "OK\r\n") && (strtoupper(substr($buffer, 0, 5)) != "ERROR"));
return $result;

}

Cyrus
11-04-2006, 19:27
oh ok now i got it ...

so this script should normally work


function get($socket) {
$buffer = fgets($socket, 4096);
$result = array();
do {
$result .= fgets($socket, 4096);
} while (($buffer != "OK\r\n") && (strtoupper(substr($buffer, 0, 5)) != "ERROR"));
return $result;

}


hmm nearly


function get($socket) {

$result = "";
do {
$buffer = fgets($socket, 4096);
$result .= $buffer;
} while (($buffer != "OK\r\n") && (strtoupper(substr($buffer, 0, 5)) != "ERROR"));
return $result;

}

nesti
11-04-2006, 19:30
lol now i think i f... up my Providers Server :)

http://nes-t.com/TSTEST/index.php

i can't open any pages anymore on my PC with the nes-t.com domain..

:confused: :confused:
:) :) :)

Cyrus
11-04-2006, 19:32
hmm for me it works

nesti
11-04-2006, 19:36
is the script working....
i can't get any connection anymore over my Work Internet Access.....


hmmm maybee i just ahve to reboot....


anyway...

thx for your help, im trying to rebuild the whole stuff this evening, so that I know every step of my precedures...

Have a nice evening

NESTi

nesti
11-04-2006, 19:41
ok its working again...

but im still not getting the name of the players when i send the command "pl 31044/n"

I think hes just moving foward till the first OK and not the last 1

nesti
11-04-2006, 21:05
oh guys ty ver much it was so a stupid error beause it wasnt working now... forgot to read out the buffer when i made the "sel" command ;)

THX

NESTi