如何仅在触发当前命令时使用命令?

Posted

技术标签:

【中文标题】如何仅在触发当前命令时使用命令?【英文标题】:How to use commands only when a current command is triggered? 【发布时间】:2018-12-09 06:38:30 【问题描述】:

这个问题可能很复杂,我的大脑无法很好地解释它,所以请用这个蹩脚的解释来解释,我的问题,当你触发一个命令时,例如 .start 它将开始让我们说一个基于文本的游戏,当然您将拥有能够实际玩游戏的命令,但我担心人们仍然可以触发游戏内命令而无需启动游戏。

     if message.content.startswith("/play"):       #Here is the play command where you execute the game to start
         await client.send_message(message.channel, "Welcome to the game!")
     if message.content.startswith("/examine):
         await client.send_message(message.channel, "You examined the rock and well, got a rock!") #In-Game commands/movements

我的意思是,有没有办法只有在游戏本身被激活时才能使用游戏中的命令? 附加问题:您将如何存储用户的信息,例如基本上保存游戏(您实际上不需要回答这个问题,因为我想自己学习,但任何提示都会很棒!)

【问题讨论】:

游戏是按玩家级别还是按频道级别进行的?您可以看到一个如何将数据持久保存在文件中的示例in this question 它的每个玩家。我在问题中所说的担心是您仍然可以在游戏之外触发命令。 【参考方案1】:

首先,我们需要一些对象来存储特定会话的状态。我们可以直接称这个对象为Game。我们将维护discord.Users 到Games 的映射。此映射中存在User 表示他们正在玩游戏。一些基础知识类似于:

from discord.ext import commands

class Game:
    def __init__(self):
        self.points = 0
        self.inventory = []

bot = commands.Bot('/')

sessions = 

@bot.command(pass_context=True)
async def play(ctx):
    if ctx.message.author.id in sessions:
        await bot.say("You're already playing")
        return
    sessions[ctx.message.author.id] = Game()
    await bot.say("Welcome to the game!")

@bot.command(pass_context=True)
async def quit(ctx):
    if ctx.message.author.id not in sessions:
        await bot.say("You're not playing the game")
        return
    del sessions[ctx.message.author.id]
    await bot.say("Game Over")

@bot.command(pass_context=True)
async def examine(ctx):
    session = sessions.get(ctx.message.author.id, None)
    if session is None:
        await bot.say("You're not playing the game")
        return
    session.inventory.append("A rock")
    await bot.say("You examined the rock and well, got a rock!")

bot.run("TOKEN")

您可以做一些事情来扩展它:利用checks 和CommandErrors 避免重复检查会话的代码;确保Games 是pickleable,并编写使用pickle 保存游戏的代码;写一个比收集石头更有趣的游戏。

【讨论】:

嗨!感谢您的回答,但是我尝试了您的代码,但我的机器人没有回复我,也没有显示任何类型的错误,我尝试一点一点地自定义文本(哈哈)我不能似乎找到了问题,或者我只是愚蠢。 class Game: def __init__(self): self.points = 0 self.inventory = [] sessions = @bot.command(pass_context=True) async def test(ctx): if ctx.message.author.id in sessions: await bot.say("oof") return sessions[ctx.message.author.id] = Game() await bot.say("oof 2") @Cupcake 你有on_message 活动吗?见:***.com/questions/49331096/… 抱歉回复晚了,但我不认为我是?可能是因为我使用@client.event 而不是@bot.command? 这是我的代码 btw class Game: def __init__(self): self.points = 0 self.inventory = [] sessions = @client.event async def club(ctx): if ctx.message.author.id in sessions: await bot.say("Your already in the game!") return sessions[ctx.message.author.id] = Game() await bot.say("Welcome to the game!") 这行不通,有几个原因。您同时引用了clientbot。您应该有一个代表您的机器人的 commands.Bot 对象。在您拥有client 的任何地方都将其替换为bot@bot.event 用于注册事件处理程序。 There is a limited list of events that discord.py handles by default. 你想使用 @bot.command 就像我在上面所做的那样来定义命令。你可以在这里找到一些基本的说明discordpy.readthedocs.io/en/rewrite/ext/commands/commands.html

以上是关于如何仅在触发当前命令时使用命令?的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 opsworks 部署时仅在特定层中的第一个实例上运行命令?

如何在不和谐中使用命令切换触发 Cog 侦听器

如何禁用按钮的 Enter 键

BigQuery bq 命令 - 仅在表为空或不存在时加载

如何在仅在前台运行的后台命令中运行?

将仅在启动时运行一次的 Elastic Beanstalk 配置命令放在哪里?