简体   繁体   English

Discord.py - 如何为每个服务器制作齿轮

[英]Discord.py - How can I make cogs per-server

I have a public bot that has cogs, but I just tested that if I load/unload a cog then it'll load/unload that cog across every server it's in, this of course is something that's horrible for a public bot我有一个有 cog 的公共机器人,但我刚刚测试过如果我加载/卸载一个 cog 然后它会在它所在的每个服务器上加载/卸载该 cog,这对于公共机器人来说当然是可怕的事情

I'll show my load & unload command:我将展示我的加载和卸载命令:

@client.command()
async def load(ctx, extension):
 client.load_extension(f"cogs.{extension}")

 await ctx.send(f"Successfully loaded the {extension} module :thumbsup: ")

@load.error
async def load_error(ctx, error):
 await ctx.send(f"The following error occured:```\n{error}\n```")

is the load command, and:是加载命令,并且:

@client.command()
async def unload(ctx, extension):
 client.unload_extension(f"cogs.{extension}")

 await ctx.send(f"Successfully unloaded the {extension} module :thumbsup: ")

@unload.error
async def unload_error(ctx, error):
 await ctx.send(f"The following error occured:```\n{error}\n```")

is the unload command是卸载命令

Edit: I wouldn't mind trying something other than what I'm attempting编辑:我不介意尝试我正在尝试的东西以外的东西

You can use a cog_check to check each command in a cog: eg您可以使用cog_check检查 cog 中的每个命令:例如

class MyCog(commands.Cog):
   def cog_check(self, ctx):
      return ctx.guild.id == 123

Since cogs are bound to the bot, loading and unloading them will effect the bot everywhere, there is no better way to make guild only cogs than using this.由于齿轮与机器人绑定,加载和卸载它们会影响机器人无处不在,没有比使用它更好的方法来制作公会齿轮。

A solution to this would be adding a simple check to each command in the cogs you don't want public 解决这个问题的方法是在你不想公开的cogs中为每个命令添加一个简单的检查

#add a check to the top of the cog
def isPrivateCommand():
    async def predicate(ctx):
        return ctx.guild.id == YOURGUILDIDHERE
    return commands.check(predicate)

.
.
.

@commands.command
@isPrivateCommand()
async def ...

This check should make sure that the command will only be executed in your guild (the guild ID you put in the check). 此检查应确保该命令仅在您的公会中执行(您在检查中输入的公会ID)。

Documentation on checks can be found here for discord.py rewrite 有关支票的文档可以在这里找到discord.py重写

Happy coding! 快乐的编码!

cogs belong to the bot, not to a server.齿轮属于机器人,而不是服务器。 So what you try to do is not possible.所以你尝试做的事情是不可能的。 But (i guess you want to do something like dyno has to activate commands in a guild)但是(我猜你想做一些像 dyno 必须在公会中激活命令的事情)

you can save all guilds that "loaded" a command in a database and then add a check to all commands if they are loaded您可以将所有“加载”命令的公会保存在数据库中,然后检查所有命令是否已加载

example_data = {
    "command_name": "example",
    "loaded_guilds": []
}


def isCommandLoaded():
    async def predicate(ctx):
        return ctx.guild.id in example_data["loaded_guilds"]:
    return commands.check(predicate)



@commands.command()
@isCommandLoaded()
async def example(self, ctx):
    """Example ..."""

than just build a load/unload command and save it to the db不仅仅是构建一个加载/卸载命令并将其保存到数据库中

at the setup from cog you could define an Guild array were to sync the tree在 cog 的设置中,您可以定义一个 Guild 数组来同步树

async def setup(bot):
     await bot.add_cog(MyCog(bot), guilds=[discord.Object(id=...)])

now u only need a function that returns all gildsid/where_cogs_synced and u will solve your problem...现在你只需要一个返回所有 gildsid/where_cogs_synced 的函数,你就会解决你的问题......

in a settings.py在 settings.py 中

def GuildsAktive() -> (int, ...):
    GUILDXYZ = 12312213121213121312      # NOQA
    return [GUILDXYZ]

in your bot file在你的机器人文件中

    async def test_sync_tree(self):
        guilds = []
        for gid in settings.GuildsAktive():
            x = await self.fetch_guild(gid)
            guilds.append(x)
        return guilds

in your COG在你的重心

async def setup(bot):
    await bot.add_cog(YOURCOG(bot), guilds=await bot.test_sync_tree())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM