我正在运行一个IRC机器人,我终于想出了如何正确地获取用户的身份验证。我现在正在寻求实施此检查以引用我的数据库,而不是依赖于他们的用户名。
我有一个命令
def privmsg(self, user, channel, msg):
if msg.startswith(".join"):
# sends whois signal
irc.IRCClient.whois(self, user, None)
我需要从outcoming source(IRC服务器)调用的函数中获取变量,因此我不能只使用AddCallback
auth = ???
player = db.getplayer(auth)
我正在通过
收到身份验证def irc_330(self, prefix, params):
auth = params[2]
我似乎无法弄清楚如何将变量发送回第一个函数,或者甚至如何等待该信号返回。我的第一个函数会在它开始之前传递任何irc_330()。
我能想到的唯一解决方案是创建一个回调函数,它将等待函数内部的调用,然后返回我需要的函数。但这似乎并不正确。
答案 0 :(得分:4)
您遇到的问题是,IRCClient
的API是相当的
很抱歉(对不起!)。具体来说,它有像.whois()
这样的API
应该返回Deferred
,但不要
您可以通过制作这些API的自己的版本来修复此问题,
实际上,返回Deferred
。
一般的想法是,IRC请求和响应没有请求ID,所以
他们总是按顺序回答。这意味着你需要建立一个队列
先进/先出请求,以便您可以将它们作为回复与回复相匹配
到达。此外,您需要将延迟触发与查询的 end 相匹配
(在您的情况下,WHOIS,因此,RPL_ENDOFWHOIS
),因为IRC服务器可能
或者可能不会发送特定字段作为回复的一部分。
以下是一个示例实现:
from collections import deque
from twisted.internet.defer import Deferred
from twisted.words.protocols.irc import IRCClient
class NoAccount(Exception):
"No account found."
class MyClient(IRCClient, object):
def __init__(self):
self._whoisQueue = deque()
def deferredWhois(self, nick):
result = Deferred()
self._whoisQueue.append((result, nick))
self.whois(nick)
return result
def irc_330(self, prefix, params):
self._currentActiveNick = params[2]
def irc_RPL_ENDOFWHOIS(self, prefix, params):
deferredToFire, who = self._whoisQueue.popleft()
currentActiveNick = self._currentActiveNick
self._currentActiveNick = None
if currentActiveNick is None:
deferredToFire.errback(NoAccount(who))
else:
deferredToFire.callback(currentActiveNick)
这会使deferredWhois
方法返回一个Deferred
方法
给定缺口的帐户名称。
希望这有帮助!