From d47201f8f257bfd3a95f0b87aaa3182b2927d12c Mon Sep 17 00:00:00 2001 From: Azarath7 <158289825+Azarath7@users.noreply.github.com> Date: Tue, 27 May 2025 12:19:11 +0300 Subject: [PATCH 1/7] Removed unnecessary network from vocard-dashboard service --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6a74b4d..7d9d039 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -101,7 +101,6 @@ services: # - 8000:8000 # networks: # - vocard - # - web vocard: container_name: vocard From eac2b0222b92dfadcb12685f55bb0d0f1c028d71 Mon Sep 17 00:00:00 2001 From: Azarath7 <158289825+Azarath7@users.noreply.github.com> Date: Sun, 15 Jun 2025 11:00:18 +0300 Subject: [PATCH 2/7] Update docker-compose.yml Refined comments, removed web service, added healthcheck for vocard-dashboard service --- docker-compose.yml | 72 ++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 50 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7d9d039..4b6cfe3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,40 +1,7 @@ # ------------------------------------------------------------------------------------------------------------ # -# READ THIS BEFORE INSTALL! - -# This is a docker-compose file for running Vocard with Lavalink and MongoDB. -# In order to run this, you need to have Docker and Docker Compose installed. -# You can install Docker from https://docs.docker.com/get-docker/ -# and Docker Compose from https://docs.docker.com/compose/install/ - -# Step 1: Start the installation by creating the future config directory for Vocard. -# example - `root@docker:~# mkdir -p /opt/vocard/config` - -# Use `cd` to navigate to the config directory. -# example - `root@docker:~# cd /opt/vocard/config` - -# Step 3: Choose installation method: Build the image from the Dockerfile or pull it from GitHub(recommended). -# If you chose to pull from Docker Hub, comment the "build" lines and uncomment the "image" line. -# If you chose to build the image from the Dockerfile, do the following: -# uncomment this -# build: -# dockerfile: ./Dockerfile -# and comment this -# image: ghcr.io/chocomeow/vocard:latest -# example - `root@docker:/opt/vocard/config# wget https://github.com/ChocoMeow/Vocard/archive/refs/heads/main.zip` - -# Step 4: Configure application.yml and settings.json in the config directory. -# In order to avoid silly syntax errors it is recommended to use external code editor such as VS Code or Notepad++. -# Then you can upload files to host using tools such as WinSCP or -# using `nano` to create and edit the files directly using hosts terminal. -# NOTE that some terminals DO NOT let you paste, so you can either use WinSCP or SSH app like Putty. - -# example - `root@docker:/opt/vocard/config# nano application.yml` -# example - `root@docker:/opt/vocard/config# nano settings.json` -# To exit nano, press `Ctrl + S`, then `Ctrl + X` to save changes. - -# Step 5: If the values are set correctly, you can start the installation by running the following command -# example - `root@docker:/opt/vocard/config# docker-compose up -d` (could be `docker compose` on some systems) +# For installation instructions please visit - https://docs.vocard.xyz/2.7.1/bot/setup/docker-linux/ +# or for Windows Docker - https://docs.vocard.xyz/2.7.1/bot/setup/docker-windows/ # ------------------------------------------ THANK YOU FOR READING! ------------------------------------------ # name: vocard @@ -87,20 +54,25 @@ services: start_period: 10s - # vocard-dashboard: - # container_name: vocard-dashboard - # image: ghcr.io/chocomeow/vocard-dashboard:latest - # restart: unless-stopped - # # If you want to build the image from the Dockerfile, uncomment the "build" lines and comment the "image" line. - # # build: - # # context: ./dashboard - # # dockerfile: ./Dockerfile - # volumes: - # - ./dashboard/settings.json:/app/settings.json - # ports: - # - 8000:8000 - # networks: - # - vocard +# vocard-dashboard: # to install this, please check out - https://docs.vocard.xyz/2.7.1/dashboard/ +# container_name: vocard-dashboard +# image: ghcr.io/chocomeow/vocard-dashboard:latest +# restart: unless-stopped +# # If you want to build the image from the Dockerfile, uncomment the "build" lines and comment the "image" line. +# # build: +# # context: ./dashboard +# # dockerfile: ./Dockerfile +# volumes: +# - ./dashboard/settings.json:/app/settings.json +# ports: +# - 8000:8000 +# networks: +# - vocard +# healthcheck: +# test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/"] +# interval: 15s +# timeout: 3s +# retries: 5 vocard: container_name: vocard @@ -117,7 +89,7 @@ services: lavalink: condition: service_healthy # vocard-dashboard: - # condition: service_started + # condition: service_healthy vocard-db: condition: service_healthy From 6587409148fcfe2394f559d79a83e5edeae97e18 Mon Sep 17 00:00:00 2001 From: Choco Date: Thu, 7 Aug 2025 10:54:16 +0800 Subject: [PATCH 3/7] Add Spotify Tokener service and update plugin configs Added a new spotify-tokener service to docker-compose.yml and updated documentation links to use the latest version. In lavalink/application.yml, enabled anonymous token usage for Spotify with a custom token endpoint, and updated YouTube and LavaSrc plugin dependencies to newer versions. --- docker-compose.yml | 21 ++++++++++++++++++--- lavalink/application.yml | 6 ++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6442950..7b76f70 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ # ------------------------------------------------------------------------------------------------------------ # -# For installation instructions please visit - https://docs.vocard.xyz/2.7.1/bot/setup/docker-linux/ -# or for Windows Docker - https://docs.vocard.xyz/2.7.1/bot/setup/docker-windows/ +# For installation instructions please visit - https://docs.vocard.xyz/latest/bot/setup/docker-linux/ +# or for Windows Docker - https://docs.vocard.xyz/latest/bot/setup/docker-windows/ # ------------------------------------------ THANK YOU FOR READING! ------------------------------------------ # name: vocard @@ -31,6 +31,22 @@ services: timeout: 5s retries: 5 + spotify-tokener: + image: ghcr.io/topi314/spotify-tokener:master + container_name: spotify-tokener + restart: unless-stopped + environment: + - SPOTIFY_TOKENER_ADDR=0.0.0.0:49152 + networks: + - vocard + ports: + - 49152:49152 + healthcheck: + test: nc -z -v localhost 49152 + interval: 10s + timeout: 5s + retries: 5 + vocard-db: container_name: vocard-db image: mongo:8 @@ -52,7 +68,6 @@ services: timeout: 5s retries: 5 start_period: 10s - # vocard-dashboard: # container_name: vocard-dashboard diff --git a/lavalink/application.yml b/lavalink/application.yml index 19b7cb0..40fdbe1 100644 --- a/lavalink/application.yml +++ b/lavalink/application.yml @@ -64,6 +64,8 @@ plugins: albumLoadLimit: 6 # The number of pages at 50 tracks each resolveArtistsInSearch: true # Whether to resolve artists in track search results (can be slow) localFiles: false # Enable local files support with Spotify playlists. Please note `uri` & `isrc` will be `null` & `identifier` will be `"local"` + preferAnonymousToken: true # Whether to use the anonymous token for resolving tracks, artists and albums. Spotify generated playlists are always resolved with the anonymous tokens since they do not work otherwise. This requires the customTokenEndpoint to be set. + customTokenEndpoint: "http://spotify-tokener:49152/api/token" # Optional custom endpoint for getting the anonymous token. If not set, spotify's default endpoint will be used which might not work. The response must match spotify's anonymous token response format. applemusic: countryCode: "US" # the country code you want to use for filtering the artists top tracks and language. See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 mediaAPIToken: "your apple music api token" # apple music api token @@ -100,9 +102,9 @@ plugins: recommendationsLoadLimit: 10 # Number of tracks lavalink: plugins: - - dependency: "dev.lavalink.youtube:youtube-plugin:1.13.3" # Please check the latest version at https://github.com/lavalink-devs/youtube-source/releases + - dependency: "dev.lavalink.youtube:youtube-plugin:1.13.4" # Please check the latest version at https://github.com/lavalink-devs/youtube-source/releases snapshot: false - - dependency: "com.github.topi314.lavasrc:lavasrc-plugin:4.7.0" # Please check the latest version at https://github.com/topi314/LavaSrc/releases + - dependency: "com.github.topi314.lavasrc:lavasrc-plugin:4.7.3" # Please check the latest version at https://github.com/topi314/LavaSrc/releases snapshot: false # - dependency: "com.github.example:example-plugin:1.0.0" # required, the coordinates of your plugin # repository: "https://maven.example.com/releases" # optional, defaults to the Lavalink releases repository by default From 76ccc7db351a7176b536504bc7c406363968ae64 Mon Sep 17 00:00:00 2001 From: Choco Date: Thu, 7 Aug 2025 11:11:23 +0800 Subject: [PATCH 4/7] Add dotenv support for environment-based settings Integrated python-dotenv to load environment variables and updated Settings to use values from either the provided dictionary or environment. Added python-dotenv to requirements.txt. --- addons/settings.py | 16 +++++++++++----- requirements.txt | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/addons/settings.py b/addons/settings.py index 5e8e4a9..eb05510 100644 --- a/addons/settings.py +++ b/addons/settings.py @@ -21,6 +21,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +import os + +from dotenv import load_dotenv from typing import ( Dict, List, @@ -28,13 +31,16 @@ from typing import ( Union ) +load_dotenv() + class Settings: def __init__(self, settings: Dict) -> None: - self.token: str = settings.get("token") - self.client_id: int = int(settings.get("client_id", 0)) - self.genius_token: str = settings.get("genius_token") - self.mongodb_url: str = settings.get("mongodb_url") - self.mongodb_name: str = settings.get("mongodb_name") + print(os.environ) + self.token: str = settings.get("token") or os.getenv("TOKEN") + self.client_id: int = int(settings.get("client_id", 0)) or int(os.getenv("CLIENT_ID")) + self.genius_token: str = settings.get("genius_token") or os.getenv("GENIUS_TOKEN") + self.mongodb_url: str = settings.get("mongodb_url") or os.getenv("MONGODB_URL") + self.mongodb_name: str = settings.get("mongodb_name") or os.getenv("MONGODB_NAME") self.invite_link: str = "https://discord.gg/wRCgB7vBQv" self.nodes: Dict[str, Dict[str, Union[str, int, bool]]] = settings.get("nodes", {}) diff --git a/requirements.txt b/requirements.txt index 352250a..30dac47 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,5 @@ validators==0.18.2 humanize==4.0.0 beautifulsoup4==4.11.1 psutil==5.9.8 -aiohttp==3.11.12 \ No newline at end of file +aiohttp==3.11.12 +python-dotenv==1.1.1 \ No newline at end of file From 8edc26a6d0524e64087aa8c4ecbb4805b7c9497a Mon Sep 17 00:00:00 2001 From: Choco <94597336+ChocoMeow@users.noreply.github.com> Date: Sun, 10 Aug 2025 12:44:05 +0800 Subject: [PATCH 5/7] Standardize permission and message keys in code and locales Updated various permission and message keys in the codebase and all language files for consistency. Also added missing keys and fixed minor typos in several language files. --- addons/settings.py | 1 - cogs/basic.py | 26 +++++++++++++------------- cogs/settings.py | 2 +- ipc/methods.py | 2 +- langs/CH.json | 29 +++++++++++++---------------- langs/DE.json | 29 +++++++++++++---------------- langs/EN.json | 29 +++++++++++++---------------- langs/ES.json | 29 +++++++++++++---------------- langs/FR.json | 29 +++++++++++++---------------- langs/JA.json | 29 +++++++++++++---------------- langs/KO.json | 29 +++++++++++++---------------- langs/PL.json | 29 +++++++++++++---------------- langs/RU.json | 29 +++++++++++++---------------- langs/UA.json | 29 +++++++++++++---------------- local_langs/zh-TW.json | 2 +- views/controller.py | 22 +++++++++++----------- voicelink/player.py | 2 +- 17 files changed, 158 insertions(+), 189 deletions(-) diff --git a/addons/settings.py b/addons/settings.py index eb05510..ff79807 100644 --- a/addons/settings.py +++ b/addons/settings.py @@ -35,7 +35,6 @@ load_dotenv() class Settings: def __init__(self, settings: Dict) -> None: - print(os.environ) self.token: str = settings.get("token") or os.getenv("TOKEN") self.client_id: int = int(settings.get("client_id", 0)) or int(os.getenv("CLIENT_ID")) self.genius_token: str = settings.get("genius_token") or os.getenv("GENIUS_TOKEN") diff --git a/cogs/basic.py b/cogs/basic.py index a7d4730..ce6242c 100644 --- a/cogs/basic.py +++ b/cogs/basic.py @@ -308,7 +308,7 @@ class Basic(commands.Cog): player = await voicelink.connect_channel(ctx) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_function", ephemeral=True) + return await send(ctx, "missingFunctionPerm", ephemeral=True) if ctx.interaction: await ctx.interaction.response.defer() @@ -457,7 +457,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_pos", ephemeral=True) + return await send(ctx, "missingPosPerm", ephemeral=True) if not player.current or player.position == 0: return await send(ctx, "noTrackPlaying", ephemeral=True) @@ -621,7 +621,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_mode", ephemeral=True) + return await send(ctx, "missingModePerm", ephemeral=True) await player.set_repeat(LoopType[mode] if mode in LoopType.__members__ else LoopType.OFF, ctx.author) await send(ctx, "repeat", mode.capitalize()) @@ -640,7 +640,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_queue", ephemeral=True) + return await send(ctx, "missingQueuePerm", ephemeral=True) await player.clear_queue(queue, ctx.author) await send(ctx, "cleared", queue.capitalize()) @@ -659,7 +659,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_queue", ephemeral=True) + return await send(ctx, "missingQueuePerm", ephemeral=True) removed_tracks = await player.remove_track(position1, position2, remove_target=member, requester=ctx.author) await send(ctx, "removed", len(removed_tracks.keys())) @@ -674,7 +674,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_pos", ephemeral=True) + return await send(ctx, "missingPosPerm", ephemeral=True) if not player.current: return await send(ctx, "noTrackPlaying", ephemeral=True) @@ -695,7 +695,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_pos", ephemeral=True) + return await send(ctx, "missingPosPerm", ephemeral=True) if not player.current: return await send(ctx, "noTrackPlaying", ephemeral=True) @@ -715,7 +715,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_pos", ephemeral=True) + return await send(ctx, "missingPosPerm", ephemeral=True) if not player.current: return await send(ctx, "noTrackPlaying", ephemeral=True) @@ -755,7 +755,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_pos", ephemeral=True) + return await send(ctx, "missingPosPerm", ephemeral=True) track1, track2 = await player.swap_track(position1, position2, ctx.author) await send(ctx, "swapped", track1.title, track2.title) @@ -773,7 +773,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_pos", ephemeral=True) + return await send(ctx, "missingPosPerm", ephemeral=True) moved_track = await player.move_track(target, to, ctx.author) await send(ctx, "moved", moved_track, to) @@ -820,7 +820,7 @@ class Basic(commands.Cog): return await send(ctx, "djToMe", ephemeral=True) if member not in player.channel.members: - return await send(ctx, "djnotinchannel", member, ephemeral=True) + return await send(ctx, "djNotInChannel", member, ephemeral=True) player.dj = member await send(ctx, "djswap", member) @@ -834,7 +834,7 @@ class Basic(commands.Cog): return await send(ctx, "noPlayer", ephemeral=True) if not player.is_privileged(ctx.author): - return await send(ctx, "missingPerms_autoplay", ephemeral=True) + return await send(ctx, "missingAutoPlayPerm", ephemeral=True) check = not player.settings.get("autoplay", False) player.settings['autoplay'] = check @@ -863,7 +863,7 @@ class Basic(commands.Cog): "Test if the bot is alive, and see the delay between your commands and my response." player: voicelink.Player = ctx.guild.voice_client - value = await get_lang(ctx.guild.id, "pingTitle1", "pingfield1", "pingTitle2", "pingfield2") + value = await get_lang(ctx.guild.id, "pingTitle1", "pingField1", "pingTitle2", "pingField2") embed = discord.Embed(color=settings.embed_color) embed.add_field( diff --git a/cogs/settings.py b/cogs/settings.py index ad6e22d..b3834fd 100644 --- a/cogs/settings.py +++ b/cogs/settings.py @@ -204,7 +204,7 @@ class Settings(commands.Cog, name="settings"): discord.ui.View.from_message(player.controller).stop() await update_settings(ctx.guild.id, {"$set": {'controller': toggle}}) - await send(ctx, 'togglecontroller', await get_lang(ctx.guild.id, "enabled" if toggle else "disabled")) + await send(ctx, 'toggleController', await get_lang(ctx.guild.id, "enabled" if toggle else "disabled")) @settings.command(name="duplicatetrack", aliases=get_aliases("duplicatetrack")) @commands.has_permissions(manage_guild=True) diff --git a/ipc/methods.py b/ipc/methods.py index 384eece..9a93a17 100644 --- a/ipc/methods.py +++ b/ipc/methods.py @@ -305,7 +305,7 @@ async def updatePosition(player: Player, member: Member, data: Dict) -> None: async def toggleAutoplay(player: Player, member: Member, data: Dict) -> Dict: if not player.is_privileged(member): - return error_msg(player.get_msg('missingPerms_autoplay')) + return error_msg(player.get_msg('missingAutoPlayPerm')) check = data.get("status", False) player.settings['autoplay'] = check diff --git a/langs/CH.json b/langs/CH.json index d61e527..29b890a 100644 --- a/langs/CH.json +++ b/langs/CH.json @@ -19,7 +19,7 @@ "247": "現在您有 `{0}` 24/7 模式。", "bypassVote": "現在您有 `{0}` 投票系統。", "setVolume": "已將音量設置為 `{0}`%", - "togglecontroller": "現在您已 `{0}` 音樂控制器。", + "toggleController": "現在您已 `{0}` 音樂控制器。", "toggleDuplicateTrack": "現在您已 `{0}` 防止隊列中存在重複曲目。", "toggleControllerMsg": "現在您已從音樂控制器 `{0}` 消息。", "toggleSilentMsg": "你{0}靜默消息。", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} 管理員\n{1} 管理伺服器\n{2} 管理頻道\n{3} 管理訊息```", "pingTitle1": "機器人資訊:", "pingTitle2": "播放器信息:", - "pingfield1": "```分片 ID: {0}/{1}\n分片延遲: {2:.3f}s {3}\n區域: {4}```", - "pingfield2": "```節點: {0} - {1:.3f}s\n播放器數量: {2}\n語音區域: {3}```", + "pingField1": "```分片 ID: {0}/{1}\n分片延遲: {2:.3f}s {3}\n區域: {4}```", + "pingField2": "```節點: {0} - {1:.3f}s\n播放器數量: {2}\n語音區域: {3}```", "addEffect": "套用音效`{0}`濾鏡。", "clearEffect": "聲音效果已清除!", - "FilterTagAlreadyInUse": "此聲音效果已在使用中!請使用 /cleareffect 移除它。", + "filterTagAlreadyInUse": "此聲音效果已在使用中!請使用 /cleareffect 移除它。", "playlistViewTitle": "📜 所有 {0} 的播放清單", "playlistViewHeaders": "ID:,時間:,名稱:,曲目數:", "playlistFooter": "輸入 /playlist play [播放清單] 加入此播放清單至隊列中。", @@ -81,19 +81,19 @@ "noTrackFound": "找不到符合該查詢的歌曲!請提供有效的網址。", "noLinkSupport": "搜索命令不支援網址!", "voted": "您已投票!", - "missingPerms_pos": "只有 DJ 或管理員才能更改位置。", - "missingPerms_mode": "只有 DJ 或管理員才能切換循環模式。", - "missingPerms_queue": "只有 DJ 或管理員才能從隊列中移除音軌。", - "missingPerms_autoplay": "只有 DJ 或管理員才能啟用或停用自動播放模式!", - "missingPerms_function": "只有 DJ 或管理員才能使用此功能。", + "missingPosPerm": "只有 DJ 或管理員才能更改位置。", + "missingModePerm": "只有 DJ 或管理員才能切換循環模式。", + "missingQueuePerm": "只有 DJ 或管理員才能從隊列中移除音軌。", + "missingAutoPlayPerm": "只有 DJ 或管理員才能啟用或停用自動播放模式!", + "missingFunctionPerm": "只有 DJ 或管理員才能使用此功能。", "timeFormatError": "時間格式不正確。例如:2:42 或 12:39:31", "lyricsNotFound": "找不到歌詞。輸入 /lyrics <歌曲名稱> <作者> 查找歌詞。", "missingTrackInfo": "有些音軌資訊缺失。", "noVoiceChannel": "找不到語音頻道!", "playlistAddError": "您無權將串流視訊添加到播放清單中!", "playlistAddError2": "添加音軌到播放清單時發生問題!", - "playlistlimited": "您已達到上限!您只能將 {0} 首歌曲添加到播放清單中。", - "playlistrepeated": "您的播放清單中已經存在相同的音軌!", + "playlistLimited": "您已達到上限!您只能將 {0} 首歌曲添加到播放清單中。", + "playlistRepeated": "您的播放清單中已經存在相同的音軌!", "playlistAdded": "❤️ 已將 **{0}** 添加到 {1} 的播放清單中 [`{2}`]!", "playerDropdown": "選擇要跳轉到的音軌...", "playerFilter": "選擇要套用的篩選器...", @@ -158,15 +158,12 @@ "autoplay": "自動播放模式現在為 **{0}**。", "notdj": "您不是DJ,當前DJ為 {0}。", "djToMe": "您無法將DJ權限轉移給自己或機器人。", - "djnotinchannel": "`{0}` 不在語音頻道中。", + "djNotInChannel": "`{0}` 不在語音頻道中。", "djswap": "您已將DJ權限轉移給 `{0}`。", - "chaptersDropdown": "選擇要跳轉到的章節...", - "noChaptersFound": "找不到任何章節!", - "chatpersNotSupport": "此命令僅支持 YouTube 影片!", "voicelinkQueueFull": "抱歉,您已達到隊列中 `{0}` 首歌曲的最大數量!", "voicelinkOutofList": "請提供有效的歌曲索引!", "voicelinkDuplicateTrack": "抱歉,此歌曲已在隊列中。", - "deocdeError": "解碼文件時出現問題!", + "decodeError": "解碼文件時出現問題!", "invalidStartTime": "無效的開始時間! 時間必須在 `00:00` 和 `{0}` 之間。", "invalidEndTime": "無效的結束時間! 時間必須在 `00:00` 和 `{0}` 之間。", "invalidTimeOrder": "結束時間不能小於或等於開始時間。", diff --git a/langs/DE.json b/langs/DE.json index 932564a..f33ab0c 100644 --- a/langs/DE.json +++ b/langs/DE.json @@ -19,7 +19,7 @@ "247": "Der 24/7-Modus wurde erfolgreich `{0}`.", "bypassVote": "Das Abstimmungssystem wurde `{0}`", "setVolume": "Stelle die Lautstärke auf `{0}`%.", - "togglecontroller": "Der Musikcontroller wurde erfolgreich `{0}`", + "toggleController": "Der Musikcontroller wurde erfolgreich `{0}`", "toggleDuplicateTrack": "Du hast das hinzufügen von doppelten Tracks in der Warteschlange `{0}`", "toggleControllerMsg": "Nachrichten vom Musik-Controller wurden erfolgreich `{0}`", "toggleSilentMsg": "Sie haben {0} stille Nachrichten.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} Administrator\n{1} Guild verwalten\n{2} Kanal verwalten\n{3} Manage_Messages```", "pingTitle1": "Bot-Info:", "pingTitle2": "Player Info:", - "pingfield1": "```Shard-ID: {0}/{1}\nShard-Latenz: {2:.3f}s {3}\nRegion: {4}```", - "pingfield2": "```Node: {0} - {1:.3f}s\nPlayer: {2}\nSprachregion: {3}```", + "pingField1": "```Shard-ID: {0}/{1}\nShard-Latenz: {2:.3f}s {3}\nRegion: {4}```", + "pingField2": "```Node: {0} - {1:.3f}s\nPlayer: {2}\nSprachregion: {3}```", "addEffect": "Wende den Effekt `{0}` Filter an.", "clearEffect": "Die Soundeffekte wurden gelöscht!", - "FilterTagAlreadyInUse": "Diese Soundeffekte sind bereits im Einsatz! Bitte verwende /cleareffect , um sie zu entfernen.", + "filterTagAlreadyInUse": "Diese Soundeffekte sind bereits im Einsatz! Bitte verwende /cleareffect , um sie zu entfernen.", "playlistViewTitle": "📜 Alle Playlists von {0}", "playlistViewHeaders": "ID:,Zeit:,Name:,Tracks:", "playlistFooter": "Gebe /playlist play [playlist] ein, um die Playlist in die Warteschlange einzufügen.", @@ -81,19 +81,19 @@ "noTrackFound": "Es wurden keine Songs mit dieser Abfrage gefunden! Bitte gib eine gültige URL an.", "noLinkSupport": "Der Suchbefehl unterstützt keine Links!", "voted": "Du hast abgestimmt!", - "missingPerms_pos": "Nur der DJ oder Admins können die Position ändern.", - "missingPerms_mode": "Nur der DJ oder Admins können den Wiederholungsmodus wechseln.", - "missingPerms_queue": "Nur der DJ oder Admins können Tracks aus der Warteschlange entfernen.", - "missingPerms_autoplay": "Nur der DJ oder Admins können den Autoplay-Modus aktivieren oder deaktivieren!", - "missingPerms_function": "Nur DJ oder Admins können diese Funktion verwenden.", + "missingPosPerm": "Nur der DJ oder Admins können die Position ändern.", + "missingModePerm": "Nur der DJ oder Admins können den Wiederholungsmodus wechseln.", + "missingQueuePerm": "Nur der DJ oder Admins können Tracks aus der Warteschlange entfernen.", + "missingAutoPlayPerm": "Nur der DJ oder Admins können den Autoplay-Modus aktivieren oder deaktivieren!", + "missingFunctionPerm": "Nur DJ oder Admins können diese Funktion verwenden.", "timeFormatError": "Falsches Zeitformat. Beispiel: 2:42 oder 12:39:31", "lyricsNotFound": "Es wurden keine Songtexte gefunden. Gebe /lyrics ein, um die Songtexte zu finden.", "missingTrackInfo": "Einige Track-Informationen fehlen.", "noVoiceChannel": "Dieser Sprachkanal wurde nicht gefunden!", "playlistAddError": "Du darfst Deiner Wiedergabenliste keine aktiven Streams hinzufügen!", "playlistAddError2": "Es gab ein Problem beim Hinzufügen von Tracks zur Wiedergabenliste!", - "playlistlimited": "Du hast das Limit erreicht! Du kannst nur noch {0} Songs zu Deiner Wiedergabenliste hinzufügen.", - "playlistrepeated": "In Deiner Wiedergabenliste gibt es bereits den gleichen Track!", + "playlistLimited": "Du hast das Limit erreicht! Du kannst nur noch {0} Songs zu Deiner Wiedergabenliste hinzufügen.", + "playlistRepeated": "In Deiner Wiedergabenliste gibt es bereits den gleichen Track!", "playlistAdded": "❤️ **{0}** wurde in der Wiedergabenliste [`{2}`] von {1} hinzugefügt.", "playerDropdown": "Wähle einen Song aus, um zu überspringen ...", "playerFilter": "Wähle einen Filter aus, um ihn anzuwenden ...", @@ -158,15 +158,12 @@ "autoplay": "Der Autoplay-Modus ist jetzt **{0}**", "notdj": "Du bist kein DJ, der aktuelle DJ ist {0}.", "djToMe": "Du kannst den DJ nicht an dich selbst oder einer App übertragen.", - "djnotinchannel": "`{0}` ist nicht im Sprachkanal.", + "djNotInChannel": "`{0}` ist nicht im Sprachkanal.", "djswap": "Du hast die DJ-Rolle auf `{0}` übertragen.", - "chaptersDropdown": "Wähle ein Kapitel zum Überspringen aus...", - "noChaptersFound": "Es wurden keine Kapitel gefunden!", - "chatpersNotSupport": "Dieser Befehl unterstützt nur YouTube-Videos!", "voicelinkQueueFull": "Entschuldigung, Du hast das Maximum von `{0}` Tracks in der Warteschlange erreicht.", "voicelinkOutofList": "Bitte gib einen gültigen Track-Index an!", "voicelinkDuplicateTrack": "Entschuldigung, dieser Track ist bereits in der Warteschlange.", - "deocdeError": "Beim Dekodieren der Datei ist etwas schief gelaufen!", + "decodeError": "Beim Dekodieren der Datei ist etwas schief gelaufen!", "invalidStartTime": "Ungültige Startzeit! Die Zeit muss innerhalb von `00:00` und `{0}` liegen.", "invalidEndTime": "Ungültige Endzeit! Die Zeit muss innerhalb von `00:00` und `{0}` liegen.", "invalidTimeOrder": "Die Endzeit darf nicht kleiner oder gleich dem Startzeit sein.", diff --git a/langs/EN.json b/langs/EN.json index 096d6a9..378a207 100644 --- a/langs/EN.json +++ b/langs/EN.json @@ -19,7 +19,7 @@ "247": "24/7 mode is now `{0}`.", "bypassVote": "You have `{0}` voting system.", "setVolume": "Set the volume to `{0}`%", - "togglecontroller": "You now have `{0}` the music controller.", + "toggleController": "You now have `{0}` the music controller.", "toggleDuplicateTrack": "You have now `{0}` duplicate track prevention.", "toggleControllerMsg": "You now have `{0}` messages from the music controller.", "toggleSilentMsg": "You have {0} silent messaging.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} Administrator\n{1} Manage_Guild\n{2} Manage_Channel\n{3} Manage_Messages```", "pingTitle1": "Bot Info:", "pingTitle2": "Player Info:", - "pingfield1": "```Shard ID: {0}/{1}\nShard Latency: {2:.3f}s {3}\nRegion: {4}```", - "pingfield2": "```Node: {0} - {1:.3f}s\nPlayers: {2}\nVoice Region: {3}```", + "pingField1": "```Shard ID: {0}/{1}\nShard Latency: {2:.3f}s {3}\nRegion: {4}```", + "pingField2": "```Node: {0} - {1:.3f}s\nPlayers: {2}\nVoice Region: {3}```", "addEffect": "Applied the `{0}` effect.", "clearEffect": "The sound effects have been cleared!", - "FilterTagAlreadyInUse": "This sound effect is already in use! Please use /cleareffect to remove it.", + "filterTagAlreadyInUse": "This sound effect is already in use! Please use /cleareffect to remove it.", "playlistViewTitle": "📜 All of {0}'s Playlists", "playlistViewHeaders": "ID:,Time:,Name:,Tracks:", "playlistFooter": "Type /playlist play [playlist] to add a playlist the into the queue.", @@ -81,19 +81,19 @@ "noTrackFound": "No songs were found with that query! Please provide a valid url.", "noLinkSupport": "Search command does not support links!", "voted": "You have voted!", - "missingPerms_pos": "Only the DJ or admins may change the position.", - "missingPerms_mode": "Only the DJ or admins may switch loop mode.", - "missingPerms_queue": "Only the DJ or admins may remove track from the queue.", - "missingPerms_autoplay": "Only the DJ or admins can enable or disable autoplay mode!", - "missingPerms_function": "Only DJ or Admin can use this function.", + "missingPosPerm": "Only the DJ or admins may change the position.", + "missingModePerm": "Only the DJ or admins may switch loop mode.", + "missingQueuePerm": "Only the DJ or admins may remove track from the queue.", + "missingAutoPlayPerm": "Only the DJ or admins can enable or disable autoplay mode!", + "missingFunctionPerm": "Only DJ or Admin can use this function.", "timeFormatError": "Incorrect time format. Example: 2:42 or 12:39:31", "lyricsNotFound": "Lyrics not found. Type /lyrics to find the lyrics.", "missingTrackInfo": "Some track details are missing.", "noVoiceChannel": "Voice Channel Not Found!", "playlistAddError": "You are not allowed to add streaming videos to your playlist!", "playlistAddError2": "There was a problem adding tracks to the playlist!", - "playlistlimited": "You have reached the limit! You can only add {0} songs to your playlist.", - "playlistrepeated": "This track is already in your playlist!", + "playlistLimited": "You have reached the limit! You can only add {0} songs to your playlist.", + "playlistRepeated": "This track is already in your playlist!", "playlistAdded": "❤️ Added **{0}** into {1}'s playlist [`{2}`]!", "playerDropdown": "Select a song to skip to ...", "playerFilter": "Select a filter to apply ...", @@ -158,15 +158,12 @@ "autoplay": "Autoplay mode is now **{0}**", "notdj": "You are not DJ. The current DJ is {0}.", "djToMe": "You cannot transfer role of DJ to yourself or a bot.", - "djnotinchannel": "`{0}` is not in the voice channel.", + "djNotInChannel": "`{0}` is not in the voice channel.", "djswap": "You have transferred the role of dj to `{0}`.", - "chaptersDropdown": "Select a chapter to skip to ...", - "noChaptersFound": "No chapters has been found!", - "chatpersNotSupport": "This command only supports Youtube videos!", "voicelinkQueueFull": "Sorry, you have reached the maximum of `{0}` tracks in the queue!", "voicelinkOutofList": "Please provide a valid track index!", "voicelinkDuplicateTrack": "Sorry, this track is already in the queue.", - "deocdeError": "Something went wrong while decoding the file!", + "decodeError": "Something went wrong while decoding the file!", "invalidStartTime": "Invalid start time, it must be between `00:00` and `{0}`", "invalidEndTime": "Invalid end time, it must be between `00:00` and `{0}`", "invalidTimeOrder": "End time cannot be less than or equal to start time", diff --git a/langs/ES.json b/langs/ES.json index cb8691c..b2ec7bb 100644 --- a/langs/ES.json +++ b/langs/ES.json @@ -19,7 +19,7 @@ "247": "Ahora tienes `{0}` modo 24/7.", "bypassVote": "Ahora tienes `{0}` sistema de votación.", "setVolume": "Ajustar el volumen a `{0}`%", - "togglecontroller": "Ahora tienes `{0}` el controlador de música.", + "toggleController": "Ahora tienes `{0}` el controlador de música.", "toggleDuplicateTrack": "Ahora tienes `{0}` para evitar que se agreguen pistas duplicadas a la cola.", "toggleControllerMsg": "Ahora tiene `{0}` mensajes del controlador de música.", "toggleSilentMsg": "Tienes {0} mensajes silenciosos.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} Administrador\n{1} Administrar servidor\n{2} Administrar canal\n{3} Administrar mensajes```", "pingTitle1": "Información del bot:", "pingTitle2": "Información del reproductor:", - "pingfield1": "```ID de fragmento: {0}/{1}\nLatencia de fragmento: {2:.3f}s {3}\nRegión: {4}```", - "pingfield2": "```Nodo: {0} - {1:.3f}s\nReproductores: {2}\nRegión de voz: {3}```", + "pingField1": "```ID de fragmento: {0}/{1}\nLatencia de fragmento: {2:.3f}s {3}\nRegión: {4}```", + "pingField2": "```Nodo: {0} - {1:.3f}s\nReproductores: {2}\nRegión de voz: {3}```", "addEffect": "plica el efecto `{0}` filtro.", "clearEffect": "¡Los efectos de sonido se han borrado!", - "FilterTagAlreadyInUse": "¡Este efecto de sonido ya está en uso! Utilice /cleareffect para eliminarlo.", + "filterTagAlreadyInUse": "¡Este efecto de sonido ya está en uso! Utilice /cleareffect para eliminarlo.", "playlistViewTitle": "📜 Todas las listas de reproducción de {0}", "playlistViewHeaders": "ID:,Tiempo:,Nombre:,Pistas:", "playlistFooter": "Escriba /playlist play [playlist] para agregar la lista de reproducción a la cola.", @@ -81,19 +81,19 @@ "noTrackFound": "No se encontraron canciones con esa consulta. Proporcione una URL válida.", "noLinkSupport": "¡El comando de búsqueda no admite enlaces!", "voted": "¡Has votado!", - "missingPerms_pos": "Solo el DJ o los administradores pueden cambiar la posición.", - "missingPerms_mode": "Solo el DJ o los administradores pueden cambiar el modo de bucle.", - "missingPerms_queue": "Solo el DJ o los administradores pueden eliminar una canción de la cola.", - "missingPerms_autoplay": "¡Solo el DJ o los administradores pueden habilitar o deshabilitar el modo de reproducción automática!", - "missingPerms_function": "Solo el DJ o los administradores pueden usar esta función.", + "missingPosPerm": "Solo el DJ o los administradores pueden cambiar la posición.", + "missingModePerm": "Solo el DJ o los administradores pueden cambiar el modo de bucle.", + "missingQueuePerm": "Solo el DJ o los administradores pueden eliminar una canción de la cola.", + "missingAutoPlayPerm": "¡Solo el DJ o los administradores pueden habilitar o deshabilitar el modo de reproducción automática!", + "missingFunctionPerm": "Solo el DJ o los administradores pueden usar esta función.", "timeFormatError": "Formato de tiempo incorrecto. Ejemplo: 2:42 o 12:39:31", "lyricsNotFound": "No se encontraron letras. Escriba /lyrics para buscar las letras.", "missingTrackInfo": "Falta información de la canción.", "noVoiceChannel": "¡Canal de voz no encontrado!", "playlistAddError": "No está autorizado para agregar videos de transmisión a su lista de reproducción.", "playlistAddError2": "Hubo un problema al agregar canciones a la lista de reproducción.", - "playlistlimited": "¡Ha alcanzado el límite! Solo puede agregar {0} canciones a su lista de reproducción.", - "playlistrepeated": "¡Ya hay una canción igual en su lista de reproducción!", + "playlistLimited": "¡Ha alcanzado el límite! Solo puede agregar {0} canciones a su lista de reproducción.", + "playlistRepeated": "¡Ya hay una canción igual en su lista de reproducción!", "playlistAdded": "❤️ Agregado **{0}** a la lista de reproducción de {1} [`{2}`]!", "playerDropdown": "Seleccione una canción para saltar a ...", "playerFilter": "Seleccione un filtro para aplicar ...", @@ -158,15 +158,12 @@ "autoplay": "El modo de reproducción automática es ahora **{0}**", "notdj": "No eres el DJ. El DJ actual es {0}.", "djToMe": "No puedes transferir el rol de DJ a ti mismo o a un bot.", - "djnotinchannel": "`{0}` no está en el canal de voz.", + "djNotInChannel": "`{0}` no está en el canal de voz.", "djswap": "Has transferido el rol de DJ a `{0}`.", - "chaptersDropdown": "Selecciona un capítulo al que saltar ...", - "noChaptersFound": "¡No se encontraron capítulos!", - "chatpersNotSupport": "¡Este comando solo es compatible con videos de Youtube!", "voicelinkQueueFull": "Lo siento, ¡ha alcanzado el máximo de `{0}` canciones en la cola!", "voicelinkOutofList": "¡Proporcione un índice de pista válido!", "voicelinkDuplicateTrack": "Lo siento, esta canción ya está en la cola.", - "deocdeError": "¡Algo salió mal al decodificar el archivo!", + "decodeError": "¡Algo salió mal al decodificar el archivo!", "invalidStartTime": "Tiempo de inicio inválido! El tiempo debe estar entre `00:00` y `{0}`.", "invalidEndTime": "Tiempo de finalización inválido! El tiempo debe estar entre `00:00` y `{0}`.", "invalidTimeOrder": "El tiempo final no puede ser menor o igual que el tiempo de inicio.", diff --git a/langs/FR.json b/langs/FR.json index 5dfbef2..fb1df9e 100644 --- a/langs/FR.json +++ b/langs/FR.json @@ -19,7 +19,7 @@ "247": "Le mode 24/7 est maintenant `{0}`.", "bypassVote": "Vous avez le système de vote `{0}`.", "setVolume": "Le volume est réglé à `{0}`%", - "togglecontroller": "Vous avez maintenant `{0}` le contrôleur de musique.", + "toggleController": "Vous avez maintenant `{0}` le contrôleur de musique.", "toggleDuplicateTrack": "Vous avez maintenant `{0}` la prévention des morceaux en double.", "toggleControllerMsg": "Vous avez maintenant `{0}` les messages du contrôleur musical.", "toggleSilentMsg": "Vous avez {0} messages silencieux.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} Administrateur\n{1} Gérer_serveur\n{2} Gérer_salons\n{3} Gérer_messages```", "pingTitle1": "Infos Bot :", "pingTitle2": "Infos Lecteur :", - "pingfield1": "```Shard ID : {0}/{1}\nLatence Shard : {2:.3f}s {3}\nRégion : {4}```", - "pingfield2": "```Node : {0} - {1:.3f}s\nLecteurs : {2}\nRégion vocale : {3}```", + "pingField1": "```Shard ID : {0}/{1}\nLatence Shard : {2:.3f}s {3}\nRégion : {4}```", + "pingField2": "```Node : {0} - {1:.3f}s\nLecteurs : {2}\nRégion vocale : {3}```", "addEffect": "Effet `{0}` appliqué.", "clearEffect": "Les effets sonores ont été supprimés !", - "FilterTagAlreadyInUse": "Cet effet sonore est déjà utilisé ! Veuillez utiliser /cleareffect pour le retirer.", + "filterTagAlreadyInUse": "Cet effet sonore est déjà utilisé ! Veuillez utiliser /cleareffect pour le retirer.", "playlistViewTitle": "📜 Toutes les playlists de {0}", "playlistViewHeaders": "ID:,Durée:,Nom:,Morceaux:", "playlistFooter": "Tapez /playlist play [playlist] pour ajouter une playlist à la file.", @@ -81,19 +81,19 @@ "noTrackFound": "Aucune chanson trouvée pour cette requête ! Veuillez fournir une URL valide.", "noLinkSupport": "La commande de recherche ne prend pas en charge les liens !", "voted": "Vous avez voté !", - "missingPerms_pos": "Seul le DJ ou les admins peuvent changer la position.", - "missingPerms_mode": "Seul le DJ ou les admins peuvent changer le mode de boucle.", - "missingPerms_queue": "Seul le DJ ou les admins peuvent retirer un morceau de la file.", - "missingPerms_autoplay": "Seul le DJ ou les admins peuvent activer/désactiver l'autoplay !", - "missingPerms_function": "Seul le DJ ou un admin peut utiliser cette fonction.", + "missingPosPerm": "Seul le DJ ou les admins peuvent changer la position.", + "missingModePerm": "Seul le DJ ou les admins peuvent changer le mode de boucle.", + "missingQueuePerm": "Seul le DJ ou les admins peuvent retirer un morceau de la file.", + "missingAutoPlayPerm": "Seul le DJ ou les admins peuvent activer/désactiver l'autoplay !", + "missingFunctionPerm": "Seul le DJ ou un admin peut utiliser cette fonction.", "timeFormatError": "Format de temps incorrect. Exemple : 2:42 ou 12:39:31", "lyricsNotFound": "Paroles non trouvées. Tapez /lyrics pour chercher les paroles.", "missingTrackInfo": "Certaines informations sur le morceau sont manquantes.", "noVoiceChannel": "Aucun salon vocal trouvé !", "playlistAddError": "Vous n'êtes pas autorisé à ajouter des vidéos en streaming à votre playlist !", "playlistAddError2": "Problème lors de l'ajout de morceaux à la playlist !", - "playlistlimited": "Vous avez atteint la limite ! Vous ne pouvez ajouter que {0} chansons à votre playlist.", - "playlistrepeated": "Ce morceau est déjà dans votre playlist !", + "playlistLimited": "Vous avez atteint la limite ! Vous ne pouvez ajouter que {0} chansons à votre playlist.", + "playlistRepeated": "Ce morceau est déjà dans votre playlist !", "playlistAdded": "❤️ **{0}** ajouté à la playlist [`{2}`] de {1} !", "playerDropdown": "Sélectionnez une chanson vers laquelle passer...", "playerFilter": "Sélectionnez un filtre à appliquer...", @@ -158,15 +158,12 @@ "autoplay": "Le mode autoplay est maintenant **{0}**", "notdj": "Vous n'êtes pas DJ. Le DJ actuel est {0}.", "djToMe": "Impossible de transférer le rôle de DJ à vous-même ou à un bot.", - "djnotinchannel": "`{0}` n'est pas dans le salon vocal.", + "djNotInChannel": "`{0}` n'est pas dans le salon vocal.", "djswap": "Vous avez transféré le rôle de DJ à `{0}`.", - "chaptersDropdown": "Sélectionnez un chapitre vers lequel passer ...", - "noChaptersFound": "Aucun chapitre trouvé !", - "chatpersNotSupport": "Cette commande ne supporte que les vidéos YouTube !", "voicelinkQueueFull": "Désolé, vous avez atteint le maximum de `{0}` morceaux dans la file !", "voicelinkOutofList": "Veuillez fournir un index de morceau valide !", "voicelinkDuplicateTrack": "Désolé, ce morceau est déjà dans la file.", - "deocdeError": "Une erreur s'est produite lors du décodage du fichier !", + "decodeError": "Une erreur s'est produite lors du décodage du fichier !", "invalidStartTime": "Heure de début invalide, doit être entre `00:00` et `{0}`", "invalidEndTime": "Heure de fin invalide, doit être entre `00:00` et `{0}`", "invalidTimeOrder": "L'heure de fin ne peut pas être inférieure ou égale à celle de début", diff --git a/langs/JA.json b/langs/JA.json index d79b725..88660fe 100644 --- a/langs/JA.json +++ b/langs/JA.json @@ -19,7 +19,7 @@ "247": "今、24/7モードは「{0}」です。", "bypassVote": "今、投票システムは「{0}」になりました。", "setVolume": "音量を「{0}%」に設定しました。", - "togglecontroller": "今、音楽コントローラーは「{0}」です。", + "toggleController": "今、音楽コントローラーは「{0}」です。", "toggleDuplicateTrack": "今、キュー内の重複トラックを防止するための設定は「{0}」です。", "toggleControllerMsg": "現在、音楽コントローラーから `{0}` 件のメッセージがあります。", "toggleSilentMsg": "あなたは{0}サイレントメッセージを持っています。", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} 管理者\n{1} ギルド管理\n{2} チャンネル管理\n{3} メッセージ管理```", "pingTitle1": "ボット情報:", "pingTitle2": "プレーヤー情報:", - "pingfield1": "```シャードID:{0}/{1}\nシャードレイテンシ:{2:.3f}s {3}\nリージョン:{4}```", - "pingfield2": "```ノード:{0} - {1:.3f}s\nプレイヤー数:{2}\n音声リージョン:{3}```", + "pingField1": "```シャードID:{0}/{1}\nシャードレイテンシ:{2:.3f}s {3}\nリージョン:{4}```", + "pingField2": "```ノード:{0} - {1:.3f}s\nプレイヤー数:{2}\n音声リージョン:{3}```", "addEffect": "`{0}` フィルターを適用します。", "clearEffect": "効果音がクリアされました!", - "FilterTagAlreadyInUse": "このサウンドエフェクトはすでに使用されています!削除するには/cleareffect を使用してください。", + "filterTagAlreadyInUse": "このサウンドエフェクトはすでに使用されています!削除するには/cleareffect を使用してください。", "playlistViewTitle": "📜 {0}のすべてのプレイリスト", "playlistViewHeaders": "ID:,時間:,名前:,トラック:", "playlistFooter": "プレイリストをキューに追加するには、/playlist play [playlist]を入力してください。", @@ -81,19 +81,19 @@ "noTrackFound": "そのクエリで曲が見つかりませんでした!有効なURLを入力してください。", "noLinkSupport": "検索コマンドはリンクをサポートしていません!", "voted": "投票しました!", - "missingPerms_pos": "DJまたは管理者のみが位置を変更できます。", - "missingPerms_mode": "DJまたは管理者のみがループモードを切り替えることができます。", - "missingPerms_queue": "DJまたは管理者のみがキューからトラックを削除できます。", - "missingPerms_autoplay": "DJまたは管理者のみがオートプレイモードを有効化または無効化できます!", - "missingPerms_function": "DJまたは管理者のみがこの機能を使用できます。", + "missingPosPerm": "DJまたは管理者のみが位置を変更できます。", + "missingModePerm": "DJまたは管理者のみがループモードを切り替えることができます。", + "missingQueuePerm": "DJまたは管理者のみがキューからトラックを削除できます。", + "missingAutoPlayPerm": "DJまたは管理者のみがオートプレイモードを有効化または無効化できます!", + "missingFunctionPerm": "DJまたは管理者のみがこの機能を使用できます。", "timeFormatError": "時間の形式が間違っています。例:2:42または12:39:31", "lyricsNotFound": "歌詞が見つかりませんでした。/lyrics <曲名> <アーティスト>と入力して歌詞を検索してください。", "missingTrackInfo": "一部のトラック情報が欠落しています。", "noVoiceChannel": "音声チャンネルが見つかりません!", "playlistAddError": "ストリーミングビデオをプレイリストに追加することはできません!", "playlistAddError2": "トラックをプレイリストに追加する際に問題が発生しました!", - "playlistlimited": "制限に達しました!プレイリストには{0}曲しか追加できません。", - "playlistrepeated": "すでにプレイリストに同じトラックがあります!", + "playlistLimited": "制限に達しました!プレイリストには{0}曲しか追加できません。", + "playlistRepeated": "すでにプレイリストに同じトラックがあります!", "playlistAdded": "❤️ **{0}**を{1}のプレイリスト[`{2}`]に追加しました!", "playerDropdown": "スキップする曲を選択してください...", "playerFilter": "適用するフィルターを選択してください...", @@ -158,15 +158,12 @@ "autoplay": "オートプレイモードが **{0}** に設定されました。", "notdj": "DJではありません。現在のDJは{0}です。", "djToMe": "自分自身またはボットにDJ権限を移行することはできません。", - "djnotinchannel": "`{0}`はボイスチャンネルにいません。", + "djNotInChannel": "`{0}`はボイスチャンネルにいません。", "djswap": "DJの役割を`{0}`に移行しました。", - "chaptersDropdown": "スキップする章を選択してください...", - "noChaptersFound": "章が見つかりませんでした!", - "chatpersNotSupport": "このコマンドはYouTubeの動画のみサポートしています!", "voicelinkQueueFull": "申し訳ありませんが、キュー内の曲数が最大値の`{0}`に達しました!", "voicelinkOutofList": "有効なトラックインデックスを指定してください!", "voicelinkDuplicateTrack": "申し訳ありませんが、このトラックは既にキューに存在します。", - "deocdeError": "ファイルのデコード中に問題が発生しました!", + "decodeError": "ファイルのデコード中に問題が発生しました!", "invalidStartTime": "無効な開始時間!時間は `00:00` と `{0}` の間に設定する必要があります。", "invalidEndTime": "無効な終了時間!時間は `00:00` と `{0}` の間に設定する必要があります。", "invalidTimeOrder": "終了時間は開始時間より大きくない必要があります。", diff --git a/langs/KO.json b/langs/KO.json index eedb8e0..fe49dfc 100644 --- a/langs/KO.json +++ b/langs/KO.json @@ -19,7 +19,7 @@ "247": "이제 24/7 모드에서 `{0}`으로 변경되었습니다.", "bypassVote": "이제 `{0}` 투표 시스템을 사용할 수 있습니다.", "setVolume": "볼륨을 `{0}`%로 설정했습니다.", - "togglecontroller": "이제 음악 컨트롤러가 `{0}`(으)로 설정되었습니다.", + "toggleController": "이제 음악 컨트롤러가 `{0}`(으)로 설정되었습니다.", "toggleDuplicateTrack": "이제 대기열에서 중복된 트랙을 방지하기 위해 `{0}`(으)로 설정되었습니다.", "toggleControllerMsg": "이제 음악 컨트롤러로부터 `{0}` 메시지가 있습니다.", "toggleSilentMsg": "당신은 {0} 침묵 메시지를 사용하고 있습니다.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} 관리자\n{1} 서버 관리\n{2} 채널 관리\n{3} 메시지 관리```", "pingTitle1": "봇 정보:", "pingTitle2": "플레이어 정보:", - "pingfield1": "```쉬드 ID: {0}/{1}\n쉬드 대기 시간: {2:.3f}s {3}\n지역: {4}```", - "pingfield2": "```노드: {0} - {1:.3f}s\n플레이어: {2}\n음성 지역: {3}```", + "pingField1": "```쉬드 ID: {0}/{1}\n쉬드 대기 시간: {2:.3f}s {3}\n지역: {4}```", + "pingField2": "```노드: {0} - {1:.3f}s\n플레이어: {2}\n음성 지역: {3}```", "addEffect": "`{0}` 필터를 적용하세요.", "clearEffect": "효과가 삭제되었습니다!", - "FilterTagAlreadyInUse": "이 필터는 이미 사용 중입니다! 삭제하려면 /cleareffect 를 사용하십시오.", + "filterTagAlreadyInUse": "이 필터는 이미 사용 중입니다! 삭제하려면 /cleareffect 를 사용하십시오.", "playlistViewTitle": "📜 {0}의 모든 재생 목록", "playlistViewHeaders": "ID:,시간:,이름:,트랙:", "playlistFooter": "/playlist play [재생 목록]을 입력하여 재생 목록을 대기열에 추가하세요.", @@ -81,19 +81,19 @@ "noTrackFound": "해당 쿼리로 곡을 찾을 수 없습니다. 유효한 URL을 제공해주세요.", "noLinkSupport": "검색 명령은 링크를 지원하지 않습니다!", "voted": "투표하셨습니다!", - "missingPerms_pos": "DJ 또는 관리자만 위치를 변경할 수 있습니다.", - "missingPerms_mode": "DJ 또는 관리자만 루프 모드를 전환할 수 있습니다.", - "missingPerms_queue": "DJ 또는 관리자만 대기열에서 곡을 제거할 수 있습니다.", - "missingPerms_autoplay": "DJ 또는 관리자만 자동재생 모드를 활성화하거나 비활성화할 수 있습니다!", - "missingPerms_function": "DJ 또는 관리자만이 이 기능을 사용할 수 있습니다.", + "missingPosPerm": "DJ 또는 관리자만 위치를 변경할 수 있습니다.", + "missingModePerm": "DJ 또는 관리자만 루프 모드를 전환할 수 있습니다.", + "missingQueuePerm": "DJ 또는 관리자만 대기열에서 곡을 제거할 수 있습니다.", + "missingAutoPlayPerm": "DJ 또는 관리자만 자동재생 모드를 활성화하거나 비활성화할 수 있습니다!", + "missingFunctionPerm": "DJ 또는 관리자만이 이 기능을 사용할 수 있습니다.", "timeFormatError": "잘못된 시간 형식입니다. 예: 2:42 또는 12:39:31", "lyricsNotFound": "가사를 찾을 수 없습니다. 가사를 찾으려면 /lyrics <노래 제목> <작곡가>를 입력하세요.", "missingTrackInfo": "일부 트랙 정보가 누락되었습니다.", "noVoiceChannel": "음성 채널을 찾을 수 없습니다!", "playlistAddError": "스트리밍 비디오를 재생목록에 추가할 수 없습니다!", "playlistAddError2": "재생목록에 곡을 추가하는 중 문제가 발생했습니다!", - "playlistlimited": "한 재생목록에 최대 {0}곡까지 추가 가능합니다. 이제 한도에 도달했습니다!", - "playlistrepeated": "재생목록에 이미 같은 곡이 있습니다!", + "playlistLimited": "한 재생목록에 최대 {0}곡까지 추가 가능합니다. 이제 한도에 도달했습니다!", + "playlistRepeated": "재생목록에 이미 같은 곡이 있습니다!", "playlistAdded": "❤️ **{0}**을(를) {1}의 재생목록 [`{2}`] 에 추가했습니다!", "playerDropdown": "건너뛰기 할 노래를 선택하세요...", "playerFilter": "적용할 필터를 선택하세요...", @@ -158,15 +158,12 @@ "autoplay": "자동 재생 모드가 **{0}**(으)로 변경되었습니다.", "notdj": "당신은 DJ가 아닙니다. 현재 DJ는 {0}입니다.", "djToMe": "자신이나 봇에게 DJ를 이전할 수 없습니다.", - "djnotinchannel": "`{0}`님이 음성 채널에 없습니다.", + "djNotInChannel": "`{0}`님이 음성 채널에 없습니다.", "djswap": "당신은 DJ 권한을 `{0}`님에게 이전했습니다.", - "chaptersDropdown": "건너뛸 챕터를 선택해주세요.", - "noChaptersFound": "챕터를 찾을 수 없습니다!", - "chatpersNotSupport": "이 명령어는 유튜브 비디오만 지원합니다!", "voicelinkQueueFull": "죄송합니다. 큐에 `{0}`개의 트랙을 모두 추가하셨습니다!", "voicelinkOutofList": "유효한 트랙 인덱스를 제공해주세요!", "voicelinkDuplicateTrack": "죄송합니다. 이 트랙은 이미 큐에 있습니다.", - "deocdeError": "파일 디코딩 중 문제가 발생했습니다!", + "decodeError": "파일 디코딩 중 문제가 발생했습니다!", "invalidStartTime": "효력 없는 시작 시간! 시간은 `00:00` 과 `{0}` 사이에 설정해야 합니다.", "invalidEndTime": "효력 없는 종료 시간! 시간은 `00:00` 과 `{0}` 사이에 설정해야 합니다.", "invalidTimeOrder": "종료 시간은 시작 시간보다 클수 있어야 합니다.", diff --git a/langs/PL.json b/langs/PL.json index 91e7f20..1e0ff06 100644 --- a/langs/PL.json +++ b/langs/PL.json @@ -19,7 +19,7 @@ "247": "Tryb 24/7: `{0}`", "bypassVote": "System głosowania: `{0}`", "setVolume": "Ustawiono głośność na `{0}`%", - "togglecontroller": "Kontroler muzyki: `{0}`", + "toggleController": "Kontroler muzyki: `{0}`", "toggleDuplicateTrack": "Unikanie duplikowania pozycji w kolejce: `{0}`", "toggleControllerMsg": "Wiadomości od kontrolera muzyki: `{0}`", "toggleSilentMsg": "Masz {0} ciche wiadomości.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} Administrator\n{1} Zarządzanie_serwerem\n{2} Zarządzanie_kanałem\n{3} Zarządzanie_wiadomościami```", "pingTitle1": "Informacje o bocie:", "pingTitle2": "Infomracje o odtwarzaczu:", - "pingfield1": "```ID Shard'a: {0}/{1}\nOpóźnienie shard'a: {2:.3f}s {3}\nRegion: {4}```", - "pingfield2": "```Węzeł: {0} - {1:.3f}s\nOdtwarzacze: {2}\nRegion: {3}```", + "pingField1": "```ID Shard'a: {0}/{1}\nOpóźnienie shard'a: {2:.3f}s {3}\nRegion: {4}```", + "pingField2": "```Węzeł: {0} - {1:.3f}s\nOdtwarzacze: {2}\nRegion: {3}```", "addEffect": "Nałożono efekt: `{0}`", "clearEffect": "Efekty dźwiękowe zostały wyczyszczone.", - "FilterTagAlreadyInUse": "Ten efekt dźwiękowy jest już w używany! Użyj /cleareffect aby go wyłączyć.", + "filterTagAlreadyInUse": "Ten efekt dźwiękowy jest już w używany! Użyj /cleareffect aby go wyłączyć.", "playlistViewTitle": "📜 Playlisty użytkownika {0}:", "playlistViewHeaders": "ID:,Czas:,Nazwa:,Ilość pozycji:", "playlistFooter": "Użyj /playlist play [nazwa_playlisty] by dodać playlistę do kolejki.", @@ -81,19 +81,19 @@ "noTrackFound": "Nie znaleziono utworu! Podaj poprawny adres URL.", "noLinkSupport": "Komenda /search nie obsługuje linków!", "voted": "Zagłosowałeś!", - "missingPerms_pos": "Tylko DJ lub administracja może zmieniać pozycje.", - "missingPerms_mode": "Tylko DJ lub administracja może zmieniać tryb pętli.", - "missingPerms_queue": "Tylko DJ lub administracja może usuwać pozycje z kolejki.", - "missingPerms_autoplay": "Tylko DJ lub administracja może włączać lub wyłączać tryb autoplay!", - "missingPerms_function": "Tylko DJ lub administracja może używać tej funkcji.", + "missingPosPerm": "Tylko DJ lub administracja może zmieniać pozycje.", + "missingModePerm": "Tylko DJ lub administracja może zmieniać tryb pętli.", + "missingQueuePerm": "Tylko DJ lub administracja może usuwać pozycje z kolejki.", + "missingAutoPlayPerm": "Tylko DJ lub administracja może włączać lub wyłączać tryb autoplay!", + "missingFunctionPerm": "Tylko DJ lub administracja może używać tej funkcji.", "timeFormatError": "Niepoprawny format czasu. Przykład: 2:42 lub 12:39:31", "lyricsNotFound": "Tekst nie został znaleziony. Użyj /lyrics by znaleźć tekst piosenki.", "missingTrackInfo": "Brakuje niektórych informacji o utworze.", "noVoiceChannel": "Kanał nie został znaleziony", "playlistAddError": "Niemożesz dodawać transmisji na żywo do playlisty!", "playlistAddError2": "Podczas dodawania utworu do playlisty wystąpił błąd!", - "playlistlimited": "Osiągnąłeś limit! Możesz dodać maksymalnie `{0}` pozycji do playlisty.", - "playlistrepeated": "Ten utwór znajduje sie już na playliście!", + "playlistLimited": "Osiągnąłeś limit! Możesz dodać maksymalnie `{0}` pozycji do playlisty.", + "playlistRepeated": "Ten utwór znajduje sie już na playliście!", "playlistAdded": "❤️ Dodano **{0}** do playlisty [`{2}`] użytkownika {1}!", "playerDropdown": "Wybierz pozycję do której pominąć ...", "playerFilter": "Wybierz efekt który chesz nałożyć ...", @@ -158,15 +158,12 @@ "autoplay": "Tryb autoodwarzania jest teraz **{0}**", "notdj": "Nie jesteś DJ'em. Obecnym DJ'em jest {0}.", "djToMe": "Nie możesz przekazać roli DJ'a sobie lub botu.", - "djnotinchannel": "`{0}` nie jest na kanale głosowym.", + "djNotInChannel": "`{0}` nie jest na kanale głosowym.", "djswap": "Przekazałeś rolę DJ'a użytkownikowi `{0}`.", - "chaptersDropdown": "Wybierz rozdział do którego przeskoczyć ...", - "noChaptersFound": "Nie znaleziono żadnych rozdziałów!", - "chatpersNotSupport": "Ta komenda obsługuje jedynie utwory z YouTube'a!", "voicelinkQueueFull": "Przepraszamy osiągnięto limit `{0}` pozycji w kolejce!", "voicelinkOutofList": "Podaj właściwy indeks utworu!", "voicelinkDuplicateTrack": "Błąd! Ten utwór znajduje się już w kolejce.", - "deocdeError": "Coś poszło nie tak podczas dekodowania pliku!", + "decodeError": "Coś poszło nie tak podczas dekodowania pliku!", "invalidStartTime": "Niepoprawny czas startu, musi on mieścić się pomiędzy `00:00` a `{0}`", "invalidEndTime": "Niepoprawny czas końca, musi on mieścić się pomiędzy `00:00` a `{0}`", "invalidTimeOrder": "Czas zakończenia odtwarzania nie może być mniejszy lub równy czasowi startu", diff --git a/langs/RU.json b/langs/RU.json index cae3948..2eb340b 100644 --- a/langs/RU.json +++ b/langs/RU.json @@ -19,7 +19,7 @@ "247": "Теперь у вас `{0}` режим 24/7.", "bypassVote": "Теперь у вас `{0}` система голосования.", "setVolume": "Установить громкость на `{0}`%", - "togglecontroller": "Теперь у вас `{0}` контроллер музыки.", + "toggleController": "Теперь у вас `{0}` контроллер музыки.", "toggleDuplicateTrack": "Теперь у вас `{0}` фильтр дубликатов в очереди.", "toggleControllerMsg": "Теперь у вас `{0}` сообщения от плеера.", "toggleSilentMsg": "У вас {0} тихих сообщений.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} Администратор\n{1} Управление_Сервером\n{2} Управление_Каналом\n{3} Управление_Сообщениями```", "pingTitle1": "Информация о боте:", "pingTitle2": "Информация о плеере:", - "pingfield1": "```ID Шарда: {0}/{1}\nЗадержка Шарда: {2:.3f}s {3}\nРегион: {4}```", - "pingfield2": "```Сервис: {0} - {1:.3f}s\nИгроки: {2}\nРегион Голоса: {3}```", + "pingField1": "```ID Шарда: {0}/{1}\nЗадержка Шарда: {2:.3f}s {3}\nРегион: {4}```", + "pingField2": "```Сервис: {0} - {1:.3f}s\nИгроки: {2}\nРегион Голоса: {3}```", "addEffect": "Применен `{0}` эффект.", "clearEffect": "Звуковые эффекты были очищены!", - "FilterTagAlreadyInUse": "Этот звуковой эффект уже используется! Пожалуйста, используйте /cleareffect <Тег>, чтобы удалить его.", + "filterTagAlreadyInUse": "Этот звуковой эффект уже используется! Пожалуйста, используйте /cleareffect <Тег>, чтобы удалить его.", "playlistViewTitle": "📜 Все плейлисты пользователя {0}", "playlistViewHeaders": "ID:,Время:,Название:,Треки:", "playlistFooter": "Введите /playlist play [плейлист], чтобы добавить плейлист в очередь.", @@ -81,19 +81,19 @@ "noTrackFound": "Треки по такому запросу не найдены! Пожалуйста, укажите действительную ссылку.", "noLinkSupport": "Команда поиска не поддерживает ссылки!", "voted": "Вы проголосовали!", - "missingPerms_pos": "Только DJ или администраторы могут изменять позицию.", - "missingPerms_mode": "Только DJ или администраторы могут переключить режим цикла.", - "missingPerms_queue": "Только DJ или администраторы могут удалять треки из очереди.", - "missingPerms_autoplay": "Только DJ или администраторы могут включать или выключать режим autoplay!", - "missingPerms_function": "Только DJ или администраторы могут использовать эту функцию.", + "missingPosPerm": "Только DJ или администраторы могут изменять позицию.", + "missingModePerm": "Только DJ или администраторы могут переключить режим цикла.", + "missingQueuePerm": "Только DJ или администраторы могут удалять треки из очереди.", + "missingAutoPlayPerm": "Только DJ или администраторы могут включать или выключать режим autoplay!", + "missingFunctionPerm": "Только DJ или администраторы могут использовать эту функцию.", "timeFormatError": "Неверный формат времени. Пример: 2:42PM или 12:39:31", "lyricsNotFound": "Текст песни не найден. Введите /lyrics <Название песни> <Автор> для поиска текста.", "missingTrackInfo": "Некоторая информация о треке отсутствует.", "noVoiceChannel": "Голосовой канал не найден!", "playlistAddError": "Вам не разрешено добавлять потоковые видео в плейлист!", "playlistAddError2": "Произошла ошибка при добавлении треков в плейлист!", - "playlistlimited": "Вы достигли лимита! Вы можете добавить только {0} треков в свой плейлист.", - "playlistrepeated": "Такой трек уже есть в плейлисте!", + "playlistLimited": "Вы достигли лимита! Вы можете добавить только {0} треков в свой плейлист.", + "playlistRepeated": "Такой трек уже есть в плейлисте!", "playlistAdded": "❤️ Добавлен **{0}** в плейлист пользователя {1} [`{2}`]!", "playerDropdown": "Выберите трек для перехода ...", "playerFilter": "Выберите фильтр для применения ...", @@ -158,15 +158,12 @@ "autoplay": "Режим autoplay **{0}**", "notdj": "Вы не DJ. Текущий DJ: {0}.", "djToMe": "Вы не можете передать роль DJ себе или боту.", - "djnotinchannel": "Пользователь `{0}` не находится в голосовом канале.", + "djNotInChannel": "Пользователь `{0}` не находится в голосовом канале.", "djswap": "Вы передали роль DJ пользователю `{0}`.", - "chaptersDropdown": "Выберите эпизод для перехода ...", - "noChaptersFound": "Эпизод не найден!", - "chatpersNotSupport": "Эта команда поддерживает только видео на YouTube!", "voicelinkQueueFull": "Извините, вы достигли максимального количества `{0}` треков в очереди!", "voicelinkOutofList": "Пожалуйста, предоставьте действительный индекс трека!", "voicelinkDuplicateTrack": "Извините, этот трек уже есть в очереди.", - "deocdeError": "Что-то пошло не так при декодировании файла!", + "decodeError": "Что-то пошло не так при декодировании файла!", "invalidStartTime": "Недействительное значение! Диапозон времени должен быть между `00:00` и `{0}`.", "invalidEndTime": "Недействительное значение! Диапозон времени должен быть между `00:00` и `{0}`.", "invalidTimeOrder": "Время конца трека не может быть меньше или равно времени начала.", diff --git a/langs/UA.json b/langs/UA.json index 6b8443d..cecbf4b 100644 --- a/langs/UA.json +++ b/langs/UA.json @@ -19,7 +19,7 @@ "247": "Тепер у вас `{0}` режим 24/7.", "bypassVote": "Тепер у вас `{0}` система голосування.", "setVolume": "Встановити гучність на `{0}`%", - "togglecontroller": "Тепер у вас `{0}` контролер музики.", + "toggleController": "Тепер у вас `{0}` контролер музики.", "toggleDuplicateTrack": "Тепер у вас `{0}` запобігання дублюванню треку в черзі.", "toggleControllerMsg": "Тепер у вас `{0}` повідомлення від контролера музики.", "toggleSilentMsg": "У вас {0} тихих повідомлень.", @@ -33,11 +33,11 @@ "settingsPermValue": "```{0} Адміністратор\n{1} Керування_Сервером\n{2} Керування_Каналом\n{3} Керування_Сообщениями```", "pingTitle1": "Інформація про бота:", "pingTitle2": "Інформація про плеєр:", - "pingfield1": "````ID Шарда: {0}/{1}\nЗатримка Шарда: {2:.3f}s {3}\nРегіон: {4}````", - "pingfield2": "```Вузол: {0} - {1:.3f}s\nГравці: {2}\nРегіон Голосу: {3}```", + "pingField1": "````ID Шарда: {0}/{1}\nЗатримка Шарда: {2:.3f}s {3}\nРегіон: {4}````", + "pingField2": "```Вузол: {0} - {1:.3f}s\nГравці: {2}\nРегіон Голосу: {3}```", "addEffect": "Застосуйте ефект `{0}` фільтр.", "clearEffect": "Звукові ефекти були очищені!", - "FilterTagAlreadyInUse": "Цей звуковий ефект уже використовується! Будь ласка, використовуйте /cleareffect <Тег>, щоб видалити його.", + "filterTagAlreadyInUse": "Цей звуковий ефект уже використовується! Будь ласка, використовуйте /cleareffect <Тег>, щоб видалити його.", "playlistViewTitle": "📜 Усі плейлисти користувача {0}", "playlistViewHeaders": "ID:,Час:,Назва:,Треки:", "playlistFooter": "Введите /playlist play [плейлист], чтобы добавить плейлист в очередь.", @@ -81,19 +81,19 @@ "noTrackFound": "Пісні з таким запитом не знайдено! Будь ласка, вкажіть дійсне посилання.", "noLinkSupport": "Команда пошуку не підтримує посилання!", "voted": "Ви проголосували!", - "missingPerms_pos": "Тільки DJ або адміністратори можуть змінювати позицію.", - "missingPerms_mode": "Тільки DJ або адміністратори можуть перемкнути режим циклу.", - "missingPerms_queue": "Тільки DJ або адміністратори можуть видаляти треки з черги.", - "missingPerms_autoplay": "Тільки DJ або адміністратори можуть вмикати або вимикати режим autoplay!", - "missingPerms_function": "Тільки DJ або адміністратори можуть використовувати цю функцію.", + "missingPosPerm": "Тільки DJ або адміністратори можуть змінювати позицію.", + "missingModePerm": "Тільки DJ або адміністратори можуть перемкнути режим циклу.", + "missingQueuePerm": "Тільки DJ або адміністратори можуть видаляти треки з черги.", + "missingAutoPlayPerm": "Тільки DJ або адміністратори можуть вмикати або вимикати режим autoplay!", + "missingFunctionPerm": "Тільки DJ або адміністратори можуть використовувати цю функцію.", "timeFormatError": "Неправильний формат часу. Приклад: 2:42", "lyricsNotFound": "Текст пісні не знайдено. Введіть /lyrics <Назва пісні> <Автор> для пошуку тексту.", "missingTrackInfo": "Деяка інформація про трек відсутня.", "noVoiceChannel": "Голосовий канал не знайдено!", "playlistAddError": "Вам не дозволено додавати потокові відео в плейлист!", "playlistAddError2": "Сталася помилка під час додавання треків у плейлист!", - "playlistlimited": "Ви досягли ліміту! Ви можете додати тільки {0} пісні до свого плейлиста.", - "playlistrepeated": "Такий самий трек уже є у вашому плейлисті!", + "playlistLimited": "Ви досягли ліміту! Ви можете додати тільки {0} пісні до свого плейлиста.", + "playlistRepeated": "Такий самий трек уже є у вашому плейлисті!", "playlistAdded": "❤️ Додано **{0}** до плейлиста користувача {1} [`{2}`]!", "playerDropdown": "Виберіть пісню для переходу ...", "playerFilter": "Виберіть фільтр для застосування ...", @@ -158,15 +158,12 @@ "autoplay": "Режим autoplay встановлено на **{0}**", "notdj": "Ви не DJ. Поточний DJ: {0}.", "djToMe": "Ви не можете передати роль DJ собі або боту.", - "djnotinchannel": "`{0}` не знаходиться в голосовому каналі.", + "djNotInChannel": "`{0}` не знаходиться в голосовому каналі.", "djswap": "Ви передали роль DJ `{0}`.", - "chaptersDropdown": "Виберіть епізод для переходу ...", - "noChaptersFound": "Епізод не знайдено!", - "chatpersNotSupport": "Ця команда підтримує тільки відео з YouTube!", "voicelinkQueueFull": "Вибачте, ви досягли максимальної кількості `{0}` треків у черзі!", "voicelinkOutofList": "Будь ласка, надайте дійсний індекс треку!", "voicelinkDuplicateTrack": "Вибачте, цей трек уже є в черзі.", - "deocdeError": "Щось пішло не так під час декодування файлу!", + "decodeError": "Щось пішло не так під час декодування файлу!", "invalidStartTime": "Недійснений час початку! Час має бути в межах `00:00` та `{0}`.", "invalidEndTime": "Недійснений час закінчення! Час має бути в межах `00:00` та `{0}`.", "invalidTimeOrder": "Час закінчення не може бути меншим або рівним часу початку.", diff --git a/local_langs/zh-TW.json b/local_langs/zh-TW.json index e56cd23..3a9f765 100644 --- a/local_langs/zh-TW.json +++ b/local_langs/zh-TW.json @@ -150,7 +150,7 @@ "volume": "音量", "Set the player's volume.": "設置播放器的音量。", "Input a integer.": "輸入一個整數。", - "togglecontroller": "切換控制器", + "toggleController": "切換控制器", "Toggles the music controller.": "切換音樂控制器。", "duplicatetrack": "重複歌曲", "Toggle Vocard to prevent duplicate songs from queuing.": "切換 Vocard 以防止重複歌曲加入隊列。", diff --git a/views/controller.py b/views/controller.py index a832614..9bfc8b8 100644 --- a/views/controller.py +++ b/views/controller.py @@ -194,10 +194,10 @@ class AddFav(ControlButton): user = await func.get_user(interaction.user.id, 'playlist') rank, max_p, max_t = func.check_roles() if len(user['200']['tracks']) >= max_t: - return await self.send(interaction, "playlistlimited", max_t, ephemeral=True) + return await self.send(interaction, "playlistLimited", max_t, ephemeral=True) if track.track_id in user['200']['tracks']: - return await self.send(interaction, "playlistrepeated", ephemeral=True) + return await self.send(interaction, "playlistRepeated", ephemeral=True) respond = await func.update_user(interaction.user.id, {"$push": {'playlist.200.tracks': track.track_id}}) if respond: await self.send(interaction, "playlistAdded", track.title, interaction.user.mention, user['200']['name'], ephemeral=True) @@ -213,7 +213,7 @@ class Loop(ControlButton): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await self.send(interaction, 'missingPerms_mode', ephemeral=True) + return await self.send(interaction, 'missingModePerm', ephemeral=True) await self.player.set_repeat(requester=interaction.user) self.change_states(self.player.queue._repeat.peek_next().name) @@ -226,7 +226,7 @@ class VolumeUp(ControlButton): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await self.send(interaction, "missingPerms_function") + return await self.send(interaction, "missingFunctionPerm") value = value if (value := self.player.volume + 20) <= 150 else 150 await self.player.set_volume(value, interaction.user) @@ -239,7 +239,7 @@ class VolumeDown(ControlButton): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await self.send(interaction, "missingPerms_function") + return await self.send(interaction, "missingFunctionPerm") value = value if (value := self.player.volume - 20) >= 0 else 0 await self.player.set_volume(value, interaction.user) @@ -255,7 +255,7 @@ class VolumeMute(ControlButton): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await self.send(interaction, "missingPerms_function") + return await self.send(interaction, "missingFunctionPerm") is_muted = self.player.volume != 0 value = 0 if is_muted else self.player.settings.get("volume", 100) @@ -269,7 +269,7 @@ class AutoPlay(ControlButton): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await self.send(interaction, "missingPerms_autoplay", ephemeral=True) + return await self.send(interaction, "missingAutoPlayPerm", ephemeral=True) check = not self.player.settings.get("autoplay", False) self.player.settings['autoplay'] = check @@ -305,7 +305,7 @@ class Forward(ControlButton): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await self.send(interaction, 'missingPerms_pos', ephemeral=True) + return await self.send(interaction, 'missingPosPerm', ephemeral=True) if not self.player.current: return await self.send(interaction, 'noTrackPlaying', ephemeral=True) @@ -324,7 +324,7 @@ class Rewind(ControlButton): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await self.send(interaction, 'missingPerms_pos', ephemeral=True) + return await self.send(interaction, 'missingPosPerm', ephemeral=True) if not self.player.current: return await self.send(interaction, 'noTrackPlaying', ephemeral=True) @@ -379,7 +379,7 @@ class Tracks(discord.ui.Select): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await func.send(interaction, "missingPerms_function", ephemeral=True) + return await func.send(interaction, "missingFunctionPerm", ephemeral=True) self.player.queue.skipto(int(self.values[0].split(". ")[0])) await self.player.stop() @@ -404,7 +404,7 @@ class Effects(discord.ui.Select): async def callback(self, interaction: discord.Interaction): if not self.player.is_privileged(interaction.user): - return await func.send(interaction, "missingPerms_function", ephemeral=True) + return await func.send(interaction, "missingFunctionPerm", ephemeral=True) avalibable_filters = voicelink.Filters.get_available_filters() if self.values[0] == "None": diff --git a/voicelink/player.py b/voicelink/player.py index 7d5d49e..398d454 100644 --- a/voicelink/player.py +++ b/voicelink/player.py @@ -760,7 +760,7 @@ class Player(VoiceProtocol): try: self._filters.add_filter(filter=filter) except FilterTagAlreadyInUse: - raise FilterTagAlreadyInUse(self.get_msg("FilterTagAlreadyInUse")) + raise FilterTagAlreadyInUse(self.get_msg("filterTagAlreadyInUse")) payload = self._filters.get_all_payloads() await self.send(method=RequestMethod.PATCH, data={"filters": payload}) From f6c25118e162ffc2ffb5b54ff7988b6d300e7e9f Mon Sep 17 00:00:00 2001 From: Choco <94597336+ChocoMeow@users.noreply.github.com> Date: Sun, 10 Aug 2025 12:44:25 +0800 Subject: [PATCH 6/7] Add Vietnamese language support Added VN.json containing Vietnamese translations for bot messages. --- langs/VN.json | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 langs/VN.json diff --git a/langs/VN.json b/langs/VN.json new file mode 100644 index 0000000..6fef020 --- /dev/null +++ b/langs/VN.json @@ -0,0 +1,172 @@ +{ + "unknownException": "⚠️ Đã xảy ra lỗi khi chạy lệnh! Vui lòng thử lại sau hoặc vào server Discord của chúng tôi để được hỗ trợ.", + "enabled": "đã bật", + "disabled": "đã tắt", + "nodeReconnect": "Vui lòng thử lại! Sau khi node kết nối lại.", + "noChannel": "Không có kênh voice để kết nối. Vui lòng cung cấp một kênh hoặc tham gia một kênh.", + "alreadyConnected": "Đã kết nối với kênh voice.", + "noPermission": "Xin lỗi! Tôi không có quyền tham gia hoặc nói trong kênh voice của bạn.", + "noCreatePermission": "Xin lỗi! Tôi không có quyền tạo kênh yêu cầu bài hát.", + "noPlaySource": "Không thể tìm thấy nguồn phát nào!", + "noPlayer": "Không tìm thấy trình phát nào trên máy chủ này.", + "notVote": "Lệnh này yêu cầu bạn bình chọn! Gõ `/vote` để biết thêm thông tin.", + "missingIntents": "Xin lỗi, lệnh này không thể thực hiện vì bot thiếu quyền yêu cầu cần thiết: `({0})`.", + "languageNotFound": "Không tìm thấy gói ngôn ngữ! Vui lòng chọn một gói ngôn ngữ hiện có.", + "changedLanguage": "Đã thay đổi thành công sang gói ngôn ngữ `{0}`.", + "setPrefix": "Hoàn thành! Tiền tố của tôi trong máy chủ của bạn bây giờ là `{0}`. Thử chạy `{1}ping` để kiểm tra.", + "setDJ": "Đặt DJ thành {0}.", + "setQueue": "Đặt chế độ hàng đợi thành `{0}`.", + "247": "Chế độ 24/7 bây giờ là `{0}`.", + "bypassVote": "Bạn có hệ thống bình chọn `{0}`.", + "setVolume": "Đặt âm lượng thành `{0}`%", + "toggleController": "Bây giờ bạn đã `{0}` bộ điều khiển nhạc.", + "toggleDuplicateTrack": "Bây giờ bạn đã `{0}` tính năng ngăn chặn bài hát trùng lặp.", + "toggleControllerMsg": "Bây giờ bạn đã `{0}` tin nhắn từ bộ điều khiển nhạc.", + "toggleSilentMsg": "Bạn có {0} tin nhắn im lặng.", + "settingsMenu": "Cài Đặt Máy Chủ | {0}", + "settingsTitle": "❤️ Thông Tin Cơ Bản:", + "settingsValue": "```Tiền tố: {0}\nNgôn ngữ: {1}\nBộ Điều Khiển Nhạc: {2}\nVai Trò DJ: @{3}\nBỏ Qua Bình Chọn: {4}\n24/7: {5}\nÂm Lượng Mặc Định: {6}%\nThời Gian Phát: {7}```", + "settingsTitle2": "🔗 Thông tin hàng đợi:", + "settingsValue2": "```Chế Độ Hàng Đợi: {0}\nSố Bài Tối Đa: {1}\nBài Hát Trùng Lặp: {2}```", + "settingsTitle3": "🎤 Thông Tin Trạng Thái Voice:", + "settingsPermTitle": "✨ Quyền hạn:", + "settingsPermValue": "```{0} Quản Trị Viên\n{1} Quản_Lý_Guild\n{2} Quản_Lý_Kênh\n{3} Quản_Lý_Tin_Nhắn```", + "pingTitle1": "Thông Tin Bot:", + "pingTitle2": "Thông Tin Trình Phát:", + "pingField1": "```ID Shard: {0}/{1}\nĐộ Trễ Shard: {2:.3f}s {3}\nKhu Vực: {4}```", + "pingField2": "```Node: {0} - {1:.3f}s\nTrình Phát: {2}\nKhu Vực Voice: {3}```", + "addEffect": "Đã áp dụng hiệu ứng `{0}`.", + "clearEffect": "Các hiệu ứng âm thanh đã được xóa!", + "filterTagAlreadyInUse": "Hiệu ứng âm thanh này đã được sử dụng! Vui lòng sử dụng /cleareffect để xóa nó.", + "playlistViewTitle": "📜 Tất Cả Playlist Của {0}", + "playlistViewHeaders": "ID:,Thời Gian:,Tên:,Bài Hát:", + "playlistFooter": "Gõ /playlist play [playlist] để thêm playlist vào hàng đợi.", + "playlistNotFound": "Không tìm thấy playlist [`{0}`]. Gõ /playlist view để xem tất cả playlist của bạn.", + "playlistNotAccess": "Xin lỗi! Bạn không được phép truy cập playlist này!", + "playlistNoTrack": "Xin lỗi! Không có bài hát nào trong playlist [`{0}`].", + "playlistNotAllow": "Lệnh này không được phép trên playlist được liên kết và chia sẻ.", + "playlistPlay": "Đã thêm playlist [`{0}`] với `{1}` bài hát vào hàng đợi.", + "playlistOverText": "Xin lỗi! Tên playlist không thể vượt quá 10 ký tự.", + "playlistSameName": "Xin lỗi! Vui lòng chọn tên mới cho playlist.", + "playlistDeleteError": "Bạn không được phép xóa playlist mặc định.", + "playlistRemove": "Bạn đã xóa playlist [`{0}`].", + "playlistSendErrorPlayer": "Xin lỗi! Bạn không thể gửi lời mời cho chính mình.", + "playlistSendErrorBot": "Xin lỗi! Bạn không thể gửi lời mời cho một bot.", + "playlistBelongs": "Xin lỗi! Playlist này thuộc về <@{0}>.", + "playlistShare": "Xin lỗi! Playlist này đã được chia sẻ với {0}.", + "playlistSent": "Xin lỗi! Bạn đã gửi lời mời cho người dùng đó trước đó rồi.", + "noPlaylistAcc": "{0} không tạo tài khoản playlist.", + "overPlaylistCreation": "Bạn không thể tạo nhiều hơn `{0}` playlist!", + "playlistExists": "Playlist [`{0}`] đã tồn tại.", + "playlistNotInvalidUrl": "Vui lòng nhập liên kết playlist Spotify hoặc Youtube công khai hợp lệ.", + "playlistCreated": "Bạn đã tạo playlist `{0}`. Gõ /playlist view để biết thêm thông tin.", + "playlistRenamed": "Bạn đã đổi tên `{0}` thành `{1}`.", + "playlistLimitTrack": "Bạn đã đạt giới hạn! Bạn chỉ có thể thêm `{0}` bài hát vào playlist của mình.", + "playlistPlaylistLink": "Bạn không được phép sử dụng liên kết playlist.", + "playlistStream": "Bạn không được phép thêm video trực tiếp vào playlist của mình.", + "playlistPositionNotFound": "Không thể tìm thấy vị trí `{0}` từ playlist [`{1}`] của bạn!", + "playlistRemoved": "👋 Đã xóa **{0}** khỏi playlist [`{2}`] của {1}.", + "playlistClear": "Bạn đã xóa thành công playlist [`{0}`] của mình.", + "playlistView": "Trình Xem Playlist", + "playlistViewDesc": "```Tên | ID: {0} | {1}\nTổng Số Bài Hát: {2}\nChủ Sở Hữu: {3}\nLoại: {4}\n```", + "playlistViewPermsValue": "📖 Đọc: ✓ ✍🏽 Viết: {0} 🗑️ Xóa: {1}", + "playlistViewPermsValue2": "📖 Đọc: {0}", + "playlistViewTrack": "Bài Hát", + "playlistViewPage": "Trang: {0}/{1} | Tổng Thời Lượng: {2}", + "inboxFull": "Xin lỗi! Hộp thư của {0} đã đầy.", + "inboxNoMsg": "Không có tin nhắn nào trong hộp thư của bạn.", + "invitationSent": "Đã gửi lời mời đến {0}.", + "notInChannel": "{0}, bạn phải ở trong {1} để sử dụng lệnh voice. Vui lòng tham gia lại nếu bạn đang ở trong voice!", + "noTrackPlaying": "Hiện tại không có bài hát nào đang phát", + "noTrackFound": "Không tìm thấy bài hát nào với truy vấn đó! Vui lòng cung cấp url hợp lệ.", + "noLinkSupport": "Lệnh tìm kiếm không hỗ trợ liên kết!", + "voted": "Bạn đã bình chọn!", + "missingPosPerm": "Chỉ DJ hoặc quản trị viên mới có thể thay đổi vị trí.", + "missingModePerm": "Chỉ DJ hoặc quản trị viên mới có thể chuyển chế độ lặp.", + "missingQueuePerm": "Chỉ DJ hoặc quản trị viên mới có thể xóa bài hát khỏi hàng đợi.", + "missingAutoPlayPerm": "Chỉ DJ hoặc quản trị viên mới có thể bật hoặc tắt chế độ tự động phát!", + "missingFunctionPerm": "Chỉ DJ hoặc Admin mới có thể sử dụng chức năng này.", + "timeFormatError": "Định dạng thời gian không chính xác. Ví dụ: 2:42 hoặc 12:39:31", + "lyricsNotFound": "Không tìm thấy lời bài hát. Gõ /lyrics để tìm lời bài hát.", + "missingTrackInfo": "Một số chi tiết bài hát bị thiếu.", + "noVoiceChannel": "Không Tìm Thấy Kênh Voice!", + "playlistAddError": "Bạn không được phép thêm video trực tiếp vào playlist của mình!", + "playlistAddError2": "Đã xảy ra sự cố khi thêm bài hát vào playlist!", + "playlistLimited": "Bạn đã đạt giới hạn! Bạn chỉ có thể thêm {0} bài hát vào playlist của mình.", + "playlistRepeated": "Bài hát này đã có trong playlist của bạn!", + "playlistAdded": "❤️ Đã thêm **{0}** vào playlist [`{2}`] của {1}!", + "playerDropdown": "Chọn một bài hát để bỏ qua đến ...", + "playerFilter": "Chọn một bộ lọc để áp dụng ...", + "buttonBack": "Quay Lại", + "buttonPause": "Tạm Dừng", + "buttonResume": "Tiếp Tục", + "buttonSkip": "Bỏ Qua", + "buttonLeave": "Rời Khỏi", + "buttonLoop": "Lặp Lại", + "buttonVolumeUp": "Tăng Âm Lượng", + "buttonVolumeDown": "Giảm Âm Lượng", + "buttonVolumeMute": "Tắt Tiếng", + "buttonVolumeUnmute": "Bật Tiếng", + "buttonAutoPlay": "Tự Động Phát", + "buttonShuffle": "Trộn Bài", + "buttonForward": "Tua Tới", + "buttonRewind": "Tua Lùi", + "buttonLyrics": "Lời Bài Hát", + "nowplayingDesc": "**Đang Phát:**\n```{0}```", + "nowplayingField": "Tiếp Theo:", + "nowplayingLink": "Nghe trên {0}", + "connect": "Đã kết nối với {0}", + "live": "TRỰC TIẾP", + "playlistLoad": " 🎶 Đã thêm playlist **{0}** với `{1}` bài hát vào hàng đợi.", + "trackLoad": "Đã thêm **[{0}](<{1}>)** bởi **{2}** (`{3}`) để bắt đầu phát.\n", + "trackLoad_pos": "Đã thêm **[{0}](<{1}>)** bởi **{2}** (`{3}`) vào hàng đợi ở vị trí **{4}**\n", + "searchTitle": "Truy Vấn Tìm Kiếm: {0}", + "searchDesc": "➥ Nền tảng: {0} **{1}**\n➥ Kết quả: **{2}**\n\n{3}", + "searchWait": "Chọn bài hát bạn muốn thêm vào hàng đợi.", + "searchTimeout": "Tìm kiếm hết thời gian. Vui lòng thử lại sau.", + "searchSuccess": "Đã thêm bài hát vào hàng đợi.", + "queueTitle": "Hàng Đợi Sắp Tới:", + "historyTitle": "Lịch Sử Hàng Đợi:", + "viewTitle": "Hàng Đợi Nhạc", + "viewDesc": "**Đang Phát: [Nhấp Vào Đây]({0}) ⮯**\n{1}", + "viewFooter": "Trang: {0}/{1} | Tổng Thời Lượng: {2}", + "pauseError": "Trình phát đã được tạm dừng.", + "pauseVote": "{0} đã bình chọn tạm dừng bài hát. [{1}/{2}]", + "paused": "`{0}` đã tạm dừng trình phát.", + "resumeError": "Trình phát không bị tạm dừng.", + "resumeVote": "{0} đã bình chọn tiếp tục bài hát. [{1}/{2}]", + "resumed": "`{0}` đã tiếp tục trình phát.", + "shuffleError": "Thêm nhiều bài hát vào hàng đợi trước khi trộn bài.", + "shuffleVote": "{0} đã bình chọn trộn hàng đợi. [{1}/{2}]", + "shuffled": "Hàng đợi đã được trộn.", + "skipError": "Không có bài hát nào để bỏ qua.", + "skipVote": "{0} đã bình chọn bỏ qua bài hát. [{1}/{2}]", + "skipped": "`{0}` đã bỏ qua bài hát.", + "backVote": "{0} đã bình chọn quay lại bài hát trước. [{1}/{2}]", + "backed": "`{0}` đang quay lại bài hát trước.", + "leaveVote": "{0} đã bình chọn dừng trình phát. [{1}/{2}]", + "left": "`{0}` đã dừng trình phát.", + "seek": "Đặt trình phát thành **{0}**", + "repeat": "Chế độ lặp lại đã được đặt thành `{0}`", + "cleared": "Đã xóa tất cả bài hát trong `{0}`", + "removed": "`{0}` bài hát đã được xóa khỏi hàng đợi.", + "forward": "Tua tới trình phát đến **{0}**", + "rewind": "Tua lùi trình phát đến **{0}**", + "replay": "Phát lại bài hát hiện tại.", + "swapped": "`{0}` và `{1}` đã được hoán đổi", + "moved": "Đã di chuyển `{0}` đến `{1}`", + "autoplay": "Chế độ tự động phát bây giờ là **{0}**", + "notdj": "Bạn không phải là DJ. DJ hiện tại là {0}.", + "djToMe": "Bạn không thể chuyển vai trò DJ cho chính mình hoặc một bot.", + "djNotInChannel": "`{0}` không ở trong kênh voice.", + "djswap": "Bạn đã chuyển vai trò DJ cho `{0}`.", + "voicelinkQueueFull": "Xin lỗi, bạn đã đạt tối đa `{0}` bài hát trong hàng đợi!", + "voicelinkOutofList": "Vui lòng cung cấp chỉ số bài hát hợp lệ!", + "voicelinkDuplicateTrack": "Xin lỗi, bài hát này đã có trong hàng đợi.", + "decodeError": "Đã xảy ra lỗi khi giải mã tệp!", + "invalidStartTime": "Thời gian bắt đầu không hợp lệ, phải nằm giữa `00:00` và `{0}`", + "invalidEndTime": "Thời gian kết thúc không hợp lệ, phải nằm giữa `00:00` và `{0}`", + "invalidTimeOrder": "Thời gian kết thúc không thể nhỏ hơn hoặc bằng thời gian bắt đầu", + "setStageAnnounceTemplate": "Hoàn thành! Từ bây giờ, trạng thái voice như cái bạn đang ở sẽ được đặt tên theo mẫu của bạn. Bạn sẽ thấy nó cập nhật trong vài giây.", + "createSongRequestChannel": "Một kênh yêu cầu bài hát ({0}) đã được tạo! Bạn có thể bắt đầu yêu cầu bất kỳ bài hát nào bằng tên hoặc URL trong kênh đó, mà không cần sử dụng tiền tố bot." +} \ No newline at end of file From e7aa431ae297221d1c01e504f08ed02260f38db6 Mon Sep 17 00:00:00 2001 From: Choco Date: Mon, 11 Aug 2025 17:44:46 +0800 Subject: [PATCH 7/7] Handle Playlist type in track search results Added a check to handle cases where the returned tracks are a Playlist object, ensuring the correct list of tracks is used for app command choices. --- cogs/basic.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cogs/basic.py b/cogs/basic.py index ce6242c..0a10f96 100644 --- a/cogs/basic.py +++ b/cogs/basic.py @@ -93,8 +93,15 @@ class Basic(commands.Cog): node = voicelink.NodePool.get_node() if not node: return [] + tracks: list[voicelink.Track] = await node.get_tracks(current, requester=interaction.user) - return [app_commands.Choice(name=truncate_string(f"🎵 {track.author} - {track.title}", 100), value=truncate_string(f"{track.author} - {track.title}", 100)) for track in tracks] if tracks else [] + if not tracks: + return [] + + if isinstance(tracks, voicelink.Playlist): + tracks = tracks.tracks + + return [app_commands.Choice(name=truncate_string(f"🎵 {track.author} - {track.title}", 100), value=truncate_string(f"{track.author} - {track.title}", 100)) for track in tracks] history = {track["identifier"]: track for track_id in reversed(await get_user(interaction.user.id, "history")) if (track := voicelink.decode(track_id))["uri"]} return [app_commands.Choice(name=truncate_string(f"🕒 {track['author']} - {track['title']}", 100), value=track['uri']) for track in history.values() if len(track['uri']) <= 100][:25]