有没有办法在Discord.py中“隐藏”命令的参数

2024-05-23 19:09:53 发布

您现在位置:Python中文网/ 问答频道 /正文

对于我的机器人,我想实现随机游戏(比如掷硬币),以及在上面的投注系统。 例如,任何人都可以使用//抛硬币,机器人会回答“正面”或“反面”,但如果命令是//下注15抛硬币,机器人也会回答“正面”或“反面”,但也会在“祝贺你赢了X”或“你输了赌注”之后说

    @commands.command()
    async def coin_toss(self, ctx: Context):
        outcomes = ("Heads", "Tails")
        result = outcomes[random.randint(0,1)]
        await ctx.reply(result)
        return result 

问题是,我希望//coin\u toss命令没有可通过调用该命令传递的参数,但我仍然希望在通过self调用该命令时传递参数。这也适用于调用self.coin\u toss

command: Command = utils.get(self.get_commands(), name=game_name)
result = await command(ctx, amount_to_bet)

目前,我使用*args“收集”用户试图传递的所有参数,但我不知道在通过通道中的消息调用命令时是否可以绕过这些参数

    @commands.command(aliases=["pile_ou_face", "pof"])
    @has_user_role_from_config()
    async def coin_toss(self, ctx: Context, *args, amount_to_bet: float = 0):
        outcomes = ("Heads", "Tails")
        result = outcomes[random.randint(0,1)]
        await ctx.reply(result)
        return result 

有办法吗?如果您想要更精确,请随时发表评论


Tags: 命令self参数asyncdef机器人硬币result
1条回答
网友
1楼 · 发布于 2024-05-23 19:09:53

我不确定这是否回答了您关于隐藏discord命令的参数的问题,但我认为这可能会让您了解如何在不需要进行太多参数解析的情况下在其他游戏命令中实现bet命令

我有两个建议。将抛硬币视为下注功能的子例程,或实现抛硬币功能的共享逻辑实现

投币作为下注的一个子程序

import os
import random

from discord.ext import commands
from dotenv import load_dotenv

load_dotenv()

DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")

bot = commands.Bot(command_prefix="//")


@bot.command()
async def coin_toss(ctx):
    outcomes = ("Heads", "Tails")
    result = outcomes[random.randint(0, 1)]
    await ctx.reply(result)
    return result


# Simulates your Utils Get Function
def get_commands():
    return [coin_toss]


def get_command_by_name(command_list, name):
    names = [c.name for c in command_list]
    if name not in names:
        return None
    else:
        return command_list[names.index(name)]


@bot.command()
async def bet(ctx, *args):
    if len(args) != 3:
        # Example //bet 15 Heads coin_toss
        await ctx.reply("Command is //bet amount outcome game_name")

    c = get_command_by_name(get_commands(), name=args[2])

    # Check Command Exists
    if c is None:
        await ctx.reply(f"Command {args[2]} does not exist")
    else:
        # Assumes result comes back as a string!!
        result = await c(ctx)
        # Compare case insensitive
        if result.lower() == args[1].lower():
            msg = f"Congratulation you won {args[0]}"
        else:
            msg = f'You lost your bet of {args[0]}'
        await ctx.reply(msg)


bot.run(DISCORD_TOKEN)

我这里有一个模拟的get_commandsutils.get(self.get_commands(), name=value)函数,因此请更新bet实现以反映函数的实际执行情况。为了便于测试,我也在类之外做了这项工作,但请进行必要的更改,将此代码合并到您当前的实现中

这种方法的缺点是延迟。您实际上发送了两个单独的回复,一个来自coin_toss函数,另一个来自bet。这可能会造成延迟的用户体验

抛硬币与共享逻辑实现

import os
import random

from discord.ext import commands
from dotenv import load_dotenv

load_dotenv()

DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")

bot = commands.Bot(command_prefix="//")


# Separated Game Logic from the Bot Command
def coin_toss_logic():
    outcomes = ("Heads", "Tails")
    result = outcomes[random.randint(0, 1)]
    return result


@bot.command()
async def coin_toss(ctx):
    await ctx.reply(coin_toss_logic())


# Simulates your Utils Get Function
def get_commands():
    return [coin_toss_logic]


def get_command_by_name(command_list, name):
    # Strip off the "_logic" portion of your command names
    # uses __name__ since not a command anymore
    # Requires a consistent naming convention!
    names = [c.__name__[:-6] for c in command_list]
    if name not in names:
        return None
    else:
        return command_list[names.index(name)]


@bot.command()
async def bet(ctx, *args):
    if len(args) != 3:
        # Example //bet 15 Heads coin_toss
        await ctx.reply("Command is //bet amount outcome game_name")

    c = get_command_by_name(get_commands(), name=args[2])

    # Check Command Exists
    if c is None:
        await ctx.reply(f"Command {args[2]} does not exist")
    else:
        # Assumes result comes back as a string!!
        # No await needed since it's not an asyc command
        result = c()
        # Need to add Result to msg since not handled by command anymore
        msg = f'{result}\n'
        # Compare case insensitive
        if result.lower() == args[1].lower():
            msg += f"Congratulation you won {args[0]}"
        else:
            msg += f'You lost your bet of {args[0]}'
        await ctx.reply(msg)


bot.run(DISCORD_TOKEN)

这种实现的好处是消息之间的延迟更少,但是,由于您有两个基本上都映射到同一名称的独立函数,因此需要做更多的工作

相关问题 更多 >