-op/deop/voice/devoice/kick users
-set channel topic/mode
-google searches
-weather checks for US zip codes
-magic 8ball
-get bash.org quotes
-add/view user submitted quotes
-give current time of a given time zone
-read a file to a channel in the style of a lecture
-various encryption - base64/rot13/md5
-Controls user control by names in a database
I know its a bit bigger than just a code snippet - but i thought some people may find it useful or simply just interesting. Hope you enjoy!!
Also maybe some people could give me some types on refining my code, or faster methods to do things etc etc. just general "heres how you can improve you coding" types of comments. Thanks

The class - ak_bot.php
Code: Select all
<?php
###################################################################################################
##
## Ak-Bot Class
## A class to control an IRC bot
##
###################################################################################################
class AK_Bot {
var $fp;
var $lfp;
var $rfp;
var $rawdata;
var $data;
var $log;
var $lecture;
var $lecture_pause;
var $botnick;
var $botpassword;
var $botident;
var $botrealname;
var $localhost;
var $quit_message;
var $serveraddress;
var $serverport;
var $serverchannel;
var $database_host;
var $database_user;
var $database_password;
var $database_name;
##--------------------------------------------
##CLASS CONSTRUCTOR
##--------------------------------------------
function AK_Bot($bot){
$this->log = $bot[log];
$this->rfp = NULL;
$this->botnick = $bot[botnick];
$this->botpassword = $bot[botpassword];
$this->botident = $bot[botident];
$this->botrealname = $bot[botrealname];
$this->localhost = $bot[localhost];
$this->serveraddress = $bot[serveraddress];
$this->serverport = $bot[serverport];
$this->serverchannel = $bot[serverchannel];
$this->database_host = $bot[database_host];
$this->database_user = $bot[database_user];
$this->database_password = $bot[database_password];
$this->database_name = $bot[database_name];
$this->version_message = "Ak-Bot Version 1.0 - Written by greybird - 2004 - startx@aknetwork.org";
set_time_limit(0); #sets the timeout limit of the script
#connects to the database
$this->database_connect();
#handles the connection
$this->connect();
}
##--------------------------------------------
##DATABASE CONNECT FUNCTION
##Connects the bot to the database
##--------------------------------------------
function database_connect(){
$db = mysql_connect($this->database_host, $this->database_user, $this->database_password);
mysql_select_db($this->database_name, $db);
}
##--------------------------------------------
##CONNECT FUNCTION
##Connects the bot to the server
##--------------------------------------------
function connect(){
$this->fp = fsockopen($this->serveraddress,$this->serverport, &$err_num, &$err_msg, 30);
if (!$this->fp){
echo "There was an error in connecting to ".$this->serveraddress;
exit;
}else{
$this->send("PASS ".$this->botpassword);
$this->send("NICK ".$this->botnick);
$this->send("USER ".$this->botident.' '.$this->localhost.' '.$this->serveraddress.' :'.$this->botrealname);
$this->send("JOIN ".$this->serverchannel);
echo "Connected to ".$this->serveraddress." as ".$this->botnick."<br>";
$this->receive();
}
}
##--------------------------------------------
##DISCONNECT FUNCTION
##Disconnects the bot from the server
##--------------------------------------------
function disconnect(){
$this->send("QUIT :".$this->version_message);
fclose($this->fp);
fclose($this->lfp);
exit();
}
##--------------------------------------------
##RECEIVE FUNCTION
##Receives all data from connection
##--------------------------------------------
function receive(){
while (!feof($this->fp)){
$this->rawdata = fgets($this->fp, 1024);
$this->rawdata = str_replace("\r", "", str_replace("\n", "", $this->rawdata));
#process the data just sent
$this->process_data();
#parse the data just sent
$this->parse_data();
#logs the data if needed
if($this->log){
$this->logging();
}
if($this->rfp AND $this->lecture_pause<>1){
$this->lecture();
}
}
$this->disconnect();
}
##--------------------------------------------
##PROCESS DATA FUNCTION
##Processes the data sent into an array or useful items
##--------------------------------------------
function process_data(){
#Splits the data into what we want
$params = explode(" ", $this->rawdata);
$user = str_replace(":", "", $from[0]);
$details = explode ("@", $from[1]);
$message = str_replace("$params[0]", "", $this->rawdata);
$message = str_replace("$params[1]", "", $message);
$message = str_replace("$params[2]", "", $message);
$from = explode ("!", $params[0]);
#stores the data in an array
$this->data[from] = str_replace(":", "", $from[0]);
$this->data[ident] = $details[0];
$this->data[host] = $details[1];
$this->data[action] = $params[1];
$this->data[sent_to] = $params[2];
$this->data[message] = substr($message, 4);
$this->data[ping] = $params[0];
if($this->data[message][0] == "!"){
$maction = explode(" ", $this->data[message]);
$mfullaction = str_replace($maction[0], "", $this->data[message]);
$this->data[action] = "TRUE";
$this->data[message_action] = $maction[0];
$this->data[message_target] = $maction[1];
$this->data[message_target2] = $maction[2];
$this->data[message_action_text] = str_replace(" ", "%20", substr($mfullaction, 1));
$this->data[message_action_text_plain] = str_replace("%20", " ", $this->data[message_action_text]);
$this->data[message_action_text_plain_with_params] = substr(str_replace($maction[0], "", str_replace($maction[1], "", $mfullaction)), 2);
}
}
##--------------------------------------------
##LOGGING FUNCTION
##Logs the data
##--------------------------------------------
function logging(){
if(!$this->lfp){ #file not open
$this->lfp = fopen('log.txt', 'w');
}
$time = date('d/m/Y-H:i');
fputs($this->lfp, $time." - ".$this->rawdata."\n");
}
##--------------------------------------------
##PARSE DATA FUNCTION
##Parses the data that was just sent - i.e. checks for messages and does them
##--------------------------------------------
function parse_data(){
if($this->data[sent_to]==$this->serverchannel AND $this->data[action] == 'TRUE'){
switch($this->data[message_action]){
case '!addquote':
case '!op':
case '!deop':
case '!voice':
case '!devoice':
case '!kick':
case '!ban':
case '!topic':
case '!mode':
case '!adduser':
case '!lecture':
case '!quit':
$this->admin_option();
break;
case '!google':
$this->google();
break;
case '!time':
$this->time();
break;
case '!8ball':
$this->ball8();
break;
case '!userlevel':
$this->my_user_level();
break;
case '!quote':
$this->quote();
break;
case '!base64':
$this->base64();
break;
case '!md5':
$this->md5();
break;
case '!rot13':
$this->rot13();
break;
case '!weather':
$this->weather();
break;
case '!version':
$this->version();
break;
case '!help':
$this->help();
break;
}
}
if($this->data[ping] == 'PING'){
$this->send("PONG");
}
}
##--------------------------------------------
##USER LEVEL FUNCTION
##Checks to see if the user is logged in and returns their user level
##--------------------------------------------
function user_level(){
$codes = array('is a registered nick',
'is an identified user',
'is a registered and identified nick',
'has identified for this nick'
);
$this->send("WHOIS ".$this->data[from]);
#sees if user us registered
for ($i=0; $i<5;$i++){
$response = fgets($this->fp, 1024);
foreach($codes as $code){
if(substr_count($response, $code)){
$registered = 1;
$i=5;
}
}
}
#checks for user level in database
if($registered){
$result = mysql_query("SELECT level FROM access WHERE user = '".$this->data[from]."' AND channel = '".$this->serverchannel."' AND server = '".$this->serveraddress."'");
while($row = mysql_fetch_assoc($result)){
$level = $row['level'];
}
if(!$level){
$level = 0;
}
}else{
$level = 0;
}
return $level;
}
##--------------------------------------------
##SEND FUNCTION
##Sends any data to the server
##--------------------------------------------
function send($data){
echo "<strong><font color="#FF0000">".$data."</font></strong><br>";
fputs($this->fp, $data."\r\n");
}
##--------------------------------------------
##NOT ALLOWED FUNCTION
##Sends notive to user saying they dont have the correcnt privs
##--------------------------------------------
function not_allowed($level){
$this->send("NOTICE ".$this->data[from]." :You must be a level ".$level." user to use this command.");
}
##--------------------------------------------
##ADMIN OPTION FUNCTION
##Controls the admin options
##--------------------------------------------
function admin_option(){
$user_level = $this->user_level();
if(!$this->data[message_target]){
$user = $this->data[from];
}else{
$user = $this->data[message_target];
}
switch($this->data[message_action]){
case '!addquote':
if($user_level>=1){
$time = time();
mysql_query("INSERT INTO quote (added_by, quote, time_posted) VALUES ('".$this->data[from]."', '".$this->data[message_action_text_plain]."', '$time')");
$this->send("NOTICE ".$this->data[from]." :Your quote was successfully added.");
}else{
$this->not_allowed('1');
}
break;
case '!op':
if($user_level>=5){
$message = "MODE ".$this->data[sent_to]." +o $user";
}else{
$this->not_allowed('5');
}
break;
case '!deop':
if($user_level>=5){
$message = "MODE ".$this->data[sent_to]." -o $user";
}else{
$this->not_allowed('5');
}
break;
case '!voice':
if($user_level>=3){
$message = "MODE ".$this->data[sent_to]." +v $user";
}else{
$this->not_allowed('3');
}
break;
case '!devoice':
if($user_level>=3){
$message = "MODE ".$this->data[sent_to]." -v $user";
}else{
$this->not_allowed('3');
}
break;
case '!kick':
if($user_level>=5){
if($this->data[message_target]<>$this->botnick){
$message = "KICK ".$this->data[sent_to]." ".$this->data[message_target]." :".str_replace($this->data[message_target]." ", '', $this->data[message_action_text_plain]);
}else{
$message = "KICK ".$this->data[sent_to]." ".$this->data[from]." :Now that was a mistake...wasnt it?";
}
}else{
$this->not_allowed('5');
}
break;
case '!topic':
if($user_level>=5){
$message = "TOPIC ".$this->data[sent_to]." :".$this->data[message_action_text_plain];
}else{
$this->not_allowed('5');
}
break;
case '!mode':
if($user_level>=5){
$message = "MODE ".$this->data[sent_to]." ".$this->data[message_action_text_plain];
}else{
$this->not_allowed('5');
}
break;
case '!adduser':
if($user_level>=2){
$this->add_user($user_level);
}else{
$this->not_allowed('2');
}
break;
case '!lecture':
if($user_level>=5){
if(strtolower($this->data[message_target]) == 'pause'){
$this->lecture_pause = 1;
$this->send("NOTICE ".$this->data[from]." :Lecture Successfully Paused.");
}else if(strtolower($this->data[message_target]) == 'stop'){
fclose($this->rfp);
$this->lecture_pause = 1;
$this->rfp = NULL;
$this->send("NOTICE ".$this->data[from]." :Lecture Successfully Stopped.");
}else if(strtolower($this->data[message_target]) == 'start'){
$this->lecture_pause = 0;
$this->send("NOTICE ".$this->data[from]." :Lecture Successfully Started.");
}else{
#opens the file if needed
if($this->rfp == NULL){
$this->lecture_pause = 0;
$this->rfp = fopen($this->data[message_target], 'r');
$this->send("NOTICE ".$this->data[from]." :Lecture Successfully Started.");
}else{
$this->send("NOTICE ".$this->data[from]." :An error occured when trying to start the lecture.");
}
}
}else{
$this->not_allowed('5');
}
break;
case '!quit':
if($user_level>=9){
$this->disconnect();
}else{
$this->not_allowed('9');
}
break;
}
$this->send($message);
}
##--------------------------------------------
##ADD USER FUNCTION
##Adds a user to the bot access list
##--------------------------------------------
function add_user($user_level){
$result = mysql_query("SELECT count(user) FROM access WHERE user = '".$this->data[message_target]."' AND channel = '".$this->serverchannel."' AND server = '".$this->serveraddress."'");
while($row = mysql_fetch_assoc($result)){
$add = $row['count(user)'];
}
if($this->data[message_target2]>=$user_level){ #cant add a user level higher or equal to yours
$this->send("NOTICE ".$this->data[from]." :You can only add a user to a lower access level than your own");
}else{
if($add){ #modify user level
mysql_query("UPDATE access SET level = '".$this->data[message_target2]."' WHERE user = '".$this->data[message_target]."' AND channel = '".$this->serverchannel."' AND server = '".$this->serveraddress."'");
$this->send("NOTICE ".$this->data[from]." :".$this->data[message_target]."'s user access level has been successfully changed to level ".$this->data[message_target2]);
}else{ #add new user
mysql_query("INSERT INTO access (user, level, channel, server) VALUES ('".$this->data[message_target]."', '".$this->data[message_target2]."', '".$this->serverchannel."', '".$this->serveraddress."')");
$this->send("NOTICE ".$this->data[from]." :You have successfully added ".$this->data[message_target]." at level ".$this->data[message_target2]);
}
}
}
##--------------------------------------------
##GOOGLE FUNCTION
##Controls the google search function
##--------------------------------------------
function google(){
if($this->data[message_action_text]){
$address = "http://www.google.com/search?hl=en&ie=UTF-8&oe=UTF-8&q=".$this->data[message_action_text];
$gfp = fopen($address, "r");
while (!feof($gfp) AND $STOP<>'TRUE'){
$gdata .= fgets($gfp, 1024);
if(strstr($gdata, "<font color=#008000>")){
$pos = strpos($gdata, "<font color=#008000>");
$gdata = substr($gdata, $pos+20);
$pos = strpos($gdata, " - ");
$gdata = substr($gdata, 0, $pos);
$STOP = 'TRUE';
}
}
fclose($gfp);
if($STOP<>'TRUE' OR $gdata == ""){
$this->send("PRIVMSG ".$this->data[sent_to]." :".$this->data[from].": There were no results for: "".$this->data[message_action_text_plain].""");
}else{
if(!ereg("^(http|https)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?/?([a-zA-Z0-9\-\._\?\,''/\\\+&%\$#\=~])*$", $gdata)){
$gdata = "http://".$gdata;
}
$this->send("PRIVMSG ".$this->data[sent_to]." :".$this->data[from].": Result For: "".$this->data[message_action_text_plain]."" - $gdata");
}
}else{
$this->send("NOTICE ".$this->data[from]." :Usage: !google <search phrase/word>");
}
}
##--------------------------------------------
##TIME FUNCTION
##Shows the current time
##--------------------------------------------
function time(){
$time = time();
$hour = substr($this->data[message_target], 1);
if($this->data[message_target][0] == '+'){ #is a plus
$time += $hour*60*60;
}else if($this->data[message_target][0] == '-'){ #is a minus
$time -= $hour*60*60;
}else{
$time += $this->data[message_target]*60*60;
}
if($hour>12 OR $this->data[message_target]>12 OR !is_numeric($this->data[message_target]) OR !is_numeric($hour)){
$time = time();
}
$this->send("NOTICE ".$this->data[from]." :The current time is ".date('G:i', $time));
}
##--------------------------------------------
##BALL8 FUNCTION
##A magic 8-ball function
##--------------------------------------------
function ball8(){
$words = array('Yes', 'No', 'Dont Count On It', 'For Sure', 'Of Course', 'Doubtful', 'Dont Be Stupid', 'Why You Asking Me...Just Leave Me Alone', 'Yes...Its In The Stars', 'Hmmmm', 'Sorry Im Away Right Now...Try Again Later', 'Dont Make Me Laugh you Muppit!!');
if($this->data[message_target]){
$num = rand(0, (count($words)-1));
$this->send("PRIVMSG ".$this->data[sent_to]." :".$this->data[from]." - $words[$num]");
}else{
$this->send("NOTICE ".$this->data[from]." :Usage: !8ball <question>");
}
}
##--------------------------------------------
##MY USER LEVEL FUNCTION
##Sends you your user level
##--------------------------------------------
function my_user_level(){
$this->send("NOTICE ".$this->data[from]." :Your user level is: ".$this->user_level());
}
##--------------------------------------------
##QUOTE FUNCTION
##Displays a quote to the user from the database
##--------------------------------------------
function quote(){
switch($this->data[message_target]){
case 'bash':
$address = "http://www.bash.org/?random";
$bfp = fopen($address, "r");
while (!feof($bfp) AND $STOP<>'TRUE'){
$bdata .= fgets($bfp, 1024);
if(strstr($bdata, '<p class="qt">')){
$pos = strpos($bdata, '<p class="qt">');
$STOP = 'TRUE';
}
}
fseek($bfp, $pos);
$data = fread($bfp, 5024);
$data = ereg_replace("<br />", " ", $data);
$data = ereg_replace("<", "<", $data);
$data = ereg_replace(">", ">", $data);
$data = ereg_replace("\n", "", $data);
$data = ereg_replace("\r", "", $data);
$data = html_entity_decode($data);
$pos = strpos($data, '</p>');
$quote = substr($data, 0, $pos);
fclose($bfp);
break;
case 'user':
$result = mysql_query("SELECT quote FROM quote WHERE quote LIKE '%".$this->data[message_target2]."%' ORDER BY rand() LIMIT 0,1");
while($row = mysql_fetch_assoc($result)){
$quote = $row[quote];
}
break;
case 'from':
$result = mysql_query("SELECT quote FROM quote WHERE added_by = '".$this->data[message_target2]."' ORDER BY rand() LIMIT 0,1");
while($row = mysql_fetch_assoc($result)){
$quote = $row[quote];
}
break;
case 'last':
$result = mysql_query("SELECT quote FROM quote ORDER BY time_posted DESC LIMIT 0,1");
while($row = mysql_fetch_assoc($result)){
$quote = $row[quote];
}
break;
case 'number':
$result = mysql_query("SELECT quote FROM quote WHERE id = '".$this->data[message_target2]."'");
while($row = mysql_fetch_assoc($result)){
$quote = $row[quote];
}
break;
case 'random':
$result = mysql_query("SELECT quote FROM quote ORDER BY rand() LIMIT 0,1");
while($row = mysql_fetch_assoc($result)){
$quote = $row[quote];
}
break;
default:
$quote = "Usage: !quote <bash|user|from|last|number|random> <value> (note bash, last and random require no <value>)";
}
if($quote == ''){
$quote = "No Quote Found.";
}
$this->send("NOTICE ".$this->data[from]." :$quote");
}
##--------------------------------------------
##LECTURE FUNCTION
##Reads a lecture file - special format file
##starts reading from <lecture> and stops at </lecture>
##--------------------------------------------
function lecture(){
$line = fgets($this->rfp, 1024);
$this->send("PRIVMSG ".$this->serverchannel." :$line");
sleep(4);
if(feof($this->rfp)){
$this->rfp = NULL;
}
}
##--------------------------------------------
##BASE64 FUNCTION
##Converts text to and from base64
##--------------------------------------------
function base64(){
if(strtolower($this->data[message_target]) == 'encode'){ #encode to base64
$value = base64_encode($this->data[message_action_text_plain_with_params]);
}else if(strtolower($this->data[message_target]) == 'decode'){ #decode
$value = base64_decode($this->data[message_action_text_plain_with_params]);
}else{ #send usage method
$value = "Usage: !base64 <encode|decode> <message to encode/decode>";
}
$this->send("NOTICE ".$this->data[from]." :$value");
}
##--------------------------------------------
##MD5 FUNCTION
##Converts text to md5 checksum - one way encryption
##--------------------------------------------
function md5(){
if($this->data[message_action_text_plain]){
$value = md5($this->data[message_action_text_plain]);
}else{
$value = "Usage: !md5 <plaintext>";
}
$this->send("NOTICE ".$this->data[from]." :$value");
}
##--------------------------------------------
##ROT13 FUNCTION
##Converts text to and from rot13
##--------------------------------------------
function rot13(){
if($this->data[message_action_text_plain]){
$value = str_rot13($this->data[message_action_text_plain]);
}else{
$value = "Usage: !rot13 <message>";
}
$this->send("NOTICE ".$this->data[from]." :$value");
}
##--------------------------------------------
##WEATHER FUNCTION
##Shows weather information for a certain zip code
##--------------------------------------------
function weather(){
if($this->data[message_target]){
$address = "http://xoap.weather.com/weather/local/".$this->data[message_target]."?cc=*&prod=xoap&par=1004186241&key=954a7d234c6d5281";
$wfp = fopen($address, "r");
while (!feof($wfp)){
$wdata .= fgets($wfp, 1024);
}
#xml parser stuff
$p = xml_parser_create();
xml_parse_into_struct($p, $wdata, $vals, $index);
xml_parser_free($p);
if($vals[1][value] == "Invalid location provided."){
$value = "The zip code was invalid.";
}else{
$value = "Current weather for ".$vals[27][value]." - Local Time: ".$vals[30][value]." - Current Temperature: ".$vals[58][value]."°F, Feels Like: ".$vals[61][value]."°F - Condition: ".$vals[64][value]." - Pressure: ".$vals[71][value]." Inches - Wind: ".$vals[90][value]." ".$vals[81][value]."MPH - Humidity: ".$vals[96][value]."% - Visibility(miles): ".$vals[99][value]." - UV Index: ".$vals[103][value]."/".$vals[106][value]." - Dew Point: ".$vals[112][value]."°F";
}
}else{
$value = "Usage: !weather <zip code>";
}
$this->send("NOTICE ".$this->data[from]." :$value");
}
##--------------------------------------------
##VERSION FUNCTION
##Shows bot version info
##--------------------------------------------
function version(){
$this->send("NOTICE ".$this->data[from]." :".$this->version_message);
}
##--------------------------------------------
##HELP FUNCTION
##Displays help messages
##--------------------------------------------
function help(){
if(!$this->data[message_target]){ #show main help
$this->send("PRIVMSG ".$this->data[from]." :Help File For ".$this->botnick);
$this->send("PRIVMSG ".$this->data[from]." :------------------------------");
$this->send("PRIVMSG ".$this->data[from]." : ");
$this->send("PRIVMSG ".$this->data[from]." : !op <nick>");
$this->send("PRIVMSG ".$this->data[from]." : !deop <nick>");
$this->send("PRIVMSG ".$this->data[from]." : !voice <nick>");
$this->send("PRIVMSG ".$this->data[from]." : !devoice <nick>");
$this->send("PRIVMSG ".$this->data[from]." : !kick <nick>");
$this->send("PRIVMSG ".$this->data[from]." : !mode <+/- mode>");
$this->send("PRIVMSG ".$this->data[from]." : !topic <topic>");
$this->send("PRIVMSG ".$this->data[from]." : !addquote <quote>");
$this->send("PRIVMSG ".$this->data[from]." : !adduser <nick> <userlevel>");
$this->send("PRIVMSG ".$this->data[from]." : !lecture <filename/pause/stop/start>");
$this->send("PRIVMSG ".$this->data[from]." : !quit");
$this->send("PRIVMSG ".$this->data[from]." : !google <search word?");
$this->send("PRIVMSG ".$this->data[from]." : !time <+/- time zone>");
$this->send("PRIVMSG ".$this->data[from]." : !8ball <question>");
$this->send("PRIVMSG ".$this->data[from]." : !userlevel");
$this->send("PRIVMSG ".$this->data[from]." : !quote <bash|user|from|last|number|random> <value> (note bash, last and random require no <value>)");
$this->send("PRIVMSG ".$this->data[from]." : !base64 <encode|decode> <message to encode/decode>");
$this->send("PRIVMSG ".$this->data[from]." : !md5 <plaintext>");
$this->send("PRIVMSG ".$this->data[from]." : !rot13 <message>");
$this->send("PRIVMSG ".$this->data[from]." : !weather <zip code>");
$this->send("PRIVMSG ".$this->data[from]." : !version");
$this->send("PRIVMSG ".$this->data[from]." : !help");
}else{
}
}
}
?>
Heres the code to call the bot class:
bot.php
Code: Select all
<?php
include("ak_bot.php");
$bot[log] = 1;
$bot[botnick] = "Ak-Void";
$bot[botpassword] = "password";
$bot[botident] = "Ak-Void";
$bot[botrealname] = "Advanced Knowledge Void";
$bot[localhost] = "localhost";
$bot[serveraddress] = "irc.server.com";
$bot[serverport] = "6667";
$bot[serverchannel] = "#macwhore";
$bot[database_host] = "localhost";
$bot[database_user] = "user";
$bot[database_password] = "thisismypassword";
$bot[database_name] = "akbot";
$mybot = new AK_Bot($bot);
?>
Code: Select all
#holds access details to the bots controls
CREATE TABLE access (
user varchar(20) NOT NULL,
level tinyint(1) NOT NULL DEFAULT '1',
channel varchar(255) NOT NULL,
server varchar(255) NOT NULL
);
#holds quotes
CREATE TABLE quote (
id int(8) NOT NULL AUTO_INCREMENT,
added_by varchar(20) NOT NULL,
quote text NOT NULL,
time_posted int(10) NOT NULL,
PRIMARY KEY(id)
);