Source) Look for "flashvars="id=#########&..." the ID is the number you want $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. $bot->join($roomID); while(true){ if($bot->read()=='DIED') { $bot->connect("174.36.242.26","10024"); $bot->join($roomID); } } class BasicXatBot { private $soc; //Socket for bot private $debug = false; //Used to toggle debugging output. private $packet; //Stores information about the last recieved packet of each kind private $userInfo; //Stores User information //If you don't know where to get these you should probably not be trying to make your own bot. //Go download WPE Pro and check out the packets XAT sends and learn about how XAT works. //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 private $userID = "351599155"; //The Bot's UserID private $k = "3607438505"; //The Bot's K value //Bot Account Settings private $name = "XBot"; //The display name the bot will use private $avatar = -1; //The Avatar value for the bot, this can be an id number or an image url. private $homepage = ""; //The bot's homepage link. private $roomID; //This gets set in code, don't touch it here. just used ->join(ID) /** * This is where everything the bot does needs to happen, this is the only default function you should need to edit * @param $event The event that just occured(and thus needs to be handled) * @param $data Any data relating to this event. */ function handleEvent($event,$data) { $info = $this->getUserArray($data['id']); switch($event) { case 'userJoined': /* $data['id'] Has the ID of the user who just joined $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 */ //Do whever you want with users joining here... echo ((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) has just joined.\n"; break; case 'userLeft': /* $data['id'] The ID of the user that just left. */ echo ((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) has just left.\n"; break; case 'privateMessage': /* $data['id'] The ID of the user that just left. $data['message'] The message sent to you as a PM */ echo "[PM] ".((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) -> $data[message]\n"; //Example of a private message command $command = explode(' ',$data['message'],2); //First parse the first word out see if it is a command... //[0] has first word [1] has everything else if($command[0]{0}=='!'){//I am use ! as the character to signify a command, so check if the first character is right. switch($command[0]) { case '!say': case '!speak': case '!talk': $this->sendPrivateMessage($command[1],$data['id']); break; case '!info': $this->sendPrivateMessage('I am a bot ^_^',$data['id']); break; } } break; case 'privateChat': /* $data['id'] The ID of the user that just left. $data['message'] The message sent to you as a PC */ echo "[PC] ".((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) -> $data[message]\n"; //Example of a private chat command $command = explode(' ',$data['message'],2); //First parse the first word out see if it is a command... //[0] has first word [1] has everything else if($command[0]{0}=='!'){//I am use ! as the character to signify a command, so check if the first character is right. switch($command[0]) { case '!info': $this->sendPrivateChat('I am a bot ^_^',$data['id']); break; } } break; case 'message': /* $data['id'] The ID of the user $data['old'] See $data['old'] under userJoined $data['message'] The message sent to main chat */ echo ((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])."($info[rank]) -> $data[message]\n"; //How to do main chat commands: if($data['old']) return; //Old message $command = explode(' ',trim($data['message']),2); //First parse the first word out see if it is a command... //[0] has first word [1] has everything else if($command[0]{0}=='!'){//I am use ! as the character to signify a command, so check if the first character is right. switch($command[0]) { case '!say': case '!speak': case '!talk': //Multiple cases lead to the same code being run... $this->sendMessage($command[1]); break; case '!slap': case '!slaps': case '!hit': $this->sendMessage(((trim($info['registeredName'])!='')?$info['registeredName']:$info['name'])." slaps $command[1] around a bit with a large trout."); break; case '!avatar'://steal an avatar via !avatar USER_ID $user = $this->getUserArray($command[1]); $this->sendMessage(str_replace('(','( ',$user['avatar'])); break; case '!info': $this->sendMessage('I am a bot ^_^',$data['id']); break; case '!yt': case '!youtube': case '!y': if(trim($command[1])=='') $this->sendMessage("Usage: $command[0] SEARCH TERMS HERE"); else { //Yeah I know I don't really need urlencode() i could just replace spaces with + but this is a bit more secure. $res = $this->get('http://www.youtube.com/results?search_query='.urlencode(preg_replace("/[^A-Za-z0-9 !.,:[]\s\s+]/",'',$command[1]))); for($i=0;$i<3;$i++) { $msg=$this->getBetween($res, '

', '

'); $res = str_replace('

'.$msg,'

