[PHP] Clientless Silkroad Security + ServerStats

10/04/2011 05:10 EuSouHunteR#61
[Only registered and activated users can see links. Click Here To Register...]

check now :(
10/04/2011 05:25 pushedx#62
Quote:
Originally Posted by EuSouHunteR View Post
[Only registered and activated users can see links. Click Here To Register...]

check now :(
You set the wrong locale. Right now you set it to ISRO's (18), which is why you see Ratio and Country. Change it to the correct locale (22) and it should display correctly.
10/04/2011 17:10 EuSouHunteR#63
if i create another php page.

another.php

<?php
include("serverstats.php");
include ("index.php");


<? echo $name; ?>
<? echo $cur; ?>
<? echo $max; ?>

?>

i get only name/current/max ?
i need make custom design.
10/09/2011 19:46 EuSouHunteR#64
i need change STATUS 1 for STATUS = Online and Offline.
where to make?
10/09/2011 23:12 merasdw#65
plz man add a new link for server fiels
10/10/2011 13:19 * White *#66
Code:
Array ( [0] =>  [1] => Warning: fsockopen() has been disabled for security reasons in /users/srstats/www/ServerStats.php on line 59 [2] => Error [3] => A connection could not be established: [: ] )
How fix that ?

Tried with 7 servers-hosts but same..


[Only registered and activated users can see links. Click Here To Register...]
10/13/2011 18:48 theevil17#67
Array ( [0] => Error [1] => A connection could not be established. )



I fix that?
10/13/2011 19:07 TheSpy#68
Quote:
Originally Posted by theevil17 View Post
Array ( [0] => Error [1] => A connection could not be established. )



I fix that?
HOW I FIX THAT PLÝZZ??


Making your text won't make anyone answer it faster. We can read text like THIS just normally. The error is probably a wrong configured server/config file.
10/13/2011 19:10 theevil17#69
Quote:
Originally Posted by TheSpy View Post
HOW I FIX THAT PLÝZZ??


Making your text won't make anyone answer it faster. We can read text like THIS just normally. The error is probably a wrong configured server/config file.
Array ( [0] => Error [1] => The version packet was rejected because a manual patch is needed. [2] =>
[3] => )


now I get it
11/14/2011 01:27 DJBeatstar#70
Hi Im running a VSRO Server. what sould i write in these lines?

Code:
	$_REQUEST["locale"] = 49;
	$_REQUEST["version"] = 130;
were can i find it out? i use these serverfiles:
[Only registered and activated users can see links. Click Here To Register...]

Thanks alot for any help...
05/07/2012 17:54 Getzabelz#71
Quote:
Originally Posted by DJBeatstar View Post
Hi Im running a VSRO Server. what sould i write in these lines?

Code:
	$_REQUEST["locale"] = 49;
	$_REQUEST["version"] = 130;
were can i find it out? i use these serverfiles:
[Only registered and activated users can see links. Click Here To Register...]

Thanks alot for any help...
VSRO Locale is 22, and version is the client of the version. If It's default it will be 088.

It should look like this when finished:

[Only registered and activated users can see links. Click Here To Register...]
05/09/2012 14:56 cyberninjah#72
for ppl that want it here is a class to help you use drews code easier.

i made a little cache function in it.

The code is not perfect i just created it to test the code drew made :)

class.silkroadAPI.php
PHP Code:
<?php
class silkroadAPI
{
    private 
$host;
    private 
$port;
    private 
$locale;
    private 
$version;
    private 
$timeout;       
    
    private 
$s//SilkroadSecurity
    
    
private $socket;
    private 
$response;
    
    private 
$connected;
    
    private 
$big_packet;
    private 
$big_opcode;
    private 
$big_count;
    private 
$big_data;
    
    
    public 
$serverList;
    
    function 
__construct($host$port$locale$version$timeout)
    {
        
$this->host $host;
        
$this->port $port;
        
$this->locale $locale;
        
$this->version $version;
        
$this->timeout $timeout;
        
        
$this->= new SilkroadSecurity();
    }    
    
    function 
Send$socket$buffer )
    {
            if( !
socket_send_buffer$socket$bufferstrlen$buffer ) ) )
            {
                    @
socket_close$socket );
                    echo( 
"Error" PHP_EOL "<br />" PHP_EOL "Could not send data." );
                    return 
false;
            }
            return 
true;
    }    
    
    
    
/*
     * Connect to the Joymax server
     */
    
function connect()
    {
    
$this->socket = @socket_createAF_INETSOCK_STREAM);
    if( 
$this->socket === false )
    {
                throw new 
Exception('Could not create the socket');
        return;
    }        
        
    @
