×
Create a new article
Write your page title here:
We currently have 3,189 articles on s23. Type your article name above or create one of the articles listed here!



    s23
    3,189Articles
    in:
    Revision as of 12:28, 4 February 2008 by 213.148.146.105 (talk) (small spelling change)

    A PHP IRC bot based on the CodeDemons PHP IRC bot skeleton with a few extra functions like MD5 sum forward and reverse and rudimentary Wikipedia and Wiktionary lookup.

    <HighlightSyntax>

    1. !/usr/bin/php

    <?php /* edgar, the php IRC bot, has its skeleton from demonbot, a demonstration from codedemons.net own functions added and changed by mutante of s23.org

    • /

    /* Variables that determine server, channel, etc */ $CONFIG = array(); $CONFIG['server'] = 'irc.daxnet.no'; // server (i.e. irc.gamesnet.net) $CONFIG['nick'] = 'Edgar23'; // nick (i.e. demonbot $CONFIG['port'] = 6667; // port (standard: 6667) $CONFIG['channel0'] = '#s23'; // channel (i.e. #php) $CONFIG['channel1'] = '#seti23'; $CONFIG['channel2'] = '#bots'; $CONFIG['channel3'] = '#wiki'; $CONFIG['channel4'] = '#yoga'; $CONFIG['channel5'] = '#shrooms'; $CONFIG['name'] = 'Edgar Alice Pope'; // bot name (i.e. demonbot) $CONFIG['admin_pass'] = 'FnordFoobar'; // admin pass (to change settings remotely) $CONFIG['myident'] = 'mutante'; $CONFIG['myhost'] = 's23.org';

    /* Let it run forever (no timeouts) */ set_time_limit(0);

    /* The connection */ $con = array();

    /* start the bot... */ init();

    function init() {

       global $con, $CONFIG;
       /* We need this to see if we need to JOIN (the channel) during
       the first iteration of the main loop */
       $firstTime = true;
       
       /* Connect to the irc server */
       $con['socket'] = fsockopen($CONFIG['server'], $CONFIG['port']);
       
       /* Check that we have connected */
       if (!$con['socket']) {
           print ("Could not connect to: ". $CONFIG['server'] ." on port ". $CONFIG['port']);
       } else {
           /* Send the username and nick */
       
               cmd_send("USER ". $CONFIG['name'] ." ".$CONFIG['myident']." ".$CONFIG['myhost']." ".$CONFIG['server']." :".$CONFIG['nick']);
           cmd_send("NICK ". $CONFIG['nick']);
                   
           /* Here is the loop. Read the incoming data (from the socket connection) */
           while (!feof($con['socket']))
           {
               /* Think of $con['buffer']['all'] as a line of chat messages.
               We are getting a 'line' and getting rid of whitespace around it. */
               $con['buffer']['all'] = trim(fgets($con['socket'], 4096));
               
               /* Pring the line/buffer to the console
               I used <- to identify incoming data, -> for outgoing. This is so that
               you can identify messages that appear in the console. */
               print date("[d/m @ H:i]")."<- ".$con['buffer']['all'] ."\n";
               
               /* If the server is PINGing, then PONG. This is to tell the server that
               we are still here, and have not lost the connection */
                       
                   if(substr($con['buffer']['all'], 0, 6) == 'PING :') {
                   /* PONG : is followed by the line that the server
                   sent us when PINGing */
                   cmd_send('PONG :'.substr($con['buffer']['all'], 6));
                   }
                   
                   /* If this is the first time we have reached this point,
                   then JOIN the channel */
                   if ($firstTime == true){
                       cmd_send("JOIN ". $CONFIG['channel0']);
                       cmd_send("JOIN ". $CONFIG['channel1']);
                       cmd_send("JOIN ". $CONFIG['channel2']);
                       cmd_send("JOIN ". $CONFIG['channel3']);
                       cmd_send("JOIN ". $CONFIG['channel4']);
                           cmd_send("JOIN ". $CONFIG['channel5']);
                       /* The next time we get here, it will NOT be the firstTime */
                       $firstTime = false;
                   }
                   /* Make sure that we have a NEW line of chats to analyse. If we don't,
                   there is no need to parse the data again */
                   elseif ($old_buffer != $con['buffer']['all']) {
                   /* Determine the patterns to be passed
                   to parse_buffer(). buffer is in the form:
                   :username!~identd@hostname JOIN :#php
                   :username!~identd@hostname PRIVMSG #PHP :action text
                   :username!~identd@hostname command channel :text */
                   
                   /*
                   Right now this bot does nothing. But this is where you would
                   add some conditions, or see what is being said in the chat, and then 
                   respond. Before you try doing that you should become familiar with
                   how commands are send over IRC. Just read the console when you run this
                   script, and then you will see the patterns in chats, i.e. where the username
                   occurs, where the hostmask is, etc. All you need is functions such as
                   preg_replace_callback(), or perhaps your own function that checks for patterns
                   in the text.
                   
                   Good Luck.
                   */
                                  parse_buffer();
    
    1. MyCommands , mutante stuff

    if (preg_match("/(bug|problem|error|fehler)/i", $con['buffer']['text'])) { cmd_send(prep_text("somebody said the bug was caused by a ".get_excuse())); }

    switch (substr($con['buffer']['text'],0,4)) {

    case "FNOR" : cmd_send(prep_text("FNORD!!!!")); break;


    case "!md5" : $arguments=explode(" ",$con['buffer']['text']); $option=$arguments[1];

     switch ($option) {
    
     case "-f" :
     $cleartext=$arguments[2];
     $md5hash = md5_forward($cleartext);
     cmd_send(prep_text("The hash for '$cleartext' is: $md5hash"));
     break;
    
     case "-r" :
     $md5hash=$arguments[2];
     list ($statusline,$cleartext) = md5_reverse($md5hash);
     cmd_send(prep_text("$statusline"));
     break;
    
     default:
     cmd_send(prep_text("MD5 hashes forward and reverse. Either use !md5 -f <cleartext> OR !md5 -r <md5hash>"));
                      }
    

    break;

    case "!hel" : cmd_send(prep_text("I'm a very young bot. My current commands are only: !help and !md5 so far.")); break;

    case "!wp " :

    $arguments=explode(" ",$con['buffer']['text']); $language=$arguments[1]; $pagename=$arguments[2];

    1. $input=str_replace(" ","_",$input);

    cmd_send(prep_text(wikipedia($language,$pagename)." \n")); break;

    case "!s23 " :

    $arguments=explode(" ",$con['buffer']['text']); $pagename=$arguments[1];

    1. $input=str_replace(" ","_",$input);

    cmd_send(prep_text(s23($pagename)." \n")); break;


    case "!wk " : $arguments=explode(" ",$con['buffer']['text']); $language=$arguments[1]; $pagename=$arguments[2];

    cmd_send(prep_text(wiktionary($language,$pagename)." \n")); break;

    }

               }
               $old_buffer = $con['buffer']['all'];
            }
       }
    

    }

    /* Accepts the command as an argument, sends the command to the server, and then displays the command in the console for debugging */ function cmd_send($command) {

       global $con, $time, $CONFIG;
       /* Send the command. Think of it as writing to a file. */
       fputs($con['socket'], $command."\n\r");
       /* Display the command locally, for the sole purpose
       of checking output. (line is not actually not needed) */
       print (date("[d/m @ H:i]") ."-> ". $command. "\n\r");
       
    

    }


    function prep_text($message) {

       global $con;
       return ('PRIVMSG '. $con['buffer']['channel'] .' :'.$message);
    

    }


    function parse_buffer() {

       /*
       :username!~identd@hostname JOIN :#php
       :username!~identd@hostname PRIVMSG #PHP :action text
       :username!~identd@hostname command channel :text
       */
       
       global $con, $CONFIG;
           
       $buffer = $con['buffer']['all'];
       $buffer = explode(" ", $buffer, 4);
       
       /* Get username */
       $buffer['username'] = substr($buffer[0], 1, strpos($buffer['0'], "!")-1);
       
       /* Get identd */
       $posExcl = strpos($buffer[0], "!");
       $posAt = strpos($buffer[0], "@");
       $buffer['identd'] = substr($buffer[0], $posExcl+1, $posAt-$posExcl-1); 
       $buffer['hostname'] = substr($buffer[0], strpos($buffer[0], "@")+1);
       
       /* The user and the host, the whole shabang */
       $buffer['user_host'] = substr($buffer[0],1);
       
       /* Isolate the command the user is sending from
       the "general" text that is sent to the channel
       This is  privmsg to the channel we are talking about.
       
       We also format $buffer['text'] so that it can be logged nicely.
       */
       switch (strtoupper($buffer[1]))
       {
           case "JOIN":
                  $buffer['text'] = "*JOINS: ". $buffer['username']." ( ".$buffer['user_host']." )";
               $buffer['command'] = "JOIN";
               $buffer['channel'] = $CONFIG['channel'];
                  break;
           case "QUIT":
                  $buffer['text'] = "*QUITS: ". $buffer['username']." ( ".$buffer['user_host']." )";
               $buffer['command'] = "QUIT";
               $buffer['channel'] = $CONFIG['channel'];
                  break;
           case "NOTICE":
                  $buffer['text'] = "*NOTICE: ". $buffer['username'];
               $buffer['command'] = "NOTICE";
               $buffer['channel'] = substr($buffer[2], 1);
                  break;
           case "PART":
                 $buffer['text'] = "*PARTS: ". $buffer['username']." ( ".$buffer['user_host']." )";
               $buffer['command'] = "PART";
               $buffer['channel'] = $CONFIG['channel'];
                 break;
           case "MODE":
                 $buffer['text'] = $buffer['username']." sets mode: ".$buffer[3];
               $buffer['command'] = "MODE";
               $buffer['channel'] = $buffer[2];
           break;
           case "NICK":
               $buffer['text'] = "*NICK: ".$buffer['username']." => ".substr($buffer[2], 1)." ( ".$buffer['user_host']." )";
               $buffer['command'] = "NICK";
               $buffer['channel'] = $CONFIG['channel'];
           break;
           
           default:
               // it is probably a PRIVMSG
               $buffer['command'] = $buffer[1];
               $buffer['channel'] = $buffer[2];
               $buffer['text'] = substr($buffer[3], 1);    
           break;    
       }
       $con['buffer'] = $buffer;
    

    }



    1. MD5 forward function
    2. input: a cleartext string
    3. output: the md5 hash for the input string
    4. by mutante/s23

    function md5_forward($cleartext) { $md5hash=md5($cleartext); return $md5hash; }

    1. MD5 reverse function
    2. input: an md5 hash
    3. output: the cleartext matching the input hash
    4. uses http://gdataonline.com/seekhash.php
    5. by mutante/s23

    function md5_reverse ($md5hash) {

    1. we use the XML output of http://gdataonline.com/seekhash.php

    $url="http://gdataonline.com/qkhash.php?mode=xml&hash=".$md5hash; $buffer = file_get_contents($url);

    1. check the buffer

    switch ($buffer) {

    1. server answers but hash is invalid, have to check this first

    case "Hash not valid.": $statusline="No success. the hash '$md5hash' is not valid."; break;

    default:

    1. now we can try to find the <status> tag

    $status=explode("<status>",$buffer); $status=explode("</status>",$status[1]); $status=$status[0];


    switch ($status) {

    1. Success found inside <status> tag, then do the parsing

    case "Success":

    $result=explode("<result>",$buffer); $result=explode("</result>",$result[1]); $cleartext=$result[0];

    $hexresult=explode("<hexresult>",$buffer); $hexresult=explode("</hexresult>",$hexresult[1]); $hexresult=$hexresult[0];

    $b64result=explode("<b64result>",$buffer); $b64result=explode("</b64result>",$b64result[1]); $b64result=$b64result[0];

    $hits=explode("<hits>",$buffer); $hits=explode("</hits>",$hits[1]); $hits=explode("/",$hits[0]); $hits=$hits[1];

    1. the message in case everything worked

    $statusline="SUCCESS - The cleartext for $md5hash is '$cleartext'. (HEX: $hexresult B64: $b64result Hits: $hits)"; break;

    1. Hast not found inside <status>

    case "Hash not found": $statusline="No success. the hash '$md5hash' was not found in the database."; break;

    1. All other cases, no <status> in buffer, or no reply at all from server..

    default: $statusline="'$status' No success. No or unusual answer from the database server."; } }

    1. we can only return multiple values as array

    $reverseresult[] = $statusline; $reverseresult[] = $cleartext; return $reverseresult;

    }

    1. end reverse function


    1. Wikipedia function

    function wikipedia($language,$pagename) { ini_set('user_agent','http://s23.org/wikistats/ | http://meta.wikimedia.org/wiki/User:mutante | mutante@s23.org'); $url="http://".$language.".wikipedia.org/w/index.php?title=".$pagename; $buffer = file_get_contents($url);

    $summary = explode("

    ",$buffer); $summary = $summary[1]; $summary = explode("

    ",$summary);

    $summary = $summary[0]; $summary = strip_tags($summary); $summary = str_replace("\n"," ",$summary); $summary = trim($summary); $summary = explode(". ",$summary);

    if ($summary[2]) {
       $summary = $summary[0].". ".$summary[1].". ".$summary[2].".";
        } elseif ($summary[1]) {
       $summary = $summary[0].". ".$summary[1].".";
        } else {
       $summary = $summary[0].".";
               }
       $summary = substr($summary,0, 320);
       $summary = "$pagename is ".$summary."\n";
    
     return $summary;
             }
    
    1. S23

    function s23($pagename) { ini_set('user_agent','http://s23.org/wikistats/ | http://meta.wikimedia.org/wiki/User:mutante | mutante@s23.org'); $url="http://s23.org/w/index.php?title=".$pagename; $buffer = file_get_contents($url);

    $summary = explode("

    ",$buffer); $summary = $summary[1]; $summary = explode("

    ",$summary);

    $summary = $summary[0]; $summary = strip_tags($summary); $summary = str_replace("\n"," ",$summary); $summary = trim($summary); $summary = explode(". ",$summary);

    if ($summary[2]) {
       $summary = $summary[0].". ".$summary[1].". ".$summary[2].".";
        } elseif ($summary[1]) {
       $summary = $summary[0].". ".$summary[1].".";
        } else {
       $summary = $summary[0].".";
               }
       $summary = substr($summary,0, 320);
       $summary = "$pagename is ".$summary."\n";
    
     return $summary;
         }
    


    1. Wiktionary function

    function wiktionary($language,$pagename) { ini_set('user_agent','http://s23.org/wikistats/ | http://meta.wikimedia.org/wiki/User:mutante | mutante@s23.org'); $url="http://".$language.".wiktionary.org/wiki/".$pagename;

    1. print "$url \n";
    $buffer = file_get_contents($url);
    
    # print $buffer;
    switch ($language) {
    case "de":
    
    $summary = explode("Bedeutungen:",$buffer);
    $summary = $summary[1];
    $summary = explode("Herkunft",$summary);
    break;
    
    case "en":
    

    $summary = explode("

      ",$buffer); $summary = $summary[1]; $summary = explode("

    ",$summary);

    $summary = str_replace("countable"," ",$summary);
    break;
    
    default:
    $summary="Sorry, only supports en and de Wiktionary atm. But try Wikipedia (!wp <lang> <word>)";
    }
    


    $summary = $summary[0];
    $summary = strip_tags($summary);
    $summary = str_replace("\n"," ",$summary);
    $summary = trim($summary);
    $summary = explode(". ",$summary);
    
    if ($summary[2]) {
    $summary = $summary[0].". ".$summary[1].". ".$summary[2].".";
    } elseif ($summary[1]) {
    $summary = $summary[0].". ".$summary[1].".";
    } else {
    $summary = $summary[0].".";
    }
    
    $summary = substr($summary,0, 320);
    $summary = "$pagename is ".$summary."\n";
    


    return $summary;
    
    }
    

    function get_excuse() { # BOFH excuse generator # Written by gf, ported to php by took # Idea and words from http://bofh.ntk.net/ExcuseBoard.html

    $first = explode(" ", "Temporary Intermittant Partial Redundant Total Multiplexed Inherent Duplicated Dual-Homed Synchronous Bidirectional Serial Asynchronous Multiple Replicated Non-Replicated Unregistered Non-Specific Generic Migrated Localised Resignalled Dereferenced Nullified Aborted Serious Minor Major Extraneous Illegal Insufficient Viral Unsupported Outmoded Legacy Permanent Invalid Deprecated Virtual Unreportable Undetermined Undiagnosable Unfiltered Static Dynamic Delayed Immediate Nonfatal Fatal Non-Valid Unvalidated Non-Static Unreplicatable Non-Serious");

    $second = explode(" ", "Array Systems Hardware Software Firmware Backplane Logic-Subsystem Integrity Subsystem Memory Comms Integrity Checksum Protocol Parity Bus Timing Synchronisation Topology Transmission Reception Stack Framing Code Programming Peripheral Environmental Loading Operation Parameter Syntax Initialisation Execution Resource Encryption Decryption File Precondition Authentication Paging Swapfile Service Gateway Request Proxy Media Registry Configuration Metadata Streaming Retrieval Installation Library Handler");

    $third = explode(" ", "Interruption Destabilisation Destruction Desynchronisation Failure Dereferencing Overflow Underflow NMI Interrupt Corruption Anomaly Seizure Override Reclock Rejection Invalidation Halt Exhaustion Infection Incompatibility Timeout Expiry Unavailability Bug Condition Crash Dump Crashdump Stackdump Problem Lockout");

    $fourth = explode(" ", "Error Problem Warning Signal Flag");

    $out = $first[rand(0,count($first)-1)]." "; $out .= $second[rand(0,count($second)-1)]." "; $out .= $third[rand(0,count($third)-1)]; if (rand(0,9) % 2 == 0) $out .= " ".$fourth[rand(0,count($fourth)-1)];

    return $out; } ?>

    </HighlightSyntax> <tasks> [2] upd8 edgar with bofh-excuses - see http://s23.org/w/index.php?title=Edgar&diff=54476&oldid=48154 (mutante) </tasks>

    Cookies help us deliver our services. By using our services, you agree to our use of cookies.
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.