Apollo Initial Files

This commit is contained in:
2024-10-26 20:33:18 +08:00
commit 2d302551f9
82 changed files with 10643 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
.vscode
.github
node_modules
npm-debug.log
.env
.git
.gitignore
.node-version
.prettierrc
.replit
config.json
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Procfile
Dockerfile
.dockerignore
+25
View File
@@ -0,0 +1,25 @@
---
name: "\U0001F41B Bug Report"
about: Report a suspected bug or problem
title: '🐛 '
labels: 'bug: unconfirmed'
assignees: ''
---
**Describe the bug**
A description of what the bug is.
**How To Reproduce**
Steps to reproduce the behavior:
1.
2.
**Expected behavior**
A description of what you expected to happen.
**Environment (add if possible)**
* Node.js version:
**Additional information & screenshots**
Add any other context or screenshots about the problem here.
@@ -0,0 +1,20 @@
---
name: "\U0001F680 Feature Request"
about: Suggest an idea for this project
title: '🚀 '
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A description of what you want to happen.
**Describe alternatives you've considered**
A description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+7
View File
@@ -0,0 +1,7 @@
contact_links:
- name: ❔ Questions / Help
url: https://github.com/eritislami/evobot/discussions
about: Please use GitHub Discussions for help and questions, do not start an issue.
- name: 📃 Discord.js Guide
url: https://discordjs.guide/
about: The official guide for discord.js
+30
View File
@@ -0,0 +1,30 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: soundcloud-downloader
versions:
- ">= 1.a, < 2"
- dependency-name: discord.js
versions:
- 12.5.2
- 12.5.3
- dependency-name: ffmpeg-static
versions:
- 4.2.8
- 4.3.0
- dependency-name: ytdl-core-discord
versions:
- 1.3.0
- dependency-name: "@discordjs/opus"
versions:
- 0.4.0
- 0.5.0
- dependency-name: ytdl-core
versions:
- 4.5.0
+14
View File
@@ -0,0 +1,14 @@
only: issues
daysUntilStale: 30
daysUntilClose: 7
exemptLabels:
- "suspected bug"
- "in progress"
- "enhancement"
- "dependencies"
staleLabel: stale
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
closeComment: false
+60
View File
@@ -0,0 +1,60 @@
name: Docker Hub
on:
release:
types: [published]
env:
# Use docker.io for Docker Hub if empty
REGISTRY: docker.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v2
# QEMU for emulation
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
# Docker Buildx for creating multi arch docker images
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
# Login against a Docker registry when not a PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
+26
View File
@@ -0,0 +1,26 @@
name: Node.js CI
on:
push:
branches: [master]
paths-ignore:
- README.md
- .github/**
- locales/**
- sounds/**
- package.json
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js 16.11.0
uses: actions/setup-node@v3
with:
node-version: "16.11.0"
cache: "npm"
- run: npm ci
- run: npm run build --if-present
+66
View File
@@ -0,0 +1,66 @@
config.json
.env
/.idea
/.vscode
/sounds/**
!/sounds/putmusichere.mp3
/dist
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# Temp ignore
config.json
+7
View File
@@ -0,0 +1,7 @@
{
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "none",
"endOfLine": "lf"
}
+2
View File
@@ -0,0 +1,2 @@
language = "nodejs"
run = "npm run prod"
+32
View File
@@ -0,0 +1,32 @@
ARG NODE_VERSION=18.18.2-slim
FROM node:${NODE_VERSION} as base
ENV USER=evobot
RUN apt-get update && \
apt-get install -y --no-install-recommends python3 build-essential && \
apt-get purge -y --auto-remove && \
rm -rf /var/lib/apt/lists/*
RUN groupadd -r ${USER} && \
useradd --create-home --home /home/evobot -r -g ${USER} ${USER}
USER ${USER}
WORKDIR /home/evobot
FROM base as build
COPY --chown=${USER}:${USER} . .
RUN npm ci
RUN npm run build
RUN rm -rf node_modules && \
npm ci --omit=dev
FROM node:${NODE_VERSION} as prod
COPY --chown=${USER}:${USER} package*.json ./
COPY --from=build --chown=${USER}:${USER} /home/evobot/node_modules ./node_modules
COPY --from=build --chown=${USER}:${USER} /home/evobot/dist ./dist
CMD [ "node", "./dist/index.js" ]
+137
View File
@@ -0,0 +1,137 @@
![Node build](https://github.com/eritislami/evobot/actions/workflows/node.yml/badge.svg)
![Docker build](https://github.com/eritislami/evobot/actions/workflows/docker.yml/badge.svg)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
![logo](https://repository-images.githubusercontent.com/186841818/8aa95700-7730-11e9-84be-e80f28520325)
# 🤖 EvoBot (Discord Music Bot)
> EvoBot is a Discord Music Bot built with TypeScript, discord.js & uses Command Handler from [discordjs.guide](https://discordjs.guide)
## Requirements
1. Discord Bot Token **[Guide](https://discordjs.guide/preparations/setting-up-a-bot-application.html#creating-your-bot)**
1.1. Enable 'Message Content Intent' in Discord Developer Portal
2. Node.js 16.11.0 or newer
## 🚀 Getting Started
```sh
git clone https://github.com/eritislami/evobot.git
cd evobot
npm install
```
After installation finishes follow configuration instructions then run `npm run start` to start the bot.
## ⚙️ Configuration
Copy or Rename `config.json.example` to `config.json` and fill out the values:
⚠️ **Note: Never commit or share your token or api keys publicly** ⚠️
```json
{
"TOKEN": "",
"MAX_PLAYLIST_SIZE": 10,
"PRUNING": false,
"LOCALE": "en",
"DEFAULT_VOLUME": 100,
"STAY_TIME": 30
}
```
## 🐬 Docker Configuration
For those who would prefer to use our [Docker container](https://hub.docker.com/repository/docker/eritislami/evobot), you may provide values from `config.json` as environment variables.
```shell
docker run -e "TOKEN=<discord-token>" eritislami/evobot
```
## 📝 Features & Commands
- 🎶 Play music from YouTube via url
`/play https://www.youtube.com/watch?v=GLvohMXgcBo`
- 🔎 Play music from YouTube via search query
`/play under the bridge red hot chili peppers`
- 🔎 Search and select music to play
`/search Pearl Jam`
- 📃 Play youtube playlists via url
`/playlist https://www.youtube.com/watch?v=YlUKcNNmywk&list=PL5RNCwK3GIO13SR_o57bGJCEmqFAwq82c`
- 🔎 Play youtube playlists via search query
`/playlist linkin park meteora`
- Now Playing (/nowplaying)
- Queue system (/queue)
- Loop / Repeat (/loop)
- Shuffle (/shuffle)
- Volume control (/volume)
- Lyrics (/lyrics)
- Pause (/pause)
- Resume (/resume)
- Skip (/skip)
- Skip to song # in queue (/skipto)
- Move a song in the queue (/move)
- Remove song # from queue (/remove)
- Show ping to Discord API (/ping)
- Show bot uptime (/uptime)
- Toggle pruning of bot messages (/pruning)
- Help (/help)
- Command Handler from [discordjs.guide](https://discordjs.guide/)
- Media Controls via Buttons
![buttons](https://i.imgur.com/67TGY0c.png)
## 🌎 Locales
Currently available locales are:
- English (en)
- Arabic (ar)
- Brazilian Portuguese (pt_br)
- Bulgarian (bg)
- Romanian (ro)
- Czech (cs)
- Dutch (nl)
- French (fr)
- German (de)
- Greek (el)
- Indonesian (id)
- Italian (it)
- Japanese (ja)
- Korean (ko)
- Minionese (mi)
- Persian (fa)
- Polish (pl)
- Russian (ru)
- Simplified Chinese (zh_cn)
- Singaporean Mandarin (zh_sg)
- Spanish (es)
- Swedish (sv)
- Traditional Chinese (zh_tw)
- Thai (th)
- Turkish (tr)
- Ukrainian (uk)
- Vietnamese (vi)
- Check [Contributing](#-contributing) if you wish to help add more languages!
- For languages please use [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) two letter format
## 🤝 Contributing
1. [Fork the repository](https://github.com/eritislami/evobot/fork)
2. Clone your fork: `git clone https://github.com/your-username/evobot.git`
3. Create your feature branch: `git checkout -b my-new-feature`
4. Stage changes `git add .`
5. Commit your changes: `cz` OR `npm run commit` do not use `git commit`
6. Push to the branch: `git push origin my-new-feature`
7. Submit a pull request
+7
View File
@@ -0,0 +1,7 @@
{
"name": "EvoBot",
"description": "🤖 Discord Music Bot built with discord.js",
"repository": "https://github.com/eritislami/evobot",
"logo": "https://i.imgur.com/JFxgbWH.png",
"keywords": ["discord", "discordjs", "typescript", "music", "bot"]
}
+27
View File
@@ -0,0 +1,27 @@
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
import { i18n } from "../utils/i18n";
import { bot } from "../index";
export default {
data: new SlashCommandBuilder().setName("help").setDescription(i18n.__("help.description")),
async execute(interaction: CommandInteraction) {
let commands = bot.slashCommandsMap;
let helpEmbed = new EmbedBuilder()
.setTitle(i18n.__mf("help.embedTitle", { botname: interaction.client.user!.username }))
.setDescription(i18n.__("help.embedDescription"))
.setColor("#F8AA2A");
commands.forEach((cmd) => {
helpEmbed.addFields({
name: `**${cmd.data.name}**`,
value: `${cmd.data.description}`,
inline: true
});
});
helpEmbed.setTimestamp();
return interaction.reply({ embeds: [helpEmbed] }).catch(console.error);
}
};
+30
View File
@@ -0,0 +1,30 @@
import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
ChatInputCommandInteraction,
EmbedBuilder,
SlashCommandBuilder
} from "discord.js";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder().setName("invite").setDescription(i18n.__("invite.description")),
execute(interaction: ChatInputCommandInteraction) {
const inviteEmbed = new EmbedBuilder().setTitle(i18n.__mf("Invite me to your server!"));
// return interaction with embed and button to invite the bot
const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setLabel(i18n.__mf("Invite"))
.setStyle(ButtonStyle.Link)
.setURL(
`https://discord.com/api/oauth2/authorize?client_id=${
interaction.client.user!.id
}&permissions=8&scope=bot%20applications.commands`
)
);
return interaction.reply({ embeds: [inviteEmbed], components: [actionRow] }).catch(console.error);
}
};
+25
View File
@@ -0,0 +1,25 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
import { safeReply } from "../utils/safeReply";
export default {
data: new SlashCommandBuilder().setName("loop").setDescription(i18n.__("loop.description")),
execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
if (!queue)
return interaction.reply({ content: i18n.__("loop.errorNotQueue"), ephemeral: true }).catch(console.error);
if (!guildMemer || !canModifyQueue(guildMemer)) return i18n.__("common.errorNotChannel");
queue.loop = !queue.loop;
const content = i18n.__mf("loop.result", { loop: queue.loop ? i18n.__("common.on") : i18n.__("common.off") });
safeReply(interaction, content);
}
};
+34
View File
@@ -0,0 +1,34 @@
import { ChatInputCommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
import { i18n } from "../utils/i18n";
// @ts-ignore
import lyricsFinder from "lyrics-finder";
import { bot } from "../index";
export default {
data: new SlashCommandBuilder().setName("lyrics").setDescription(i18n.__("lyrics.description")),
async execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
if (!queue || !queue.songs.length) return interaction.reply(i18n.__("lyrics.errorNotQueue")).catch(console.error);
await interaction.reply("⏳ Loading...").catch(console.error);
let lyrics = null;
const title = queue.songs[0].title;
try {
lyrics = await lyricsFinder(queue.songs[0].title, "");
if (!lyrics) lyrics = i18n.__mf("lyrics.lyricsNotFound", { title: title });
} catch (error) {
lyrics = i18n.__mf("lyrics.lyricsNotFound", { title: title });
}
let lyricsEmbed = new EmbedBuilder()
.setTitle(i18n.__mf("lyrics.embedTitle", { title: title }))
.setDescription(lyrics.length >= 4096 ? `${lyrics.substr(0, 4093)}...` : lyrics)
.setColor("#F8AA2A")
.setTimestamp();
return interaction.editReply({ content: "", embeds: [lyricsEmbed] }).catch(console.error);
}
};
+46
View File
@@ -0,0 +1,46 @@
import move from "array-move";
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
export default {
data: new SlashCommandBuilder()
.setName("move")
.setDescription(i18n.__("move.description"))
.addIntegerOption((option) =>
option.setName("movefrom").setDescription(i18n.__("move.args.movefrom")).setRequired(true)
)
.addIntegerOption((option) =>
option.setName("moveto").setDescription(i18n.__("move.args.moveto")).setRequired(true)
),
execute(interaction: ChatInputCommandInteraction) {
const movefromArg = interaction.options.getInteger("movefrom");
const movetoArg = interaction.options.getInteger("moveto");
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
const queue = bot.queues.get(interaction.guild!.id);
if (!queue) return interaction.reply(i18n.__("move.errorNotQueue")).catch(console.error);
if (!canModifyQueue(guildMemer!)) return;
if (!movefromArg || !movetoArg)
return interaction.reply({ content: i18n.__mf("move.usagesReply", { prefix: bot.prefix }), ephemeral: true });
if (isNaN(movefromArg) || movefromArg <= 1)
return interaction.reply({ content: i18n.__mf("move.usagesReply", { prefix: bot.prefix }), ephemeral: true });
let song = queue.songs[movefromArg - 1];
queue.songs = move(queue.songs, movefromArg - 1, movetoArg == 1 ? 1 : movetoArg - 1);
interaction.reply({
content: i18n.__mf("move.result", {
author: interaction.user.id,
title: song.title,
index: movetoArg == 1 ? 1 : movetoArg
})
});
}
};
+45
View File
@@ -0,0 +1,45 @@
import { ChatInputCommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
import { splitBar } from "string-progressbar";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder().setName("nowplaying").setDescription(i18n.__("nowplaying.description")),
cooldown: 10,
execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
if (!queue || !queue.songs.length)
return interaction.reply({ content: i18n.__("nowplaying.errorNotQueue"), ephemeral: true }).catch(console.error);
const song = queue.songs[0];
const seek = queue.resource.playbackDuration / 1000;
const left = song.duration - seek;
let nowPlaying = new EmbedBuilder()
.setTitle(i18n.__("nowplaying.embedTitle"))
.setDescription(`${song.title}\n${song.url}`)
.setColor("#F8AA2A");
if (song.duration > 0) {
nowPlaying.addFields({
name: "\u200b",
value:
new Date(seek * 1000).toISOString().substr(11, 8) +
"[" +
splitBar(song.duration == 0 ? seek : song.duration, seek, 20)[0] +
"]" +
(song.duration == 0 ? " ◉ LIVE" : new Date(song.duration * 1000).toISOString().substr(11, 8)),
inline: false
});
nowPlaying.setFooter({
text: i18n.__mf("nowplaying.timeRemaining", {
time: new Date(left * 1000).toISOString().substr(11, 8)
})
});
}
return interaction.reply({ embeds: [nowPlaying] });
}
};
+25
View File
@@ -0,0 +1,25 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
import { safeReply } from "../utils/safeReply";
export default {
data: new SlashCommandBuilder().setName("pause").setDescription(i18n.__("pause.description")),
execute(interaction: ChatInputCommandInteraction) {
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
const queue = bot.queues.get(interaction.guild!.id);
if (!queue) return interaction.reply({ content: i18n.__("pause.errorNotQueue") }).catch(console.error);
if (!canModifyQueue(guildMemer!)) return i18n.__("common.errorNotChannel");
if (queue.player.pause()) {
const content = i18n.__mf("pause.result", { author: interaction.user.id });
safeReply(interaction, content);
return true;
}
}
};
+12
View File
@@ -0,0 +1,12 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder().setName("ping").setDescription(i18n.__("ping.description")),
cooldown: 10,
execute(interaction: ChatInputCommandInteraction) {
interaction
.reply({ content: i18n.__mf("ping.result", { ping: Math.round(interaction.client.ws.ping) }), ephemeral: true })
.catch(console.error);
}
};
+98
View File
@@ -0,0 +1,98 @@
import { DiscordGatewayAdapterCreator, joinVoiceChannel } from "@discordjs/voice";
import { ChatInputCommandInteraction, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js";
import { bot } from "../index";
import { MusicQueue } from "../structs/MusicQueue";
import { Song } from "../structs/Song";
import { i18n } from "../utils/i18n";
import { playlistPattern } from "../utils/patterns";
export default {
data: new SlashCommandBuilder()
.setName("play")
.setDescription(i18n.__("play.description"))
.addStringOption((option) => option.setName("song").setDescription("The song you want to play").setRequired(true)),
cooldown: 3,
permissions: [PermissionsBitField.Flags.Connect, PermissionsBitField.Flags.Speak],
async execute(interaction: ChatInputCommandInteraction, input: string) {
let argSongName = interaction.options.getString("song");
if (!argSongName) argSongName = input;
const guildMember = interaction.guild!.members.cache.get(interaction.user.id);
const { channel } = guildMember!.voice;
if (!channel)
return interaction.reply({ content: i18n.__("play.errorNotChannel"), ephemeral: true }).catch(console.error);
const queue = bot.queues.get(interaction.guild!.id);
if (queue && channel.id !== queue.connection.joinConfig.channelId)
return interaction
.reply({
content: i18n.__mf("play.errorNotInSameChannel", { user: bot.client.user!.username }),
ephemeral: true
})
.catch(console.error);
if (!argSongName)
return interaction
.reply({ content: i18n.__mf("play.usageReply", { prefix: bot.prefix }), ephemeral: true })
.catch(console.error);
const url = argSongName;
if (interaction.replied) await interaction.editReply("⏳ Loading...").catch(console.error);
else await interaction.reply("⏳ Loading...");
// Start the playlist if playlist url was provided
if (playlistPattern.test(url)) {
await interaction.editReply("🔗 Link is playlist").catch(console.error);
return bot.slashCommandsMap.get("playlist")!.execute(interaction, "song");
}
let song;
try {
song = await Song.from(url, url);
} catch (error: any) {
console.error(error);
if (error.name == "NoResults")
return interaction
.reply({ content: i18n.__mf("play.errorNoResults", { url: `<${url}>` }), ephemeral: true })
.catch(console.error);
if (error.name == "InvalidURL")
return interaction
.reply({ content: i18n.__mf("play.errorInvalidURL", { url: `<${url}>` }), ephemeral: true })
.catch(console.error);
if (interaction.replied)
return await interaction.editReply({ content: i18n.__("common.errorCommand") }).catch(console.error);
else return interaction.reply({ content: i18n.__("common.errorCommand"), ephemeral: true }).catch(console.error);
}
if (queue) {
queue.enqueue(song);
return (interaction.channel as TextChannel)
.send({ content: i18n.__mf("play.queueAdded", { title: song.title, author: interaction.user.id }) })
.catch(console.error);
}
const newQueue = new MusicQueue({
interaction,
textChannel: interaction.channel! as TextChannel,
connection: joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator as DiscordGatewayAdapterCreator
})
});
bot.queues.set(interaction.guild!.id, newQueue);
newQueue.enqueue(song);
interaction.deleteReply().catch(console.error);
}
};
+102
View File
@@ -0,0 +1,102 @@
import { DiscordGatewayAdapterCreator, joinVoiceChannel } from "@discordjs/voice";
import {
ChatInputCommandInteraction,
EmbedBuilder,
PermissionsBitField,
SlashCommandBuilder,
TextChannel
} from "discord.js";
import { bot } from "../index";
import { MusicQueue } from "../structs/MusicQueue";
import { Playlist } from "../structs/Playlist";
import { Song } from "../structs/Song";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder()
.setName("playlist")
.setDescription(i18n.__("playlist.description"))
.addStringOption((option) => option.setName("playlist").setDescription("Playlist name or link").setRequired(true)),
cooldown: 5,
permissions: [PermissionsBitField.Flags.Connect, PermissionsBitField.Flags.Speak],
async execute(interaction: ChatInputCommandInteraction, queryOptionName = "playlist") {
let argSongName = interaction.options.getString(queryOptionName);
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
const { channel } = guildMemer!.voice;
const queue = bot.queues.get(interaction.guild!.id);
if (!channel)
return interaction.reply({ content: i18n.__("playlist.errorNotChannel"), ephemeral: true }).catch(console.error);
if (queue && channel.id !== queue.connection.joinConfig.channelId)
if (interaction.replied)
return interaction
.editReply({ content: i18n.__mf("play.errorNotInSameChannel", { user: interaction.client.user!.username }) })
.catch(console.error);
else
return interaction
.reply({
content: i18n.__mf("play.errorNotInSameChannel", { user: interaction.client.user!.username }),
ephemeral: true
})
.catch(console.error);
let playlist;
try {
playlist = await Playlist.from(argSongName!.split(" ")[0], argSongName!);
} catch (error) {
console.error(error);
if (interaction.replied)
return interaction.editReply({ content: i18n.__("playlist.errorNotFoundPlaylist") }).catch(console.error);
else
return interaction
.reply({ content: i18n.__("playlist.errorNotFoundPlaylist"), ephemeral: true })
.catch(console.error);
}
if (queue) {
queue.songs.push(...playlist.videos);
} else {
const newQueue = new MusicQueue({
interaction,
textChannel: interaction.channel! as TextChannel,
connection: joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator as DiscordGatewayAdapterCreator
})
});
bot.queues.set(interaction.guild!.id, newQueue);
newQueue.enqueue(...playlist.videos);
}
let playlistEmbed = new EmbedBuilder()
.setTitle(`${playlist.data.title}`)
.setDescription(
playlist.videos
.map((song: Song, index: number) => `${index + 1}. ${song.title}`)
.join("\n")
.slice(0, 4095)
)
.setURL(playlist.data.url!)
.setColor("#F8AA2A")
.setTimestamp();
if (interaction.replied)
return interaction.editReply({
content: i18n.__mf("playlist.startedPlaylist", { author: interaction.user.id }),
embeds: [playlistEmbed]
});
interaction
.reply({
content: i18n.__mf("playlist.startedPlaylist", { author: interaction.user.id }),
embeds: [playlistEmbed]
})
.catch(console.error);
}
};
+125
View File
@@ -0,0 +1,125 @@
import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
ChatInputCommandInteraction,
CommandInteraction,
EmbedBuilder,
Interaction,
SlashCommandBuilder
} from "discord.js";
import { bot } from "../index";
import { Song } from "../structs/Song";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder().setName("queue").setDescription(i18n.__("queue.description")),
cooldown: 5,
async execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
if (!queue || !queue.songs.length) return interaction.reply({ content: i18n.__("queue.errorNotQueue") });
let currentPage = 0;
const embeds = generateQueueEmbed(interaction, queue.songs);
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("previous").setLabel("⬅️").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("stop").setLabel("⏹").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("next").setLabel("➡️").setStyle(ButtonStyle.Secondary)
);
await interaction.reply("⏳ Loading queue...");
if (interaction.replied)
await interaction.editReply({
content: `**${i18n.__mf("queue.currentPage")} ${currentPage + 1}/${embeds.length}**`,
embeds: [embeds[currentPage]],
components: [row]
});
const queueEmbed = await interaction.fetchReply();
const filter = (buttonInteraction: Interaction) =>
buttonInteraction.isButton() && buttonInteraction.user.id === interaction.user.id;
const collector = queueEmbed.createMessageComponentCollector({ filter, time: 60000 });
const buttonHandlers = {
next: async () => {
if (currentPage >= embeds.length - 1) return;
currentPage++;
await interaction.editReply({
content: `**${i18n.__mf("queue.currentPage", {
page: currentPage + 1,
length: embeds.length
})}**`,
embeds: [embeds[currentPage]],
components: [row]
});
},
previous: async () => {
if (currentPage === 0) return;
currentPage--;
await interaction.editReply({
content: `**${i18n.__mf("queue.currentPage", {
page: currentPage + 1,
length: embeds.length
})}**`,
embeds: [embeds[currentPage]],
components: [row]
});
},
stop: async () => {
await interaction.editReply({
components: []
});
collector.stop();
}
};
collector.on("collect", async (buttonInteraction) => {
buttonInteraction.deferUpdate();
const handler = buttonHandlers[buttonInteraction.customId as keyof typeof buttonHandlers];
if (handler) {
await handler();
}
});
collector.on("end", () => {
queueEmbed
.edit({
components: []
})
.catch(console.error);
});
}
};
function generateQueueEmbed(interaction: CommandInteraction, songs: Song[]) {
let embeds = [];
let k = 10;
for (let i = 0; i < songs.length; i += 10) {
const current = songs.slice(i, k);
let j = i;
k += 10;
const info = current.map((track) => `${++j} - [${track.title}](${track.url})`).join("\n");
const embed = new EmbedBuilder()
.setTitle(i18n.__("queue.embedTitle"))
.setThumbnail(interaction.guild?.iconURL()!)
.setColor("#F8AA2A")
.setDescription(i18n.__mf("queue.embedCurrentSong", { title: songs[0].title, url: songs[0].url, info: info }))
.setTimestamp();
embeds.push(embed);
}
return embeds;
}
+57
View File
@@ -0,0 +1,57 @@
import { SlashCommandBuilder, CommandInteraction, ChatInputCommandInteraction } from "discord.js";
import { bot } from "../index";
import { Song } from "../structs/Song";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
const pattern = /^[0-9]{1,2}(\s*,\s*[0-9]{1,2})*$/;
export default {
data: new SlashCommandBuilder()
.setName("remove")
.setDescription(i18n.__("remove.description"))
.addStringOption((option) =>
option.setName("slot").setDescription(i18n.__("remove.description")).setRequired(true)
),
execute(interaction: ChatInputCommandInteraction) {
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
const removeArgs = interaction.options.getString("slot");
const queue = bot.queues.get(interaction.guild!.id);
if (!queue)
return interaction.reply({ content: i18n.__("remove.errorNotQueue"), ephemeral: true }).catch(console.error);
if (!canModifyQueue(guildMemer!)) return i18n.__("common.errorNotChannel");
if (!removeArgs)
return interaction.reply({ content: i18n.__mf("remove.usageReply", { prefix: bot.prefix }), ephemeral: true });
const songs = removeArgs.split(",").map((arg) => parseInt(arg));
let removed: Song[] = [];
if (pattern.test(removeArgs)) {
queue.songs = queue.songs.filter((item, index) => {
if (songs.find((songIndex) => songIndex - 1 === index)) removed.push(item);
else return true;
});
interaction.reply(
i18n.__mf("remove.result", {
title: removed.map((song) => song.title).join("\n"),
author: interaction.user.id
})
);
} else if (!isNaN(+removeArgs) && +removeArgs >= 1 && +removeArgs <= queue.songs.length) {
return interaction.reply(
i18n.__mf("remove.result", {
title: queue.songs.splice(+removeArgs - 1, 1)[0].title,
author: interaction.user.id
})
);
} else {
return interaction.reply({ content: i18n.__mf("remove.usageReply", { prefix: bot.prefix }) });
}
}
};
+32
View File
@@ -0,0 +1,32 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
import { safeReply } from "../utils/safeReply";
export default {
data: new SlashCommandBuilder().setName("resume").setDescription(i18n.__("resume.description")),
execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
if (!queue)
return interaction.reply({ content: i18n.__("resume.errorNotQueue"), ephemeral: true }).catch(console.error);
if (!canModifyQueue(guildMemer!)) return i18n.__("common.errorNotChannel");
if (queue.player.unpause()) {
const content = i18n.__mf("resume.resultNotPlaying", { author: interaction.user.id });
safeReply(interaction, content);
return true;
}
const content = i18n.__("resume.errorPlaying");
safeReply(interaction, content);
return false;
}
};
+86
View File
@@ -0,0 +1,86 @@
import {
ActionRowBuilder,
ChatInputCommandInteraction,
SlashCommandBuilder,
StringSelectMenuBuilder,
StringSelectMenuInteraction
} from "discord.js";
import youtube, { Video } from "youtube-sr";
import { bot } from "..";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder()
.setName("search")
.setDescription(i18n.__("search.description"))
.addStringOption((option) =>
option.setName("query").setDescription(i18n.__("search.optionQuery")).setRequired(true)
),
async execute(interaction: ChatInputCommandInteraction) {
const query = interaction.options.getString("query", true);
const member = interaction.guild!.members.cache.get(interaction.user.id);
if (!member?.voice.channel)
return interaction.reply({ content: i18n.__("search.errorNotChannel"), ephemeral: true }).catch(console.error);
const search = query;
await interaction.reply("⏳ Loading...").catch(console.error);
let results: Video[] = [];
try {
results = await youtube.search(search, { limit: 10, type: "video" });
} catch (error) {
console.error(error);
interaction.editReply({ content: i18n.__("common.errorCommand") }).catch(console.error);
return;
}
if (!results || !results[0]) {
interaction.editReply({ content: i18n.__("search.noResults") });
return;
}
const options = results!.map((video) => {
return {
label: video.title ?? "",
value: video.url
};
});
const row = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
new StringSelectMenuBuilder()
.setCustomId("search-select")
.setPlaceholder("Nothing selected")
.setMinValues(1)
.setMaxValues(10)
.addOptions(options)
);
const followUp = await interaction.followUp({
content: "Choose songs to play",
components: [row]
});
followUp
.awaitMessageComponent({
time: 30000
})
.then((selectInteraction) => {
if (!(selectInteraction instanceof StringSelectMenuInteraction)) return;
selectInteraction.update({ content: "⏳ Loading the selected songs...", components: [] });
bot.slashCommandsMap
.get("play")!
.execute(interaction, selectInteraction.values[0])
.then(() => {
selectInteraction.values.slice(1).forEach((url) => {
bot.slashCommandsMap.get("play")!.execute(interaction, url);
});
});
})
.catch(console.error);
}
};
+31
View File
@@ -0,0 +1,31 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
import { safeReply } from "../utils/safeReply";
export default {
data: new SlashCommandBuilder().setName("shuffle").setDescription(i18n.__("shuffle.description")),
execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
if (!queue)
return interaction.reply({ content: i18n.__("shuffle.errorNotQueue"), ephemeral: true }).catch(console.error);
if (!guildMemer || !canModifyQueue(guildMemer)) return i18n.__("common.errorNotChannel");
let songs = queue.songs;
for (let i = songs.length - 1; i > 1; i--) {
let j = 1 + Math.floor(Math.random() * i);
[songs[i], songs[j]] = [songs[j], songs[i]];
}
queue.songs = songs;
const content = i18n.__mf("shuffle.result", { author: interaction.user.id });
safeReply(interaction, content);
}
};
+21
View File
@@ -0,0 +1,21 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
import { safeReply } from "../utils/safeReply";
export default {
data: new SlashCommandBuilder().setName("skip").setDescription(i18n.__("skip.description")),
execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
if (!queue) return interaction.reply(i18n.__("skip.errorNotQueue")).catch(console.error);
if (!canModifyQueue(guildMemer!)) return i18n.__("common.errorNotChannel");
queue.player.stop(true);
safeReply(interaction, i18n.__mf("skip.result", { author: interaction.user.id }));
}
};
+51
View File
@@ -0,0 +1,51 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
export default {
data: new SlashCommandBuilder()
.setName("skipto")
.setDescription(i18n.__("skipto.description"))
.addIntegerOption((option) =>
option.setName("number").setDescription(i18n.__("skipto.args.number")).setRequired(true)
),
execute(interaction: ChatInputCommandInteraction) {
const playlistSlotArg = interaction.options.getInteger("number");
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
if (!playlistSlotArg || isNaN(playlistSlotArg))
return interaction
.reply({
content: i18n.__mf("skipto.usageReply", { prefix: bot.prefix, name: module.exports.name }),
ephemeral: true
})
.catch(console.error);
const queue = bot.queues.get(interaction.guild!.id);
if (!queue)
return interaction.reply({ content: i18n.__("skipto.errorNotQueue"), ephemeral: true }).catch(console.error);
if (!canModifyQueue(guildMemer!)) return i18n.__("common.errorNotChannel");
if (playlistSlotArg > queue.songs.length)
return interaction
.reply({ content: i18n.__mf("skipto.errorNotValid", { length: queue.songs.length }), ephemeral: true })
.catch(console.error);
if (queue.loop) {
for (let i = 0; i < playlistSlotArg - 2; i++) {
queue.songs.push(queue.songs.shift()!);
}
} else {
queue.songs = queue.songs.slice(playlistSlotArg - 2);
}
queue.player.stop();
interaction
.reply({ content: i18n.__mf("skipto.result", { author: interaction.user.id, arg: playlistSlotArg - 1 }) })
.catch(console.error);
}
};
+20
View File
@@ -0,0 +1,20 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
import { safeReply } from "../utils/safeReply";
export default {
data: new SlashCommandBuilder().setName("stop").setDescription(i18n.__("stop.description")),
execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
if (!queue) return interaction.reply(i18n.__("stop.errorNotQueue")).catch(console.error);
if (!guildMemer || !canModifyQueue(guildMemer)) return i18n.__("common.errorNotChannel");
queue.stop();
safeReply(interaction, i18n.__mf("stop.result", { author: interaction.user.id }));
}
};
+21
View File
@@ -0,0 +1,21 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
export default {
data: new SlashCommandBuilder().setName("uptime").setDescription(i18n.__("uptime.description")),
execute(interaction: ChatInputCommandInteraction) {
let seconds = Math.floor(bot.client.uptime! / 1000);
let minutes = Math.floor(seconds / 60);
let hours = Math.floor(minutes / 60);
let days = Math.floor(hours / 24);
seconds %= 60;
minutes %= 60;
hours %= 24;
return interaction
.reply({ content: i18n.__mf("uptime.result", { days: days, hours: hours, minutes: minutes, seconds: seconds }) })
.catch(console.error);
}
};
+38
View File
@@ -0,0 +1,38 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { bot } from "../index";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
export default {
data: new SlashCommandBuilder()
.setName("volume")
.setDescription(i18n.__("volume.description"))
.addIntegerOption((option) => option.setName("volume").setDescription(i18n.__("volume.description"))),
execute(interaction: ChatInputCommandInteraction) {
const queue = bot.queues.get(interaction.guild!.id);
const guildMemer = interaction.guild!.members.cache.get(interaction.user.id);
const volumeArg = interaction.options.getInteger("volume");
if (!queue)
return interaction.reply({ content: i18n.__("volume.errorNotQueue"), ephemeral: true }).catch(console.error);
if (!canModifyQueue(guildMemer!))
return interaction.reply({ content: i18n.__("volume.errorNotChannel"), ephemeral: true }).catch(console.error);
if (!volumeArg || volumeArg === queue.volume)
return interaction
.reply({ content: i18n.__mf("volume.currentVolume", { volume: queue.volume }) })
.catch(console.error);
if (isNaN(volumeArg))
return interaction.reply({ content: i18n.__("volume.errorNotNumber"), ephemeral: true }).catch(console.error);
if (Number(volumeArg) > 100 || Number(volumeArg) < 0)
return interaction.reply({ content: i18n.__("volume.errorNotValid"), ephemeral: true }).catch(console.error);
queue.volume = volumeArg;
queue.resource.volume?.setVolumeLogarithmic(volumeArg / 100);
return interaction.reply({ content: i18n.__mf("volume.result", { arg: volumeArg }) }).catch(console.error);
}
};
+8
View File
@@ -0,0 +1,8 @@
{
"TOKEN": "",
"MAX_PLAYLIST_SIZE": 10,
"PRUNING": false,
"LOCALE": "en",
"STAY_TIME": 30,
"DEFAULT_VOLUME": 100
}
+15
View File
@@ -0,0 +1,15 @@
import { Client, GatewayIntentBits } from "discord.js";
import { Bot } from "./structs/Bot";
export const bot = new Bot(
new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages
]
})
);
+8
View File
@@ -0,0 +1,8 @@
import { SlashCommandBuilder } from "discord.js";
export interface Command {
permissions?: string[];
cooldown?: number;
data: SlashCommandBuilder;
execute(...args: any): any;
}
+8
View File
@@ -0,0 +1,8 @@
export interface Config {
TOKEN: string;
MAX_PLAYLIST_SIZE: number;
PRUNING: boolean;
STAY_TIME: number;
DEFAULT_VOLUME: number;
LOCALE: string;
}
+8
View File
@@ -0,0 +1,8 @@
import { VoiceConnection } from "@discordjs/voice";
import { CommandInteraction, TextChannel } from "discord.js";
export interface QueueOptions {
interaction: CommandInteraction;
textChannel: TextChannel;
connection: VoiceConnection;
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "تشغيل مقطع صوتي",
"usagesReply": "إستعمال: {prefix}clip <اسم>",
"errorQueue": "لا يمكن تشغيل المقطع نظرًا لوجود قائمة اغاني تعمل...",
"errorNotChannel": "تحتاج إلى الانضمام إلى قناة صوتية أولاً!"
},
"clips": {
"description": "قائمة المقاطع"
},
"help": {
"description": "يعرض جميع الاوامر",
"embedTitle": "{botname} مساعدة",
"embedDescription": "قائمة الاوامر"
},
"invite": {
"description": "يرسل رابط دعوة البوت"
},
"loop": {
"description": "تغير وضع التكرار",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا",
"result": "التكرار الان {loop}"
},
"lyrics": {
"description": "احصل على كلمات الأغنية التي يتم تشغيلها حاليًا",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا",
"lyricsNotFound": "{title} لم يتم العثور على كلمات لـ",
"embedTitle": "{title} - كلمات"
},
"move": {
"description": "نقل الأغاني في القائمة",
"errorNotQueue": "لا توجد قائمة حاليًا",
"usagesReply": "{prefix}move استعمال: رقم",
"result": "<@{author}> انتقل **{title}** الي {index} في القائمة 🚚"
},
"nowplaying": {
"description": "يظهر الاغنية التي تكون قيد التشغيل",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا",
"embedTitle": "تعمل الان",
"live": " ◉ مباشر",
"timeRemaining": "الوقت المتبقي {time}"
},
"pause": {
"description": "إيقاف الموسيقى التي قيد التشغيل",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا",
"result": "<@{author}> أوقف الموسيقى مؤقتًا ⏸"
},
"ping": {
"description": "يظهر معدل السرعة",
"result": "`{ping}ms` متوسط السرعة هو 📈"
},
"play": {
"description": "يشغل اغنية من يوتيوب او ساوندكلود",
"errorNotChannel": "تحتاج إلى الانضمام إلى قناة صوتية أولاً!",
"errorNotInSameChannel": "{user} يجب أن تكون في نفس القناة مثل",
"usageReply": "الاستعمال: {prefix}play <رابط يوتيوب | اسم مقطع | رابط سواندكلود>",
"missingPermissionConnect": "لا يمكن الاتصال بقناة صوتية ، أذونات مفقودة",
"missingPermissionSpeak": "لا يمكنني التحدث في هذه القناة الصوتية ، تأكد من أن لدي الأذونات المناسبة!",
"queueAdded": "تمت اضافة **{title}** الي القائمة بواسطة <@{author}> ✅",
"cantJoinChannel": "تعذر الانضمام إلى القناة: {error}",
"queueEnded": "قائمة الاغاني انتهت ❌",
"queueError": "خطأ: {error}",
"startedPlaying": "🎶 {url} **{title}** بدأ تشغيل",
"skipSong": "<@{author}> تخطى الأغنية ⏩",
"pauseSong": "<@{author}> أوقف الموسيقى مؤقتًا ⏸",
"resumeSong": "<@{author}> استأنف الموسيقى ▶",
"unmutedSong": "<@{author}> فك كتم الصوت 🔊",
"mutedSong": "<@{author}> كتم صوت! 🔇",
"decreasedVolume": "<@{author}> 🔉 **{volume}%** خفض الصوت, مستوي الصوت الان هو",
"increasedVolume": "<@{author}> 🔊 **{volume}%** زاد الصوت, مستوي الصوت الان هو",
"loopSong": "<@{author}> التكرار الان {loop}",
"stopSong": "<@{author}> أوقف الموسيقى ⏹",
"leaveChannel": "جارٍ ترك القناة الصوتية...",
"songNotFound": "Audio Not Found",
"songAccessErr": "Video is age restricted, private or unavailable"
},
"playlist": {
"description": "تشغيل قائمة تشغيل من يوتيوب",
"usagesReply": "الاستعمال: {prefix}playlist <رابط قائمة يوتيوب | اسم قائمة>",
"errorNotChannel": "تحتاج إلى الانضمام إلى قناة صوتية أولاً!",
"errorNotInSameChannel": "{user} يجب أن تكون في نفس القناة مثل",
"missingPermissionConnect": "لا يمكن الاتصال بلقناة الصوتية ، أذونات مفقودة",
"missingPermissionSpeak": "لا يمكنني التحدث في هذه القناة الصوتية ، تأكد من أن لدي الأذونات المناسبة!",
"errorNotFoundPlaylist": "قائمة التشغيل غير موجودة :(",
"fetchingPlaylist": "جاري إحضار قائمة التشغيل... ⌛",
"playlistCharLimit": "\nقائمة التشغيل أكبر من عدد الأحرف المسموح به...",
"startedPlaylist": "<@{author}> بدأ قائمة تشغيل",
"cantJoinChannel": "لم استطيع الانضمام الي القناة: {error}"
},
"pruning": {
"description": "تغير وضع حذف الرسائل التلقائي",
"errorWritingFile": "حدث خطأ اثناء الكتابة إلى الملف.",
"result": "الوضع الان {result}"
},
"queue": {
"description": "يظهر قائمة الاغاني",
"missingPermissionMessage": "لا يوجد إذن لإدارة الرسائل أو إضافة ردود الفعل",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا ❌",
"currentPage": "الصفحة الحالية - ",
"embedTitle": "قائمة الاغاني\n",
"embedCurrentSong": "**الاغنية الحالية - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "يحذف اغنية من القائمة",
"errorNotQueue": "لا توجد قائمة حاليًا",
"usageReply": "استعمال: {prefix}remove <رقم>",
"result": "<@{author}> تمت إزالة **{title}** من قائمة الانتظار ❌"
},
"resume": {
"description": "استئناف تشغيل الموسيقى الحالية",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا",
"resultNotPlaying": "<@{author}> استأنف الموسيقى ▶",
"errorPlaying": "القائمة لم يتم إيقافها."
},
"search": {
"description": "ابحث عن مقاطع الفيديو وحددها لتشغيلها",
"usageReply": "استعمال: {prefix}{name} <اسم مقطع>",
"errorAlreadyCollector": "مُجمع الرسائل نشط بالفعل في هذه القناة.",
"errorNotChannel": "تحتاج إلى الانضمام إلى قناة صوتية أولاً!",
"resultEmbedTitle": "**رد برقم الأغنية التي تريد تشغيلها**",
"resultEmbedDesc": "{search} نتائج لـ"
},
"shuffle": {
"description": "خلط القائمة",
"errorNotQueue": "لا توجد قائمة موجودة حاليا",
"result": "<@{author}> تم خلط القائمة 🔀"
},
"skip": {
"description": "تخطي الأغنية التي يتم تشغيلها حاليًا",
"errorNotQueue": "لا يوجد أي شيء يمكنني تخطيه من أجلك.",
"result": "<@{author}> تخطى الأغنية ⏭"
},
"skipto": {
"description": "تخطي إلى الرقم المحدد",
"usageReply": "استعمال: {prefix}{name} <رقم>",
"errorNotQueue": "لا توجد قائمة حاليًا",
"errorNotValid": "قائمة الانتظار تتكون من {length} أغنية فقط!",
"result": "<@{author}> تخطي {arg} اغنية ⏭"
},
"stop": {
"description": "يوقف الموسيقى",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا",
"result": "<@{author}> أوقف الموسيقى ⏹"
},
"uptime": {
"description": "تحقق من مدة وقت التشغيل",
"result": "وقت التشغيل: `{days} يوم,{hours} ساعة, {minutes} دقيقة, {seconds} ثانية`"
},
"volume": {
"description": "تغير مستوي الصوت",
"errorNotQueue": "لا توجد أغنية قيد التشغيل حاليا",
"errorNotChannel": "تحتاج إلى الانضمام إلى قناة صوتية أولاً!",
"currentVolume": "🔊 **{volume}%** مستوي الصوت الحالي هو",
"errorNotNumber": "رجاء اختر رقم لتغير مستوي الصوت",
"errorNotValid": "رجاء استخدم رقم بين الصفر والمئة",
"result": "تم ضبط الصوت على **{arg}%**"
},
"common": {
"on": "**تشغيل**",
"off": "**ايقاف**",
"enabled": "**مفعل**",
"disabled": "**مقفل**",
"errorNotChannel": "تحتاج إلى الانضمام إلى قناة صوتية أولاً!",
"cooldownMessage": "يرجى الانتظار {time} ثانية أخرى قبل إعادة استخدام الأمر `{name}`.",
"errorCommand": "حدث خطأ أثناء تنفيذ هذا الأمر."
}
}
+181
View File
@@ -0,0 +1,181 @@
{
"clip": {
"description": "Възпроизвеждане на звук от клип",
"usagesReply": "Употреба: {prefix}clip <name>",
"errorQueue": "Не може да се възпроизвежда клип, поради активна опашка.",
"errorNotChannel": "Първо трябва да се присъедините към гласов канал!"
},
"clips": {
"description": "Списък на всички клипове"
},
"help": {
"description": "Показва всички команди и описания",
"embedTitle": "{botname} Помощ",
"embedDescription": "Списък на всички команди"
},
"invite": {
"description": "Изпращане на линк за покана на бота"
},
"loop": {
"description": "Превключване за повтаране на музикален цикъл",
"errorNotQueue": "Няма нищо за възпроизвеждане.",
"result": "Цикълът сега е {loop}"
},
"lyrics": {
"description": "Получаване на текст за текущата песен",
"errorNotQueue": "Няма нищо за възпроизвеждане.",
"lyricsNotFound": "Не е намерен текст на песента за {title}.",
"embedTitle": "{title} - Текстове на песни"
},
"move": {
"description": "Преместване на песни в опашката",
"errorNotQueue": "Няма опашка.",
"usagesReply": "Употреба: {prefix}move <Queue Number>",
"result": "<@{author}> 🚚 премести **{title}** на {index} в опашката.",
"args": {
"movefrom": "Слот за преместване от",
"moveto": "Слот за преместване към"
}
},
"nowplaying": {
"description": "Покажи сегашната песен",
"errorNotQueue": "Няма нищо за възпроизвеждане.",
"embedTitle": "Сега се изпълнява",
"live": " ◉ НА ЖИВО",
"timeRemaining": "Оставащото време: {time}"
},
"pause": {
"description": "Пауза на възпроизвежданата в момента музика",
"errorNotQueue": "Няма нищо за възпроизвеждане.",
"result": "<@{author}> ⏸ паузира музиката."
},
"ping": {
"description": "Показва средния пинг на бота",
"result": "📈 Среден пинг към API: {ping} ms"
},
"play": {
"description": "Възпроизвежда аудио от YouTube",
"errorNotChannel": "Първо трябва да се присъедините към гласов канал!",
"errorNotInSameChannel": "Трябва да сте в същия канал като {user}",
"usageReply": "Употреба: {prefix}play <YouTube URL | Video Name>",
"missingPermissionConnect": "Не мога да се свържа с гласов канал, липсват разрешения",
"missingPermissionSpeak": "Не мога да говоря в този гласов канал, уверете се, че имам правилните разрешения!",
"queueAdded": "✅ **{title}** е добавено към опашката от <@{author}>",
"cantJoinChannel": "Не може да се присъедини към канала: {error}",
"queueEnded": "❌ Опашката за музика приключи.",
"queueError": "Грешка: {error}",
"startedPlaying": "🎶 Започна да се възпроизвежда: **{title}** {url}",
"skipSong": "<@{author}> ⏩ прескочи песента",
"pauseSong": "<@{author}> ⏸ паузира музиката.",
"resumeSong": "<@{author}> ▶ възобнови музиката!",
"unmutedSong": "<@{author}> 🔊 включи музиката!",
"mutedSong": "<@{author}> 🔇 заглуши музиката!",
"decreasedVolume": "<@{author}> 🔉 намали силата на звука, сега силата на звука е {volume}%",
"increasedVolume": "<@{author}> 🔊 увеличи силата на звука, силата на звука сега е {volume}%",
"loopSong": "<@{author}> Цикълът сега е {loop}",
"stopSong": "<@{author}> ⏹ спря музиката!",
"leaveChannel": "Напускане на гласов канал...",
"songNotFound": "Аудиото не е намерено",
"songAccessErr": "Видеото е ограничено по възраст, частно или недостъпно",
"errorNoResults": "Не са намерени резултати за {url}",
"errorInvalidURL": "Невалиден URL адрес, моля, опитайте с търсене или youtube url адрес"
},
"playlist": {
"description": "Възпроизвеждане на плейлист от youtube",
"usagesReply": "Употреба: {prefix}playlist <YouTube Playlist URL | Playlist Name>",
"errorNotChannel": "Първо трябва да се присъедините към гласов канал!",
"errorNotInSameChannel": "Трябва да сте в същия канал като {user}",
"missingPermissionConnect": "Не мога да се свържа с гласов канал, липсват разрешения",
"missingPermissionSpeak": "Не мога да говоря в този гласов канал, уверете се, че имам правилните разрешения!",
"errorNotFoundPlaylist": "Плейлист не намерен :(",
"fetchingPlaylist": "⌛ набиране на плейлист...",
"playlistCharLimit": "\nПлейлист по-голям от ограничението на писмени знаци...",
"startedPlaylist": "<@{author}> Стартира списък за възпроизвеждане",
"cantJoinChannel": "Не може да се присъедини към канала: {error}"
},
"pruning": {
"description": "Превключване на изрязването на съобщенията на бота",
"errorWritingFile": "Имаше грешка при записването на файла.",
"result": "Орязването на съобщенията е {result}"
},
"queue": {
"description": "Покажете музикалната опашка и сега изпълняваната музика.",
"missingPermissionMessage": "Липсва разрешение за управление на съобщения или добавяне на реакции",
"errorNotQueue": "❌ **Нищо не се възпроизвежда в този сървър**",
"currentPage": "Текуща Страница - ",
"embedTitle": "Опашка на Песни\n",
"embedCurrentSong": "**Текуща Песен - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Премахване на песен от опашката",
"errorNotQueue": "Няма опашка.",
"usageReply": "Употреба: {prefix}remove <Queue Number>",
"result": "<@{author}> ❌ премахна **{title}** от опашката."
},
"resume": {
"description": "Възобнови възпроизвежданата в момента музика",
"errorNotQueue": "Няма нищо за възпроизвеждане.",
"resultNotPlaying": "<@{author}> ▶ възобнови музиката!",
"errorPlaying": "Опашката не е спряна."
},
"search": {
"description": "Търсене и избиране на видеоклипове за възпроизвеждане",
"usageReply": "Употреба: {prefix}{name} <Video Name>",
"errorAlreadyCollector": "Колектор на съобщения вече е активен в този канал.",
"errorNotChannel": "Първо трябва да се присъедините към гласов канал!",
"resultEmbedTitle": "**Отговорете с номера на песента, която искате да пуснете**",
"resultEmbedDesc": "Резултати за: {search}",
"optionQuery": "Заявка за търсене",
"noResults": "Няма резултати за заявката, моля, опитайте нещо друго"
},
"shuffle": {
"description": "Разбъркване на опашката",
"errorNotQueue": "Няма опашка.",
"result": "<@{author}> 🔀 разбърка опашката"
},
"skip": {
"description": "Пропуснете изпълняваната в момента песен",
"errorNotQueue": "Няма нищо, което да се изпълнява и което да мога да пропусна за вас.",
"result": "<@{author}> ⏭ прескочи песента"
},
"skipto": {
"description": "Преминете към избрания номер на опашката",
"usageReply": "Употреба: {prefix}{name} <Queue Number>",
"errorNotQueue": "Няма опашка.",
"errorNotValid": "Опашката е дълга само {length} песни!",
"result": "<@{author}> ⏭ прескочи {arg} песни",
"args": {
"number": "Номерът на опашката, до която да се прескочи"
}
},
"stop": {
"description": "Спира музиката",
"errorNotQueue": "Няма нищо, което да свири.",
"result": "<@{author}> ⏹ спря музиката!"
},
"uptime": {
"description": "Проверете времето на работа",
"result": "Време на активност: `{days} ден(дни),{hours} часа, {minutes} минути, {seconds} секунди`"
},
"volume": {
"description": "Промяна на силата на звука на текущо възпроизвежданата музика",
"errorNotQueue": "Няма нищо за възпроизвеждане.",
"errorNotChannel": "Първо трябва да се присъедините към гласов канал!",
"currentVolume": "🔊 Текущата сила на звука е: **{volume}%**",
"errorNotNumber": "Моля, използвайте число, за да зададете силата на звука.",
"errorNotValid": "Моля, използвайте число между 0 и 100.",
"result": "Силата на звука зададен на: **{arg}%**"
},
"common": {
"on": "**включено**",
"off": "**изключено**",
"enabled": "**активирано**",
"disabled": "**деактивирано**",
"errorNotChannel": "Първо трябва да се присъедините към гласов канал!",
"cooldownMessage": "моля, изчакайте {time} още секунда(и) преди да използвате отново командата `{name}`.",
"errorCommand": "Имаше грешка при изпълнението на тази команда."
},
"Invite me to your server!": "Покани ме на твоя сървър!",
"Invite": "Покани"
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Přehraje klipový zvuk",
"usagesReply": "Použití: {prefix}clip <název>",
"errorQueue": "Nelze přehrát klip, protože je aktivní fronta.",
"errorNotChannel": "Nejprve se musíš připojit do hlasového kanálu!"
},
"clips": {
"description": "Vypsat všechny klipy"
},
"help": {
"description": "Zobrazit všechny příkazy a popisy",
"embedTitle": "Nápověda bota {botname}",
"embedDescription": "Vypsat všechny příkazy"
},
"invite": {
"description": "Poslat pozvánku bota"
},
"loop": {
"description": "Přepnout opakování hudby",
"errorNotQueue": "Momentálně nic nehraje.",
"result": "Opakování je nyní {loop}"
},
"lyrics": {
"description": "Získat texty pro právě hrající skladbu",
"errorNotQueue": "Momentálně nic nehraje.",
"lyricsNotFound": "Pro {title} nebyly nalezeny žádné texty.",
"embedTitle": "{title} - Text"
},
"move": {
"description": "Přesouvat skladby ve frontě",
"errorNotQueue": "Není tu žádná fronta.",
"usagesReply": "Použití: {prefix}move <číslo ve frontě>",
"result": "<@{author}> 🚚 přesunul **{title}** na {index}. pozici ve frontě."
},
"nowplaying": {
"description": "Zobrazit právě hrající skladbu",
"errorNotQueue": "Momentálně nic nehraje.",
"embedTitle": "Právě hraje",
"live": " ◉ ŽIVĚ",
"timeRemaining": "Zbývající čas: {time}"
},
"pause": {
"description": "Pozastavit právě hrající hudbu",
"errorNotQueue": "Momentálně nic nehraje.",
"result": "<@{author}> ⏸ pozastavil hudbu."
},
"ping": {
"description": "Zobrazit průměrný ping bota",
"result": "📈 Průměrný ping na API: {ping} ms"
},
"play": {
"description": "Přehraje hudbu z YouTube nebo SoundCloudu",
"errorNotChannel": "Nejprve se musíš připojit do hlasového kanálu!",
"errorNotInSameChannel": "Musíš být ve stejném kanále jako {user}",
"usageReply": "Použití: {prefix}play <YouTube URL | Název videa | SoundCloud URL>",
"missingPermissionConnect": "Nelze se připojit do hlasového kanálu, chybí oprávnění",
"missingPermissionSpeak": "V tomto hlasovém kanále nemohu mluvit, ujisti se, že mám správná oprávnění!",
"queueAdded": "✅ Skladba **{title}** byla přidána do fronty uživatelem <@{author}>",
"cantJoinChannel": "Nelze se připojit do kanálu: {error}",
"queueEnded": "❌ Hudební fronta skončila.",
"queueError": "Chyba: {error}",
"startedPlaying": "🎶 Spuštěno přehrávání: **{title}** {url}",
"skipSong": "<@{author}> ⏩ přeskočil skladbu",
"pauseSong": "<@{author}> ⏸ pozastavil hudbu.",
"resumeSong": "<@{author}> ▶ zrušil pozastavení hudby!",
"unmutedSong": "<@{author}> 🔊 zrušil ztlumení hudby!",
"mutedSong": "<@{author}> 🔇 ztlumil hudbu!",
"decreasedVolume": "<@{author}> 🔉 snížil hlasitost, hlasitost je nyní {volume}%",
"increasedVolume": "<@{author}> 🔊 zvýšil hlasitost, hlasitost je nyní {volume}%",
"loopSong": "<@{author}> Opakování je nyní {loop}",
"stopSong": "<@{author}> ⏹ zastavil hudbu!",
"leaveChannel": "Opouštění hlasového kanálu...",
"songNotFound": "Hudba nenalezena",
"songAccessErr": "Video je omezeno věkem, soukromé nebo nedostupné"
},
"playlist": {
"description": "Přehrát playlist z YouTube",
"usagesReply": "Použití: {prefix}playlist <URL YouTube Playlistu | Název playlistu>",
"errorNotChannel": "Nejprve se musíš připojit do hlasového kanálu!",
"errorNotInSameChannel": "Musíš být ve stejném kanále jako {user}",
"missingPermissionConnect": "Nelze se připojit do hlasového kanálu, chybí oprávnění",
"missingPermissionSpeak": "V tomto hlasovém kanále nemohu mluvit, ujisti se, že mám správná oprávnění!",
"errorNotFoundPlaylist": "Playlist nenalezen :(",
"fetchingPlaylist": "⌛ načítání playlistu...",
"playlistCharLimit": "\nPlaylist je větší než limit znaků...",
"startedPlaylist": "<@{author}> spustil playlist",
"cantJoinChannel": "Nepodařilo se připojit do kanálu: {error}"
},
"pruning": {
"description": "Přepnout mazání zpráv bota",
"errorWritingFile": "Při zapisování do souboru se vyskytla chyba.",
"result": "Mazání zpráv je {result}"
},
"queue": {
"description": "Zobrazit frontu bota a právě hrající skladbu.",
"missingPermissionMessage": "Chybí mi oprávnění na správu zpráv nebo přidávání reakcí",
"errorNotQueue": "❌ **V tomto serveru nic nehraje**",
"currentPage": "Aktuální stránka - ",
"embedTitle": "Fronta\n",
"embedCurrentSong": "**Aktuální skladba - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Odebrat skladbu z fronty",
"errorNotQueue": "Neexistuje žádná fronta.",
"usageReply": "Použití: {prefix}remove <číslo ve frontě>",
"result": "<@{author}> ❌ odebral skladbu **{title}** z fronty."
},
"resume": {
"description": "Zrušit pozastavení právě hrající hudby",
"errorNotQueue": "Momentálně nic nehraje.",
"resultNotPlaying": "<@{author}> ▶ zrušil pozastavení hudby!",
"errorPlaying": "Fronta není pozastavena."
},
"search": {
"description": "Hledat a vybrat videa k přehrání",
"usageReply": "Použití: {prefix}{name} <název videa>",
"errorAlreadyCollector": "V tomto kanálu je již spuštěno sbírání zpráv.",
"errorNotChannel": "Nejprve se musíš připojit do hlasového kanálu!",
"resultEmbedTitle": "**Odpověz číslem skladby, kterou chceš přehrát**",
"resultEmbedDesc": "Výsledky pro: {search}"
},
"shuffle": {
"description": "Zamíchat frontu",
"errorNotQueue": "Neexistuje žádná fronta.",
"result": "<@{author}> 🔀 zamíchal frontu"
},
"skip": {
"description": "Přeskočit právě hrající skladbu",
"errorNotQueue": "Momentálně nehraje nic, co bych mohl přeskočit.",
"result": "<@{author}> ⏭ přeskočil skladbu"
},
"skipto": {
"description": "Přeskočit na vybrané číslo skladby ve frontě",
"usageReply": "Použití: {prefix}{name} <číslo ve frontě>",
"errorNotQueue": "Neexistuje žádná fronta.",
"errorNotValid": "Fronta má délku pouze {length} skladeb!",
"result": "<@{author}> ⏭ přeskočil {arg} skladeb"
},
"stop": {
"description": "Zastaví hudbu",
"errorNotQueue": "Momentálně nic nehraje.",
"result": "<@{author}> ⏹ zastavil hudbu!"
},
"uptime": {
"description": "Zkontrolovat dobu běhu",
"result": "Doba běhu: `{days}d, {hours}h, {minutes}m, {seconds}s`"
},
"volume": {
"description": "Změnit hlasitost právě hrající hudby",
"errorNotQueue": "Momentálně nic nehraje.",
"errorNotChannel": "Nejprve se musíš připojit do hlasového kanálu!",
"currentVolume": "🔊 Aktuální hlasitost je: **{volume}%**",
"errorNotNumber": "Použij prosím číslo pro nastavení hlasitosti.",
"errorNotValid": "Použij prosím číslo mezi 0 - 100.",
"result": "Hlasitost nastavena na: **{arg}%**"
},
"common": {
"on": "**zapnuto**",
"off": "**vypnuto**",
"enabled": "**povoleno**",
"disabled": "**zakázáno**",
"errorNotChannel": "Nejprve se musíš připojit do hlasového kanálu!",
"cooldownMessage": "počkej prosím ještě {time} sekund před opětovným použitím příkazu `{name}`.",
"errorCommand": "Při vykonávání tohoto příkazu se vyskytla chyba."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Spielt eine Kurz-Schnitt Audio Datei ab",
"usagesReply": "Nutzung: {prefix}clip <name>",
"errorQueue": "Ich kann den Kurz-Schnitt nicht abspielen, da die derzeitige Queue inaktiv ist.",
"errorNotChannel": "Betrete zuerst einen Voice-Channel!"
},
"clips": {
"description": "Zeigt alle Kurz-Schnitt Audios an"
},
"help": {
"description": "Zeigt alle Commands und deren Beschreibungen an",
"embedTitle": "{botname} Help",
"embedDescription": "Zeigt alle Commands an"
},
"invite": {
"description": "Schickt einen Boteinladungslink"
},
"loop": {
"description": "Musikschleife umschalten",
"errorNotQueue": "Es wird gerade nichts gespielt.",
"result": "Musikschleife ist nun auf {loop}"
},
"lyrics": {
"description": "Bekomme den Songtext(lyrics) vom jetzigem Song",
"errorNotQueue": "Es wird gerade nichts gespielt.",
"lyricsNotFound": "Keine Lyrics für {title} gefunden.",
"embedTitle": "{title} - Lyrics"
},
"move": {
"description": "Verschiebe Songs in der Queue",
"errorNotQueue": "Es gibt keine Queue.",
"usagesReply": "Nutzung: {prefix}move <Queue Number>",
"result": "<@{author}> 🚚 verschiebte **{title}** zu {index} in der Queue."
},
"nowplaying": {
"description": "Zeigt den jetzigen Song an",
"errorNotQueue": "Es wird gerade nichts gespielt.",
"embedTitle": "Spiele gerade",
"live": " ◉ LIVE",
"timeRemaining": "Übrige Zeit: {time}"
},
"pause": {
"description": "Pausiere den jetzigen Song",
"errorNotQueue": "Es wird gerade nichts gespielt.",
"result": "<@{author}> ⏸ pausierte den Song."
},
"ping": {
"description": "Zeigt den durchschnittlichen Ping vom Bot an",
"result": "📈 Durchschnittlicher Ping zur API ist: {ping} ms"
},
"play": {
"description": "Spielt Audio von Youtube oder Soundcloud ab",
"errorNotChannel": "Betrete zuerst einen Voice-Channel!",
"errorNotInSameChannel": "Du musst im selben Voice-Channel wie {user} sein",
"usageReply": "Nutzung: {prefix}play <YouTube URL | Video Name | Soundcloud URL>",
"missingPermissionConnect": "Ich kann deinem Voice-Channel nicht joinen, stelle sicher, dass ich die Berechtigung dazu habe!",
"missingPermissionSpeak": "Ich kann deinem Voice-Channel nicht sprechen, stelle sicher, dass ich die Berechtigung dazu habe!",
"queueAdded": "✅ **{title}** wurde von <@{author}> der Queue hinzugefügt",
"cantJoinChannel": "Konnte dem Channel nicht joinen, Fehlercode: {error}",
"queueEnded": "❌ Music-Queue beended.",
"queueError": "Error: {error}",
"startedPlaying": "🎶 Spiele jetzt: **{title}** {url}",
"skipSong": "<@{author}> ⏩ hat den Song übersprungen.",
"pauseSong": "<@{author}> ⏸ hat die Musik pausiert.",
"resumeSong": "<@{author}> ▶ hat die Musik fortgesetzt!",
"unmutedSong": "<@{author}> 🔊 hat die Musik unmuted!",
"mutedSong": "<@{author}> 🔇 hat die Musik gemuted!",
"decreasedVolume": "<@{author}> 🔉 hat die Lautstärke reduziert, sie ist jetzt auf {volume}%",
"increasedVolume": "<@{author}> 🔊 hat die Lautstärke erhöht, sie ist jetzt auf {volume}%",
"loopSong": "<@{author}> Musikschleife ist nun auf {loop}",
"stopSong": "<@{author}> ⏹ hat die Musik gestoppt!",
"leaveChannel": "Verlasse den Voice-Channel...",
"songNotFound": "Audio nicht gefunden",
"songAccessErr": "Das Video ist altersbeschränkt, privat oder nicht verfügbar"
},
"playlist": {
"description": "Spielt eine Playlist von Youtube ab",
"usagesReply": "Nutzung: {prefix}playlist <YouTube Playlist URL | Playlist Name>",
"errorNotChannel": "Betrete zuerst einen Voice-Channel!",
"errorNotInSameChannel": "Du musst im selben Voice-Channel wie {user} sein",
"missingPermissionConnect": "Ich kann deinem Voice-Channel nicht joinen, stelle sicher, dass ich die Berechtigung dazu habe!",
"missingPermissionSpeak": "Ich kann deinem Voice-Channel nicht sprechen, stelle sicher, dass ich die Berechtigung dazu habe!",
"errorNotFoundPlaylist": "Playlist nicht gefunden :(",
"fetchingPlaylist": "⌛ Abrufen der Playlist...",
"playlistCharLimit": "\nPlaylist ist größer als das Limit...",
"startedPlaylist": "<@{author}> hat eine Playlist gestartet",
"cantJoinChannel": "Konnte den Voice-Channel nicht joinen, Fehler: {error}"
},
"pruning": {
"description": "Schalten Sie das Bereinigen von Bot-Nachrichten um",
"errorWritingFile": "Beim Schreiben in die Datei ist ein Fehler aufgetreten.",
"result": "Nachrichtenbereinigung ist {result}"
},
"queue": {
"description": "Zeige die Musikqueue und spiele jetzt.",
"missingPermissionMessage": "Fehlende Berechtigung zum Verwalten von Nachrichten oder Hinzufügen von Reaktionen",
"errorNotQueue": "❌ **Auf diesem Server wird nichts gespielt**",
"currentPage": "Aktuelle Seite - ",
"embedTitle": "Song Queue\n",
"embedCurrentSong": "**Jetziges Lied - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Entfernen Sie das Lied aus der Queue",
"errorNotQueue": "Es gibt keine Queue.",
"usageReply": "Nutzung: {prefix}remove <Queue Number>",
"result": "<@{author}> ❌ hat **{title}** aus der Queue entfernt."
},
"resume": {
"description": "Setzte die Musik fort",
"errorNotQueue": "Es wird gerade nichts gespielt.",
"resultNotPlaying": "<@{author}> ▶ hat die Musik fortgesetzt!",
"errorPlaying": "Die Queue ist nicht pausiert."
},
"search": {
"description": "Suche und wähle Videos zum Abspielen aus",
"usageReply": "Nutzung: {prefix}{name} <Video Name>",
"errorAlreadyCollector": "In diesem Kanal ist bereits ein Nachrichtensammler aktiv.",
"errorNotChannel": "Betrete zuerst einen Voice-Channel!",
"resultEmbedTitle": "**Antworte mit der Songnummer, die du spielen möchten**",
"resultEmbedDesc": "Ergebnisse für: {search}"
},
"shuffle": {
"description": "Mischte die Queue",
"errorNotQueue": "Es gibt keine Queue.",
"result": "<@{author}> 🔀 hat die Queue gemischt"
},
"skip": {
"description": "Überspringe den jetzigen Song",
"errorNotQueue": "Es wird gerade nichts gespielt that I could skip for you.",
"result": "<@{author}> ⏭ hat den Song übersprungen"
},
"skipto": {
"description": "Überspringe eine ausgewählte Menge von Songs",
"usageReply": "Nutzung: {prefix}{name} <Queue Number>",
"errorNotQueue": "Es gibt keine Queue.",
"errorNotValid": "Die Queue ist nur {length} Songs lang!",
"result": "<@{author}> ⏭ hat {arg} Songs übersprungen"
},
"stop": {
"description": "Stoppe die Musik",
"errorNotQueue": "Es wird gerade nichts gespielt.",
"result": "<@{author}> ⏹ hat die Musik gestoppt!"
},
"uptime": {
"description": "Checke die Uptime vom Bot",
"result": "Uptime: `{days} day(s),{hours} hours, {minutes} minutes, {seconds} seconds`"
},
"volume": {
"description": "Ändere die Lautstärke vom jetzigem Song",
"errorNotQueue": "Es wird gerade nichts gespielt.",
"errorNotChannel": "Betrete zuerst einen Voice-Channel!",
"currentVolume": "🔊 Die Lautstärke ist: **{volume}%**",
"errorNotNumber": "Bitte nutze eine Number um die Lautstärke zu ändern.",
"errorNotValid": "Bitte nutze eine Number zwischen 0 - 100.",
"result": "Lautstärke wurde auf **{arg}%** gesetzt."
},
"common": {
"on": "**an**",
"off": "**aus**",
"enabled": "**aktiviert**",
"disabled": "**deaktiviert**",
"errorNotChannel": "Betrete zuerst einen Voice-Channel!",
"cooldownMessage": "Bitte warte noch {time} Sekunde(n) bevor du wieder den Command `{name}` nuzten kannst.",
"errorCommand": "Da war ein Fehler beim ausführen des Commands."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Παίζει έναν ήχο ενός κλίπ",
"usagesReply": "Χρήση: {prefix}clip <name>",
"errorQueue": "Αδύνατη αναπαραγωγή κλίπ καθώς υπάρχει ενεργή ουρά.",
"errorNotChannel": "Θα πρέπει να συνδεθείς σε ένα κανάλι ομιλίας πρώτα!"
},
"clips": {
"description": "Εμφάνιση όλων των κλίπς σε λίστα"
},
"help": {
"description": "Εμφάνιση όλων των εντολών και περιγραφών",
"embedTitle": "{botname} Βοήθεια",
"embedDescription": "Εμφάνιση όλων των εντολών σε λίστα"
},
"invite": {
"description": "Στείλε στο bot σύνδεσμο πρόσκλησης"
},
"loop": {
"description": "Εναλλαγή του βρόγχου μουσικής",
"errorNotQueue": "Δεν αναπαράγεται κάτι.",
"result": "Ο βρόγχος τώρα είναι {loop}"
},
"lyrics": {
"description": "Στίχοι του τραγουδιού που παίζει τώρα",
"errorNotQueue": "There is nothing playing.",
"lyricsNotFound": "Δεν αναπαράγεται κάτι..",
"embedTitle": "{title} - Στίχοι"
},
"move": {
"description": "Μετακίνησε τα τραγούδια στην ουρά",
"errorNotQueue": "Δεν υπάρχει ουρά αναπαραγωγής.",
"usagesReply": "Χρήση: {prefix}move <Νούμερο Ουράς>",
"result": "<@{author}> 🚚 μετακίνησε **{title}** ως {index}ο στην ουρά."
},
"nowplaying": {
"description": "Εμφάνιση του τραγουδιού που παίζει τώρα",
"errorNotQueue": "Δεν αναπαράγεται κάτι.",
"embedTitle": "Τώρα παίζει",
"live": " ◉ LIVE",
"timeRemaining": "Χρόνος που υπολείπεται: {time}"
},
"pause": {
"description": "Παύση του τραγουδιού που παίζει τώρα",
"errorNotQueue": "Δεν αναπαράγεται κάτι.",
"result": "<@{author}> ⏸ σταμάτησε την αναπαραγωγή μουσικής."
},
"ping": {
"description": "Εμφάνισε το μέσο όρο ping του bot",
"result": "📈 Μέσος όρος ping στο API: {ping} ms"
},
"play": {
"description": "Αναπαραγωγή ήχου από το YouTube ή το Soundcloud",
"errorNotChannel": "Θα πρέπει να συνδεθείς σε ένα κανάλι ομιλίας πρώτα!",
"errorNotInSameChannel": "Θα πρέπει να είσαι στο κανάλι κανάλι ομιλίας όπως ο χρήστης {user}",
"usageReply": "Χρήση: {prefix}play <URL του YouTubeYouTube | Όνομα Video | URL του Soundcloud>",
"missingPermissionConnect": "Αδύνατη σύνδεση στο κανάλι ομιλίας, λείπουν άδειες",
"missingPermissionSpeak": "Δε μπορώ να μιλήσω στο κανάλι ομιλίας, έλεγξε αν έχω τις σωστές άδειες!",
"queueAdded": "✅ **{title}** Προστέθηκε στην ουρά από <@{author}>",
"cantJoinChannel": "Αδύνατη σύνδεση στο κανάλι: {error}",
"queueEnded": "❌ Η ουρά αναπαραγωγής τελείωσε.",
"queueError": "Σφάλμα: {error}",
"startedPlaying": "🎶 Ξεκίνησε να παίζει τώρα: **{title}** {url}",
"skipSong": "<@{author}> ⏩ Παράλειψη τραγουδιού",
"pauseSong": "<@{author}> ⏸ Παύση τραγουδιού.",
"resumeSong": "<@{author}> ▶ Επανέναρξη αναπαραγωγής τραγουδιού!",
"unmutedSong": "<@{author}> 🔊 Διακοπή σίγασης μουσικής!",
"mutedSong": "<@{author}> 🔇 Σίγαση μουσικής!",
"decreasedVolume": "<@{author}> 🔉 χαμήλωσε την ένταση, η ένταση τώρα είναι {volume}%",
"increasedVolume": "<@{author}> 🔊 αύξησε την ένταση, η ένταση τώρα είναι {volume}%",
"loopSong": "<@{author}> Ο βρόγχος τώρα είναι {loop}",
"stopSong": "<@{author}> ⏹ σταμάτησε την αναπαραγωγή!",
"leaveChannel": "Έξοδος από το κανάλι ομιλίας...",
"songNotFound": "Δε βρέθηκε ήχος",
"songAccessErr": "Video is age restricted, private or unavailable"
},
"playlist": {
"description": "Αναπαραγωγή playlist από το youtube",
"usagesReply": "Χρήση: {prefix}playlist < URL του Playlist του YouTube | Όνομα του Playlist >",
"errorNotChannel": "Θα πρέπει να συνδεθείς σε ένα κανάλι ομιλίας πρώτα!",
"errorNotInSameChannel": "Θα πρέπει να είσαι στο κανάλι κανάλι ομιλίας όπως ο χρήστης {user}",
"missingPermissionConnect": "Αδύνατη σύνδεση στο κανάλι ομιλίας, λείπουν άδειες",
"missingPermissionSpeak": "Δε μπορώ να μιλήσω στο κανάλι ομιλίας, έλεγξε αν έχω τις σωστές άδειες!",
"errorNotFoundPlaylist": "Το Playlist δε βρέθηκε :(",
"fetchingPlaylist": "⌛ Το playlist έρχεται...",
"playlistCharLimit": "\nPlaylist μεγαλύτερο από το όριο χαρακτήρων...",
"startedPlaylist": "<@{author}> Ξεκίνησε ένα playlist",
"cantJoinChannel": "Αδύνατη σύνδεση στο κανάλι: {error}"
},
"pruning": {
"description": "Εναλλαγή περικοπής μηνυμάτων του bot",
"errorWritingFile": "Υπήρξε σφάλμα γράφοντας στο αρχείο.",
"result": "Η περικοπή μηνήματος είναι {result}"
},
"queue": {
"description": "Εμφάνιση της ουράς αναπαραγωγής και του τραγουδιού που παίζει τώρα.",
"missingPermissionMessage": "Λείπει άδεια διαχείρισης μηνυμάτων ή προσθήκης αντιδράσεων",
"errorNotQueue": "❌ **Δεν αναπαράγεται κάτι στο server**",
"currentPage": "Τωρινή Σελίδα - ",
"embedTitle": "Ουρά τραγουδιών\n",
"embedCurrentSong": "**Παίζει τώρα - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Αφαίρεση τραγουδιού από την ουρά αναπαραγωγής",
"errorNotQueue": "Δεν υπάρχει ουρά αναπαραγωγής.",
"usageReply": "Χρήση: {prefix}αφαίρεση <Νούμερο ουράς αναπαραγωγής>",
"result": "<@{author}> ❌ αφαίρεσε **{title}** από την ουρά αναπαραγωγής."
},
"resume": {
"description": "Επανέναρξη της μουσικής που παίζει τώρα",
"errorNotQueue": "Δεν αναπαράγεται κάτι.",
"resultNotPlaying": "<@{author}> ▶ ξεκίνησε πάλι τη μοσυική!",
"errorPlaying": "Η ουρά αναπαραγωγής δεν είναι σε παύση."
},
"search": {
"description": "Αναζήτηση και επιλογή αναπαραγωγής video",
"usageReply": "Χρήση: {prefix}{name} <Όνομα του Video>",
"errorAlreadyCollector": "Ένας συλλέκτης μηνυμάτων είναι ήδη ενεργός σ' αυτό το κανάλι.",
"errorNotChannel": "Θα πρέπει να συνδεθείς σε ένα κανάλι ομιλίας πρώτα!",
"resultEmbedTitle": "**Απάντησε με το νούμερο τραγουδιού που θέλεις να παίξει**",
"resultEmbedDesc": "Αποτελέσματα για: {search}"
},
"shuffle": {
"description": "Ανάμιξη ουράς αναπαραγωγής",
"errorNotQueue": "Δεν υπάρχει ουρά αναπαραγωγής.",
"result": "<@{author}> 🔀 ανακάτεψε την ουρά αναπαραγωγής"
},
"skip": {
"description": "Πάράλειψη κομματιού που παίζει τώρα",
"errorNotQueue": "Δεν υπάρχει κάτι να παίζει για να παραληφθεί.",
"result": "<@{author}> ⏭ παρέλειψε το τραγούδι"
},
"skipto": {
"description": "Πάράλειψη στο συγκεκριμένο αριθμό ουράς αναπαραγωγής",
"usageReply": "Χρήση: {prefix}{name} <Αριθμός Ουράς Αναπαραγωγής>",
"errorNotQueue": "Δεν υπάρχει ουρά αναπαραγωγής.",
"errorNotValid": "Η ουρά αναπαραγωγής έχει διάρκεια αναπαραγωγής μόνο {length} !",
"result": "<@{author}> ⏭ παρέλειψε {arg} ταργούδια"
},
"stop": {
"description": "Παύση μουσικής",
"errorNotQueue": "Δεν αναπαράγεται κάτι.",
"result": "<@{author}> ⏹ σταμάτησε τη μουσική!"
},
"uptime": {
"description": "Έλεγχος χρόνου διαθεσιμότητας",
"result": "Χρόνος Διαθεσιμότητας: `{days} μέρες,{hours} ώρες, {minutes} λεπτά, {seconds} δευτερόλεπτα`"
},
"volume": {
"description": "Αλλαγή έντασης μουσικής που παίζει",
"errorNotQueue": "Δεν αναπαράγεται κάτι.",
"errorNotChannel": "Θα πρέπει να συνδεθείς σε ένα κανάλι ομιλίας πρώτα!",
"currentVolume": "🔊 Η ένταση τώρα είναι: **{volume}%**",
"errorNotNumber": "Παρακαλώ χρησιμοποιήστε έναν αριθμό για ρύθμιση έντασης.",
"errorNotValid": "Παρακαλώ χρησιμοποιήστε έναν αριθμόΠαρακαλώ χρησιμοποιήστε έναν αριθμό από το 0 - 100.",
"result": "Η ένταση ρυθμίστηκε σε: **{arg}%**"
},
"common": {
"on": "**on**",
"off": "**off**",
"enabled": "**ενεργοποιημένος/-η/-ο**",
"disabled": "**απενεργοποιημένος/-η/-ο**",
"errorNotChannel": "Θα πρέπει να συνδεθείς σε ένα κανάλι ομιλίας πρώτα!",
"cooldownMessage": "Παρακαλώ περιμένετε {time} δευτερόλεπτα ακόμη πριν ξαναχρησιμοποιήσετε την εντολή `{name}`.",
"errorCommand": "Υπήρξε σφάλμα στην εκτέλεση εντολής."
}
}
+180
View File
@@ -0,0 +1,180 @@
{
"clip": {
"description": "Plays a clip sound",
"usagesReply": "Usage: {prefix}clip <name>",
"errorQueue": "Can't play clip because there is an active queue.",
"errorNotChannel": "You need to join a voice channel first!"
},
"clips": {
"description": "List all clips"
},
"help": {
"description": "Display all commands and descriptions",
"embedTitle": "{botname} Help",
"embedDescription": "List of all commands"
},
"invite": {
"description": "Send bot invite link"
},
"loop": {
"description": "Toggle music loop",
"errorNotQueue": "There is nothing playing.",
"result": "Loop is now {loop}"
},
"lyrics": {
"description": "Get lyrics for the currently playing song",
"errorNotQueue": "There is nothing playing.",
"lyricsNotFound": "No lyrics found for {title}.",
"embedTitle": "{title} - Lyrics"
},
"move": {
"description": "Move songs around in the queue",
"errorNotQueue": "There is no queue.",
"usagesReply": "Usage: {prefix}move <Queue Number>",
"result": "<@{author}> 🚚 moved **{title}** to {index} in the queue.",
"args": {
"movefrom": "Slot to move from",
"moveto": "Slot to move to"
}
},
"nowplaying": {
"description": "Show now playing song",
"errorNotQueue": "There is nothing playing.",
"embedTitle": "Now playing",
"live": " ◉ LIVE",
"timeRemaining": "Time Remaining: {time}"
},
"pause": {
"description": "Pause the currently playing music",
"errorNotQueue": "There is nothing playing.",
"result": "<@{author}> ⏸ paused the music."
},
"ping": {
"description": "Show the bot's average ping",
"result": "📈 Average ping to API: {ping} ms"
},
"play": {
"description": "Plays audio from YouTube",
"errorNotChannel": "You need to join a voice channel first!",
"errorNotInSameChannel": "You must be in the same channel as {user}",
"usageReply": "Usage: {prefix}play <YouTube URL | Video Name>",
"missingPermissionConnect": "Cannot connect to voice channel, missing permissions",
"missingPermissionSpeak": "I cannot speak in this voice channel, make sure I have the proper permissions!",
"queueAdded": "✅ **{title}** has been added to the queue by <@{author}>",
"cantJoinChannel": "Could not join the channel: {error}",
"queueEnded": "❌ Music queue ended.",
"queueError": "Error: {error}",
"startedPlaying": "🎶 Started playing: **{title}** {url}",
"skipSong": "<@{author}> ⏩ skipped the song",
"pauseSong": "<@{author}> ⏸ paused the music.",
"resumeSong": "<@{author}> ▶ resumed the music!",
"unmutedSong": "<@{author}> 🔊 unmuted the music!",
"mutedSong": "<@{author}> 🔇 muted the music!",
"decreasedVolume": "<@{author}> 🔉 decreased the volume, the volume is now {volume}%",
"increasedVolume": "<@{author}> 🔊 increased the volume, the volume is now {volume}%",
"loopSong": "<@{author}> Loop is now {loop}",
"stopSong": "<@{author}> ⏹ stopped the music!",
"leaveChannel": "Leaving voice channel...",
"songNotFound": "Audio Not Found",
"songAccessErr": "Video is age restricted, private or unavailable",
"errorNoResults": "No results found for {url}",
"errorInvalidURL": "Invalid URL, please try a search or youtube url"
},
"playlist": {
"description": "Play a playlist from youtube",
"usagesReply": "Usage: {prefix}playlist <YouTube Playlist URL | Playlist Name>",
"errorNotChannel": "You need to join a voice channel first!",
"errorNotInSameChannel": "You must be in the same channel as {user}",
"missingPermissionConnect": "Cannot connect to voice channel, missing permissions",
"missingPermissionSpeak": "I cannot speak in this voice channel, make sure I have the proper permissions!",
"errorNotFoundPlaylist": "Playlist not found :(",
"fetchingPlaylist": "⌛ fetching the playlist...",
"playlistCharLimit": "\nPlaylist larger than character limit...",
"startedPlaylist": "<@{author}> Started a playlist",
"cantJoinChannel": "Could not join the channel: {error}"
},
"pruning": {
"description": "Toggle pruning of bot messages",
"errorWritingFile": "There was an error writing to the file.",
"result": "Message pruning is {result}"
},
"queue": {
"description": "Show the music queue and now playing.",
"missingPermissionMessage": "Missing permission to manage messages or add reactions",
"errorNotQueue": "❌ **Nothing playing in this server**",
"currentPage": "Current Page - ",
"embedTitle": "Song Queue\n",
"embedCurrentSong": "**Current Song - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Remove song from the queue",
"errorNotQueue": "There is no queue.",
"usageReply": "Usage: {prefix}remove <Queue Number>",
"result": "<@{author}> ❌ removed **{title}** from the queue."
},
"resume": {
"description": "Resume currently playing music",
"errorNotQueue": "There is nothing playing.",
"resultNotPlaying": "<@{author}> ▶ resumed the music!",
"errorPlaying": "The queue is not paused."
},
"search": {
"description": "Search and select videos to play",
"usageReply": "Usage: {prefix}{name} <Video Name>",
"errorAlreadyCollector": "A message collector is already active in this channel.",
"errorNotChannel": "You need to join a voice channel first!",
"resultEmbedTitle": "**Reply with the song number you want to play**",
"resultEmbedDesc": "Results for: {search}",
"optionQuery": "Search query",
"noResults": "No results for query, please try something else"
},
"shuffle": {
"description": "Shuffle queue",
"errorNotQueue": "There is no queue.",
"result": "<@{author}> 🔀 shuffled the queue"
},
"skip": {
"description": "Skip the currently playing song",
"errorNotQueue": "There is nothing playing that I could skip for you.",
"result": "<@{author}> ⏭ skipped the song"
},
"skipto": {
"description": "Skip to the selected queue number",
"usageReply": "Usage: {prefix}{name} <Queue Number>",
"errorNotQueue": "There is no queue.",
"errorNotValid": "The queue is only {length} songs long!",
"result": "<@{author}> ⏭ skipped {arg} songs",
"args": {
"number": "The queue number to skip to"
}
},
"stop": {
"description": "Stops the music",
"errorNotQueue": "There is nothing playing.",
"result": "<@{author}> ⏹ stopped the music!"
},
"uptime": {
"description": "Check the uptime",
"result": "Uptime: `{days} day(s),{hours} hours, {minutes} minutes, {seconds} seconds`"
},
"volume": {
"description": "Change volume of currently playing music",
"errorNotQueue": "There is nothing playing.",
"errorNotChannel": "You need to join a voice channel first!",
"currentVolume": "🔊 The current volume is: **{volume}%**",
"errorNotNumber": "Please use a number to set volume.",
"errorNotValid": "Please use a number between 0 - 100.",
"result": "Volume set to: **{arg}%**"
},
"common": {
"on": "**on**",
"off": "**off**",
"enabled": "**enabled**",
"disabled": "**disabled**",
"errorNotChannel": "You need to join a voice channel first!",
"cooldownMessage": "please wait {time} more second(s) before reusing the `{name}` command.",
"errorCommand": "There was an error executing that command."
},
"Invite me to your server!": "Invite me to your server!",
"Invite": "Invite"
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Reproduce un sonido .mp3 dentro de la carpeta sonido",
"usagesReply": "Cómo usarlo: {prefix}clip <nombre_clip.mp3>",
"errorQueue": "No se puede reproducir el clip porque hay una cola activa",
"errorNotChannel": "¡Primero debes unirte a un canal de voz!"
},
"clips": {
"description": "Lista todos los clips"
},
"help": {
"description": "Muestra todos los comandos y descripciones",
"embedTitle": "Ayuda de {botname}",
"embedDescription": "Listado de comandos"
},
"invite": {
"description": "Envía un link de invitación para el bot"
},
"loop": {
"description": "Activa el modo de reproducción en bucle",
"errorNotQueue": "No se está reproduciendo nada.",
"result": "Reproduciendo en bucle: {loop}"
},
"lyrics": {
"description": "Obtén la letra de la música actual",
"errorNotQueue": "No se está reproduciendo nada.",
"lyricsNotFound": "No se encontró la letra de {title}.",
"embedTitle": "{title} - Letra"
},
"move": {
"description": "Mueve canciones de la cola",
"errorNotQueue": "No hay una cola.",
"usagesReply": "Uso correcto: {prefix}move <Número en la Cola>",
"result": "<@{author}> 🚚 movió **{title}** al puesto {index} de la cola."
},
"nowplaying": {
"description": "Muestra la música que se está reproduciendo actualmente",
"errorNotQueue": "No se está reproduciendo nada.",
"embedTitle": "Música actual:",
"live": " ◉ EN DIRECTO",
"timeRemaining": "Tiempo Restante: {time}"
},
"pause": {
"description": "Pausa la música que se está reproduciendo actualmente",
"errorNotQueue": "No se está reproduciendo nada.",
"result": "<@{author}> ⏸ Pausó la música."
},
"ping": {
"description": "Muestra la latencia media del bot (ping)",
"result": "📈 Latencia media a la API: {ping} ms"
},
"play": {
"description": "Reproduce música de YouTube o SoundCloud",
"errorNotChannel": "¡Primero debes unirte a un canal de voz!",
"errorNotInSameChannel": "Tienes que estar en el mismo canal de voz que {user}",
"usageReply": "Uso correcto: {prefix}play <URL de YouTube | Nombre del vídeo | URL de SoundCloud>",
"missingPermissionConnect": "No se puede conectar al canal de voz, permisos insuficientes.",
"missingPermissionSpeak": "¡No se puede reproducir sonidos en este canal de voz, comprueba los permisos!",
"queueAdded": "✅ <@{author}> ha añadido **{title}** a la cola de reproducción",
"cantJoinChannel": "No se pudo conectar al canal: {error}",
"queueEnded": "❌ Cola de música finalizada.",
"queueError": "Error: {error}",
"startedPlaying": "🎶 Ahora reproduciendo: **{title}** {url}",
"skipSong": "<@{author}> ⏩ ¡Saltó la música!",
"pauseSong": "<@{author}> ⏸ ¡Pausó la música!",
"resumeSong": "<@{author}> ▶ ¡Continuó la reproducción!",
"unmutedSong": "<@{author}> 🔊 ¡Desilenció la música!",
"mutedSong": "<@{author}> 🔇 ¡Silenció la música!",
"decreasedVolume": "<@{author}> 🔉 Bajó el volumen de la música, el volumen actual ahora es {volume}%",
"increasedVolume": "<@{author}> 🔊 Subió el volumen de la música, el volumen actual ahora es {volume}%",
"loopSong": "<@{author}> El bucle actual esta {loop}",
"stopSong": "<@{author}> ⏹ ¡Paró la música!",
"leaveChannel": "Saliendo del chat de voz...",
"songNotFound": "Música no encontrada",
"songAccessErr": "El video tiene restricción de edad, es privado o no está disponible"
},
"playlist": {
"description": "Reproduce una lista de reproducción de YouTube",
"usagesReply": "Uso correcto: {prefix}playlist <URL de la Lista de Reproducción en YouTube | Nombre de la Lista de Reproducción>",
"errorNotChannel": "¡Primero debes unirte a un canal de voz!",
"errorNotInSameChannel": "Tienes que estar en el mismo canal de voz que {user}",
"missingPermissionConnect": "No se puede conectar al canal de voz, permisos insuficientes.",
"missingPermissionSpeak": "¡No se puede reproducir sonidos en este canal de voz, comprueba los permisos!",
"errorNotFoundPlaylist": "No se encontró la lista de reproducción :(",
"fetchingPlaylist": "⌛ Obteniendo la lista de reproducción...",
"playlistCharLimit": "\nLista de reproducción más larga que el límite de caracteres por mensaje...",
"startedPlaylist": "<@{author}> Comenzó a reproducir una lista de reproducción",
"cantJoinChannel": "No se pudo conectar al canal: {error}"
},
"pruning": {
"description": "Activa la eliminación de los mensajes del bot",
"errorWritingFile": "Se produjo un error escribiendo el archivo.",
"result": "El modo actual es {result}"
},
"queue": {
"description": "Muestra la reproducción actual y la cola.",
"missingPermissionMessage": "Se necesitan permisos para añadir reacciones o enviar mensajes.",
"errorNotQueue": "❌ **No se está reproduciendo nada en el servidor**",
"currentPage": "Página actual - ",
"embedTitle": "Cola de música\n",
"embedCurrentSong": "**Música actual - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Elimina canciones de la cola de reproducción",
"errorNotQueue": "No hay una cola de reproducción.",
"usageReply": "Uso correcto: {prefix}remove <Número en la Cola>",
"result": "<@{author}> ❌ Eliminó **{title}** de la cola de reproducción."
},
"resume": {
"description": "Continua con la reproducción actual",
"errorNotQueue": "❌ **No se está reproduciendo nada en el servidor**",
"resultNotPlaying": "<@{author}> ▶ ¡Le dio a continuar!",
"errorPlaying": "La cola no está en pausa."
},
"search": {
"description": "Busca y selecciona vídeos para reproducir.",
"usageReply": "Uso correcto: {prefix}{name} <Nombre del Vídeo>",
"errorAlreadyCollector": "Un recolector de mensajes ya está activo en el servidor actualmente.",
"errorNotChannel": "¡Primero debes unirte a un canal de voz!",
"resultEmbedTitle": "**Responde con el número de la música que quieras**",
"resultEmbedDesc": "Resultados para: {search}"
},
"shuffle": {
"description": "Reproducción aleatoria de la cola",
"errorNotQueue": "No hay una cola de reproducción.",
"result": "<@{author}> 🔀 ha activado la reproducción aleatoria de la cola"
},
"skip": {
"description": "Salta a la siguiente música en la cola de reproducción",
"errorNotQueue": "No se está reproduciendo nada que pueda saltar para ti.",
"result": "<@{author}> ⏭ Saltó la música"
},
"skipto": {
"description": "Salta a la posición seleccionada en la cola",
"usageReply": "Cómo usarlo: {prefix}{name} <Número en la Cola>",
"errorNotQueue": "No hay una cola de reproducción.",
"errorNotValid": "¡La cola solo tiene {length} canciones!",
"result": "<@{author}> ⏭ Saltó {arg} canciones"
},
"stop": {
"description": "Para la música",
"errorNotQueue": "No se está reproduciendo nada.",
"result": "<@{author}> ⏹ ¡Paró la música!"
},
"uptime": {
"description": "Comprueba el tiempo desde que se inició el bot",
"result": "Tiempo en línea: `{days} día(s), {hours} horas, {minutes} minutos, {seconds} segundos`"
},
"volume": {
"description": "Cambia el volumen de reproducción actual",
"errorNotQueue": "No se está reproduciendo nada.",
"errorNotChannel": "¡Primero debes unirte a un canal de voz!",
"currentVolume": "🔊 El volumen actual es: **{volume}%**",
"errorNotNumber": "Por favor utiliza un número para asignar el volumen actual.",
"errorNotValid": "Por favor utiliza un número entre 0 - 100.",
"result": "Volumen al: **{arg}%**"
},
"common": {
"on": "**Encendido**",
"off": "**Apagado**",
"enabled": "**Activado**",
"disabled": "**Desactivado**",
"errorNotChannel": "¡Primero debes unirte a un canal de voz!",
"cooldownMessage": "Por favor espera {time} segundos antes de volver a usar el comando `{name}`.",
"errorCommand": "Se produjo un error con ese comando."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "پخش کردن کلیپ",
"usagesReply": "استفاده: {prefix}clip <name>",
"errorQueue": "قادر به پخش کلیپ نیست",
"errorNotChannel": "ابتدا باید در یک چنل جوین شوید!"
},
"clips": {
"description": "لیست تمام کلیپ ها"
},
"help": {
"description": "نمایش تمام دستور ها",
"embedTitle": "{botname} دستور های",
"embedDescription": "نمایش تمام دستور ها"
},
"invite": {
"description": "ارسال لینک بات"
},
"loop": {
"description": "تغییر وضعیت تکرار",
"errorNotQueue": "هیچ چیزی در حال پخش نیست.",
"result": "تکرار {loop}"
},
"lyrics": {
"description": "نمایش متن موسیقی در حال پخش",
"errorNotQueue": "هیچ چیزی در حال پخش نیست.",
"lyricsNotFound": "متن برای آهنگ یافت نشد {title}.",
"embedTitle": "{title} - متن"
},
"move": {
"description": "جابه جایی آهنگ در صف",
"errorNotQueue": "هیچ چیزی در حال پخش نیست.",
"usagesReply": "استفاده: {prefix}move <Queue Number>",
"result": "<@{author}> 🚚 جابه جایی **{title}** to {index} در صف."
},
"nowplaying": {
"description": "نمایش آهنگ در حال پخش",
"errorNotQueue": "هیچ چیزی در حال پخش نیست.",
"embedTitle": "در حال پخش",
"live": " ◉ زنده",
"timeRemaining": "زمان باقی مانده: {time}"
},
"pause": {
"description": "متوقف کردن آهنگ در حال پخش",
"errorNotQueue": "هیچ چیزی در حال پخش نیست.",
"result": "<@{author}> ⏸ آهنگ را متوقف کرد."
},
"ping": {
"description": "نمایش پینگ",
"result": "📈 پینگ میانگین سرور: {ping} ms"
},
"play": {
"description": "پخش آهنگ از یوتوب یا ساوندکلاود",
"errorNotChannel": "ابتدا باید در یک چنل جوین شوید!",
"errorNotInSameChannel": "باید در چنل این کاربر باشید {user}",
"usageReply": "استفاده: {prefix}play <لینک یوتوب | نام فیلم | لینک ساوندکلاود>",
"missingPermissionConnect": "به دلیل عدم اجازه بات قادر به اتصال نیست",
"missingPermissionSpeak": "به دلیل عدم اجازه بات قادر به پخش نیست",
"queueAdded": "✅ <@{author}> این را به صف اضافه کرد **{title}**",
"cantJoinChannel": "امکان اتصال به چنل نیست: {error}",
"queueEnded": "❌ صف آهنگ تمام شد.",
"queueError": "خطا: {error}",
"startedPlaying": "🎶 در حال اجرای: **{title}** {url}",
"skipSong": "<@{author}> ⏩ آهنگ را اسکیپ کرد",
"pauseSong": "<@{author}> ⏸ آهنگ را متوقف کرد",
"resumeSong": "<@{author}> ▶ آهنگ را پخش کرد",
"unmutedSong": "<@{author}> 🔊 صدای آهنگ را فعال کرد!",
"mutedSong": "<@{author}> 🔇 صدای آهنگ را غیر فعال کرد!",
"decreasedVolume": "<@{author}> 🔉 صدای آهنگ را به این عدد کاهش داد {volume}%",
"increasedVolume": "<@{author}> 🔊 صدای آهنگ را به این عدد افزایش داد {volume}%",
"loopSong": "<@{author}> تکرار آهنگ {loop}",
"stopSong": "<@{author}> ⏹ آهنگ را متوقف کرد!",
"leaveChannel": "در حال خارج شدن از چنل...",
"songNotFound": "آهنگ پیدا نشد",
"songAccessErr": "امکان دسترسی به آهنگ موجود نیست"
},
"playlist": {
"description": "پخش پلی لیست از یوتوب",
"usagesReply": "استفاده: {prefix}playlist <لینک پلی لیست یوتوب | نام پلی لیست>",
"errorNotChannel": "ابتدا باید در یک چنل جوین شوید!",
"errorNotInSameChannel": "باید در چنل این کاربر باشید {user}",
"missingPermissionConnect": "به دلیل عدم اجازه بات قادر به اتصال نیست",
"missingPermissionSpeak": "به دلیل عدم اجازه بات قادر به پخش نیست",
"errorNotFoundPlaylist": "پلی لیست پیدا نشد :(",
"fetchingPlaylist": "⌛ در حال فتچ کردن...",
"playlistCharLimit": "\nپلی لیست بیش از حد بزرگ است...",
"startedPlaylist": "<@{author}> یک پلی لیست پخش کرد",
"cantJoinChannel": "امکان اتصال به چنل نیست: {error}"
},
"pruning": {
"description": "روشن/خاموش کردن پیام های بات",
"errorWritingFile": "مشکلی پیش آمد.",
"result": "پیام های بات : {result}"
},
"queue": {
"description": "نمایش صف و آهنگ در حال پخش",
"missingPermissionMessage": "امکان دسترسی به پیام ها نیست",
"errorNotQueue": "❌ **هیچ آهنگی در حال پخش نیست**",
"currentPage": "صفحه ی فعلی - ",
"embedTitle": "صف آهنگ\n",
"embedCurrentSong": "**آهنگ فعلی - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "حذف آهنگ از صف",
"errorNotQueue": "صفی وجود ندارد.",
"usageReply": "استفاده: {prefix}remove <Queue Number>",
"result": "<@{author}> ❌ آهنگ **{title}** را از صف حذف کرد."
},
"resume": {
"description": "ادامه ی آهنگ فعلی",
"errorNotQueue": "آهنگی در حال پخش نیست.",
"resultNotPlaying": "<@{author}> ▶ آهنگ را ادامه داد!",
"errorPlaying": "متوقف نشده است"
},
"search": {
"description": "جست و جو و انتخاب آهنگ",
"usageReply": "استفاده: {prefix}{name} <Video Name>",
"errorAlreadyCollector": "در حال حاضر یک جست و جوی دیگر فعال است",
"errorNotChannel": "ابتدا باید در یک چنل جوین شوید!",
"resultEmbedTitle": "**عدد آهنگ مورد نظر را ریپلای کنید**",
"resultEmbedDesc": "نتیجه ی جست و جو: {search}"
},
"shuffle": {
"description": "شافل",
"errorNotQueue": "چیزی در حال پخش نیست",
"result": "<@{author}> 🔀 لیست را شافل کرد"
},
"skip": {
"description": "اسکیپ آهنگ فعلی",
"errorNotQueue": "چیزی در حال پخش نیست",
"result": "<@{author}> ⏭ آهنگ را اسکیپ کرد"
},
"skipto": {
"description": "آهنگ را اسکیپ کرد",
"usageReply": "استفاده: {prefix}{name} <Queue Number>",
"errorNotQueue": "چیزی در حال پخش نیست",
"errorNotValid": "صف شامل {length} آهنگ است",
"result": "<@{author}> ⏭ skipped {arg} songs"
},
"stop": {
"description": "متوقف کردن آهنگ",
"errorNotQueue": "چیزی در حال پخش نیست",
"result": "<@{author}> ⏹ آهنگ را متوقف کرد!"
},
"uptime": {
"description": "چک کردن آپ تایم",
"result": "آپ تایم: `{days} روز,{hours} ساعت, {minutes} دقیقه, {seconds} ثانیه`"
},
"volume": {
"description": "تغییر صدای آهنگ در حال پخش",
"errorNotQueue": "چیزی در حال پخش نیست",
"errorNotChannel": "ابتدا باید در یک چنل جوین شوید!",
"currentVolume": "🔊 صدای فعلی: **{volume}%**",
"errorNotNumber": "یک عدد برای صدای آهنگ انتخاب کنید.",
"errorNotValid": "یک عدد بین 0-100 انتخاب کنید.",
"result": "صدای آهنگ: **{arg}%**"
},
"common": {
"on": "**روشن**",
"off": "**خاموش**",
"enabled": "**فعال**",
"disabled": "**غیر فعال**",
"errorNotChannel": "ابتدا باید در یک چنل جوین شوید!",
"cooldownMessage": "لطفا {time} ثانه صبر کنید.",
"errorCommand": "مشکلی به وجود آمد."
}
}
+180
View File
@@ -0,0 +1,180 @@
{
"clip": {
"description": "Joue un extrait sonore",
"usagesReply": "Utilisation : {prefix}clip <nom>",
"errorQueue": "Impossible de jouer l'extrait car il y a une file d'attente active.",
"errorNotChannel": "Vous devez rejoindre un salon vocal d'abord !"
},
"clips": {
"description": "Liste tous les extraits"
},
"help": {
"description": "Affiche toutes les commandes et leurs descriptions",
"embedTitle": "Aide de {botname}",
"embedDescription": "Liste de toutes les commandes"
},
"invite": {
"description": "Envoyer le lien d'invitation du bot"
},
"loop": {
"description": "Activer/désactiver la boucle de la musique",
"errorNotQueue": "Rien n'est en train de jouer.",
"result": "La boucle est maintenant {loop}"
},
"lyrics": {
"description": "Obtenir les paroles de la chanson en cours de lecture",
"errorNotQueue": "Rien n'est en train de jouer.",
"lyricsNotFound": "Aucune paroles trouvées pour {title}.",
"embedTitle": "{title} - Paroles"
},
"move": {
"description": "Déplacer des chansons dans la file d'attente",
"errorNotQueue": "Il n'y a pas de file d'attente.",
"usagesReply": "Utilisation : {prefix}move <Numéro de file d'attente>",
"result": "<@{author}> 🚚 a déplacé **{title}** à la position {index} dans la file d'attente.",
"args": {
"movefrom": "Position de départ",
"moveto": "Position de destination"
}
},
"nowplaying": {
"description": "Afficher la chanson en cours de lecture",
"errorNotQueue": "Rien n'est en train de jouer.",
"embedTitle": "En train de jouer",
"live": " ◉ EN DIRECT",
"timeRemaining": "Temps restant : {time}"
},
"pause": {
"description": "Met en pause la musique en cours de lecture",
"errorNotQueue": "Rien n'est en train de jouer.",
"result": "<@{author}> ⏸ a mis la musique en pause."
},
"ping": {
"description": "Afficher la moyenne de ping du bot",
"result": "📈 Ping moyen vers l'API : {ping} ms"
},
"play": {
"description": "Joue de l'audio depuis YouTube",
"errorNotChannel": "Vous devez rejoindre un salon vocal d'abord !",
"errorNotInSameChannel": "Vous devez être dans le même salon que {user}",
"usageReply": "Utilisation : {prefix}play <URL YouTube | Nom de la vidéo>",
"missingPermissionConnect": "Impossible de se connecter au salon vocal, permissions manquantes",
"missingPermissionSpeak": "Je ne peux pas parler dans ce salon vocal, assurez-vous que j'ai les permissions nécessaires !",
"queueAdded": "✅ **{title}** a été ajouté à la file d'attente par <@{author}>",
"cantJoinChannel": "Impossible de rejoindre le salon : {error}",
"queueEnded": "❌ File d'attente de musique terminée.",
"queueError": "Erreur : {error}",
"startedPlaying": "🎶 Lecture en cours : **{title}** {url}",
"skipSong": "<@{author}> ⏩ a passé la chanson",
"pauseSong": "<@{author}> ⏸ a mis la musique en pause.",
"resumeSong": "<@{author}> ▶ a repris la musique !",
"unmutedSong": "<@{author}> 🔊 a réactivé le son de la musique !",
"mutedSong": "<@{author}> 🔇 a coupé le son de la musique !",
"decreasedVolume": "<@{author}> 🔉 a réduit le volume, le volume est maintenant de {volume}%",
"increasedVolume": "<@{author}> 🔊 a augmenté le volume, le volume est maintenant de {volume}%",
"loopSong": "<@{author}> La boucle est maintenant {loop}",
"stopSong": "<@{author}> ⏹ a arrêté la musique !",
"leaveChannel": "Quitte le salon vocal...",
"songNotFound": "Audio non trouvé",
"songAccessErr": "La vidéo est restreinte par l'âge, privée ou indisponible",
"errorNoResults": "Aucun résultat trouvé pour {url}",
"errorInvalidURL": "URL invalide, veuillez essayer une recherche ou une URL YouTube"
},
"playlist": {
"description": "Joue une liste de lecture depuis YouTube",
"usagesReply": "Utilisation : {prefix}playlist <URL de la liste de lecture YouTube | Nom de la liste de lecture>",
"errorNotChannel": "Vous devez rejoindre un salon vocal d'abord !",
"errorNotInSameChannel": "Vous devez être dans le même salon que {user}",
"missingPermissionConnect": "Impossible de se connecter au salon vocal, permissions manquantes",
"missingPermissionSpeak": "Je ne peux pas parler dans ce salon vocal, assurez-vous que j'ai les permissions nécessaires !",
"errorNotFoundPlaylist": "Liste de lecture introuvable :(",
"fetchingPlaylist": "⌛ Récupération de la liste de lecture...",
"playlistCharLimit": "\nListe de lecture plus longue que la limite de caractères...",
"startedPlaylist": "<@{author}> a lancé une liste de lecture",
"cantJoinChannel": "Impossible de rejoindre le salon : {error}"
},
"pruning": {
"description": "Activer/désactiver la suppression des messages du bot",
"errorWritingFile": "Une erreur s'est produite lors de l'écriture dans le fichier.",
"result": "La suppression des messages est {result}"
},
"queue": {
"description": "Afficher la file d'attente de musique et la chanson en cours de lecture.",
"missingPermissionMessage": "Permission manquante pour gérer les messages ou ajouter des réactions",
"errorNotQueue": "❌ **Rien ne joue dans ce serveur**",
"currentPage": "Page actuelle - ",
"embedTitle": "File d'attente de chansons\n",
"embedCurrentSong": "**Chanson en cours - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Retirer une chanson de la file d'attente",
"errorNotQueue": "Il n'y a pas de file d'attente.",
"usageReply": "Utilisation : {prefix}remove <Numéro de file d'attente>",
"result": "<@{author}> ❌ a retiré **{title}** de la file d'attente."
},
"resume": {
"description": "Reprendre la lecture de la musique en cours",
"errorNotQueue": "Rien n'est en train de jouer.",
"resultNotPlaying": "<@{author}> ▶ a repris la musique !",
"errorPlaying": "La file d'attente n'est pas en pause."
},
"search": {
"description": "Rechercher et sélectionner des vidéos à lire",
"usageReply": "Utilisation : {prefix}{name} <Nom de la vidéo>",
"errorAlreadyCollector": "Un collecteur de messages est déjà actif dans ce canal.",
"errorNotChannel": "Vous devez rejoindre un salon vocal d'abord !",
"resultEmbedTitle": "**Répondez avec le numéro de la chanson que vous voulez jouer**",
"resultEmbedDesc": "Résultats pour : {search}",
"optionQuery": "Requête de recherche",
"noResults": "Aucun résultat pour la requête, veuillez essayer autre chose"
},
"shuffle": {
"description": "Mélanger la file d'attente",
"errorNotQueue": "Il n'y a pas de file d'attente.",
"result": "<@{author}> 🔀 a mélangé la file d'attente"
},
"skip": {
"description": "Passer la chanson en cours de lecture",
"errorNotQueue": "Rien n'est en train de jouer que je pourrais passer pour vous.",
"result": "<@{author}> ⏭ a passé la chanson"
},
"skipto": {
"description": "Passer au numéro de file d'attente sélectionné",
"usageReply": "Utilisation : {prefix}{name} <Numéro de file d'attente>",
"errorNotQueue": "Il n'y a pas de file d'attente.",
"errorNotValid": "La file d'attente ne comporte que {length} chansons !",
"result": "<@{author}> ⏭ a sauté {arg} chansons",
"args": {
"number": "Le numéro de file d'attente à sauter vers"
}
},
"stop": {
"description": "Arrêter la musique",
"errorNotQueue": "Rien n'est en train de jouer.",
"result": "<@{author}> ⏹ a arrêté la musique !"
},
"uptime": {
"description": "Vérifier le temps d'activité",
"result": "Temps d'activité : `{days} jour(s), {hours} heures, {minutes} minutes, {seconds} secondes`"
},
"volume": {
"description": "Changer le volume de la musique en cours de lecture",
"errorNotQueue": "Rien n'est en train de jouer.",
"errorNotChannel": "Vous devez rejoindre un salon vocal d'abord !",
"currentVolume": "🔊 Le volume actuel est de : **{volume}%**",
"errorNotNumber": "Veuillez utiliser un nombre pour régler le volume.",
"errorNotValid": "Veuillez utiliser un nombre entre 0 et 100.",
"result": "Volume réglé à : **{arg}%**"
},
"common": {
"on": "**activé**",
"off": "**désactivé**",
"enabled": "**activé**",
"disabled": "**désactivé**",
"errorNotChannel": "Vous devez rejoindre un salon vocal d'abord !",
"cooldownMessage": "Veuillez patienter {time} seconde(s) de plus avant de réutiliser la commande `{name}`.",
"errorCommand": "Une erreur s'est produite lors de l'exécution de cette commande."
},
"Invitez-moi sur votre serveur !": "Invitez-moi sur votre serveur !",
"Inviter": "Inviter"
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Memutar suara klip",
"usagesReply": "Penggunaan: {prefix}clip <nama klip>",
"errorQueue": "Tidak dapat memutar klip karena ada antrian yang sedang aktif.",
"errorNotChannel": "Kamu harus bergabung dengan saluran suara terlebih dahulu!"
},
"clips": {
"description": "Daftar semua klip"
},
"help": {
"description": "Menampilkan semua perintah dan deskripsi",
"embedTitle": "{botname} Bantuan",
"embedDescription": "Daftar semua perintah"
},
"invite": {
"description": "Mengirim tautan undangan bot"
},
"loop": {
"description": "Mengatur ulang musik (Loop)",
"errorNotQueue": "Tidak ada musik yang dimainkan.",
"result": "Putaran sekarang adalah {loop}"
},
"lyrics": {
"description": "Dapatkan lirik untuk lagu yang sedang diputar",
"errorNotQueue": "Tidak ada musik yang dimainkan.",
"lyricsNotFound": "Tidak ada lirik yang ditemukan untuk lagu {title}.",
"embedTitle": "Lirik lagu - {title}"
},
"move": {
"description": "Memindahkan lagu ke dalam antrian",
"errorNotQueue": "Tidak ada antrian.",
"usagesReply": "Penggunaan: {prefix}move <Nomor Antrian>",
"result": "<@{author}> 🚚 memindahkan **{title}** ke {index} untuk masuk ke dalam antrian."
},
"nowplaying": {
"description": "Menampilkan lagu yang sedang diputar",
"errorNotQueue": "Tidak ada musik yang dimainkan.",
"embedTitle": "Sedang memainkan",
"live": " ◉ LANGSUNG",
"timeRemaining": "Waktu yang tersisa: {time}"
},
"pause": {
"description": "Menjeda musik yang sedang diputar",
"errorNotQueue": "Tidak ada musik yang dimainkan.",
"result": "<@{author}> ⏸ Menjeda musik."
},
"ping": {
"description": "Menampilkan ping rata-rata bot",
"result": "📈 Ping rata-rata ke API: {ping} ms"
},
"play": {
"description": "Memutar audio dari YouTube atau Soundcloud",
"errorNotChannel": "Kamu harus bergabung dengan saluran suara terlebih dahulu!",
"errorNotInSameChannel": "Kamu harus berada di saluran yang sama dengan {user}",
"usageReply": "Penggunaan: {prefix}play <YouTube URL | Nama Video | Soundcloud URL>",
"missingPermissionConnect": "Tidak dapat terhubung ke saluran suara, karena tidak diberikan izin",
"missingPermissionSpeak": "Saya tidak dapat berbicara di saluran suara ini, pastikan saya sudah diberikan izin!",
"queueAdded": "✅ **{title}** telah ditambahkan ke antrian oleh <@{author}>",
"cantJoinChannel": "Tidak dapat bergabung ke saluran: {error}",
"queueEnded": "❌ Antrian musik berakhir.",
"queueError": "Terjadi kesalahan: {error}",
"startedPlaying": "🎶 Mulai memutar: **{title}** {url}",
"skipSong": "<@{author}> ⏩ melewatkan lagu",
"pauseSong": "<@{author}> ⏸ menjeda lagu.",
"resumeSong": "<@{author}> ▶ melanjutkan memutar lagu!",
"unmutedSong": "<@{author}> 🔊 mengaktifkan suara musik!",
"mutedSong": "<@{author}> 🔇 meredam suara musik!",
"decreasedVolume": "<@{author}> 🔉 menurunkan volume, volume lagu sekarang {volume}%",
"increasedVolume": "<@{author}> 🔊 meningkatkan volume, volume lagu sekarang {volume}%",
"loopSong": "<@{author}> Memutar ulang lagu {loop}",
"stopSong": "<@{author}> ⏹ Menghentikan musik!",
"leaveChannel": "Keluar dari saluran suara...",
"songNotFound": "Audio Tidak Ditemukan",
"songAccessErr": "Video dibatasi usia, pribadi atau tidak tersedia"
},
"playlist": {
"description": "Memutar playlist dari youtube",
"usagesReply": "Penggunaan: {prefix}playlist <YouTube Playlist URL | Nama Playlist>",
"errorNotChannel": "Kamu harus bergabung dengan saluran suara terlebih dahulu!",
"errorNotInSameChannel": "Kamu harus berada di saluran yang sama dengan {user}",
"missingPermissionConnect": "tidak dapat terhubung ke saluran suara, karena tidak diberi izin",
"missingPermissionSpeak": "Saya tidak dapat berbicara di saluran suara ini, pastikan saya sudah diberikan izin!",
"errorNotFoundPlaylist": "Playlist tidak ditemukan :(",
"fetchingPlaylist": "⌛ mengambil playlist...",
"playlistCharLimit": "\nPlaylist melebihi dari batas karakter...",
"startedPlaylist": "<@{author}> Memulai playlist musik",
"cantJoinChannel": "Tidak dapat bergabung ke saluran: {error}"
},
"pruning": {
"description": "Mengalihkan pemangkasan pesan bot",
"errorWritingFile": "Terjadi kesalahan saat menulis ke dalam file.",
"result": "Pesan pemangkasan adalah {result}"
},
"queue": {
"description": "Menampilkan antrian musik dan yang sedang diputar",
"missingPermissionMessage": "Tidak ada izin untuk mengelola pesan atau menambahkan emoji",
"errorNotQueue": "❌ **Tidak ada yang diputar di server ini**",
"currentPage": "Halaman saat ini - ",
"embedTitle": "Antrian Lagu\n",
"embedCurrentSong": "**Lagu saat ini - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Menghapus lagu dari antrian",
"errorNotQueue": "Tidak ada antrian.",
"usageReply": "Penggunaan: {prefix}remove <Nomor Antrian>",
"result": "<@{author}> ❌ menghapus **{title}** dari antrian lagu."
},
"resume": {
"description": "Melanjutkan memutar musik saat ini",
"errorNotQueue": "Tidak ada musik yang dimainkan.",
"resultNotPlaying": "<@{author}> ▶ melanjutkan memutar musik!",
"errorPlaying": "Antrian tidak dijeda."
},
"search": {
"description": "Cari dan pilih video untuk diputar",
"usageReply": "Penggunaan: {prefix}{name} <Nama Video>",
"errorAlreadyCollector": "Kolektor pesan sudah aktif di saluran ini.",
"errorNotChannel": "Kamu harus bergabung dengan saluran suara terlebih dahulu!",
"resultEmbedTitle": "**Balas dengan nomor lagu yang ingin kamu putar**",
"resultEmbedDesc": "Hasil untuk: {search}"
},
"shuffle": {
"description": "Mengacak antrian musik",
"errorNotQueue": "Tidak ada antrian.",
"result": "<@{author}> 🔀 telah mengacak antrian"
},
"skip": {
"description": "Melewati lagu yang sedang diputar",
"errorNotQueue": "Tidak ada musik yang sedang diputar untuk di lewati.",
"result": "<@{author}> ⏭ telah melewatkan lagu"
},
"skipto": {
"description": "Lewati ke nomor antrian yang dipilih",
"usageReply": "Penggunaan: {prefix}{name} <Nomor Antrian>",
"errorNotQueue": "Tidak ada antrian.",
"errorNotValid": "Hanya terdapat {length} antrian lagu!",
"result": "<@{author}> ⏭ telah melewatkan {arg} lagu"
},
"stop": {
"description": "Menghentikan pemutaran musik",
"errorNotQueue": "Tidak ada musik yang dimainkan.",
"result": "<@{author}> ⏹ telah menghentikan musik!"
},
"uptime": {
"description": "Melihat waktu aktif (Uptime)",
"result": "Waktu aktif: `{days} Hari, {hours} Jam, {minutes} Menit, {seconds} Detik`"
},
"volume": {
"description": "Mengubah volume musik yang sedang diputar",
"errorNotQueue": "Tidak ada musik yang dimainkan.",
"errorNotChannel": "Kamu harus bergabung dengan saluran suara terlebih dahulu!",
"currentVolume": "🔊 Volume saat ini adalah: **{volume}%**",
"errorNotNumber": "Silakan gunakan nomor untuk mengatur volume.",
"errorNotValid": "Silakan gunakan nomor diantara 0 sampai 100.",
"result": "Volume disetel ke: **{arg}%**"
},
"common": {
"on": "**nyala**",
"off": "**mati**",
"enabled": "**diaktifkan**",
"disabled": "**dinonaktifkan**",
"errorNotChannel": "Kamu harus bergabung dengan saluran suara terlebih dahulu!",
"cooldownMessage": "Mohon tunggu {time} lagi sebelum menggunakan perintah `{name}` ini kembali.",
"errorCommand": "Terjadi kesalahan saat menjalankan perintah ini."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Riproduce una clip audio",
"usagesReply": "Utilizzo: {prefix}clip <nome>",
"errorQueue": "Impossibile riprodurre la clip perché è presente una coda attiva.",
"errorNotChannel": "Devi prima entrare in un canale vocale!"
},
"clips": {
"description": "Elenca tutte le clip"
},
"help": {
"description": "Visualizza tutti i comandi e le descrizioni",
"embedTitle": "Aiuto di {botname}",
"embedDescription": "Elenco di tutti i comandi"
},
"invite": {
"description": "Invia link di invito del bot"
},
"loop": {
"description": "Attiva / disattiva loop brano",
"errorNotQueue": "Non c'è niente in riproduzione.",
"result": "Il loop è ora {loop}"
},
"lyrics": {
"description": "Ottieni il testo per il brano attualmente in riproduzione",
"errorNotQueue": "Non c'è niente in riproduzione.",
"lyricsNotFound": "Nessun testo trovato per {title}.",
"embedTitle": "{title} - Testo"
},
"move": {
"description": "Sposta il brano nella coda",
"errorNotQueue": "Non c'è nessuna coda attiva.",
"usagesReply": "Utilizzo: {prefix}move <Numero in Coda>",
"result": "<@{author}> 🚚 ha spostato **{title}** a {index} nella coda."
},
"nowplaying": {
"description": "Mostra il brano in riproduzione",
"errorNotQueue": "Non c'è niente in riproduzione.",
"embedTitle": "Ora in riproduzione",
"live": " ◉ IN DIRETTA",
"timeRemaining": "Tempo rimanente: {time}"
},
"pause": {
"description": "Mette in pausa il brano attualmente in riproduzione",
"errorNotQueue": "Non c'è niente in riproduzione.",
"result": "<@{author}> ⏸ ha messo in pausa il brano."
},
"ping": {
"description": "Mostra il ping medio del bot",
"result": "📈 Ping medio all'API: {ping} ms"
},
"play": {
"description": "Riproduce un brano da YouTube o Soundcloud",
"errorNotChannel": "Devi prima entrare in un canale vocale!",
"errorNotInSameChannel": "Devi essere nello stesso canale di {user}",
"usageReply": "Utilizzo: {prefix}play <URL video di YouTube | Nome video | URL di Soundcloud>",
"missingPermissionConnect": "Non posso connettermi al canale vocale, permessi mancanti",
"missingPermissionSpeak": "Non posso parlare in questo canale vocale, assicurati di avermi dato i permessi appropriati!",
"queueAdded": "✅ **{title}** è stato aggiunto nella coda da <@{author}>",
"cantJoinChannel": "Non posso connettermi al canale: {error}",
"queueEnded": "❌ Coda di riproduzione terminata.",
"queueError": "Errore: {error}",
"startedPlaying": "🎶 Iniziata riproduzione: **{title}** {url}",
"skipSong": "<@{author}> ⏩ ha saltato il brano",
"pauseSong": "<@{author}> ⏸ ha messo in pausa la riproduzione.",
"resumeSong": "<@{author}> ▶ ha ripreso la riproduzione!",
"unmutedSong": "<@{author}> 🔊 ha smutato la riproduzione!",
"mutedSong": "<@{author}> 🔇 ha mutato la riproduzione!",
"decreasedVolume": "<@{author}> 🔉 ha abbassato il volume, il volume è ora al {volume}%",
"increasedVolume": "<@{author}> 🔊 ha aumentato il volume, il volume è ora al {volume}%",
"loopSong": "<@{author}> Il loop è ora {loop}",
"stopSong": "<@{author}> ⏹ ha fermato la riproduzione!",
"leaveChannel": "Esco dal canale vocale...",
"songNotFound": "Brano non trovato",
"songAccessErr": "Video is age restricted, private or unavailable"
},
"playlist": {
"description": "Riproduce una playlist da YouTube",
"usagesReply": "Utilizzo: {prefix}playlist <URL Playlist di YouTube | Nome Playlist>",
"errorNotChannel": "Devi prima entrare in un canale vocale!",
"errorNotInSameChannel": "Devi essere nello stesso canale di {user}",
"missingPermissionConnect": "Non posso connettermi al canale vocale, permessi mancanti",
"missingPermissionSpeak": "Non posso parlare in questo canale vocale, assicurati di avermi dato i permessi appropriati!",
"errorNotFoundPlaylist": "Playlist non trovata :(",
"fetchingPlaylist": "⌛ recupero info della playlist...",
"playlistCharLimit": "\nPlaylist maggiore del limite di caratteri...",
"startedPlaylist": "<@{author}> Ha avviato una playlist",
"cantJoinChannel": "Non posso connettermi al canale: {error}"
},
"pruning": {
"description": "Attiva o disattiva l'eliminazione dei messaggi dei bot",
"errorWritingFile": "Si è verificato un errore durante la scrittura del file.",
"result": "L'eliminazione dei messaggi è {result}"
},
"queue": {
"description": "Mostra la coda di riproduzione e il brano in corso.",
"missingPermissionMessage": "Manca il permesso per gestire i messaggi o aggiungere reazioni",
"errorNotQueue": "❌ **Non c'è niente in riproduzione in questo server**",
"currentPage": "Pagina corrente - ",
"embedTitle": "Coda di riproduzione\n",
"embedCurrentSong": "**Brano corrente - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Rimuovi brano dalla coda",
"errorNotQueue": "Non c'è nessuna coda attiva.",
"usageReply": "Utilizzo: {prefix}remove <Numero in Coda>",
"result": "<@{author}> ❌ ha rimosso **{title}** dalla coda."
},
"resume": {
"description": "Riprendi la riproduzione del brano",
"errorNotQueue": "Non c'è niente in riproduzione.",
"resultNotPlaying": "<@{author}> ▶ ha ripreso la riproduzione!",
"errorPlaying": "La coda non è in pausa."
},
"search": {
"description": "Cerca e seleziona i video da riprodurre",
"usageReply": "Usage: {prefix}{name} <Nome Video>",
"errorAlreadyCollector": "Un raccoglitore di messaggi è già attivo in questo canale.",
"errorNotChannel": "Devi prima entrare in un canale vocale!",
"resultEmbedTitle": "**Rispondi con il numero del brano che desideri riprodurre**",
"resultEmbedDesc": "Risultati per: {search}"
},
"shuffle": {
"description": "Coda mischiata",
"errorNotQueue": "Non c'è nessuna coda attiva.",
"result": "<@{author}> 🔀 ha mischiato la coda"
},
"skip": {
"description": "Salta il brano attualmente in riproduzione",
"errorNotQueue": "Non c'è niente che io possa saltare per te.",
"result": "<@{author}> ⏭ ha saltato il brano"
},
"skipto": {
"description": "Passa al numero di coda selezionato",
"usageReply": "Utilizzo: {prefix}{name} <Numero in Coda>",
"errorNotQueue": "Non c'è nessuna coda attiva.",
"errorNotValid": "La coda è lunga solo {length} brani!",
"result": "<@{author}> ⏭ ha saltato {arg} brani"
},
"stop": {
"description": "Ferma la riproduzione",
"errorNotQueue": "Non c'è niente in riproduzione.",
"result": "<@{author}> ⏹ ha fermato la riproduzione!"
},
"uptime": {
"description": "Controlla il tempo di attività",
"result": "Tempo di attività: `{days} giorno(i), {hours} ora(e), {minutes} minuto(i), {seconds} secondo(i)`"
},
"volume": {
"description": "Cambia il volume del brano attualmente in riproduzione",
"errorNotQueue": "Non c'è niente in riproduzione.",
"errorNotChannel": "Devi prima entrare in un canale vocale!",
"currentVolume": "🔊 Il volume attuale è: **{volume}%**",
"errorNotNumber": "Utilizzare un numero per impostare il volume.",
"errorNotValid": "Si prega di utilizzare un numero compreso tra 0 e 100.",
"result": "Volume impostato su: **{arg}%**"
},
"common": {
"on": "**acceso**",
"off": "**spento**",
"enabled": "**abilitato**",
"disabled": "**disabilitato**",
"errorNotChannel": "Devi prima entrare in un canale vocale!",
"cooldownMessage": "attendi {time} secondo(i) prima di riutilizzare il comando `{name}`.",
"errorCommand": "Si è verificato un errore durante l'esecuzione del comando."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "クリップ音声の再生",
"usagesReply": "使い方: {prefix}clip <名>",
"errorQueue": "キューが残っているためクリップ音声を再生出来ません",
"errorNotChannel": "先にボイスチャンネルに参加してください!"
},
"clips": {
"description": "クリップ音声の一覧"
},
"help": {
"description": "すべてのコマンドと詳細を表示",
"embedTitle": "{botname} ヘルプ",
"embedDescription": "すべてのコマンドの一覧"
},
"invite": {
"description": "Bot の招待リンクを送信"
},
"loop": {
"description": "ループの切り替え",
"errorNotQueue": "何も再生していません。",
"result": "ループが今すぐ {loop}"
},
"lyrics": {
"description": "現在再生している曲の歌詞を取得",
"errorNotQueue": "何も再生していません。",
"lyricsNotFound": "{title} の歌詞が見つかりません。",
"embedTitle": "{title} - 歌詞"
},
"move": {
"description": "キューにある曲を移動",
"errorNotQueue": "キューに何も入っていません。",
"usagesReply": "使い方: {prefix}move <キュー番号>",
"result": "<@{author}> が **{title}** をキューの {index} 個目に移動 🚚 しました。"
},
"nowplaying": {
"description": "再生中の曲を表示",
"errorNotQueue": "何も再生していません。",
"embedTitle": "再生中",
"live": " ◉ ライブ",
"timeRemaining": "残り: {time}"
},
"pause": {
"description": "再生中の曲を一時停止",
"errorNotQueue": "何も再生していません。",
"result": "<@{author}> が一時停止 ⏸ しました。"
},
"ping": {
"description": "この Bot の平均 ping 値を表示",
"result": "📈 API に対する平均 ping 値: {ping} ms"
},
"play": {
"description": "YouTube または Soundcloud から音楽を再生",
"errorNotChannel": "先にボイスチャンネルに参加してください!",
"errorNotInSameChannel": "{user} さんと同じチャンネルにいる必要があります",
"usageReply": "使い方: {prefix}play <YouTube URL | 名前 | Soundcloud URL>",
"missingPermissionConnect": "ボイスチャンネルに接続出来ません、権限が不足しています",
"missingPermissionSpeak": "このボイスチャンネルで音を発することが出来ません、権限が適切かどうか確認してください!",
"queueAdded": "✅ <@{author}> が **{title}** をキューに追加しました",
"cantJoinChannel": "チャンネルに参加出来ません: {error}",
"queueEnded": "❌ キューを最後まで再生しました。",
"queueError": "エラー: {error}",
"startedPlaying": "🎶 再生中: **{title}** {url}",
"skipSong": "<@{author}> が ⏩ スキップしました",
"pauseSong": "<@{author}> が ⏸ 一時停止しました",
"resumeSong": "<@{author}> が ▶ 再開しました!",
"unmutedSong": "<@{author}> が 🔊 ミュート解除しました!",
"mutedSong": "<@{author}> が 🔇 ミュートしました!",
"decreasedVolume": "<@{author}> が 🔉 ボリュームを下げました、現在 {volume}%",
"increasedVolume": "<@{author}> が 🔊 ボリュームをあげました、現在 {volume}%",
"loopSong": "<@{author}> がループ再生を {loop} にしました",
"stopSong": "<@{author}> が ⏹ 停止しました!",
"leaveChannel": "ボイスチャンネルを退出します",
"songNotFound": "音声が見つかりません",
"songAccessErr": "動画は年齢制限あり、非公開、または利用できません"
},
"playlist": {
"description": "YouTube プレイリストから再生",
"usagesReply": "使い方: {prefix}playlist <YouTube Playlist URL | プレイリスト名>",
"errorNotChannel": "先にボイスチャンネルに参加してください!",
"errorNotInSameChannel": "{user} さんと同じチャンネルにいる必要があります",
"missingPermissionConnect": "ボイスチャンネルに接続出来ません、権限が不足しています",
"missingPermissionSpeak": "このボイスチャンネルで音を発することが出来ません、権限が適切かどうか確認してください!",
"errorNotFoundPlaylist": "プレイリストが存在しません :(",
"fetchingPlaylist": "⌛ プレイリストを取得しています...",
"playlistCharLimit": "\nプレイリストが文字数制限を超えています...",
"startedPlaylist": "<@{author}> がプレイリストを再生しています",
"cantJoinChannel": "チャンネルに参加出来ません: {error}"
},
"pruning": {
"description": "Bot からのメッセージを取り除くか切り替え",
"errorWritingFile": "ファイル書き込み時にエラーが発生しました。",
"result": "メッセージのプルーニングは {result}"
},
"queue": {
"description": "キューと再生中の曲を表示",
"missingPermissionMessage": "manage messages および add reactions の権限が不足しています",
"errorNotQueue": "❌ **何も再生していません**",
"currentPage": "現在のページ - ",
"embedTitle": "曲のキュー\n",
"embedCurrentSong": "**再生中 - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "キューにある曲を削除",
"errorNotQueue": "キューに何も入っていません。",
"usageReply": "使い方: {prefix}remove <キュー番号>",
"result": "<@{author}> がキューから **{title}** を ❌ 削除しました。"
},
"resume": {
"description": "再生中の曲を再開",
"errorNotQueue": "何も再生していません。",
"resultNotPlaying": "<@{author}> が曲を ▶ 再開しました!",
"errorPlaying": "キューは一時停止していません。"
},
"search": {
"description": "曲を検索して再生",
"usageReply": "使い方: {prefix}{name} <ビデオ名>",
"errorAlreadyCollector": "このチャンネルにはすでにメッセージコレクターが存在しています。",
"errorNotChannel": "先にボイスチャンネルに参加してください!",
"resultEmbedTitle": "**再生したい曲の番号を返信してください**",
"resultEmbedDesc": "検索結果: {search}"
},
"shuffle": {
"description": "キューをシャッフル",
"errorNotQueue": "キューに何も入っていません。",
"result": "<@{author}> が 🔀 シャッフルしました"
},
"skip": {
"description": "再生中の曲をスキップ",
"errorNotQueue": "スキップする曲がありません。",
"result": "<@{author}> が ⏭ スキップしました"
},
"skipto": {
"description": "指定した番号の曲をスキップ",
"usageReply": "使い方: {prefix}{name} <キュー番号>",
"errorNotQueue": "キューに何も入っていません。",
"errorNotValid": "キューには {length} 曲しか入っていません!",
"result": "<@{author}> が {arg} 曲 ⏭ スキップしました"
},
"stop": {
"description": "曲を停止",
"errorNotQueue": "何も再生していません。",
"result": "<@{author}> が ⏹ 停止しました!"
},
"uptime": {
"description": "稼働時間を確認",
"result": "稼働時間: `{days} 日 {hours} 時間 {minutes} 分 {seconds} 秒`"
},
"volume": {
"description": "再生中の曲のボリュームを変更",
"errorNotQueue": "何も再生していません。",
"errorNotChannel": "先にボイスチャンネルに参加してください!",
"currentVolume": "🔊 現在のボリューム: **{volume}%**",
"errorNotNumber": "音量は数字で指定してください。",
"errorNotValid": "数字は 0 - 100 の間で指定してください。",
"result": "ボリュームを設定: **{arg}%**"
},
"common": {
"on": "**オン**",
"off": "**オフ**",
"enabled": "**有効**",
"disabled": "**無効**",
"errorNotChannel": "先にボイスチャンネルに参加してください!",
"cooldownMessage": "`{name}` コマンドの実行中のため、あと {time} 秒お待ち下さい。",
"errorCommand": "コマンド実行時にエラーが発生しました。"
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "주어진 클립을 재생합니다.",
"usagesReply": "사용 방법: {prefix}clip <name>",
"errorQueue": "대기열에 음악이 있을 경우 클립을 재생할 수 없습니다.",
"errorNotChannel": "음성 채널에 들어와 있지 않습니다."
},
"clips": {
"description": "모든 클립을 재생합니다."
},
"help": {
"description": "모든 명령어와 설명을 표시합니다.",
"embedTitle": "{botname} 도움말",
"embedDescription": "명령어 리스트"
},
"invite": {
"description": "봇에 대한 초대 링크를 생성합니다."
},
"loop": {
"description": "음악 반복을 실행/해제 합니다.",
"errorNotQueue": "재생할 음악이 없습니다.",
"result": "음악 반복 상태: {loop}"
},
"lyrics": {
"description": "현재 재생중인 음악의 가사를 가져옵니다.",
"errorNotQueue": "재생할 음악이 없습니다.",
"lyricsNotFound": "{title} 에 대한 가사를 찾을 수 없습니다.",
"embedTitle": "{title} 가사"
},
"move": {
"description": "대기열에서 음악을 이동합니다.",
"errorNotQueue": "대기열에 음악이 없습니다.",
"usagesReply": "사용 방법: {prefix}move <Queue Number>",
"result": "<@{author}> 🚚 **{title}** 를 대기열에서 {index}번째로 옮겼습니다."
},
"nowplaying": {
"description": "현재 재생중인 음악을 표시합니다.",
"errorNotQueue": "재생할 음악이 없습니다.",
"embedTitle": "현재 재생중",
"live": " ◉ 스트리밍",
"timeRemaining": "남은 재생시간은 {time} 입니다."
},
"pause": {
"description": "현재 재생중인 음악을 일시 중지합니다.",
"errorNotQueue": "재생할 음악이 없습니다.",
"result": "<@{author}> ⏸ 음악을 일시 중지했습니다."
},
"ping": {
"description": "봇의 평균 핑 수치를 보여줍니다.",
"result": "📈 현재 평균 핑 수치는 {ping} ms 입니다."
},
"play": {
"description": "YouTube 또는 Soundcloud 부터 음악을 재생합니다.",
"errorNotChannel": "음성 채널에 들어와 있지 않습니다.",
"errorNotInSameChannel": "{user} 와 같은 음성 채널에 들어와 있어야 합니다.",
"usageReply": "사용 방법: {prefix}play <YouTube URL | Video Name | Soundcloud URL>",
"missingPermissionConnect": "음성 채널에 들어갈 수 없습니다. 권한을 확인해 주세요.",
"missingPermissionSpeak": "음성 채널에서 말할 수 없습니다. 권한을 확인해 주세요.",
"queueAdded": "✅ **{title}** 가 <@{author}>에 의해 대기열에 추가되었습니다.",
"cantJoinChannel": "채널에 진입할 수 없습니다.: {error}",
"queueEnded": "❌ 모든 대기열 재생을 완료했습니다.",
"queueError": "에러가 발생했습니다.: {error}",
"startedPlaying": "🎶 **{title}** 재생을 시작합니다. {url}",
"skipSong": "<@{author}> ⏩ 음악을 넘겼습니다.",
"pauseSong": "<@{author}> ⏸ 음악을 일시중지 했습니다.",
"resumeSong": "<@{author}> ▶ 음악을 재개했습니다.",
"unmutedSong": "<@{author}> 🔊 음소거를 해제했습니다.",
"mutedSong": "<@{author}> 🔇 음악을 음소거 했습니다.",
"decreasedVolume": "<@{author}> 🔉 볼륨을 낮추어, 현재 {volume}% 로 설정되어 있습니다.",
"increasedVolume": "<@{author}> 🔊 볼륨을 높여, 현재 {volume}% 로 설정되어 있습니다",
"loopSong": "<@{author}> 음악 반복 상태: {loop}",
"stopSong": "<@{author}> ⏹ 음악을 중지했습니다.",
"leaveChannel": "채널을 떠나는 중입니다.",
"songNotFound": "오디오를 찾을 수 없음",
"songAccessErr": "동영상에 연령 제한이 있거나 비공개이거나 사용할 수 없습니다."
},
"playlist": {
"description": "Youtube 부터 재생목록을 재생합니다.",
"usagesReply": "사용 방법: {prefix}playlist <YouTube Playlist URL | Playlist Name>",
"errorNotChannel": "음성 채널에 들어와 있지 않습니다.",
"errorNotInSameChannel": "{user} 와 같은 음성 채널에 들어와 있어야 합니다.",
"missingPermissionConnect": "음성 채널에 들어갈 수 없습니다. 권한을 확인해 주세요.",
"missingPermissionSpeak": "음성 채널에서 말할 수 없습니다. 권한을 확인해 주세요.",
"errorNotFoundPlaylist": "재생목록을 찾지 못했습니다. :(",
"fetchingPlaylist": "⌛ 재생목록을 가져오고 있습니다...",
"playlistCharLimit": "\n재생목록 생략...",
"startedPlaylist": "<@{author}> 재생목록을 시작합니다.",
"cantJoinChannel": "채널에 진입할 수 없습니다.: {error}"
},
"pruning": {
"description": "봇이 발행하는 메세지의 삭제 여부를 결정합니다.",
"errorWritingFile": "파일 작성에 실패했습니다.",
"result": "메세지 자동 삭제가 {result} 되었습니다."
},
"queue": {
"description": "현재 재생중인 음악과 대기열을 표시합니다.",
"missingPermissionMessage": "메세지를 관리하는 권한이 없습니다. 권한을 확인해 주세요.",
"errorNotQueue": "❌ **대기열에 어떤 항목도 존재하지 않습니다.**",
"currentPage": "현재 페이지 - ",
"embedTitle": "대기열\n",
"embedCurrentSong": "**현재 재생중인 음악 - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "대기열부터 음악을 제거합니다.",
"errorNotQueue": "대기열에 음악이 없습니다.",
"usageReply": "사용 방법: {prefix}remove <Queue Number>",
"result": "<@{author}> ❌ **{title}** 를 대기열부터 제거했습니다."
},
"resume": {
"description": "현재 재생중인 음악을 재개합니다.",
"errorNotQueue": "재생할 음악이 없습니다.",
"resultNotPlaying": "<@{author}> ▶ 음악을 재개했습니다.",
"errorPlaying": "대기열이 일시중지 되어있지 않습니다."
},
"search": {
"description": "영상을 검색하고 재생할 영상을 선택합니다.",
"usageReply": "사용방법`: {prefix}{name} <Video Name>",
"errorAlreadyCollector": "해당 채널에 메세지 컬렉터가 이미 존재합니다.",
"errorNotChannel": "음성 채널에 들어와 있지 않습니다.",
"resultEmbedTitle": "**재생할 음악 번호를 답장으로 보내주세요.**",
"resultEmbedDesc": "검색 결과: {search}"
},
"shuffle": {
"description": "대기열 섞기",
"errorNotQueue": "대기열에 음악이 없습니다.",
"result": "<@{author}> 🔀 대기열을 섞었습니다."
},
"skip": {
"description": "현재 재생중인 음악을 넘깁니다.",
"errorNotQueue": "넘길 음악이 존재하지 않습니다.",
"result": "<@{author}> ⏭ 음악을 넘겼습니다."
},
"skipto": {
"description": "설정한 대기열 번호까지 음악을 넘깁니다.",
"usageReply": "사용 방법: {prefix}{name} <Queue Number>",
"errorNotQueue": "대기열에 음악이 없습니다.",
"errorNotValid": "대기열에 {length} 개의 음악이 존재합니다.",
"result": "<@{author}> ⏭ {arg} 개의 음악을 넘겼습니다."
},
"stop": {
"description": "모든 음악을 멈춥니다.",
"errorNotQueue": "재생할 음악이 없습니다.",
"result": "<@{author}> ⏹ 음악을 멈췄습니다."
},
"uptime": {
"description": "가동 시간 확인",
"result": "가동 시간: `{days} 일,{hours} 시간, {minutes} 분, {seconds} 초`"
},
"volume": {
"description": "현재 재생중인 음악의 볼륨을 설정합니다.",
"errorNotQueue": "재생할 음악이 없습니다.",
"errorNotChannel": "음성 채널에 들어와 있지 않습니다.",
"currentVolume": "🔊 현재 볼륨은 **{volume}%** 입니다.",
"errorNotNumber": "설정할 볼륨을 입력해 주세요.",
"errorNotValid": "0 과 100 사이의 볼륨을 사용해 주세요.",
"result": "볼륨이 **{arg}%**로 설정되었습니다."
},
"common": {
"on": "**켜짐**",
"off": "**꺼짐**",
"enabled": "**활성화**",
"disabled": "**비활성화**",
"errorNotChannel": "음성 채널에 들어와 있지 않습니다.",
"cooldownMessage": "`{name}` 명령어를 실행하기 전 {time} 초 만큼 기다려주세요.",
"errorCommand": "명령어 실행에 실패했습니다."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Kop a pul suka",
"usagesReply": "Hug: {prefix}clip <nomba>",
"errorQueue": "Takan hopa pul feguin bada tis nan sixpoh tic.",
"errorNotChannel": "To mo da nut a vola fagtit prima!"
},
"clips": {
"description": "Listo tadda clips"
},
"help": {
"description": "Mobpsi tadda kamod yee foxwot",
"embedTitle": "{botname} Hep",
"embedDescription": "Listo de tadda kamod"
},
"invite": {
"description": "Si bot invite ami"
},
"loop": {
"description": "Toggle bocami wab",
"errorNotQueue": "Bada tis secmop maenae.",
"result": "Wab tis prompo {loop}"
},
"lyrics": {
"description": "Linda lyrics nunu ta pryers maenae amu",
"errorNotQueue": "Bada tis secmop maenae.",
"lyricsNotFound": "No lyrics polo nunu {title}.",
"embedTitle": "{title} - Lyrics"
},
"move": {
"description": "Mova rob woeod een ta tic",
"errorNotQueue": "Bada tis no tic.",
"usagesReply": "Hug: {prefix}move <Tic Nobam>",
"result": "<@{author}> 🚚 ono **{title}** da {index} een ta tic."
},
"nowplaying": {
"description": "Ta daa prompo maenae amu",
"errorNotQueue": "Bada tis secmop maenae.",
"embedTitle": "Prompo maenae",
"live": " ◉ VIVO",
"timeRemaining": "Veela Fudivy: {time}"
},
"pause": {
"description": "Pause ta pryers maenae bocami",
"errorNotQueue": "Bada tis secmop maenae.",
"result": "<@{author}> ⏸ paused ta bocami."
},
"ping": {
"description": "Ta daa ta bot's picmet ping",
"result": "📈 Picmet ping da VAU: {ping} ms"
},
"play": {
"description": "Plays sow da YouTube sif Soundcloud",
"errorNotChannel": "To mo da nut a vola fagtit prima!",
"errorNotInSameChannel": "To miklo be een ta mismo fagtit sim {user}",
"usageReply": "Hug: {prefix}play <YouTube URL | Hit Nomba | Soundcloud URL>",
"missingPermissionConnect": "Oeput ladami da vola fagtit, bidlev permissions",
"missingPermissionSpeak": "Ka oeput dub een ba vola fagtit, haga udo Ka kaylay ta zagass permissions!",
"queueAdded": "✅ **{title}** hego bem koa da ta tic bey <@{author}>",
"cantJoinChannel": "Tup non nut ta fagtit: {error}",
"queueEnded": "❌ Bocami tic moc.",
"queueError": "Via: {error}",
"startedPlaying": "🎶 Capley maenae: **{title}** {url}",
"skipSong": "<@{author}> ⏩ skipped ta amug",
"pauseSong": "<@{author}> ⏸ paused ta bocami.",
"resumeSong": "<@{author}> ▶ rapson ta bocami!",
"unmutedSong": "<@{author}> 🔊 unmuted ta bocami!",
"mutedSong": "<@{author}> 🔇 muted ta bocami!",
"decreasedVolume": "<@{author}> 🔉 ohmraj ta nogarc, ta nogarc tis prompo {volume}%",
"increasedVolume": "<@{author}> 🔊 yagcru ta nogarc, ta nogarc tis prompo {volume}%",
"loopSong": "<@{author}> Wab tis prompo {loop}",
"stopSong": "<@{author}> ⏹ haka ta bocami!",
"leaveChannel": "Etayin vola fagtit...",
"songNotFound": "Sow Non Polo",
"songAccessErr": "Hit tis shh hugrig, defoxy sif letbig"
},
"playlist": {
"description": "Hopa a playlist da youtube",
"usagesReply": "Hug: {prefix}playlist <YouTube Playlist URL | Playlist Nomba>",
"errorNotChannel": "To mo da nut a vola fagtit prima!",
"errorNotInSameChannel": "To miklo be een ta mismo fagtit sim {user}",
"missingPermissionConnect": "Oeput ladami da vola fagtit, bidlev permissions",
"missingPermissionSpeak": "Ka oeput dub een ba vola fagtit, haga udo Ka kaylay ta zagass permissions!",
"errorNotFoundPlaylist": "Playlist non polo :(",
"fetchingPlaylist": "⌛ fetching ta playlist...",
"playlistCharLimit": "\nPlaylist ditho pan kinhoy cay...",
"startedPlaylist": "<@{author}> Capley a playlist",
"cantJoinChannel": "Could non nut ta fagtit: {error}"
},
"pruning": {
"description": "Toggle pruning de bot beif",
"errorWritingFile": "Bada tos nan via scriba da ta sad.",
"result": "Dogjay pruning tis {result}"
},
"queue": {
"description": "Ta daa ta bocami tic yee prompo maenae.",
"missingPermissionMessage": "Bidlev ryapeh da godhit beif sif tokali voxaby",
"errorNotQueue": "❌ **Secmop maenae een ba patohs**",
"currentPage": "Hodski Piplo - ",
"embedTitle": "Amu Tic\n",
"embedCurrentSong": "**Hodski Amu - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Absdot amu da ta tic",
"errorNotQueue": "Bada tis no tic.",
"usageReply": "Hug: {prefix}remove <Tic Nobam>",
"result": "<@{author}> ❌ oftsos **{title}** da ta tic."
},
"resume": {
"description": "Skatil pryers maenae bocami",
"errorNotQueue": "Bada tis secmop maenae.",
"resultNotPlaying": "<@{author}> ▶ rapson ta bocami!",
"errorPlaying": "Ta tic tis non paused."
},
"search": {
"description": "Yukjug yee regbo videos da hopa",
"usageReply": "Hug: {prefix}{name} <Hit Nomba>",
"errorAlreadyCollector": "A dogjay askrho tis bedy sixpoh een ba fagtit.",
"errorNotChannel": "To mo da nut a vola fagtit prima!",
"resultEmbedTitle": "**Ave com ta amu nobam to quer da hopa**",
"resultEmbedDesc": "Fouwos nunu: {search}"
},
"shuffle": {
"description": "Shuffle tic",
"errorNotQueue": "Bada tis no tic.",
"result": "<@{author}> 🔀 shuffled ta tic"
},
"skip": {
"description": "Skip ta pryers maenae amu",
"errorNotQueue": "Bada tis secmop maenae pak Ka tup skip nunu to.",
"result": "<@{author}> ⏭ skipped ta amu"
},
"skipto": {
"description": "Skip da ta sirsei tic nobam",
"usageReply": "Hug: {prefix}{name} <Tic Nobam>",
"errorNotQueue": "Bada tis no tic.",
"errorNotValid": "Ta tic tis solo {length} rob lugol!",
"result": "<@{author}> ⏭ skipped {arg} rob"
},
"stop": {
"description": "Buy ta bocami",
"errorNotQueue": "Bada tis secmop maenae.",
"result": "<@{author}> ⏹ haka ta bocami!"
},
"uptime": {
"description": "Bada ta uptime",
"result": "Uptime: `{days} dex,{hours} als, {minutes} sacwad, {seconds} emebid`"
},
"volume": {
"description": "Greebo nogarc de pryers maenae bocami",
"errorNotQueue": "Bada tis secmop maenae.",
"errorNotChannel": "To mo da nut a vola fagtit prima!",
"currentVolume": "🔊 Ta hodski nogarc tis: **{volume}%**",
"errorNotNumber": "Radbad uso a nobam da ka kow nogarc.",
"errorNotValid": "Radbad uso a nobam squee 0 - 100.",
"result": "Nogarc ka kow da: **{arg}%**"
},
"common": {
"on": "**en**",
"off": "**dak**",
"enabled": "**dubduh**",
"disabled": "**norhex**",
"errorNotChannel": "To mo da nut a vola fagtit prima!",
"cooldownMessage": "radbad sky {time} mas emebid bidom reusing ta `{name}` dogpun.",
"errorCommand": "Bada tos nan via unhod pak dogpun."
}
}
+179
View File
@@ -0,0 +1,179 @@
{
"clip": {
"description": "Spiller en klipplyd",
"usagesReply": "Bruk: {prefix}klipp <navn>",
"errorQueue": "Kan ikke spille av klippet fordi det er en aktiv kø.",
"errorNotChannel": "Du må først bli med i en stemmekanal!"
},
"clips": {
"description": "List opp alle klippene"
},
"help": {
"description": "Vis alle kommandoer og beskrivelser",
"embedTitle": "{botname} Hjelp",
"embedDescription": "Liste over alle kommandoer"
},
"invite": {
"description": "Send invitasjonslenke til bot"
},
"loop": {
"description": "Slå på loop",
"errorNotQueue": "Det er ingenting som spilles av.",
"result": "Loop er nå {loop}"
},
"lyrics": {
"description": "Få teksten til sangen som spilles for øyeblikket",
"errorNotQueue": "Det er ingenting som spilles av.",
"lyricsNotFound": "Ingen tekster funnet for {title}.",
"embedTitle": "{title} - Sangtekster"
},
"move": {
"description": "Flytt sanger rundt i køen",
"errorNotQueue": "Det er ingen kø.",
"usagesReply": "Bruk: {prefix}flytt <kønummer>",
"result": "<@{author}> 🚚 flyttet **{title}** til {index} i køen.",
"args": {
"movefrom": "Slot å flytte fra",
"moveto": "Slot å flytte til"
}
},
"nowplaying": {
"description": "Vis sang som spilles nå",
"errorNotQueue": "Det er ingenting som spilles av.",
"embedTitle": "Spilles nå",
"live": " ◉ LIVE",
"timeRemaining": "Gjenstående tid: {time}"
},
"pause": {
"description": "Sett musikken som spilles på pause",
"errorNotQueue": "Det er ingenting som spilles av.",
"result": "<@{author}> ⏸ satte musikken på pause."
},
"ping": {
"description": "Vis botens gjennomsnittlige ping",
"result": "📈 Gjennomsnittlig ping til API: {ping} ms"
},
"play": {
"description": "Spiller lyd fra YouTube",
"errorNotChannel": "Du må først bli med i en talekanal!",
"errorNotInSameChannel": "Du må være i samme kanal som {user}",
"usageReply": "Bruk: {prefix}spill <YouTube URL | Videonavn>",
"missingPermissionConnect": "Kan ikke koble til talekanalen, mangler tillatelser",
"missingPermissionSpeak": "Jeg kan ikke snakke i denne talekanalen, sørg for at jeg har de riktige tillatelsene!",
"queueAdded": "✅ **{title}** har blitt lagt til i køen av <@{author}>",
"cantJoinChannel": "Kunne ikke bli med i kanalen: {error}",
"queueEnded": "❌ Musikkøen er avsluttet.",
"queueError": "Feil: {error}",
"startedPlaying": "🎶 Begynte å spille: **{title}** {url}",
"skipSong": "<@{author}> ⏩ hoppet over sangen",
"pauseSong": "<@{author}> ⏸ satte musikken på pause.",
"resumeSong": "<@{author}> ▶ gjenopptok musikken!",
"unmutedSong": "<@{author}> 🔊 dempet musikken!",
"mutedSong": "<@{author}> 🔇 dempet musikken!",
"decreasedVolume": "<@{author}> 🔉 reduserte volumet, volumet er nå {volume}%",
"increasedVolume": "<@{author}> 🔊 økte volumet, volumet er nå {volume}%",
"loopSong": "<@{author}> Loop er nå {loop}",
"stopSong": "<@{author}> ⏹ stoppet musikken!",
"leaveChannel": "Forlater talekanal...",
"songNotFound": "Lyd ikke funnet",
"songAccessErr": "Videoen er aldersbegrenset, privat eller utilgjengelig",
"errorNoResults": "Ingen resultater funnet for {url}",
"errorInvalidURL": "Ugyldig nettadresse, prøv et søk eller youtube-nettadresse"
},
"playlist": {
"description": "Spill av en spilleliste fra youtube",
"usagesReply": "Bruk: {prefix}spilleliste <YouTube-spillelistenettadresse | -spillelistenavn>",
"errorNotChannel": "Du må først bli med i en talekanal!",
"errorNotInSameChannel": "Du må være i samme kanal som {user}",
"missingPermissionConnect": "Kan ikke koble til talekanalen, mangler tillatelser",
"missingPermissionSpeak": "Jeg kan ikke snakke i denne talekanalen, sørg for at jeg har de riktige tillatelsene!",
"errorNotFoundPlaylist": "Spilleliste ikke funnet :(",
"fetchingPlaylist": "⌛ henter spillelisten...",
"playlistCharLimit": "\nSpilleliste større enn tegngrensen...",
"startedPlaylist": "<@{author}> Startet en spilleliste",
"cantJoinChannel": "Kunne ikke bli med i kanalen: {error}"
},
"pruning": {
"description": "Veksle beskjæring av bot-meldinger",
"errorWritingFile": "Det oppsto en feil ved skriving til filen.",
"result": "Beskjæring av melding er {result}"
},
"queue": {
"description": "Vis musikkkøen og spilles nå.",
"missingPermissionMessage": "Manglende tillatelse til å administrere meldinger eller legge til reaksjoner",
"errorNotQueue": "❌ **Ingenting spilles på denne serveren**",
"currentPage": "Gjeldende side -",
"embedTitle": "Sangkø\n",
"embedCurrentSong": "**Gjeldende sang [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Fjern sang fra køen",
"errorNotQueue": "Det er ingen kø.",
"usageReply": "Bruk: {prefix}fjern <kønummer>",
"result": "<@{author}> ❌ fjernet **{title}** fra køen."
},
"resume": {
"description": "Fortsett avspilling av musikk",
"errorNotQueue": "Det er ingenting som spilles av.",
"resultNotPlaying": "<@{author}> ▶ gjenopptok musikken!",
"errorPlaying": "Køen er ikke satt på pause."
},
"search": {
"description": "Søk og velg videoer som skal spilles av",
"usageReply": "Bruk: {prefix}{name} <Videonavn>",
"errorAlreadyCollector": "En meldingssamler er allerede aktiv i denne kanalen.",
"errorNotChannel": "Du må først bli med i en talekanal!",
"resultEmbedTitle": "**Svar med sangnummeret du vil spille**",
"resultEmbedDesc": "Resultater for: {search}",
"optionQuery": "Søkeord"
},
"shuffle": {
"description": "Shuffle køen",
"errorNotQueue": "Det er ingen kø.",
"result": "<@{author}> 🔀 blandet køen"
},
"skip": {
"description": "Hopp over sangen som spilles for øyeblikket",
"errorNotQueue": "Det er ingenting som jeg kan hoppe over for deg.",
"result": "<@{author}> ⏭ hoppet over sangen"
},
"skipto": {
"description": "Hopp til det valgte kønummeret",
"usageReply": "Bruk: {prefix}{name} <kønummer>",
"errorNotQueue": "Det er ingen kø.",
"errorNotValid": "Køen er bare {length} sanger lang!",
"result": "<@{author}> ⏭ hoppet over {arg} sanger",
"args": {
"number": "Kønummeret du skal hoppe til"
}
},
"stop": {
"description": "Stopper musikken",
"errorNotQueue": "Det er ingenting som spilles av.",
"result": "<@{author}> ⏹ stoppet musikken!"
},
"uptime": {
"description": "Sjekk driftstid",
"result": "Driftstid: `{days} dag(er),{hours} timer, {minutes} minutter, {seconds} sekunder`"
},
"volume": {
"description": "Endre volumet for musikk som spilles for øyeblikket",
"errorNotQueue": "Det er ingenting som spilles av.",
"errorNotChannel": "Du må først bli med i en talekanal!",
"currentVolume": "🔊 Gjeldende volumet er: **{volume}%**",
"errorNotNumber": "Bruk et tall for å stille inn volumet.",
"errorNotValid": "Vennligst bruk et tall mellom 0 - 100.",
"result": "Volum satt til: **{arg}%**"
},
"common": {
"on": "**på**",
"off": "**off**",
"enabled": "**aktivert**",
"disabled": "**deaktivert**",
"errorNotChannel": "Du må først bli med i en talekanal!",
"cooldownMessage": "vennligst vent {time} sekund(er) til før du bruker `{name}`-kommandoen på nytt.",
"errorCommand": "Det oppsto en feil under utførelse av denne kommandoen."
},
"Invite me to your server!": "Inviter meg til serveren din!",
"Invite": "Inviter"
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Speelt een clip af.",
"usagesReply": "Gebruik: {prefix}clip <naam>",
"errorQueue": "Kan clip niet afspelen omdat er een actieve wachtrij is.",
"errorNotChannel": "Je moet eerst een voice channel joinen!"
},
"clips": {
"description": "Lijst van alle clips"
},
"help": {
"description": "Vertoon alle comamnds en beschrijvingen",
"embedTitle": "{botname} Help",
"embedDescription": "Lijst van alle commands"
},
"invite": {
"description": "Verstuur bot invite link"
},
"loop": {
"description": "Toggle music loop",
"errorNotQueue": "Er speelt niets af.",
"result": "Loop is nu {loop}"
},
"lyrics": {
"description": "Haal de lyrics op voor het nummer dat momenteel wordt afgespeeld.",
"errorNotQueue": "Er is niks aan het afspelen.",
"lyricsNotFound": "Geen lyrics gevonden voor {title}.",
"embedTitle": "{title} - Lyrics"
},
"move": {
"description": "Verplaats nummers in de wachtrij",
"errorNotQueue": "Er is geen wachtrij.",
"usagesReply": "Gebruik: {prefix}move <Wachtrij Nummer>",
"result": "<@{author}> 🚚 verplaatst **{title}** naar {index} in de wachtrij."
},
"nowplaying": {
"description": "Toon het spelende nummer",
"errorNotQueue": "Er is niks aan het afspelen.",
"embedTitle": "Nu aan het afspelen",
"live": " ◉ LIVE",
"timeRemaining": "Tijd resterend: {time}"
},
"pause": {
"description": "Pauzeer de muziek die aan het afspelen is",
"errorNotQueue": "Er is niks aan het afspelen.",
"result": "<@{author}> ⏸ heeft de muziek gepauzeerd."
},
"ping": {
"description": "Laat de gemiddelde ping van de bot zien",
"result": "📈 Gemiddelde Ping naar API: {ping} ms"
},
"play": {
"description": "Speel geluid af van YouTube of Soundcloud",
"errorNotChannel": "Je moet eerst een voice channel joinen!",
"errorNotInSameChannel": "Je moet in dezelfde channel zitten als {user}",
"usageReply": "Gebruik: {prefix}play <YouTube URL | Video Naam | Soundcloud URL>",
"missingPermissionConnect": "Kan geen verbinding maken met voice channel, missing permissions",
"missingPermissionSpeak": "Ik kan niet spreken in de voice channel, Zorg ervoor dat ik de juiste permissions heb!",
"queueAdded": "✅ **{title}** is toegevoegd aan de wachtrij door <@{author}>",
"cantJoinChannel": "Ik kon de channel niet betreden: {error}",
"queueEnded": "❌ Muziek wachtrij afgelopen.",
"queueError": "Foutmelding: {error}",
"startedPlaying": "🎶 Gestart met afspelen: **{title}** {url}",
"skipSong": "<@{author}> ⏩ skipte het liedje",
"pauseSong": "<@{author}> ⏸ pauzeerde de muziek!.",
"resumeSong": "<@{author}> ▶ hervatte de muziek!",
"unmutedSong": "<@{author}> 🔊 unmuted de muziek!",
"mutedSong": "<@{author}> 🔇 muted de muziek!",
"decreasedVolume": "<@{author}> 🔉 verlaagde het volume, het volume is nu {volume}%",
"increasedVolume": "<@{author}> 🔊 verhoogde het volume, het volume is nu {volume}%",
"loopSong": "<@{author}> Herhaling is nu {loop}",
"stopSong": "<@{author}> ⏹ stopte de muziek!",
"leaveChannel": "Voice channel verlaten...",
"songNotFound": "Audio Not Found",
"songAccessErr": "Video is age restricted, private or unavailable"
},
"playlist": {
"description": "Speel een playlist af van youtube",
"usagesReply": "Gebruik: {prefix}playlist <YouTube Playlist URL | Playlist Naam>",
"errorNotChannel": "Je moet eerst een voice channel joinen!",
"errorNotInSameChannel": "Je moet in dezelfde channel zitten als {user}",
"missingPermissionConnect": "Kan geen verbinding maken met voice channel, missing permissions",
"missingPermissionSpeak": "Ik kan niet spreken in de voice channel, Zorg ervoor dat ik de juiste permissions heb!",
"errorNotFoundPlaylist": "Playlist niet gevonden :(",
"fetchingPlaylist": "⌛ playlist aan het ophalen...",
"playlistCharLimit": "\nAfspeellijst groter dan tekenlimiet...",
"startedPlaylist": "<@{author}> Starte een playlist",
"cantJoinChannel": "Ik kon de channel niet betreden: {error}"
},
"pruning": {
"description": "Toggle pruning van bot berichten",
"errorWritingFile": "Er is een fout opgetreden bij het schrijven naar het bestand.",
"result": "bericht pruning is {result}"
},
"queue": {
"description": "Toon de muziekwachtrij en het huidige liedje.",
"missingPermissionMessage": "Ik heb geen permissies voor manage messages en add reactions.",
"errorNotQueue": "❌ **Er wordt niets afgespeeld op deze server**",
"currentPage": "Huidige pagina - ",
"embedTitle": "Muziek Wachtrij\n",
"embedCurrentSong": "**Huidig lied - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Verwijder liedje van de wachrij",
"errorNotQueue": "Er is geen wachtrij.",
"usageReply": "Gebruik: {prefix}remove <Wachtrij nummer>",
"result": "<@{author}> ❌ heeft **{title}** verwijderd van de wachtrij."
},
"resume": {
"description": "Hervat de muziek die momenteel wordt afgespeeld",
"errorNotQueue": "Er speelt niets af.",
"resultNotPlaying": "<@{author}> ▶ hervatte de muziek!",
"errorPlaying": "De wachtrij is niet gepauzeerd."
},
"search": {
"description": "Zoek en selecteer videos om af te spelen.",
"usageReply": "Gebruik: {prefix}{name} <Video Naam>",
"errorAlreadyCollector": "Er is al een berichten verzamelaar actief in dit kanaal.",
"errorNotChannel": "Je moet eerst een voice channel joinen!",
"resultEmbedTitle": "**Reageer met het nummer die u wilt afspelen**",
"resultEmbedDesc": "Resultaten voor: {search}"
},
"shuffle": {
"description": "Wachtrij in willekeurige volgorde",
"errorNotQueue": "Er is geen wachtrij.",
"result": "<@{author}> 🔀 de wachtrij is in een willekeurige volgorde geplaatst."
},
"skip": {
"description": "Sla het huidige nummer over.",
"errorNotQueue": "Er is niks aan het afspelen dat ik kan overslaan.",
"result": "<@{author}> ⏭ Sloeg het huidige nummer over"
},
"skipto": {
"description": "Ga naar het geselecteerde wachtrijnummer",
"usageReply": "Gebruik: {prefix}{name} <Wachtrij Nummer>",
"errorNotQueue": "Er is geen wachtrij.",
"errorNotValid": "De wachtrij is {length} liedjes lang!",
"result": "<@{author}> ⏭ sloeg {arg} liedjes over!"
},
"stop": {
"description": "Stopt de muziek",
"errorNotQueue": "Er is niks aan het afspelen.",
"result": "<@{author}> ⏹ stopte de muziek!"
},
"uptime": {
"description": "Controleer de uptime",
"result": "Uptime: `{days} dagen,{hours} uren, {minutes} minuten, {seconds} seconden`"
},
"volume": {
"description": "Verander het volume van het huidige nummer",
"errorNotQueue": "Er is niks aan het afspelen.",
"errorNotChannel": "Je moet eerst een voice channel joinen!",
"currentVolume": "🔊 Het huidige volume is: **{volume}%**",
"errorNotNumber": "Gebruik een nummer of het volume te veranderen.",
"errorNotValid": "Gebruik een nummer tussen 0 - 100.",
"result": "Volume veranderd naar: **{arg}%**"
},
"common": {
"on": "**aan**",
"off": "**uit**",
"enabled": "**ingeschakeld**",
"disabled": "**uitgeschakeld**",
"errorNotChannel": "Je moet eerst een voice channel joinen!",
"cooldownMessage": "Wacht nog {time} seconden voor je `{name}` hergebruikt.",
"errorCommand": "Er was een error tijdens het uitvoeren van deze command."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Odtwarza klip",
"SkładniasReply": "Składnia: {prefix}clip <nazwa>",
"errorQueue": "Nie można odtworzyć klipu, ponieważ jest aktywna kolejka.",
"errorNotChannel": "Musisz dołączyć na kanał głosowy!"
},
"clips": {
"description": "Wyświetla wszyskie klipy"
},
"help": {
"description": "Wyświetla listę wszystkich komend",
"embedTitle": "{botname} Help",
"embedDescription": "Lista wszystkich komend"
},
"invite": {
"description": "Wysyła link do zaproszenia bota"
},
"loop": {
"description": "Przełączenie pętli",
"errorNotQueue": "Nie ma aktywnej kolejki na tym serwerze.",
"result": "Pętla jest teraz: {loop}"
},
"lyrics": {
"description": "Wyświetla słowa dla aktualnie odtwarzanego utworu",
"errorNotQueue": "Nie ma aktywnej kolejki na tym serwerze.",
"lyricsNotFound": "Brak słów dla: {title}.",
"embedTitle": "{title} - Lyrics"
},
"move": {
"description": "Przenosi utwory w kolejce",
"errorNotQueue": "Nie ma kolejki na tym serwerze.",
"SkładniasReply": "Składnia: {prefix}move <Numer w kolejce>",
"result": "<@{author}> 🚚 przeniósł **{title}** na miejsce {index} w kolejce."
},
"nowplaying": {
"description": "Wyświetla aktualnie odtwarzany utwór",
"errorNotQueue": "Nie ma aktywnej kolejki na tym serwerze.",
"embedTitle": "Teraz Odtwarzane",
"live": " ◉ LIVE",
"timeRemaining": "Pozostały Czas: {time}"
},
"pause": {
"description": "Zatrzymaj aktualnie odtwarzaną muzykę",
"errorNotQueue": "Nie ma aktywnej kolejki na tym serwerze.",
"result": "<@{author}> ⏸ zatrzymano odtwarzanie."
},
"ping": {
"description": "Pokazuje średni ping bot'a",
"result": "📈 Średni ping do API: {ping} ms"
},
"play": {
"description": "Odtwarza utwory z Youtube lub Soundcloud!",
"errorNotChannel": "Musisz dołączyć do kanału głosowego!",
"errorNotInSameChannel": "Musisz być na tym samym kanale co {user}",
"SkładniaReply": "Składnia: {prefix}play <YouTube URL | Nazwa Nagrania | Soundcloud URL>",
"missingPermissionConnect": "Nie mogę połączyć się z tym kanałem, sprawdź uprawnienia!",
"missingPermissionSpeak": "Nie mogę odtwarzać w tym kanale, sprawdź uprawnienia!",
"queueAdded": "✅ Utwór **{title}** został dodany do kolejki przez <@{author}>",
"cantJoinChannel": "Brak możliwości dołączenia na kanał: {error}",
"queueEnded": "❌ Kolejka odtwarzania skończona.",
"queueError": "Błąd: {error}",
"startedPlaying": "🎶 Rozpoczęto odtwarzanie: **{title}** {url}",
"skipSong": "<@{author}> ⏩ pominął",
"pauseSong": "<@{author}> ⏸ zatrzymał odtwarzanie.",
"resumeSong": "<@{author}> ▶ wznowił odtwarzanie!",
"unmutedSong": "<@{author}> 🔊 odciszył odtwarzanie!",
"mutedSong": "<@{author}> 🔇 wyciszył odtwarzanie!",
"decreasedVolume": "<@{author}> 🔉 podniósł poziom głośności, wynosi teraz: {volume}%",
"increasedVolume": "<@{author}> 🔊 podniósł poziom głośności, wynosi teraz: {volume}%",
"loopSong": "<@{author}> Przełączył pętlę na: {loop}",
"stopSong": "<@{author}> ⏹ Zatrzymał odtwarzanie!",
"leaveChannel": "Opuszczanie kanału głosowego...",
"songNotFound": "Utwór nieznaleziony.",
"songAccessErr": "Film jest ograniczony wiekowo, prywatny lub niedostępny."
},
"playlist": {
"description": "Odtwarza listę odtwarzania z youtuba",
"SkładniasReply": "Składnia: {prefix}playlist <URL Listy Odtwarzania Youtube| Nazwa listy odtwarzania>",
"errorNotChannel": "Musisz dołączyć do kanału głosowego!",
"errorNotInSameChannel": "Musisz być na tym samym kanale głosowym co: {user}",
"missingPermissionConnect": "Nie mogę połączyć się z tym kanałem, sprawdź uprawnienia!",
"missingPermissionSpeak": "Nie mogę odtwarzać w tym kanale, sprawdź uprawnienia!",
"errorNotFoundPlaylist": "Lista odtwarzania nie znaleziona. :(",
"fetchingPlaylist": "⌛ przetwarzanie listy odtwarzania...",
"playlistCharLimit": "\nLista odtwarzania jest większa niż dozowlony limit znaków...",
"startedPlaylist": "<@{author}> Uruchomniono Listę odtwarzania",
"cantJoinChannel": "Nie mogę dołączyć do kanału: {error}"
},
"pruning": {
"description": "Przełącza usuwanie czyszczenie wiadomości bota",
"errorWritingFile": "Był problem w zapisywaniu ustawienia.",
"result": "Czyszczenie wiadomości jest: {result}"
},
"queue": {
"description": "Wyświetla aktualną kolejkę utworów, oraz właśnie odtwarzany.",
"missingPermissionMessage": "Brakujące uprawnienia: Zarządzanie Wiadomościami i/lub Dodawanie Reakcji",
"errorNotQueue": "❌ **Nic nie jest odtwarzane na tym serwerze**",
"currentPage": "Aktualna Strona - ",
"embedTitle": "Kolejka utworów\n",
"embedCurrentSong": "**Aktualnie odtwarzany utwór - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Usuń utwór z kolejki",
"errorNotQueue": "Nie ma kolejki na tym serwerze.",
"SkładniaReply": "Składnia: {prefix}remove <Numer w kolejce>",
"result": "<@{author}> ❌ usunięto **{title}** z kolejki."
},
"resume": {
"description": "Wznów odtwarzanie muzyki",
"errorNotQueue": "Nie ma aktywnej kolejki na tym serwerze.",
"resultNotPlaying": "<@{author}> ▶ wznowił odtwarzanie!",
"errorPlaying": "Kolejka nie jest zatrzymana."
},
"search": {
"description": "Wyszukaj i wybierz utwór do odtworzenia",
"SkładniaReply": "Składnia: {prefix}{name} <nazwa nagrania>",
"errorAlreadyCollector": "Wyszukiwacz muzyki jest już aktywny na tym kanale.",
"errorNotChannel": "Musisz dołączyć do kanału głosowego!",
"resultEmbedTitle": "**Odpowiedz numerem utoworu który chcesz odtworzyć**",
"resultEmbedDesc": "Wyniki dla: {search}"
},
"shuffle": {
"description": "Pomieszaj kolejkę",
"errorNotQueue": "Nie ma kolejki na tym serwerze.",
"result": "<@{author}> 🔀 pomieszaj kolejkę"
},
"skip": {
"description": "Przewiń aktualnie odtwarzany utwór",
"errorNotQueue": "Nie mam czego pominąć.",
"result": "<@{author}> ⏭ pominął utwór"
},
"skipto": {
"description": "Przewiń do wybranego numeru w kolejce",
"SkładniaReply": "Składnia: {prefix}{name} <Numer w kolejce>",
"errorNotQueue": "Nie ma kolejki na tym serwerze.",
"errorNotValid": "Kolejka ma tylko {length} utworów!",
"result": "<@{author}> ⏭ pominął {arg} utowórw"
},
"stop": {
"description": "Zatrzymuje muzykę",
"errorNotQueue": "Nic nie jest odtwarzane.",
"result": "<@{author}> ⏹ Zatrzymano odtwarzanie!"
},
"uptime": {
"description": "Sprawdź czas online bot'a",
"result": "Czas online: `{days}dni ,{hours} godzin, {minutes} minut, {seconds} sekund`"
},
"volume": {
"description": "Zmień głośność odtwarzania utworu",
"errorNotQueue": "Nic nie jest odtwarzane.",
"errorNotChannel": "Musisz dołączyć do kanału głosowego!",
"currentVolume": "🔊 Aktualna głośność: **{volume}%**",
"errorNotNumber": "Proszę, użyj numeru by ustawić głośność.",
"errorNotValid": "Proszę, użyj numeru z zakresu 0 - 100.",
"result": "Głośność ustawiona na: **{arg}%**"
},
"common": {
"on": "**włączone**",
"off": "**wyłączone**",
"enabled": "**włączone**",
"disabled": "**wyłączone**",
"errorNotChannel": "Musisz dołączyć do kanału głosowego!",
"cooldownMessage": "Proszę zaczekaj {time} przed kolejny użyciem komendy `{name}`.",
"errorCommand": "Podczas wykonywania tej komendy pojawił się błąd."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Reproduz um clipe de música.",
"usagesReply": "Uso: {prefix}clip <nome>",
"errorQueue": "Não é possível reproduzir este clipe porque há uma playlist ativa.",
"errorNotChannel": "Você precisa entrar em um canal de voz primeiro!"
},
"clips": {
"description": "Lista todos os clipes"
},
"help": {
"description": "Mostra todos os comandos e descrições.",
"embedTitle": "{botname} Ajuda",
"embedDescription": "Lista de todos os comandos."
},
"invite": {
"description": "Envia o link de convite do bot."
},
"loop": {
"description": "Ativa o modo de repetição.",
"errorNotQueue": "Não há nada reproduzindo.",
"result": "Repetir está {loop}"
},
"lyrics": {
"description": "Mostra a letra da música que está reproduzindo.",
"errorNotQueue": "Não há nada reproduzindo.",
"lyricsNotFound": "Nenhuma letra encontrada para {title}.",
"embedTitle": "{title} - Letra"
},
"move": {
"description": "Troca a música de posição na playlist.",
"errorNotQueue": "Não há playlist.",
"usagesReply": "Uso: {prefix}move <Posição na playlist>",
"result": "<@{author}> 🚚 moveu **{title}** para {index} na playlist."
},
"nowplaying": {
"description": "Mostra música em reprodução.",
"errorNotQueue": "Não há nada reproduzindo.",
"embedTitle": "Reproduzindo",
"live": " ◉ AO VIVO",
"timeRemaining": "Tempo restante: {time}"
},
"pause": {
"description": "Pausa a música reproduzindo.",
"errorNotQueue": "Não há nada reproduzindo.",
"result": "<@{author}> ⏸ pausou a música."
},
"ping": {
"description": "Mostra o ping médio do bot.",
"result": "📈 Ping médio da API: {ping} ms"
},
"play": {
"description": "Reproduz áudio do Youtube ou Soundcloud",
"errorNotChannel": "Você precisa entrar em um canal de voz primeiro!",
"errorNotInSameChannel": "Você precisa está no mesmo canal que {user}",
"usageReply": "Uso: {prefix}play <URL do Youtube | Nome do Vídeo | URL do Soundcloud>",
"missingPermissionConnect": "Não posso conectar a canais de voz, falta permissão!",
"missingPermissionSpeak": "Não posso tocar neste canal de voz, falta permissão!",
"queueAdded": "✅ **{title}** foi adicionado na playlist por <@{author}>",
"cantJoinChannel": "Não pude entrar no canal: {error}",
"queueEnded": "❌ Fim da playlist.",
"queueError": "Erro: {error}",
"startedPlaying": "🎶 Tocando: **{title}** {url}",
"skipSong": "<@{author}> ⏩ pulou a música.",
"pauseSong": "<@{author}> ⏸ pausou a música.",
"resumeSong": "<@{author}> ▶ resumiu a música!",
"unmutedSong": "<@{author}> 🔊 desmutou a música!",
"mutedSong": "<@{author}> 🔇 mutou a música!",
"decreasedVolume": "<@{author}> 🔉 baixou o volume, o volume agora é {volume}%",
"increasedVolume": "<@{author}> 🔊 aumentou o volume, o volume agora é {volume}%",
"loopSong": "<@{author}> Repetir está {loop}",
"stopSong": "<@{author}> ⏹ parou a música!",
"leaveChannel": "Deixando o canal de voz!",
"songNotFound": "Audio Not Found",
"songAccessErr": "Video is age restricted, private or unavailable"
},
"playlist": {
"description": "Reproduz uma playlist do youtube",
"usagesReply": "Uso: {prefix}playlist <URL da Playlist do Youtube | Nome da Playlist>",
"errorNotChannel": "Você precisa entrar em um canal de voz primeiro!",
"errorNotInSameChannel": "Você precisa está no mesmo canal que {user}",
"missingPermissionConnect": "Não posso conectar a canais de voz, falta permissão!",
"missingPermissionSpeak": "Não posso tocar neste canal de voz, falta permissão!",
"errorNotFoundPlaylist": "Playlist não encontrada :(",
"fetchingPlaylist": "⌛ importando playlist...",
"playlistCharLimit": "\nPlaylist maior que o permitido...",
"startedPlaylist": "<@{author}> reproduzindo uma playlist.",
"cantJoinChannel": "Não pude entrar no canal: {error}"
},
"pruning": {
"description": "Ativa a remoção de mensagem após fim da música.",
"errorWritingFile": "Houve um erro ao escrever no arquivo.",
"result": "Remoção de mensagem {result}"
},
"queue": {
"description": "Mostra a playlist atual.",
"missingPermissionMessage": "Falta permissão para adicionar reações!",
"errorNotQueue": "❌ **Nada reproduzindo neste servidor.**",
"currentPage": "Pagina atual - ",
"embedTitle": "Playlist\n",
"embedCurrentSong": "**Música atual - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Remove música da playlist",
"errorNotQueue": "Não há playlist.",
"usageReply": "Uso: {prefix}remove <Número da música>",
"result": "<@{author}> ❌ removido **{title}** da playlist."
},
"resume": {
"description": "Reproduz novamente a música pausada.",
"errorNotQueue": "Não há nada reproduzindo.",
"resultNotPlaying": "<@{author}> ▶ resumiu a música!",
"errorPlaying": "A playlist não está pausada."
},
"search": {
"description": "Procura e seleciona vídeo para tocar",
"usageReply": "Uso: {prefix}{name} <Nome do Vídeo>",
"errorAlreadyCollector": "Uma busca ainda está ativa.",
"errorNotChannel": "Você precisa entrar em um canal de voz primeiro!",
"resultEmbedTitle": "**Você precisa enviar um número para tocar.**",
"resultEmbedDesc": "Resultador para: {search}"
},
"shuffle": {
"description": "Ativa o modo aleatório",
"errorNotQueue": "Não há nada na playlist.",
"result": "<@{author}> 🔀 colocou a playlist no aleatório."
},
"skip": {
"description": "Pula a música atual.",
"errorNotQueue": "Não há nada tocando que eu possa pular.",
"result": "<@{author}> ⏭ pulou a música"
},
"skipto": {
"description": "Pula para uma determinada posição na fila.",
"usageReply": "Uso: {prefix}{name} <Número da playlist>",
"errorNotQueue": "Não há nada na playlist.",
"errorNotValid": "A playlist tem {length} música apenas!",
"result": "<@{author}> ⏭ pulou para música {arg}"
},
"stop": {
"description": "Para a música.",
"errorNotQueue": "Não há nada reproduzindo.",
"result": "<@{author}> ⏹ parou a música!"
},
"uptime": {
"description": "Verifica o tempo ativo",
"result": "Tempo online: `{days} dia(s),{hours} hora(s), {minutes} minuto(s), {seconds} segundo(s)`"
},
"volume": {
"description": "Muda o volume da música atual.",
"errorNotQueue": "Não há nada reproduzindo.",
"errorNotChannel": "Você precisa entrar em um canal de voz primeiro!",
"currentVolume": "🔊 O volume atual é: **{volume}%**",
"errorNotNumber": "Por-favor utilize números para mudar o volume.",
"errorNotValid": "Por-favor utilize números entre 0 - 100.",
"result": "Volume alterado para: **{arg}%**"
},
"common": {
"on": "**ligado**",
"off": "**desligado**",
"enabled": "**ativado**",
"disabled": "**desativado**",
"errorNotChannel": "Você precisa entrar em um canal de voz primeiro!",
"cooldownMessage": "Por favor espere {time} segundo(s) mais antes de usar o comando `{name}` novamente.",
"errorCommand": "Houve um erro ao executar este comando."
}
}
+165
View File
@@ -0,0 +1,165 @@
{
"clip": {
"description": "Redă un sunet de clip",
"usagesReply": "Utilizare: {prefix}clip <nume>",
"errorQueue": "Nu pot reda clipul deoarece există o coadă activă.",
"errorNotChannel": "Trebuie să te alături mai întâi unui canal vocal!"
},
"clips": {
"description": "Listează toate clipurile"
},
"help": {
"description": "Afișează toate comenzile și descrierile",
"embedTitle": "{botname} Ajutor",
"embedDescription": "Listă de toate comenzile"
},
"invite": {
"description": "Trimite linkul de invitație al botului"
},
"loop": {
"description": "Comută repetarea melodiilor",
"errorNotQueue": "Nu se redă nimic.",
"result": "Repetarea este acum {loop}"
},
"lyrics": {
"description": "Obține versurile pentru melodia care se redă în prezent",
"errorNotQueue": "Nu se redă nimic.",
"lyricsNotFound": "Nu s-au găsit versuri pentru {title}.",
"embedTitle": "{title} - Versuri"
},
"move": {
"description": "Mută melodiile în coadă",
"errorNotQueue": "Nu există o coadă.",
"usagesReply": "Utilizare: {prefix}move <Număr în coadă>",
"result": "<@{author}> 🚚 a mutat melodia {title} pe poziția {index} în coadă.",
"args": {
"movefrom": "Poziția de mutat",
"moveto": "Poziția în care să fie mutat"
}
},
"nowplaying": {
"description": "Afișează melodia care se redă în prezent",
"errorNotQueue": "Nu se redă nimic.",
"embedTitle": "Se redă acum",
"live": " ◉ LIVE",
"timeRemaining": "Timp rămas: {time}"
},
"pause": {
"description": "Pune în pauză melodia care se redă în prezent",
"errorNotQueue": "Nu se redă nimic.",
"result": "<@{author}> ⏸ a pus muzica pe pauză."
},
"ping": {
"description": "Afișează ping-ul mediu al botului",
"result": "📈 Ping mediu către API: {ping} ms"
},
"play": {
"description": "Redă audio de pe YouTube",
"errorNotChannel": "Trebuie să te alături mai întâi unui canal vocal!",
"errorNotInSameChannel": "Trebuie să fii în același canal cu {user}",
"usageReply": "Utilizare: {prefix}play <URL YouTube | Nume Video>",
"missingPermissionConnect": "Nu se poate conecta la canalul vocal, permisiuni lipsă",
"missingPermissionSpeak": "Nu pot vorbi în acest canal vocal, asigură-te că am permisiunile corespunzătoare!",
"queueAdded": "✅ {title} a fost adăugat în coadă de <@{author}>",
"cantJoinChannel": "Nu am putut să mă alătur canalului: {error}",
"queueEnded": "❌ Coada de muzică s-a încheiat.",
"queueError": "Eroare: {error}",
"startedPlaying": "🎶 A început redarea: {title} {url}",
"skipSong": "<@{author}> ⏩ a trecut peste melodie",
"pauseSong": "<@{author}> ⏸ a pus muzica pe pauză.",
"resumeSong": "<@{author}> ▶ a reluat muzica!",
"unmutedSong": "<@{author}> 🔊 a dat volumul la muzică!",
"mutedSong": "<@{author}> 🔇 a tăcut muzica!",
"decreasedVolume": "<@{author}> 🔉 a redus volumul, volumul este acum {volume}%",
"increasedVolume": "<@{author}> 🔊 a mărit volumul, volumul este acum {volume}%",
"loopSong": "<@{author}> Repetarea este acum {loop}",
"stopSong": "<@{author}> ⏹ a oprit muzica!",
"leaveChannel": "Părăsesc canalul vocal...",
"songNotFound": "Audio negăsit",
"songAccessErr": "Video restricționat pe bază de vârstă, privat sau indisponibil",
"errorNoResults": "Niciun rezultat găsit pentru {url}",
"errorInvalidURL": "URL invalid, te rog încearcă o căutare sau un URL de pe YouTube"
},
"playlist": {
"description": "Redă o listă de redare de pe YouTube",
"usagesReply": "Utilizare: {prefix}playlist <URL listă redare YouTube | Nume listă redare>",
"errorNotChannel": "Trebuie să te alături mai întâi unui canal vocal!",
"errorNotInSameChannel": "Trebuie să fii în același canal cu {user}",
"missingPermissionConnect": "Nu se poate conecta la canalul vocal, permisiuni lipsă",
"missingPermissionSpeak": "Nu pot vorbi în acest canal vocal, asigură-te că am permisiunile corespunzătoare!",
"errorNotFoundPlaylist": "Listă de redare negăsită :(",
"fetchingPlaylist": "⌛ se obține lista de redare...",
"playlistCharLimit": "\nLista de redare depășește limita de caractere...",
"startedPlaylist": "<@{author}> A început o listă de redare",
"cantJoinChannel": "Nu am putut să mă alătur canalului: {error}"
},
"pruning": {
"description": "Comută eliminarea mesajelor botului",
"errorWritingFile": "A apărut o eroare la scrierea în fișier.",
"result": "Eliminarea mesajelor este {result}"
},
"queue": {
"description": "Afișează coada de muzică și melodia care se redă în prezent.",
"missingPermissionMessage": "Permisiunea de a gestiona mesajele sau adăuga reacții lipsește",
"errorNotQueue": "❌ Nimic nu se redă în acest server",
"currentPage": "Pagina curentă - ",
"embedTitle": "Coada de melodii\n",
"embedCurrentSong": "Melodia curentă - {title}\n\n{info}"
},
"remove": {
"description": "Elimină melodia din coadă",
"errorNotQueue": "Nu există o coadă.",
"usageReply": "Utilizare: {prefix}remove <Număr din coadă>",
"result": "<@{author}> ❌ a eliminat {title} din coadă."
},
"resume": {
"description": "Reia redarea muzicii",
"errorNotQueue": "Nu se redă nimic.",
"resultNotPlaying": "<@{author}> ▶ a reluat muzica!",
"errorPlaying": "Coadă nu este pusă pe pauză."
},
"search": {
"description": "Caută și selectează videoclipuri de redat",
"usageReply": "Utilizare: {prefix}{name} <Nume videoclip>",
"errorAlreadyCollector": "Există deja un colector de mesaje activ în acest canal.",
"errorNotChannel": "Trebuie să te alături mai întâi unui canal vocal!",
"resultEmbedTitle": "Răspunde cu numărul melodiei pe care dorești să o redai",
"resultEmbedDesc": "Rezultate pentru: {search}",
"optionQuery": "Căutare"
},
"shuffle": {
"description": "Amestecă coada de melodii",
"errorNotQueue": "Nu există o coadă.",
"result": "<@{author}> 🔀 a amestecat coada"
},
"skip": {
"description": "Trece peste melodia care se redă în prezent",
"errorNotQueue": "Nu se redă nimic ce aș putea să trec peste.",
"result": "<@{author}> ⏭ a trecut peste melodie"
},
"skipto": {
"description": "Sari la numărul selectat din coadă",
"usageReply": "Utilizare: {prefix}{name} <Număr din coadă>",
"errorNotQueue": "Nu există o coadă.",
"errorNotValid": "Coadă are doar {length} melodii!",
"result": "<@{author}> ⏭ a trecut peste {arg} melodii",
"args": {
"number": "Numărul melodiei la care să sari"
}
},
"stop": {
"description": "Oprește muzica",
"errorNotQueue": "Nu se redă nimic.",
"result": "<@{author}> ⏹ a oprit muzica!"
},
"uptime": {
"description": "Verifică timpul de funcționare",
"result": "Timpul de funcționare: {uptime}"
},
"volume": {
"description": "Ajustează volumul muzicii",
"usageReply": "Utilizare: {prefix}volume <Volum>",
"errorNotQueue": "Nu se redă nimic.",
"result": "Volumul este acum {volume}%"
}
}
+180
View File
@@ -0,0 +1,180 @@
{
"clip": {
"description": "Воспроизводит музыку клипа",
"usagesReply": "Использование: {prefix}clip <имя>",
"errorQueue": "Невозможно воспроизвести клип, потому что есть активная очередь.",
"errorNotChannel": "Сначала вам нужно присоединиться к голосовому каналу!"
},
"clips": {
"description": "Список всех клипов"
},
"help": {
"description": "Показать все команды и описания",
"embedTitle": "{botname} Помощь",
"embedDescription": "Список всех команд"
},
"invite": {
"description": "Отправить ссылку для приглашения бота"
},
"loop": {
"description": "Активировать повтор музыки",
"errorNotQueue": "Ничего не играет.",
"result": "Повтор сейчас {loop}"
},
"lyrics": {
"description": "Получить текст для текущей песни",
"errorNotQueue": "Ничего не играет.",
"lyricsNotFound": "Тексты для {title} не найдены.",
"embedTitle": "{title} - Текст песни"
},
"move": {
"description": "Переместить песни в очереди",
"errorNotQueue": "Очереди нет.",
"usagesReply": "Использование: {prefix}move <Номер в очереди>",
"result": "<@{author}> 🚚 **{title}** перемещен на {index} место в очереди.",
"args": {
"movefrom": "Переместить слот из",
"moveto": "Переместить слот в"
}
},
"nowplaying": {
"description": "Показать воспроизводимую песню",
"errorNotQueue": "Ничего не играет.",
"embedTitle": "Сейчас играет",
"live": " ◉ ПРЯМОЙ ЭФИР",
"timeRemaining": "Оставшееся время: {time}"
},
"pause": {
"description": "Приостановить воспроизведение текущей музыки",
"errorNotQueue": "Ничего не играет.",
"result": "<@{author}> ⏸ приостановил музыку."
},
"ping": {
"description": "Показать средний пинг бота",
"result": "📈 Средний пинг до API: {ping} мс"
},
"play": {
"description": "Воспроизведение музыки с YouTube или Soundcloud",
"errorNotChannel": "Сначала вам нужно присоединиться к голосовому каналу!",
"errorNotInSameChannel": "Вы должны быть в том же канале, что и {user}",
"usageReply": "Использование: {prefix}play <Ссылка на YouTube | Название видео | Ссылка на Soundcloud>",
"missingPermissionConnect": "Не удается подключиться к голосовому каналу, отсутствуют соответствующие разрешения",
"missingPermissionSpeak": "Я не могу говорить в этом голосовом канале, убедитесь, что у меня есть соответствующие разрешения!",
"queueAdded": "✅ **{title}** был добавлен в очередь <@{author}>",
"cantJoinChannel": "Не удалось присоединиться к каналу: {error}",
"queueEnded": "❌ Музыкальная очередь закончилась.",
"queueError": "Ошибка: {error}",
"startedPlaying": "🎶 Началось воспроизведение: **{title}** {url}",
"skipSong": "<@{author}> ⏩ пропустил песню",
"pauseSong": "<@{author}> ⏸ приостановил музыку.",
"resumeSong": "<@{author}> ▶ возобновил музыку!",
"unmutedSong": "<@{author}> 🔊 включил звук!",
"mutedSong": "<@{author}> 🔇 выключил звук!",
"decreasedVolume": "<@{author}> 🔉 уменьшил громкость, теперь громкость {volume}%",
"increasedVolume": "<@{author}> 🔊 увеличил громкость, теперь громкость {volume}%",
"loopSong": "<@{author}> Сейчас повторяется {loop}",
"stopSong": "<@{author}> ⏹ остановил музыку!",
"leaveChannel": "Выход из голосового канала...",
"songNotFound": "Песня не найдена",
"songAccessErr": "Видео ограничено по возрасту, закрыто или недоступно",
"errorNoResults": "Результатов не найдено для {url}",
"errorInvalidURL": "Неверный адрес. Вставьте ссылку с YouTube либо попробуйте поиск"
},
"playlist": {
"description": "Воспроизвести плейлист с YouTube",
"usagesReply": "Использование: {prefix}playlist <Ссылка на YouTube плейлист | Название плейлиста>",
"errorNotChannel": "Сначала вам нужно присоединиться к голосовому каналу!",
"errorNotInSameChannel": "Вы должны быть на том же канале, что и {user}",
"missingPermissionConnect": "Не удается подключиться к голосовому каналу, отсутствуют соответствующие разрешения",
"missingPermissionSpeak": "Я не могу говорить в этом голосовом канале, убедитесь, что у меня есть соответствующие разрешения!",
"errorNotFoundPlaylist": "Плейлист не найден :(",
"fetchingPlaylist": "⌛ получение списка воспроизведения...",
"playlistCharLimit": "\nПлейлист превышает ограничение на количество символов...",
"startedPlaylist": "<@{author}> запустил плейлист",
"cantJoinChannel": "Не удалось присоединиться к каналу: {error}"
},
"pruning": {
"description": "Активировать удаление сообщений бота",
"errorWritingFile": "При записи в файл произошла ошибка.",
"result": "Удаление сообщений {result}"
},
"queue": {
"description": "Показать очередь музыки и воспроизводимую композицию.",
"missingPermissionMessage": "Отсутствует разрешение на управление сообщениями или добавление реакций",
"errorNotQueue": "❌ **На этом сервере ничего не играет**",
"currentPage": "Текущая страница - ",
"embedTitle": "Очередь музыки\n",
"embedCurrentSong": "**Текущая песня - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Удалить музыку из очереди",
"errorNotQueue": "Очереди нет.",
"usageReply": "Использование: {prefix}remove <Номер в очереди>",
"result": "<@{author}> ❌ удалено **{title}** из очереди."
},
"resume": {
"description": "Возобновить воспроизведение музыки",
"errorNotQueue": "Ничего не играет.",
"resultNotPlaying": "<@{author}> ▶ возобновил музыку!",
"errorPlaying": "Очередь не приостановлена."
},
"search": {
"description": "Найти и выбрать видео для воспроизведения",
"usageReply": "Использование: {prefix}{name} <Название видео>",
"errorAlreadyCollector": "Сборщик сообщений уже активен на этом канале.",
"errorNotChannel": "Сначала вам нужно присоединиться к голосовому каналу!",
"resultEmbedTitle": "**Ответьте номером песни, которую хотите воспроизвести**",
"resultEmbedDesc": "Результаты для: {search}",
"optionQuery": "Запрос для поиска",
"noResults": "Нету результатов. Попробуйте ввести что-то другое"
},
"shuffle": {
"description": "Перемешать очередь",
"errorNotQueue": "Очереди нет.",
"result": "<@{author}> 🔀 перемешал очередь"
},
"skip": {
"description": "Пропустить текущую воспроизводимую песню",
"errorNotQueue": "Нет ничего такого, что я мог бы пропустить для вас.",
"result": "<@{author}> ⏭ пропустил музыку"
},
"skipto": {
"description": "Перейти к выбранному номеру в очереди",
"usageReply": "Использование: {prefix}{name} <Номер в очереди>",
"errorNotQueue": "Очереди нет.",
"errorNotValid": "В очереди всего {length} трек(ов)!",
"result": "<@{author}> ⏭ пропущено {arg} трек(ов)",
"args": {
"number": "Номер очереди, к которой нужно перейти"
}
},
"stop": {
"description": "Останавливает музыку",
"errorNotQueue": "Ничего не играет.",
"result": "<@{author}> ⏹ остановил музыку!"
},
"uptime": {
"description": "Проверить текущее время работы",
"result": "Время работы: `{days} день(ей),{hours} час(ов), {minutes} минут(ты), {seconds} секунда(ды)`"
},
"volume": {
"description": "Изменение громкости воспроизводимой музыки",
"errorNotQueue": "Ничего не играет.",
"errorNotChannel": "Сначала вам нужно присоединиться к голосовому каналу!",
"currentVolume": "🔊 Текущая громкость: **{volume}%**",
"errorNotNumber": "Пожалуйста, используйте число, чтобы установить громкость.",
"errorNotValid": "Пожалуйста, используйте число между 0 - 100.",
"result": "Громкость установлена ​​на: **{arg}%**"
},
"common": {
"on": "**вкл.**",
"off": "**выкл.**",
"enabled": "**включено**",
"disabled": "**отключено**",
"errorNotChannel": "Сначала вам нужно присоединиться к голосовому каналу!",
"cooldownMessage": "Пожалуйста, подождите {time} секунд(ы) перед повторным использованием `{name}` команды.",
"errorCommand": "При выполнении этой команды произошла ошибка."
},
"Invite me to your server!": "Пригласите меня на свой сервер!",
"Invite": "Пригласить"
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Spelar upp ett klippljud",
"usagesReply": "Användning: /klipp <namn>",
"errorQueue": "Det går inte att spela upp klipp eftersom det finns en aktiv kö.",
"errorNotChannel": "Du måste gå med i en röstkanal först!"
},
"clips": {
"description": "Lista alla klipp"
},
"help": {
"description": "Visa alla kommandon och beskrivningar",
"embedTitle": "{botname} Hjälp",
"embedDescription": "Lista över alla kommandon"
},
"invite": {
"description": "Skicka länk till botinbjudan"
},
"loop": {
"description": "Växla musikslinga",
"errorNotQueue": "Det är inget i kön",
"result": "Musikslinga {loop}"
},
"lyrics": {
"description": "Hämta texter till den spelade låten",
"errorNotQueue": "Det spelar ingenting.",
"lyricsNotFound": "Inga texter hittades för {title}.",
"embedTitle": "{title} - Text"
},
"move": {
"description": "Flytta låtar i kön",
"errorNotQueue": "Det finns inget i kön.",
"usagesReply": "Användning: {prefix} flytta <Könummer>",
"result": "<@{author}> 🚚 flyttade **{title}** till {index} i kön."
},
"nowplaying": {
"description": "Visa nu spelande låt",
"errorNotQueue": "Det finns inget i kön.",
"embedTitle": "Nu spelas",
"live": " ◉ LIVE",
"timeRemaining": "Återstående tid: {time}"
},
"pause": {
"description": "Pausa den musik som för närvarande spelas",
"errorNotQueue": "Det finns inget i kön.",
"result": "<@{author}> ⏸ pausade musiken."
},
"ping": {
"description": "Visa botens genomsnittliga ping",
"result": "📈 Genomsnittlig ping till API: {ping} ms"
},
"play": {
"description": "Spelar upp ljud från YouTube eller Soundcloud",
"errorNotChannel": "Du måste gå med i en röstkanal först!",
"errorNotInSameChannel": "Du måste vara i samma kanal som {user}",
"usageReply": "Användning: {prefix}spela <YouTube URL | Videonamn | Soundcloud URL>",
"missingPermissionConnect": "Det går inte att ansluta till röstkanal, behörighet saknas",
"missingPermissionSpeak": "Jag kan inte prata i den här röstkanalen, se till att jag har rätt behörighet!",
"queueAdded": "✅ ** {title} ** har lagts till i kön av <@{author}>",
"cantJoinChannel": "Det gick inte att gå med i kanalen: {error}",
"queueEnded": "❌ Musikkön avslutades.",
"queueError": "Error: {error}",
"startedPlaying": "🎶 Började spela: **{title}** {url}",
"skipSong": "<@{author}> ⏩ hoppade över låten",
"pauseSong": "<@{author}> ⏸ pausade musiken.",
"resumeSong": "<@{author}> ▶ återupptog musiken!",
"unmutedSong": "<@{author}> 🔊 tystnade på musiken!",
"mutedSong": "<@{author}> 🔇 stängde av musiken!",
"decreasedVolume": "<@{author}> 🔉 minskade volymen, volymen är nu {volume}%",
"increasedVolume": "<@{author}> 🔊 ökade volymen, volymen är nu {volume}%",
"loopSong": "<@{author}> Loop är nu {loop}",
"stopSong": "<@{author}> ⏹ stoppade musiken!",
"leaveChannel": "Lämna röstkanal...",
"songNotFound": "Audio Not Found",
"songAccessErr": "Video is age restricted, private or unavailable"
},
"playlist": {
"description": "Spela en spellista från youtube",
"usagesReply": "Användning: {prefix} spellista <YouTube-spellistans URL | Spellistans namn>",
"errorNotChannel": "Du måste gå med i en röstkanal först!",
"errorNotInSameChannel": "Du måste vara i samma kanal som {user}",
"missingPermissionConnect": "Det går inte att ansluta till röstkanal, behörighet saknas",
"missingPermissionSpeak": "Jag kan inte prata i den här röstkanalen, se till att jag har rätt behörighet!",
"errorNotFoundPlaylist": "Spellistan hittades inte :(",
"fetchingPlaylist": "⌛ hämtar spellistan...",
"playlistCharLimit": "\nSpellista större än teckenbegränsning...",
"startedPlaylist": "<@{author}> Startade en spellista",
"cantJoinChannel": "Det gick inte att gå med i kanalen: {error}"
},
"pruning": {
"description": "Växla beskärning av bot-meddelanden",
"errorWritingFile": "Det gick inte att skriva till filen.",
"result": "Beskärning av meddelanden är {result}"
},
"queue": {
"description": "Visa musikkön och spelar nu.",
"missingPermissionMessage": "Saknar behörighet att hantera meddelanden eller lägga till reaktioner",
"errorNotQueue": "❌ **Ingenting spelas på den här servern**",
"currentPage": "Nuvarande sida -",
"embedTitle": "Låtkö\n",
"embedCurrentSong": "**Aktuell låt - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Ta bort låten från kön",
"errorNotQueue": "Det finns inget i kön.",
"usageReply": "Användning: {prefix}ta bort <Könummer>",
"result": "<@{author}>❌ **{title}** borttagen från kön."
},
"resume": {
"description": "Fortsätt spela musik",
"errorNotQueue": "Det finns inget i kön.",
"resultNotPlaying": "<@{author}> ▶ återupptog musiken!",
"errorPlaying": "Kön är inte pausad."
},
"search": {
"description": "Sök och välj videor att spela",
"usageReply": "Användande: {prefix}{name} <Video Name>",
"errorAlreadyCollector": "En meddelandesamlare är redan aktiv i den här kanalen.",
"errorNotChannel": "Du måste gå med i en röstkanal först!",
"resultEmbedTitle": "**Svara med sångnumret du vill spela**",
"resultEmbedDesc": "Resultat för: {search}"
},
"shuffle": {
"description": "Blanda kö",
"errorNotQueue": "Det finns inget i kön.",
"result": "<@{author}> 🔀 blandade kön"
},
"skip": {
"description": "Hoppa över låten",
"errorNotQueue": "Det finns inget som jag kan hoppa över för dig.",
"result": "<@{author}> ⏭ hoppade över låten"
},
"skipto": {
"description": "Hoppa till valt könummer",
"usageReply": "Användande: {prefix}{name} <Queue Number>",
"errorNotQueue": "Det finns inget i kön.",
"errorNotValid": "Kön är bara {length} låtar lång!",
"result": "<@{author}> ⏭ hoppade över {arg} låtar"
},
"stop": {
"description": "Stoppar musiken",
"errorNotQueue": "Det finns inget i kön.",
"result": "<@{author}> ⏹ stoppade musiken!"
},
"uptime": {
"description": "Kontrollera driftstiden",
"result": "Upptid: '{days} dag(ar), {hours} timmar, {minutes} minuter, {seconds} sekunder`"
},
"volume": {
"description": "Ändra volymen",
"errorNotQueue": "Det spelar ingenting.",
"errorNotChannel": "Du måste gå med i en röstkanal först!",
"currentVolume": "🔊 Den aktuella volymen är: **{volume}%**",
"errorNotNumber": "Använd ett nummer för att ställa in volymen.",
"errorNotValid": "Använd ett nummer mellan 0 - 100.",
"result": "Volym inställd på: **{arg}%**"
},
"common": {
"on": "**på**",
"off": "**av**",
"enabled": "**aktiverad**",
"disabled": "**Inaktiverad**",
"errorNotChannel": "Du måste gå med i en röstkanal först!",
"cooldownMessage": "vänta {time} sekunder till innan du återanvänder kommandot `{name}`.",
"errorCommand": "Det uppstod ett fel vid körningen av kommandot."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "เล่นคลิปเสียง",
"usagesReply": "การใช้งาน: {prefix}clip <ขื่อ>",
"errorQueue": "ไม่สามารถเล่นคลิปเพราะมีคิวที่ใช้งานอยู่.",
"errorNotChannel": "คุณต้องเข้าร่วมช่องเสียงก่อน!"
},
"clips": {
"description": "รายการคลิปทั้งหมด"
},
"help": {
"description": "แสดงคำสั่งและคำอธิบายทั้งหมด",
"embedTitle": "{botname} ช่วย",
"embedDescription": "รายการคำสั่งทั้งหมด"
},
"invite": {
"description": "ส่งลิงค์เชิญบอท"
},
"loop": {
"description": "เปิดเพลงลูป",
"errorNotQueue": "ไม่มีอะไรเล่น.",
"result": "ลูปคือตอนนี้ {loop}"
},
"lyrics": {
"description": "รับเนื้อเพลงสำหรับเพลงที่กำลังเล่นอยู่ในปัจจุบัน",
"errorNotQueue": "ไม่มีอะไรเล่น.",
"lyricsNotFound": "ไม่พบเนื้อเพลง {title}.",
"embedTitle": "{title} - เนื้อเพลง"
},
"move": {
"description": "ย้ายเพลงไปรอบๆ ในคิว",
"errorNotQueue": "ไม่มีคิว.",
"usagesReply": "การใช้งาน: {prefix}move <เลขคิว>",
"result": "<@{author}> 🚚 ย้ายเพลง **{title}** ไป {index} ในคิว."
},
"nowplaying": {
"description": "แสดงเล่นเพลงตอนนี้",
"errorNotQueue": "ไม่มีอะไรเล่น.",
"embedTitle": "กำลังเล่น",
"live": " ◉ LIVE",
"timeRemaining": "เวลาที่เหลืออยู่: {time}"
},
"pause": {
"description": "หยุดเพลงที่กำลังเล่นอยู่ในปัจจุบัน",
"errorNotQueue": "ไม่มีอะไรเล่น.",
"result": "<@{author}> ⏸ หยุดเพลง."
},
"ping": {
"description": "แสดงปิงเฉลี่ยของบอท",
"result": "📈 ปิงเฉลี่ยต่อ API: {ping} ms"
},
"play": {
"description": "เล่นเพลงจาก YouTube หรือ SoundCloud",
"errorNotChannel": "คุณต้องเข้าร่วมช่องเสียงก่อน!",
"errorNotInSameChannel": "คุณต้องอยู่ในช่องเดียวกันกับ {user}",
"usageReply": "การใช้งาน: {prefix}play <ชื่อวิดีโอ หรือ ลิงค์จากYouTube | ลิงค์ SoundCloud>",
"missingPermissionConnect": "ไม่สามารถเชื่อมต่อกับช่องสัญญาณเสียงการอนุญาตที่ขาดหายไป",
"missingPermissionSpeak": "ฉันไม่สามารถพูดในช่องสัญญาณเสียงนี้ให้แน่ใจว่าฉันมีสิทธิ์ที่เหมาะสม!",
"queueAdded": "✅ **{title}** ถูกเพิ่มไปยังคิวโดย <@{author}>",
"cantJoinChannel": "ไม่สามารถเข้าร่วมช่อง: {error}",
"queueEnded": "❌ คิวเพลงสิ้นสุดลง.",
"queueError": "ข้อผิดพลาด: {error}",
"startedPlaying": "🎶 เริ่มเล่นเพลง: **{title}** {url}",
"skipSong": "<@{author}> ⏩ ข้ามเพลง",
"pauseSong": "<@{author}> ⏸ หยุดเพลง.",
"resumeSong": "<@{author}> ▶ ดำเนินการต่อเพลงต่อ!",
"unmutedSong": "<@{author}> 🔊 เปิดเสียงเพลง!",
"mutedSong": "<@{author}> 🔇 ปิดเสียงเพลง!",
"decreasedVolume": "<@{author}> 🔉 ลดระดับเสียงเพลงปริมาณตอนนี้คือ {volume}%",
"increasedVolume": "<@{author}> 🔊 เพิ่มระดับเสียงเพลงปริมาณตอนนี้คือ {volume}%",
"loopSong": "<@{author}> ลูปคือตอนนี้ {loop}",
"stopSong": "<@{author}> ⏹ หยุดเพลง!",
"leaveChannel": "ออกจากช่องเสียง...",
"songNotFound": "ไม่พบเสียง",
"songAccessErr": "วิดีโอมีการจำกัดอายุ เป็นส่วนตัวหรือไม่พร้อมใช้งาน"
},
"playlist": {
"description": "เล่นเพลย์ลิสต์จาก YouTube",
"usagesReply": "การใช้งาน: {prefix}playlist <ชื่อเพลย์ลิสต์ จากYouTube หรือ ลิงค์เพลย์ลิสต์>",
"errorNotChannel": "คุณต้องเข้าร่วมช่องเสียงก่อน!",
"errorNotInSameChannel": "คุณต้องอยู่ในช่องเดียวกันกับ {user}",
"missingPermissionConnect": "ไม่สามารถเชื่อมต่อกับช่องสัญญาณเสียงการอนุญาตที่ขาดหายไป",
"missingPermissionSpeak": "ฉันไม่สามารถพูดในช่องสัญญาณเสียงนี้ให้แน่ใจว่าฉันมีสิทธิ์ที่เหมาะสม!",
"errorNotFoundPlaylist": "ไม่พบเพลย์ลิสต์ :(",
"fetchingPlaylist": "⌛ ดึงเพลย์ลิสต์...",
"playlistCharLimit": "\nเพลย์ลิสต์ใหญ่กว่าขีด จำกัด ของอักขระ...",
"startedPlaylist": "<@{author}> เริ่มเพลย์ลิสต์",
"cantJoinChannel": "ไม่สามารถเข้าร่วมช่อง: {error}"
},
"pruning": {
"description": "สลับการตัดแต่งกิ่งของข้อความบอท",
"errorWritingFile": "มีข้อผิดพลาดในการเขียนไฟล์.",
"result": "การตัดแต่งกิ่งข้อความคือ {result}"
},
"queue": {
"description": "แสดงคิวเพลงและตอนนี้เล่น.",
"missingPermissionMessage": "การอนุญาตที่ขาดหายไปในการจัดการข้อความหรือเพิ่มปฏิกิริยา",
"errorNotQueue": "❌ **ไม่มีอะไรเล่นในเซิร์ฟเวอร์นี้**",
"currentPage": "หน้าปัจจุบัน - ",
"embedTitle": "คิวเพลง\n",
"embedCurrentSong": "**เพลงปัจจุบัน - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "ลบเพลงจากคิว",
"errorNotQueue": "ไม่มีคิว.",
"usageReply": "การใช้งาน: {prefix}remove <เลขคิว>",
"result": "<@{author}> ❌ ลบเพลง **{title}** จากคิว."
},
"resume": {
"description": "ดำเนินการต่อเล่นเพลงต่อในเพลงปัจจุบัน",
"errorNotQueue": "ไม่มีอะไรเล่น.",
"resultNotPlaying": "<@{author}> ▶ ดำเนินการเล่นเพลงต่อ!",
"errorPlaying": "คิวไม่หยุดชั่วคราว."
},
"search": {
"description": "ค้นหาและเลือกวิดีโอเพื่อเล่น",
"usageReply": "การใช้งาน: {prefix}{name} <ชื่อวิดีโอ>",
"errorAlreadyCollector": "ตัวรวบรวมข้อความใช้งานอยู่ในช่องนี้แล้ว.",
"errorNotChannel": "คุณต้องเข้าร่วมช่องเสียงก่อน!",
"resultEmbedTitle": "**ตอบกลับด้วยหมายเลขเพลงที่คุณต้องการเล่น**",
"resultEmbedDesc": "ผลลัพธ์สำหรับ: {search}"
},
"shuffle": {
"description": "สุ่มคิว",
"errorNotQueue": "ไม่มีคิว.",
"result": "<@{author}> 🔀 สุ่มคิว"
},
"skip": {
"description": "ข้ามเพลงที่กำลังเล่นอยู่ในปัจจุบัน",
"errorNotQueue": "ไม่มีอะไรเล่น ที่ฉันสามารถข้ามให้คุณได้.",
"result": "<@{author}> ⏭ ข้ามเพลง"
},
"skipto": {
"description": "ข้ามไปที่หมายเลขคิวที่เลือก",
"usageReply": "การใช้งาน: {prefix}{name} <เลขคิว>",
"errorNotQueue": "ไม่มีคิว",
"errorNotValid": "คิวเป็นเพียง {length} เพลงยาว!",
"result": "<@{author}> ⏭ ข้ามไป {arg} songs"
},
"stop": {
"description": "หยุดเพลง",
"errorNotQueue": "ไม่มีอะไรเล่น.",
"result": "<@{author}> ⏹ หยุดเพลง!"
},
"uptime": {
"description": "ตรวจสอบเวลาทำงาน",
"result": "เวลาต่อไป: `{days} วัน(s),{hours} ชั่วโมง, {minutes} นาที, {seconds} วินาที`"
},
"volume": {
"description": "เปลี่ยนปริมาณการเล่นเพลงในปัจจุบัน",
"errorNotQueue": "ไม่มีอะไรเล่น.",
"errorNotChannel": "คุณต้องเข้าร่วมช่องเสียงก่อน!",
"currentVolume": "🔊 ปริมาณปัจจุบันคือ: **{volume}%**",
"errorNotNumber": "โปรดใช้ตัวเลขเพื่อตั้งค่าระดับเสียง.",
"errorNotValid": "โปรดใช้ตัวเลขระหว่าง 0 - 100.",
"result": "ระดับเสียงที่ตั้งค่าเป็น: **{arg}%**"
},
"common": {
"on": "**เปิด**",
"off": "**ปิด**",
"enabled": "**เปิดใช้งาน**",
"disabled": "**ปิดใช้งาน**",
"errorNotChannel": "คุณต้องเข้าร่วมช่องเสียงก่อน!",
"cooldownMessage": "โปรดรอ {time} ไม่วินาที(s) ก่อนที่จะนำกลับมาใช้ใหม่ `{name}` คำสั้ง.",
"errorCommand": "มีข้อผิดพลาดในการดำเนินการ คำสั้ง."
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "Klip oynatılıyor.",
"usagesReply": "Kullanım: {prefix}clip <isim>",
"errorQueue": "Sırada klip olduğu için oynatılamıyor.",
"errorNotChannel": "Bir sesli kanala girmelisiniz !"
},
"clips": {
"description": "Tüm klipleri listele"
},
"help": {
"description": "Tüm komutları ve açıklamaları görüntüle",
"embedTitle": "{botname} Yardım",
"embedDescription": "Tüm komutlar"
},
"invite": {
"description": "Bot davet bağlantısı gönder"
},
"loop": {
"description": "Müzik döngüsünü aç/kapa",
"errorNotQueue": "Hiçbir şey oynatılmıyor.",
"result": "Döngü {loop}"
},
"lyrics": {
"description": "Çalan şarkının sözlerini getir.",
"errorNotQueue": "Hiçbir şey oynatılmıyor.",
"lyricsNotFound": "Şarkı sözü bulunamadı {title}.",
"embedTitle": "{title} - Sözleri"
},
"move": {
"description": "Şarkıyı sırada taşı",
"errorNotQueue": "Liste bulunamadı.",
"usagesReply": "Kullanım: {prefix} taşı <Liste numarası>",
"result": "<@{author}> 🚚 **{title}** klibini {index}.sıraya taşıdı."
},
"nowplaying": {
"description": "Şimdi çalan şarkıyı göster",
"errorNotQueue": "Hiçbir şey oynatılmıyor.",
"embedTitle": "Şimdi oynatılıyor.",
"live": " ◉ Canlı",
"timeRemaining": "Kalan süre: {time}"
},
"pause": {
"description": "Oynatılan klibi durdur.",
"errorNotQueue": "Hiçbir şey oynatılmıyor.",
"result": "<@{author}> ⏸ müziği durdurdu."
},
"ping": {
"description": "Bot ping testi",
"result": "📈 Ortalama Ping: {ping} ms"
},
"play": {
"description": "YouTube veya Soundcloud'dan ses çalar",
"errorNotChannel": "Bir sesli kanala girmelisiniz !",
"errorNotInSameChannel": "Aynı kanalda olmalısınız {user}",
"usageReply": "Kullanım: {prefix}oynat <YouTube URL | Video İsmi | Soundcloud URL>",
"missingPermissionConnect": "Kanala katılınamadı,gerekli izinler yok.",
"missingPermissionSpeak": "Bu ses kanalında konuşamıyorum, uygun izinlere sahip olduğumdan emin olun!",
"queueAdded": "✅ **{title}** <@{author}> tarafından kuyruğa eklendi.",
"cantJoinChannel": "Kanala katılamadı: {error}",
"queueEnded": "❌ Müzik listesi bitti.",
"queueError": "Hata: {error}",
"startedPlaying": "🎶 Oynatmaya başladı: **{title}** {url}",
"skipSong": "<@{author}> ⏩ şarkıyı atladı",
"pauseSong": "<@{author}> ⏸ müziği durdurdu.",
"resumeSong": "<@{author}> ▶ müziği yeniden oynattı!",
"unmutedSong": "<@{author}> 🔊 şarkının sesini açtı!",
"mutedSong": "<@{author}> 🔇 şarkıyı susturdu!",
"decreasedVolume": "<@{author}> 🔉 sesi azalttı ses seviyesi {volume}%",
"increasedVolume": "<@{author}> 🔊 sesi artırdı ses seviyesi {volume}%",
"loopSong": "<@{author}> Döngü şuan {loop}",
"stopSong": "<@{author}> ⏹ müziği durdurdu!",
"leaveChannel": "Sesli kanaldan çıkıyor...",
"songNotFound": "Audio Not Found",
"songAccessErr": "Video is age restricted, private or unavailable"
},
"playlist": {
"description": "Youtubeden bir çalma listesi oynat",
"usagesReply": "Kullanım: {prefix}şarkı listesi <YouTube Çalma listesi linki | Liste adı>",
"errorNotChannel": "Önce sesli kanala girmelisiniz",
"errorNotInSameChannel": "Aynı kanalda olmalısınız {user}",
"missingPermissionConnect": "Kanala katılınamadı,gerekli izinler yok.",
"missingPermissionSpeak": "Bu ses kanalında konuşamıyorum, uygun izinlere sahip olduğumdan emin olun!",
"errorNotFoundPlaylist": "Çalma listesi bulunamadı :(",
"fetchingPlaylist": "⌛ Oynatma listesi getiriliyor...",
"playlistCharLimit": "\nOynatma listesi karakter sınırından büyük...",
"startedPlaylist": "<@{author}> çalma listesini açtı",
"cantJoinChannel": "Kanala katılamadı: {error}"
},
"pruning": {
"description": "Bot mesajlarının budamasını değiştir",
"errorWritingFile": "Dosyaya yazılırken bir hata oluştu.",
"result": "Mesaj kısaltma {result}"
},
"queue": {
"description": "Müzik listesini ve şuan çalan şarkıyı göster.",
"missingPermissionMessage": "Mesaj yönetimi ve reaksiyon yapılamadı izinler eksik.",
"errorNotQueue": "❌ **Bu sunucuda hiçbir şey oynatılmıyor**",
"currentPage": "Mevcut sayfa - ",
"embedTitle": "Şarkı listesi\n",
"embedCurrentSong": "**Çalan şarkı - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Şarkı listeden kaldırıldı",
"errorNotQueue": "Bir liste yok.",
"usageReply": "Kullanım: {prefix}kaldır <Liste numarası>",
"result": "<@{author}> ❌ listeden kaldırdı **{title}**"
},
"resume": {
"description": "Şarkıyı devam ettir",
"errorNotQueue": "Hiçbir şey çalınmıyor.",
"resultNotPlaying": "<@{author}> ▶ şarkıyı devam ettirdi!",
"errorPlaying": "Liste durdurulmadı."
},
"search": {
"description": "Oynatmak için klip arayın ve seçin",
"usageReply": "Kullanım: {prefix}{name} <Video İsmi>",
"errorAlreadyCollector": "Bu kanalda zaten aktif bir mesaj toplayıcı var.",
"errorNotChannel": "Önce bir sesli kanala katılmalısınız!",
"resultEmbedTitle": "**Oynatmak istediğiniz şarkının numarasını yazınız**",
"resultEmbedDesc": "Sonuçlar: {search}"
},
"shuffle": {
"description": "Listeyi karıştır",
"errorNotQueue": "Bir liste yok.",
"result": "<@{author}> 🔀 listeyi karıştırdı"
},
"skip": {
"description": "Çalan şarkıyı atla",
"errorNotQueue": "Sırada başka şarkı olmadığından atlayamıyorum.",
"result": "<@{author}> ⏭ şarkıyı geçti"
},
"skipto": {
"description": "Seçili liste numarasına atla",
"usageReply": "Kullanım: {prefix}{name} <Liste numarası>",
"errorNotQueue": "Bir liste yok.",
"errorNotValid": "Listede sadece {length} şarkı var!",
"result": "<@{author}> ⏭ şarkıyı {arg} atladı"
},
"stop": {
"description": "Şarkıyı durdurur",
"errorNotQueue": "Şuan hiçbir şey çalınmıyor.",
"result": "<@{author}> ⏹ müziği durdurdu"
},
"uptime": {
"description": "Ne kadar süredir online ",
"result": "Online süresi: `{days} gün,{hours} saat, {minutes} dakika, {seconds} saniye`"
},
"volume": {
"description": "Çalan şarkının ses seviyesini değiştirin",
"errorNotQueue": "Şuan hiçbir şey çalınmıyor.",
"errorNotChannel": "Önce sesli sohbet kanalına girmelisiniz!",
"currentVolume": "🔊 Mevcut ses yüksekliği: **{volume}%**",
"errorNotNumber": "Lütfen ses seviyesini ayarlamak için sayı giriniz.",
"errorNotValid": "Lütfen 0-100 arasında bir sayı giriniz",
"result": "Ses seviyesi: **{arg}%**"
},
"common": {
"on": "**açık**",
"off": "**kapalı**",
"enabled": "**etkinleştirildi**",
"disabled": "**devre dışı bırakıldı**",
"errorNotChannel": "Önce sesli sohbet kanalına girmelisiniz!",
"cooldownMessage": "`{name}` komutunu kullanmak için {time} saniye beklemelisiniz .",
"errorCommand": "Komutu gerçekleştirirken bir hata oluştu."
}
}
+180
View File
@@ -0,0 +1,180 @@
{
"clip": {
"description": "Відтворює музику з кліпу",
"usagesReply": "Використовуйте: {prefix}clip <назва>",
"errorQueue": "Неможливо відтворити кліп, тому що є активна черга.",
"errorNotChannel": "Спочатку вам необхідно приєднатися до голосового каналу!"
},
"clips": {
"description": "Список всіх кліпів"
},
"help": {
"description": "Показати всі команди та їх опис",
"embedTitle": "{botname} Допомога",
"embedDescription": "Перелік всіх команд"
},
"invite": {
"description": "Відправити посилання для запрошення бота"
},
"loop": {
"description": "Повторення музики",
"errorNotQueue": "Нічого не відтворюється.",
"result": "Повторення {loop}"
},
"lyrics": {
"description": "Отримати текст для поточної пісні",
"errorNotQueue": "Нічого не грає.",
"lyricsNotFound": "Тексти для {title} не найдені.",
"embedTitle": "{title} - Текст пісні"
},
"move": {
"description": "Перемістити пісні в черзі",
"errorNotQueue": "Черги немає.",
"usagesReply": "Використовуйте: {prefix}move <Номер в черзі>",
"result": "<@{author}> 🚚 **{title}** переміщений на {index} місце в черзі.",
"args": {
"movefrom": "Перемістити слот з",
"moveto": "Перемістити слот у"
}
},
"nowplaying": {
"description": "Показати пісню, яка відтворюється",
"errorNotQueue": "Нічого не грає.",
"embedTitle": "Зараз грає",
"live": " ◉ ПРЯМА ТРАНСЛЯЦІЯ",
"timeRemaining": "Залишилось часу: {time}"
},
"pause": {
"description": "Призупинити відтворювану в даний момент музику",
"errorNotQueue": "Нічого не грає.",
"result": "<@{author}> ⏸ призупинив музику."
},
"ping": {
"description": "Показати середній пінг бота",
"result": "📈 Середній пінг до API: {ping} ms"
},
"play": {
"description": "Відтворення музики з YouTube або Soundcloud",
"errorNotChannel": "Спочатку вам необхідно приєднатися до голосового каналу!",
"errorNotInSameChannel": "Ви повинні бути в тому ж каналі, що і {user}",
"usageReply": "Використовуйте: {prefix}play <Посилання на YouTube | Назва відео | Посилання на SoundСloud>",
"missingPermissionConnect": "Не вдається підключитися до голосового каналу, відсутні відповідні дозволи",
"missingPermissionSpeak": "Я не можу говорити в цьому голосовому каналі, переконайтесь, що у мене є відповідні дозволи!",
"queueAdded": "✅ **{title}** було додано в чергу <@{author}>",
"cantJoinChannel": "Не вдалось приєднатись до каналу: {error}",
"queueEnded": "❌ Черга відтворення закінчилась.",
"queueError": "Помилка: {error}",
"startedPlaying": "🎶 Почалось відтворення: **{title}** {url}",
"skipSong": "<@{author}> ⏩ пропустив пісню",
"pauseSong": "<@{author}> ⏸ призупинив пісню.",
"resumeSong": "<@{author}> ▶ відновив відтворення пісні!",
"unmutedSong": "<@{author}> 🔊 увімкнув звук!",
"mutedSong": "<@{author}> 🔇 вимкнув звук!",
"decreasedVolume": "<@{author}> 🔉 зменшив гучність, тепер гучність {volume}%",
"increasedVolume": "<@{author}> 🔊 збільшив гучність, тепер гучність {volume}%",
"loopSong": "<@{author}> Зараз повторюється {loop}",
"stopSong": "<@{author}> ⏹ зупинив музику!",
"leaveChannel": "Вихід з голосового каналу...",
"songNotFound": "Пісню не знайдено",
"songAccessErr": "Відео недоступне, приватне або має вікові обмеження",
"errorNoResults": "Результатів не знайдено для {url}",
"errorInvalidURL": "Недійсна адреса. Вставте посилання с YouTube або спробуйте пошук"
},
"playlist": {
"description": "Відтворити плейлист з YouTube",
"usagesReply": "Використовуйте: {prefix}playlist <Посилання на плейлист YouTube | Назва плейлиста>",
"errorNotChannel": "Спочатку вам необхідно приєднатися до голосового каналу!",
"errorNotInSameChannel": "Ви повинні бути в тому ж каналі, що і {user}",
"missingPermissionConnect": "Не вдається підключитися до голосового каналу, відсутні дозволи",
"missingPermissionSpeak": "Я не можу говорити в цьому голосовому каналі, переконайтесь, що у мене є відповідні дозволи!",
"errorNotFoundPlaylist": "Плейлист не знайдено :(",
"fetchingPlaylist": "⌛ отримання списку відтворення...",
"playlistCharLimit": "\nПлейлист перевищує обмеження на кількість символів...",
"startedPlaylist": "<@{author}> запустив плейлист",
"cantJoinChannel": "Не вдалось приєднатись до каналу: {error}"
},
"pruning": {
"description": "Увімкнути обрізку повідомлень бота",
"errorWritingFile": "При записі в файл виникла помилка.",
"result": "Видалення повідомлень {result}"
},
"queue": {
"description": "Показати чергу відтворення і те що зараз відтворюється.",
"missingPermissionMessage": "Відсутні дозволи на керування повідомленнями або додавання реакцій",
"errorNotQueue": "❌ **На цьому сервері нічого не грає**",
"currentPage": "Поточна сторінка - ",
"embedTitle": "Черга відтворення\n",
"embedCurrentSong": "**Поточна пісня - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Видалити пісню з черги",
"errorNotQueue": "Черга пуста.",
"usageReply": "Використовуйте: {prefix}remove <Номер в черзі>",
"result": "<@{author}> ❌ видалив **{title}** з черги."
},
"resume": {
"description": "Відновити відтворення музики",
"errorNotQueue": "Нічого не грає.",
"resultNotPlaying": "<@{author}> ▶ відновив відтворення!",
"errorPlaying": "Черга не призупинена."
},
"search": {
"description": "Знайдіть і виберіть відео для відтворення",
"usageReply": "Використовуйте: {prefix}{name} <Назва відео>",
"errorAlreadyCollector": "Збиральник повідомлень вже активний в цьому каналі.",
"errorNotChannel": "Спочатку вам необхідно приєднатися до голосового каналу!",
"resultEmbedTitle": "**Дайте відповідь номером пісні, яку хочете відтворити**",
"resultEmbedDesc": "Результати для: {search}",
"optionQuery": "Запит для пошуку",
"noResults": "Немає результатів. Спробуйте щось інше"
},
"shuffle": {
"description": "Перемішати чергу",
"errorNotQueue": "Черга пуста.",
"result": "<@{author}> 🔀 перемішав чергу"
},
"skip": {
"description": "Пропустити відтворювану в даний момент пісню",
"errorNotQueue": "Немає нічого з того, що я би міг пропустити.",
"result": "<@{author}> ⏭ пропустив пісню"
},
"skipto": {
"description": "Перейти до вибраного номеру в черзі",
"usageReply": "Використовуйте: {prefix}{name} <Номер в черзі>",
"errorNotQueue": "Черга пуста.",
"errorNotValid": "В черзі всього {length} пісня(ень)!",
"result": "<@{author}> ⏭ пропущено {arg} пісня(ень)",
"args": {
"number": "Номер черги, до якої потрібно перейти"
}
},
"stop": {
"description": "Зупиняє музику",
"errorNotQueue": "Нічого не відтворюється.",
"result": "<@{author}> ⏹ зупинив музику!"
},
"uptime": {
"description": "Перевірити час безвідмовної роботи",
"result": "Час роботи: `{days} День(ів),{hours} година(ин), {minutes} хвилина(ин), {seconds} секунда(ди)`"
},
"volume": {
"description": "Змінити гучність відтворюваної музики",
"errorNotQueue": "Нічого не відтворюється.",
"errorNotChannel": "Спочатку вам необхідно приєднатися до голосового каналу!",
"currentVolume": "🔊 Поточна гучність: **{volume}%**",
"errorNotNumber": "Будь ласка, використовуйте число, щоб встановити гучність.",
"errorNotValid": "Будь ласка, використовуйте число від 0 до 100.",
"result": "Гучність встановлена ​​на: **{arg}%**"
},
"common": {
"on": "**Увімк.**",
"off": "**Вимк.**",
"enabled": "**увімкнено**",
"disabled": "**вимкнено**",
"errorNotChannel": "Спочатку вам необхідно приєднатися до голосового каналу!",
"cooldownMessage": "Будь ласка, зачекайте {time} секунд перед повторним використанням `{name}` команди.",
"errorCommand": "При виконанні цієї команди виникла помилка."
},
"Invite me to your server!": "Запросіть мене на свій сервер!",
"Invite": "Запросити"
}
+180
View File
@@ -0,0 +1,180 @@
{
"clip": {
"description": "Phát một đoạn âm thanh",
"usagesReply": "Sử dụng: {prefix}clip <tên>",
"errorQueue": "Không thể phát một đoạn âm thanh vì có hàng đợi đang hoạt động.",
"errorNotChannel": "Bạn cần tham gia kênh thoại trước!"
},
"clips": {
"description": "Liệt kê tất cả các đoạn âm thanh có sẵn"
},
"help": {
"description": "Hiển thị tất cả các lệnh và mô tả",
"embedTitle": "Trợ giúp {botname}",
"embedDescription": "Danh sách tất cả các lệnh"
},
"invite": {
"description": "Gửi liên kết mời bot."
},
"loop": {
"description": "Bật tắt chức năng lặp lại",
"errorNotQueue": "Không có gì đang phát.",
"result": "Lặp hiện tại là {loop}"
},
"lyrics": {
"description": "Hiển thị lời bài hát của bài nhạc đang phát",
"errorNotQueue": "Không có bài nhạc nào đang phát.",
"lyricsNotFound": "Không tìm thấy lời cho bài hát {title}.",
"embedTitle": "{title} - Lời bài hát"
},
"move": {
"description": "Di chuyển bài hát trong hàng đợi",
"errorNotQueue": "Không có hàng đợi nào.",
"usagesReply": "Sử dụng: {prefix}move <Số Thứ Tự Hàng Đợi>",
"result": "<@{author}> 🚚 đã di chuyển **{title}** đến vị trí {index} trong hàng đợi.",
"args": {
"movefrom": "Vị trí di chuyển từ",
"moveto": "Vị trí di chuyển đến"
}
},
"nowplaying": {
"description": "Hiển thị bài hát đang phát",
"errorNotQueue": "Không có gì đang phát.",
"embedTitle": "Đang phát",
"live": " ◉ TRỰC TIẾP",
"timeRemaining": "Thời Gian Còn Lại: {time}"
},
"pause": {
"description": "Tạm dừng âm nhạc đang phát",
"errorNotQueue": "Không có gì đang phát.",
"result": "<@{author}> ⏸ đã tạm dừng âm nhạc."
},
"ping": {
"description": "Hiển thị độ trễ trung bình của bot",
"result": "📈 Độ trễ trung bình đến API: {ping} ms"
},
"play": {
"description": "Phát âm thanh từ YouTube",
"errorNotChannel": "Bạn cần tham gia kênh thoại trước!",
"errorNotInSameChannel": "Bạn phải ở trong cùng một kênh với {user}",
"usageReply": "Sử dụng: {prefix}play <URL YouTube | Tên Video>",
"missingPermissionConnect": "Không thể kết nối đến kênh thoại, thiếu quyền hạn",
"missingPermissionSpeak": "Tôi không thể nói trong kênh thoại này, hãy chắc chắn rằng tôi có đủ quyền!",
"queueAdded": "✅ **{title}** đã được thêm vào hàng đợi bởi <@{author}>",
"cantJoinChannel": "Không thể tham gia kênh: {error}",
"queueEnded": "❌ Hết hàng đợi âm nhạc.",
"queueError": "Lỗi: {error}",
"startedPlaying": "🎶 Bắt đầu phát: **{title}** {url}",
"skipSong": "<@{author}> ⏩ đã bỏ qua bài hát.",
"pauseSong": "<@{author}> ⏸ đã tạm dừng âm nhạc.",
"resumeSong": "<@{author}> ▶ đã tiếp tục phát âm nhạc!",
"unmutedSong": "<@{author}> 🔊 đã bỏ tắt âm nhạc!",
"mutedSong": "<@{author}> 🔇 đã tắt âm nhạc!",
"decreasedVolume": "<@{author}> 🔉 đã giảm âm lượng, âm lượng hiện tại là {volume}%",
"increasedVolume": "<@{author}> 🔊 đã tăng âm lượng, âm lượng hiện tại là {volume}%",
"loopSong": "<@{author}> Lặp hiện tại là {loop}",
"stopSong": "<@{author}> ⏹ đã dừng âm nhạc!",
"leaveChannel": "Rời khỏi kênh thoại...",
"songNotFound": "Không tìm thấy âm thanh",
"songAccessErr": "Video có giới hạn độ tuổi, riêng tư hoặc không khả dụng",
"errorNoResults": "Không có kết quả cho {url}",
"errorInvalidURL": "URL không hợp lệ, vui lòng thử tìm kiếm hoặc nhập URL YouTube"
},
"playlist": {
"description": "Phát danh sách phát từ youtube",
"usagesReply": "Sử dụng: {prefix}playlist <URL Danh sách phát YouTube | Tên Danh sách phát>",
"errorNotChannel": "Bạn cần tham gia kênh thoại trước!",
"errorNotInSameChannel": "Bạn phải ở trong cùng một kênh với {user}",
"missingPermissionConnect": "Không thể kết nối đến kênh thoại, thiếu quyền hạn",
"missingPermissionSpeak": "Tôi không thể nói trong kênh thoại này, hãy chắc chắn rằng tôi có đủ quyền!",
"errorNotFoundPlaylist": "Không tìm thấy danh sách phát :(",
"fetchingPlaylist": "⌛ đang tải danh sách phát...",
"playlistCharLimit": "\nDanh sách phát lớn hơn giới hạn ký tự...",
"startedPlaylist": "<@{author}> Bắt đầu danh sách phát",
"cantJoinChannel": "Không thể tham gia kênh: {error}"
},
"pruning": {
"description": "Tùy chỉnh xóa tin nhắn của bot",
"errorWritingFile": "Có lỗi khi ghi vào tệp.",
"result": "Tự động xóa tin nhắn hiện đang {result}"
},
"queue": {
"description": "Hiển thị hàng đợi âm nhạc và bài hát đang phát.",
"missingPermissionMessage": "Thiếu quyền để quản lý tin nhắn hoặc thêm biểu tượng",
"errorNotQueue": "❌ **Không có gì đang phát trong máy chủ này**",
"currentPage": "Trang Hiện Tại - ",
"embedTitle": "Hàng Đợi Bài Hát\n",
"embedCurrentSong": "**Bài Hát Đang Phát - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "Xóa bài hát khỏi hàng đợi",
"errorNotQueue": "Không có hàng đợi nào.",
"usageReply": "Sử dụng: {prefix}remove <Số Thứ Tự Hàng Đợi>",
"result": "<@{author}> ❌ đã xóa **{title}** khỏi hàng đợi."
},
"resume": {
"description": "Tiếp tục phát âm nhạc đang phát",
"errorNotQueue": "Không có gì đang phát.",
"resultNotPlaying": "<@{author}> ▶ đã tiếp tục phát âm nhạc!",
"errorPlaying": "Hàng đợi không tạm dừng."
},
"search": {
"description": "Tìm kiếm và chọn video để phát",
"usageReply": "Sử dụng: {prefix}{name} <Tên Video>",
"errorAlreadyCollector": "Hiện đang có một người dùng khác đang tìm kiếm trong kênh này.",
"errorNotChannel": "Bạn cần tham gia kênh thoại trước!",
"resultEmbedTitle": "**Trả lời với số bài hát bạn muốn phát**",
"resultEmbedDesc": "Kết quả cho: {search}",
"optionQuery": "Truy vấn tìm kiếm",
"noResults": "Không có kết quả cho truy vấn, vui lòng thử một cái gì khác"
},
"shuffle": {
"description": "Xáo trộn hàng đợi",
"errorNotQueue": "Không có hàng đợi nào.",
"result": "<@{author}> 🔀 đã xáo trộn hàng đợi"
},
"skip": {
"description": "Bỏ qua bài hát đang phát",
"errorNotQueue": "Không có gì đang phát để bỏ qua cho bạn.",
"result": "<@{author}> ⏭ đã bỏ qua bài hát"
},
"skipto": {
"description": "Bỏ qua đến số hàng đợi được chọn",
"usageReply": "Sử dụng: {prefix}{name} <Số Thứ Tự Hàng Đợi>",
"errorNotQueue": "Không có hàng đợi nào.",
"errorNotValid": "Hàng đợi chỉ có {length} bài hát!",
"result": "<@{author}> ⏭ đã bỏ qua {arg} bài hát",
"args": {
"number": "Số thứ tự hàng đợi để bỏ qua đến"
}
},
"stop": {
"description": "Dừng âm nhạc",
"errorNotQueue": "Không có gì đang phát.",
"result": "<@{author}> ⏹ đã dừng âm nhạc!"
},
"uptime": {
"description": "Kiểm tra thời gian hoạt động",
"result": "Thời Gian Hoạt Động: `{days} ngày, {hours} giờ, {minutes} phút, {seconds} giây`."
},
"volume": {
"description": "Thay đổi âm lượng của âm nhạc đang phát",
"errorNotQueue": "Không có gì đang phát.",
"errorNotChannel": "Bạn cần tham gia kênh thoại trước!",
"currentVolume": "🔊 Âm lượng hiện tại là: **{volume}%**",
"errorNotNumber": "Vui lòng sử dụng số để đặt âm lượng.",
"errorNotValid": "Vui lòng sử dụng số từ 0 - 100.",
"result": "Âm lượng được đặt là: **{arg}%**"
},
"common": {
"on": "**Bật**",
"off": "**Tắt**",
"enabled": "**Bật**",
"disabled": "**Tắt**",
"errorNotChannel": "Bạn cần tham gia kênh thoại trước!",
"cooldownMessage": "vui lòng đợi thêm {time} giây trước khi sử dụng lại lệnh `{name}`.",
"errorCommand": "Có lỗi khi thực hiện lệnh đó."
},
"Invite me to your server!": "Mời tôi vào máy chủ của bạn!",
"Invite": "Mời"
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "播放本地音乐",
"usagesReply": "用法: {prefix}clip <名称>",
"errorQueue": "无法播放本地音乐,因为目前已经有有效的音乐队列",
"errorNotChannel": "你必须先加入语音频道!"
},
"clips": {
"description": "列出所有本地音乐"
},
"help": {
"description": "列出所有指令的详细资讯",
"embedTitle": "{botname} 帮助",
"embedDescription": "所有的指令清单"
},
"invite": {
"description": "传送邀请连结"
},
"loop": {
"description": "变更音乐重複设定",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "重複播放已经 {loop}"
},
"lyrics": {
"description": "取得当前播放的歌曲歌词",
"errorNotQueue": "现在没有任何歌曲正在播放",
"lyricsNotFound": "没有找到 {title} 的歌词",
"embedTitle": "{title} - 歌词"
},
"move": {
"description": "移动歌曲到队列的其他位置",
"errorNotQueue": "队列中没有歌曲",
"usagesReply": "用法: {prefix}move <歌曲队列编号>",
"result": "<@{author}> 🚚 从音乐队列中移动 **{title}** 至 {index}"
},
"nowplaying": {
"description": "显示现在播放什麽",
"errorNotQueue": "现在没有任何歌曲正在播放",
"embedTitle": "现正播放",
"live": " ◉ 直播",
"timeRemaining": "剩馀时间: {time}"
},
"pause": {
"description": "暂停当前歌曲",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> ⏸ 暂停了歌曲"
},
"ping": {
"description": "查看机器人延迟平均值",
"result": "📈 API延迟平均值: {ping} 毫秒"
},
"play": {
"description": "播放 YouTube 或 Soundcloud 的音乐",
"errorNotChannel": "你必须先加入语音频道!",
"errorNotInSameChannel": "你必须跟 {user} 在同一个频道裡",
"usageReply": "Usage: {prefix}play <YouTube 网址 | 影片名称 | Soundcloud 网址>",
"missingPermissionConnect": "无法连结至语音频道,没有权限",
"missingPermissionSpeak": "我无法在语音频道裡说话,请确定我有相关的权限!",
"queueAdded": "✅ **{title}** 已经被 <@{author}> 加入音乐队列",
"cantJoinChannel": "无法加入语音频道: {error}",
"queueEnded": "❌ 音乐队列完结",
"queueError": "错误: {error}",
"startedPlaying": "🎶 开始播放: **{title}** {url}",
"skipSong": "<@{author}> ⏩ 跳过了歌曲",
"pauseSong": "<@{author}> ⏸ 暂停了歌曲 music.",
"resumeSong": "<@{author}> ▶ 恢復了音乐!",
"unmutedSong": "<@{author}> 🔊 解除静音了音乐!",
"mutedSong": "<@{author}> 🔇 静音了音乐!",
"decreasedVolume": "<@{author}> 🔉 降低了音量, 目前音量为 {volume}%",
"increasedVolume": "<@{author}> 🔊 增加了音量, 目前音量为 {volume}%",
"loopSong": "<@{author}> 重複播放目前是 {loop}",
"stopSong": "<@{author}> ⏹ 停止了歌曲!",
"leaveChannel": "正在离开语音频道...",
"songNotFound": "没有找到曲目",
"songAccessErr": "视频有年龄限制、私人或不可用"
},
"playlist": {
"description": "播放 YouTube 的播放清单",
"usagesReply": "用法: {prefix}playlist <YouTube 播放清单网址 | 播放清单名称>",
"errorNotChannel": "你必须先加入语音频道!",
"errorNotInSameChannel": "你必须跟 {user} 在同一个频道裡",
"missingPermissionConnect": "无法加入语音频道,没有讯息",
"missingPermissionSpeak": "我无法在语音频道裡说话,请确定我有相关的权限!",
"errorNotFoundPlaylist": "没有找到播放清单 :(",
"fetchingPlaylist": "⌛ 正在取得播放清单...",
"playlistCharLimit": "\n播放清单大于限制的歌曲数目...",
"startedPlaylist": "<@{author}> 开始播放播放清单",
"cantJoinChannel": "无法加入语音频道: {error}"
},
"pruning": {
"description": "变更机器人精简模式",
"errorWritingFile": "在写入档案时發生错误",
"result": "讯息精简模式为 {result}"
},
"queue": {
"description": "列出音乐队列",
"missingPermissionMessage": "没有权限管理讯息或新增反应",
"errorNotQueue": "❌ **现在没有任何歌曲正在播放**",
"currentPage": "目前页面 - ",
"embedTitle": "伺服器音乐队列\n",
"embedCurrentSong": "**当前歌曲 - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "从音乐队列移除歌曲",
"errorNotQueue": "现在没有任何歌曲正在播放",
"usageReply": "用法: {prefix}remove <歌曲队列编号>",
"result": "<@{author}> ❌ 从音乐队列移除了 **{title}**"
},
"resume": {
"description": "恢復播放音乐",
"errorNotQueue": "现在没有任何歌曲正在播放",
"resultNotPlaying": "<@{author}> ▶ 恢復了音乐!",
"errorPlaying": "音乐队列没有被暂停"
},
"search": {
"description": "搜寻以及选择歌曲",
"usageReply": "用法: {prefix}{name} <影片名称>",
"errorAlreadyCollector": "讯息接收器已经在这个频道上启用",
"errorNotChannel": "你必须先加入语音频道!",
"resultEmbedTitle": "**回复你想要播放的歌曲代码**",
"resultEmbedDesc": "搜寻{search}的结果"
},
"shuffle": {
"description": "随机排序音乐队列",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> 🔀 随机排序了音乐队列"
},
"skip": {
"description": "跳过当前歌曲",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> ⏭ 跳过了歌曲"
},
"skipto": {
"description": "跳到指定的歌曲",
"usageReply": "用法: {prefix}{name} <歌曲队列编号>",
"errorNotQueue": "现在没有任何歌曲正在播放",
"errorNotValid": "音乐队列只有 {length} 个歌曲!",
"result": "<@{author}> ⏭ 跳过了 {arg} 歌曲"
},
"stop": {
"description": "停止音乐队列",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> ⏹ 停止了队列!"
},
"uptime": {
"description": "查看机器人上线时间",
"result": "上线时间: `{days} 天,{hours} 小时, {minutes} 分钟, {seconds} 秒`"
},
"volume": {
"description": "变更目前歌曲音量",
"errorNotQueue": "现在没有任何歌曲正在播放",
"errorNotChannel": "你必须先加入语音频道!",
"currentVolume": "🔊 当前音量为: **{volume}%**",
"errorNotNumber": "请使用数字来变更音量",
"errorNotValid": "请使用 0 - 100 的数字!",
"result": "音量设置为: **{arg}%**"
},
"common": {
"on": "**启动**",
"off": "**关闭**",
"enabled": "**开启**",
"disabled": "**关闭**",
"errorNotChannel": "你必须先加入语音频道!",
"cooldownMessage": "请等待 {time} 秒后再使用 `{name}` 指令",
"errorCommand": "执行指令时發生错误"
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "播放本地音乐",
"usagesReply": "用法: {prefix}clip <名称>",
"errorQueue": "无法播放本地音乐,因为目前已经有有效的音乐队列",
"errorNotChannel": "你必须先加入语音频道!"
},
"clips": {
"description": "列出所有本地音乐"
},
"help": {
"description": "列出所有指令的详细资讯",
"embedTitle": "{botname} 帮助",
"embedDescription": "所有的指令清单"
},
"invite": {
"description": "传送邀请连结"
},
"loop": {
"description": "变更音乐重複设定",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "重複播放已经 {loop}"
},
"lyrics": {
"description": "取得当前播放的歌曲歌词",
"errorNotQueue": "现在没有任何歌曲正在播放",
"lyricsNotFound": "没有找到 {title} 的歌词",
"embedTitle": "{title} - 歌词"
},
"move": {
"description": "移动歌曲到队列的其他位置",
"errorNotQueue": "没有队列",
"usagesReply": "用法: {prefix}move <歌曲队列编号>",
"result": "<@{author}> 🚚 从音乐队列中移动 **{title}** 至 {index}"
},
"nowplaying": {
"description": "显示现在播放什麽",
"errorNotQueue": "现在没有任何歌曲正在播放",
"embedTitle": "现正播放",
"live": " ◉ 直播",
"timeRemaining": "剩馀时间: {time}"
},
"pause": {
"description": "暂停当前歌曲",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> ⏸ 暂停了歌曲"
},
"ping": {
"description": "查看机器人延迟平均值",
"result": "📈 API延迟平均值: {ping} 毫秒"
},
"play": {
"description": "播放 YouTube 或 Soundcloud 的音乐",
"errorNotChannel": "你必须先加入语音频道!",
"errorNotInSameChannel": "你必须跟 {user} 在同一个频道裡",
"usageReply": "Usage: {prefix}play <YouTube 网址 | 影片名称 | Soundcloud 网址>",
"missingPermissionConnect": "无法连结至语音频道,没有权限",
"missingPermissionSpeak": "我无法在语音频道裡说话,请确定我有相关的权限!",
"queueAdded": "✅ **{title}** 已经被 <@{author}> 加入音乐队列",
"cantJoinChannel": "无法加入语音频道: {error}",
"queueEnded": "❌ 音乐队列完结",
"queueError": "错误: {error}",
"startedPlaying": "🎶 开始播放: **{title}** {url}",
"skipSong": "<@{author}> ⏩ 跳过了歌曲",
"pauseSong": "<@{author}> ⏸ 暂停了歌曲 music.",
"resumeSong": "<@{author}> ▶ 恢復了音乐!",
"unmutedSong": "<@{author}> 🔊 解除静音了音乐!",
"mutedSong": "<@{author}> 🔇 静音了音乐!",
"decreasedVolume": "<@{author}> 🔉 降低了音量, 目前音量为 {volume}%",
"increasedVolume": "<@{author}> 🔊 增加了音量, 目前音量为 {volume}%",
"loopSong": "<@{author}> 重複播放目前是 {loop}",
"stopSong": "<@{author}> ⏹ 停止了歌曲!",
"leaveChannel": "正在离开语音频道...",
"songNotFound": "没有找到曲目",
"songAccessErr": "视频有年龄限制、私人或不可用"
},
"playlist": {
"description": "播放 YouTube 的播放清单",
"usagesReply": "用法: {prefix}playlist <YouTube 播放清单网址 | 播放清单名称>",
"errorNotChannel": "你必须先加入语音频道!",
"errorNotInSameChannel": "你必须跟 {user} 在同一个频道裡",
"missingPermissionConnect": "无法加入语音频道,没有讯息",
"missingPermissionSpeak": "我无法在语音频道裡说话,请确定我有相关的权限!",
"errorNotFoundPlaylist": "没有找到播放清单 :(",
"fetchingPlaylist": "⌛ 正在取得播放清单...",
"playlistCharLimit": "\n播放清单大于限制的歌曲数目...",
"startedPlaylist": "<@{author}> 开始播放播放清单",
"cantJoinChannel": "无法加入语音频道: {error}"
},
"pruning": {
"description": "变更机器人精简模式",
"errorWritingFile": "在写入档案时發生错误",
"result": "讯息精简模式为 {result}"
},
"queue": {
"description": "列出音乐队列",
"missingPermissionMessage": "没有权限管理讯息或新增反应",
"errorNotQueue": "❌ **现在没有任何歌曲正在播放**",
"currentPage": "目前页面 - ",
"embedTitle": "伺服器音乐队列\n",
"embedCurrentSong": "**当前歌曲 - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "从音乐队列移除歌曲",
"errorNotQueue": "现在没有任何歌曲正在播放",
"usageReply": "用法: {prefix}remove <歌曲队列编号>",
"result": "<@{author}> ❌ 从音乐队列移除了 **{title}**"
},
"resume": {
"description": "恢復播放音乐",
"errorNotQueue": "现在没有任何歌曲正在播放",
"resultNotPlaying": "<@{author}> ▶ 恢復了音乐!",
"errorPlaying": "音乐队列没有被暂停"
},
"search": {
"description": "搜寻以及选择歌曲",
"usageReply": "用法: {prefix}{name} <影片名称>",
"errorAlreadyCollector": "讯息接收器已经在这个频道上启用",
"errorNotChannel": "你必须先加入语音频道!",
"resultEmbedTitle": "**回复你想要播放的歌曲代码**",
"resultEmbedDesc": "搜寻{search}的结果"
},
"shuffle": {
"description": "随机排序音乐队列",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> 🔀 随机排序了音乐队列"
},
"skip": {
"description": "跳过当前歌曲",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> ⏭ 跳过了歌曲"
},
"skipto": {
"description": "跳到指定的歌曲",
"usageReply": "用法: {prefix}{name} <歌曲队列编号>",
"errorNotQueue": "现在没有任何歌曲正在播放",
"errorNotValid": "音乐队列只有 {length} 个歌曲!",
"result": "<@{author}> ⏭ 跳过了 {arg} 歌曲"
},
"stop": {
"description": "停止音乐队列",
"errorNotQueue": "现在没有任何歌曲正在播放",
"result": "<@{author}> ⏹ 停止了队列!"
},
"uptime": {
"description": "查看机器人上线时间",
"result": "上线时间: `{days} 天,{hours} 小时, {minutes} 分钟, {seconds} 秒`"
},
"volume": {
"description": "变更目前歌曲音量",
"errorNotQueue": "现在没有任何歌曲正在播放",
"errorNotChannel": "你必须先加入语音频道!",
"currentVolume": "🔊 当前音量为: **{volume}%**",
"errorNotNumber": "请使用数字来变更音量",
"errorNotValid": "请使用 0 - 100 的数字!",
"result": "音量设置为: **{arg}%**"
},
"common": {
"on": "**启动**",
"off": "**关闭**",
"enabled": "**开启**",
"disabled": "**关闭**",
"errorNotChannel": "你必须先加入语音频道!",
"cooldownMessage": "请等待 {time} 秒后再使用 `{name}` 指令",
"errorCommand": "执行指令时發生错误"
}
}
+167
View File
@@ -0,0 +1,167 @@
{
"clip": {
"description": "播放本地音樂",
"usagesReply": "用法: {prefix}clip <名稱>",
"errorQueue": "無法播放本地音樂,因為目前已經有有效的音樂隊列",
"errorNotChannel": "你必須先加入語音頻道!"
},
"clips": {
"description": "列出所有本地音樂"
},
"help": {
"description": "列出所有指令的詳細資訊",
"embedTitle": "{botname} 幫助",
"embedDescription": "所有的指令清單"
},
"invite": {
"description": "傳送邀請連結"
},
"loop": {
"description": "變更音樂重複設定",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"result": "重複播放已經 {loop}"
},
"lyrics": {
"description": "取得當前播放的歌曲歌詞",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"lyricsNotFound": "沒有找到 {title} 的歌詞",
"embedTitle": "{title} - 歌詞"
},
"move": {
"description": "移動歌曲到隊列的其他位置",
"errorNotQueue": "隊列中沒有歌曲",
"usagesReply": "用法: {prefix}move <歌曲隊列編號>",
"result": "<@{author}> 🚚 從音樂隊列中移動 **{title}** 至 {index}"
},
"nowplaying": {
"description": "顯示現在播放什麼",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"embedTitle": "現正播放",
"live": " ◉ 直播",
"timeRemaining": "剩餘時間: {time}"
},
"pause": {
"description": "暫停當前歌曲",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"result": "<@{author}> ⏸ 暫停了歌曲"
},
"ping": {
"description": "查看機器人延遲平均值",
"result": "📈 API延遲平均值: {ping} 毫秒"
},
"play": {
"description": "播放 YouTube 或 Soundcloud 的音樂",
"errorNotChannel": "你必須先加入語音頻道!",
"errorNotInSameChannel": "你必須跟 {user} 在同一個頻道裡",
"usageReply": "Usage: {prefix}play <YouTube 網址 | 影片名稱 | Soundcloud 網址>",
"missingPermissionConnect": "無法連結至語音頻道,沒有權限",
"missingPermissionSpeak": "我無法在語音頻道裡說話,請確定我有相關的權限!",
"queueAdded": "✅ **{title}** 已經被 <@{author}> 加入音樂隊列",
"cantJoinChannel": "無法加入語音頻道: {error}",
"queueEnded": "❌ 音樂隊列完結",
"queueError": "錯誤: {error}",
"startedPlaying": "🎶 開始播放: **{title}** {url}",
"skipSong": "<@{author}> ⏩ 跳過了歌曲",
"pauseSong": "<@{author}> ⏸ 暫停了歌曲 music.",
"resumeSong": "<@{author}> ▶ 恢復了音樂!",
"unmutedSong": "<@{author}> 🔊 解除靜音了音樂!",
"mutedSong": "<@{author}> 🔇 靜音了音樂!",
"decreasedVolume": "<@{author}> 🔉 降低了音量, 目前音量為 {volume}%",
"increasedVolume": "<@{author}> 🔊 增加了音量, 目前音量為 {volume}%",
"loopSong": "<@{author}> 重複播放目前是 {loop}",
"stopSong": "<@{author}> ⏹ 停止了歌曲!",
"leaveChannel": "正在離開語音頻道...",
"songNotFound": "沒有找到曲目",
"songAccessErr": "视频有年龄限制、私人或不可用"
},
"playlist": {
"description": "播放 YouTube 的播放清單",
"usagesReply": "用法: {prefix}playlist <YouTube 播放清單網址 | 播放清單名稱>",
"errorNotChannel": "你必須先加入語音頻道!",
"errorNotInSameChannel": "你必須跟 {user} 在同一個頻道裡",
"missingPermissionConnect": "無法加入語音頻道,沒有訊息",
"missingPermissionSpeak": "我無法在語音頻道裡說話,請確定我有相關的權限!",
"errorNotFoundPlaylist": "沒有找到播放清單 :(",
"fetchingPlaylist": "⌛ 正在取得播放清單...",
"playlistCharLimit": "\n播放清單大於限制的歌曲數目...",
"startedPlaylist": "<@{author}> 開始播放播放清單",
"cantJoinChannel": "無法加入語音頻道: {error}"
},
"pruning": {
"description": "變更機器人精簡模式",
"errorWritingFile": "在寫入檔案時發生錯誤",
"result": "訊息精簡模式為 {result}"
},
"queue": {
"description": "列出音樂隊列",
"missingPermissionMessage": "沒有權限管理訊息或新增反應",
"errorNotQueue": "❌ **現在沒有任何歌曲正在播放**",
"currentPage": "目前頁面 - ",
"embedTitle": "伺服器音樂隊列\n",
"embedCurrentSong": "**當前歌曲 - [{title}]({url})**\n\n{info}"
},
"remove": {
"description": "從音樂隊列移除歌曲",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"usageReply": "用法: {prefix}remove <歌曲隊列編號>",
"result": "<@{author}> ❌ 從音樂隊列移除了 **{title}**"
},
"resume": {
"description": "恢復播放音樂",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"resultNotPlaying": "<@{author}> ▶ 恢復了音樂!",
"errorPlaying": "音樂隊列沒有被暫停"
},
"search": {
"description": "搜尋以及選擇歌曲",
"usageReply": "用法: {prefix}{name} <影片名稱>",
"errorAlreadyCollector": "訊息接收器已經在這個頻道上啟用",
"errorNotChannel": "你必須先加入語音頻道!",
"resultEmbedTitle": "**回覆你想要播放的歌曲代碼**",
"resultEmbedDesc": "搜尋{search}的結果"
},
"shuffle": {
"description": "隨機排序音樂隊列",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"result": "<@{author}> 🔀 隨機排序了音樂隊列"
},
"skip": {
"description": "跳過當前歌曲",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"result": "<@{author}> ⏭ 跳過了歌曲"
},
"skipto": {
"description": "跳到指定的歌曲",
"usageReply": "用法: {prefix}{name} <歌曲隊列編號>",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"errorNotValid": "音樂隊列只有 {length} 個歌曲!",
"result": "<@{author}> ⏭ 跳過了 {arg} 歌曲"
},
"stop": {
"description": "停止音樂隊列",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"result": "<@{author}> ⏹ 停止了隊列!"
},
"uptime": {
"description": "查看機器人上線時間",
"result": "上線時間: `{days} 天,{hours} 小時, {minutes} 分鐘, {seconds} 秒`"
},
"volume": {
"description": "變更目前歌曲音量",
"errorNotQueue": "現在沒有任何歌曲正在播放",
"errorNotChannel": "你必須先加入語音頻道!",
"currentVolume": "🔊 當前音量為: **{volume}%**",
"errorNotNumber": "請使用數字來變更音量",
"errorNotValid": "請使用 0 - 100 的數字!",
"result": "音量設置為: **{arg}%**"
},
"common": {
"on": "**啟動**",
"off": "**關閉**",
"enabled": "**開啟**",
"disabled": "**關閉**",
"errorNotChannel": "你必須先加入語音頻道!",
"cooldownMessage": "請等待 {time} 秒後再使用 `{name}` 指令",
"errorCommand": "執行指令時發生錯誤"
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"execMap": {
"ts": "ts-node"
}
}
+3649
View File
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
{
"name": "evobot",
"version": "2.9.0",
"description": "Discord music bot built with discord.js",
"main": "index.ts",
"author": "Erit Islami <eritislami@gmail.com>",
"private": true,
"homepage": "https://github.com/eritislami/evobot",
"repository": "github:eritislami/evobot",
"bugs": "https://github.com/eritislami/evobot/issues",
"engines": {
"node": ">=16.11.0"
},
"scripts": {
"dev": "nodemon index.ts",
"start": "ts-node index.ts",
"build": "tsc --build",
"prod": "npm run build && node ./dist/index.js",
"commit": "cz",
"format": "npx prettier --write '**/*.ts' --config .prettierrc"
},
"dependencies": {
"@discordjs/voice": "^0.17.0",
"array-move": "^3.0.1",
"discord.js": "^14.15.3",
"dotenv": "^16.4.5",
"ffmpeg-static": "^4.4.1",
"i18n": "^0.15.1",
"lyrics-finder": "^21.0.5",
"play-dl": "^1.9.7",
"soundcloud-downloader": "^0.2.3",
"string-progressbar": "^1.0.4",
"youtube-sr": "~4.3.0"
},
"devDependencies": {
"@types/i18n": "^0.13.12",
"@types/node": "^20.14.2",
"cz-conventional-changelog": "^3.0.1",
"nodemon": "^2.0.22",
"prettier": "^3.3.1",
"ts-node": "^10.9.2"
},
"optionalDependencies": {
"@discordjs/opus": "^0.9.0",
"libsodium-wrappers": "^0.7.13",
"opusscript": "^0.1.1",
"sodium-native": "^3.4.1",
"tweetnacl": "^1.0.3"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog",
"disableScopeLowerCase": false,
"disableSubjectLowerCase": false
}
}
}
+114
View File
@@ -0,0 +1,114 @@
import {
ApplicationCommandDataResolvable,
ChatInputCommandInteraction,
Client,
Collection,
Events,
Interaction,
REST,
Routes,
Snowflake
} from "discord.js";
import { readdirSync } from "fs";
import { join } from "path";
import { Command } from "../interfaces/Command";
import { checkPermissions, PermissionResult } from "../utils/checkPermissions";
import { config } from "../utils/config";
import { i18n } from "../utils/i18n";
import { MissingPermissionsException } from "../utils/MissingPermissionsException";
import { MusicQueue } from "./MusicQueue";
export class Bot {
public readonly prefix = "/";
public commands = new Collection<string, Command>();
public slashCommands = new Array<ApplicationCommandDataResolvable>();
public slashCommandsMap = new Collection<string, Command>();
public cooldowns = new Collection<string, Collection<Snowflake, number>>();
public queues = new Collection<Snowflake, MusicQueue>();
public constructor(public readonly client: Client) {
this.client.login(config.TOKEN);
this.client.on("ready", () => {
console.log(`${this.client.user!.username} ready!`);
this.registerSlashCommands();
});
this.client.on("warn", (info) => console.log(info));
this.client.on("error", console.error);
this.onInteractionCreate();
}
private async registerSlashCommands() {
const rest = new REST({ version: "9" }).setToken(config.TOKEN);
const commandFiles = readdirSync(join(__dirname, "..", "commands")).filter((file) => !file.endsWith(".map"));
for (const file of commandFiles) {
const command = await import(join(__dirname, "..", "commands", `${file}`));
this.slashCommands.push(command.default.data);
this.slashCommandsMap.set(command.default.data.name, command.default);
}
await rest.put(Routes.applicationCommands(this.client.user!.id), { body: this.slashCommands });
}
private async onInteractionCreate() {
this.client.on(Events.InteractionCreate, async (interaction: Interaction): Promise<any> => {
if (!interaction.isChatInputCommand()) return;
const command = this.slashCommandsMap.get(interaction.commandName);
if (!command) return;
if (!this.cooldowns.has(interaction.commandName)) {
this.cooldowns.set(interaction.commandName, new Collection());
}
const now = Date.now();
const timestamps = this.cooldowns.get(interaction.commandName)!;
const cooldownAmount = (command.cooldown || 1) * 1000;
const timestamp = timestamps.get(interaction.user.id);
if (timestamp) {
const expirationTime = timestamp + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return interaction.reply({
content: i18n.__mf("common.cooldownMessage", {
time: timeLeft.toFixed(1),
name: interaction.commandName
}),
ephemeral: true
});
}
}
timestamps.set(interaction.user.id, now);
setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount);
try {
const permissionsCheck: PermissionResult = await checkPermissions(command, interaction);
if (permissionsCheck.result) {
command.execute(interaction as ChatInputCommandInteraction);
} else {
throw new MissingPermissionsException(permissionsCheck.missing);
}
} catch (error: any) {
console.error(error);
if (error.message.includes("permissions")) {
interaction.reply({ content: error.toString(), ephemeral: true }).catch(console.error);
} else {
interaction.reply({ content: i18n.__("common.errorCommand"), ephemeral: true }).catch(console.error);
}
}
});
}
}
+356
View File
@@ -0,0 +1,356 @@
import {
AudioPlayer,
AudioPlayerPlayingState,
AudioPlayerState,
AudioPlayerStatus,
AudioResource,
createAudioPlayer,
entersState,
NoSubscriberBehavior,
VoiceConnection,
VoiceConnectionDisconnectReason,
VoiceConnectionState,
VoiceConnectionStatus
} from "@discordjs/voice";
import {
ActionRowBuilder,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
CommandInteraction,
GuildMember,
Interaction,
Message,
TextChannel
} from "discord.js";
import { promisify } from "node:util";
import { bot } from "../index";
import { QueueOptions } from "../interfaces/QueueOptions";
import { config } from "../utils/config";
import { i18n } from "../utils/i18n";
import { canModifyQueue } from "../utils/queue";
import { Song } from "./Song";
import { safeReply } from "../utils/safeReply";
const wait = promisify(setTimeout);
export class MusicQueue {
public readonly interaction: CommandInteraction;
public readonly connection: VoiceConnection;
public readonly player: AudioPlayer;
public readonly textChannel: TextChannel;
public readonly bot = bot;
public resource: AudioResource;
public songs: Song[] = [];
public volume = config.DEFAULT_VOLUME || 100;
public loop = false;
public muted = false;
public waitTimeout: NodeJS.Timeout | null;
private queueLock = false;
private readyLock = false;
private stopped = false;
/**
* Constructs a new MusicQueue instance, setting up the audio player,
* voice connection, and event listeners to manage voice state changes
* and audio playback. It also handles network state changes to ensure
* a stable connection for audio streaming.
* @param options
*/
public constructor(options: QueueOptions) {
Object.assign(this, options);
this.player = createAudioPlayer({ behaviors: { noSubscriber: NoSubscriberBehavior.Play } });
this.connection.subscribe(this.player);
const networkStateChangeHandler = (
oldNetworkState: VoiceConnectionState,
newNetworkState: VoiceConnectionState
) => {
const newUdp = Reflect.get(newNetworkState, "udp");
clearInterval(newUdp?.keepAliveInterval);
};
this.connection.on("stateChange", async (oldState: VoiceConnectionState, newState: VoiceConnectionState) => {
Reflect.get(oldState, "networking")?.off("stateChange", networkStateChangeHandler);
Reflect.get(newState, "networking")?.on("stateChange", networkStateChangeHandler);
if (newState.status === VoiceConnectionStatus.Disconnected) {
if (newState.reason === VoiceConnectionDisconnectReason.WebSocketClose && newState.closeCode === 4014) {
try {
this.stop();
} catch (e) {
console.log(e);
this.stop();
}
} else if (this.connection.rejoinAttempts < 5) {
await wait((this.connection.rejoinAttempts + 1) * 5_000);
this.connection.rejoin();
} else {
this.connection.destroy();
}
} else if (
!this.readyLock &&
(newState.status === VoiceConnectionStatus.Connecting || newState.status === VoiceConnectionStatus.Signalling)
) {
this.readyLock = true;
try {
await entersState(this.connection, VoiceConnectionStatus.Ready, 20_000);
} catch {
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) {
try {
this.connection.destroy();
} catch {}
}
} finally {
this.readyLock = false;
}
}
});
this.player.on("stateChange", async (oldState: AudioPlayerState, newState: AudioPlayerState) => {
if (oldState.status !== AudioPlayerStatus.Idle && newState.status === AudioPlayerStatus.Idle) {
if (this.loop && this.songs.length) {
this.songs.push(this.songs.shift()!);
} else {
this.songs.shift();
if (!this.songs.length) return this.stop();
}
if (this.songs.length || this.resource.audioPlayer) this.processQueue();
} else if (oldState.status === AudioPlayerStatus.Buffering && newState.status === AudioPlayerStatus.Playing) {
this.sendPlayingMessage(newState);
}
});
this.player.on("error", (error) => {
console.error(error);
if (this.loop && this.songs.length) {
this.songs.push(this.songs.shift()!);
} else {
this.songs.shift();
}
this.processQueue();
});
}
public enqueue(...songs: Song[]) {
if (this.waitTimeout !== null) clearTimeout(this.waitTimeout);
this.waitTimeout = null;
this.stopped = false;
this.songs = this.songs.concat(songs);
this.processQueue();
}
public stop() {
if (this.stopped) return;
this.stopped = true;
this.loop = false;
this.songs = [];
this.player.stop();
!config.PRUNING && this.textChannel.send(i18n.__("play.queueEnded")).catch(console.error);
if (this.waitTimeout !== null) return;
this.waitTimeout = setTimeout(() => {
if (this.connection.state.status !== VoiceConnectionStatus.Destroyed) {
try {
this.connection.destroy();
} catch {}
}
bot.queues.delete(this.interaction.guild!.id);
!config.PRUNING && this.textChannel.send(i18n.__("play.leaveChannel"));
}, config.STAY_TIME * 1000);
}
/**
* Processes the song queue for playback. This method checks if the queue is locked or if the player
* is busy. If not, it proceeds to play the next song in the queue. This method is also responsible
* for handling playback errors and retrying song playback when necessary. It ensures that the queue
* continues to play smoothly, handling transitions between songs, including loop and stop behaviors.
*/
public async processQueue(): Promise<void> {
if (this.queueLock || this.player.state.status !== AudioPlayerStatus.Idle) {
return;
}
if (!this.songs.length) {
return this.stop();
}
this.queueLock = true;
const next = this.songs[0];
try {
const resource = await next.makeResource();
this.resource = resource!;
this.player.play(this.resource);
this.resource.volume?.setVolumeLogarithmic(this.volume / 100);
} catch (error) {
console.error(error);
return this.processQueue();
} finally {
this.queueLock = false;
}
}
private async handleSkip(interaction: ButtonInteraction): Promise<void> {
await this.bot.slashCommandsMap.get("skip")!.execute(interaction);
}
private async handlePlayPause(interaction: ButtonInteraction): Promise<void> {
if (this.player.state.status === AudioPlayerStatus.Playing) {
await this.bot.slashCommandsMap.get("pause")!.execute(interaction);
} else {
await this.bot.slashCommandsMap.get("resume")!.execute(interaction);
}
}
private async handleMute(interaction: ButtonInteraction): Promise<void> {
if (!canModifyQueue(interaction.member as GuildMember)) return;
this.muted = !this.muted;
if (this.muted) {
this.resource.volume?.setVolumeLogarithmic(0);
safeReply(interaction, i18n.__mf("play.mutedSong", { author: interaction.user })).catch(console.error);
} else {
this.resource.volume?.setVolumeLogarithmic(this.volume / 100);
safeReply(interaction, i18n.__mf("play.unmutedSong", { author: interaction.user })).catch(console.error);
}
}
private async handleDecreaseVolume(interaction: ButtonInteraction): Promise<void> {
if (this.volume == 0) return;
if (!canModifyQueue(interaction.member as GuildMember)) return;
this.volume = Math.max(this.volume - 10, 0);
this.resource.volume?.setVolumeLogarithmic(this.volume / 100);
safeReply(interaction, i18n.__mf("play.decreasedVolume", { author: interaction.user, volume: this.volume })).catch(
console.error
);
}
private async handleIncreaseVolume(interaction: ButtonInteraction): Promise<void> {
if (this.volume == 100) return;
if (!canModifyQueue(interaction.member as GuildMember)) return;
this.volume = Math.min(this.volume + 10, 100);
this.resource.volume?.setVolumeLogarithmic(this.volume / 100);
safeReply(interaction, i18n.__mf("play.increasedVolume", { author: interaction.user, volume: this.volume })).catch(
console.error
);
}
private async handleLoop(interaction: ButtonInteraction): Promise<void> {
await this.bot.slashCommandsMap.get("loop")!.execute(interaction);
}
private async handleShuffle(interaction: ButtonInteraction): Promise<void> {
await this.bot.slashCommandsMap.get("shuffle")!.execute(interaction);
}
private async handleStop(interaction: ButtonInteraction): Promise<void> {
await this.bot.slashCommandsMap.get("stop")!.execute(interaction);
}
private commandHandlers = new Map([
["skip", this.handleSkip],
["play_pause", this.handlePlayPause],
["mute", this.handleMute],
["decrease_volume", this.handleDecreaseVolume],
["increase_volume", this.handleIncreaseVolume],
["loop", this.handleLoop],
["shuffle", this.handleShuffle],
["stop", this.handleStop]
]);
private createButtonRow() {
const firstRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("skip").setLabel("⏭").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("play_pause").setLabel("⏯").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("mute").setLabel("🔇").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("decrease_volume").setLabel("🔉").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("increase_volume").setLabel("🔊").setStyle(ButtonStyle.Secondary)
);
const secondRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder().setCustomId("loop").setLabel("🔁").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("shuffle").setLabel("🔀").setStyle(ButtonStyle.Secondary),
new ButtonBuilder().setCustomId("stop").setLabel("⏹").setStyle(ButtonStyle.Secondary)
);
return [firstRow, secondRow];
}
/**
* Sets up a message component collector for the playing message to handle
* button interactions. This collector listens for button clicks and dispatches
* commands based on the custom ID of the clicked button. It supports functionalities
* like skip, stop, play/pause, volume control, and more. The collector is also
* responsible for stopping itself when the corresponding song is skipped or stopped,
* ensuring that interactions are only valid for the current playing song.
*/
private async sendPlayingMessage(newState: AudioPlayerPlayingState) {
const song = (newState.resource as AudioResource<Song>).metadata;
let playingMessage: Message;
try {
playingMessage = await this.textChannel.send({
content: song.startMessage(),
components: this.createButtonRow()
});
} catch (error: unknown) {
console.error(error);
if (error instanceof Error) this.textChannel.send(error.message);
return;
}
const filter = (i: Interaction) => i.isButton() && i.message.id === playingMessage.id;
const collector = playingMessage.createMessageComponentCollector({
filter,
time: song.duration > 0 ? song.duration * 1000 : 60000
});
collector.on("collect", async (interaction) => {
if (!interaction.isButton()) return;
if (!this.songs) return;
const handler = this.commandHandlers.get(interaction.customId);
if (["skip", "stop"].includes(interaction.customId)) collector.stop();
if (handler) await handler.call(this, interaction);
});
collector.on("end", () => {
// Remove the buttons when the song ends
playingMessage.edit({ components: [] }).catch(console.error);
// Delete the message if pruning is enabled
if (config.PRUNING) {
setTimeout(() => {
playingMessage.delete().catch();
}, 3000);
}
});
}
}
+40
View File
@@ -0,0 +1,40 @@
import youtube, { Playlist as YoutubePlaylist } from "youtube-sr";
import { config } from "../utils/config";
import { Song } from "./Song";
const pattern = /^.*(youtu.be\/|list=)([^#\&\?]*).*/i;
export class Playlist {
public data: YoutubePlaylist;
public videos: Song[];
public constructor(playlist: YoutubePlaylist) {
this.data = playlist;
this.videos = this.data.videos
.filter((video) => video.title != "Private video" && video.title != "Deleted video")
.slice(0, config.MAX_PLAYLIST_SIZE - 1)
.map((video) => {
return new Song({
title: video.title!,
url: `https://youtube.com/watch?v=${video.id}`,
duration: video.duration / 1000
});
});
}
public static async from(url: string = "", search: string = "") {
const urlValid = pattern.test(url);
let playlist;
if (urlValid) {
playlist = await youtube.getPlaylist(url);
} else {
const result = await youtube.searchOne(search, "playlist");
playlist = await youtube.getPlaylist(result.url!);
}
return new this(playlist);
}
}
+80
View File
@@ -0,0 +1,80 @@
import { AudioResource, createAudioResource, StreamType } from "@discordjs/voice";
import youtube from "youtube-sr";
import { i18n } from "../utils/i18n";
import { videoPattern, isURL } from "../utils/patterns";
const { stream, video_basic_info } = require("play-dl");
export interface SongData {
url: string;
title: string;
duration: number;
}
export class Song {
public readonly url: string;
public readonly title: string;
public readonly duration: number;
public constructor({ url, title, duration }: SongData) {
this.url = url;
this.title = title;
this.duration = duration;
}
public static async from(url: string = "", search: string = "") {
const isYoutubeUrl = videoPattern.test(url);
let songInfo;
if (isYoutubeUrl) {
songInfo = await video_basic_info(url);
return new this({
url: songInfo.video_details.url,
title: songInfo.video_details.title,
duration: parseInt(songInfo.video_details.durationInSec)
});
} else {
const result = await youtube.searchOne(search);
result ? null : console.log(`No results found for ${search}`);
if (!result) {
let err = new Error(`No search results found for ${search}`);
err.name = "NoResults";
if (isURL.test(url)) err.name = "InvalidURL";
throw err;
}
songInfo = await video_basic_info(`https://youtube.com/watch?v=${result.id}`);
return new this({
url: songInfo.video_details.url,
title: songInfo.video_details.title,
duration: parseInt(songInfo.video_details.durationInSec)
});
}
}
public async makeResource(): Promise<AudioResource<Song> | void> {
let playStream;
const source = this.url.includes("youtube") ? "youtube" : "soundcloud";
if (source === "youtube") {
playStream = await stream(this.url);
}
if (!stream) return;
return createAudioResource(playStream.stream, { metadata: this, inputType: playStream.type, inlineVolume: true });
}
public startMessage() {
return i18n.__mf("play.startedPlaying", { title: this.title, url: this.url });
}
}
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"strict": true,
"outDir": "dist",
"module": "commonjs",
"target": "es2022",
"moduleResolution": "node",
"resolveJsonModule": true,
"useUnknownInCatchVariables": true,
"allowUnreachableCode": false,
"esModuleInterop": true,
"skipLibCheck": true,
"importHelpers": true,
"typeRoots": ["node_modules/@types"],
"types": ["node"],
"sourceMap": true,
"strictPropertyInitialization": false
},
"include": ["./", "./config.json", "./locales/*.json", "./sounds/*.mp3"],
"exclude": ["/.github", "./dist", "./node_modules"]
}
+9
View File
@@ -0,0 +1,9 @@
export class MissingPermissionsException {
public message = "Missing permissions:";
constructor(public permissions: string[]) {}
public toString() {
return `${this.message} ${this.permissions.join(", ")}`;
}
}
+21
View File
@@ -0,0 +1,21 @@
import { ChatInputCommandInteraction, PermissionResolvable } from "discord.js";
import { Command } from "../interfaces/Command";
export interface PermissionResult {
result: boolean;
missing: string[];
}
export async function checkPermissions(
command: Command,
interaction: ChatInputCommandInteraction
): Promise<PermissionResult> {
const member = await interaction.guild!.members.fetch({ user: interaction.client.user!.id });
const requiredPermissions = command.permissions as PermissionResolvable[];
if (!command.permissions) return { result: true, missing: [] };
const missing = member.permissions.missing(requiredPermissions);
return { result: !Boolean(missing.length), missing };
}
+19
View File
@@ -0,0 +1,19 @@
import "dotenv/config";
import { Config } from "../interfaces/Config";
let config: Config;
try {
config = require("../config.json");
} catch (error) {
config = {
TOKEN: process.env.TOKEN || "",
MAX_PLAYLIST_SIZE: parseInt(process.env.MAX_PLAYLIST_SIZE!) || 10,
PRUNING: process.env.PRUNING === "true" ? true : false,
STAY_TIME: parseInt(process.env.STAY_TIME!) || 30,
DEFAULT_VOLUME: parseInt(process.env.DEFAULT_VOLUME!) || 100,
LOCALE: process.env.LOCALE || "en"
};
}
export { config };
+62
View File
@@ -0,0 +1,62 @@
import i18n from "i18n";
import { join } from "path";
import { config } from "./config";
i18n.configure({
locales: [
"ar",
"bg",
"cs",
"de",
"el",
"en",
"es",
"fa",
"fr",
"id",
"it",
"ja",
"ko",
"mi",
"nb",
"nl",
"pl",
"pt_br",
"ro",
"ru",
"sv",
"th",
"tr",
"uk",
"vi",
"zh_cn",
"zh_sg",
"zh_tw"
],
directory: join(__dirname, "..", "locales"),
defaultLocale: "en",
retryInDefaultLocale: true,
objectNotation: true,
register: global,
logWarnFn: function (msg) {
console.log(msg);
},
logErrorFn: function (msg) {
console.log(msg);
},
missingKeyFn: function (locale, value) {
return value;
},
mustacheConfig: {
tags: ["{{", "}}"],
disable: false
}
});
i18n.setLocale(config.LOCALE);
export { i18n };
+6
View File
@@ -0,0 +1,6 @@
export const videoPattern = /^(https?:\/\/)?(www\.)?(m\.|music\.)?(youtube\.com|youtu\.?be)\/.+$/;
export const playlistPattern = /^.*(list=)([^#\&\?]*).*/;
export const scRegex = /^https?:\/\/(soundcloud\.com)\/(.*)$/;
export const mobileScRegex = /^https?:\/\/(soundcloud\.app\.goo\.gl)\/(.*)$/;
export const isURL =
/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
+4
View File
@@ -0,0 +1,4 @@
import { GuildMember } from "discord.js";
export const canModifyQueue = (member: GuildMember) =>
member.voice.channelId === member.guild.members.me!.voice.channelId;
+13
View File
@@ -0,0 +1,13 @@
import { ButtonInteraction, CommandInteraction } from "discord.js";
export async function safeReply(interaction: CommandInteraction | ButtonInteraction, content: string) {
try {
if (interaction.deferred || interaction.replied) {
await interaction.followUp(content);
} else {
await interaction.reply(content);
}
} catch (error) {
console.error(error);
}
}