socket_set_nonblock$this->socket );
    @
socket_connect$this->socket$this->host$this->port );
    @
socket_set_block$this->socket );        
        
    
$r = array( $this->socket );
    
$w = array( $this->socket );
    
$e = array( $this->socket );

    if( 
false === @socket_select$r$w$e$this->timeout ) )
    {
        @
socket_close$this->socket );
        throw new 
Exception"A connection could not be established." );
        return;
    }
    if( 
count$w ) != || count$e ) == )
    {
        @
socket_close$this->socket );
        throw new 
Exception"A connection could not be established." );
        return;
    }        
        
        
$this->connected true;
        
    
$this->big_packet false;
    
$this->big_opcode 0;
    
$big_count 0;
    
$big_data "";

    while( 
$this->connected )
    {
        
$r = array( $this->socket );
        
$w NULL;
        
$e NULL;

        if( 
false === @socket_select$r$w$e$this->timeout ) )
        {
            @
socket_close$this->socket );
            echo( 
"Error" PHP_EOL "<br />" PHP_EOL "There was an error with the connection." );
            return;
        }

        if( 
count$r ) != )
        {
            @
socket_close$this->socket );
            throw new 
Exception"No more data was received on the socket." );
            return;
        }

        
$this->response socket_recv_buffer$this->socket);
        if( 
$this->response == false )
        {
            @
socket_close$this->socket );
            throw new 
Exception"Could not receive data." );
            return;
        }      
                
        
$header "";

        
$array unpack"vsize"$this->response );
        
$this->response "";

        
$size = (int)$array["size"];
        if( 
bcand$size0x8000 ) > )
        {
            
$expected_size 0;
            
            
$input_size bcadd4bcand$size0x7FFF ) );
            
$lVal bcmod$input_size);
            if( 
$lVal != )
            {
                
$expected_size bcsubbcadd$input_size), $lVal );
            }
            else
            {
                
$expected_size $input_size;
            }

            
$enc_payload socket_recv_buffer$this->socket$expected_size );

            
$enc_payload_tmp "";
            while( 
strlen$enc_payload ) > )
            {
                
$val unpack"N"$enc_payload );
                
$enc_payload substr$enc_payload);
                
$enc_payload_tmp .= bcbytearrayhexdecdechex$val[1] ) ), );
            }

            
$dec_payload mcrypt_ecbMCRYPT_BLOWFISHbcbytearray$this->s->m_handshake_blowfish_key), $enc_payload_tmpMCRYPT_DECRYPT );

            
$dec_payload_arr = array();
            while( 
strlen$dec_payload ) > )
            {
                
$val unpack"N"$dec_payload );
                
$dec_payload substr$dec_payload);
                
$val hexdecdechex$val[1] ) );

                
$m bcbytearray$val );
                
$m unpack"C*"$m );
                for( 
$x 1$x <= 4; ++$x )
                {
                    
array_push$dec_payload_arr$m[$x] );
                }
            }

            
$payload "";

            
$dec_payload_arr array_splice$dec_payload_arr0$input_size );
            for( 
$x 0$x count$dec_payload_arr ); ++$x )
            {
                
$payload .= pack"C"bchexdecbcdechex$dec_payload_arr[$x] ) ) );
            }

            
$header unpack"vopcode/vsecurity"$payload );
            
$header["size"] = bcsub$input_size);
            
$header["encrypted"] = true;

            if( 
$header["size"] > )
            {
                
$payload substr$payload);
                
$header["payload"] = hexdump$payload );
            }
            else
            {
                
$payload "";
            }
        }
        else
        {
            
$header socket_recv_buffer$this->socket);
            
$header unpack"vopcode/vsecurity"$header );
            
$header["size"] = $size;
            
$header["encrypted"] = false;

            if( 
$size )
            {
                
$payload socket_recv_buffer$this->socket$size );
                
$header["payload"] = hexdump$payload );
            }
        }   
                
                
$this->parsePackets($header,$payload);
                
        }
        
    }
    
    function 
parsePackets($header,$payload)
    {
        switch(
$header["opcode"])
        {
            case 
0x5000:
                
$this->packetHandShake($header,$payload);
                break;
            case 
0x600D:
                
$this->packet0x600D($header$payload);
                break;
            case 
0x2001:
                
$new_payload pack"Cva9V"$this->locale9"SR_Client"$this->version );
                
$packet_payload $this->s->format_packet0x6100$new_payloadtrue );

                
$this->Send$this->socket$packet_payload );                        
                break;
            case 
