PHP IRC Bot创建无限循环 [英] PHP IRC Bot creating infinite loop

查看:47
本文介绍了PHP IRC Bot创建无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,Stack Overflow的开发人员们!最近,我回到了Web开发中(尽管我以前不太擅长此事),而PHP是我的首选武器.自从我退出PHP以来,PHP似乎已经发生了变化,并将其与我从未使用过PHP套接字的事实结合起来,然后才导致灾难性的首次尝试创建IRC机器人(我在一个IRC渠道上,机器人在这里发展很大) ,并且我想将其集成到我的网站中.用php编写它似乎是一个有趣的挑战).它创建了一个无限循环,使我的浏览器运行缓慢,并且我无法复制任何错误或警告.这样的好心人会介意看一下这个脚本吗(基于这个 bot ):

Hello fellow developers of Stack Overflow! I recently got back into web development (although I wasn't too good at it before) with PHP being my weapon of choice. PHP seems to have changed since I was out of it, and combine that with the fact that I have never used PHP sockets, before lead to a disastrous first attempt to create an IRC bot (I am on an IRC channel where bot developing is big, and I want to integrate it into my website. Writing it in php also seems like a fun challenge). It created an infinite loop that made my browser go slow, and I wasn't able to copy any errors or warnings. Would the good folks of so mind looking over this script (based on this bot):

<!DOCTYPE html>
<html lang="en-US">
    <head>
        <title>Lucky Cloud</title>
    </head>

    <body>
        <?php
            error_reporting(E_ERROR);

            $bot = array(
                            "Host"     => "irc.quakenet.org",
                            "Channels" => ["#cplusplus", "#BotDevGroundZero"],
                            "Nick"     => "LuckyCloud",
                            "Ident"    => "LuckyCloud",
                            "Real"     => "LuckyCloud",
                            "Port"     => 6667
                   );
            $buffer = "";
        ?>

        <p>
            Server: <?php echo $bot["Host"]; ?><br />
            Channel(s): <?php foreach($bot["Channels"] as $channel) echo $channel.($channel != end($bot["Channels"]) ? ", " : ""); ?><br />
            Port: <? echo $bot["Port"]; ?><br />
            ___________________________________________________________________________________________________________________<br />
        </p>

        <?php
            global $socket;
            $socket = fsockopen($bot["host"], $bot["Port"]);

            function sendData($cmd, $msg = null) {
                if($msg == null) {
                    fputs($socket, $cmd."\r\n");
                    echo "<strong>".$cmd."</strong><br />";
                }

                else {
                    fputs($socket, $cmd." ".$msg."\r\n");
                    echo "<strong>".$cmd." ".$msg."</strong><br />";
                }
            }

            sendData("NICK", $bot["Nick"]);
            sendData("USER", $bot["Ident"]." ".$bot["Host"]." ".$bot["Real"]);

            $buffer = "";

            while(true) {
                foreach($bot["Channels"] as $channel) {
                    sendData("JOIN", $channel);
                }

                $buffer += fgets($socket, 1024);
                $temp = explode("\n", $buffer);
                $buffer = end($temp);

                foreach($temp as $line) {
                    echo $line;
                    $line = rtrim($line);
                    $line = explode($line);

                    if($line[0] == "PING") {
                        sendData("PONG", $line[1]);
                    }
                }
            }
        ?>
    </body>
</html>

很抱歉遇到任何格式问题. cpanel编辑器的行为很奇怪

推荐答案

PHP并不是这项工作的最佳选择.保持长时间运行的连接确实不是很好.该脚本可能用于短时加入,您只需在其中放置一条消息然后离开即可.类似于基于事件的通知".

PHP is not the best thing for this job. It's really not good at keeping long running connections. This script might be used for short time joins, where you simply drop a message and leave. Something like "event based notification".

脚本的几项补充:

  • 时区
  • 错误报告和显示
  • 时间限制0
  • 同时修改为while (!feof($socket)) {
  • PING/PONG:替换为substr爆炸
  • 这连接到freenode,quakenet是个bit子-这里还需要一些魔术:)
  • JOIN在WHILE内部,但我们只需要一次-添加了后卫
  • 在频道内观看它的连接
  • 输出未刷新...嗯.
  • timezone
  • error_reporting and display
  • timelimit 0
  • while modified to while (!feof($socket)) {
  • PING/PONG: replaced explode by substr
  • this connects to freenode, quakenet is a bitch - some more magic needed here :)
  • JOIN is inside the WHILE, but we need it only one time - guard added
  • be inside the channel to watch it connect
  • the output is not flushed... hmm..
<html lang="en-US">
<head>
    <title>Lucky Cloud</title>
</head>  
<body>
    <?php
        date_default_timezone_set('America/Los_Angeles');
        error_reporting(E_ALL);
        ini_set("display_errors", 1);
        set_time_limit(0);

        $bot = array(
            "Host"     => "kornbluth.freenode.net", #"underworld2.no.quakenet.org", #irc.quakenet.org",
            "Channels" => ["#testerchan"],
            "Nick"     => "Tester7888",
            "Ident"    => "Tester7888",
            "Real"     => "Susi Q",
            "Port"     => 6667
        );
    ?>

    <p>
        Server: <?php echo $bot["Host"]; ?><br />
        Channel(s): <?php foreach($bot["Channels"] as $key => $channel) { echo $channel; } ?><br />
        Port: <?php echo $bot["Port"]; ?><br />
        ___________________________________________________________________________________________________________________<br />
    </p>

    <?php
        global $socket;

        function sendData($cmd, $msg = null) {
            global $socket;
            if($msg == null) {
                fputs($socket, $cmd."\r\n");
                echo "<strong>".$cmd."</strong><br />";
            } else {
                fputs($socket, $cmd." ".$msg."\r\n");
                echo "<strong>".$cmd." ".$msg."</strong><br />";
            }
        }

        $socket = fsockopen($bot["Host"], $bot["Port"], $error1, $error2);
        if(!$socket) {
            echo 'Crap! fsockopen failed. Details: ' . $error1 . ': ' . $error2;
        }

        sendData("NICK", $bot["Nick"]);
        sendData("USER", $bot["Ident"]." ".$bot["Host"]." ".$bot["Real"]);

        $join_at_start = true;

        $buffer = "";

        while (!feof($socket)) {
            $buffer = trim(fgets($socket, 128));
            echo date('H:i')." ".nl2br($buffer)."<br/>";
            flush();

            # Ping <-> Pong
            if(substr($buffer, 0, 6) == "PING :") {
                fputs($socket, "PONG :".substr($buffer, 6)."\r\n");
                echo $buffer;
                flush();
            }

            // break out of while, 0 bytes
           /* $stream_meta_data = stream_get_meta_data($socket);
            if($stream_meta_data['unread_bytes'] <= 0) {
                break;
            }*/

            # join only one time
            if($join_at_start === true && false === strpos($buffer, 'Your host is trying to (re)connect too fast -- throttled')) {
                foreach($bot["Channels"] as $key => $channel) {
                   sendData("JOIN", $channel);
                   $join_at_start = false;
                }
            }
        }
    ?>
</body>

这篇关于PHP IRC Bot创建无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