IRC related help

2019-07-09 01:45发布

Now I have my bot to send message when the bot joins. However how do I make a form that would post data so that the bot will say the message to the channel?

Here is my script (Rewamped):

<?php
set_time_limit(0);

$socket = fsockopen("//", 6667) or die();

$msg = $_POST['message'];
$pr = $_POST['percentage'];
$pr /= 100;

fputs($socket,"USER BOT 0 zo :ZH bot\n");
// Set the bots nickname
fputs($socket,"NICK BOT1\n");

fputs($socket,"JOIN #bots\n");

while(1) {

   while($data = fgets($socket, 128)) {
      // echo the data received to page
      echo nl2br($data);
      // flush old data, it isn't needed any longer.
      flush();

      $ex = explode(' ', $data);

      if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");

      $search_string = "/^:([A-Za-z0-9_\-]+)[@!~a-zA-Z0-9@\.\-]+\s*([A-Z]+)\s*[:]*([\#a-zA-Z0-9\-]+)*\s*[:]*([!\#\-\.A-Za-z0-9 ]+)*/";

      $do = preg_match($search_string, $data, $matches);

      // check that there is a command received
      if(isset($matches['2'])) {
         switch($matches['2']) {
            case "PRIVMSG":
               $user = $matches['1'];
               $channel = $matches['3'];
               $chat_text = isset($matches['4']) ? $matches['4'] : "";

               // check chat for !time
               if(strtolower($chat_text) == "!time") { 
                  $output = "::::: " . date('l jS \of F Y h:i:s A') . " :::::";
                  fputs($socket, "PRIVMSG " . $channel . " :" . $output . "\n");
               } elseif(strtolower($chat_text) == "!hello") {
                  fputs($socket, "PRIVMSG " . $channel . " :Hello!\n");
               }
            break;

            case "JOIN":
               $user = $matches['1'];
               $channel = $matches['3'];
               fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel . "\n");
            break;
         }

      }
   }
}
?>

E.g. Making a form that would send the data to the IRC channel. The output would be "wget file info port" <-- That would be the text sent to the IRC channel.

Here are parts related:

fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel ."\n");

Hope someone can help out.

标签: php irc
2条回答
成全新的幸福
2楼-- · 2019-07-09 01:56

Okay here's a better answer. The first section still stands. A new PHP process is called every time you want to initiate a new script. Thus, you need some way to do IPC.

Here's how it's done on *nix (but not windows) in PHP:

Receiver:

<?php
$queueKey = 123321;

$queue = false;
if(msg_queue_exists($queueKey)) {
        echo "Queue Exists.\n";
}

// Join the queue
$queue = msg_get_queue($queueKey);

while(!($queue == false)) {
        // Note: This function could block if you feel like threading
        $msgRec = msg_receive(
                $queue,        // I: Queue to get messages from
                0,             // I: Message type (0 = first on queue)
                $msgType,      // O: Type of message received
                1024,          // I: Max message size
                $msgData,      // O: Data in the message
                true,          // I: Unserialize data
                MSG_IPC_NOWAIT // I: Don't block
        );

        if($msgRec) {
                echo "Message received:\n";
                echo "Type = $msgType\n";
                echo "Data = \n";
                print_r($msgData);
        }
}
?>

Sender:

<?php
$queueKey = 123321;

$queue = false;
if(msg_queue_exists($queueKey)) {
        echo "Queue Exists.\n";
} else {
        echo "WARNING: Queue does not exist. Maybe no listeners?\n";
}

$queue = msg_get_queue($queueKey);

$abc["something"] = "something value";
$abc["hello"] = "world";
$abc["fu"] = "bar";
msg_send(
        $queue, // Queue to send on
        1,      // Message type
        $abc,   // Data to send
        true,   // Serialize data?
        true    // Block
);

?>

This should produce (in the receiver loop) something similar to this:

Message received:
Type = 1 
Data =
Array 
(
    [something] => something value
    [hello] => world
    [fu] => bar 
)

Your script might look something like this

postToMe.php:

<?php
$queueKey = 123321;

$queue = false;
if(msg_queue_exists($queueKey)) {
        echo "Queue Exists.\n";
} else {
        echo "WARNING: Queue does not exist. Maybe no listeners?\n";
}

$queue = msg_get_queue($queueKey);

msg_send(
        $queue, // Queue to send on
        1,      // Message type
        $_POST, // Data to send
        true,   // Serialize data?
        true    // Block
);

?>

bot.php:

<?php 
set_time_limit(0); 

$socket = fsockopen("//", 6667) or die(); 

$msg = $_POST['message']; 
$pr = $_POST['percentage']; 
$pr /= 100; 

