如何让这些Perl脚本延迟?

时间:2015-06-27 21:54:14

标签: perl bots irc

我在Perl中制作了一个简单的IRC机器人,可以用来捕捉鸭子"回应this IRC game bot。我是在私人脚本频道irc.freenode.net ##duckhunt2上这样做的,以免干扰真人玩游戏。

到目前为止,我已尝试使用Net::IRC和XChat插件({3}}制作Perl僵尸程序。 duck source bot发送消息,如

・゜゜・。。・゜゜\_O< quack!

自从最后一只鸭子开枪以来,在8到60分钟之间的随机时间,让你知道一只鸭子到了。然后,您可以使用.bang回复拍摄鸭子,并在分数中添加一个点数。但是,如果您回复得太快(在一秒钟内),它会使您处于2小时冷却模式,在此模式下您无法射击任何鸭子。有时它也会因为枪械和枪支而导致7秒钟的冷却时间。等,如游戏机器人代码的第272行所示。

Perl代码

use Net::IRC;
use Time::HiRes qw(usleep nanosleep);

$ducksource = 'DUCK_SOURCE';
$server     = 'IRC_SERVER';
$channel    = 'IRC_CHANNEL';
$botnick    = 'BOT_NICKNAME';
$botnick2   = 'BOT_BACKUP_NICKNAME';
$password   = 'BOT_PASSWORD';
$botadmin   = 'BOT_ADMIN_NICKNAME';

$irc = new Net::IRC;

$conn = $irc->newconn(
    Nick     => $botnick,
    Server   => $server,
    Port     => IRC_SERVER_PORT,
    Username => $botnick
);

$conn->add_global_handler('376',        \&on_connect);
$conn->add_global_handler('disconnect', \&on_disconnect);
$conn->add_global_handler('kick',       \&on_kick);
$conn->add_global_handler('msg',        \&on_msg);
$conn->add_global_handler('public',     \&on_public);

$irc->start;

sub on_connect {

    $self = shift;

    $self->privmsg('nickserv', "identify $password");
    $self->join($channel);

    print "Connected\n";
}

sub on_disconnect {

    $self = shift;

    print "Disconnected, attempting to reconnect\n";
    $self->connect();
}

sub on_kick {

    $self = shift;

    $self->join($channel);
    $self->privmsg('nickserv', "/nick $botnick");
}

sub on_msg {

    $self  = shift;
    $event = shift;

    if ($event->nick eq $botadmin) {

        foreach $arg ($event->args) {

            if ($arg =~ m/uptime/) {
                $self->privmsg($botadmin, `uptime`);
            }
        }
    }
}

sub on_public {

    $self  = shift;
    $event = shift;

    if ($event->nick eq $ducksource) {

        foreach $arg ($event->args) {

            if (($arg =~ m/</) && ($arg !~ m/>/)) {
                usleep(250000);
                $self->privmsg($channel, ".bang");
            }

            if (   ($arg =~ m/missed/)
                || ($arg =~ m/jammed/)
                || ($arg =~ m/luck/)
                || ($arg =~ m/WTF/)) {
                $self->privmsg('nickserv', "/nick $botnick2");
                $self->privmsg($channel,   ".bang");
                $self->privmsg('nickserv', "/nick $botnick");
            }

            if (($arg =~ m/script/) || ($arg =~ m/period/)) {
                $self->privmsg('nickserv', "/nick $botnick2");
                $self->privmsg($channel,   ".bang");
            }
        }
    }
}

Perl僵尸程序连接到服务器,加入聊天室,并响应出现的鸭子,但我无法让它延迟发送命令.bang,以便游戏机器人收到1秒钟过后,我不进入两小时的冷却模式。

我知道Perl sleep命令只接受一秒的倍数。我需要延迟0.25秒,因为消息到达游戏机器人需要大约0.75秒,所以我尝试使用Time :: HiRes和usleep命令,它使用微秒(1,000微秒= 1毫秒)。

在我的代码的第61行,我添加了usleep(250000),这会使脚本暂停0.25秒,然后在下一行发送消息

$self->privmsg($channel, ".bang")

但脚本不会等待 - 它只是正常发送消息。它就像忽略usleep命令一样。

如何修复此问题并让机器人在发送消息之前等待?

其次,我对如何更改昵称感到困惑。如果游戏机器人给我7秒的冷却时间,我想快速将我的昵称改为另一个昵称(例如HunterBot6000HunterBot6000_)射击鸭子(.bang),并在另一个机器人获得鸭子之前改变我的昵称。通常,您可以通过/nick NEWNICK命令完成切换更改。但是,我尝试将此命令发送到频道和 NickServ ,这并没有改变我的昵称。我应该怎样做到这一点?

我还尝试为脚本编写一个XChat插件,看看是否可以解决时间问题,但这也不起作用。连接到服务器并加入XChat中的聊天室后,我加载了插件,我遇到了同样的问题 - 它使用.bang响应鸭子,但在发送之前我无法让它等待。

您可以查看文档with my code here。我做错了什么?

3 个答案:

答案 0 :(得分:0)

您提出了多个问题,但我只能通过手机接听一个

您可以通过发送

来更改昵称
NICK newnick

更多信息可在RFC 2812

中找到

然而,Net :: IRC可能有更合适的手段。

答案 1 :(得分:0)

我也遇到过来自Time :: HiRes的麻烦。这应该会导致250毫秒的睡眠:

select(undef, undef, undef, 0.25);

答案 2 :(得分:0)

感谢大家的帮助。我能够使usleep命令工作并通过将延迟更改为更大的秒数(例如usleep(25000000),25秒)来验证它是否正确延迟,然后通过删除将其更改回0.25秒一次0个。我还在之前和之后添加了print Time::HiRes::time;来验证延迟是否有效。我还发现改变缺刻的正确命令是$self->nick($botnick2);,即使在任何Net :: IRC文档中都找不到它。再次感谢大家的帮助和建议。