首页 文章

IRC相关帮助

提问于
浏览
2

现在我有机器人在机器人加入时发送消息 . 但是,如何制作一个可以发布数据的表单,以便机器人将消息发送到 Channels ?

这是我的脚本(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;
         }

      }
   }
}
?>

例如 . 制作一个将数据发送到IRC Channels 的表单 . 输出将是“wget file info port”< - 这将是发送到IRC Channels 的文本 .

以下是相关部分:

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

希望有人可以帮忙 .

2 回答

  • 3

    好的,这是一个更好的答案 . 第一部分仍然有效 . 每次要启动新脚本时都会调用一个新的PHP进程 . 因此,您需要一些方法来进行IPC .

    以下是在PHP中使用* nix(但不是windows)的方法:

    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
    );
    
    ?>
    

    这应该产生(在接收器循环中)类似于此的东西:

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

    您的脚本可能看起来像这样

    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

    基本上,这个脚本将一直运行 . PHP的工作方式是,对于每个正在运行的脚本,都会创建一个新的PHP进程 . 脚本可以同时运行多次,但是它们无法直接通信 .

    您需要创建另一个脚本(或至少是这个脚本的全部新功能)来接受post变量,然后将它们发送到此脚本的运行版本 .

    (注意:我将提供2个解决方案,因为1非常困难 . 另外,刚刚找到了's Semaphore that I',但是我不确定这是否适合我们的需求因为我几乎一无所知http://php.net/manual/en/book.sem.php

    Best (But Advanced)

    我能想到这样做的最好方法是使用套接字(特别是在* nix上,因为套接字对于IPC [进程间通信]来说非常棒) . 它基本上只是为了传达细节而创建一个客户端/服务器,那么你需要为你的IPC提出某种协议 .

    我不会在这里编写任何代码,但与此相关的链接是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

    如果在* nix上使用此功能,我强烈建议使用AF_UNIX作为域 . 它非常高效,并且有很多应用程序将它用于IPC .

    优点:非常强大的解决方案 - 高效 - 即时(或尽可能接近)通信

    缺点: - 很难实施

    Not As Great (But Still Good)

    只需使用文件来传达信息 . 让您的bot脚本每15秒检查一次文件是否有变化 . 我建议使用XML作为数据(因为简单的xml使php中的xml处理很简单)

    你需要考虑的事情是:在同时收到2个帖子时会有什么反应? (如果您只使用平面文件或不考虑有多个条目,这将成为一个问题) . 如何确定消息是否是新消息(我在阅读后立即删除/删除文件 . 注意:处理后没有,因为有人可以在处理/发送消息时发布到表单脚本)

    链接:如何使用简单的xml http://php.net/manual/en/simplexml.examples-basic.php http://au2.php.net/manual/en/book.simplexml.php

    相关文件http://au2.php.net/manual/en/function.file-put-contents.php http://au2.php.net/manual/en/function.file-get-contents.php

    话虽如此,您还可以使用MySQL / Postgres或其他一些数据库后端来处理脚本之间的数据流 .

    优点: - 易于实施

    缺点: - 缓慢传输数据(按给定间隔检查文件) - 使用外部文件,可以删除/修改我的外部应用程序/用户

相关问题