Jump to content

String, but not a string?? :confused:


Kush

Recommended Posts

I'm trying to do some regex, but I'm having trouble with my input string for the regex. I'm querying a server and getting results from that via socket and trying to regex the results and extract content. I've got the regex working (thanks to mjdamato ;) ), but it only works when I have the regex string like this:

 

$input = "hostname: Hooter's GG 5.1 Elimination HLstatsX:CE version : 1.0.0.58/15 4426 secure udp/ip : 25.2.132.39:27015 map : fy_dustdm at: 0 x, 0 y, 0 z players : 0 (20 max) # userid name uniqueid connected ping loss state adr ";

 

When I get the results from my socket it's stored in a variable and it doesn't work when it's exactly the same. I did var_dump on the results from the socket and this is what it outputs:

string(229) "hostname: Hooter's GG 5.1 Elimination HLstatsX:CE version : 1.0.0.58/15 4426 secure udp/ip : 25.2.132.39:27015 map : fy_dustdm at: 0 x, 0 y, 0 z players : 0 (20 max) # userid name uniqueid connected ping loss state adr " 

 

Since it's exactly the same why doesn't the second way work? Let me know if this is too confusing..

Link to comment
https://forums.phpfreaks.com/topic/228059-string-but-not-a-string-confused/
Share on other sites

Can you please post your code.

 

$r = new rcon("25.2.132.39", 27015, "serverpasswordherebutiremovedit");

if(!$r->isValid())
    die("Unable to connect to server.");

if(!$r->Auth())
    die("Unable to authenticate! Wrong password?");

$command = "hostname: Hooter's GG 5.1 Elimination HLstatsX:CE version : 1.0.0.58/15 4426 secure udp/ip : 25.2.132.39:27015 map : fy_dustdm at: 0 x, 0 y, 0 z players : 0 (20 max) # userid name uniqueid connected ping loss state adr ";

$status = $r->sendRconCommand("status");

var_dump($status);

$serverInformation = getServerInformation($status);

 

Here's the rcon class:

<?php
/*
CS:S Rcon PHP Class - code by 1FO|zyzko 01/12/2005
www.1formatik.com - www.1fogames.com
    --------------------------------------------------
*/
define("SERVERDATA_EXECCOMMAND", 02);
define("SERVERDATA_AUTH", 03);

class rcon {
    var $Password;
    var $Host;
    var $Port = 27015;
    var $_Sock = null;
    var $_Id = 0;
    var $valid = false;

    function __construct($Host,$Port,$Password) {
  	  return $this->init($Host,$Port,$Password);
    }

    function rcon ($Host,$Port,$Password) {
    	return $this->init($Host,$Port,$Password);
    }

    function init($Host,$Port,$Password) {
        $this->Password = $Password;
    	$this->Host = $Host;
    	$this->Port = $Port;
    	$this->_Sock = @fsockopen($this->Host,$this->Port, $errno, $errstr, 30);// or
    	    //die("Unable to open the port: $errstr ($errno)\n"+$this->Host+":"+$this->Port);
        if($this->_Sock) {
            $this->_Set_Timeout($this->_Sock,2,500);
            $this->valid = true;
        }
    }

    function isValid() {
        return $this->valid;
    }

    function Auth() {
    	$PackID = $this->_Write(SERVERDATA_AUTH, $this->Password);

    	$ret = $this->_PacketRead();
    	if ($ret[1]['ID'] == -1) {
            return 0;
    	} else {
            return 1;
      }
    }

    function _Set_Timeout(&$res,$s,$m=0) {
    	if (version_compare(phpversion(),'4.3.0','<')) {
            return socket_set_timeout($res,$s,$m);
    	}
    	return stream_set_timeout($res,$s,$m);
    }

    function _Write($cmd, $s1='', $s2='') {
    	$id = ++$this->_Id;
    	$data = pack("VV",$id,$cmd).$s1.chr(0).$s2.chr(0);
    	$data = pack("V",strlen($data)).$data;
    	fwrite($this->_Sock,$data,strlen($data));
    	return $id;
    }

    function _PacketRead() {
    	$retarray = array();
    	while ($size = @fread($this->_Sock,4)) {
  	    $size = unpack('V1Size',$size);
  	    if ($size["Size"] > 4096) {
    		  $packet = "\x00\x00\x00\x00\x00\x00\x00\x00".fread($this->_Sock,4096);
    	  } else {
    		  $packet = fread($this->_Sock,$size["Size"]);
    	  }
    	    array_push($retarray,unpack("V1ID/V1Reponse/a*S1/a*S2",$packet));
    	}
    	return $retarray;
    }

