PHP, Telnet und TS3

20/11/2010 - 10:35 von InV4in | Report spam
Hallo, ich versuche eine Gaming-Plattform auf die Beine zu stellen und
entwickle hierfür mit PHP. Ich möchte in der Lage sein über PHP mit
unseren Teamspeak-Servern zu kommunizieren um dynamisch neue Channels
zu erstellen und diese bei Bedarf wieder zu löschen.

Um eine Verbindung zu den TS-Servern herzustellen benutze ich folgende
Telnet-Klasse:
http://www.dali.net.nz/Telnet.class.php.txt

Die Verbindungsherstellung funktioniert mit $telnet = new
Telnet($server_ip, "10011"); und ich bin auch in der Lage mit $result
= $telnet->exec("channelcreate channel_name=test
channel_flag_permanent=1"); einen Channel zu erstellen.

Mein Problem ist: als $result wird mir unabhàngig von der Abfrage ein
leerer String zurückgegeben, so dass ich Channels nicht wieder löschen
kann, da mir die Channel ID nicht übermittelt wird. Die Ausgabe bei
der oben genannten Anfrage sollte eigentlich etwa so lauten:
cid%
error id=0 msg=ok

Mir ist völlig unklar, warum ich keine Rückgabe erhalte und wàre für
Hilfe sehr dankbar. Liebe Grüße.
 

Lesen sie die antworten

#1 Thomas PointedEars Lahn
09/01/2011 - 19:15 | Warnen spam
InV4in wrote:
^^^^^^
Bitte trag an dieser Stelle Deinen vollstàndigen/richtigen Namen ein. Das
gilt hier im deutschsprachigen Usenet als höflich und erhöht somit Deine
Chancen auf sinnvolle Antworten. [psf 7.16]

Hallo, ich versuche eine Gaming-Plattform auf die Beine zu stellen und
entwickle hierfür mit PHP. Ich möchte in der Lage sein über PHP mit
unseren Teamspeak-Servern zu kommunizieren um dynamisch neue Channels
zu erstellen und diese bei Bedarf wieder zu löschen.

Um eine Verbindung zu den TS-Servern herzustellen benutze ich folgende
Telnet-Klasse:
http://www.dali.net.nz/Telnet.class.php.txt



<http://www.dali.net.nz/Telnet.class.phps> wàre wahrscheinlich besser lesbar
gewesen, siehe <http://php.net/highlight_file>.

Die Verbindungsherstellung funktioniert mit $telnet = new
Telnet($server_ip, "10011"); und ich bin auch in der Lage mit $result
= $telnet->exec("channelcreate channel_name=test
channel_flag_permanent=1"); einen Channel zu erstellen.

Mein Problem ist: als $result wird mir unabhàngig von der Abfrage ein
leerer String zurückgegeben, so dass ich Channels nicht wieder löschen
kann, da mir die Channel ID nicht übermittelt wird. Die Ausgabe bei
der oben genannten Anfrage sollte eigentlich etwa so lauten:
cid%
error id=0 msg=ok

Mir ist völlig unklar, warum ich keine Rückgabe erhalte und wàre für
Hilfe sehr dankbar. Liebe Grüße.



Mit telnet(1) kann man zwar grundsàtzlich beliebige TCP-Verbindungen
aufbauen, Telnet ist aber trotzdem ein anderes Protokoll als TeamSpeak.

Wenn Du Dir das Script genauer anschaust (oder einen Debugger, wie z.B.
Zend Debugger in Eclipse PDT einsetzt):

| public function exec($command) {
| $this->write($command);
| $this->waitPrompt();
| return $this->getBuffer();
| }

| […]
| private function write($buffer, $addNewLine = true){
| if (!$this->socket){
| throw new Exception("Telnet connection closed");
| }
|
| // clear buffer from last command
| $this->clearBuffer();
|
| if ($addNewLine == true){
| $buffer .= "";
| }
|
| if (!fwrite($this->socket, $buffer) < 0){
| throw new Exception("Error writing to socket");
| }
|
| return self::TELNET_OK;
| }

| […]
| private function waitPrompt(){
| return $this->readTo($this->prompt);
| }

| […]
| private function readTo($prompt){
| if (!$this->socket){
| throw new Exception("Telnet connection closed");
| }
|
| // clear the buffer
| $this->clearBuffer();
|
| do{
| $c = $this->getc();
|
| if ($c false){
| throw new Exception("Couldn't find the requested : '" . $prompt
| . "', it was not in the data returned from server : '" . $buf
| . "'");
| }
|
| // Interpreted As Command
| if ($c == $this->IAC){
| if ($this->negotiateTelnetOptions()){
| continue;
| }
| }
|
| // append current char to global buffer
| $this->buffer .= $c;
|
| // we've encountered the prompt. Break out of the loop
| if ((substr($this->buffer, strlen($this->buffer) - strlen($prompt)))
| == $prompt){
| return self::TELNET_OK;
| }
|
| } while($c != $this->NULL || $c != $this->DC1);
| }

| […]
| private function getBuffer(){
| // cut last line (is always prompt)
| $buf = explode("", $this->buffer);
| unset($buf[count($buf)-1]);
| $buf = implode("",$buf);
| return trim($buf);
| }

Etwa ist $this->prompt da noch NULL, da die Eigenschaft deklariert wird als

| private $prompt;

und der Konstruktoraufruf nur $this->connect() aufruft. Eine Zuweisung an
$this->prompt findet erst in

| public function login($username, $password) {
| […]
| $this->setPrompt();
| […]
| }

statt. Du müsstest also evtl. $telnet->setPrompt(…) vor $telnet->exec()
aufrufen, damit nicht zuviel gelesen wird.

Grundsàtzlich halte ich diese Klasse für Deine Zwecke für ungeeignet, da
einerseits sowohl Overkill als auch für das falsche Protokoll ausgelegt.
Ich finde es seltsam, das Du sie benutzen willst, denn eine Google-Suche
nach "teamspeak php" führt mehr oder weniger direkt zu
<http://forum.teamspeak.com/showthread.php?t!905>.

Ausserdem hat die Telnet-Klasse anscheinend einen Bug:

| } while($c != $this->NULL || $c != $this->DC1);

Das `||' müsste sinnvollerweise ein `&&' sein, sonst würde das Script auch
bei DC1 (0x11) nicht anhalten, da ja `$c != $this->NULL' zu `true' führt
(0x11 != 0x0).


HTH
PointedEars

Ähnliche fragen