Запутан в этом Discord.py Переписать + Код световой реакции - нужно объяснение - PullRequest
2 голосов
/ 05 марта 2020

Так что, пока мы все, я, безусловно, в курсе всего, кто копирует и вставляет чужой код, и волшебным образом он работает, он теряет некоторый контекст и понимание при выяснении, как этот код на самом деле работает и функционирует.

Я работаю с Discord.py Rewrite и частью кода под названием Reaction Light , чтобы создать бота , который позволяет самостоятельно назначение ролей на моем сервере Discord . Бот на 100% функционален и работает как задумано. Теперь я изменил некоторые вещи из их кода, поэтому мои методы находятся в разных местах и ​​вызываются из разных областей.

Вот где я запутался:

У меня есть метод, который называется isadmin() это вызывается всякий раз, когда необходимо выполнить проверку, чтобы выяснить, является ли пользователь, выполняющий команду, администратором. Роли администратора определены в файле .env, который я получаю с помощью модуля dotenv. Довольно простые вещи. (Я перепишу эту часть позже и, надеюсь, поместим все идентификаторы роли администратора в файл и получу их оттуда.) Однако я не совсем понимаю, что именно делает третий аргумент этого метода. msg=False

Всякий раз, когда я писал свои cogs для этого, я вызываю этот метод как таковой, не передавая ему аргумент 'msg', как показано ниже:

admin.py

# admin.py
# Simple ping pong command
@commands.command()
    async def ping(self, ctx):
        if helpers.isadmin(ctx):
            print("Running Command from admin.py")
            await ctx.send('Pong!')

Теперь в моем методе прослушивателя on_message() он передает аргумент msg, затем выполняет некоторый код, не связанный с командой ping, но связанный с функциональностью самоопределяющейся роли. бота.

message.py

# message.py
@commands.Cog.listener()
    async def on_message(self, message):
        if helpers.isadmin(message, msg=True):
            # Execute some code here for the self-assigning roles

Насколько я знаю, этот рабочий процесс работает так, и я буду использовать команду ping в качестве примера, который вызывается командой r.ping.

  1. on_message () прослушивает все сообщения, отправляемые на сервер
  2. Команда Ping, выданная в канале пользователем
  3. on_message () слышит сообщение и проверяет, является ли пользователь администратором, но также передает msg аргумент
  4. Команда ping вызывается из admin.py и затем проверяет (снова?), Если пользователь является администратором, и если он / она, выполняет команду.

Итак, я пытаюсь выяснить, когда или когда не следует использовать этот аргумент msg, и если он уже проверяет, является ли пользователь администратором в приемнике, я должен проверить снова в самой команде? Разве это не избыточно?

Вот метод isadmin() в файле helpers.py

# helpers.py
def isadmin(self, ctx, msg=False):
        # Checks if command author has one of .env admin role IDs
        try:
            check = (
                [role.id for role in ctx.author.roles]
                if msg
                else [role.id for role in ctx.message.author.roles]
            )
            if self.admin_a in check or self.admin_b in check or self.admin_c in check:
                return True
            return False
        except AttributeError:
            # Error raised from 'fake' users, such as webhooks
            return False

1 Ответ

2 голосов
/ 05 марта 2020

Честно говоря, я не уверен, почему это так. Если у вас есть доступ к ctx.author, у вас есть доступ к ctx.message, поскольку ctx.author является просто автором этого сообщения, кажется избыточным. Однако я настоятельно рекомендую вам использовать чеки для этого. Например, у меня есть:

def is_owner():
    def predicate(ctx):
        return ctx.author.id in ctx.bot.config()["owners"]
    return commands.check(predicate)

, и я использую это в качестве декоратора

# utils/checks/checks.py
from utils.checks import checks

@checks.is_owner()
@commands.group(hidden=True, case_insensitive=True, description="Load a module")
async def load(self, ctx):
    if not ctx.invoked_subcommand:
        return await ctx.send_help(ctx.command)

Например, вы можете иметь

def is_admin():
    def predicate(ctx):
        role_id = 123123123123123 # replace this with os.getenv("wherever your admin role is")
        return role_id in [x.id for x in ctx.author.roles]
    return commands.check(predicate)

Это намного чище и намного проще в использовании / понимании на мой взгляд.

...