#discord #discord.py
Вопрос:
@commands.command()
@commands.has_permissions(manage_roles=True)
async def mute(self, ctx, member:discord.Member, *, time: TimeConverter = None):
role = discord.utils.get(ctx.guild.roles, name="Muted by ez")
if not role:
role = await ctx.guild.create_role(name="Muted by ez")
for channel in ctx.guild.channels:
await channel.set_permissions(role, speak=False, send_messages=False, read_message_history=True,
read_messages=False)
await member.add_roles(role)
await asyncio.sleep(time)
await member.remove_roles(role)
await ctx.send(f"Muted {member.mention} for {time}s")
else:
await member.add_roles(role)
await ctx.send(f"Muted {member.mention} for {time}s")
await asyncio.sleep(time)
await member.remove_roles(role)
await ctx.send(f'Unmuted {member.mention}')
@commands.command()
@commands.has_permissions(manage_roles=True)
async def unmute(self, ctx, member: discord.Member):
role = discord.utils.get(ctx.guild.roles, name="Muted by ez")
await member.remove_roles(role)
await ctx.send(f'Unmuted {member.mention}')
этот мой код до сих пор отлично работает, но я так долго занимаюсь этим и спрашиваю себя, как добавить пользователей в базу данных json, чтобы, когда они присоединятся, у них все еще была роль.
Обновите лучший код, который у меня теперь есть все, но не эти, с дополнительными данными: я хочу добавить идентификатор гильдии, продолжительность отключения звука и идентификатор автора
поэтому я попытался сохранить все это, но у меня было много ошибок, поэтому я надеюсь, что вы снова сможете помочь мне с этим моим кодом до сих пор
import re
import asyncio
import discord
from discord.ext import commands
import cogs._json
time_regex = re.compile("(?:(d{1,5})(h|s|m|d)) ?")
time_dict = {"h": 3600, "s": 1, "m": 60, "d": 86400}
class TimeConverter(commands.Converter):
async def convert(self, ctx, argument):
args = argument.lower()
matches = re.findall(time_regex, args)
time = 0
for key, value in matches:
try:
time = time_dict[value] * float(key)
except KeyError:
raise commands.BadArgument(
f"{value} is an invalid time key! h|m|s|d are valid arguments"
)
except ValueError:
raise commands.BadArgument(f"{key} is not a number!")
return round(time)
class Moderation(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(
name='mute',
description="Mutes a given user for x time!",
ussage='<user> [time]'
)
@commands.has_permissions(manage_roles=True)
async def mute(self, ctx, member: discord.Member, *, time: TimeConverter= None):
role = discord.utils.get(ctx.guild.roles, name="Muted by ez")
if not role:
role = await ctx.guild.create_role(name="Muted by ez", colour=0x171717)
for channel in ctx.guild.channels:
await channel.set_permissions(role, speak=False, send_messages=False, read_message_history=True,
read_messages=False, add_reactions=False)
pass
try:
data = cogs._json.read_json("muted_users")
if member.id in data['muted_users']:
remsg = await ctx.send("reloading the mute")
await member.remove_roles(role)
data = cogs._json.read_json("muted_users")
data["muted_users"].remove(member.id)
cogs._json.write_json(data, "muted_users")
await asyncio.sleep(2)
await remsg.edit(content=f"Unmuted `{member}`")
data = cogs._json.read_json("muted_users")
data["muted_users"].append(member.id)
cogs._json.write_json(data, "muted_users")
await member.add_roles(role)
if not time:
await asyncio.sleep(2)
await remsg.edit(content=f"Muted `{member}`")
else:
await asyncio.sleep(2)
await remsg.edit(content=f"Muted `{member}` for `{time}s`")
await asyncio.sleep(time)
await member.remove_roles(role)
data = cogs._json.read_json("muted_users")
data["muted_users"].remove(member.id)
cogs._json.write_json(data, "muted_users")
await ctx.send(content=f"Unmuted `{member}`")
return
except KeyError:
pass
data = cogs._json.read_json("muted_users")
data["muted_users"].append(member.id)
cogs._json.write_json(data, "muted_users")
await member.add_roles(role)
if not time:
await ctx.send(f"Muted `{member}`")
else:
await ctx.send(f"Muted `{member}`for `{time}s`")
await asyncio.sleep(time)
print(time)
if role in member.roles:
await member.remove_roles(role)
data = cogs._json.read_json("muted_users")
data["muted_users"].remove(member.id)
cogs._json.write_json(data, "muted_users")
await ctx.send(f"Unmuted `{member}`")
else:
data = cogs._json.read_json("muted_users")
data["muted_users"].remove(member.id)
cogs._json.write_json(data, "muted_users")
@commands.command(
name='unmute',
description="Unmuted a member!",
usage='<user>'
)
@commands.has_permissions(manage_roles=True)
async def unmute(self, ctx, member: discord.Member):
role = discord.utils.get(ctx.guild.roles, name="Muted by ez")
if not role:
role = await ctx.guild.create_role(name="Muted by ez", color=0x171717)
for channel in ctx.guild.channels:
await channel.set_permissions(role, speak=False, send_messages=False, read_message_history=True,
read_messages=False, add_reactions=False)
return
if role not in member.roles:
await ctx.send("This member is not muted.")
data = cogs._json.read_json("muted_users")
data["muted_users"].remove(member.id)
cogs._json.write_json(data, "muted_users")
await member.remove_roles(role)
data = cogs._json.read_json("muted_users")
data["muted_users"].remove(member.id)
cogs._json.write_json(data, "muted_users")
await ctx.send(f"Unmuted `{member}`")
def setup(bot):
bot.add_cog(Moderation(bot))
that is the cog
import json
from pathlib import Path
def get_path():
"""
A function to get the current path to bot.py
Returns:
- cwd (string) : Path to bot.py directory
"""
cwd = Path(__file__).parents[1]
cwd = str(cwd)
return cwd
def read_json(filename):
"""
A function to read a json file and return the data.
Params:
- filename (string) : The name of the file to open
Returns:
- data (dict) : A dict of the data in the file
"""
cwd = get_path()
with open(cwd '/bot_config/' filename '.json', 'r') as file:
data = json.load(file)
return data
def write_json(data, filename):
"""
A function used to write data to a json file
Params:
- data (dict) : The data to write to the file
- filename (string) : The name of the file to write to
"""
cwd = get_path()
with open(cwd '/bot_config/' filename '.json', 'w') as file:
json.dump(data, file, indent=4)
мой «файл преобразования»
{
"muted_users": []
}
мой файл хранилища json
@commands.Cog.listener()
async def on_member_join(self, member):
print(member)
await member.send("hello")
role = discord.utils.get(member.guild.roles, name="Muted by ez")
data = cogs._json.read_json("muted_users")
if member.id in data['muted_users']:
await member.add_roles(role)
и мой модуль on_member_join.
Этот код полностью работает, но я хочу сделать его лучше, bcs, как в модуле объединения участников, может быть одним участником, поэтому один и тот же ребенок отключается на одном сервере, а не на другом, но отключается на обоих. вот почему мне нужен идентификатор гильдии.
и как я могу удалить все эти данные, когда я снова включу участника?
я этого не понял, так что не могли бы вы мне еще раз помочь?
Ответ №1:
Этапы рабочего процесса будут следующими
- Когда используется команда, соберите пользовательские данные
- сохраните его в файле json, предпочтительно используя уникальный идентификатор пользователя в качестве ключа.
- Когда присоединяется новый участник, проверьте идентификатор пользователя в разделе данные json
- Если идентификатор существует в данных json, назначьте им отключенную роль, в противном случае передайте.
Полезные ресурсы
Пример хранения данных
import json
...
class Moderation(commands.Cog):
...
@commands.command()
async def mute(self, ctx, member:discord.Member):
...
# add the muted role
await member.add_roles(role)
# open the json file and add the data
with open('users.json', 'w') as fp:
data = json.load(fp)
if member.id not in data['muted']:
data['muted'].append(member.id)
json.dump(data, fp)
...
создайте файл JSON users.json
со следующими данными:
{
"muted": []
}
в этом простом примере отключенные пользователи хранятся как в списке. Сгенерированный файл JSON будет выглядеть следующим образом:
{
"muted": [123123123, 1231231231, 23423423423]
}
Пример проверки того, что пользователь находится в списке
import json
...
@client.event
async def on_member_join(member):
...
with open('users.json', 'r') as fp:
data = json.load(fp)
if member.id in data['muted']:
await member.add_roles(role)
...
Изменить: Хранение Дополнительных Данных
Это редактирование предназначено для ответа на часть вопроса, полученного в комментариях
Чтобы собрать больше данных, вы можете использовать словари вместо одного списка. Возможность структуры данных JSON, которую вы ищете, может быть следующей
{
"guild_1_id": {
"user_1_id": {
"channel": "12345678",
"moderator": "12345678"
},
"user_2_id": {
"channel": "12345678",
"moderator": "12345678"
},
...
},
"guild_2_id": {
"user_1_id": {
"channel": "12345678",
"moderator": "12345678"
}
}
...
}
Во-первых, соберите все необходимые данные, сохраните их в словаре под идентификатором участника
newdata = {
member.id: {
"channel": ctx.channel.id,
"moderator": ctx.author.id
}
}
При обновлении данных JSON проверьте, существует ли в нем идентификатор гильдии, если да, то обновите данные сервера, чтобы включить данные нового участника, в противном случае создайте новый ключ с идентификатором гильдии и назначьте ему данные нового участника.
Измененная версия выглядит следующим образом
# open the json file and add the data
with open('users.json', 'w') as fp:
data = json.load(fp)
if ctx.guild.id not in data.keys():
data[ctx.guild.id] = newdata
else:
data[ctx.guild.id].update(newdata)
json.dump(data, fp)
Объединив их, вы получите это
import json
...
class Moderation(commands.Cog):
...
@commands.command()
async def mute(self, ctx, member:discord.Member):
...
await member.add_roles(role)
newdata = {
member.id: {
"channel": ctx.channel.id,
"moderator": ctx.author.id
}
}
# open the json file and add the data
with open('users.json', 'w') as fp:
data = json.load(fp)
if ctx.guild.id not in data.keys():
data[ctx.guild.id] = newdata
else:
data[ctx.guild.id].update(newdata)
json.dump(data, fp)
...
Теперь измените свои данные участника on_member_join
, зарегистрировавшись в
@client.event
async def on_member_join(member):
...
with open('users.json', 'r') as fp:
data = json.load(fp)
if member.id in data[member.guild.id].keys():
await member.add_roles(role)
# further data can be accessed as following
user_data = data[member.guild.id][member.id]
channel = user_data['channel']
moderator = user_data['moderator']
...
Также проверьте
Комментарии:
1. прежде всего, так много, я сохранил его сейчас, но как я должен это сделать, когда я хотел бы сохранить больше данных, таких как идентификатор канала, идентификатор гильдии или идентификатор автора, есть ли у меня больше возможностей для данных или как это работает?
2. @Socsz Я обновил свой ответ, чтобы включить более подробную информацию о том, как вы можете хранить больше данных, пожалуйста, проверьте еще раз 🙂
3. братан, большое тебе спасибо за твою помощь, но я не совсем правильно понял, я добавил еще несколько деталей к своему вопросу, так что я надеюсь, что ты сможешь помочь