View difference between Paste ID: TemNw507 and HqCA2CLP
SHOW: | | - or go back to the newest paste.
1
<?php
2
3
/**
4
 * @author 3nvisi0n
5
 * @copyright 2011
6
 * 
7
 * This is just a basic version of my Xat Bot you can build upon to add the feature you want.
8
 * 
9
 */
10
set_time_limit(0);//No time out
11
$bot = new BasicXatBot();
12
$roomID = 88973610;//Don't know how to get this ID? goto xat.com/ROOM_YOU_WANT_BOT_IN  and View Source(Firefox: Ctrl+U, Internet Explorer: View>Source) Look for "flashvars="id=#########&..." the ID is the number you want
13
$bot->connect("174.36.242.26","10024"); //Connect to XAT...this IP will change as necessary automatically depending on the room you want to join.
14
$bot->join($roomID);
15
while(true){
16
    if($bot->read()=='DIED') {
17
        $bot->connect("174.36.242.26","10024"); 
18
        $bot->join($roomID);
19
    }
20
}
21
22
23
class BasicXatBot {
24
    private $soc;                   //Socket for bot
25
    private $debug = false;          //Used to toggle debugging output.
26
    private $packet;                //Stores information about the last recieved packet of each kind
27
    private $userInfo;              //Stores User information
28
    
29
    //If you don't know where to get these you should probably not be trying to make your own bot.
30
    //Go download WPE Pro and check out the packets XAT sends and learn about how XAT works.
31
    //The UserID and K Value are the source or the 'old falsh' error(if you get it) make sure you get these values from a REGISTERED account
32
    
33-
    private $userID = "351599155";  //The Bot's UserID
33+
    private $userID = "37007701";  //The Bot's UserID
34
    private $k = "3607438505";      //The Bot's K value
35
    
36
    //Bot Account Settings
37
    private $name = "XBot";         //The display name the bot will use
38
    private $avatar = -1;           //The Avatar value for the bot, this can be an id number or an image url.
39
    private $homepage = "";         //The bot's homepage link.
40
    private $roomID;                //This gets set in code, don't touch it here. just used ->join(ID)
41
    
42
    
43
    /**
44
     * This is where everything the bot does needs to happen, this is the only default function you should need to edit
45
     * @param $event The event that just occured(and thus needs to be handled) 
46
     * @param $data Any data relating to this event.
47
     */
48
    function handleEvent($event,$data) {
49
       $info = $this->getUserArray($data['id']);
50
       switch($event) {
51
            case 'userJoined':
52
             /* $data['id']             Has the ID of the user who just joined
53
                $data['old']            Sometimes XAT sends packets that are not current(for example when you join a room, old ==true for all users who are already in the room when you join, but still this event is handled as thought they just joined */
54
                
55
                //Do whever you want with users joining here...
56
                echo ((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) has just joined.\n";
57
            break;
58
            case 'userLeft':
59
                /* $data['id']     The ID of the user that just left. */                
60
                echo ((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) has just left.\n";
61
            break;
62
            case 'privateMessage':
63
                /* $data['id']      The ID of the user that just left.
64
                   $data['message'] The message sent to you as a PM */
65
                echo "[PM] ".((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) -> $data[message]\n";
66
                
67
                //Example of a private message command
68
                $command = explode(' ',$data['message'],2); //First parse the first word out see if it is a command...
69
                //[0] has first word [1] has everything else
70
                if($command[0]{0}=='!'){//I am use ! as the character to signify a command, so check if the first character is right.
71
                    switch($command[0]) {
72
                        case '!say':
73
                        case '!speak':
74
                        case '!talk':
75
                            $this->sendPrivateMessage($command[1],$data['id']);
76
                        break;
77
                        case '!info':
78
                            $this->sendPrivateMessage('I am a bot ^_^',$data['id']);
79
                        break;
80
                    }
81
                }
82
            break;
83
            case 'privateChat':
84
                /* $data['id']      The ID of the user that just left.
85
                   $data['message'] The message sent to you as a PC */
86
                echo "[PC] ".((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) -> $data[message]\n";
87
                
88
                //Example of a private chat command
89
                $command = explode(' ',$data['message'],2); //First parse the first word out see if it is a command...
90
                //[0] has first word [1] has everything else
91
                if($command[0]{0}=='!'){//I am use ! as the character to signify a command, so check if the first character is right.
92
                    switch($command[0]) {
93
                        case '!info':
94
                            $this->sendPrivateChat('I am a bot ^_^',$data['id']);
95
                        break;
96
                    }
97
                }
98
            break;
99
            case 'message':
100
                /* $data['id']      The ID of the user
101
                   $data['old']     See $data['old'] under userJoined
102
                   $data['message'] The message sent to main chat */
103
                echo ((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) -> $data[message]\n";
104
                
105
                //How to do main chat commands: 
106
                if($data['old'])   return; //Old message             
107
                $command = explode(' ',trim($data['message']),2); //First parse the first word out see if it is a command...
108
                //[0] has first word [1] has everything else
109
                if($command[0]{0}=='!'){//I am use ! as the character to signify a command, so check if the first character is right.
110
                    switch($command[0]) {
111
                        case '!say':
112
                        case '!speak':
113
                        case '!talk':
114
                            //Multiple cases lead to the same code being run...
115
                            $this->sendMessage($command[1]);
116
                        break;
117
                        case '!slap':
118
                        case '!slaps':
119
                        case '!hit':
120
                            $this->sendMessage(((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])." slaps $command[1] around a bit with a large trout.");
121
                        break;
122
                        case '!avatar'://steal an avatar via !avatar USER_ID
123
                            $user = $this->getUserArray($command[1]);
124
                            $this->sendMessage(str_replace('(','( ',$user['avatar']));
125
                        break;
126
                        case '!info':
127
                            $this->sendMessage('I am a bot ^_^',$data['id']);
128
                        break;
129
                        case '!yt':
130
                        case '!youtube':
131
                        case '!y':
132
                            if(trim($command[1])=='') $this->sendMessage("Usage: $command[0] SEARCH TERMS HERE");
133
                            else {
134
                                //Yeah I know I don't really need urlencode() i could just replace spaces with + but this is a bit more secure.
135
                                $res = $this->get('http://www.youtube.com/results?search_query='.urlencode(preg_replace("/[^A-Za-z0-9 !.,:[]\s\s+]/",'',$command[1])));
136
                                for($i=0;$i<3;$i++) {
137
                                    $msg=$this->getBetween($res, '<h3>', '</h3>');
138
                                    $res = str_replace('<h3>'.$msg,'</h3>',$res);
139
                                    $url = "http://www.youtube.com".$this->getBetween($msg,'href="', '"');
140
                                    $title = @ereg_replace('[^A-Za-z0-9 -()[]<>{}&@]','',$this->getBetween($msg,'title="', '"'));
141
                                    $this->sendMessage($title." - $url");
142
                                    sleep(1);//Xat won't let us send more than 1 message per second, it ignores anything faster.
143
                                }   
144
                            }
145
                        break;
146
                        case '!g':
147
                        case '!google':
148
                            $res = $this->get('http://www.google.com/search?hl=en&source=hp&biw=&bih=&q='.str_replace(' ','+',$command[1]).'&btnG=Google+Search',true);
149
                            for($i=0;$i<3;$i++) {
150
                                $msg=$this->getBetween($res, '<h3 class="r"><a href="', '"');
151
                                $res = str_replace('<h3 class="r"><a href="'.$msg,'',$res);
152
                                $this->sendMessage($msg);
153
                                sleep(1);
154
                            }
155
                    }
156
                }
157
            break;
158
        
159
       }        
160
    }
161
    
162
    
163
    
164
    /* ****************************************************** */
165
    /* *YOU SHOULD NOT NEED TO EDIT ANYTHING AFTER THIS LINE* */
166
    /* ****************************************************** */
167
    /**
168
     * Connects to a given ip on the given port
169
     * @param $ip The IP to connect to.
170
     * @param $port The port on the IP to connect to.
171
     */
172
    function connect($ip, $port) {
173
        if($this->soc!=null) socket_close($this->soc);
174
        $this->soc = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
175
        if(!$this->soc) die(socket_strerror(socket_last_error($this->soc)));
176
        if(!socket_connect($this->soc,$ip,$port)) die("Could not connect.");  
177
    }
178
    
179
    /**
180
     * Writes the given message to the object socket($this->soc)
181
     * @param $message The packet to send.
182
     */
183
    function send($message) {
184
        if($this->debug)echo "->>\t$message\n";
185
        socket_write($this->soc, $message."\0", strlen($message)+1); 
186
    }
187
    
188
    
189
    /**
190
     * Reads a message from the socket, will read until entire message has been recieved or connection closes.
191
     * @param $parse Used for recursive calls to tell the function not to parse a partial packet
192
     */
193
    function read($parse=true) {
194
        $res = rtrim(socket_read($this->soc, 4096));
195
        if($this->debug)echo "<<-\t$res\n";
196
        if(!$res) {
197
            return "DIED"; //Used to gracefully handle a closed socket
198
        }
199
        if($res{strlen($res)-1}!='>') { $res.=$this->read(false);} //Recursive call for messages split over several packets.
200
        if($parse)$this->parse($res);
201
        return $res;
202
    }
203
    
204
    /**
205
     * Parses the recieved packets into their message and types.
206
     * @param $packet The packet recieved.
207
     */
208
    function parse($packet) {
209
        if(substr_count($packet,'>')>1) $packet = explode('/>',$packet);//If necessary split the packet into individual messages
210
        foreach((Array)$packet as $p) {
211
            $p = trim($p);
212
            if(strlen($p)<5) return;//garbage data
213
            $type = trim(strtolower(substr($p,1,strpos($p.' ',' '))));//packet type
214
            $p = trim(str_replace("<$type",'',str_replace('/>','',$p)));//remove details so it is just the info to be parsed
215
            parse_str(str_replace('"','',str_replace('" ','&',str_replace('="','=',str_replace('&','__38',$p)))),$this->packet[$type]);
216
            foreach($this->packet[$type] as $k=>$v) {
217
                $this->packet[$type][$k] = str_replace('__38','&',$v); //htmlspecial chars are protected instead of being parsed 
218
            }
219
            $this->handle($type,$p);
220
        }
221
    }
222
    
223
    /**
224
     * This is the inital handler for the packets, parses them and sends them off to their respective function to be handled further.
225
     * @param $type The character code indicating the type of data within the message.
226
     * @param $message The data the message contains.
227
     */
228
    function handle($type,$msg) { 
229
        switch($type) {
230
            case 'gp':
231
                if(isset($this->packet['gp']['x']))
232
                    $this->send('<x i="'.$this->packet['gp']['x'].'" u="'.$this->userID.'" t="j" />'); //Handle groups
233
            break;
234
            case 'q'://XAT notice to change ip/port
235
                $this->connect($this->packet['q']['d'], $this->packet['q']['p']);
236
                $this->join($this->roomID);
237
            break;  
238
            case 'o': 
239
                $this->packet['o']['u'] = $this->parseU(@$this->packet['u']['u']);
240
                $this->userInfo[$this->packet['o']['u']]['name'] = @$this->packet['o']['n'];
241
                $this->userInfo[$this->packet['o']['u']]['registeredName'] = ((isset($this->packet['o']['N']))?$this->packet['o']['N']:'');
242
                $this->userInfo[$this->packet['o']['u']]['avatar'] = @$this->packet['o']['a'];
243
                $this->userInfo[$this->packet['o']['u']]['homepage'] = @$this->packet['o']['h'];
244
                $this->userInfo[$this->packet['o']['u']]['rank'] = $this->f2rank(@$this->packet['o']['f']);
245
            break;
246
            case 'u':
247
                //Joined
248
                //Default Bot stuff regarding userInformation
249
                $this->packet['u']['u'] = $this->parseU(@$this->packet['u']['u']);
250
                $this->userInfo[$this->packet['u']['u']]['name'] = @$this->packet['u']['n'];
251
                $this->userInfo[$this->packet['u']['u']]['registeredName'] = ((isset($this->packet['u']['N']))?$this->packet['u']['N']:'');
252
                $this->userInfo[$this->packet['u']['u']]['avatar'] = @$this->packet['u']['a'];
253
                $this->userInfo[$this->packet['u']['u']]['homepage'] = @$this->packet['u']['h'];
254
                $this->userInfo[$this->packet['u']['u']]['rank'] = $this->f2rank(@$this->packet['u']['f']);
255
                
256
                $event = 'userJoined';
257
                $data['id'] = $this->packet['u']['u'];
258
                $data['old'] = ($type=='o'||(isset($this->packet['u']['s']))?true:false);
259
                $this->handleEvent($event,$data);
260
                
261
            break;
262
            case 'l':
263
                //User Left or was kicked, banned
264
                unset($this->userInfo[$this->packet['l']['u']]);
265
                $event = 'userLeft';
266
                $data['id'] = $this->packet['l']['u'];
267
                $this->handleEvent($event,$data);
268
                
269
            break;
270
            case 'p':
271
                //Private message/chat recieved
272
                $event = ((isset($this->packet['p']['d']))?'privateChat':'privateMessage');
273
                $data['id'] =  $this->parseU(@$this->packet['p']['u']);
274
                $data['message'] = $this->packet['p']['t'];
275
                $this->handleEvent($event,$data);
276
            break;
277
            case 'm':
278
                //message to main chat.
279
                $event = 'message';
280
                $data['id'] = $this->parseU(@$this->packet['m']['u']);
281
                $data['message'] = $this->packet['m']['t'];
282
                $data['old'] = ((isset($this->packet['m']['s']))?true:false);
283
                $this->handleEvent($event,$data);
284
            break;
285
        }
286
    }
287
    
288
    /**
289
     * Joins a room.
290
     * @param $roomID the numeric roomID to join.
291
     */
292
    function join($roomID) {
293
        //Announce we are here:
294
        $this->send('<y m="1" />');//Anounces our arrival to the server and gets some information to send back
295
        $this->read(); //Auto parsed into $this->packet['y']
296
        $this->send('<j2 q="1" y="'.$this->packet['y']['i'].'" k="'.$this->k.'" k3="0" z="12" p="0" c="'.$roomID.'" f="0" u="'.$this->userID.'" d0="0" n="'.$this->name.'" a="'.$this->avatar.'" h="'.$this->homepage.'" v="0" />');
297
        $this->roomID = $roomID;
298
    }
299
    
300
    /**
301
     * Parses the u value from a packet to get just the id
302
     * @param $id the id to be parsed.
303
     */
304
    function parseU($id) {
305
        if(substr_count($id,'_')>=1) $id = substr($id,0,strpos($id,'_'));
306
        return $id;
307
    }
308
    
309
    /**
310
     * Converts an f value to a string containing the corresponding rank...this if you don't understand bitwise operations is a little 'magical' deal with it.
311
     * @param $f The f value to be parsed.
312
     */
313
    function f2rank($f) {
314
        $f = $this->parseU($f);
315
        
316
        if($f==-1) return 'guest';
317
        //Okay, 98% of you reading this on NewHax won't know what any of this means; if you do you are more adnvanced than I expected
318
        //Not that this is advnaced stuff, but basiclly it is a bit-wise comparision(notice & instead of && it is checking if certain binary bits are set to 1
319
        //The F value is essientially a bunch of flags where for example 00010000 == banned(the 0s can be 0 or 1, just as long as that one 1 is a one you are banned.
320
        if((16 & $f)) return 'banned';
321
        if((1 & $f)&&(2 & $f)) return 'member';
322
        if((4 & $f)) return 'owner';
323
        if((32 & $f)&&(1 & $f)&&!(2 & $f)) return 'main';
324
        if(!(1 & $f)&&!(2 & $f)) return 'guest';
325
        if((16 & $f)) return 'banned';
326
        if((2 & $f)&&!(1 & $f)) return 'mod';
327
    }
328
    
329
    /**
330
     * Returns an assoc array of information regarding the user with the given id
331
     * @param $id The user id you want information on.
332
     */
333
    function getUserArray($id) {
334
        $id = $this->parseU($id);
335
        if(isset($this->userInfo[$id])) {
336
             return $this->userInfo[$id];
337
        } else return false;
338
    }
339
    
340
    /**
341
     * Sends the given message to the main chat
342
     * @param $message
343
     */
344
    function sendMessage($message) {
345
        if(empty($message))return;
346
        $this->send('<m t="'.$message.'" u="'.$this->userID.'" />');    
347
    }
348
    
349
    /**
350
     * Sends a PC to the given ID
351
     * @param $message The message to send.
352
     * @param $id The id to send the message to
353
     */
354
    function sendPrivateChat($message, $id) {
355
        if(empty($message))return;
356
        $this->send('<p u="'.$id.'" t="'.$message.'" s="2" d="'.$this->userID.'" />');    
357
    }
358
    
359
    /**
360
     * Sends a PM to the given ID
361
     * @param $message The message to send.
362
     * @param $id The id to send the message to
363
     */
364
    function sendPrivateMessage($message,$id) {
365
        $id = $this->parseU($id);
366
        if(empty($message))return;
367
        $this->send('<p u="'.$id.'" t="'.$message.'" />');    
368
    }
369
    
370
    /** 
371
     * Makes the given $id an owner, assuming the bot is main
372
     * @param $id The id to promote
373
     */
374
    function mod($id) {
375
        $this->send('<c u="'.$this->parseU($id).'" t="/M" />');
376
    }
377
    
378
    /** 
379
     * Makes the given $id a mod, assuming the bot is owner
380
     * @param $id The id to promote
381
     */
382
    function owner($id) {
383
        $this->send('<c u="'.$this->parseU($id).'" t="/m" />');
384
    }
385
    
386
    /** 
387
     * Makes the given $id a member, assuming the bot is mod
388
     * @param $id The id to member
389
     */
390
    function member($id) {
391
            $this->send('<c u="'.$this->parseU($id).'" t="/e" />');
392
    }
393
    
394
    /** 
395
     * KIcks the given ID assuming the bot is a mod and $id is a member or less
396
     * @param $id The id to kick
397
     */
398
    function kick($message, $id) {
399
        $this->send('<c p="'.$message.'" u="'.$this->parseU($id).'" t="/k" />');   
400
    }
401
    
402
    /** 
403
     * Bans the ID for a given time(0 is forever)
404
     * @param $id The id to ban
405
     */
406
    function ban($message, $id, $time) {
407
        if(empty($time)) $time = 3600;
408
        $this->send('<c p="'.$message.'" u="'.$this->parseU($id).'" t="/g'.$time.'" />');
409
    }
410
    
411
    /** 
412
     * Unbans the given ID
413
     * @param $id The id to unban
414
     */
415
    function unban($id) {
416
        $this->send('<c u="'.$this->parseU($id).'" t="/u" />');    
417
    }
418
    
419
    /**
420
     * Performs a basic HTTP GET to the given URL
421
     * @param $url The url to retrieve, please include http:// and www if necessary
422
     * @param $includeHeader Tells teh function wether or not to include the server header respond before the main content
423
     */
424
    function get($url, $includeHeader=false) {
425
        $urlp = parse_url($url); 
426
        $fp = fsockopen($urlp['host'],80); 
427
        $path = explode('/',$url,4);
428
        $path = ((count($path)>=4)?$path[3]:"");
429
        $req = "GET /$path HTTP/1.1\r\n";
430
        $req .= "Host: $urlp[host]\r\n";
431
        $req .= "Connection: Close\r\n\r\n";
432
        fputs($fp, $req);
433
        $res = ""; 
434
        while(!feof($fp)) $res .= fgets($fp, 4096);
435
        fclose($fp);
436
        if($includeHeader) return $res;
437
        $res = explode("\r\n\r\n",$res,2);
438
        return $res[1];
439
    }
440
    /**
441
     * A utility function to get all text beween $start and $end
442
     * @param $content The content from which we are grabbing data
443
     * @param $start where to start grabbing from
444
     * @param $end the end of the content to grab
445
     */
446
    function getBetween($content,$start,$end){
447
        $r = explode($start, $content);
448
        if (isset($r[1])){
449
            $r = explode($end, $r[1]);
450
            return $r[0];
451
        }
452
        return '';
453
    }
454
    
455
}
456
457
?>