diff --git a/Christmas/Cogs/Commands_Arcade.py b/Christmas/Cogs/Commands_Arcade.py index 9bdd9ce..af2ebc1 100644 --- a/Christmas/Cogs/Commands_Arcade.py +++ b/Christmas/Cogs/Commands_Arcade.py @@ -1,33 +1,53 @@ import io from discord import SlashCommandGroup, Option, Member, Color, File, Attachment +from discord.utils import basic_autocomplete from discord.ext.commands import Cog, BucketType, cooldown, guild_only, Context, has_permissions from Christmas.Database import database from Christmas.UI.Embed import ChristmasEmbed, Arcade_Embed, Default_Embed from Christmas.UI.Buttons import Arcade_Register_Agree from Christmas.Cogs.Event import model + +from Christmas.UI.AutoComplete import Guild_Autocomplete class CArcade(Cog): def __init__(self, bot): self.bot = bot - ARCADE = SlashCommandGroup(name="눈싸움", description="눈싸움 관련 명령어") - - @cooldown(1, 5, BucketType.user) - @has_permissions(administrator=True) - @guild_only() - @ARCADE.command(name="등록", description="눈싸움 등록") - async def _등록(self, ctx: Context): - if not await database.get_guild(ctx.guild.id): return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버를 가입해주세요!", color=Color.red()),ephemeral=True) - #if await database.get_arcade(ctx.guild.id): return await ctx.respond(embed=Arcade_Embed.register_already(), ephemeral=True) - await ctx.respond(embed=Arcade_Embed.register_inital(), view=Arcade_Register_Agree(), ephemeral=True) - - @guild_only() - @cooldown(1, 10, BucketType.user) - @ARCADE.command(name="정보", description="눈싸움 정보") - async def _정보(self, ctx: Context): - if not await database.get_guild(ctx.guild.id): return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버를 가입해주세요!", color=Color.red()),ephemeral=True) - if await database.get_arcade(ctx.guild.id): return await ctx.respond(embed=Arcade_Embed.register_already(), ephemeral=True) - pass - - + #ARCADE = SlashCommandGroup(name="눈싸움", description="눈싸움 관련 명령어") + # + # @cooldown(1, 5, BucketType.user) + # @has_permissions(administrator=True) + # @guild_only() + # @ARCADE.command(name="등록", description="눈싸움 등록") + # async def _등록(self, ctx: Context): + # if not await database.get_guild(ctx.guild.id): return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버를 가입해주세요!", color=Color.red()),ephemeral=True) + # #if await database.get_arcade(ctx.guild.id): return await ctx.respond(embed=Arcade_Embed.register_already(), ephemeral=True) + # await ctx.respond(embed=Arcade_Embed.register_inital(), view=Arcade_Register_Agree(), ephemeral=True) + # + # @guild_only() + # @cooldown(1, 10, BucketType.user) + # @ARCADE.command(name="정보", description="눈싸움 정보") + # async def _정보(self, ctx: Context): + # if not await database.get_guild(ctx.guild.id): return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버를 가입해주세요!", color=Color.red()),ephemeral=True) + # if await database.get_arcade(ctx.guild.id): return await ctx.respond(embed=Arcade_Embed.register_already(), ephemeral=True) + # pass + # + # @guild_only() + # @cooldown(1, 10, BucketType.user) + # @ARCADE.command(name="돈벌기", description="눈싸움 돈벌기") + # async def _돈벌기(self, ctx: Context): + # pass + # + # @guild_only() + # @cooldown(1, 10, BucketType.user) + # @ARCADE.command(name="레이드", description="눈싸움 레이드") + # async def _레이드(self, ctx: Context): + # pass + # + ### @guild_only() + # @cooldown(1, 10, BucketType.user) + # @ARCADE.command(name="연합요청", description="눈싸움 연합요청") + # async def _연합요청(self, ctx: Context, guild: Option(str, "연합할 서버를 입력해주세요!", autocomplete=basic_autocomplete(Guild_Autocomplete))): + # pass + # def setup(bot): bot.add_cog(CArcade(bot)) \ No newline at end of file diff --git a/Christmas/Cogs/Commands_Mail.py b/Christmas/Cogs/Commands_Mail.py index 43681cb..3de3b66 100644 --- a/Christmas/Cogs/Commands_Mail.py +++ b/Christmas/Cogs/Commands_Mail.py @@ -1,10 +1,10 @@ import pendulum -from discord import Member, SlashCommandGroup, Option +from discord import Member, SlashCommandGroup, Option, Color from discord.ext.commands import Cog, cooldown, BucketType, command, has_permissions, bot_has_permissions, Context, guild_only, bot_has_guild_permissions, check from Christmas.UI.Modal import Send_Mail_Modal -from Christmas.UI.Embed import Mail_Embed +from Christmas.UI.Embed import Mail_Embed, ChristmasEmbed from Christmas.Database import database from Christmas.UI.Paginator import Mail_Paginator class CMail(Cog): @@ -21,6 +21,7 @@ class CMail(Cog): if pendulum.now() > christmas: await ctx.respond("이미 편지를 보낼수 있는 기간이 지났어요! 받은 편지가 있다면 확인해보세요!", ephemeral=True) return + if ctx.author == member: return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="자기 자신에게 편지를 보낼수 없어요!", color=Color.red()),ephemeral=True) if await database.get_mail_user(member.id, ctx.author.id): if await database.get_instered_mail_edited(member.id, ctx.author.id): await ctx.respond(embed=Mail_Embed.mail_cant_edit(), ephemeral=True) diff --git a/Christmas/Cogs/Commands_Music.py b/Christmas/Cogs/Commands_Music.py index e685ed3..b0fc0fd 100644 --- a/Christmas/Cogs/Commands_Music.py +++ b/Christmas/Cogs/Commands_Music.py @@ -3,6 +3,7 @@ from discord import Member, SlashCommandGroup, Option, AutocompleteContext, Colo from discord.ext.commands import Cog, cooldown, BucketType, command, has_permissions, bot_has_permissions, Context, guild_only, bot_has_guild_permissions, check import wavelink import random +import pendulum from Christmas.Database import database from Christmas.UI.Embed import Music_Embed, ChristmasEmbed from Christmas.config import ChristmasConfig @@ -19,10 +20,12 @@ class CMusic(Cog): @guild_only() async def _play(self, ctx: Context): if not await database.get_guild(ctx.guild.id): return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버를 가입해주세요!", color=Color.red()),ephemeral=True) - await ctx.defer(ephemeral=True) + await ctx.defer() get_guild = await database.get_guild(ctx.guild.id) - if not get_guild["music"] == True: return await ctx.respond(embed=Music_Embed.music_notenable(), ephemeral=True) - if ctx.author.voice == None or ctx.author.voice.channel == None: return await ctx.respond(embed=Music_Embed.author_not_voice(), ephemeral=True) + if not get_guild["music"] == True: return await ctx.respond(embed=Music_Embed.music_notenable()) + if get_guild["admin_run"] == True: + if not ctx.author.guild_permissions.administrator: return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="관리자만 사용할수 있는 명령어에요!", color=Color.red()),ephemeral=True) + if ctx.author.voice == None or ctx.author.voice.channel == None: return await ctx.respond(embed=Music_Embed.author_not_voice()) player = None node = wavelink.Pool.get_node() if node.get_player(ctx.guild.id) == None: @@ -30,7 +33,11 @@ class CMusic(Cog): else: player = node.get_player(ctx.guild.id) try: - query = await wavelink.Playable.search(random.choice(self.config.LOFI()), source=wavelink.TrackSource.YouTube) + query = None + if pendulum.now() > pendulum.datetime(2023, 12, 24, 12, 0, 0): + query = await wavelink.Playable.search(self.config.CHRISTMAS, source=wavelink.TrackSource.YouTube) + else: + query = await wavelink.Playable.search(random.choice(self.config.LOFI), source=wavelink.TrackSource.YouTube) await player.play(query[0]) await ctx.respond(embed=Music_Embed.music_play()) except Exception as e: @@ -42,17 +49,40 @@ class CMusic(Cog): @guild_only() async def _stop(self, ctx: Context): if not await database.get_guild(ctx.guild.id): return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버를 가입해주세요!", color=Color.red()),ephemeral=True) - await ctx.defer(ephemeral=True) + await ctx.defer() get_guild = await database.get_guild(ctx.guild.id) - if not get_guild["music"] == True: return await ctx.respond(embed=Music_Embed.music_notenable(), ephemeral=True) - if ctx.author.voice == None or ctx.author.voice.channel == None: return await ctx.respond(embed=Music_Embed.author_not_voice(), ephemeral=True) + if not get_guild["music"] == True: return await ctx.respond(embed=Music_Embed.music_notenable()) + if get_guild["admin_run"] == True: + if not ctx.author.guild_permissions.administrator: return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="관리자만 사용할수 있는 명령어에요!", color=Color.red()),ephemeral=True) + if ctx.author.voice == None or ctx.author.voice.channel == None: return await ctx.respond(embed=Music_Embed.author_not_voice()) node = wavelink.Pool.get_node() player = node.get_player(ctx.guild.id) if player == None: return await ctx.respond(embed=Music_Embed.music_not_playing(), ephemeral=True) await player.stop() - await ctx.me.voice.disconnect() + # 음악 채널에서 나감 + await player.disconnect() await ctx.respond(embed=Music_Embed.music_stop()) - - + + @MUSIC.command(name="설정", description="음악 설정을 변경합니다.") + @cooldown(1, 10, BucketType.user) + @guild_only() + async def _setting(self, ctx: Context, setting: Option(str, name="설정", description="설정할 항목을 선택해주세요!", choices=["음악 활성화", "관리자만 재생 가능"], required=True), value: Option(str, name="값", description="설정할 값을 선택해주세요!", choices=["켜기", "끄기"], required=True)): + if not await database.get_guild(ctx.guild.id): return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버를 가입해주세요!", color=Color.red()),ephemeral=True) + await ctx.defer() + if not ctx.author.guild_permissions.administrator: return await ctx.respond(embed=ChristmasEmbed(title="❌ 에러!", description="관리자만 사용할수 있는 명령어에요!", color=Color.red()),ephemeral=True) + if setting == "관리자만 재생 가능": + if value == "켜기": + await database.update_music_setting(ctx.guild.id, True, "admin_run") + await ctx.respond(embed=Music_Embed.music_setting(True, "admin_run"), ephemeral=True) + else: + await database.update_music_setting(ctx.guild.id, False, "admin_run") + await ctx.respond(embed=Music_Embed.music_setting(False, "admin_run"), ephemeral=True) + if setting == "음악 활성화": + if value == "켜기": + await database.update_music_setting(ctx.guild.id, True, "music") + await ctx.respond(embed=Music_Embed.music_setting(True, "music"), ephemeral=True) + else: + await database.update_music_setting(ctx.guild.id, False, "music") + await ctx.respond(embed=Music_Embed.music_setting(False, "music"), ephemeral=True) def setup(bot): bot.add_cog(CMusic(bot)) \ No newline at end of file diff --git a/Christmas/Cogs/Commands_Util.py b/Christmas/Cogs/Commands_Util.py index 596cc2c..a1fa46d 100644 --- a/Christmas/Cogs/Commands_Util.py +++ b/Christmas/Cogs/Commands_Util.py @@ -30,5 +30,10 @@ class CUtil(Cog): data2 = await Get_Backend_latency() await ctx.respond(embed=Default_Embed.BotInfo(data, bot=self.bot, APIlatency=data2)) + @cooldown(1, 10, BucketType.user) + @slash_command(name="도움말", description="도움말을 확인합니다.") + async def _help(self, ctx: Context): + await ctx.respond(embed=Default_Embed.help()) + def setup(bot): bot.add_cog(CUtil(bot)) \ No newline at end of file diff --git a/Christmas/Cogs/Event.py b/Christmas/Cogs/Event.py index aa59585..3c16504 100644 --- a/Christmas/Cogs/Event.py +++ b/Christmas/Cogs/Event.py @@ -1,10 +1,12 @@ import random import wavelink +import pendulum import onnxruntime as rt from discord import ApplicationContext, DiscordException, Game, Guild from discord.ext.commands import Cog +from discord.ext import tasks from discord.ext.commands import CommandOnCooldown from Christmas.UI.Embed import Default_Embed @@ -57,6 +59,6 @@ class Event(Cog): #@Cog.listener() #async def on_wavelink_node_ready(self, node: wavelink.Node): # print(f"Node {node.id} is ready!") - + def setup(bot): bot.add_cog(Event(bot)) \ No newline at end of file diff --git a/Christmas/Database/__init__.py b/Christmas/Database/__init__.py index e493c68..2dff320 100644 --- a/Christmas/Database/__init__.py +++ b/Christmas/Database/__init__.py @@ -19,7 +19,7 @@ class database: async def register_guild(guild_id: int) -> None: conn = await MongoDBClient().connect() - await conn.guild.insert_one({"_id": guild_id}) + await conn.guild.insert_one({"_id": guild_id, "admin_run": False, "music": True}) async def insert_mail(send_user_id: int, user_id: int, user_name: str, mail_title: str, mail_content: str): try: @@ -81,4 +81,11 @@ class database: async def get_arcade(guild_id: int): conn = await MongoDBClient().connect() return await conn.arcade.find_one({"_id": guild_id}) + + async def update_music_setting(guild_id: int, value: bool, setting: str): + conn = await MongoDBClient().connect() + if setting == "music": + await conn.guild.update_one({"_id": guild_id}, {"$set": {"music": value}}) + elif setting == "admin_run": + await conn.guild.update_one({"_id": guild_id}, {"$set": {"admin_run": value}}) \ No newline at end of file diff --git a/Christmas/SearchEngine/Snowball.py b/Christmas/SearchEngine/Snowball.py new file mode 100644 index 0000000..eba7050 --- /dev/null +++ b/Christmas/SearchEngine/Snowball.py @@ -0,0 +1,16 @@ +from Christmas.SearchEngine import Search + + + +class Snowball: + + async def register_guild(guild_id: int, guild_name: str, region: str): + search = Search() + index = await search.connect() + await index.add_documents([{"guild_id": guild_id, "guild_name": guild_name, "region": region}]) + + async def query_guild(query: str): + search = Search() + index = await search.connect() + result = await index.search(query) + return result \ No newline at end of file diff --git a/Christmas/SearchEngine/__init__.py b/Christmas/SearchEngine/__init__.py new file mode 100644 index 0000000..d271363 --- /dev/null +++ b/Christmas/SearchEngine/__init__.py @@ -0,0 +1,15 @@ +from meilisearch_python_sdk import AsyncClient as Client +from Christmas.config import ChristmasConfig + + +class Search: + def __init__(self): + self.config = ChristmasConfig() + + async def connect(self): + self.client = Client(self.config.SEARCH_ENGINE["HOST"], self.config.SEARCH_ENGINE["KEY"]) + self.index = self.client.index(self.config.SEARCH_ENGINE["INDEX"]) + return self.index + + async def close(self): + await self.client.aclose() \ No newline at end of file diff --git a/Christmas/UI/AutoComplete.py b/Christmas/UI/AutoComplete.py new file mode 100644 index 0000000..b077c88 --- /dev/null +++ b/Christmas/UI/AutoComplete.py @@ -0,0 +1,16 @@ +from discord import AutocompleteContext + +from Christmas.SearchEngine.Snowball import Snowball + + +async def Guild_Autocomplete(ctx: AutocompleteContext): + snowball = Snowball() + query = ctx.value + print(query) + result = await snowball.query_guild(query) + results = [] + for i in result["hits"]: + gname = i["guild_name"] + gid = i["guild_id"] + results.append(f"{gname} ({gid})") + return results \ No newline at end of file diff --git a/Christmas/UI/Buttons.py b/Christmas/UI/Buttons.py index b57f241..4b5c201 100644 --- a/Christmas/UI/Buttons.py +++ b/Christmas/UI/Buttons.py @@ -4,6 +4,7 @@ from discord import Interaction, ButtonStyle, Embed, Color, TextChannel, Forbidd from Christmas.UI.Embed import Mail_Embed, Arcade_Embed from Christmas.Database import database +from Christmas.SearchEngine.Snowball import Snowball class Mail_Confirm_Button(View): def __init__(self, editmode: bool, recive_user: Member, title: str, description: str, *args, **kwargs): self.editmode = editmode @@ -39,8 +40,11 @@ class Arcade_Register_Agree(View): async def agree(self, button, interaction: Interaction): await interaction.response.defer() try: - await database.register_arcade(interaction.guild.id, interaction.guild.name, random.choice(["south", "north"])) + region = random.choice(["south", "north"]) + await database.register_arcade(interaction.guild.id, interaction.guild.name, region) + await Snowball.register_guild(interaction.guild.id, interaction.guild.name, region) except Exception as e: + print(e) await interaction.edit_original_response(embed=Arcade_Embed.register_failed(), view=None) return await interaction.edit_original_response(embed=Arcade_Embed.register_sucessfull(), view=None) diff --git a/Christmas/UI/Embed.py b/Christmas/UI/Embed.py index d0b3eac..add5ea6 100644 --- a/Christmas/UI/Embed.py +++ b/Christmas/UI/Embed.py @@ -68,7 +68,17 @@ class Default_Embed: def cooldown(sec): return "이 명령어는 " + str(sec) + "초 뒤에 다시 사용할 수 있어요!" - + @staticmethod + def help(): + embed = ChristmasEmbed(title="🎉 크돌이 도움말", description="크리스마스를 즐겨보세요!") + embed.add_field(name="``/도움말``", value="크돌이의 도움말을 확인해요!", inline=False) + embed.add_field(name="``/서버가입``", value="이 서버에 크돌이를 가입해요!", inline=False) + embed.add_field(name="``/봇정보``", value="크돌이의 정보를 확인해요!", inline=False) + embed.add_field(name="**편지**", value="``/편지 보내기 (유저)``: 유저에게 편지를 보내요!\n``/편지 확인``: 받은 편지를 확인해요!", inline=False) + embed.add_field(name="**그림**", value="``/그림 생성``: 크돌이가 그림을 그려줘요!\n``/그림 분석``: 그림을 분석해요!", inline=False) + embed.add_field(name="**음악**", value="``/음악 재생``: 크돌이가 음악을(LOFI) 재생해요!\n``/음악 정지``: 크돌이가 음악을 정지해요!\n``음악 설정 (설정이름) (값)``: 음악 설정을 변경해요!", inline=False) + embed.set_footer() + return embed @staticmethod def BotInfo(gpuserver: typing.Dict[str, typing.Any], bot, APIlatency) -> Embed: @@ -79,7 +89,7 @@ class Default_Embed: gpuserver: [system_memory_usage,cuda_memory_usage,oom_count] """ embed = Embed(title="**봇 정보**", description="크돌이의 정보에요!") - embed.add_field(name="**봇 개요**", value=f"봇 ID: {bot.user.id}\n봇 버전: 0.0.9\n가동시간: {str(uptime)}", inline=False) + embed.add_field(name="**봇 개요**", value=f"봇 ID: {bot.user.id}\n봇 버전: 1.0.0\n가동시간: {str(uptime)}\n개발자: RunaLab(tmddn3070)", inline=False) orin = psutil.virtual_memory().used orin = orin / 1024 / 1024 / 1024 if gpuserver == None or gpuserver["status"] == "offline": @@ -255,6 +265,22 @@ class Music_Embed: embed.set_footer() return embed + @staticmethod + def music_setting(value: bool, settings: str): + embed = ChristmasEmbed(title="✅ 음악 설정 변경!", description="음악 설정을 변경했어요!") + if settings == "music": + if value == True: + embed.add_field(name="안내", value="이제 이 서버에서 음악을 재생할수 있어요!", inline=False) + else: + embed.add_field(name="안내", value="이제 이 서버에서 음악을 재생할수 없어요!", inline=False) + elif settings == "admin_run": + if value == False: + embed.add_field(name="안내", value="이제 이 서버에서 관리자를 제외한 사람들도 음악을 재생할수 있어요!", inline=False) + else: + embed.add_field(name="안내", value="이제 이 서버에서 관리자를 제외한 사람은 음악을 재생할수 없어요!", inline=False) + embed.set_footer() + return embed + class Arcade_Embed: @@ -306,3 +332,4 @@ class Arcade_Embed: embed = ChristmasEmbed(title="🎉 눈싸움 정보!", description=f"{guild.name}서버의 눈싸움 정보에요!") embed.add_field(name="진영", value=f"{region}", inline=False) embed.add_field(name="상대진영", value=f"{region}", inline=False) + diff --git a/Christmas/config.py b/Christmas/config.py index 1e7def1..70b1d7b 100644 --- a/Christmas/config.py +++ b/Christmas/config.py @@ -41,9 +41,16 @@ class ChristmasConfig: def AI(self): return self.json["AI_GATEWAY"] + @property def LOFI(self): return self.json["LOFI"] @property def CHRISTMAS(self): - return self.json["CHRISTMAS"] \ No newline at end of file + return self.json["CHRISTMAS"] + + @property + def SEARCH_ENGINE(self): + return self.json["SEARCH_ENGINE"] + + \ No newline at end of file diff --git a/requirement.txt b/requirement.txt index b7bdcc6..4cd321a 100644 --- a/requirement.txt +++ b/requirement.txt @@ -7,4 +7,4 @@ pendulum Wavelink onnxruntime psutil -meilisearch-python-async \ No newline at end of file +meilisearch_python_sdk \ No newline at end of file