<?
/*
* Ventrilo.php - Display the status of a Ventrilo Server
* Written By: Andrew Zbikowski <andyzib@gmail.com> (AKA Glarawyn, RK1)
* Version: 2.0.2 2008-07-7
*
* BeBot - An Anarchy Online Chat Automaton
* Copyright (C) 2004 Jonas Jax
* Copyright (C) 2005-2007 Thomas Juberg Stensås, ShadowRealm Creations and the BeBot development team.
*
* Developed by:
* - Alreadythere (RK2)
* - Blondengy (RK1)
* - Blueeagl3 (RK1)
* - Glarawyn (RK1)
* - Khalem (RK1)
* - Naturalistic (RK1)
*
* See Credits file for all aknowledgements.
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; version 2 of the License only.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
*  USA
*
*  Ported to BeBot 0.5 by Vrykolas - I did the easy bit, those named above
*  did all the hard work.
*/

$showvent = new ShowVent($bot);

/*
The Class itself...
*/
class ShowVent Extends BaseActiveModule
// Start Class
    
var $bot;
    var 
$colors;
    var 
$cachesec;
    var 
$cache;
    var 
$windows;
    
/*
    Constructor:
    Hands over a referance to the "Bot" class.
    */
    /*
    Constructor:
    Hands over a referance to the "Bot" class.
    */
    
function __construct (&$bot)
    {
        
parent::__construct(&$botget_class($this));

        
/*
        Bind the command to the bot.
        */
        
$this -> register_command('all''vent''MEMBER');


// Put in to clean up a bug from a previous install - can be removed after 1st run
$this -> bot -> db -> query("UPDATE #___settings SET `value` = '' WHERE module = 'Ventrilo' AND setting IN('server', 'password') AND datatype = 'null';");
$this -> bot -> db -> query("UPDATE #___settings SET `value` = 0 WHERE module = 'Ventrilo' AND setting = 'port' AND datatype = 'null';");
$this -> bot -> db -> query("UPDATE #___settings SET datatype = 'string' WHERE module = 'Ventrilo' AND setting IN('server', 'password', 'port');");
// End of removable code

        
$this -> bot -> core("settings") -> create ("Ventrilo""showserver""On""Display server information.""On;Off"FALSE1);
        
$this -> bot -> core("settings") -> create ("Ventrilo""showclient""On""Display client information.""On;Off"FALSE2);
        
$this -> bot -> core("settings") -> create ("Ventrilo""server"''"Hostname or IP Address of Ventrilo Server."''FALSE3);
        
$this -> bot -> core("settings") -> create ("Ventrilo""port"0"Port of Ventrilo server."''FALSE4);
        
$this -> bot -> core("settings") -> create ("Ventrilo""password"''"Status password for Ventrilo Server. If a password is set, you must set a port."''FALSE5);
        
$this -> bot -> core("settings") -> create ("Ventrilo""prgpath""./extras/""Path to ventrilo_status program.""./extras/;.\\extras\\;C:\\Program Files\\VentSrv\\"FALSE6);

        
$this -> help['description'] = 'Display the status of a Ventrilo Server';
        
$this -> help['command']['vent']="Returns the status of the configured Ventrilo Server.";
        
$this -> help['notes'] = "The ventrilo_status program from the Ventrilo Server distribution is required. ventrilo_status is not distributed with this module.";

        
$this -> cache['lastupdate'] = 0;
        
$this -> cachesec 60// Number of seconds to cache results for.
        
$this -> colors = array (
            
'infoheader'        => "#00DD44"// Limeish
            
'infoheadline'        => "#DDDD44"// Beige
            
'infotextbold'        => "#EEEEEE"// White?
            
'infotext'           => "#66AA66"// Green
            
'npcchat'            => "#7CE2EC"// Light Blue
            
'admin'                => "#FF0000"// Red
            
'locked'            => "#FF7718"// Orange
            
'red'                => "#FF0000",
            
'yellow'            => "#FFFF00",
            
'green'                => "#00FF00",
        );
        
/*
        Figure out the name of our ventrilo_status command
        Or, is this Windows (add .exe) or is this not Windows. ;-)
        */
        
if (strtoupper(substr(php_uname("s"), 03)) === 'WIN')
            
$this -> windows TRUE;
        else
            
$this -> windows FALSE;
    }

    