',$res); $url = "http://www.youtube.com".$this->getBetween($msg,'href="', '"'); $title = @ereg_replace('[^A-Za-z0-9 -()[]<>{}&@]','',$this->getBetween($msg,'title="', '"')); $this->sendMessage($title." - $url"); sleep(1);//Xat won't let us send more than 1 message per second, it ignores anything faster. } } break; case '!g': case '!google': $res = $this->get('http://www.google.com/search?hl=en&source=hp&biw=&bih=&q='.str_replace(' ','+',$command[1]).'&btnG=Google+Search',true); for($i=0;$i<3;$i++) { $msg=$this->getBetween($res, '

soc) * @param $message The packet to send. */ function send($message) { if($this->debug)echo "->>\t$message\n"; socket_write($this->soc, $message."\0", strlen($message)+1); } /** * Reads a message from the socket, will read until entire message has been recieved or connection closes. * @param $parse Used for recursive calls to tell the function not to parse a partial packet */ function read($parse=true) { $res = rtrim(socket_read($this->soc, 4096)); if($this->debug)echo "<<-\t$res\n"; if(!$res) { return "DIED"; //Used to gracefully handle a closed socket } if($res{strlen($res)-1}!='>') { $res.=$this->read(false);} //Recursive call for messages split over several packets. if($parse)$this->parse($res); return $res; } /** * Parses the recieved packets into their message and types. * @param $packet The packet recieved. */ function parse($packet) { if(substr_count($packet,'>')>1) $packet = explode('/>',$packet);//If necessary split the packet into individual messages foreach((Array)$packet as $p) { $p = trim($p); if(strlen($p)<5) return;//garbage data $type = trim(strtolower(substr($p,1,strpos($p.' ',' '))));//packet type $p = trim(str_replace("<$type",'',str_replace('/>','',$p)));//remove details so it is just the info to be parsed parse_str(str_replace('"','',str_replace('" ','&',str_replace('="','=',str_replace('&','__38',$p)))),$this->packet[$type]); foreach($this->packet[$type] as $k=>$v) { $this->packet[$type][$k] = str_replace('__38','&',$v); //htmlspecial chars are protected instead of being parsed } $this->handle($type,$p); } } /** * This is the inital handler for the packets, parses them and sends them off to their respective function to be handled further. * @param $type The character code indicating the type of data within the message. * @param $message The data the message contains. */ function handle($type,$msg) { switch($type) { case 'gp': if(isset($this->packet['gp']['x'])) $this->send(''); //Handle groups break; case 'q'://XAT notice to change ip/port $this->connect($this->packet['q']['d'], $this->packet['q']['p']); $this->join($this->roomID); break; case 'o': $this->packet['o']['u'] = $this->parseU(@$this->packet['u']['u']); $this->userInfo[$this->packet['o']['u']]['name'] = @$this->packet['o']['n']; $this->userInfo[$this->packet['o']['u']]['registeredName'] = ((isset($this->packet['o']['N']))?$this->packet['o']['N']:''); $this->userInfo[$this->packet['o']['u']]['avatar'] = @$this->packet['o']['a']; $this->userInfo[$this->packet['o']['u']]['homepage'] = @$this->packet['o']['h']; $this->userInfo[$this->packet['o']['u']]['rank'] = $this->f2rank(@$this->packet['o']['f']); break; case 'u': //Joined //Default Bot stuff regarding userInformation $this->packet['u']['u'] = $this->parseU(@$this->packet['u']['u']); $this->userInfo[$this->packet['u']['u']]['name'] = @$this->packet['u']['n']; $this->userInfo[$this->packet['u']['u']]['registeredName'] = ((isset($this->packet['u']['N']))?$this->packet['u']['N']:''); $this->userInfo[$this->packet['u']['u']]['avatar'] = @$this->packet['u']['a']; $this->userInfo[$this->packet['u']['u']]['homepage'] = @$this->packet['u']['h']; $this->userInfo[$this->packet['u']['u']]['rank'] = $this->f2rank(@$this->packet['u']['f']); $event = 'userJoined'; $data['id'] = $this->packet['u']['u']; $data['old'] = ($type=='o'||(isset($this->packet['u']['s']))?true:false); $this->handleEvent($event,$data); break; case 'l': //User Left or was kicked, banned unset($this->userInfo[$this->packet['l']['u']]); $event = 'userLeft'; $data['id'] = $this->packet['l']['u']; $this->handleEvent($event,$data); break; case 'p': //Private message/chat recieved $event = ((isset($this->packet['p']['d']))?'privateChat':'privateMessage'); $data['id'] = $this->parseU(@$this->packet['p']['u']); $data['message'] = $this->packet['p']['t']; $this->handleEvent($event,$data); break; case 'm': //message to main chat. $event = 'message'; $data['id'] = $this->parseU(@$this->packet['m']['u']); $data['message'] = $this->packet['m']['t']; $data['old'] = ((isset($this->packet['m']['s']))?true:false); $this->handleEvent($event,$data); break; } } /** * Joins a room. * @param $roomID the numeric roomID to join. */ function join($roomID) { //Announce we are here: $this->send('');//Anounces our arrival to the server and gets some information to send back $this->read(); //Auto parsed into $this->packet['y'] $this->send(''); $this->roomID = $roomID; } /** * Parses the u value from a packet to get just the id * @param $id the id to be parsed. */ function parseU($id) { if(substr_count($id,'_')>=1) $id = substr($id,0,strpos($id,'_')); return $id; } /** * 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. * @param $f The f value to be parsed. */ function f2rank($f) { $f = $this->parseU($f); if($f==-1) return 'guest'; //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 //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 //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. if((16 & $f)) return 'banned'; if((1 & $f)&&(2 & $f)) return 'member'; if((4 & $f)) return 'owner'; if((32 & $f)&&(1 & $f)&&!(2 & $f)) return 'main'; if(!(1 & $f)&&!(2 & $f)) return 'guest'; if((16 & $f)) return 'banned'; if((2 & $f)&&!(1 & $f)) return 'mod'; } /** * Returns an assoc array of information regarding the user with the given id * @param $id The user id you want information on. */ function getUserArray($id) { $id = $this->parseU($id); if(isset($this->userInfo[$id])) { return $this->userInfo[$id]; } else return false; } /** * Sends the given message to the main chat * @param $message */ function sendMessage($message) { if(empty($message))return; $this->send(''); } /** * Sends a PC to the given ID * @param $message The message to send. * @param $id The id to send the message to */ function sendPrivateChat($message, $id) { if(empty($message))return; $this->send('

'); } /** * Sends a PM to the given ID * @param $message The message to send. * @param $id The id to send the message to */ function sendPrivateMessage($message,$id) { $id = $this->parseU($id); if(empty($message))return; $this->send('

'); } /** * Makes the given $id an owner, assuming the bot is main * @param $id The id to promote */ function mod($id) { $this->send(''); } /** * Makes the given $id a mod, assuming the bot is owner * @param $id The id to promote */ function owner($id) { $this->send(''); } /** * Makes the given $id a member, assuming the bot is mod * @param $id The id to member */ function member($id) { $this->send(''); } /** * KIcks the given ID assuming the bot is a mod and $id is a member or less * @param $id The id to kick */ function kick($message, $id) { $this->send(''); } /** * Bans the ID for a given time(0 is forever) * @param $id The id to ban */ function ban($message, $id, $time) { if(empty($time)) $time = 3600; $this->send(''); } /** * Unbans the given ID * @param $id The id to unban */ function unban($id) { $this->send(''); } /** * Performs a basic HTTP GET to the given URL * @param $url The url to retrieve, please include http:// and www if necessary * @param $includeHeader Tells teh function wether or not to include the server header respond before the main content */ function get($url, $includeHeader=false) { $urlp = parse_url($url); $fp = fsockopen($urlp['host'],80); $path = explode('/',$url,4); $path = ((count($path)>=4)?$path[3]:""); $req = "GET /$path HTTP/1.1\r\n"; $req .= "Host: $urlp[host]\r\n"; $req .= "Connection: Close\r\n\r\n"; fputs($fp, $req); $res = ""; while(!feof($fp)) $res .= fgets($fp, 4096); fclose($fp); if($includeHeader) return $res; $res = explode("\r\n\r\n",$res,2); return $res[1]; } /** * A utility function to get all text beween $start and $end * @param $content The content from which we are grabbing data * @param $start where to start grabbing from * @param $end the end of the content to grab */ function getBetween($content,$start,$end){ $r = explode($start, $content); if (isset($r[1])){ $r = explode($end, $r[1]); return $r[0]; } return ''; } } ?>