С ботом, как мне избежать или обработать MOTD IRC-сервера?

975
LiamMeron

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

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

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

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

1
Я не знаю Python или каких-либо вещей IRC, но я думаю, вы могли бы просто подождать 10 секунд или что-то еще, прежде чем он активируется. Frank 10 лет назад 0
Вам не нужно ждать окончания MOTD, чтобы начать посылать команды. Вы получите результаты позже. BatchyX 10 лет назад 1
@ chipperyman573 Я думал об этом, но это неправильно, полагаясь на таймер для аутентификации. На мой взгляд, это может вызвать столько же проблем с модульностью, сколько и мои текущие настройки. LiamMeron 10 лет назад 0

1 ответ на вопрос

2
grawity

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

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

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


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

Кроме того, из вашего описания, похоже, что вы используете несколько ненадежный метод для обнаружения конца 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 : conn.send("JOIN %s\r\n" % ",".join(channels)) sent_initial_join = True 

Но, как сказано выше, это никогда не должно быть необходимым. Просто отправить JOINсек сразу после NICK, USERи тому подобное CAP END.

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

Спасибо. Утверждение о том, что сеть не принимает команды объединения каналов до конца MOTD, было основано на моем собственном опыте при написании этого бота. Я не смог заставить его присоединиться к каналу, пока я не дождался окончания разговора с сервером. Я полностью осознаю, насколько плоха моя текущая настройка, поэтому я ищу лучший способ справиться с ней. Точно так же я знаю о недостатках 10-секундного тайм-аута. Спасибо за ссылку, которая должна помочь мне сделать бота намного более портативным: D LiamMeron 10 лет назад 0
@LiamMeron Это, вероятно, связано с некоторой ошибкой в ​​вашем боте, например, предположением, что конкретное сообщение должно быть ответом на конкретную команду. David Schwartz 10 лет назад 0
Серверы freenode настроены на задержку ответов до 1-2 секунд после MOTD, но они * всегда * отправляют ответы; Я проверил это. grawity 10 лет назад 0
Да, вы все правы! Я просто переписал необходимые части кода, чтобы просто продолжить и отправить команду JOIN, и это работает. Я не знаю, что это за ошибка, но я думаю, тот факт, что она теперь работает, делает мой вопрос довольно спорным. Тем не менее, я все еще чему-то научился, поэтому, как говорит мой друг, «время никогда не теряется, пока что-то учат». Спасибо! LiamMeron 10 лет назад 0
некоторые [ответ] (http://stackoverflow.com/a/2969441/1986995) говорят, что нам нужно подождать, а другие, например, ваши, говорят, что мы этого не делаем. freeforall tousez 9 лет назад 0
@freeforalltousez: Этот ответ неверен. Если вы выполните то, что написано во втором абзаце, вы не сможете подключиться к половине сетей _at all_, потому что их ircds не поймет, что вы подключены, пока _you_ не отправит некоторые данные. _ (Они используют функцию, называемую «отложенное принятие»; она служит защитой от некоторых атак.) _ Некоторые даже не имеют _ что-либо отправлять; Первоначальные уведомления - просто вежливая информация о медленных проверках, и я видел сети, которые не выполняют такие проверки, поэтому они также не отправляют приветствие. grawity 9 лет назад 0