Load cog for multiple bots

核能气质少年 提交于 2019-12-08 17:40:04

问题


Using discord.py, I can run multiple bots from one piece of code, but I'm looking for a way to load a cog or extension into multiple bots. For a test case, I have bot.py, which handles loading the cog and starting the bot, and cog.py which is a simple cog that incrementally adds 1 to a counter

bot.py

from discord.ext import commands
import asyncio

client1 = commands.Bot(command_prefix='!')
client2 = commands.Bot(command_prefix='~')

client1.load_extension('cog')
client2.load_extension('cog')

@client1.event
async def on_ready():
    print('client1 ready')

@client1.command()
async def ping():
    await client1.say('Pong')

@client2.event
async def on_ready():
    print('client2 ready')

@client2.command()
async def ping():
    await client2.say('Pong')

loop = asyncio.get_event_loop()
loop.create_task(client1.start('TOKEN1'))
loop.create_task(client2.start('TOKEN2'))
loop.run_forever()

cog.py

from discord.ext import commands

class TestCog:

    def __init__(self, bot):
        self.bot = bot
        self.counter = 0

    @commands.command()
    async def add(self):
        self.counter += 1
        await self.bot.say('Counter is now %d' % self.counter)


def setup(bot):
    bot.add_cog(TestCog(bot))

Using !ping will make client1 respond with Pong, while using ~ping will make client2 respond with Pong, which is expected behaviour.

However, only one of the bots will respond to both !add and ~add, with the counter increasing with either command. This seems dependent on which bot loads the cog last.

Is there a way to have the correct bot respond to the correct command while also having the counter increase with either command? I know I can split it into two cogs and save the result to a file for example, but is it possible to do it without saving the counter to disk?


回答1:


This is due to the the @commands.command() only loaded once. Therefore, both of the bots shared the same Command instance. What you need is to add the command on an instance level, and not by the @commands.command() decorator.

class TestCog:
    counter = 0

    def __init__(self, bot):
        self.bot = bot
        self.bot.add_command(commands.Command('add', self.add))

    async def add(self):
        TestCog.counter += 1
        await self.bot.say('Counter is now %d' % TestCog.counter)

or:

class TestCog:
    counter = 0

    def __init__(self, bot):
        self.bot = bot
        self.bot.command()(self.add)

    async def add(self):
        TestCog.counter += 1
        await self.bot.say('Counter is now %d' % TestCog.counter)

In order to make both bots share the same attribute. You want class attribute, not instance's.



来源:https://stackoverflow.com/questions/49302170/load-cog-for-multiple-bots

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!