1

У меня есть бот IRC, написанный на Python, который работает довольно хорошо. Я думаю, что проблема заключается в моих ограниченных знаниях протокола IRC, поэтому гуру IRC особенно приветствуются здесь:D

При первом подключении к сети IRC обычно отображается MOTD. Сеть не будет принимать никаких команд, пока MOTD не закончится. Так что с моим ботом у меня должен быть цикл, который проверяет конец MOTD. Это совсем не модульно, так как, по моему опыту, не все серверы заканчивают свою MOTD одинаково. Есть ли способ сказать серверу, чтобы он не отправлял MOTD, или действительно лучший способ дождаться окончания MOTD, чтобы сообщить серверу, к какому каналу я хочу подключиться?

Мой текущий код для ожидания окончания MOTD состоит из цикла while, читающего входной буфер и разбирающего каждую полную команду в список. Он берет этот список и ищет в каждом строковом объекте определенную строку, которая появляется в конце MOTD FreeNode, если он найден, цикл завершается и перед входом в основной цикл отправляется команда для присоединения к каналу.

Есть ли лучший способ справиться с MOTD? Я не могу не чувствовать, что этот путь довольно неуклюж.

1 ответ1

2

Есть ли способ сказать серверу не отправлять MOTD, или действительно лучший способ дождаться окончания MOTD, чтобы сообщить серверу, к какому каналу я хочу подключиться?

Нет, нет способа отключить MOTD. Однако в этом даже не должно быть необходимости, поскольку ваше предположение о том, что "Сеть не будет принимать никаких команд до завершения MOTD", в первую очередь неверно.

Все сети начинают принимать команды сразу, как только вы регистрируетесь (то есть отправляете NICK и USER) - некоторые из них просто откладывают действие этих команд на секунду или две. Вполне допустимо начать посылать команды как можно скорее.


В любом случае вам не нужно было бы задерживать основной цикл для достижения этого - действительно, все полученные входные данные должны обрабатываться одним и тем же циклом. Вместо этого вы просто будете следить за тем, видели ли вы уже строку "конец MOTD", и отправлять JOIN когда увидите ее в первый раз.

Кроме того, из вашего описания, похоже, что вы используете несколько ненадежный метод для определения конца 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 сразу после NICK , USER и таких вещей, как CAP END .

И, боги, не используйте что-то настолько глупое, как 10-секундный тайм-аут для этого.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .