RyanEricW Posted February 5, 2009 Share Posted February 5, 2009 Basically the problem lies within connecting or writing using sockets. Here's the weird thing, this works perfectly on windows based server, but when I use it on a linux server, it's like linux doesn't even want to work with UDP stuff. I'm very frusted and been pulling hairs out for 5 hours now... Hopefully someone can help. This connects to a Half-Life 2 server and pulls data like (server name, max players, current players, etc). index.php <? require("CServerInfo.php"); $sinfo = array(); $sinfo = $ServerInfo->getInfo("66.55.154.167","27015"); ?> CServerInfo.php <?php if(!isset($_SESSION)) // We are using AJAX so need a new session, as we bypass some stuff before session_start(); define('INFO_RESPONSE_HL1',0x6D); define('CHALLENGE_RESPONSE',0x41); include 'hexdump.php'; class CServerInfo { var $raw; function getInfo($address,$port) { if (isset($_SESSION['getInfo.' . $address . '.' . $port]) && is_array($_SESSION['getInfo.' . $address . '.' . $port])) { return $_SESSION['getInfo.' . $address . '.' . $port]; } $ret = array(); $s = fsockopen("udp://".$address,$port,$errno,$errstring,1); if (!$s) echo "$errstring ($errno)<br />\n"; stream_set_timeout($s,1); if(!fwrite($s,"\xFF\xFF\xFF\xFF\x54Source Engine Query",39)) { echo "Error Writing Data. $errstring ($errno)"; } $packet = fread($s,1024); echo "Packet: $packet"; if(empty($packet)) { $_SESSION['getInfo.' . $address . '.' . $port] = $this->getInfoProxy($address, $port); return $this->getInfoProxy($address, $port); } $parr = explode("\x00",substr($packet,6)); if(!isset($packet[4])) { $_SESSION['getInfo.' . $address . '.' . $port] = array(); return $_SESSION['getInfo.' . $address . '.' . $port]; } if (ord($packet[4]) == INFO_RESPONSE_HL1) { //HL1 Response $packet = substr($packet,strpos($packet,"\x00")+1); $parr = explode("\x00",$packet); $ret['hostname'] = $parr[0]; $ret['map'] = $parr[1]; $ret['gamename'] = $parr[2]; $ret['gamedesc'] = $parr[3]; $packet = substr($packet,strlen($ret['hostname'])+1+strlen($ret['map'])+1+strlen($ret['gamename'])+1+strlen($ret['gamedesc'])+1); $ret['numplayers'] = ord($packet[0]); $ret['maxplayers'] = ord($packet[1]); //$version = ord($packet[2]); $ret['dedicated'] = $packet[3]; $ret['os'] = $packet[4]; $ret['password'] = ord($packet[5]); if (ord($packet[6])) { //Skip mod info $packet = substr($packet,strpos($packet,"\x00")+1); $packet = substr($packet,strpos($packet,"\x00")+3); } else { $packet = substr($packet,6); } $ret['secure'] = ord($packet[0]); $ret['botcount'] = ord($packet[1]); } else { //HL2 Response $ret['hostname'] = $parr[0]; $ret['map'] = $parr[1]; $ret['gamename'] = $parr[2]; $ret['gamedesc'] = $parr[3]; $packet = substr($packet,6+strlen($ret['hostname'])+1+strlen($ret['map'])+1+strlen($ret['gamename'])+1+strlen($ret['gamedesc'])+1+2); $ret['numplayers'] = ord($packet[0]); $ret['maxplayers'] = ord($packet[1]); $ret['botcount'] = ord($packet[2]); $ret['dedicated'] = ord($packet[3]); $ret['os'] = $packet[4]; $ret['password'] = ord($packet[5]); $ret['secure'] = $packet[6]; } $_SESSION['getInfo.' . $address . '.' . $port] = $ret; return $ret; } function getPlayers($address,$port) { set_magic_quotes_runtime(0); $ret = array(); $s = fsockopen("udp://".$address,$port,$errno,$errstring,1); stream_set_timeout($s,1); // 1 second timeout on read/write operations fwrite($s,"\xFF\xFF\xFF\xFF\x57"); //Get challenge # $packet = fread($s,1024); $chalId = $this->getChallenge($packet); fwrite($s,"\xFF\xFF\xFF\xFF\x55".$chalId); $packet = fread($s,2048); if(empty($packet)) { return $this->getPlayersProxy($address, $port); } $packet = substr($packet,5); $nump = ord($packet[0]); $packet = substr($packet,1); $this->raw = $packet; for ($i=0;$i<$nump;$i++) { $temp = array(); $temp['index'] = $this->_getbyte(); $temp['name']= $this->_getnullstr(); $temp['kills']= $this->_getlong(); $temp['time']= SecondsToString((int)$this->_getfloat(),true); if(!empty($temp['name'])) array_push($ret,$temp); } array_qsort($ret, 'kills', SORT_DESC); return $ret; } function getChallenge($packet) { if(isset($packet[4]) && ord($packet[4]) == CHALLENGE_RESPONSE) { return substr($packet,5); } return "\xFF\xFF\xFF\xFF"; } /* Proxy functions are used when there is a problem with blocked ports, or firewalls like with some webhosts. */ function getInfoProxy($address,$port) { if(!(isset($address) && isset($port))) return false; $ret = array(); $info = @file_get_contents(SERVER_QUERY . "?ip=" . $address . "&port=" .$port."&type=info"); if(strstr($info, "Page not found")) return false; if($info) { $inf = explode("\t", $info); $ret['hostname'] = $inf[0]; $ret['numplayers'] = $inf[1]; $ret['maxplayers'] = $inf[2]; $ret['map'] = $inf[3]; $_SESSION['getInfo.' . $address . '.' . $port] = $ret; return $ret; } else return false; } function getPlayersProxy($address,$port) { if(!(isset($address) && isset($port))) return false; $ret = array(); $players = @file_get_contents(SERVER_QUERY . "?ip=" . $address . "&port=" .$port."&type=players"); if(strstr($players, "Page not found")) return false; if($players) { $plr = explode("\n", $players); foreach($plr AS $player) { $items = explode("\t", $player); if(!isset($items[1])) { continue; } $row = array(); $row['index'] = $items[0]; $row['name'] = $items[1]; $row['kills'] = $items[2]; $row['time'] = $items[3]; array_push($ret, $row); } return $ret; } else return false; } function _getnullstr() { if (empty($this->raw)) return ''; $end = strpos($this->raw, "\0"); $str = substr($this->raw, 0, $end); $this->raw = substr($this->raw, $end+1); return $str; } function _getchar() { return sprintf("%c", $this->_getbyte()); } function _getbyte() { $byte = substr($this->raw, 0, 1); $this->raw = substr($this->raw, 1); return ord($byte); } function _getshort() { $lo = $this->_getbyte(); $hi = $this->_getbyte(); $short = ($hi << | $lo; return $short; } function _getlong() { $lo = $this->_getshort(); $hi = $this->_getshort(); $long = ($hi << 16) | $lo; return $long; } function _getfloat() { $f = @unpack("f1float", $this->raw); $this->raw = substr($this->raw, 4); return $f['float']; } } $ServerInfo = new CServerInfo(); ?> hexdump.php <?php function hexdump ($data, $htmloutput = true, $uppercase = false, $return = false) { // Init $hexi = ''; $ascii = ''; $dump = ($htmloutput === true) ? '<pre>' : ''; $offset = 0; $len = strlen($data); // Upper or lower case hexidecimal $x = ($uppercase === false) ? 'x' : 'X'; // Iterate string for ($i = $j = 0; $i < $len; $i++) { // Convert to hexidecimal $hexi .= sprintf("%02$x ", ord($data[$i])); // Replace non-viewable bytes with '.' if (ord($data[$i]) >= 32) { $ascii .= ($htmloutput === true) ? htmlentities($data[$i]) : $data[$i]; } else { $ascii .= '.'; } // Add extra column spacing if ($j === 7) { $hexi .= ' '; $ascii .= ' '; } // Add row if (++$j === 16 || $i === $len - 1) { // Join the hexi / ascii output $dump .= sprintf("%04$x %-49s %s", $offset, $hexi, $ascii); // Reset vars $hexi = $ascii = ''; $offset += 16; $j = 0; // Add newline if ($i !== $len - 1) { $dump .= "\n"; } } } // Finish dump $dump .= $htmloutput === true ? '</pre>' : ''; $dump .= "\n"; // Output method if ($return === false) { echo $dump; } else { return $dump; } } ?> Quote Link to comment Share on other sites More sharing options...
RyanEricW Posted February 5, 2009 Author Share Posted February 5, 2009 Bump Quote Link to comment Share on other sites More sharing options...
RyanEricW Posted February 6, 2009 Author Share Posted February 6, 2009 I installed the script from where I got the includes from and they said: Notice: fwrite() [function.fwrite]: send of 25 bytes failed with errno=1 Operation not permitted in /home/convictg/public_html/phgstats/classes/hl.class.php on line 78 Notice: fwrite() [function.fwrite]: send of 5 bytes failed with errno=1 Operation not permitted in /home/convictg/public_html/phgstats/classes/hl.class.php on line 59 Notice: fwrite() [function.fwrite]: send of 5 bytes failed with errno=1 Operation not permitted in /home/convictg/public_html/phgstats/classes/hl.class.php on line 100 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.