0xA107:
            
$count unpack_uint8$payload );
            for( 
$x 0$x $count; ++$x )
            {
                
$id unpack_uint8$payload );
                
$len unpack_uint16$payload );
                
$ip unpack_ASCII$payload$len );
                
$port unpack_uint16$payload );
                
//echo( "id: $id ip: $ip port: $port<br />" );
            
}                
                break;
            case 
0xA101:
                
$this->packetServerList($header$payload);
                
$this->connected false;
                break;
                
        }
    }
    
    function 
packetServerList($header$payload)
    {
        
$header true;

        
$new_server unpack_uint8$payload );
        while( 
$new_server == )
        {
                
$id unpack_uint8$payload );
                
$len unpack_uint16$payload );
                
$name unpack_ASCII$payload$len );
                
$new_server unpack_uint8$payload );
        }

        
$new_server unpack_uint8$payload );
        while( 
$new_server == )
        {
                
$id unpack_uint16$payload );
                
$len unpack_uint16$payload );

                if( 
$this->locale == 18 )
                {
                        
$c chrunpack_int8$payload ) );
                        if( 
$c == '1' )
                        {
                                
$c "USA";
                        }
                        else if( 
$c == '0' )
                        {
                                
$c "Korea";
                        }

                        
$len--;
                        
$name unpack_ASCII$payload$len );

                        
$ratio unpack_float$payload );                                        
                }
                else
                {
                        
$name unpack_ASCII$payload$len );
                        
$cur unpack_uint16$payload );
                        
$max unpack_uint16$payload );
                }

                
$state unpack_uint8$payload );

                if( 
$this->locale == || $this->locale == 23 // csro/vsro extra bytes
                
{
                        
$extra1 unpack_uint8$payload );
                        
$extra2 "";

                        if( 
$extra1 == )
                        {
                                
$extra2 unpack_uint8$payload );
                        }
                }

                if( 
$this->locale == 40 // russian
                
{
                        
$name mb_convert_encoding$name"utf-8""Windows-1251" );
                }
                else if( 
$this->locale == // korean
                
{
                        
$name mb_convert_encoding$name"utf-8""EUC-KR" );
                }
                else if( 
$this->locale == // chinese
                
{
                        
$name mb_convert_encoding$name"utf-8""EUC-CN" );
                }
                else if( 
$this->locale == 12 // taiwanese
                
{
                        
$name mb_convert_encoding$name"utf-8""BIG-5" );
                }
                else if( 
$this->locale == 15 // japanese
                
{
                        
$name mb_convert_encoding$name"utf-8""EUC-JP" ); // not tested, might need to use something else
                
}
                else 
// everything else that uses default windows codepage
                
{
                        
$name mb_convert_encoding$name"utf-8""Windows-1252" );
                }

                if( 
$this->locale == 18 )
                {
                        if( 
$header )
                        {
                                
//print( "Id|Country|Name|Ratio|State" . PHP_EOL . "<br />" . PHP_EOL );
                        
}

                        
                        
$serverinfo['ID'] = $id;
                        
$serverinfo['country'] = $c;
                        
$serverinfo['name'] = $name;
                        
$serverinfo['currentusers'] = round($ratio 3500);
                        
$serverinfo['maxusers'] = 3500;
                        
$serverinfo['ratio'] = $ratio;                        
                        
$serverinfo['state'] = $state;                        

                        
$this->serverList[] = $serverinfo;
                }
                else if( 
$this->locale == || $this->locale == 23 )
                {
                        if( 
$header )
                        {
                                print( 
"Id|Name|Cur|Max|State|Extra1|Extra2" PHP_EOL "<br />" PHP_EOL );
                        }
                        print( 
"$id|$name|$cur|$max|$state|$extra1|$extra2PHP_EOL "<br />" PHP_EOL );
                }
                else
                {
                        if( 
$header )
                        {
                                print( 
"Id|Name|Cur|Max|State" PHP_EOL "<br />" PHP_EOL );
                        }
                        print( 
"$id|$name|$cur|$max|$statePHP_EOL "<br />" PHP_EOL );
                }

                
$new_server unpack_uint8$payload );

                
$header false;
        }        
    }
    
    
    function 
packetHandShake($header$payload)
    {
        
$data unpack"Cflag"$payload );
        if( 
$data["flag"] == 0x0E )
        {
                
$data unpack"Cflag/Vblowfishlow/Vblowfishhigh/Vseedcount/Vseedcrc/Vhandshakelow/Vhandshakehigh/Vg/Vp/VA"$payload );
                