/*
    This function handles all the inputs and returns FALSE if the
    calling function should not send output, otherwise returns a string
    sutible for output via send_tell, send_pgroup, and send_gc.
    */
    
function command_handler($name$msg$origin)
    {
        
$this->error->reset(); //Reset the error message so we don't trigger the handler by old error messages.

        
return $this -> show_vent();
    }

    
/*
    Produces output for display.
    */
    
function show_vent()
    {
        if (
'' == $this -> bot -> core("settings") -> get('Ventrilo','server'))
        {
            return 
"Use <pre>set Ventrilo server HOST to set your Ventrilo server.";
        }
        if (
== $this -> bot -> core("settings") -> get('Ventrilo','port'))
        {
            return 
"Use <pre>set Ventrilo port PORTNUM to set your Ventrilo server's port.";
        }
        
$this -> get_vent();
        
$inside .= $this -> channel_display($this -> cache['vent']['channels'], $this -> cache['vent']['clients']);
        if (
"on" == strtolower($this -> bot -> core("settings") -> get('Ventrilo''showserver')))
        {
            
$inside .= $this -> server_display($this -> cache['vent']['server']);
        }
        if (
"on" == strtolower($this -> bot -> core("settings") -> get('Ventrilo','showclient')))
        {
            
$inside .= $this -> client_display($this -> cache['vent']['clients']);
        }
        return 
$this -> bot -> core("tools") -> make_blob("Ventrilo Status"$inside);
    }

    
/*
    Formats the server array for output.
    */
    
function server_display($server)
    {
        
$return "##AO_INFOHEADER##Ventrilo Server Status##END##\n\n";
        
$return .= "Name: ".$server['name']."\n";
        
$return .= "Phonetic: ".$server['phonetic']."\n";
        
$return .= "Comment: ".$server['comment']."\n";
        
$return .= "Auth: ".$server['auth']."\n";
        
$return .= "Max Clients: ".$server['maxclients']."\n";
        
$return .= "Voice Codec: ".$server['voicecodec']."\n";
        
$return .= "Voice Format: ".$server['voiceformat']."\n";
        
$return .= "Uptime: ".$server['uptime']."\n";
        
$return .= "Platform: ".$server['platform']."\n";
        
$return .= "Version: ".$server['version']."\n";
        
$return .= "Channel Count: ".$server['channelcount']."\n";
        
$return .= "Client Count: ".$server['clientcount']."\n";
        
$return .= "\n";
        return 
$return;
    }

    
/*
    Formats the clients array for output
    */
    
function client_display($clients)
    {
        
$output "##AO_INFOHEADER##User Info:##END##\n\n";
        if (!empty(
$clients))
        {
            foreach (
$clients as $client)
            {
                
$string $client['name'];
                if (
$client['admin'])
                {
                    
$string "##AO_GM##".$string."##END##";
                }

                if (
$client['comment'] <> "")
                    
$string .= " (".$client['comment'].")";
                
$string .= " ";

                
$string .= "[Ping: ";

                if (
$client['ping'] <= 200)
                {
                    
$string .= "##GREEN##".$client['ping']."##END##";
                }
                elseif (
$client['ping'] <= 300)
                {
                    
$string .= "##YELLOW##".$client['ping']."##END##";
                }
                else
                {
                    
$string .= "##RED##".$client['ping']."##END##";
                }

                
$string .= "] ";

                
$dhms $this -> bot -> core("time") -> get_DHMS($client['sec']);
                
$string .= "[Online For ";
                if (
$dhms[0] > 0)
                    
$string .= $dhms[0]." Days, ";
                if (
$dhms[1] > 0)
                    
$string .= $dhms[1]." Hours, ";
                
$string .= $dhms[2]." Minutes, ";
                
$string .= $dhms[3]." Seconds.] ";
                
$string .= "\n";
                
$output .= $string;
            }
        }
        else
        {
            
$output .= "No clients connected to Ventrilo server.";
        }
        return 
$output;
    }

    