    function Read() {
    	$Packets = $this->_PacketRead();
    	foreach($Packets as $pack) {
    	  if (isset($ret[$pack['ID']])) {
            $ret[$pack['ID']]['S1'] .= $pack['S1'];
            $ret[$pack['ID']]['S2'] .= $pack['S1'];
    	  } else {
            $ret[$pack['ID']] = array(
                'Reponse' => $pack['Reponse'],
                'S1' => $pack['S1'],
                'S2' =>	$pack['S2'],
            );
      	  }
    	}
    	return $ret;
    }
    
    /**
     * Send an rcon command the server.  The command must be properly formatted before
     * sending to this method.  This means that variables that require quotes must have
     * quotes put around them.
     * Ex. $command = "kickid ". "\"".$steamId."\" ".$banReason
     */
    function sendRconCommand($command) {
      $this->_Write(SERVERDATA_EXECCOMMAND, $command, '');
      $ret = $this->Read();
      return $ret[$this->_Id]['S1'];
    }
    
?>

Oh, forgot to add the "getServerInformation()", but that's just the regex part:

 

function getServerInformation($string)
{
    $data = array(
        'hostname'  => "~hostname: (.*?) version :~",
        'version'   => "~version : (.*?) secure udp/ip :~",
        'secure ip' => "~secure udp/ip : (.*?) map :~",
        'map'       => "~map : (.*?) at:~",
        'at'        => "~at: (.*?) players :~",
        'players'   => "~players : (.*) #~"
    );

    foreach($data as $varName => $pattern)
    {
        preg_match($pattern, $string, $matches);
        $data[$varName] = $matches[1];
    }
    return $data;
}

 

Also, in the code provided when I use the var $command to getServerInformation() it works just fine, but it's supposed to be the same string the socket returns..

OK, just to clarify - if you call getServerInformation($command), you get the result you expect?  But if you call getServerInformation($status) you don't?  What happens instead?

 

Do var_dump($command) and var_dump($status) both print identical output?

OK, just to clarify - if you call getServerInformation($command), you get the result you expect?  But if you call getServerInformation($status) you don't?  What happens instead?

 

Do var_dump($command) and var_dump($status) both print identical output?

 

When doing this:

var_dump($command);
echo "<br>";
var_dump($status);

 

It output the same exact string (visibly at least), but the starting of the var_dump was different..

 

$command had string(228) "hostname: ..etc..etc.. this all was exactly the same"

 

$status had string(238) "hostname: ..etc..etc.. this all was exactly the same"

 

When I tried doing:

$serverInformation = getServerInformation($command);

 

This was the result:

Array
(
    [hostname] => Hooter's GG 5.1 Elimination HLstatsX:CE
    [version] => 1.0.0.58/15 4426
    [secure ip] => 25.2.132.39:27015
    [map] => fy_dustdm
    [at] => 0 x, 0 y, 0 z
    [players] => 0 (20 max)
)

 

This is the result when I tried getServerInformation() with the variable $status:

Array
(
    [hostname] => 
    [version] => 
    [secure ip] => 
    [map] => 
    [at] => 
    [players] => 
)

That number that's different is the string length.  It means the strings are in fact different.  Try this code:

 

print "c: " . urlencode($command) . "<br>";
print "s: " . urlencode($status) . "<br>";

 

Apparently so.. results:

c: hostname%3A+Hooter%27s+GG+5.1+Elimination+HLstatsX%3ACE+version+%3A+1.0.0.58%2F15+4426+secure+udp%2Fip+%3A+25.2.132.39%3A27015+map+%3A+gg_snowtiger%5BBETA%5D+at%3A+0+x%2C+0+y%2C+0+z+players+%3A+0+%2820+max%29+%23+userid+name+uniqueid+connected+ping+loss+state+adr+

s: hostname%3A+Hooter%27s+GG+5.1+Elimination+HLstatsX%3ACE+%0Aversion+%3A+1.0.0.58%2F15+4426+secure++%0Audp%2Fip++%3A++25.2.132.39%3A27015%0Amap+++++%3A+gg_snowtiger%5BBETA%5D+at%3A+0+x%2C+0+y%2C+0+z%0Aplayers+%3A+0+%2820+max%29%0A%0A%23+userid+name+uniqueid+connected+ping+loss+state+adr%0A

It seems to be the 0x0A characters.  AKA the linefeed character.  Those regexp aren't written to handle it, so they're failing.  The simplest fix would be to remove the offending characters:

 

$status = str_replace("\x0a", "", $status);

 

Also notice this:

 

map+%3A

map+++++%3A

 

The "+" denote spaces .. there are multiple spaces there which will also confuse the regexp.  I would modify the regexp to this:

 

        'map'       => "~map *: (.*?) at:~",

 

So now it will accept "map:", "map :", "map                      :".  You might need to make other modifications if there's other parts of the output that have more or less spaces than expected.  Eg there's a similar issues between "secure" and "udp", which will also break the regexp matching.  It can be fixed the same way, by adding "*" after the space in the regexp

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.