$packet_payload $this->s->Handshake_E$data );

                if( !
$this->Send$this->socket$packet_payload ) )
                        return;
        }
        else if( 
$data["flag"] == 0x10 )
        {
                
$data unpack"Cflag/Vhandshakelow/Vhandshakehigh"$payload );
                
$packet_payload $this->s->Handshake_10$data );

                if( !
$this->Send$this->socket$packet_payload ) )
                        return;

                
$new_payload pack"va9C"9"SR_Client");
                
$packet_payload $this->s->format_packet0x2001$new_payloadtrue );

                if( !
$this->Send$this->socket$packet_payload ) )
                        return;
        }
        else
        {
                @
socket_close$this->socket );
                echo( 
"Unknown flag: " dechex$data["flag"] ) );
                return;
        }        
    }
    
    function 
packet0x600D($header$payload)
    {
        
$type unpack_uint8$payload );
        if( 
$type == // header
        
{
                if( 
$this->big_packet == true )
                {
                        @
socket_close$this->socket );
                        echo( 
"Error" PHP_EOL "<br />" PHP_EOL "Received an invalid 0x600d packet. Duplicate header." );
                        return;
                }

                
$this->big_count unpack_uint16$payload );
                
$this->big_opcode unpack_uint16$payload );

                
$this->big_packet true;
                

        }
        else if( 
$type == // data
        
{
                if( !
$this->big_packet )
                {
                        @
socket_close$this->socket );
                        echo( 
"Error" PHP_EOL "<br />" PHP_EOL "Received an invalid 0x600d packet. Out of order data." );
                        return;
                }

                
$this->big_data .= $payload// Append the data
                
$payload "";

                --
$this->big_count// One less packet chunk to process
                
if( $this->big_count == // The massive packet is complete now
                
{
                        
$this->big_packet false;
                        if( 
$this->big_opcode == 0xA100 // 0x6100 response
                        
{
                                
$res unpack_uint8$this->big_data );

                                if( 
$res == // Success, now request server list
                                
{
                                        if( 
$this->locale == 18 // ISRO has this
                                        
{
                                                
$new_payload "";
                                                
$packet_payload $this->s->format_packet0x6107$new_payloadtrue );

                                                if( !
$this->Send$this->socket$packet_payload ) )
                                                        return;
                                        }

                                        
$new_payload "";
                                        
$packet_payload $this->s->format_packet0x6101$new_payloadtrue );

                                        if( !
$this->Send$this->socket$packet_payload ) )
                                                return;
                                }
                                else 
// Error, can be version, GatewayServer being down, etc...
                                
{
                                        print( 
"Error" PHP_EOL "<br />" PHP_EOL );

                                        
$res unpack_uint8$this->big_data );

                                        if( 
$res == )
                                        {
                                                print( 
"The version packet was rejected because the GatewayServer is closed." PHP_EOL "<br />" PHP_EOL );
                                        }
                                        else if( 
$res == )
                                        {
                                                print( 
"The version packet was rejected because it is outdated." PHP_EOL "<br />" PHP_EOL );

                                                
$len unpack_uint16$this->big_data );
                                                
$ip unpack_ASCII$this->big_data$len );
                                                
$port unpack_uint16$this->big_data );                                
                                                
$new_version unpack_uint32$this->big_data );

                                                print( 
"$ip|$port|$new_versionPHP_EOL "<br />" PHP_EOL );

                                                
$new_file unpack_uint8$this->big_data );
                                                while( 
$new_file == )
                                                {
                                                        
$id unpack_uint32$this->big_data );
                                                        
$len unpack_uint16$this->big_data );
                                                        
$name unpack_ASCII$this->big_data$len );
                                                        
$len unpack_uint16$this->big_data );
                                                        
$path unpack_ASCII$this->big_data$len );
                                                        
$size unpack_uint32$this->big_data );
                                                        
$in_pk2 unpack_uint8$this->big_data );
                                                        
$new_file unpack_uint8$this->big_data );

                                                        print( 
"$id|$name|$path|$size|$in_pk2PHP_EOL "<br />" PHP_EOL );
                                                }

                                                break;
                                        }
                                        else if( 
$res == )
                                        {
                                                print( 
"The version packet was rejected because the version is too new." PHP_EOL "<br />" PHP_EOL );
                                        }
                                        else if( 
$res == )
                                        {
                                                print( 
"The version packet was rejected because the version is too old." PHP_EOL "<br />" PHP_EOL );
                                        }
                                        else if( 
$res == )
                                        {
                                                print( 
"The version packet was rejected because a manual patch is needed." PHP_EOL "<br />" PHP_EOL );
                                        }
                                        else
                                        {
                                                print( 
"The version packet was rejected (Code: $res)." PHP_EOL "<br />" PHP_EOL );
                                        }

                                        print( 
hexdump$this->big_data ) );
                                        print( 
PHP_EOL "<br />" );

                                        @