/*
    Formats the channel array for output
    */
    
function channel_display($channels$clients)
    {
        
$tab "##tab##";
        
ksort($channels);
        
// Format each channel.
        
foreach ($channels as $channel)
        {
            
//$outchan[$channel['cid']] = $tab;
            
$outchan[$channel['cid']] .= "+ ".$channel['name'];
            if (
$channel['prot'] <> 0)
            {
                
$outchan[$channel['cid']] = "##ORANGE##".$outchan[$channel['cid']]."##END##";
            }
            if     (
$channel['comment'] <> "")
            {
                
$outchan[$channel['cid']] .= " (".$channel['comment'].")";
            }
            
$outchan[$channel['cid']] .= "\n";
        }

        
// Now that should look like $outchan['cid'] = Channel Name (Channel Comment)\n
        
if (!empty($clients))
        {
            foreach (
$clients as $client)
            {
                
$string $client['name'];
                if (
$client['admin'])
                {
                    
$string "##AO_GM##".$string."##END##";
                }
                if (
$client['comment'] <> "")
                {
                    
$string .= " (".$client['comment'].")";
                }

                
$string .= "\n";

                
$outchan[$client['cid']] .= $tab."- ".$string;
            }
        }

        
// Check for sub-channels.
        
foreach ($channels as $channel)
        {
            if (
$channel['pid'] <> 0)
            {
                
$outchan[$channel['cid']] = str_replace($tab'##tab####tab##'$outchan[$channel['cid']]);
                
$outchan[$channel['pid']] .= $tab.$outchan[$channel['cid']];
                unset (
$outchan[$channel['cid']]);
            }
        }

        
// Now this should looke like:
        // Channel Name (Channel Comment)\n##tab###- Username (Comment), Ping: NUM, Online for X Days, X Hours, X Minutes, X Seconds.\n
        
foreach ($outchan as $string)
        {
            
$output .= str_replace($tab"    "$string);
        }
        return 
"##AO_INFOHEADER##Channel Info: ##END##\n\n".$output."\n\n";
    }

    
/*
    Gets the output from ventrilo_status and breaks it up into an array.
    */
    
function get_vent()
    {
        if (
time() - $this -> cache['lastupdate'] > $this -> cachesec)
        {
            
// Combine settings to form the server string.
            // server:port:password
            
$server $this -> bot -> core("settings") -> get('Ventrilo''server');
            
$port $this -> bot -> core("settings") -> get('Ventrilo''port');
            
$passwd $this -> bot -> core("settings") -> get('Ventrilo''password');
            if (isset(
$port))
            {
                
$server .= ":".$port;
                if (isset(
$passwd))
                {
                    
$server .= ":".$passwd;
                }
            }
            
// Name of the ventrilo_status executable.
            
if ($this -> windows)
            {
                
$ventrilo_status "ventrilo_status.exe";
            }
            else
            {
                
$ventrilo_status "ventrilo_status";
            }

            
// Put together the full command...
            
$command "\"".$this -> bot -> core("settings") -> get('Ventrilo''prgpath').$ventrilo_status."\" -c2 -t".$server;
            
$vent shell_exec($command);
            
$vent explode("\n"$vent);
            
$vent $this -> parse_vent($vent);
            
$this -> cache['lastupdate'] = time();
            
$this -> cache['vent'] = $vent;
            
//$this -> cache['server'] = $this -> server_display($vent['server']);
            //$this -> cache['channels'] = $this -> channel_display($vent['channels'], $vent['server']['channelcount'], $vent['clients']);
            //return $vent;
        
}
        return 
$this -> cache['vent'];
    }

    
