Ankündigung

Einklappen
Keine Ankündigung bisher.

Teamspeakbot Script

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Teamspeakbot Script

    Sehr geehrte Communitymember ,

    ich bin gerade dabei ein Teamspeakbot zu entickeln, komme allerdings nicht weiter. Und zwar möchte ich bei über ein Socket auf die Teamspeak Telnet konsole zugreifen. Das Funktioniert auch schonmal, allerdings möchte ich dann wenn jemand "!info" in die Console eingibt, dass dort die Info angezeigt wird. Meine einzige Lösung die ich dazu hatte, war eine while(1) Schleife, allerdings reagiert dann nichts anderes mehr in meinem Script.

    bot.php
    PHP-Code:
    #!/usr/bin/php
    <?php

        
    /*
            Includes
        */
        
    require_once("config.php");
        require_once(
    "../config.php");
        require_once(
    "TeamspeakInstanz.class.php");
        require_once(
    "TeamspeakCommandEvents.class.php");

        
    /*
            Laufzeit verlängern
        */
        
    set_time_limit(0);
        
    ini_set('default_charset''UTF-8');
        
    setlocale(LC_ALL'UTF-8');

        
    writeInLog(5,"Initialize Bot...");

        
    /*
            Datenbankverbindung herstellen
        */
        
    try
        {
            
    $databaseConnection     =     new PDO('mysql:host='.SQL_Hostname.';port='.SQL_Port.';dbname='.SQL_Datenbank.''SQL_UsernameSQL_Password);
            
    writeInLog(5,"MySQL Connection successfull!");
        }
        catch (
    PDOException $e)
        {
            
    writeInLog(1"MySQL Connection Failed:".$e->getMessage());
            
    unlink("runningScript");
            
    goShutdown();
        };

        
    /*
            Funktion: Logfile
        */
        
    function writeInLog($loglevel$logtext)
        {
            
    $file             =     '../logs/bot.log';
            if (
    $loglevel == 1)
            {
                
    $loglevel     =     "\tCRITICAL\t";
            }
            elseif (
    $loglevel == 2)
            {
                
    $loglevel    =     "\tERROR\t\t";
            }
            elseif (
    $loglevel == 3)
            {
                
    $loglevel     =     "\tWARNING\t\t";
            }
            elseif (
    $loglevel == 4)
            {
                
    $loglevel     =    "\tNOTICE\t\t";
            }
            elseif (
    $loglevel == 5)
            {
                
    $loglevel     =     "\tINFO\t\t";
            };

            
    $date            =    date("Y-m-d H:i:s");
            
    $input             =     $date.$loglevel.$logtext."\n";

            
    $loghandle fopen($file'a');
            
    fwrite($loghandle$input);
            if (
    filesize($file) > 10242880)
            {
                
    fwrite($loghandle$date."\tNOTICE\t\tLogfile filesie of 10 MiB reached.. Rotate logfile.\n");
                
    fwrite($loghandle$date."\tNOTICE\t\tRestart Bot to continue with new log file...\n");
                
    fclose($loghandle);
                
    $file2 "$file.old";
                if (
    file_exists($file2))
                {
                    
    unlink($file2);
                };
                
    rename($file$file2);
                if (
    substr(php_uname(), 07) == "Windows")
                {
                    
    exec("del /F ".substr(__DIR__,0,-4).'logs/pid');
                    
    $WshShell = new COM("WScript.Shell");
                    
    $oExec $WshShell->Run("cmd /C php ".substr(__DIR__,0,-4)."worker.php start"0false);
                    exit;
                }
                else
                {
                    
    exec("rm -f ".substr(__DIR__,0,-4).'logs/pid');
                    
    exec("php ".substr(__DIR__,0,-4)."worker.php start");
                    exit;
                };
            };
        };

        
    /*
            Create the Teamspeakbot Instanzes
        */
        /*$TeamspeakInstanzen                        =    [];
        foreach($ts3_server AS $instanz => $instanzdata)
        {
            if($instanz == 0)
            {
                $TeamspeakInstanzen[$instanz]    =    new TeamspeakInstanzClass();
            };
        };*/
        
    $server        =    new TeamspeakInstanzClass($ts3_server[0], 10$settings);
    ?>
    TeamspeakInstanzClass:
    PHP-Code:
    <?php
        
    /*
            TeamspeakInstanzClass
        */
        
    class TeamspeakInstanzClass
        
    {
            
    /*
                Variabeln
            */
            
    public $infoText        =    '';

            public 
    $sock            =    NULL;
            private 
    $settings        =    array();

            
    /*
                Konstruktor
            */
            
    function __construct($config$serverid$settings)
            {
                
    /*
                    Teamspeakverbindung
                */
                
    self::connect($config$serverid);

                
    /*
                    Settings speichern
                */
                
    $this->settings        =    $settings;

                
    /*
                    Kommandos aktivieren
                */
                
    new TeamspeakCommandEvents($this->sock$settings$this->infoText);

                
    /*
                    Check die Config
                */
                
    self::CheckConfig();
            }

            private function 
    connect($config$serverid)
            {
                
    $this->infoText        .=    "\n######################################################\n";
                
    $this->infoText        .=    "# ".TS3_CHATNAME." [b][color=green]Online![/color][/b]\n";
                
    $this->infoText        .=    "# Current Version: [i]".bot_version."[/i]\n";
                
    $this->infoText        .=    "######################################################\n";

                if(!
    $this->sock        =    fsockopen($config['ip'], $config['queryport'], $errno$errstr10))
                {
                    
    writeInLog(1"Teamspeak Connections fail! (Message: ".$errstr.")");
                    exit();
                }
                else
                {
                    
    // Login
                    
    fputs($this->sock,"login ".$config['user']." ".$config['pw']."\n");

                    
    $data            =    array();
                    
    $data            =    $this->getData($this->sock);

                    if(
    $data['success'] == true)
                    {
                        
    // Server select
                        
    fputs($this->sock,"use {$serverid}\n");

                        
    $data            =    $this->getData($this->sock);
                        if(
    $data['success'] == true)
                        {
                            
    // Bot einen Namen geben
                            
    fputs($this->sock,"clientupdate client_nickname=".$this->escapeText(TS3_CHATNAME)."\n");

                            
    // Events registrieren
                            
    fputs($this->sock,"servernotifyregister event=server\nservernotifyregister event=textserver\n");

                            
    // Infotext beim Start ausgeben
                            
    fputs($this->sock,"sendtextmessage targetmode=3 id=".$this->escapeText($serverid)." msg=".$this->escapeText($this->infoText)."\n");
                        }
                        else
                        {
                            
    writeInLog(1"Teamspeakselect fail! ServerId ".$serverid." does not exist! (Message: ".$data['errors'].")");
                            exit();
                        };
                    }
                    else
                    {
                        
    writeInLog(1"Teamspeak Connections fail! (Message: ".$data['errors'].")");
                        exit();
                    };
                };
            }

            private function 
    CheckConfig()
            {
                
    /*
                    Afk Mover
                */
                /*if($settings['afkChannel'] != -1)
                {
                    $afkMover        =    new teamspeakAfkMover($this->sock, $settings);
                }*/

                
    print_r($this->settings);
            }

            
    /*

                if(empty($data))
                {
                    $this->runtime['socket'] = $this->runtime['bot_clid'] = '';
                    $this->addDebugLog('Socket closed.', $tracert[1]['function'], $tracert[0]['line']);
                    return $this->generateOutput(false, array('Socket closed.'), false);
                }
                else if(strpos($data, 'error id=3329 msg=connection') !== false) {
                    $this->runtime['socket'] = $this->runtime['bot_clid'] = '';
                    $this->addDebugLog('You got banned from server. Socket closed.', $tracert[1]['function'], $tracert[0]['line']);
                    return $this->generateOutput(false, array('You got banned from server. Connection closed.'), false);
                }
            */

            
    public function escapeText($text)
            {
                
    $text str_replace("\t"'\t'$text);
                
    $text str_replace("\v"'\v'$text);
                
    $text str_replace("\r"'\r'$text);
                
    $text str_replace("\n"'\n'$text);
                
    $text str_replace("\f"'\f'$text);
                
    $text str_replace(' ''\s'$text);
                
    $text str_replace('|''\p'$text);
                
    $text str_replace('/''\/'$text);
                return 
    $text;
            }

            public function 
    unEscapeText($text)
            {
                
    $escapedChars = array("\t""\v""\r""\n""\f""\s""\p""\/");
                
    $unEscapedChars = array(''''''''''' ''|''/');
                
    $text str_replace($escapedChars$unEscapedChars$text);
                return 
    $text;
            }

            public function 
    getData($socket)
            {
                
    $data                        =    "";
                do {
                    
    $data                     .=     fgets($socket4096);

                    if(empty(
    $data))
                    {
                        
    writeInLog(1"Socket looks like its closed!");
                        exit();
                    }
                    else if(
    strpos($data'error id=3329 msg=connection') !== false) {
                        
    //$this->runtime['socket'] = $this->runtime['bot_clid'] = '';
                        
    writeInLog(1"You got banned from server. Connection closed.");
                        exit();
                    };

                } while(
    strpos($data'msg=') === false or strpos($data'error id=') === false);

                if(
    strpos($data'error id=0 msg=ok') === false)
                {
                    
    $splittedResponse         =     explode('error id='$data);
                    
    $chooseEnd                 =     count($splittedResponse) - 1;

                    
    $cutIdAndMsg explode(' msg='$splittedResponse[$chooseEnd]);

                    if(
    $tracert != null)
                        
    $this->addDebugLog('ErrorID: '.$cutIdAndMsg[0].' | Message: '.$this->unEscapeText($cutIdAndMsg[1]), $tracert[1]['function'], $tracert[0]['line']);

                    return 
    $this->generateOutput(false, array('ErrorID: '.$cutIdAndMsg[0].' | Message: '.$this->unEscapeText($cutIdAndMsg[1])), false);
                }
                else
                {
                    return 
    $this->generateOutput(true, array(), $data);
                };
            }

            private function 
    generateOutput($success$errors$data)
            {
                return array(
    'success' => $success'errors' => $errors'data' => $data);
            }

            
    /*
                Funktion: convTime
            */
            
    public function convTime($timestamp)
            {
                
    // Milliseconds to seconds
                
    $timestamp        =    $timestamp 1000;

                
    // Seconds to Minutes
                
    $timestamp        =    $timestamp 60;

                return 
    $timestamp;
            }
        };
    ?>
    TeamspeakCommandEvents:
    PHP-Code:
    <?php
        
    /*
            TeamspeakCommandEvents
        */
        
    class TeamspeakCommandEvents extends TeamspeakInstanzClass
        
    {
            function 
    __construct($socket$settings$infoText)
            {
                while(
    $data         =         fgets($socket))
                {
                    if(
    strpos($data'error id=') === false)
                    {
                        
    //echo $data."\n\n";
                        
    $data         =         trim($data);
                        
    $ex         =         explode(" ",$data);

                        if (
    $ex[0] == "notifytextmessage")
                        {
                            
    // Daten auslesen
                            
    $message     =     substr($ex[2],4);
                            
    $nick         =     substr($ex[4],12);
                            
    $id            =    substr($ex[3],10);

                            
    // If !info
                            
    if($message == '!info')
                            {
                                
    fputs($socket,"sendtextmessage targetmode=3 id=".parent::escapeText($settings['serverid'])." msg=".parent::escapeText($infoText)."\n");
                            };
                        };
                    };
                }
            }
        };
    ?>
    Gibt es nicht eine Lösung als Art "onNotify" statt while(1) zu nutzen?

    Mit freundlichen Grüßen
    Lukas
    http://first-coder.de/ <== Free Teamspeak3 Webinterface for everyone

  • #2
    Ja, deine while Schleife nennt sich busy wait und ist immer schlecht, da sie 100 % Prozessor Leistung braucht (Ja, ich weiß, bei einem guten Betriebssystem sind es 99,99%, damit man den Prozess noch killen kann).

    Soetwas mit onNotify gibt es, nennt sich pthreads. Threads sind ein Thema für sich, würder mich da erstmal einarbeiten. Die Dokumentation dazu von PHP ist eher mager, aber Du kannst dir viel von appserver.io abschauen, wie das machen.

    Dein Problem ist eher, dass sich niemand wirklich auf deinen Bot verbindet. Dann wäre es einfach gewesen: eingehende Sockets akzeptieren und bis zum Verbindungsaufbau an der Code Stelle warten (blockierende Sockets), dann einen Arbeitsthread starten, der alles erledigt. Da du das nicht hast, müsstest du dich eher mal mit den TeamSepak SDK befassen, denn darin gibt es bestimmt Events. Das ist aber auf C++ Basis und mir ist kein Weg bekannt, in PHP C++ Header Files einzubinden. Das heißt ich denke mal stark, dass du mit PHP falsch beraten bist.

    Kommentar


    • #3
      Es gibt ein Teamspeak PHP Framework, das Events anbietet. Vermutlich gibt es dort auch ein Event für Konsolenbefehle.
      Diese Events musst du aber auch über eine Schleife pullen.

      So wie du dir das vorstellst (dass wenn jemand ein Konsolenbefehl absendet, dass dann einfach ein PHP Event ausgeführt wird) geht das nicht. Irgendwoher müsste der Teamspeak Server wissen, dass er ein PHP Script aufrufen müsste bei einem bestimmten Event. Geht mit der TeamspeakSDK.
      Der andere Weg ist, dass du über PHP beim Server ständig anfragst, ob ein Event (Konsolenkommando gesendet) ausgelöst wurde und darauf dann reagierst (das auslesen kanns du mit dem Teamspeak PHP Framework machen).

      Das Abfragen macht man dann über einen Daemon, der im Hintergrund und als eigenständiger PHP Prozess arbeitet (im Prinzip eine riesige Endless-While-Schleife). Wenn sowas aber wirklich permanent laufen soll muss man da sehr ordentlich und bedacht arbeiten, sonst läuft irgendwann der Arbeitsspeicher voll (unset(), Garbage Collector aufrufen, etc.).
      "Software is like Sex, it's best if it's free." - Linus Torvalds

      Kommentar


      • #4
        Zitat von JaMa Beitrag anzeigen
        Es gibt ein Teamspeak PHP Framework, das Events anbietet. Vermutlich gibt es dort auch ein Event für Konsolenbefehle.
        Das Abfragen macht man dann über einen Daemon, der im Hintergrund und als eigenständiger PHP Prozess arbeitet (im Prinzip eine riesige Endless-While-Schleife). Wenn sowas aber wirklich permanent laufen soll muss man da sehr ordentlich und bedacht arbeiten, sonst läuft irgendwann der Arbeitsspeicher voll (unset(), Garbage Collector aufrufen, etc.).
        Warum weigern sich alle so strikt gegen Threads?

        Kommentar


        • #5
          Ich weigere mich nicht strikt gegen Threads. Nur habe ich für sowas eigentlich keine Verwendung.
          Wenn ich Aufgaben habe die im Hintergrund laufen sollen, dann lasse ich das über Daemons erledigen (für kleine Sachen PHP, für größeres dann C++).

          Ob das jetzt ein extra Thread ist, der die Events pulled oder der Daeomon selber, macht für mich keinen großen Unterschied mehr, da das ganze sowieso im Hintergrund abläuft und nicht Zeitkritisch sein wird.
          "Software is like Sex, it's best if it's free." - Linus Torvalds

          Kommentar

          Lädt...
          X