使用机器人时,我如何避免或处理 IRC 服务器 MOTD?

使用机器人时,我如何避免或处理 IRC 服务器 MOTD?

我有一个用 Python 编写的 IRC 机器人,运行良好。我认为问题在于我对 IRC 协议的了解有限,因此我特别欢迎 IRC 专家 :D

当您首次连接到 IRC 网络时,通常会显示 MOTD。在 MOTD 完成之前,网络不会接受任何命令。因此,对于我的机器人,我必须有一个循环来检查 MOTD 的结束。这根本不是特别模块化的,因为根据我的经验,并非所有服务器都以相同的方式结束其 MOTD。有没有办法告诉服务器不要发送 MOTD,或者确实有更好的方法等待 MOTD 结束以告诉服务器我希望连接到哪个频道?

我当前用于等待 MOTD 结束的代码由一个 while 循环组成,该循环读取输入缓冲区并将每个完整命令解析为一个列表。它获取此列表并搜索每个字符串对象以查找出现在 FreeNode 的 MOTD 末尾的特定字符串,如果找到,则循环结束并发送加入频道的命令,然后进入主循环。

有没有更好的方法来处理 MOTD?我不禁觉得这种方法相当笨拙。

答案1

有没有办法告诉服务器不要发送 MOTD,或者确实有更好的方法等待 MOTD 结束后再告诉服务器我希望连接到哪个频道

不,没有办法关闭 MOTD。但是,这甚至都没有必要,因为您的假设“在 MOTD 完成之前,网络不会接受任何命令”首先就不正确。

所有网络开始接受命令立即地只要你注册(即发送NICKUSER) - 有些只是延迟作用于一两秒即可完成这些命令。尽快开始发送命令是完全有效的。


无论如何,你不需要延迟主循环来实现这一点——事实上,全部收到的输入应该由同一个循环处理。相反,你只需要跟踪是否已经看到“MOTD 结束”行,并在JOIN第一次看到它时发送 s。

此外,从您的描述来看,您使用的检测 MOTD 结束的方法确实不太可靠。如果您正在寻找“/MOTD 结束”字符串,请不要这样做。相反,请按照以下说明解析整行RFC 1459§2.3.1(这是一个不太 Pythonic 的解析器)并检查命令在每一行中,因为描述性文本在不同的 IRC 守护进程之间可能有所不同。您还应该检查“no /MOTD”消息。

例如,您将拥有:

# raw input is ":leguin.freenode.net 376 grawity :End of /MOTD.\r\n"
# split input is [":leguin.freenode.net", "376", "grawity", "End of /MOTD."]
# parsed input is {"prefix":  "leguin.freenode.net",
#                  "command": "376",
#                  "args":    ["grawity", "End of /MOTD."]}

RPL_WELCOME   = "001"
RPL_ENDOFMOTD = "376"
ERR_NOMOTD    = "422"

if not sent_initial_join:
    if command in {RPL_WELCOME, RPL_ENDOFMOTD, ERR_NOMOTD}:
        conn.send("JOIN %s\r\n" % ",".join(channels))
        sent_initial_join = True

但如上所述,这完全没有必要。只需在、和JOIN之后立即发送 s即可。NICKUSERCAP END

以诸神的名义,不是为此,可以使用像 10 秒超时这样愚蠢的方法。

答案2

我所做的是等到我得到 376 或 422 的数字,然后我发送加入频道、设置通知列表等的命令。

if split_line[1] == '376' or split_line[1] == "422":
    # End of /motd # keep track if it is the first motd 
    # (on connect) or already connected.
    if not socket_data.state[client_socket]['connected']:
        socket_data.state[client_socket]['connected'] = time()
        # Join channels now

irc 服务器发送以数字开头的消息,数字可以是第一个字,也可以是“:irc.server.com”后面的第二个字。我只需检查行的第一个字符是否不是“:”,然后向 split_line 添加一个空字符串。如果第二个字是数字,则它就是数值。不同的数字表示不同的含义,在本例中,只需查找 422 即可告诉您没有 MOTD 文件,而 376 表示 MOTD 结束,375 是 MOTD 的内容。https://www.tg007.net/raws列出了许多原始数字代码。

相关内容