fputs($socket,"USER BOT 0 zo :ZH bot\n"); 
// Set the bots nickname 
fputs($socket,"NICK BOT1\n"); 

fputs($socket,"JOIN #bots\n"); 


$queueKey = 123321;
$queue = false;

// Join the IPC queue
$queue = msg_get_queue($queueKey);
if(!$queue) echo "ERROR: Could not join IPC queue. Form data will not be received";

while(1) { 
   // Handle new post info
   // You may want to increase the message size from 1024 if post data is large
   if(msg_receive($queue, 0, $msgType, 1024, $msgData, true, MSG_IPC_NOWAIT)) {
      // Handle data here. Post data is stored in $msgData
   }

   while($data = fgets($socket, 128)) { 
      // echo the data received to page 
      echo nl2br($data); 
      // flush old data, it isn't needed any longer. 
      flush(); 

      $ex = explode(' ', $data); 

      if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n"); 

      $search_string = "/^:([A-Za-z0-9_\-]+)[@!~a-zA-Z0-9@\.\-]+\s*([A-Z]+)\s*[:]*([\#a-zA-Z0-9\-]+)*\s*[:]*([!\#\-\.A-Za-z0-9 ]+)*/"; 

      $do = preg_match($search_string, $data, $matches); 

      // check that there is a command received 
      if(isset($matches['2'])) { 
         switch($matches['2']) { 
            case "PRIVMSG": 
               $user = $matches['1']; 
               $channel = $matches['3']; 
               $chat_text = isset($matches['4']) ? $matches['4'] : ""; 

               // check chat for !time 
               if(strtolower($chat_text) == "!time") {  
                  $output = "::::: " . date('l jS \of F Y h:i:s A') . " :::::"; 
                  fputs($socket, "PRIVMSG " . $channel . " :" . $output . "\n"); 
               } elseif(strtolower($chat_text) == "!hello") { 
                  fputs($socket, "PRIVMSG " . $channel . " :Hello!\n"); 
               } 
            break; 

            case "JOIN": 
               $user = $matches['1']; 
               $channel = $matches['3']; 
               fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel . "\n"); 
            break; 
         } 

      } 
   } 
} 
?> 
查看更多
不美不萌又怎样
3楼-- · 2019-07-09 01:59

Basically, this script will be running all the time. The way PHP works is that for each script that is being run, a new PHP process is created. Scripts can be run multiple times simultaneously, however they will not be able to directly communicate.

You will need to create enother script (or at least a whole new function of this one) to accept the post variables, and then send them to the running version of this script.

(Note: I will provide 2 solutions, since 1 is significantly more difficult. Also, there's Semaphore that I've just found, however I am unsure exactly if this suits our needs because I know next to nothing about it http://php.net/manual/en/book.sem.php)

Best (But Advanced)

The best way I can think of doing this would be to use sockets (particularly on *nix, since sockets are fantastic for IPC [inter process communication]). It's a little difficult, since you're basically create a client/server just to communicate details, then you need to come up with some sort of a protocol for your IPC.

I won't code anything up here, but the links that are relevant to this are http://www.php.net/manual/en/function.socket-create.php http://www.php.net/manual/en/function.socket-bind.php http://www.php.net/manual/en/function.socket-listen.php http://www.php.net/manual/en/function.socket-accept.php http://www.php.net/manual/en/function.socket-connect.php

If using this on *nix, I would highly recommend using AF_UNIX as the domain. It's very efficient, and quite a number of applications use it for IPC.

Pros: Very robust solution - Highly efficient - Instant (or as close as we can get) communication

Cons: - Quite difficult to implement

Not As Great (But Still Good)

Just use files to communicate the information. Have your bot script check the file every 15 seconds for changes. I would suggest using XML for the data (since simple xml makes xml processing in php well... simple)

Things you need to consider would be: How would it react when receiving 2 posts at the same time? (If you just use a flat file or don't account for having multiple entries, this will become a problem). How you find out if a message is new (I'd delete/blank the file right after reading. Note: Not after processing, as someone could post to the form script while you are processing/sending the message)

Links: How to use simple xml http://php.net/manual/en/simplexml.examples-basic.php http://au2.php.net/manual/en/book.simplexml.php

File related http://au2.php.net/manual/en/function.file-put-contents.php http://au2.php.net/manual/en/function.file-get-contents.php

With that being said, you could also use MySQL/Postgres or some other database back end to deal with the flow of data between scripts.

Pros: - Easy to implement

Cons: - Slow to transfer data (checks files at given intervals) - Uses external files, which can be deleted/modified my external applications/users

查看更多
登录 后发表回答