Hier mal die 5 php-Dateien:
ventrilodisplay_ex1.php
<?php
function VentriloDisplayEX1( &$stat, $name, $cid, $bgidx )
{
$chan = $stat->ChannelFind( $cid );
if ( $bgidx % 2 )
$bg = "#666666";
else
$bg = "#333333";
/*
if ( $chan->m_prot )
$fg = "#FF0000";
else
$fg = "#FFFFFF";
*/
$fg = "#FFFFFF";
if ( $chan->m_prot )
{
if ( $bgidx %2 )
$bg = "#660000";
else
$bg = "#330000";
}
echo " <tr>\n";
echo " <td bgcolor=\"$bg\"><font color=\"$fg\"><strong>";
echo $name;
echo "</strong></font>\n";
echo " <table width=\"95%\" border=\"0\" align=\"right\">\n";
// Display Client for this channel.
for ( $i = 0; $i < count( $stat->m_clientlist ); $i++ )
{
$client = $stat->m_clientlist[ $i ];
if ( $client->m_cid != $cid )
continue;
echo " <tr>\n";
echo " <td bgcolor=\"#FFFFFF\">";
$flags = "";
if ( $client->m_admin )
$flags .= "A";
if ( $client->m_phan )
$flags .= "P";
if ( strlen( $flags ) )
echo "\"$flags\" ";
echo $client->m_name;
if ( $client->m_comm )
echo " ($client->m_comm)";
echo " </td>\n";
echo " </tr>\n";
}
// Display sub-channels for this channel.
for ( $i = 0; $i < count( $stat->m_channellist ); $i++ )
{
if ( $stat->m_channellist[ $i ]->m_pid == $cid )
{
$cn = $stat->m_channellist[ $i ]->m_name;
if ( strlen( $stat->m_channellist[ $i ]->m_comm ) )
{
$cn .= " (";
$cn .= $stat->m_channellist[ $i ]->m_comm;
$cn .= ")";
}
VentriloDisplayEX1( $stat, $cn, $stat->m_channellist[ $i ]->m_cid, $bgidx + 1 );
}
}
echo " </table>\n";
echo " </td>\n";
echo " </tr>\n";
}
?>
ventriloinfo_ex1.php
<?php
function VentriloInfoEX1_Stripe( &$bgidx, $name, $val )
{
if ( $bgidx % 2 )
$bgcolname = "#666666";
else
$bgcolname = "#333333";
if ( $bgidx % 2 )
$bgcolval = "#FFFFCC";
else
$bgcolval = "#FFFFFF";
echo " <tr>\n";
echo " <td width=\"35%\" bgcolor=\"$bgcolname\"><font color=\"#FFFFFF\">";
echo "<strong>";
echo $name;
echo "</strong>";
echo "</font></td>\n";
echo " <td width=\"65%\" bgcolor=\"$bgcolval\"><font color=\"#000000\">";
echo "<div align=\"center\">";
echo $val;
echo "</div";
echo "</font></td>\n";
echo " </tr>\n";
$bgidx += 1;
}
function VentriloInfoEX1( &$stat )
{
$bgidx = 0;
VentriloInfoEX1_Stripe( $bgidx, "Name", $stat->m_name );
VentriloInfoEX1_Stripe( $bgidx, "Phonetic", $stat->m_phonetic );
VentriloInfoEX1_Stripe( $bgidx, "Comment", $stat->m_comment );
VentriloInfoEX1_Stripe( $bgidx, "Auth", $stat->m_auth );
VentriloInfoEX1_Stripe( $bgidx, "Max Clients", $stat->m_maxclients );
VentriloInfoEX1_Stripe( $bgidx, "Voice Codec", $stat->m_voicecodec_desc );
VentriloInfoEX1_Stripe( $bgidx, "Voice Format", $stat->m_voiceformat_desc );
VentriloInfoEX1_Stripe( $bgidx, "Uptime", $stat->m_uptime );
VentriloInfoEX1_Stripe( $bgidx, "Platform", $stat->m_platform );
VentriloInfoEX1_Stripe( $bgidx, "Version", $stat->m_version );
VentriloInfoEX1_Stripe( $bgidx, "Channel Count", $stat->m_channelcount );
VentriloInfoEX1_Stripe( $bgidx, "Client Count", $stat->m_clientcount );
}
?>
ventrilostatus.php
<?php
/*
This file should not be modified. This is so that future versions can be
dropped into place as servers are updated.
Version 2.3.0: Supports phantoms.
Version 2.2.1: Supports channel comments.
*/
function StrKey( $src, $key, &$res )
{
$key .= " ";
if ( strncasecmp( $src, $key, strlen( $key ) ) )
return false;
$res = substr( $src, strlen( $key ) );
return true;
}
function StrSplit( $src, $sep, &$d1, &$d2 )
{
$pos = strpos( $src, $sep );
if ( $pos === false )
{
$d1 = $src;
return;
}
$d1 = substr( $src, 0, $pos );
$d2 = substr( $src, $pos + 1 );
}
function StrDecode( &$src )
{
$res = "";
for ( $i = 0; $i < strlen( $src ); )
{
if ( $src[ $i ] == '%' )
{
$res .= sprintf( "%c", intval( substr( $src, $i + 1, 2 ), 16 ) );
$i += 3;
continue;
}
$res .= $src[ $i ];
$i += 1;
}
return( $res );
}
class CVentriloClient
{
var $m_uid; // User ID.
var $m_admin; // Admin flag.
var $m_phan; // Phantom flag.
var $m_cid; // Channel ID.
var $m_ping; // Ping.
var $m_sec; // Connect time in seconds.
var $m_name; // Login name.
var $m_comm; // Comment.
function Parse( $str )
{
$ary = explode( ",", $str );
for ( $i = 0; $i < count( $ary ); $i++ )
{
StrSplit( $ary[ $i ], "=", $field, $val );
if ( strcasecmp( $field, "UID" ) == 0 )
{
$this->m_uid = $val;
continue;
}
if ( strcasecmp( $field, "ADMIN" ) == 0 )
{
$this->m_admin = $val;
continue;
}
if ( strcasecmp( $field, "CID" ) == 0 )
{
$this->m_cid = $val;
continue;
}
if ( strcasecmp( $field, "PHAN" ) == 0 )
{
$this->m_phan = $val;
continue;
}
if ( strcasecmp( $field, "PING" ) == 0 )
{
$this->m_ping = $val;
continue;
}
if ( strcasecmp( $field, "SEC" ) == 0 )
{
$this->m_sec = $val;
continue;
}
if ( strcasecmp( $field, "NAME" ) == 0 )
{
$this->m_name = StrDecode( $val );
continue;
}
if ( strcasecmp( $field, "COMM" ) == 0 )
{
$this->m_comm = StrDecode( $val );
continue;
}
}
}
}
class CVentriloChannel
{
var $m_cid; // Channel ID.
var $m_pid; // Parent channel ID.
var $m_prot; // Password protected flag.
var $m_name; // Channel name.
var $m_comm; // Channel comment.
function Parse( $str )
{
$ary = explode( ",", $str );
for ( $i = 0; $i < count( $ary ); $i++ )
{
StrSplit( $ary[ $i ], "=", $field, $val );
if ( strcasecmp( $field, "CID" ) == 0 )
{
$this->m_cid = $val;
continue;
}
if ( strcasecmp( $field, "PID" ) == 0 )
{
$this->m_pid = $val;
continue;
}
if ( strcasecmp( $field, "PROT" ) == 0 )
{
$this->m_prot = $val;
continue;
}
if ( strcasecmp( $field, "NAME" ) == 0 )
{
$this->m_name = StrDecode( $val );
continue;
}
if ( strcasecmp( $field, "COMM" ) == 0 )
{
$this->m_comm = StrDecode( $val );
continue;
}
}
}
}
class CVentriloStatus
{
// These need to be filled in before issueing the request.
var $m_cmdprog; // Path and filename of external process to execute. ex: /var/www/html/ventrilo_status
var $m_cmdcode; // Specific status request code. 1=General, 2=Detail.
var $m_cmdhost; // Hostname or IP address to perform status of.
var $m_cmdport; // Port number of server to status.
// These are the result variables that are filled in when the request is performed.
var $m_error; // If the ERROR: keyword is found then this is the reason following it.
var $m_name; // Server name.
var $m_phonetic; // Phonetic spelling of server name.
var $m_comment; // Server comment.
var $m_maxclients; // Maximum number of clients.
var $m_voicecodec_code; // Voice codec code.
var $m_voicecodec_desc; // Voice codec description.
var $m_voiceformat_code; // Voice format code.
var $m_voiceformat_desc; // Voice format description.
var $m_uptime; // Server uptime in seconds.
var $m_platform; // Platform description.
var $m_version; // Version string.
var $m_channelcount; // Number of channels as specified by the server.
var $m_channelfields; // Channel field names.
var $m_channellist; // Array of CVentriloChannel's.
var $m_clientcount; // Number of clients as specified by the server.
var $m_clientfields; // Client field names.
var $m_clientlist; // Array of CVentriloClient's.
function Parse( $str )
{
// Remove trailing newline.
$pos = strpos( $str, "\n" );
if ( $pos === false )
{
}
else
{
$str = substr( $str, 0, $pos );
}
// Begin parsing for keywords.
if ( StrKey( $str, "ERROR:", $val ) )
{
$this->m_error = $val;
return -1;
}
if ( StrKey( $str, "NAME:", $val ) )
{
$this->m_name = StrDecode( $val );
return 0;
}
if ( StrKey( $str, "PHONETIC:", $val ) )
{
$this->m_phonetic = StrDecode( $val );
return 0;
}
if ( StrKey( $str, "COMMENT:", $val ) )
{
$this->m_comment = StrDecode( $val );
return 0;
}
if ( StrKey( $str, "AUTH:", $this->m_auth ) )
return 0;
if ( StrKey( $str, "MAXCLIENTS:", $this->m_maxclients ) )
return 0;
if ( StrKey( $str, "VOICECODEC:", $val ) )
{
StrSplit( $val, ",", $this->m_voicecodec_code, $desc );
$this->m_voicecodec_desc = StrDecode( $desc );
return 0;
}
if ( StrKey( $str, "VOICEFORMAT:", $val ) )
{
StrSplit( $val, ",", $this->m_voiceformat_code, $desc );
$this->m_voiceformat_desc = StrDecode( $desc );
return 0;
}
if ( StrKey( $str, "UPTIME:", $val ) )
{
$this->m_uptime = $val;
return 0;
}
if ( StrKey( $str, "PLATFORM:", $val ) )
{
$this->m_platform = StrDecode( $val );
return 0;
}
if ( StrKey( $str, "VERSION:", $val ) )
{
$this->m_version = StrDecode( $val );
return 0;
}
if ( StrKey( $str, "CHANNELCOUNT:", $this->m_channelcount ) )
return 0;
if ( StrKey( $str, "CHANNELFIELDS:", $this->m_channelfields ) )
return 0;
if ( StrKey( $str, "CHANNEL:", $val ) )
{
$chan = new CVentriloChannel;
$chan->Parse( $val );
$this->m_channellist[ count( $this->m_channellist ) ] = $chan;
return 0;
}
if ( StrKey( $str, "CLIENTCOUNT:", $this->m_clientcount ) )
return 0;
if ( StrKey( $str, "CLIENTFIELDS:", $this->m_clientfields ) )
return 0;
if ( StrKey( $str, "CLIENT:", $val ) )
{
$client = new CVentriloClient;
$client->Parse( $val );
$this->m_clientlist[ count( $this->m_clientlist ) ] = $client;
return 0;
}
// Unknown key word. Could be a new keyword from a newer server.
return 1;
}
function ChannelFind( $cid )
{
for ( $i = 0; $i < count( $this->m_channellist ); $i++ )
if ( $this->m_channellist[ $i ]->m_cid == $cid )
return( $this->m_channellist[ $i ] );
return NULL;
}
function ChannelPathName( $idx )
{
$chan = $this->m_channellist[ $idx ];
$pathname = $chan->m_name;
for(;;)
{
$chan = $this->ChannelFind( $chan->m_pid );
if ( $chan == NULL )
break;
$pathname = $chan->m_name . "/" . $pathname;
}
return( $pathname );
}
function Request()
{
$cmdline = $this->m_cmdprog;
$cmdline .= " -c" . $this->m_cmdcode;
$cmdline .= " -t" . $this->m_cmdhost;
if ( strlen( $this->m_cmdport ) )
{
$cmdline .= ":" . $this->m_cmdport;
// For password to work you MUST provide a port number.
if ( strlen( $this->m_cmdpass ) )
$cmdline .= ":" . $this->m_cmdpass;
}
// Just in case.
$cmdline = escapeshellcmd( $cmdline );
// Execute the external command.
$pipe = popen( $cmdline, "r" );
if ( $pipe === false )
{
$this->m_error = "PHP Unable to spawn shell.";
return -10;
}
// Process the results coming back from the shell.
$cnt = 0;
while( !feof( $pipe ) )
{
$s = fgets( $pipe, 1024 );
if ( strlen( $s ) == 0 )
continue;
$rc = $this->Parse( $s );
if ( $rc < 0 )
{
pclose( $pipe );
return( $rc );
}
$cnt += 1;
}
pclose( $pipe );
if ( $cnt == 0 )
{
// This is possible since the shell might not be able to find
// the specified process but the shell did spawn. More likely to
// occur then the -10 above.
$this->m_error = "PHP Unable to start external status process.";
return -11;
}
return 0;
}
};
?>
ventrilodisplay_ex2.php
<?php
function VentriloDisplayEX2_Stripe( $perc, $val, $bgidx )
{
$fgcol = "#000000";
if ( $bgidx < 0 )
{
$fgcol = "#FFFFFF";
$bgcol = "#000000";
}
else
{
if ( $bgidx % 2 )
$bgcol = "#FFFFCC";
else
$bgcol = "#FFFFFF";
}
echo " <td width=\"$perc\" bgcolor=\"$bgcol\"><font color=\"$fgcol\">$val</font></td>\n";
}
function VentriloDisplayEX2( &$stat, $name, $cid, $bgidx )
{
// Display the table headers.
echo " <tr>\n";
VentriloDisplayEX2_Stripe( "5%", "Flags", -1 );
VentriloDisplayEX2_Stripe( "5%", "UID", -1 );
VentriloDisplayEX2_Stripe( "5%", "CID", -1 );
VentriloDisplayEX2_Stripe( "10%", "Sec", -1 );
VentriloDisplayEX2_Stripe( "10%", "Ping", -1 );
VentriloDisplayEX2_Stripe( "20%", "Name", -1 );
VentriloDisplayEX2_Stripe( "45%", "Comment", -1 );
echo " </tr>\n";
// Display all clients.
for ( $i = 0; $i < count( $stat->m_clientlist ); $i++ )
{
echo " <tr>\n";
$client = $stat->m_clientlist[ $i ];
$flags = "";
if ( $client->m_admin )
$flags .= "A";
if ( $client->m_phan )
$flags .= "P";
VentriloDisplayEX2_Stripe( "5%", $flags, $bgidx );
VentriloDisplayEX2_Stripe( "5%", $client->m_uid, $bgidx );
VentriloDisplayEX2_Stripe( "5%", $client->m_cid, $bgidx );
VentriloDisplayEX2_Stripe( "10%", $client->m_sec, $bgidx );
VentriloDisplayEX2_Stripe( "10%", $client->m_ping, $bgidx );
VentriloDisplayEX2_Stripe( "20%", $client->m_name, $bgidx );
VentriloDisplayEX2_Stripe( "45%", $client->m_comm, $bgidx );
echo " </tr>\n";
$bgidx += 1;
}
}
?>
ventrilotest.php
<html>
<head>
<title>Ventrilo Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<p>
<br>
<?php
include "ventrilostatus.php";
include "ventriloinfo_ex1.php";
include "ventrilodisplay_ex1.php";
include "ventrilodisplay_ex2.php";
/*
This example PHP script came with a file called ventriloreadme.txt and should
be read if you are having problems making these scripts function properly.
In it's current state this script is not usable. You MUST read the
ventriloreadme.txt file if you do not know what needs to be changed.
The location of the 'ventrilo_status' program must be accessible from
PHP and what ever HTTP server you are using. This can be effected by
PHP safemode and other factors. The placement, access rights and ownership
of the file it self is your responsibility. Change to fit your needs.
*/
$stat = new CVentriloStatus;
$stat->m_cmdprog = "c:/var/www/html/ventrilo_status"; // Adjust accordingly.
$stat->m_cmdcode = "2"; // Detail mode.
$stat->m_cmdhost = "127.0.0.1"; // Assume ventrilo server on same machine.
$stat->m_cmdport = "3784"; // Port to be statused.
$stat->m_cmdpass = ""; // Status password if necessary.
$rc = $stat->Request();
if ( $rc )
{
echo "CVentriloStatus->Request() failed. <strong>$stat->m_error</strong><br><br>\n";
}
// Create a web link for this server. Please note that the status password
// is not the same thing as a servers global logon password. This is why the
// example doesn't add one.
echo "Building a ventrilo:// web link from the supplied information. \n";
echo "Please note that if the retrieved server name has spaces in it then anything following them \n";
echo "will not show up in the client. This is a client side issue. You might use _'s in server names ";
echo "instead until the problem is fixed.<br><br>\n";
$weblink = "ventrilo://$stat->m_cmdhost:$stat->m_cmdport/servername=$stat->m_name";
echo "<center><a href=\"$weblink\">Click here to connect to the following server.</a></center><br><br>\n";
// Server basic info.
echo "Basic information about the server using VentriloInfoEX1.<br><br>\n";
echo "<center><table width=\"50%\" border=\"0\">\n";
VentriloInfoEX1( $stat );
echo "</table></center>\n";
// Server channels/users info.
echo "<br>Channel and user info using VentriloDisplayEX2.<br><br>\n";
echo "<br>\n";
echo "<center><table width=\"95%\" border=\"0\">\n";
$name = "";
VentriloDisplayEX2( $stat, $name, 0, 0 );
echo "</table></center>\n";
echo "<br>Channel and user info using VentriloDisplayEX1.<br><br>\n";
/* Use this if you prefer the first channel name to look more
like a ventrilo client display where the first entry is the
server name followed by it's comment.
$name = $stat->m_name;
if ( strlen( $stat->m_comment ) )
$name .= " ($stat->m_comment)";
*/
$name = "Lobby";
echo "<br>\n";
echo "<center><table width=\"95%\" border=\"0\">\n";
VentriloDisplayEX1( $stat, $name, 0, 0 );
echo "</table></center>\n";
?>
</p>
</body>
</html>
und zu guter letzt noch die readme:
This README file details how to configure the
ventrilotest.php script in order to issue status requests to
a Ventrilo server and process the response. The document and
examples are written assuming that a Windows based WEB/PHP
server will be used. If you plan on running these scripts on
a Linux/Unix based platform then you will need to make the
appropriate changes.
This document will not teach you how to administrate a
WEB/PHP server. It is your responsibility to learn these
things on your own or have someone else teach it to you.
Before you can even use the ventrilotest.php file you will
need to tweak the $stat->m_cmdprog path first. Please read
the entire document before doing so.
With the exception of the ventrilostatus.php script, all of
the other php files are for example purposes. Feel free to
customize them or create new ones based on these examples.
Please be advised that the ventrilo_status program must be
on the same machine where you plan on running these PHP
scripts, or accessible from the same machine.
These scripts were tested on PHP Version 4.2.2 and 4.3.3 but
should work with any version 4 system as far as we know.
Be advised that if your web/php server is running Linux then
you must install the Linux version of the ventrilo_status
program. Likewise, if your web server is running Windows
then you must install the Windows version of the
ventrilo_status.exe program. The same goes for all of the
other supported server platforms. Installing the windows
ventrilo_status.exe program on a Linux machine will not work
no matter how hard you try.
Before you can issue status requests to a Ventrilo server
you must first configure the Ventrilo server to receive and
process UDP messages. This can be done in the servers INI
file under that [Status] section. All servers version 2.1.2
or higher come with examples showing all of the options.
However, the UDP support is disabled by default so that they
are compliant with older versions. You must read the
"ventrilo_srv.htm" file that comes with each of the servers
in order to understand what and how to configure the
[Status] section of the server. We will give examples here
but we will not be addressing the advanced options to
prevent server abuse. This is your responsibility and you
can only learn how to do it by reading the ventrilo_srv.htm
file and having a working knowledge about network interface
cards, IP addresses and network administration. If you do
not have these skills then you should let someone more
qualified configure the server for you.
In the ventrilo_srv.ini file and under the [Status] section
you should:
Uncomment the example Intf=0.0.0.0 by removing the # sign in
front of it. This will enable processing of all UDP messages
from all network cards in the system.
Comment out all of the FilterGen and FilterDetail lines.
This can be done by placing a # sign in front of them.
After changing the INI file you will need to restart the
Ventrilo server.
You can manually start the ventrilo_status program from a
command prompt and give it the details for requesting the
status of a server. Instructions on how to do this can be
found in the ventrilo_srv.htm file.
Now, open the ventrilotest.php file with an editor.
There are several key lines that must be filled in properly
in order to issue requests to the Ventrilo server via the
ventrilostatus.php script. Each example will be followed by