Wie kann ich mit einem Bot IRC-Server-MOTDs vermeiden oder damit umgehen?

1052
LiamMeron

Ich habe einen IRC-Bot in Python geschrieben, der ziemlich gut funktioniert. Ich denke, das Problem liegt in meinem begrenzten Wissen über das IRC-Protokoll, daher sind hier IRC-Gurus besonders willkommen: D

Wenn Sie sich zum ersten Mal mit einem IRC-Netzwerk verbinden, wird normalerweise ein MOTD angezeigt. Das Netzwerk akzeptiert keine Befehle, bis der MOTD abgeschlossen ist. Bei meinem Bot muss ich also eine Schleife haben, die nach dem Ende der MOTD sucht. Dies ist überhaupt nicht besonders modular, da meines Erachtens nicht alle Server ihre MOTDs auf dieselbe Weise beenden. Gibt es eine Möglichkeit, dem Server mitzuteilen, dass er den MOTD nicht senden soll, oder tatsächlich eine bessere Möglichkeit, auf das Ende des MOTD zu warten, um dem Server mitzuteilen, zu welchem ​​Kanal ich mich verbinden möchte?

Mein aktueller Code für das Warten auf das Ende von MOTD besteht aus einer while-Schleife, die den Eingangspuffer liest und jeden vollständigen Befehl in eine Liste parst. Er nimmt diese Liste und durchsucht jedes Zeichenkettenobjekt nach einer bestimmten Zeichenfolge, die am Ende von FreeNodes MOTD angezeigt wird. Wenn es gefunden wird, endet die Schleife und ein Befehl zum Verbinden eines Kanals wird gesendet, bevor die Hauptschleife aufgerufen wird.

Gibt es einen besseren Weg, mit den MOTDs umzugehen? Ich kann nicht anders als das Gefühl, dass dieser Weg ziemlich unbeholfen ist.

1
Ich kenne weder Python noch IRC-Sachen, aber ich kann mir vorstellen, Sie könnten es einfach 10 Sekunden warten lassen oder so, bevor es aktiviert wird. Frank vor 10 Jahren 0
Sie müssen nicht warten, bis der MOTD fertig ist, um Befehle zu senden. Sie erhalten die Ergebnisse später nur. BatchyX vor 10 Jahren 1
@ chipperyman573 Ich habe daran gedacht, aber es reibt mich den falschen Weg, mich auf einen Timer zur Authentifizierung zu verlassen. Meines Erachtens kann dies hinsichtlich der Modularität so viele Probleme verursachen wie mein aktuelles Setup. LiamMeron vor 10 Jahren 0

1 Antwort auf die Frage

2
grawity

Gibt es eine Möglichkeit, dem Server mitzuteilen, dass er den MOTD nicht senden soll, oder tatsächlich eine bessere Möglichkeit, auf das Ende des MOTD zu warten, um dem Server mitzuteilen, zu welchem ​​Kanal ich mich verbinden möchte

Nein, es gibt keine Möglichkeit, den MOTD auszuschalten. Es sollte jedoch nicht einmal notwendig sein, da Ihre Annahme, dass "das Netzwerk keine Befehle akzeptiert, bis die MOTD abgeschlossen ist", überhaupt nicht wahr ist.

Alle Netzwerke akzeptieren sofort nach der Registrierung Befehle (dh Senden NICKund Senden USER) - einige von ihnen verzögern die Bearbeitung dieser Befehle lediglich um ein oder zwei Sekunden. Es ist absolut gültig, Befehle so bald wie möglich zu senden.


In jedem Fall müssen Sie die Hauptschleife nicht verzögern, um dies zu erreichen. In der Tat sollten alle empfangenen Eingaben von derselben Schleife behandelt werden. Stattdessen würden Sie einfach nachverfolgen, ob Sie bereits eine "Ende von MOTD" -Zeile gesehen haben, und die JOINs beim ersten Mal senden .

Aus Ihrer Beschreibung klingt es auch so, als würden Sie eine etwas unzuverlässige Methode verwenden, um das Ende von MOTD zu erkennen. Wenn Sie nach der Zeichenfolge "End of / MOTD" suchen - nicht. Analysieren Sie stattdessen die gesamte Zeile gemäß RFC 1459 § 2.3.1 (hier ist kein Pythonic-Parsonic- Parser ) und überprüfen Sie den Befehl in jeder Zeile, da der beschreibende Text zwischen verschiedenen IRC-Daemons variieren kann. Sie sollten auch nach der Meldung "no / MOTD" suchen.

Zum Beispiel hätten Sie:

# 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 

Aber wie gesagt, das sollte niemals nötig sein. Senden Sie einfach die JOINs unmittelbar nach NICK, USERund solche Dinge CAP END.

Und bei den Göttern sollte man nicht so dumm wie einen Timeout von 10 Sekunden verwenden.

Thank you. The statement regarding the network not accepting channel join commands before the end of the MOTD was based off of my own experience when writing this bot. I was unable to get it to join the channel, unless I waited for the server to finish talking. I am entirely aware of how bad my current setup is, which is why I am looking for a better way of dealing with it. Similarly I am aware of the flaws of the 10 second timeout. Thank you for the link, that should help me to make the bot much more portable :D LiamMeron vor 10 Jahren 0
@LiamMeron Das liegt wahrscheinlich an einem Fehler in Ihrem Bot, z. B. der Annahme, dass eine bestimmte Nachricht eine Antwort auf einen bestimmten Befehl sein muss. David Schwartz vor 10 Jahren 0
Die freenode-Server sind so konfiguriert, dass sie die Antworten bis zu 1-2 Sekunden nach der MOTD verzögern, aber sie * senden * immer die Antworten. Ich habe das getestet. grawity vor 10 Jahren 0
Yup, y'all are right! I just re-wrote the necessary parts of the code to just go ahead and send the JOIN command, and it works. I dunno what the bug was, but I guess the fact that it now works renders my question fairly moot. However, I still learned something, so as a friend says, "Time is never wasted, so long as something is learned." Thanks! LiamMeron vor 10 Jahren 0
Einige [Antwort] (http://stackoverflow.com/a/2969441/1986995) sagen, wir müssen warten, und andere, wie Ihre, sagen, dass wir das nicht tun. freeforall tousez vor 9 Jahren 0
@freeforalltousez: Diese Antwort ist falsch. Wenn Sie das tun, was der zweite Absatz sagt, können Sie sich nicht mit der Hälfte der Netzwerke verbinden _at all_, da ihre ircds nicht erkennen, dass Sie verbunden sind, bis _you_ einige Daten sendet. _ (Sie verwenden eine Funktion mit der Bezeichnung "verzögerte Annahme"; sie dient als Schutz gegen einige Angriffe.) _ Manche haben nicht einmal etwas zu senden; Bei den ersten Hinweisen handelt es sich lediglich um Höflichkeitsinformationen über langsame Überprüfungen. Ich habe gesehen, dass Netzwerke solche Überprüfungen nicht durchführen. Daher wird auch keine Begrüßung gesendet. grawity vor 9 Jahren 0