0

I would like to input a command into my bot that waits for a certain response before executing that response command. If that response isn't seen in a minute, it resets.

I thought the time module would be required for this, specifically time.sleep(). However, upon playing around with this, found that time.sleep() runs for its full duration, and can not be stopped until finished. Makes sense when you think about it, hind sight is 20/20. What I have tried:

@commands.command()
@commands.guild_only()
async def challenge(self, ctx):
    # opens and loads in player one's character sheet. This is done in this method solely because I'm unsure if
    # loading json files in __init__ is actually a good idea. If I understand things correctly, things in a class's
    # __init__ is ran EVERY TIME a method is called within it. If so, then the json files would be opened, loaded,
    # and closed multiple times in a single run. Seems inefficient, and bad coding.
    if self.game == 0:
        player = str(ctx.message.author)
        path = os.getcwd()
        charFolder = os.path.join(path + "/characters/")
        charFile = Path(charFolder + player + ".txt")
        if not charFile.is_file():
            await ctx.send("You don't even have a character made to fight. What are you planning to do? Emoji the"
                           "opponent to death? Make a character, first.")
        elif self.game == 0.5:
            await ctx.send("A challenge has already been issued.")
        else:
            self.pOneUsername = ctx.message.author
            file = open(charFolder + player + ".txt", "r", encoding="utf-8")
            charStats = json.load(file)
            file.close()

            self.pOneInfo = charStats

            await ctx.send(self.pOneInfo['name'] + " has issued a challenge. Who accepts? (type !accept)")
            self.game = 0.5
            time.sleep(30)
            await ctx.send("30 seconds to respond to challenge.")
            time.sleep(20)
            await ctx.send("10 seconds to respond to challenge.")
            time.sleep(10)("closing challenge offered.")
            self.game = 0 

I want the game to 'wait' the desired minute, and that works here, but because it is sleeping, it doesn't respond to anyone typing '!accept' the command to accept a challenge, until the minute has passed, and by then, python self.game has been reset to 0, making the '!accept' command not work. Any ideas or steps on how to get the desired result?

the !accept command, if you need it:

player = str(ctx.message.author)
path = os.getcwd()
charFolder = os.path.join(path + "/characters/")
charFile = Path(charFolder + player + ".txt")
if not charFile.is_file():
    await ctx.send("You don't even have a character made to fight. What are you planning to do? Emoji the "
                   "opponent to death? Make a character, first.")
elif ctx.message.author == self.pOneUsername:
    await ctx.send("You can't fight yourself. This isn't Street Fighter.")
else:
    self.game = 1
    self.pTwoUsername = ctx.message.author
    file = open(charFolder + player + ".txt", "r", encoding="utf-8")
    charStats = json.load(file)
    file.close()

    self.pTwoInfo = charStats

    self.pOneTotalHP = self.pOneInfo['hp']
    self.pTwoTotalHP = self.pTwoInfo['hp']
    self.pOneCurrentHP = self.pOneInfo['hp']
    self.pTwoCurrentHP = self.pTwoInfo['hp']
    self.pOneLevel = self.pOneInfo['level']
    self.pTwoLevel = self.pTwoInfo['level']
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
A Python
  • 83
  • 8
  • Does this solution https://stackoverflow.com/questions/492519/timeout-on-a-function-call/494273#494273 solve your problem? – Claudio Jul 03 '19 at 04:15
  • I don't think so, most answers there seem to revolve around signal, which I guess needs a UNIX platform to work properly? I'm windows 10 I'm not that amazing a programmer to follow all the replies 100%. There might be a few in their that help my situation. – A Python Jul 03 '19 at 04:25
  • Then again, the answer from that link might be staring me straight in the face, and I wouldn't know it. I'm assuming by the answers found there, multi-threading seems to be the answer, but I've never worked with multi-threading before, and copy/pasting some of the examples there doesn't help me to figure out how to implement it into my own code. – A Python Jul 03 '19 at 06:12
  • You need to use [`wait_for`](https://discordpy.readthedocs.io/en/latest/api.html#discord.Client.wait_for) to wait for messages. Instead of having multiple commands each representing different states of the games, you have a single coroutine that listens for input at certain times. – Patrick Haugh Jul 03 '19 at 13:33

0 Answers0