IRC related help

£可爱£侵袭症+ 提交于 2019-12-23 23:58:15

问题


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.


回答1:


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; 
         } 

      } 
   } 
} 
?> 



回答2:


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



来源:https://stackoverflow.com/questions/4220905/irc-related-help

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!