我正在尝试建立一个不兼容计时器的机器人。如果有人键入“!challenge”命令,其中一个程序将起作用,在该命令中,机器人将等待60秒以查看是否有人键入“!accept”命令作为响应。如果不是,则说明“挑战已被忽略。重置。”或类似的东西。
另一个计时器实际上是在游戏本身期间运行的,并且长达一个小时。但是,放置命令后,小时会重置。如果游戏空闲一个小时(一个玩家DC或退出),则机器人会重置游戏本身。
我在使用线程:
# Initiate a challenge to the room. Opponent is whoever uses the !accept command. This command should be
# unavailable for use the moment someone !accepts, to ensure no one trolls during a fight.
if message[:10] == "!challenge":
msg, opponent, pOneInfo, new_game, bTimer, playerOne = message_10_challenge(channel, charFolder, message, unspoiledArena, character, self.game)
if opponent is not "":
self.opponent = opponent
if pOneInfo is not None:
self.pOneInfo = pOneInfo
self.pOneTotalHP = self.pOneInfo['thp']
self.pOneCurrentHP = self.pOneInfo['thp']
self.pOneLevel = self.pOneInfo['level']
if new_game != 0:
self.game = new_game
if bTimer is True:
timeout = 60
self.timer = Timer(timeout, self.challengeTimeOut)
self.timer.start()
if playerOne is not "":
self.playerOne = playerOne
super().MSG(channel, msg)
和:
# Response to use to accept a challenge.
if message == "!accept":
msg, pTwoInfo, new_game, playerTwo, bTimer, bGameTimer, new_oppenent, token = message_accept(channel, charFolder, unspoiledArena, character, self.game, self.opponent, self.pOneInfo)
if not charFile.is_file():
super().MSG(channel, "You don't even have a character made to fight.")
else:
if new_game is not None:
self.game = new_game
if pTwoInfo is not None:
self.pTwoInfo = pTwoInfo
self.pTwoTotalHP = self.pTwoInfo['thp']
self.pTwoCurrentHP = self.pTwoInfo['thp']
self.pTwoLevel = self.pTwoInfo['level']
if bTimer:
self.timer.cancel()
if bGameTimer:
gametimeout = 3600
self.gameTimer = Timer(gametimeout, self.combatTimeOut)
self.gameTimer.start()
if new_oppenent is not None:
self.opponent = new_oppenent
if playerTwo is not None:
self.playerTwo = playerTwo
if token is not None:
self.token = token
for msg_item in msg:
super().MSG(channel, msg_item)
具有功能:
def challengeTimeOut(self):
super().MSG(unspoiledArena, "Challenge was not accepted. Challenge reset.")
self.game = 0
def combatTimeOut(self):
super().PRI('Unspoiled Desire', "!reset")
以上是同一游戏的示例,但是在不同的聊天平台上,具有处理计时器的线程。但是我猜线程和discord.py不是朋友。因此,我试图使以上代码与discord.py一起使用,后者似乎使用了asyncio。
想法是在
中使用asyncio.sleep()
if bTimer is true:
await asyncio.sleep(60)
self.game = 0
await ctx.send("Challenge was not accepted. Challenge reset.")
这有效...但是它不会停止计时器,因此即使有人!accepts
从而将bTimer
更改为False
,这也会取消计时器:
if bTimer:
self.timer.cancel()
它仍然会说“挑战未接受。挑战已重置。”
如果我尝试,bGameTimer
也会发生相同的问题:
if bGameTimer:
await asyncio.sleep(3600)
await ctx.send("!reset")
1小时后,无论完成与否,游戏都会被硬连线重置。而不是每转一圈都重置1小时计时器,只有在整整一个小时都没有发出命令的情况下才重置。
有没有一种方法可以轻松取消或重置睡眠周期?
答案 0 :(得分:2)
与您的线程代码等效的异步代码为:
...
if bTimer:
self.timer = asyncio.create_task(self.challengeTimeout())
...
async def challengeTimeout(self):
await asyncio.sleep(60)
self.game = 0
await ctx.send("Challenge was not accepted. Challenge reset.")
asyncio.create_task()
创建一个轻量级的“任务”对象,该对象大致等同于线程。它与您的其他协程“并行”运行,您可以通过调用其cancel()
方法来取消它:
if bTimer:
self.timer.cancel()