Вы можете использовать on_message
, чтобы переопределить бота от автоматического вызова команд, а затем создать некоторую логику, чтобы вы решили, что он больше не хочет принимать команды (он же сон) .Но убедитесь, что у вас есть возможность как владельца бота разбудить его, или вы СОЛ, и вам нужно будет перезапустить его.
Должно работать что-то вроде следующего.
Допущение в моем коде, что вы используете переделку и f-строки, приемлемо, но логика здесь и очень мало нуждается в изменении, я думаю, что она совместимас версией async
.
Основной поток управления:
bot.py
from discord.ext import commands
class MyBot(commands.bot):
def __init__(self, command_prefix = '!', description=None):
super().__init__(command_prefix, description)
#you could just say False here but if you
#want to start the bot asleep here's a decent way to do it.
self.asleep = kwargs.get('asleep', False)
async def is_owner(obj):
owner = self.application_info().owner
return obj.author == owner
async def on_message(self, message):
ctx = await self.get_context(message)
is_owner = client.is_owner(ctx):
if is_owner or not self.asleep:
self.invoke(ctx)
...
owner.py - или где бы вы ни находились, ваши команды "только для владельца бота" .
from discord.ext import commands
...
@commands.command()
async def sleep(self, ctx):
self.bot.asleep = True
await ctx.say(f"I am now asleep, I will only respond to {ctx.author}")
@commands.command()
async def awaken(self, ctx):
self.bot.asleep = False
await ctx.say("Ahhh, just woke up! Ready to take commands!")
...
launcher.py
import MyBot
...
bot = MyBot(...)
bot.load_extension("path/to/owner_py_file")
...
Я придумал это, основываясь на том, как RDanny бот назначает свою базу данных каждому контексту перед вызовом команды.Это очень хорошо написанный бот, который владелец публично опубликовал исходный код для образовательных целей.
Редактировать
, чтобы приспособить вашу текущую сборку
В вашем случае, я предполагаю, что вы просто создаете бота, используя что-то вроде client = commands.bot(...)
, это опять-таки довольно круто и не позволит вам использовать любую мощь, которую вы получите от подкласса bot
, но вы могли бы просто реализоватьи получите те же функции, что и выше:
client = commands.bot(...)
client.asleep = False
Затем для команд, которые вы указали в вопросе:
@client.command(pass_context=True)
async def sleep(ctx):
client.sleep = True
@client.command(pass_context=True)
async def awake(ctx):
client.asleep = False
Затем для переопределения on_message
. Пожалуйста, укажите: этот ответ , чтобы помочь объяснить, почему это работает. или даже документы .подсказка подсказка
async def _is_owner(obj):
owner = self.application_info().owner
return obj.author == owner
@client.event()
async def on_message(message):
ctx = await self.get_context(message)
is_owner = _is_owner(ctx):
if is_owner or not self.asleep:
client.invoke(ctx)
Если вышеуказанная реализация не работает для вас, вы можете дать метод, описанный в ответе, который я связал чуть выше:
@client.event
async def on_message(message):
is_owner = _is_owner(ctx):
if is_owner or not client.asleep:
await bot.process_commands(message)
Обратите внимание Я не знаю, как устроен ваш модуль, но если это делается внутри класса, и вы определяете _is_owner(...)
внутри этого класса, вам нужно будет использовать is_owner = self._is_owner(...)
, хотя этоможет быть определено в другом месте.