#python #discord #discord.py
Вопрос:
Я пытаюсь создать команду, которая может запрещать людей на Сервере и тех, кто не находится на сервере. Но есть проблема: если я использую async def ban(ctx, member: discord.Member, *, reason):
для использования атрибут «роли», то он не сможет запретить тех, кого нет на сервере. Если я использую async def ban(ctx, member: discord.User, *, reason):
, я не смогу использовать атрибут «роли», потому что это не атрибут.
Зачем я это делаю? Я пытаюсь сделать так, чтобы модераторы сервера не могли запретить тем, у кого есть роли модераторов
Код:
async def ban(ctx, member: discord.User = None, *, reason=None):
if get(ctx.author.roles, id=866038959980544050) or get(ctx.author.roles, id=866436325503008768) or get(
ctx.author.roles, id=866441730631008316) or ctx.author.guild_permissions.administrator: # Check if the author has the Role "Moderator", "Admin", etc.
if get(member.roles, id=867371024466968596) or get(member.roles, id=867132420489871411) and not ctx.author.guild_permissions.administrator: # Check if the member has the Role "Moderator", "Admin", etc.
await ctx.send("You cannot ban this user.")
Ответ №1:
Предполагая, что вы используете команды discord.ext., вы могли бы использовать ввод текста.Конвертер союзов, чтобы убедиться, что аргумент является либо пользователем, либо участником.
import typing
[...]
async def ban(ctx, user: typing.Union[discord.Member, discord.User]):
Обратите внимание, что порядок имеет значение: discord.Member
сначала он пытается применить этот конвертер , прежде чем пытаться discord.User
, таким образом, отдавая приоритет преобразованию в участника, а не преобразованию в пользователя (что должно быть тем, что вы хотите).
Чтобы различить эти два случая, теперь вы можете проверить, соответствует ли user
тип discord.Member
, и выполнить проверку.
if type(user) is discord.Member:
if YOUR_CHECKS:
await ctx.send('You cannot ban this user')
return
# Perform ban
await ctx.send('Ban successful')
При тестировании я обнаружил, что библиотека команд выдаст вам числовой идентификатор пользователя вместо реального пользователя и покажет
Failed fetching discord object! Passing ID instead.
в качестве предупреждения. Если вам нужно больше, чем просто идентификатор пользователя, вы можете преобразовать его в пользовательский объект с помощью
if type(user) is int:
user = await bot.fetch_user(user)
if user is None:
await ctx.send('User not found')
return
Обратите внимание, что fetch_user
это вызов API, и вы, возможно, захотите избежать его. Смотрите документы для получения дополнительной информации.
Ответ №2:
Одним из способов сделать это было бы проверить, входит ли данный member
игрок в текущую гильдию. Если это так True
, вы можете создать новый member object
с их идентификатором или другим предпочтительным методом, в противном случае вы можете предположить, что у них нет роли модератора. Для простоты я включил проверку только для одной роли, но вы можете настроить ее так, как хотите. Кроме этого, все остальное более подробно объясняется в приведенном ниже коде.
if member in ctx.guild.members: # checks if the provided member is in the current server
member = ctx.guild.get_member(member.id) # Get the member object of the user
if get(member.roles, id=866038959980544050): # Check if this role is in the member's roles
await ctx.send("This member has <@amp;866038959980544050>")
else:
await ctx.send("This member does not have <@amp;866038959980544050>")
return # returns, since member was in the server
# This happens if the provided member is not in the current server
await ctx.send("This member, who is not in this server, does not have <@amp;866038959980544050>")
Ответ №3:
Вы должны использовать это
@bot.command(...)
@commands.has_any_role(role id)
...