IRC阅读插座 [英] IRC Reading Sockets

查看:98
本文介绍了IRC阅读插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个机器人,除了输入内容外,大多数东西都准备就绪.我想要这样的东西:!test word",并让它输出类似"word2"的东西.这是我用来输出数据的代码.我也想找出我的用户名(opername).抱歉,如果页面上的缩进不可用;对我来说很好.

I am making a bot and have most everything ready except input. I want to have something like this: "!test word" and have it output something like "word2". Here is the code that I am using to output data. I would also like to find out my username (opername). Sorry if the indenting is off on the page; it's just fine on my end.

while True:

    data = irc.recv ( 4096 )
    if data.find ('PING' ) != -1:
      irc.send ('PONG ' + data.split() [ 1 ] + '\r\n' )

    if data.find ('!quit') != -1:
      irc.send ('QUIT\r\n')

    if data.find ('!enc %s\r\n' % werd) != -1:
      irc.send ("PRIVMSG %s :%s\r\n" % (channel,werd))

推荐答案

您的代码中存在一个基本缺陷,必须对其进行修复,然后才能进一步解决.

There's a fundamental flaw in your code that has to be fixed before you can get any further.

IRC是基于行的协议,但是您不是逐行阅读的.相反,您一次最多读取4096个字节.那可能返回一行的前半部分,或者一行的中间三分之一,或者一行的最后三分之一,然后是两个完整的行,以及第四个字符的前两个字符.

IRC is a line-based protocol, but you're not reading line by line. Instead, you're reading up to 4096 bytes at a time. That could return the first half of a line, or the middle third of a line, or the last third of a line followed by two complete lines and the first two characters of the fourth.

如果您不明白为什么会出现问题,请想象:假设一个read返回以'\r\nPI'结尾的内容,而下一个返回以'NG foo\r\n'开头的内容.这些都不符合您的find('PING'),因此您将错过该命令.

If you don't understand why this is a problem: Imagine that one read returns something ending in '\r\nPI', and the next one returns something starting with 'NG foo\r\n'. Neither of those will match your find('PING'), so you'll miss the command.

最简单的方法是将循环更改为以下形式:

The easiest way around this is to change your loop to something like this:

for line in irc.makefile():

作为次要说明,您可能希望使用'!quit' in data而不是data.find ('!quit') != -1.

As a minor note, you probably want '!quit' in data rather than data.find ('!quit') != -1.

最后,我认为这不是您真正想要的(尽管我可能错了):

Finally, I don't think this is what you actually want (although I could be wrong):

if data.find ('!enc %s\r\n' % werd) != -1:
    irc.send ("PRIVMSG %s :%s\r\n" % (channel,werd))

如果werd是来自其他地方的静态字符串,这将起作用,但是根据您的描述,这听起来像您希望能够捕获任何命令!enc foo\r\n并返回PRIVMSG #chan: foo\r\n,并且还捕获!enc bar\r\n并返回PRIVMSG #chan: bar\r\n,依此类推,以防有人输入.为此,您可能需要一个正则表达式,或者您只需要稍微复杂一些的字符串处理代码(例如,用空格分隔data,并且如果有任何元素与'!enc'匹配,则下一个元素是要发回的单词).

This will work if werd is a static string that came from somewhere else, but from your description, it sounds like you want to be able to catch any command !enc foo\r\n and return PRIVMSG #chan: foo\r\n, and also catch !enc bar\r\n and return PRIVMSG #chan: bar\r\n, and so on for any other possibility that someone might type. For that, you may want a regular expression, or you may just want slightly more complicated string-processing code (e.g., split data by whitespace, and if any element matches '!enc', the next element is the word to send back).

这是一种可能会或可能不会像您尝试做的事情的一种方式的示例:

Here's an example of one way to do something that may or may not be like what you're trying to do:

m = re.search(r'!enc (.*)\r\n', line)
if m:
    irc.send('PRIVMSG %s: %s\r\n' % (channel, m.group(1)))

我想要类似这样的内容:!test word",并输出类似"word2"的内容

I want to have something like this: "!test word" and have it output something like "word2"

好的,那么当给定"word"时,如何确定您想要"word2"?无论规则是什么,显然您都必须在某个地方编写该规则.或者,如果您需要编码方面的帮助,则必须向我们描述.

OK, so how does it figure out that you want "word2" when given "word"? Whatever the rule is, you obviously have to code that rule up somewhere. Or, if you need help coding it up, you have to describe it to us.

从评论中:

我只想要!test x".用户输入!test x",我对"x"进行填充并输出更改

I just want "!test x". The user enters "!test x", I do stuff to "x" and output the changes

我假设您在此处将x用作元变量,而不是字面量-也就是说,如果用户执行"!test x",则对"x"进行填充,如果用户执行"!test y",则对到"y"之类的东西.如果我错了,请告诉我.

I'm assuming you're using x here as a metavariable, not a literal—that is, if the user does "!test x" you do stuff to "x", if the user does "!test y" you do stuff to "y", etc. If I'm wrong, please let me know.

很明显,上面的代码不会抓住这个问题,因为它是在搜索"enc"而不是"test".但这是一个微不足道的变化:

Obviously the code above isn't going to catch that, because it's searching for "enc" rather than "test". But that's a trivial change:

m = re.search(r'!test (.*)\r\n', line)

对于在输出x之前对x进行处理",m.group(1)是上面的x,所以:

And as for "do stuff" to x before outputting it, m.group(1) is the x above, so:

if m:
    irc.send('PRIVMSG %s: %s\r\n' % (channel, do_stuff_to(m.group(1))))

如果您不确定要发送,接收和解析的内容,则可以随时添加一条打印语句来进行测试:

If you're not sure what you're sending, receiving, and parsing, you can always add a print statement to test things out:

m = re.search(r'!test (.*)\r\n', line)
print m, m.groups() if m else ''
if m:
    print 'got %s, sending %s' % (m.group(1), do_stuff_to(m.group(1))))
    irc.send('PRIVMSG %s: %s\r\n' % (channel, do_stuff_to(m.group(1))))

如果您想查看套接字上发生了什么,可以通过两种方法:安装 wireshark 并用它来监视网络上的消息,或者使用 netcat 设置伪造的服务器.我不会解释前者,因为要解释的东西太多了,并且已经有不错的教程了.但是对于后者,就这么简单:打开一个终端并运行nc -kl 8888.然后让您的机器人连接到localhost:8888而不是远程服务器.观察机器人发送给您的内容,然后将回复内容键入或粘贴到终端窗口中. (在Windows以外的几乎所有平台上,nc都是内置的;在Windows上,您需要从某处获取netcat或ncat,但是我很确定Wikipedia页面具有链接.)如果需要进行大量调试,则可以将netcat设置为代理,该代理仅在bot和真实服务器之间来回转发消息并打印出通过的所有内容.

If you want to watch what's going over the socket, there are two ways to do that: Install wireshark and use it to spy on the messages on the wire, or set up a fake server using netcat. I won't explain the former, because there's too much to explain, and there are already good tutorials. But for the latter, it's as simple as this: Open a terminal and run nc -kl 8888. Then have your bot connect to localhost:8888 instead of the remote server. Watch what the bot sends to you, and type or paste the replies into the terminal window. (On almost any platform but Windows, nc comes built in; on Windows you need to get netcat or ncat from somewhere, but I'm pretty sure the Wikipedia page has links.) If you need to do a lot of debugging, you can set netcat up as a proxy that just forwards messages back and forth between your bot and the real server and prints out everything that passes through.

这篇关于IRC阅读插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