Как заставить бота спать и перестать отвечать на команды (или on_messages) - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь создать команду, которая переводит бота в основном в спящем режиме, это означает, что бот перестает отвечать на команды (или on_messages, если это возможно). Попытка использовать client.pause (Boolean), но она не выдает ошибок.я не знаю, что именно он делает, но ничего не происходит. Вот где я сейчас нахожусь.

@client.command(pass_context=True)
async def sleep(ctx):
    client.pause = True

@client.command(pass_context=True)
async def awake(ctx):
    client.pause = False

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Вы можете использовать функцию get_prefix, чтобы изменить команду бота, чтобы она не отвечала ни на какие общедоступные префиксы.

backup_prefixes=['.','!','s.','k!']
prefixes = ['.','!','s.','k!']
def get_prefix(bot, msg):
    return commands.when_mentioned_or(*prefixes)(bot, msg)

bot = commands.Bot(command_prefix=get_prefix)

@bot.event
async def on_ready():
    print(bot.user.name)


@bot.command(pass_context=True)
async def resume(con):
    for i in backup_prefixes:
        prefixes.append(i)


@bot.command(pass_context=True)
async def pause(con):
    prefixes.clear()
    # prefixes.append("an unknow prefix so it can't be invoked") #Ex: aslkdjflkj2k4lkj21312kj
    prefixes.append(',')

Вы можете дополнительно добавить дополнительные операторы if, чтобы убедиться, что только определенные пользователи могутиспользуйте команду, чтобы отключить бот, чтобы он не отвечал другим пользователям.

0 голосов
/ 22 февраля 2019

Вы можете использовать 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(...), хотя этоможет быть определено в другом месте.

...