2014-10-17 41 views
5

(非母语英语,很抱歉可能英文不好,我也是编程的新手)。
你好,我试图连接到使用QueryServer的TeamSpeak服务器来制作一个bot。经过几天的苦苦挣扎之后,它才有效,只有一个问题,并且我被这个问题困住了。如何保持python 3脚本(Bot)运行

如果需要检查,这是我使用的TeamSpeak API:http://py-ts3.readthedocs.org/en/latest/api/query.html

这是什么是真正在我的脚本发生摘要:

  1. 它连接。
  2. 它检查信道ID(和它自己的客户端ID)
  3. 它加入的信道
  4. 脚本结束,因此它断开。

我的问题是:我怎样才能使它不会断开?如何让脚本保持“等待”状态,以便在有人在频道中键入“hi bot”时读取脚本?所有需要阅读文本和回答它们的代码似乎都很容易编程,但是我遇到了一个问题,我无法让机器人“运行”,因为它一结束运行脚本就关闭文件。

更多信息:
我使用Python的3.4.1
我试着学习线程http://www.tutorialspoint.com/python/python_multithreading.htm,但不管是哑巴还是不按我想的方式工作。
在API中有一个名为on_event的函数,我希望始终保持运行。机器人代码只应运行一次,然后保持“等待”,直到事件发生。我应该怎么做?没有线索。

代码:

import ts3 
import telnetlib 
import time 

class BotPrincipal: 
    def Conectar(ts3conn): 
     MiID = [i["client_id"] for i in ts3conn.whoami()] 
     ChannelToJoin = "[Pruebas] Bots" 
     ts3conn.on_event = BotPrincipal.EventHappened() 
     try: 
      BuscandoIDCanal = ts3conn.channelfind(pattern=ChannelToJoin) 
      IDCanal = [i["cid"] for i in BuscandoIDCanal] 
      if not IDCanal: 
       print("No channel found with that name") 
       return None 
      else: 
       MiID = str(MiID).replace("'", "") 
       MiID = str(MiID).replace("]", "") 
       MiID = str(MiID).replace("[", "") 
       IDCanal = str(IDCanal).replace("'", "") 
       IDCanal = str(IDCanal).replace("]", "") 
       IDCanal = str(IDCanal).replace("[", "")     
       print("ID de canal " + ChannelToJoin + ": " + IDCanal) 
       print("ID de cliente " + Nickname + ": " + MiID) 
      try: 
       print("Moving you into: " + ChannelToJoin) 
       ts3conn.clientmove(cid=IDCanal, clid=MiID) #entra al canal 
       try: 
        print("Asking for notifications from: " + ChannelToJoin) 
        ts3conn.servernotifyregister(event="channel", id_=IDCanal) 
        ts3conn.servernotifyregister(event="textchannel", id_=IDCanal) 
       except ts3.query.TS3QueryError: 
        print("You have no permission to use the telnet command: servernotifyregister") 
       print("------- Bot Listo -------") 
      except ts3.query.TS3QueryError: 
       print("You have no permission to use the telnet command: clientmove") 
     except ts3.query.TS3QueryError: 
      print("Error finding ID for " + ChannelToJoin + ". telnet: channelfind") 

    def EventHappened(): 
     print("Doesn't work") 

# Data needed # 
USER = "thisisafakename" 
PASS = "something" 
HOST = "111.111.111.111" 
PORT = 10011 
SID = 1 

if __name__ == "__main__":  
    with ts3.query.TS3Connection(HOST, PORT) as ts3conn: 
     ts3conn.login(client_login_name=USER, client_login_password=PASS) 
     ts3conn.use(sid=SID) 
     print("Connected to "+HOST) 
     BotPrincipal.Conectar(ts3conn) 
+1

作为一个方面说明,这不是你如何使用类。你的'Conectar'应该带一个'self'参数,你的主代码应该构造一个'BotPrincipal'实例并且调用该实例的'Conectar'方法等等。这是3个错误组合消除这种工作,这可能不是你想要依赖的东西。 – abarnert 2014-10-17 19:09:16

+1

只需添加到abarnets注释,只需看看[Python的官方文档](https://docs.python.org/3.4/tutorial/classes.html#a-first-look-at-classes)或一些[不同的教程](http://en.wikibooks.org/wiki/A_Beginner's_Python_Tutorial/Classes)。 – Vyktor 2014-10-17 19:25:31

+0

因为我从来没有真正学过任何编程语言,我只是用谷歌来努力,我可以看到我失败的地方。我正在查看该网站,并试图解决这些问题。我很感激帮助。 – Saelyth 2014-10-17 19:39:37

回答

3

从API的一个快速一瞥,它看起来像你需要明确地告诉ts3conn对象等待事件。似乎有几个方法可以做到这一点,但ts3conn.recv(True)似乎是最明显的:

块,直到所有的未提取的反应已经收到或永远,如果recv_forever是真实的。

大概在每个命令进入时,它会调用你的on_event处理函数,那么当你返回时它将回到永久等待下一个命令。

我不知道你在这里或不需要的线程,但recv_in_thread的文档使它听起来像是你可能:

呼叫recv()在一个线程。这很有用,如果您使用servernotifyregister并且您希望接收事件。

你大概想要同时得到servernotify事件和命令,我猜这个库的写法你需要线程吗?如果是这样,请致电ts3conn.recv_in_thread()而不是ts3conn.recv(True)。 (如果你看看the source,所有这些都会启动一个后台线程,并在该线程上调用self.recv(True))。

+0

让我看看我是否明白这一点。我应该在def EventHappened()中调用ts3conn.recv_in_thread():它会创建自己的线程,所以我不需要自己做? – Saelyth 2014-10-17 20:13:41

+0

@Saelyth:不在'EventHappened'里面,或者在'Conectar'结尾,或者在'Conectar'返回后的主代码中。是的,它创建自己的线程,所以你不必。除非你试图在你的处理程序中完成依赖于全局变量或其他共享变量的东西,否则你甚至不必担心线程存在的事实。 – abarnert 2014-10-17 21:15:58

+0

耶!谢谢你的答案:D – Saelyth 2014-10-17 21:43:59