/*
    Parses output of get_vent()
    */
    
function parse_vent($array)
    {
        if (empty(
$array))
            return 
FALSE;
        
$channel 0;
        
$client 0;
        foreach (
$array as $string)
        {
            if (
preg_match("/(.+?): (.*)/"$string$info))
            {
                
// $info[1] Will be the
                
if ($info[1] == "CLIENT")
                {
                    
// $vent[strtolower($info[1].$client)] = parse_client($info[0]);
                    
$vent['clients'][$client] = $this -> parse_client($info[0]);
                    
$client++;

                }
                else if (
$info[1] == "CHANNEL")
                {
                    
//$vent[strtolower($info[1].$channel)] = parse_channel($info[0]);
                    
$tmp $this -> parse_channel($info[0]);
                    
$vent['channels'][$tmp['cid']] = $tmp;
                    
$channel++;
                }
                else
                {
                    
$vent['server'][strtolower($info[1])] = $info[2];
                }
            }
        }
        
// Need a Lobby channel.
        
$vent['channels'][0] = array('cid' => 0'pid' => 0'prot' => 0'name' => "Lobby"'comment' => "");
        return 
$vent;
    }

    
/*
    Parses channels into an array.
    */
    
function parse_channel($string)
    {
        
// CHANNEL: CID=1,PID=0,PROT=0,NAME=XP and SK,COMM=
        
if (preg_match("/CHANNEL: CID=(.+?),PID=(.+?),PROT=(.+?),NAME=(.+?),COMM=(.*)/"$string$info))
        {
            
print_r("Channel With Comment");
        }
        else if (
preg_match("/CHANNEL: CID=(.+?),PID=(.+?),PROT=(.+?),NAME=(.*)/"$string$info))
        {
            
$info[5] = "";
        }

        
$channel['cid'] = $info[1]; // CID (Channel ID Number)
        
$channel['pid'] = $info[2]; // PID (Parent Channel ID Number)
        
$channel['prot'] = $info[3]; // PROT (Protected/Locked)
        
$channel['name'] = $info[4]; // NAME (Channel Name)
        
$channel['comment'] = $info[5]; //COMM (Comment)
        
return $channel;
    }

    
/*
    Parses clients into an array.
    */
    
function parse_client($string)
    {
        
// CLIENT: UID=292,ADMIN=1,CID=210,PHAN=0,PING=62,SEC=17689,NAME=Juts,COMM=
        
if (preg_match("/CLIENT: ADMIN=(.+?),CID=(.+?),PHAN=(.+?),PING=(.+?),SEC=(.+?),NAME=(.+?),COMM=(.*)/"$string$info))
        {
            
print_r("Client With Comment");
        }
        else if (
preg_match("/CLIENT: ADMIN=(.+?),CID=(.+?),PHAN=(.+?),PING=(.+?),SEC=(.+?),NAME=(.*)/"$string$info))
        {
            
$info[8] = "";
        }
        
//$client['uid'] = $info[1]; // User ID (ID number)
        
$client['admin'] = $info[1]; // Admin Status (0 = not admin, 1 = admin)
        
$client['cid'] = $info[2]; // CID (Channel ID) ID number of the channel the user is currently in.
        
$client['phan'] = $info[3]; // PHAN: I have no clue what this is.
        
$client['ping'] = $info[4]; // Ping Latency between server and client
        
$client['sec'] = $info[5]; // Sec Client has been connected for this many seconds
        
$client['name'] = $info[6]; // Name Client Name
        
$client['comment'] = $info[7]; // Comment Client Comment
        
return $client;
    }

// End of Class
?>