0

私は Python で IRC ボットを作成しました。IRC コマンドを待機し、メッセージを呼び出し元の関数に返す方法を見つけようとしています。これらのものをゼロから作成することを学ぼうとしているなど、さまざまな理由で外部ライブラリの使用を拒否しています。また、既存のもののドキュメントをふるいにかけましたが、それらは包括的すぎます。シンプルなものを作ってみました。

例えば:

def who(bot, nick):
    bot.send('WHO %s' % nick)
    response = ResponseWaiter('352')  # 352 - RPL_WHOREPLY
    return response.msg

IRC メッセージを解析する Message クラスのオブジェクトを呼び出し元の関数に返します。

def check_host(bot, nick, host):
    who_info = who(bot, nick)
    if who_info.host == host:
        return True
    return False

私はリアクター パターン、オブザーバー パターンを調べ、これのために 100 の異なるイベント システム デザインを実装しようとしましたが、役に立ちませんでした。私は完全に迷っています。

解決策を提供するか、正しい方向に向けてください。これを行う簡単な方法が必要です。

だから私がやったことは、ボットのwhoメソッドから私のジェネレーター(ボットメソッド)からグラブメッセージを使用することです。ジェネレーターは次のようになります。

def msg_generator(self):
    ''' Provides messages until bot dies '''
    while self.alive:
        for msg in self.irc.recv(self.buffer).split(('\r\n').encode()):
            if len(msg) > 3:
                try: yield Message(msg.decode())
                except Exception as e:
                    self.log('%s %s\n' % (except_str, str(e)))

これで、ボットの who メソッドは次のようになります。

def who(self, nick):
    self.send('WHO %s' % nick)
    for msg in self.msg_generator():
        if msg.command == '352':
            return msg

ただし、現在はメッセージを制御しているため、who メソッドに使用していないメッセージを適切なハンドラーに放棄する何らかの方法が必要です。

私のボットは通常、すべてのメッセージを次のように処理します。

def handle(self):
    for msg in self.msg_generator():
        self.log('◀    %s' % (msg))
        SpaghettiHandler(self, msg)

そのため、ボットの who メソッドがジェネレーターを使用してメッセージを受信して​​いる間、私の SpaghettiHandler が処理するメッセージは処理されません。

それは機能しています..そして、メッセージを失うのが難しいほど十分に高速に機能します. しかし、ボットが同時に多くのコマンドを実行すると、これが問題になる可能性があります。この方向で解決策が見つかると確信していますが、関係のないメッセージを放棄するように設定していても、それが良い方法であるかどうかわからないため、これを答えとして作成しませんでしたリスナーに。

4

0 に答える 0