<?php
require_once 'modules/admin/models/DashboardPlugin.php';
require_once 'newedge/classes/NE_PluginCollection.php';
require_once 'newedge/classes/NE_Error.php';

class PluginTeamspeak3status extends DashboardPlugin
{
    var $hasTab = false;
    var $hasPanel = true;
    var $name = "Teamspeak 3 Status";
    var $description = /*T*/"This plugin adds a dashboard panel which lists the current status of all teamspeak 3 servers.  Data shown includes server uptime, number of servers, number of clients online and total number of clients allowed."/*/T*/;
    var $default = false;

    function getTab()
    {
        return '';
    }
    
    function getPanel()
    {
        $this->tpl->define(array('teamspeak' => '../../plugins/dashboard/teamspeak3status/PluginTeamspeak3status.tpl'));
        
        $query = "SELECT name, hostname FROM server WHERE plugin='teamspeak3'";
        $result = $this->db->query($query);
                
        while ($row = $result->fetch()) {
            $status = $this->getStatus($row['hostname'], 10011);
            $status['server_name'] = $row['name'];
            $this->tpl->setKey($status);
            $this->tpl->parse('ts3Server_out', '.ts3Server');
        }

        if (!$result->getNumRows()) {
            $this->tpl->parse('noServers_out', 'noServers');
            return $this->tpl->fetch('noServers_out');
        }
        
        $this->tpl->parse('teamspeak', 'teamspeak');   
        return $this->tpl->fetch('teamspeak');
    }
    
    function getStatus($host, $port)
    {
        $statusInfo = array(
            'error'             => '',
            'uptime'            => 0,
            'servers_online'    => 0,
            'clients_max'       => 0,
            'clients_online'    => 0,
        );
    
        $conn = $this->connect($host, $port);
        $result = $this->callCommand("hostinfo", $conn);
        if (is_a($result, 'NE_Error')) {
            $statusInfo['error'] = $result->getMessage();
        } else {
            if (isset($result['msg']) && $result['msg'] != 'ok') {
                $statusInfo['error'] = $result['msg'];
            } else {
                if (isset($result['instance_uptime'])) 
                    $statusInfo['uptime'] = $this->timeformat($result['instance_uptime']);
                    
                if (isset($result['virtualservers_running_total']))
                    $statusInfo['servers_online'] = $result['virtualservers_running_total'];
                    
                if (isset($result['virtualservers_total_maxclients']))
                    $statusInfo['clients_max'] = $result['virtualservers_total_maxclients'];
                    
                if (isset($result['virtualservers_total_clients_online']))
                    $statusInfo['clients_online'] = $result['virtualservers_total_clients_online'];
            }
        }
        return $statusInfo;
    }
    
    function timeformat($msecs) 
    {
        $mins = 0;
        $hours = 0;
        $days = 0;
        $years = 0;
        
        if ($msecs == 0) return 'Offline';
        
        $secs = ceil($msecs / 1000);
        
        if ($secs >= 60) {
            $mins = floor($secs / 60);
            $secs = $secs % 60;
        }
        if ($mins >= 60) {
            $hours = floor($mins / 60);
            $mins = $mins % 60;
        }
        if ($hours >= 24) {
            $days = floor($hours / 24);
            $hours = $hours % 24;
        }
        if ($days >= 365) {
            $years = floor($days / 365);
            $days = $days % 365;
        }
        $uptime = "";
        if ($years != 1 && $years != 0) $uptime .= $years." years ";
        elseif ($uptime != "") $uptime .= $years." year ";
        if ($days != 1 && $days != 0) $uptime .= $days." days ";
        elseif ($days != 0 || $uptime != "") $uptime .= $days." day ";
        if ($hours != 1) $uptime .= $hours." hours ";
        elseif ($hours != 0 || $uptime != "") $uptime .= $hours." hour ";
        if ($mins != 1) $uptime .= $mins." mins ";
        else $uptime .= $mins." min ";
        if ($secs != 1) $uptime .= $secs." secs ";
        else $uptime .= $secs." sec";
        return $uptime;
  }
    
    function connect($host, $port)
    {
        // Connect to the server and check that it was successful
        $conn = @fsockopen($host, $port);
        if (!$conn) {
            throw new Exception('Connection failed. ERROR: Cannot connect to server('.$return.')');
        }
        
        $return = fgets($conn, 10);
        if (strpos($return, "TS3") === false)
        {
            fclose($conn);
            throw new Exception('Welcome message missing. ERROR: Cannot connect to server('.$return.')');
        }
        
        return $conn;
    }
    
    function callCommand($command, $conn)
    {
        fputs($conn, $command . "\n");
        $result = array();
        $char = '';
        $token = '';
        while (($char = fgetc($conn)) !== false) {
            // End of token
            if (trim($char) == '' && $token != 'error') {
                $pieces = explode('=', $token);
                if (sizeof($pieces) == 2) {
                    $result[$pieces[0]] = $pieces[1];
                }
                $token = '';
                if (isset($result['msg'])) break;
            } else {
                $token .= $char;
            }
        }
        return $result;
    }
}

?>
