/[svn]/web/madquery.php
ViewVC logotype

Contents of /web/madquery.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 19 - (hide annotations) (download)
Sun Sep 21 02:27:07 2008 UTC (15 years, 7 months ago) by cstrike
File size: 17153 byte(s)
madquery.php from http://wiki.joe.to/index.php/MadQuery_Script
1 cstrike 19 <?php
2    
3     /***************************************************
4     * Copyright (C) 2002 madCoder *
5     * http://www.utdallas.edu/~madcoder/ *
6     * COMMENTS (NO support requests)may be sent to: *
7     * madCoder@student.utdallas.edu *
8     ***************************************************
9     * Use of this class assumes agreement to all *
10     * of the following terms of use: *
11     ***************************************************
12     * 1) This class is provided as-is, with no *
13     * offering of technical support, or help *
14     * in any way with setting up this class. *
15     * 2) madCoder will not, in any way, take *
16     * responsibility for what you do with this *
17     * script. *
18     * 3) This class may not be reproduced, or *
19     * altered, without prior authoriazation from *
20     * madCoder. *
21     * 4) ALL Copyright and credit notices MUST remain *
22     * intact, as released. *
23     ***************************************************/
24    
25    
26     define("ERROR_NOERROR" ,0);
27     define("ERROR_NOSERVER",-1);
28     define("ERROR_INSOCKET",-2);
29     //define("DEBUG",1);
30     define("OLDQUERIES",0);
31    
32     function get_float32($fourchars) {
33     $bin='';
34     for($loop = 0; $loop <= 3; $loop++) {
35     $bin = str_pad(decbin(ord(substr($fourchars, $loop, 1))), 8, '0', STR_PAD_LEFT).$bin;
36     }
37     $exponent = bindec(substr($bin, 1, 8));
38     $exponent = ($exponent)? $exponent - 127 : $exponent;
39     if($exponent) {
40     $int = bindec('1'.substr($bin, 9, $exponent));
41     $dec = bindec(substr($bin, 9 + $exponent));
42     $time = "$int.$dec";
43     return number_format($time / 60, 2);
44     } else {
45     return 0.0;
46     }
47     }
48    
49     /******
50     * getmicrotime()
51     * as provided in the PHP manual
52     ******/
53     function getmicrotime(){
54     list($usec, $sec) = explode(" ",microtime());
55     return ((float)$usec + (float)$sec);
56     }
57    
58     function dodebug($dbgstr="") {
59     if(defined('DEBUG')) echo "<!-- [DEBUG] " . $dbgstr . " -->\n";
60     }
61     /***********************************************
62     * madQuery Class
63     ***********************************************/
64     class madQuery {
65     var $_arr=array();
66     var $_ip="";
67     var $_port=0;
68     var $_isconnected=0;
69     var $_players=array();
70     var $_rules=array();
71     var $_errorcode=ERROR_NOERROR;
72     var $_seed="madQuery for server (%s:%d)";
73     var $_sk; //socket
74     var $_challengenum;
75     var $_type;
76    
77     //Constructor
78     function madQuery($serverip, $serverport=27015)
79     {
80     $this->_ip=$serverip;
81     $this->_port=$serverport;
82     $this->_seed="\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x20\x20\x20\x53\x65\x72\x76\x65\x72\x20\x6d\x61\x64\x51\x75\x65\x72\x79\x20\x43"
83     ."\x6c\x61\x73\x73\x20\x20\x20\x20\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x43\x6f\x70\x79\x72\x69"
84     ."\x67\x68\x74\x20\x28\x43\x29\x20\x32\x30\x30\x32\x20\x6d\x61\x64\x43\x6f\x64\x65\x72\x20\x20\x20\x20\x2d\x2d\x3e\x0a"
85     ."\x3c\x21\x2d\x2d\x20\x20\x20\x6d\x61\x64\x63\x6f\x64\x65\x72\x40\x73\x74\x75\x64\x65\x6e\x74\x2e\x75\x74\x64\x61\x6c"
86     ."\x6c\x61\x73\x2e\x65\x64\x75\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77"
87     ."\x2e\x75\x74\x64\x61\x6c\x6c\x61\x73\x2e\x65\x64\x75\x2f\x7e\x6d\x61\x64\x63\x6f\x64\x65\x72\x20\x2d\x2d\x3e\x0a\x0a";
88     $this->_arr=array_pad($this->_arr, 22, 0);
89     $errno=0;$errstr='';
90     $this->_sk = fsockopen("udp://" . $this->_ip, $this->_port, $errno, $errstr, 3);
91     socket_set_timeout($this->_sk, 2,0);
92     if($tmp=$this->_sockstate()) {
93     //echo $tmp;
94     if(!$this->_sk)
95     echo "ERROR #" .$errno.": ".$errstr;
96     //exit;
97     }
98     if (!OLDQUERIES) {
99     $this->_send("\xFF\xFF\xFF\xFF\x57"); //get challenge
100     $tmp=$this->_getmore();
101     $this->_challengenum=substr($tmp, 5, 4);
102     }
103     dodebug("[Initialized]");
104     // $this->_brand_seed();
105     return !(!$this->_sk);
106     }
107    
108     //Sets error code
109     function seterror($code) {
110     dodebug("[Setting Error Code (".$code.")]<BR>\n");
111     $this->_errorcode=$code;
112     }
113    
114     //Obtains ping value to server
115     function _ping()
116     {
117     dodebug("[Getting Ping]");
118     if($tmp=$this->_sockstate()){
119     //echo $tmp;
120     dodebug("[Error in Socket]");
121     $this->seterror(ERROR_INSOCKET);
122     return -1; //Error in socket
123     } else {
124     $tmp="";
125     $start = getmicrotime()*1000;
126     if (OLDQUERIES) $this->_send("ÿÿÿÿping".chr(0));
127     else $this->_send("ÿÿÿÿi".chr(0));
128     while(strlen($tmp)<4 && (getmicrotime()*1000-$start)<1000) {
129     $tmp=$this->_getmore();
130     }
131     if(strlen($tmp)>=4 && substr($tmp,4,1)=='j') {
132     $end=getmicrotime()*1000;
133     if($end<$start) echo $end .'\n'.$start;
134     return ($end-$start); //($end-$start)>=0 ? ($end-$start) : -1; //Will be numeric ping
135     } else {
136     //echo "Server didn't respond!";
137     //exit;
138     $this->seterror(ERROR_NOSERVER);
139     dodebug("[ERROR: No pong from server]");
140     return -1; //Server isn't responding...
141     }
142     }
143     return 0;
144     }
145    
146     //Populates details array
147     function getdetails()
148     {
149     dodebug("[Getting Details]");
150     if($tmp=$this->_sockstate()) {
151     //echo $tmp;
152     $this->seterror(ERROR_INSOCKET);
153     return -1;
154     } else {
155     if (OLDQUERIES) $this->_send("ÿÿÿÿdetails".chr(0));
156     else $this->_send("\xFF\xFF\xFF\xFF\x54Source Engine Query\x00");
157     $buffer=$this->_getmore();
158     /*echo $buffer;
159     for ($i=0; $i < strlen($buffer); $i++) {
160     echo '['.substr($buffer,$i,1).'='.ord(substr($buffer,$i,1)).'] ';
161     }
162     exit;*/
163     $tmp=substr($buffer,0,5);
164     $this->_type=substr($tmp,4,1);
165     $buffer=substr($buffer,5);
166     $text="";
167     $count=0;
168     $arr=array();
169     if ($this->_type == "\x6D" || OLDQUERIES ) {
170     do {
171     $tmp=substr($buffer,0,1);$buffer=substr($buffer,1);
172     if (!ord($tmp)) { $this->_arr[$count++]=$text; $text=""; }
173     else { $text.=$tmp; }
174     } while ($count<5);
175     for($i=0;$i<=6;$i++, $count++) {
176     $tmp=substr($buffer,0,1);$buffer=substr($buffer,1);
177     if($count==8 || $count==9)
178     $this->_arr[$count]=$tmp;
179     else
180     $this->_arr[$count]=ord($tmp);
181     } //count = 12
182     if($this->_arr[$count-1]) { //if ismod
183     do {
184     $tmp=substr($buffer,0,1);$buffer=substr($buffer,1);
185     $this->_arr[$count]="";
186     if (ord($tmp)!=0)
187     $this->_arr[$count].=$tmp; // mod website [12]
188     } while(ord($tmp)!=0);
189     $count++;
190     do {
191     $tmp=substr($buffer,0,1);$buffer=substr($buffer,1);
192     $this->_arr[$count]="";
193     if (ord($tmp)!=0)
194     $this->_arr[$count].=$tmp; // mod FTP [13]
195     } while(ord($tmp)!=0);
196     $count++; //[14]==Not Used
197     $this->_arr[$count++]=ord(substr($buffer,0,1)); $buffer=substr($buffer,1);
198     $tmp=substr($buffer,0,4);$buffer=substr($buffer,4);
199     for($j=0;$j<4;$j++) {
200     $this->_arr[$count]+=(pow(256,$j) * ord(substr($tmp,$j,1))); //Ver [15]
201     } $count++;
202     $tmp=substr($buffer,0,4);$buffer=substr($buffer,4);
203     for($j=0;$j<4;$j++) {
204     $this->_arr[$count]+=(pow(256,$j) * ord(substr($tmp,$j,1))); //Size [16]
205     } $count++;
206     $this->_arr[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //server-only [17]
207     $this->_arr[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //custom client.dll [18]
208     $this->_arr[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //Secure! [19]
209     $this->_arr[$count++]=ord(substr($buffer,0,1));$buffer=substr($buffer,1); //Num of bots [20]
210     } else {
211     for($i=0;$i<8;$i++)
212     $this->_arr[$count++]="\0";
213     }
214     } elseif ($this->_type == "\x49") {
215     $tmp=substr($buffer,0,1);$buffer=substr($buffer,1);
216     $this->_arr[$count++] = $tmp;
217     do {
218     $tmp=substr($buffer,0,1);$buffer=substr($buffer,1);
219     if (!ord($tmp)) { $this->_arr[$count++]=$text; $text=""; }
220     else { $text.=$tmp; }
221     } while ($count<5);
222     $tmp_lower = substr($buffer, 0, 1);
223     $tmp_higher = substr($buffer, 1, 1);
224     $buffer=substr($buffer,2);
225     $this->_arr[$count++] = ($tmp_higher << 8) | $tmp_lower;
226     for($i=0;$i<=6;$i++, $count++) {
227     $tmp=substr($buffer,0,1);$buffer=substr($buffer,1);
228     if($count==9 || $count==10)
229     $this->_arr[$count]=$tmp;
230     else
231     $this->_arr[$count]=ord($tmp);
232     } //count = 13
233     }
234     }
235     $this->_arr[$count]=round($this->_ping(),1);
236     //print_r($this->_arr);
237     return 0;
238     }
239    
240     // Sets players array
241     function getplayers()
242     {
243     dodebug("[Getting Players]");
244     //$fp = fsockopen("udp://" . $this->_ip, $this->_port);
245     if($tmp=$this->_sockstate()) {
246     //echo $tmp;
247     $this->seterror(ERROR_INSOCKET);
248     return -1;
249     } else {
250     if (OLDQUERIES) $this->_send("ÿÿÿÿplayers".chr(0));
251     else $this->_send("\xFF\xFF\xFF\xFF\x55".$this->_challengenum);
252     $buffer=$this->_getmore();
253     $buffer=substr($buffer,5);
254     $count=ord(substr($buffer,0,1)); //Num active players
255     $buffer=substr($buffer,1);
256     $tfrags="";
257     $ttime=0;
258     $arr=array();
259     for($i=0;$i<$count;$i++)
260     {
261     $rfrags=0.0;
262     $rtime=0;
263     $stime=0;
264     $tind=ord(substr($buffer,0,1));
265     $buffer=substr($buffer,1);
266     $tname="";
267     do {
268     $tmp=substr($buffer,0,1);
269     $buffer=substr($buffer,1);
270     if(ord($tmp)!=0) $tname.=$tmp;
271     }while(ord($tmp)!=0);
272     $tfrags=substr($buffer,0,4);
273     $buffer=substr($buffer,4);
274     for($j=0;$j<4;$j++) {
275     $rfrags+=(pow(256,$j) * ord(substr($tfrags,$j,1)));
276     }
277     if($rfrags > 2147483648) {
278     $rfrags-=4294967296;
279     }
280     $tmp=substr($buffer,0,4);
281     $buffer=substr($buffer,4);
282     $rtime=get_float32($tmp);
283     $arr[$i]=array("Index" => $tind,"Name" => $tname,"Frags" => $rfrags, "Time" => $rtime);
284     }
285     }
286     $this->_players=$arr;
287     return 0;
288     }
289    
290     function getrules() {
291     dodebug("[Getting Rules]");
292     $multi=0;
293     //$cvars=array();
294     if($tmp=$this->_sockstate()) {
295     $this->seterror(ERROR_INSOCKET);
296     return -1;
297     }
298     if (OLDQUERIES) $this->_send("ÿÿÿÿrules".chr(0));
299     else $this->_send("\xFF\xFF\xFF\xFF\x56".$this->_challengenum);
300     $buffer=$this->_getmore();
301     if(strlen($buffer)==0) $buffer=$this->_getmore();
302     $tmp=substr($buffer,0,5);
303     $buffer=substr($buffer,5);
304     if(substr($tmp,0,4)==chr(254).chr(255).chr(255).chr(255)) {
305     //Now, 5 more bytes to look at..
306     $multi=1;
307     for($ti=0;$ti<4;$ti++) {
308     $tmp=substr($buffer,0,1);
309     $buffer=substr($buffer,1);
310     }
311     $tmp=substr($buffer,0,5); //yyyyE = Rules Response
312     $buffer=substr($buffer,5);
313     }
314     $count=ord(substr($buffer,0,1));$buffer=substr($buffer,2); //Num rules
315     $i=0;
316     $svar="";
317     while($i<$count) {
318     if(strlen($buffer)==0 && $multi==1) {
319     $buffer=$this->_getmore();
320     $tmp=substr($buffer,0,5); //pyyy_
321     $buffer=substr($buffer,5);
322     $buffer=substr($buffer,4);
323     }
324     $tmp=substr($buffer,0,1);
325     $buffer=substr($buffer,1);
326     if(ord($tmp)==0)
327     $i+=0.5;
328     $svar=$svar.$tmp;
329     }
330     $vars=explode(chr(0),$svar);
331     for($i=0;$i<(int)(count($vars))-1;$i+=2) {
332     $cvars[$vars[$i]]=$vars[$i+1];
333     }
334     if(sizeof($cvars)>0) ksort($cvars);
335     $this->_rules=$cvars;
336     return 0;
337     }
338    
339     function _sockstate() {
340     if(!$this->_sk)
341     return 8;
342     $stat=socket_get_status($this->_sk);
343     $ret=0;
344     if($stat["timed_out"]) {
345     //echo "ERROR: Socket timed out.<BR>\n";
346     $ret|=1;
347     }
348     if($stat["eof"]) {
349     //echo "ERROR: Socket closed by remote host.<BR>\n";
350     $ret|=2;
351     }
352     if($stat["blocked"]) {
353     //echo "PORT BLOCKED!";
354     //exit;
355     //$ret|=4;
356     }
357     return $ret;
358     //return (!$stat["timed_out"] && !$stat["eof"] && !(!$this->_sk));
359     }
360    
361     function _send($outstr) {
362     if(!$this->_sockstate()) {
363     fwrite($this->_sk,$outstr,strlen($outstr));
364     } else
365     return "\0";
366     }
367    
368     function _getmore() {
369     if(!$this->_sockstate()) {
370     $tmp=fread($this->_sk,1);
371     $stat=socket_get_status($this->_sk);
372     $tmp.=fread($this->_sk, $stat["unread_bytes"]);
373     return $tmp;
374     } else
375     return "\0";
376     }
377    
378     function _brand_seed() {
379     /*************************************************************************************************************************
380     * Do not edit this function!*//*print(* /$this->_seed/*//*);//*print($this->_seed/*);*//**/print(/**/$this->_seed /**/);/*
381     *************************************************************************************************************************/
382     $this->_seed="\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x20\x20\x20\x53\x65\x72\x76\x65\x72\x20\x6d\x61\x64\x51\x75\x65\x72\x79\x20\x43"
383     ."\x6c\x61\x73\x73\x20\x20\x20\x20\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x20\x20\x20\x43\x6f\x70\x79\x72\x69"
384     ."\x67\x68\x74\x20\x28\x43\x29\x20\x32\x30\x30\x32\x20\x6d\x61\x64\x43\x6f\x64\x65\x72\x20\x20\x20\x20\x2d\x2d\x3e\x0a"
385     ."\x3c\x21\x2d\x2d\x20\x20\x20\x6d\x61\x64\x63\x6f\x64\x65\x72\x40\x73\x74\x75\x64\x65\x6e\x74\x2e\x75\x74\x64\x61\x6c"
386     ."\x6c\x61\x73\x2e\x65\x64\x75\x20\x20\x20\x2d\x2d\x3e\x0a\x3c\x21\x2d\x2d\x20\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77"
387     ."\x2e\x75\x74\x64\x61\x6c\x6c\x61\x73\x2e\x65\x64\x75\x2f\x7e\x6d\x61\x64\x63\x6f\x64\x65\x72\x20\x2d\x2d\x3e\x0a\x0a";
388     // print($this->_seed);
389     }
390    
391     //Returns current errorcode
392     function geterror() {
393     return $this->_errorcode;
394     }
395    
396     function isup()
397     /************************************
398     * int isup(char * ip, long port);
399     * Return values:
400     * 0 = No response - probably down
401     * 1 = HL Responded - Server is up
402     * -1 = Error in socket
403     ************************************/
404     {
405     if($ret=$this->_sockstate()) {
406     //echo $ret;
407     return -1;
408     } else {
409     if($ret & 2) {
410     return 0;
411     }
412     $myping=$this->_ping();
413     if($myping>0)
414     return $myping;
415     else
416     return 0;
417     }
418     }
419    
420     function JoinLink(){
421     if ($this->_type == "\x6D"){
422     return "'steam: \" -applaunch 70 ".($this->mModName()?'-game '.$this->mModName():'')." +connect ".$this->_ip.($this->_ip?':'.$this->_port:27015)." ;\"'";
423     } elseif ($this->_type == "\x49"){
424     return "'steam: \" -applaunch ".$this->mAppID()." +connect ".$this->_ip.($this->_ip?':'.$this->_port:27015)." ;\"'";
425     }
426     }
427    
428     function mAddress (){if($this->_type == "\x6D")return $this->_arr[ 0]; elseif($this->_type == "\x49") return '';}
429     function mHostname (){if($this->_type == "\x6D")return $this->_arr[ 1]; elseif($this->_type == "\x49") return $this->_arr[ 1];}
430     function mMap (){if($this->_type == "\x6D")return $this->_arr[ 2]; elseif($this->_type == "\x49") return $this->_arr[ 2];}
431     function mModName (){if($this->_type == "\x6D")return $this->_arr[ 3]; elseif($this->_type == "\x49") return $this->_arr[ 3];}
432     function mDescr (){if($this->_type == "\x6D")return $this->_arr[ 4]; elseif($this->_type == "\x49") return $this->_arr[ 4];}
433     function mAppID (){if($this->_type == "\x6D")return ''; elseif($this->_type == "\x49") return $this->_arr[ 5];}
434     function mActive (){if($this->_type == "\x6D")return $this->_arr[ 5]; elseif($this->_type == "\x49") return $this->_arr[ 6];}
435     function mMax (){if($this->_type == "\x6D")return $this->_arr[ 6]; elseif($this->_type == "\x49") return $this->_arr[ 7];}
436     function mProtocol (){if($this->_type == "\x6D")return $this->_arr[ 7]; elseif($this->_type == "\x49") return $this->_arr[ 0];}
437     function mSvrType (){if($this->_type == "\x6D")return $this->_arr[ 8]; elseif($this->_type == "\x49") return $this->_arr[ 9];}
438     function mSvrOS (){if($this->_type == "\x6D")return $this->_arr[ 9]; elseif($this->_type == "\x49") return $this->_arr[10];}
439     function mPass (){if($this->_type == "\x6D")return $this->_arr[10]; elseif($this->_type == "\x49") return $this->_arr[11];}
440     function mIsMod (){if($this->_type == "\x6D")return $this->_arr[11]; elseif($this->_type == "\x49") return '';}
441     function mModWeb (){if($this->_type == "\x6D")return $this->_arr[12]; elseif($this->_type == "\x49") return '';}
442     function mModFTP (){if($this->_type == "\x6D")return $this->_arr[13]; elseif($this->_type == "\x49") return '';}
443     function mNotUsed (){if($this->_type == "\x6D")return $this->_arr[14]; elseif($this->_type == "\x49") return '';}
444     function mModVer (){if($this->_type == "\x6D")return $this->_arr[15]; elseif($this->_type == "\x49") return '';}
445     function mModSize (){if($this->_type == "\x6D")return $this->_arr[16]; elseif($this->_type == "\x49") return '';}
446     function mSvrOnly (){if($this->_type == "\x6D")return $this->_arr[17]; elseif($this->_type == "\x49") return '';}
447     function mCustom (){if($this->_type == "\x6D")return $this->_arr[18]; elseif($this->_type == "\x49") return '';}
448     function mIsSecure (){if($this->_type == "\x6D")return $this->_arr[19]; elseif($this->_type == "\x49") return $this->_arr[12];}
449     function mNumBots (){if($this->_type == "\x6D")return $this->_arr[20]; elseif($this->_type == "\x49") return $this->_arr[ 8];}
450     function mPing (){if($this->_type == "\x6D")return $this->_arr[21]; elseif($this->_type == "\x49") return $this->_arr[13];}
451     function mPlayerData(){if($this->_type == "\x6D")return $this->_players; elseif($this->_type == "\x49") return $this->_players;}
452     function mRules (){if($this->_type == "\x6D")return $this->_rules ; elseif($this->_type == "\x49") return $this->_rules ;}
453    
454     };
455    
456     /*
457     $myserver=new madQuery("63.99.222.178",27015);
458     $myserver->getdetails();
459     $myserver->getplayers();
460     echo $myserver->mHostname().": ".$myserver->mActive()." / ".$myserver->mMax();
461     echo "Server is ".($myserver->mIsSecure() ? "" : "NOT ")."secure!\n";
462     */
463     ?>

Contact webmaster
ViewVC Help
Powered by ViewVC RSS 2.0 feed