socket_close$this->socket );
                                        return;
                                }
                        }
                        else if( 
$this->big_opcode == 0x2005 // server info, ignore
                        
{
                        }
                        else if( 
$this->big_opcode == 0x6005 // server info, ignore
                        
{
                        }
                        else
                        {
                                @
socket_close$this->socket );
                                echo( 
"Error" PHP_EOL "<br />" PHP_EOL "Unknown packet contained in 0x600d: 0x" dechex$this->big_opcode ) );
                                return;
                        }

                        
$this->big_opcode 0;
                        
$this->big_data "";
                }
        }
        else
        {
                @
socket_close$this->socket );
                echo( 
"Error" PHP_EOL "<br />" PHP_EOL "Unknown type(" $type ") in 0x600d." );
                return;
        }        
    }
}
?>
Little example:
view.php
PHP Code:
<?php
$cachefile 
"cache/serverlist_json.cache";

if(
file_exists($cachefile) && (filemtime($cachefile) + (60) ) > time()  )
{
    
$fh fopen("cache/serverlist_json.cache"'r');
    
$theData fread($fhfilesize("cache/serverlist_json.cache"));
    
fclose($fh);
    
    echo 
$theData;    
}else{
    require( 
"SilkroadSecurity.php" );
    require( 
"SocketUtility.php" );
    require( 
"HexDump.php" );
    require( 
"class.silkroadAPI.php" );

    
$api = new silkroadAPI("gwgt1.joymax.com",15779,18,364,5);

    
$api->connect();    
    
    
$fh fopen($cachefile'w') or die("can't open file");
    
fwrite($fhjson_encode($api->serverList));
    
fclose($fh);    
        
    echo 
json_encode($api->serverList);
}

?>
03/26/2020 16:29 ^Nitro^#73
Quote:
Originally Posted by pushedx View Post
Short and sweet: this project allows you to have native server stats via PHP without having to use an external program to collect the server stats.

In other words, everyone should be able to host their own server stats on their site as long as they have a capable web server. I've tested locally and on a remote host, so it should be fine with most modern hosts. Unfortunately, as tricky as this code was to write, there is nothing that can be done if your server does not support all the components.

This is a bare minimal release, so you will need some web designing skills to make it look "pretty" or additional php/database skills to enhance it more.

readme.txt


Just a helpful hint: if you wonder how to "loop" updates, take a look into CRON jobs (your web host must support them!). If not, you will have to come up with another solution (such as using a program that always runs to force the refresh).

Also, using these concepts, you can use this code for other games and projects in a similar fashion! PHP is quite capable afterall.

Enjoy! :)

Troubleshooting:

Make a test page with the following code:
Code:
<?php
	phpinfo();
?>
Upload the page, run the script, and save the results. Delete the page afterwards.

Q. Why do I see an empty page when I try to use the server stats?
A. This usually means a needed php component is not there. Check for the following strings in "Configure Command": '--enable-sockets', '--with-mcrypt=', and '--enable-bcmath'.

Look for each section in the configuration. It should look something like the following.
BCMath: [Only registered and activated users can see links. Click Here To Register...]
mcrypt: [Only registered and activated users can see links. Click Here To Register...]
sockets: [Only registered and activated users can see links. Click Here To Register...]

Q. Can more/less debugging information be provided for PHP errors?
A. In short, no. It all depends on how PHP is configured and most hosts are really restrictive to changes made to PHP. Unless you are running your own server where you can reconfigure PHP!

Q. What do the different errors mean?
A. Most errors should be self descriptive. Try to search the text in the php files to see what they are associated with.

Q. I get a bunch of MCRYPT warnings when trying to run the stats?
A. Please see [Only registered and activated users can see links. Click Here To Register...].

More Q/A will be added as they arise.
Very nice good job
but the MCRYPT has a discontinued feature in the newest PHP Versions
03/26/2020 23:39 Devsome#74
Quote:
Originally Posted by ^Nitro^ View Post
Very nice good job
but the MCRYPT has a discontinued feature in the newest PHP Versions
Try this: [Only registered and activated users can see links. Click Here To Register...]