From 9efdca7e618669283a9dfb5778771db24df438cf Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 17 Nov 2017 18:38:14 +0100 Subject: [PATCH 01/62] Add missing annotations, remove redundant checks --- .../fredboat/messaging/CentralMessaging.java | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java b/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java index c71a91b9c..f15ba3fcb 100644 --- a/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java +++ b/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java @@ -59,18 +59,22 @@ *

* Everything related to sending things out from FredBoat */ +@SuppressWarnings("UnusedReturnValue") public class CentralMessaging { + @Nonnull private static final Logger log = LoggerFactory.getLogger(CentralMessaging.class); //this is needed for when we absolutely don't care about a rest action failing (use this only after good consideration!) // because if we pass null for a failure handler to JDA it uses a default handler that results in a warning/error level log + @Nonnull public static final Consumer NOOP_EXCEPTION_HANDLER = __ -> { }; //use this to schedule rest actions whenever queueAfter() or similar JDA methods would be used // this makes it way easier to track stats + handle failures of such delayed RestActions // instead of implementing a ton of overloaded methods in this class + @Nonnull public static final ScheduledExecutorService restService = Executors.newScheduledThreadPool(10, runnable -> new Thread(runnable, "central-messaging-scheduler")); @@ -83,19 +87,24 @@ public class CentralMessaging { // a per-thread scope // this makes sense since the vast majority of message processing in FredBoat is happening in the main JDA threads + @Nonnull private static ThreadLocal threadLocalMessageBuilder = ThreadLocal.withInitial(MessageBuilder::new); + @Nonnull private static ThreadLocal threadLocalEmbedBuilder = ThreadLocal.withInitial(EmbedBuilder::new); + @Nonnull public static MessageBuilder getClearThreadLocalMessageBuilder() { return threadLocalMessageBuilder.get().clear(); } //presets fredboat color on a clear embed + @Nonnull public static EmbedBuilder getColoredEmbedBuilder() { return getClearThreadLocalEmbedBuilder() .setColor(BotConstants.FREDBOAT_COLOR); } + @Nonnull public static EmbedBuilder getClearThreadLocalEmbedBuilder() { return threadLocalEmbedBuilder.get() .clearFields() @@ -110,11 +119,13 @@ public static EmbedBuilder getClearThreadLocalEmbedBuilder() { } //May not be an empty string, as MessageBuilder#build() will throw an exception - public static Message from(String string) { + @Nonnull + public static Message from(@Nonnull String string) { return getClearThreadLocalMessageBuilder().append(string).build(); } - public static Message from(MessageEmbed embed) { + @Nonnull + public static Message from(@Nonnull MessageEmbed embed) { return getClearThreadLocalMessageBuilder().setEmbed(embed).build(); } @@ -133,6 +144,7 @@ public static Message from(MessageEmbed embed) { * @return Future that can be waited on in case the code requires completion. Similar to JDA's RestAction#complete, * avoid usage where not absolutely needed. */ + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull Message message, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { return sendMessage0( @@ -144,6 +156,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // Message + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull Message message, @Nullable Consumer onSuccess) { return sendMessage0( @@ -155,6 +168,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // Message + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull Message message) { return sendMessage0( channel, @@ -165,6 +179,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // Embed + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull MessageEmbed embed, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { return sendMessage0( @@ -176,6 +191,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // Embed + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull MessageEmbed embed, @Nullable Consumer onSuccess) { return sendMessage0( @@ -187,6 +203,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // Embed + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull MessageEmbed embed) { return sendMessage0( channel, @@ -197,6 +214,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // String + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull String content, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { return sendMessage0( @@ -208,6 +226,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // String + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull String content, @Nullable Consumer onSuccess) { return sendMessage0( @@ -219,6 +238,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul } // String + @Nonnull public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnull String content) { return sendMessage0( channel, @@ -243,6 +263,7 @@ public static MessageFuture sendMessage(@Nonnull MessageChannel channel, @Nonnul * @return Future that can be waited on in case the code requires completion. Similar to JDA's RestAction#complete, * avoid usage where not absolutely needed. */ + @Nonnull public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull File file, @Nullable Message message, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { return sendFile0( @@ -254,6 +275,7 @@ public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull F ); } + @Nonnull public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull File file, @Nullable Message message, @Nullable Consumer onSuccess) { return sendFile0( @@ -265,6 +287,7 @@ public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull F ); } + @Nonnull public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull File file, @Nullable Message message) { return sendFile0( channel, @@ -275,6 +298,7 @@ public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull F ); } + @Nonnull public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull File file, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { return sendFile0( @@ -286,6 +310,7 @@ public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull F ); } + @Nonnull public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull File file, @Nullable Consumer onSuccess) { return sendFile0( @@ -297,6 +322,7 @@ public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull F ); } + @Nonnull public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull File file) { return sendFile0( channel, @@ -322,6 +348,7 @@ public static MessageFuture sendFile(@Nonnull MessageChannel channel, @Nonnull F * @return Future that can be waited on in case the code requires completion. Similar to JDA's RestAction#complete, * avoid usage where not absolutely needed. */ + @Nonnull public static MessageFuture editMessage(@Nonnull Message oldMessage, @Nonnull Message newMessage, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { return editMessage0( @@ -333,6 +360,7 @@ public static MessageFuture editMessage(@Nonnull Message oldMessage, @Nonnull Me ); } + @Nonnull public static MessageFuture editMessage(@Nonnull Message oldMessage, @Nonnull Message newMessage) { return editMessage0( oldMessage.getChannel(), @@ -343,6 +371,7 @@ public static MessageFuture editMessage(@Nonnull Message oldMessage, @Nonnull Me ); } + @Nonnull public static MessageFuture editMessage(@Nonnull Message oldMessage, @Nonnull String newContent) { return editMessage0( oldMessage.getChannel(), @@ -353,7 +382,7 @@ public static MessageFuture editMessage(@Nonnull Message oldMessage, @Nonnull St ); } - + @Nonnull public static MessageFuture editMessage(@Nonnull MessageChannel channel, long oldMessageId, @Nonnull Message newMessage, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { return editMessage0( @@ -365,6 +394,7 @@ public static MessageFuture editMessage(@Nonnull MessageChannel channel, long ol ); } + @Nonnull public static MessageFuture editMessage(@Nonnull MessageChannel channel, long oldMessageId, @Nonnull Message newMessage) { return editMessage0( channel, @@ -375,6 +405,7 @@ public static MessageFuture editMessage(@Nonnull MessageChannel channel, long ol ); } + @Nonnull public static MessageFuture editMessage(@Nonnull MessageChannel channel, long oldMessageId, @Nonnull String newContent) { return editMessage0( channel, @@ -389,7 +420,7 @@ public static MessageFuture editMessage(@Nonnull MessageChannel channel, long ol // Miscellaneous messaging related methods // ******************************************************************************** - public static void sendTyping(MessageChannel channel) { + public static void sendTyping(@Nonnull MessageChannel channel) { try { channel.sendTyping().queue( __ -> Metrics.successfulRestActions.labels("sendTyping").inc(), @@ -459,15 +490,9 @@ public static EmbedBuilder addNpFooter(@Nonnull EmbedBuilder eb, @Nonnull Member // ******************************************************************************** //class internal message sending method + @Nonnull private static MessageFuture sendMessage0(@Nonnull MessageChannel channel, @Nonnull Message message, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { - if (channel == null) { - throw new IllegalArgumentException("Channel is null"); - } - if (message == null) { - throw new IllegalArgumentException("Message is null"); - } - MessageFuture result = new MessageFuture(); Consumer successWrapper = m -> { result.complete(m); @@ -503,14 +528,9 @@ private static MessageFuture sendMessage0(@Nonnull MessageChannel channel, @Nonn } //class internal file sending method + @Nonnull private static MessageFuture sendFile0(@Nonnull MessageChannel channel, @Nonnull File file, @Nullable Message message, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { - if (channel == null) { - throw new IllegalArgumentException("Channel is null"); - } - if (file == null) { - throw new IllegalArgumentException("File is null"); - } MessageFuture result = new MessageFuture(); Consumer successWrapper = m -> { @@ -547,14 +567,9 @@ private static MessageFuture sendFile0(@Nonnull MessageChannel channel, @Nonnull } //class internal editing method + @Nonnull private static MessageFuture editMessage0(@Nonnull MessageChannel channel, long oldMessageId, @Nonnull Message newMessage, @Nullable Consumer onSuccess, @Nullable Consumer onFail) { - if (channel == null) { - throw new IllegalArgumentException("Channel is null"); - } - if (newMessage == null) { - throw new IllegalArgumentException("New message is null"); - } MessageFuture result = new MessageFuture(); Consumer successWrapper = m -> { @@ -600,7 +615,8 @@ private static void handleInsufficientPermissionsException(@Nonnull MessageChann //handles failed JDA rest actions by logging them with an informational string and optionally ignoring some error response codes - public static Consumer getJdaRestActionFailureHandler(String info, ErrorResponse... ignored) { + @Nonnull + public static Consumer getJdaRestActionFailureHandler(@Nonnull String info, ErrorResponse... ignored) { return t -> { if (t instanceof ErrorResponseException) { ErrorResponseException e = (ErrorResponseException) t; From 5d5485a7dd07565e7623207202ee3a0777ef78c7 Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 17 Nov 2017 18:39:45 +0100 Subject: [PATCH 02/62] Fix unnecessary logging of insufficient permission exceptions --- .../java/fredboat/messaging/CentralMessaging.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java b/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java index f15ba3fcb..48a403304 100644 --- a/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java +++ b/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java @@ -516,7 +516,9 @@ private static MessageFuture sendMessage0(@Nonnull MessageChannel channel, @Nonn try { channel.sendMessage(message).queue(successWrapper, failureWrapper); } catch (InsufficientPermissionException e) { - failureWrapper.accept(e); + if (onFail != null) { + onFail.accept(e); + } if (e.getPermission() == Permission.MESSAGE_EMBED_LINKS) { handleInsufficientPermissionsException(channel, e); } else { @@ -558,7 +560,9 @@ private static MessageFuture sendFile0(@Nonnull MessageChannel channel, @Nonnull // this is scheduled to be fixed through JDA's message-rw branch channel.sendFile(FileUtils.readFileToByteArray(file), file.getName(), message).queue(successWrapper, failureWrapper); } catch (InsufficientPermissionException e) { - failureWrapper.accept(e); + if (onFail != null) { + onFail.accept(e); + } handleInsufficientPermissionsException(channel, e); } catch (IOException e) { log.error("Could not send file {}, it appears to be borked", file.getAbsolutePath(), e); @@ -595,7 +599,9 @@ private static MessageFuture editMessage0(@Nonnull MessageChannel channel, long try { channel.editMessageById(oldMessageId, newMessage).queue(successWrapper, failureWrapper); } catch (InsufficientPermissionException e) { - failureWrapper.accept(e); + if (onFail != null) { + onFail.accept(e); + } handleInsufficientPermissionsException(channel, e); } return result; From df8f0d17ee8ec56c8c4a0192e5044144b3391c52 Mon Sep 17 00:00:00 2001 From: Napster Date: Mon, 20 Nov 2017 13:39:59 +0100 Subject: [PATCH 03/62] Adjust Hikari timeout Reason this is getting bumped is that I'm seeing a few issues on the Patron bot of timed out connections, but there is no actual connection loss of the ssh tunnel. Let's see if this fixes that. Bumping this means that in case of an actual connection loss this + the interval of database healthchecks (currently 5 seconds) are the worst case lag a user might see, until the connection is marked as failed and failfasts until it is reestablished. I think having a slight lag at the start of an actual tunnel connection loss (which are rare, about one every 4 days) instead of occasional random timeouts (looks like about 20 per day) is the better compromise. --- FredBoat/src/main/java/fredboat/db/DatabaseManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java index 5b540f421..55ab4a565 100644 --- a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java +++ b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java @@ -53,7 +53,7 @@ public class DatabaseManager { private static final String DEFAULT_PERSISTENCE_UNIT_NAME = "fredboat.default"; //see https://github.com/brettwooldridge/HikariCP connectionTimeout - private static final int HIKARI_TIMEOUT_MILLISECONDS = 1000; + private static final int HIKARI_TIMEOUT_MILLISECONDS = 10000; private EntityManagerFactory emf; private Session sshTunnel; From 265decc45a6f2e1691575c24336f09d459032b10 Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Mon, 26 Jun 2017 01:17:16 +0200 Subject: [PATCH 04/62] Populate the MDC with debug information --- .../java/fredboat/event/EventListenerBoat.java | 15 +++++++++++++-- FredBoat/src/main/resources/logback.xml | 8 ++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java index 8e5b365a2..15dd58575 100644 --- a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java +++ b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java @@ -60,6 +60,7 @@ import net.dv8tion.jda.core.events.message.priv.PrivateMessageReceivedEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.MDC; import java.util.concurrent.TimeUnit; @@ -81,7 +82,17 @@ public EventListenerBoat() { @Override public void onMessageReceived(MessageReceivedEvent event) { + try (// before execution set some variables that can help with finding traces that belong to each other + MDC.MDCCloseable _guild = MDC.putCloseable("guild", event.getGuild().getId()); + MDC.MDCCloseable _channel = MDC.putCloseable("channel", event.getChannel().getId()); + MDC.MDCCloseable _invoker = MDC.putCloseable("invoker", event.getAuthor().getId()); + ) { + + doOnMessageReceived(event); + } + } + private void doOnMessageReceived(MessageReceivedEvent event) { if (FeatureFlags.RATE_LIMITER.isActive()) { if (Ratelimiter.getRatelimiter().isBlacklisted(event.getAuthor().getIdLong())) { Metrics.blacklistedMessagesReceived.inc(); @@ -95,7 +106,7 @@ public void onMessageReceived(MessageReceivedEvent event) { } if (event.getAuthor().equals(event.getJDA().getSelfUser())) { - log.info(event.getGuild().getName() + " \t " + event.getAuthor().getName() + " \t " + event.getMessage().getRawContent()); + log.info(event.getMessage().getRawContent()); return; } @@ -116,7 +127,7 @@ public void onMessageReceived(MessageReceivedEvent event) { if (context == null) { return; } - log.info(event.getGuild().getName() + " \t " + event.getAuthor().getName() + " \t " + event.getMessage().getRawContent()); + log.info(event.getMessage().getRawContent()); //ignore all commands in channels where we can't write, except for the help command if (!channel.canTalk() && !(context.command instanceof HelpCommand)) { diff --git a/FredBoat/src/main/resources/logback.xml b/FredBoat/src/main/resources/logback.xml index 516f443a4..11ea18cbc 100644 --- a/FredBoat/src/main/resources/logback.xml +++ b/FredBoat/src/main/resources/logback.xml @@ -34,7 +34,7 @@ 30 - [%date{HH:mm:ss}] [ %-5level] [%logger{0}] %msg%n + [%date{HH:mm:ss}] [ %-5level] [%mdc] [%logger{0}] %msg%n @@ -48,7 +48,7 @@ 5 - [%d] [ %-5level] [%thread] %logger{35}: %msg%n + [%d] [ %-5level] [%mdc] [%thread] %logger{35}: %msg%n @@ -62,7 +62,7 @@ 30 - [%date{HH:mm:ss}] [%thread] [%logger{0}] %msg%n + [%date{HH:mm:ss}] [%mdc] [%thread] [%logger{0}] %msg%n @@ -85,7 +85,7 @@ INFO - [%date{HH:mm:ss}] [ %-5level] [%logger{0}] %msg%n + [%date{HH:mm:ss}] [ %-5level] [%mdc] [%logger{0}] %msg%n From f3a2760a6c3e92adcf36ce8e4a2df0b2c32f2f9d Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 18:14:07 +0100 Subject: [PATCH 05/62] Add additional permission check for deleting messages --- .../java/fredboat/command/moderation/PrefixCommand.java | 2 +- .../main/java/fredboat/commandmeta/abs/CommandContext.java | 6 ++++-- .../src/main/java/fredboat/messaging/CentralMessaging.java | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java index b5c741071..8336e7e61 100644 --- a/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java +++ b/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java @@ -66,7 +66,7 @@ public PrefixCommand(@Nonnull String name, String... aliases) { //the refresh value to have the changes reflect faster in the bot, or consider implementing a FredBoat wide //Listen/Notify system for changes to in memory cached values backed by the db .recordStats() - .refreshAfterWrite(1, TimeUnit.MINUTES) //NOTE: never use refreshing without async reloading + .refreshAfterWrite(1, TimeUnit.MINUTES) //NOTE: never use refreshing without async reloading, because Guavas cache uses the thread calling it to do cleanup tasks (including refreshing) .expireAfterAccess(1, TimeUnit.MINUTES) //evict inactive guilds .concurrencyLevel(Config.getNumShards()) //each shard has a thread (main JDA thread) accessing this cache many times .build(CacheLoader.asyncReloading(CacheLoader.from(GuildConfig::getPrefix), FredBoat.executor)); diff --git a/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java b/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java index a1b6eca27..486a83f4c 100644 --- a/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java +++ b/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java @@ -157,8 +157,10 @@ private CommandContext(@Nonnull Guild guild, @Nonnull TextChannel channel, @Nonn */ public void deleteMessage() { TextChannel tc = msg.getTextChannel(); - if (tc != null && hasPermissions(tc, Permission.MESSAGE_MANAGE, Permission.MESSAGE_READ)) { - CentralMessaging.deleteMessage(msg); + if (tc != null && hasPermissions(tc, Permission.MESSAGE_MANAGE, //While Manage Message _should_ be enough as it _should_ + Permission.MESSAGE_READ, // implicitly give us all the other Text permissions, + Permission.MESSAGE_HISTORY)) { // it is bugged, so we do some additional checks here. + CentralMessaging.deleteMessage(msg); // See https://github.com/DV8FromTheWorld/JDA/issues/414 for more info. } } diff --git a/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java b/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java index 48a403304..73691e534 100644 --- a/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java +++ b/FredBoat/src/main/java/fredboat/messaging/CentralMessaging.java @@ -57,7 +57,7 @@ /** * Created by napster on 10.09.17. *

- * Everything related to sending things out from FredBoat + * Everything related to sending RestActions from FredBoat */ @SuppressWarnings("UnusedReturnValue") public class CentralMessaging { From 2e1428d1ee6ec570461ad2b4213c407e02ca6930 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 18:38:09 +0100 Subject: [PATCH 06/62] Bump various dependencies Resolve resulting deprecation Remove sqlite dependencies Explicitly specify files to replace tokens in --- FredBoat/build.gradle | 24 +++++++++---------- .../fredboat/util/ratelimit/Ratelimiter.java | 4 ++-- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 8a0c20114..f7a4d3263 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -1,6 +1,6 @@ buildscript { dependencies { - classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.1' + classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.2' } } plugins { @@ -49,11 +49,11 @@ dependencies { compile group: 'commons-codec', name: 'commons-codec', version: '1.11' compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3' compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' - compile group: 'io.sentry', name: 'sentry-logback', version: '1.6.1' - compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.9.0' - compile group: 'com.sparkjava', name: 'spark-core', version: '2.6.0' + compile group: 'io.sentry', name: 'sentry-logback', version: '1.6.3' + compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.9.1' + compile group: 'com.sparkjava', name: 'spark-core', version: '2.7.1' compile group: 'org.yaml', name: 'snakeyaml', version: '1.19' - compile group: 'it.unimi.dsi', name: 'fastutil', version: '8.1.0' + compile group: 'it.unimi.dsi', name: 'fastutil', version: '8.1.1' compile group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: '3.1.0' compile group: 'io.prometheus', name: 'simpleclient', version: '0.1.0' compile group: 'io.prometheus', name: 'simpleclient_hotspot', version: '0.1.0' @@ -66,18 +66,16 @@ dependencies { compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.12.Final' compile group: 'org.hibernate', name: 'hibernate-hikaricp', version: '5.2.12.Final' compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.8.RELEASE' - compile group: 'org.springframework', name: 'spring-orm', version: '4.3.11.RELEASE' + compile group: 'org.springframework', name: 'spring-orm', version: '4.3.12.RELEASE'//v5 breaks things (spring boot) compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4' - compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.20.1' - compile group: 'com.github.gwenn', name: 'sqlite-dialect', version: '24970986d0' compile group: 'com.jcraft', name: 'jsch', version: '0.1.54' - compile group: 'org.togglz', name: 'togglz-core', version: '2.4.1.Final' - compile group: 'com.google.guava', name: 'guava', version: '23.0' + compile group: 'org.togglz', name: 'togglz-core', version: '2.5.0.Final' + compile group: 'com.google.guava', name: 'guava', version: '23.4-jre' compile group: 'com.github.vladimir-bukhtoyarov', name: 'bucket4j-core', version: '3.0.2' //tests - testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.0.1' - testRuntime group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.0.1' + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.0.2' + testRuntime group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.0.2' // To avoid compiler warnings about @API annotations in JUnit code. testCompileOnly group: 'org.apiguardian', name: 'apiguardian-api', version: '1.0.0' } @@ -86,7 +84,7 @@ import org.apache.tools.ant.filters.ReplaceTokens processResources { //inject values into app.properties - filesMatching("**/*.properties") { + filesMatching("**/app.properties") { filter ReplaceTokens, tokens: [ "project.version" : project.version, "project.groupId" : project.group, diff --git a/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java b/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java index e65ae8e85..445c623d1 100644 --- a/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java +++ b/FredBoat/src/main/java/fredboat/util/ratelimit/Ratelimiter.java @@ -36,11 +36,11 @@ import fredboat.util.DiscordUtil; import fredboat.util.Tuple2; import net.dv8tion.jda.core.JDA; -import org.eclipse.jetty.util.ConcurrentHashSet; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; /** * Created by napster on 17.04.17. @@ -76,7 +76,7 @@ public static Ratelimiter getRatelimiter() { private Blacklist autoBlacklist = null; private Ratelimiter() { - Set whitelist = new ConcurrentHashSet<>(); + Set whitelist = ConcurrentHashMap.newKeySet(); //it is ok to use the jda of any shard as long as we aren't using it for guild specific stuff JDA jda = FredBoat.getShard(0).getJda(); From 4c9bafeca5f822f76e934008b03333ec6d4084cb Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 18:39:59 +0100 Subject: [PATCH 07/62] Bump jda dep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're a music bot, so we are setting a listening status 🎵 --- FredBoat/build.gradle | 2 +- FredBoat/src/main/java/fredboat/FredBoatShard.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index f7a4d3263..6a3584120 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -31,7 +31,7 @@ shadowJar { dependencies { compile project(':Shared') - compile group: 'net.dv8tion', name: 'JDA', version: '3.3.1_300' + compile group: 'net.dv8tion', name: 'JDA', version: '3.3.1_306' compile group: 'com.github.FredBoat', name: 'lavaplayer', version: '1.2.44.2-FredBoat' compile group: 'com.github.FredBoat', name: 'jda-nas', version: '1.0.5.1-JDA' diff --git a/FredBoat/src/main/java/fredboat/FredBoatShard.java b/FredBoat/src/main/java/fredboat/FredBoatShard.java index ba71535d7..6f4dfb35c 100644 --- a/FredBoat/src/main/java/fredboat/FredBoatShard.java +++ b/FredBoat/src/main/java/fredboat/FredBoatShard.java @@ -284,7 +284,7 @@ protected synchronized static JDABuilder getDefaultShardBuilder(@Nonnull EventLi if (defaultShardBuilder == null) { JDABuilder builder = new JDABuilder(AccountType.BOT) .setToken(Config.CONFIG.getBotToken()) - .setGame(Game.of(Config.CONFIG.getGame())) + .setGame(Game.listening(Config.CONFIG.getGame())) .setBulkDeleteSplittingEnabled(false) .setEnableShutdownHook(false) .setAudioEnabled(true) From 8d6328183e0187b92ade378f76786144627dd4f4 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 21:15:49 +0100 Subject: [PATCH 08/62] Reset a few broken translations Invalidated them on crowdin too --- FredBoat/src/main/resources/lang/zh_CN.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FredBoat/src/main/resources/lang/zh_CN.properties b/FredBoat/src/main/resources/lang/zh_CN.properties index f95226396..d415cac40 100644 --- a/FredBoat/src/main/resources/lang/zh_CN.properties +++ b/FredBoat/src/main/resources/lang/zh_CN.properties @@ -19,14 +19,14 @@ selectInterval=\u6570\u5b57\u5fc5\u987b\u5728 1 \u5230 {0} \u4e4b\u95f4 selectSelectionNotGiven=\u5f53\u524d\u65e0\u641c\u7d22\u7ed3\u679c\u4f9b\u60a8\u9009\u62e9\u3002 shuffleOn=\u300c\u968f\u673a\u64ad\u653e\u300d\u6a21\u5f0f\u5df2\u6253\u5f00\u3002 shuffleOff=\u300c\u968f\u673a\u64ad\u653e\u300d\u6a21\u5f0f\u5df2\u5173\u95ed\u3002 -reshufflePlaylist=I have translated reshuffled as reorganized, I am not entirely sure that it is a correct translation. +reshufflePlaylist=Queue reshuffled. reshufflePlayerNotShuffling=\u5fc5\u987b\u5148\u6253\u5f00 "\u65e0\u5e8f\u64ad\u653e" \u6a21\u5f0f\u3002 skipEmpty=\u5f53\u524d\u64ad\u653e\u5217\u8868\u4e3a\u7a7a\u3002 skipOutOfBounds=\u65e0\u6cd5\u79fb\u9664\u7b2c {0} \u9996\u6b4c\uff0c\u56e0\u4e3a\u5f53\u524d\u64ad\u653e\u5217\u8868\u53ea\u6709 {1} \u9996\u6b4c\u66f2\u3002 skipNumberTooLow=\u60a8\u8f93\u5165\u7684\u6570\u5b57\u5fc5\u987b\u5927\u4e8e 0\u3002 skipSuccess=\u5df2\u8df3\u8fc7 \#{0}\: **{1}** skipRangeInvalid=\u6307\u5b9a\u7684\u6b4c\u66f2\u8303\u56f4\u65e0\u6548\u3002 -skipRangeSuccess=Tracks between \#{0} to \#{}~\#{1} have been removed. +skipRangeSuccess=Tracks \#{0} to \#{1} have been removed. skipTrackNotFound=\u5f53\u524d\u64ad\u653e\u5217\u8868\u4e3a\u7a7a\uff0c\u65e0\u6cd5\u4f7f\u7528\u8df3\u8fc7\u529f\u80fd\u3002 stopAlreadyEmpty=\u64ad\u653e\u5217\u8868\u5df2\u6e05\u7a7a\u3002 stopEmptyOne=\u64ad\u653e\u5217\u8868\u5df2\u6e05\u7a7a\uff0c`1` \u9996\u6b4c\u66f2\u5df2\u88ab\u79fb\u9664\u3002 From 52f8c7659cc698df351d43d743f833b3ffdee871 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 21:16:52 +0100 Subject: [PATCH 09/62] Handle formatting languages of translation strings gracefully --- .../main/java/fredboat/messaging/internal/Context.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/messaging/internal/Context.java b/FredBoat/src/main/java/fredboat/messaging/internal/Context.java index e5776c73d..236d4f790 100644 --- a/FredBoat/src/main/java/fredboat/messaging/internal/Context.java +++ b/FredBoat/src/main/java/fredboat/messaging/internal/Context.java @@ -188,7 +188,14 @@ public String i18nFormat(@Nonnull String key, Object... params) { log.warn("Context#i18nFormat() called with empty or null params, this is likely a bug.", new MessagingException("a stack trace to help find the source")); } - return MessageFormat.format(this.i18n(key), params); + try { + return MessageFormat.format(this.i18n(key), params); + } catch (IllegalArgumentException e) { + log.warn("Failed to format key '{}' for language '{}' with following parameters: {}", + key, getI18n().getBaseBundleName(), params, e); + //fall back to default props + return MessageFormat.format(I18n.DEFAULT.getProps().getString(key), params); + } } From 637f817f6fea6748ec0202fa3c18fc91bb6fadcd Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 21:41:19 +0100 Subject: [PATCH 10/62] Allow Patron Boat in FBH --- .../main/java/fredboat/commandmeta/CommandManager.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java b/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java index 581dfe43c..e1d7d4e47 100644 --- a/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java +++ b/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java @@ -26,7 +26,6 @@ package fredboat.commandmeta; -import fredboat.Config; import fredboat.audio.player.PlayerRegistry; import fredboat.command.fun.AkinatorCommand; import fredboat.commandmeta.abs.Command; @@ -40,7 +39,6 @@ import fredboat.perms.PermissionLevel; import fredboat.perms.PermsUtil; import fredboat.shared.constant.BotConstants; -import fredboat.shared.constant.DistributionEnum; import fredboat.util.TextUtils; import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Member; @@ -70,13 +68,6 @@ public static void prefixCalled(CommandContext context) { totalCommandsExecuted.incrementAndGet(); Metrics.commandsExecuted.labels(invoked.getClass().getSimpleName()).inc(); - if (guild.getJDA().getSelfUser().getId().equals(BotConstants.PATRON_BOT_ID) - && Config.CONFIG.getDistribution() == DistributionEnum.PATRON - && guild.getId().equals(BotConstants.FREDBOAT_HANGOUT_ID)) { - log.info("Ignored command because patron bot is not allowed in FredBoatHangout"); - return; - } - if (FeatureFlags.PATRON_VALIDATION.isActive()) { PatronageChecker.Status status = PatronageCheckerHolder.instance.getStatus(guild); if (!status.isValid()) { From 525fdd8fe7db25109f3ba299c85c7dac6edbb30e Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 22:37:27 +0100 Subject: [PATCH 11/62] Make use of full webhook url --- FredBoat/credentials.yaml.example | 7 +++---- FredBoat/src/main/java/fredboat/Config.java | 14 ++++---------- FredBoat/src/main/java/fredboat/FredBoatShard.java | 3 +-- .../src/main/java/fredboat/event/EventLogger.java | 7 +++---- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/FredBoat/credentials.yaml.example b/FredBoat/credentials.yaml.example index fb992b1cd..24d5ac838 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/credentials.yaml.example @@ -89,10 +89,9 @@ sentryDsn: # Webhook to a Discord channel that will post some guild stats and shard status changes -# More information: https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks -# These are the id and token that you are looking for: https://canary.discordapp.com/api/webhooks// -# eventLogWebhookId: -# eventLogWebhookToken: +# More information on webhooks: https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks +# Example: "https://canary.discordapp.com/api/webhooks/1234567890/QWERTZUIOPasdfghjklYXCVBNM" (no, this one will not work) +eventLogWebhook: "" # post build tool test results into a discord channel. the token must be discord bot token testToken: diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java index 1b8e05fce..bd1b2766d 100644 --- a/FredBoat/src/main/java/fredboat/Config.java +++ b/FredBoat/src/main/java/fredboat/Config.java @@ -117,8 +117,7 @@ public class Config { // misc private String sentryDsn; private List lavalinkHosts = new ArrayList<>(); - private long eventLogWebhookId; - private String eventLogWebhookToken; + private String eventLogWebhook; private String testBotToken; private String testChannelId; @@ -251,8 +250,7 @@ public Config(File credentialsFile, File configFile) { }); } - eventLogWebhookId = (long) creds.getOrDefault("eventLogWebhookId", 0L); - eventLogWebhookToken = (String) creds.getOrDefault("eventLogWebhookToken", ""); + eventLogWebhook = (String) creds.getOrDefault("eventLogWebhook", ""); testBotToken = (String) creds.getOrDefault("testToken", ""); testChannelId = creds.getOrDefault("testChannelId", "") + ""; @@ -399,12 +397,8 @@ public String getOpenWeatherKey() { return openWeatherKey; } - public long getEventLogWebhookId() { - return eventLogWebhookId; - } - - public String getEventLogWebhookToken() { - return eventLogWebhookToken; + public String getEventLogWebhook() { + return eventLogWebhook; } public boolean isRestServerEnabled() { diff --git a/FredBoat/src/main/java/fredboat/FredBoatShard.java b/FredBoat/src/main/java/fredboat/FredBoatShard.java index 6f4dfb35c..6a4ab91b7 100644 --- a/FredBoat/src/main/java/fredboat/FredBoatShard.java +++ b/FredBoat/src/main/java/fredboat/FredBoatShard.java @@ -294,8 +294,7 @@ protected synchronized static JDABuilder getDefaultShardBuilder(@Nonnull EventLi .setHttpClientBuilder(new OkHttpClient.Builder() .eventListener(new OkHttpEventMetrics("jda"))) .addEventListener(Metrics.instance().jdaEventsMetricsListener) - .addEventListener(new EventLogger(Config.CONFIG.getEventLogWebhookId(), - Config.CONFIG.getEventLogWebhookToken())); + .addEventListener(new EventLogger(Config.CONFIG.getEventLogWebhook())); if (LavalinkManager.ins.isEnabled()) { diff --git a/FredBoat/src/main/java/fredboat/event/EventLogger.java b/FredBoat/src/main/java/fredboat/event/EventLogger.java index 410bf6167..ecba58176 100644 --- a/FredBoat/src/main/java/fredboat/event/EventLogger.java +++ b/FredBoat/src/main/java/fredboat/event/EventLogger.java @@ -89,10 +89,9 @@ public EventLogger(long id, String token) { this(new WebhookClientBuilder(id, token).build()); } - // this relies on https://github.com/DV8FromTheWorld/JDA/pull/530 being merged into master -// public EventLogger(String eventLogWebhookUrl) { -// this(new WebhookClientBuilder(eventLogWebhookUrl).build()); -// } + public EventLogger(String eventLogWebhookUrl) { + this(new WebhookClientBuilder(eventLogWebhookUrl).build()); + } @Override From 33638de43bddf1c0c3527dbe67b60f014a5b9828 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 23:46:58 +0100 Subject: [PATCH 12/62] Reformat and add more explanations to credentials file The config class barely survived an OCD fit of the developer. It will never look the same again. --- FredBoat/credentials.yaml.example | 95 +++++--- FredBoat/src/main/java/fredboat/Config.java | 202 ++++++++++-------- .../src/main/java/fredboat/FredBoatShard.java | 12 +- 3 files changed, 186 insertions(+), 123 deletions(-) diff --git a/FredBoat/credentials.yaml.example b/FredBoat/credentials.yaml.example index 24d5ac838..578696892 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/credentials.yaml.example @@ -8,7 +8,20 @@ ### IF YOU POST THIS FILE ONLINE (such as on GitHub) YOUR BOT COULD BE COMPROMISED ### ### +### Use a proper text editor when editing this file, for example Sublime. ### Do not use tab characters in this file, use plain spaces. +### +### Keep at least one space after a colon, like so: +### +### key: value +### +### You can wrap most values into quotation marks, except numbers and booleans: +### +### someUrl: "http://example.com" +### someToken: "123.qwe.456[DFG=" +### somePortNumber: 22 +### useSomeFeature: true +### ### More information on correctly formatting yaml files: http://www.yaml.org/start.html @@ -17,18 +30,18 @@ ### Essential credentials ################################################################ - -token: # Add your discord bot token below to the beta and patron slots, between the quotation marks +# Add your discord bot token below to the beta and patron slots, between the quotation marks +token: # Don't remove or add anything in this line. This is how a map works in YAML. Just edit the lines below. # Find the token of your bot on https://discordapp.com/developers/applications/me # Tutorial: https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token beta: "PutYourDiscordBotTokenHere" patron: "PutYourDiscordBotTokenHere" + # Used by the ;;split and ;;np commands. Must be hooked up to the Youtube Data API. -# Add your google API key in the brackets below between the quotation marks +# Add your google API key between the quotation marks # How to get the key: https://developers.google.com/youtube/registering_an_application - -googleServerKeys: ["PutYourGoogleAPIKeyHere"] +googleServerKeys: "PutYourGoogleAPIKeyHere" @@ -38,54 +51,75 @@ googleServerKeys: ["PutYourGoogleAPIKeyHere"] # For the ;;mal command # Create an account on https://myanimelist.net/ and enter its login below -malUser: -malPassword: +malUser: "" +malPassword: "" # Used to access imgur galleries for some RandomImageCommands # Acquired from here: https://api.imgur.com/oauth2/addclient # Choose an option that does not require an Authorization callback URL -imgurClientId: +imgurClientId: "" # Used to retrieve Spotify playlists # Get them from here: https://developer.spotify.com/my-applications -spotifyId: -spotifySecret: +spotifyId: "" +spotifySecret: "" # Used by ;;weather command. # Get them from: http://openweathermap.org/appid -openWeatherKey: +openWeatherKey: "" + + ################################################################ -### Developers and advanced users only +### Developers and very experienced users only ################################################################ -# database url for when you don't want to run on the default built in sqlite db. -# FredBoat was written to work with PostgreSQL -jdbcUrl: #jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass +# FredBoat was written to work with PostgreSQL. +# If you are running with docker-compose then you don't need to change the jdbcUrl here. +# In PostgreSQL, role means user and vice versa. Keep that in mind when reading the following help and the provided links. +# If you are running your own PostgreSQL database, you will need to provide a role and a database belonging to that role. +# The role needs at least the permission to log in. +# Learn more about roles here: https://www.postgresql.org/docs/10/static/database-roles.html +# Learn more about creating databases here: https://www.postgresql.org/docs/10/static/manage-ag-createdb.html +# Learn more about the postgres jdbc url here: https://jdbc.postgresql.org/documentation/head/connect.html +# If you are using an SSH tunnel, you need to point your jdbc url to localhost:9333 +# Example jdbc: "jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass" +jdbcUrl: "" -# ssh tunnel for a remote database. this is useful for when you don't want to expose your database on the remote server +# Ssh tunnel for a remote database. this is useful for when you don't want to expose your database on the remote server # and instead use ssh tunneling to access it -# useSshTunnel: false -# sshHost: -# sshUser: -# sshPrivateKeyFile: -# forwardToPort: +# If you are running with docker-compose then you don't need to change any ssh value here. +# If you are using an SSH tunnel, you need to point your jdbc url to localhost:9333 +useSshTunnel: false +sshHost: "" # add the ssh port to the ip / url, usually 22, for example: "db.example.com:22" +sshUser: "" # user on the remote machine +sshPrivateKeyFile: "" # path to an ssh private key file which is authorized to log in to the sshUser on the remote machine. learn how to create these: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04#step-four-—-add-public-key-authentication-(recommended) +forwardToPort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default + + +# Additional google keys +# If you find yourself running a big bot and hitting youtube API ratelimits, you can add several keys via the list below. +# Remember to comment out the other "googleServerKeys" entry in this file, you can have only one of them. +# FredBoat will pick the keys by random to to access Youtube. +#googleServerKeys: ["Key1", "Key2", "Key3"] # error aggregation service -sentryDsn: +sentryDsn: "" -# if you are running lavalink nodes this is the place to add them -# lavalinkHosts: - # "ws://localhost:5555": "youshallnotpass" - # "ws://192.168.1.20:5556": "youshallnotpass" - # "ws://lavalink.example.com:5557": "youshallnotpass" +# If you are running lavalink nodes this is the place to add them. +# Examples shown below, don't forget to uncomment them properly. +# More on Lavalink: https://github.com/Frederikam/Lavalink +#lavalinkHosts: + #"ws://localhost:5555": "youshallnotpass" + #"ws://192.168.1.20:5556": "youshallnotpass" + #"ws://lavalink.example.com:5557": "youshallnotpass" # Webhook to a Discord channel that will post some guild stats and shard status changes @@ -93,6 +127,7 @@ sentryDsn: # Example: "https://canary.discordapp.com/api/webhooks/1234567890/QWERTZUIOPasdfghjklYXCVBNM" (no, this one will not work) eventLogWebhook: "" -# post build tool test results into a discord channel. the token must be discord bot token -testToken: -testChannelId: + +# Post build tool test results into a discord channel. The token must be a discord bot token. +testToken: "" +testChannelId: "" diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java index bd1b2766d..6b0e1ca44 100644 --- a/FredBoat/src/main/java/fredboat/Config.java +++ b/FredBoat/src/main/java/fredboat/Config.java @@ -321,13 +321,31 @@ private static String cleanTabs(String content, String file) { } } - public String getRandomGoogleKey() { - if (googleKeys.isEmpty()) { - throw new MessagingException("No Youtube API key detected. Please read the documentation of the credentials file on how to obtain one."); + + public static class LavalinkHost { + + private final URI uri; + private final String password; + + public LavalinkHost(URI uri, String password) { + this.uri = uri; + this.password = password; + } + + public URI getUri() { + return uri; + } + + public String getPassword() { + return password; } - return googleKeys.get((int) Math.floor(Math.random() * getGoogleKeys().size())); } + + // ******************************************************************************** + // Config Getters + // ******************************************************************************** + public DistributionEnum getDistribution() { return distribution; } @@ -340,95 +358,116 @@ public boolean isDevDistribution() { return distribution == DistributionEnum.DEVELOPMENT; } - public String getBotToken() { - return botToken; + public String getPrefix() { + return prefix; } - public String getJdbcUrl() { - return jdbcUrl; + public boolean isRestServerEnabled() { + return restServerEnabled; } - public int getHikariPoolSize() { - return hikariPoolSize; + public List getAdminIds() { + return adminIds; } - //this static method works even when called from tests with invalid config files leading to a null config - public static int getNumShards() { - if (CONFIG != null) { - return CONFIG.numShards; + public boolean useAutoBlacklist() { + return useAutoBlacklist; + } + + public String getGame() { + if (game == null || game.isEmpty()) { + return "Say " + getPrefix() + "help"; } else { - return 1; + return game; } } - public String getMalUser() { - return malUser; + public boolean getContinuePlayback() { + return continuePlayback; } - public String getMalPassword() { - return malPassword; + public boolean isYouTubeEnabled() { + return youtubeAudio; } - public String getImgurClientId() { - return imgurClientId; + public boolean isSoundCloudEnabled() { + return soundcloudAudio; } - public List getGoogleKeys() { - return googleKeys; + public boolean isBandCampEnabled() { + return bandcampAudio; } - public String getCarbonKey() { - return carbonKey; + public boolean isTwitchEnabled() { + return twitchAudio; } - public String getSpotifyId() { - return spotifyId; + public boolean isVimeoEnabled() { + return vimeoAudio; } - public String getSpotifySecret() { - return spotifySecret; + public boolean isMixerEnabled() { + return mixerAudio; } - public String getPrefix() { - return prefix; + public boolean isSpotifyEnabled() { + return spotifyAudio; } - public String getOpenWeatherKey() { - return openWeatherKey; + public boolean isHttpEnabled() { + return httpAudio; } - public String getEventLogWebhook() { - return eventLogWebhook; - } - public boolean isRestServerEnabled() { - return restServerEnabled; + public boolean useVoiceChannelCleanup() { + return useVoiceChannelCleanup; } - public List getAdminIds() { - return adminIds; + // ******************************************************************************** + // Credentials Getters + // ******************************************************************************** + + public String getBotToken() { + return botToken; } - public boolean useAutoBlacklist() { - return useAutoBlacklist; + public List getGoogleKeys() { + return googleKeys; } - public String getGame() { - if (game == null || game.isEmpty()) { - return "Say " + getPrefix() + "help"; - } else { - return game; + public String getRandomGoogleKey() { + if (googleKeys.isEmpty()) { + throw new MessagingException("No Youtube API key detected. Please read the documentation of the credentials file on how to obtain one."); } + return googleKeys.get((int) Math.floor(Math.random() * getGoogleKeys().size())); } - public boolean getContinuePlayback() { return continuePlayback; } + public String getMalUser() { + return malUser; + } - public String getTestBotToken() { - return testBotToken; + public String getMalPassword() { + return malPassword; } - public String getTestChannelId() { - return testChannelId; + public String getImgurClientId() { + return imgurClientId; + } + + public String getSpotifyId() { + return spotifyId; + } + + public String getSpotifySecret() { + return spotifySecret; + } + + public String getOpenWeatherKey() { + return openWeatherKey; + } + + public String getJdbcUrl() { + return jdbcUrl; } public boolean isUseSshTunnel() { @@ -455,56 +494,37 @@ public List getLavalinkHosts() { return lavalinkHosts; } - public class LavalinkHost { - - private final URI uri; - private final String password; - - public LavalinkHost(URI uri, String password) { - this.uri = uri; - this.password = password; - } - - public URI getUri() { - return uri; - } - - public String getPassword() { - return password; - } - } - - public boolean isYouTubeEnabled() { - return youtubeAudio; + public String getEventLogWebhook() { + return eventLogWebhook; } - public boolean isSoundCloudEnabled() { - return soundcloudAudio; + public String getTestBotToken() { + return testBotToken; } - public boolean isBandCampEnabled() { - return bandcampAudio; + public String getTestChannelId() { + return testChannelId; } - public boolean isTwitchEnabled() { - return twitchAudio; - } - public boolean isVimeoEnabled() { - return vimeoAudio; - } + // ******************************************************************************** + // Derived and unofficial values + // ******************************************************************************** - public boolean isMixerEnabled() { - return mixerAudio; + //this static method works even when called from tests with invalid config files leading to a null config + public static int getNumShards() { + if (CONFIG != null) { + return CONFIG.numShards; + } else { + return 1; + } } - public boolean isSpotifyEnabled() { - return spotifyAudio; + public int getHikariPoolSize() { + return hikariPoolSize; } - public boolean isHttpEnabled() { - return httpAudio; + public String getCarbonKey() { + return carbonKey; } - - public boolean useVoiceChannelCleanup() {return useVoiceChannelCleanup; } } diff --git a/FredBoat/src/main/java/fredboat/FredBoatShard.java b/FredBoat/src/main/java/fredboat/FredBoatShard.java index 6a4ab91b7..29d5282f4 100644 --- a/FredBoat/src/main/java/fredboat/FredBoatShard.java +++ b/FredBoat/src/main/java/fredboat/FredBoatShard.java @@ -293,8 +293,16 @@ protected synchronized static JDABuilder getDefaultShardBuilder(@Nonnull EventLi .setReconnectQueue(connectQueue) .setHttpClientBuilder(new OkHttpClient.Builder() .eventListener(new OkHttpEventMetrics("jda"))) - .addEventListener(Metrics.instance().jdaEventsMetricsListener) - .addEventListener(new EventLogger(Config.CONFIG.getEventLogWebhook())); + .addEventListener(Metrics.instance().jdaEventsMetricsListener); + + String eventLogWebhook = Config.CONFIG.getEventLogWebhook(); + if (eventLogWebhook != null && !eventLogWebhook.isEmpty()) { + try { + builder.addEventListener(new EventLogger(Config.CONFIG.getEventLogWebhook())); + } catch (Exception e) { + log.error("Failed to create Eventlogger, events will not be logged to discord via webhook", e); + } + } if (LavalinkManager.ins.isEnabled()) { From 418aa17450ba11a29a62f49d03345093f202088d Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 23 Nov 2017 23:53:19 +0100 Subject: [PATCH 13/62] Eliminate last sqlite traces --- FredBoat/src/main/java/fredboat/Config.java | 8 ++------ .../audio/source/SpotifyPlaylistSourceManager.java | 3 +-- .../src/main/java/fredboat/command/admin/TestCommand.java | 1 - 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java index 6b0e1ca44..11444376b 100644 --- a/FredBoat/src/main/java/fredboat/Config.java +++ b/FredBoat/src/main/java/fredboat/Config.java @@ -278,13 +278,9 @@ public Config(File credentialsFile, File configFile) { numShards = recommendedShardCount; log.info("Discord recommends " + numShards + " shard(s)"); - //more database connections don't help with performance, so use a value based on available cores + //more database connections don't help with performance, so use a value based on available cores, but not too low //http://www.dailymotion.com/video/x2s8uec_oltp-performance-concurrent-mid-tier-connections_tech - if (jdbcUrl == null || jdbcUrl.isEmpty() || distribution == DistributionEnum.DEVELOPMENT) - //more than one connection for the fallback sqlite db is problematic as there is currently (2017-04-16) - // no supported way in the custom driver and/or dialect to set lock timeouts - hikariPoolSize = 1; - else hikariPoolSize = Math.max(2, Runtime.getRuntime().availableProcessors()); + hikariPoolSize = Math.max(4, Runtime.getRuntime().availableProcessors()); log.info("Hikari max pool size set to " + hikariPoolSize); PlayerLimitManager.setLimit((Integer) config.getOrDefault("playerLimit", -1)); diff --git a/FredBoat/src/main/java/fredboat/audio/source/SpotifyPlaylistSourceManager.java b/FredBoat/src/main/java/fredboat/audio/source/SpotifyPlaylistSourceManager.java index 53377f81d..176be4c84 100644 --- a/FredBoat/src/main/java/fredboat/audio/source/SpotifyPlaylistSourceManager.java +++ b/FredBoat/src/main/java/fredboat/audio/source/SpotifyPlaylistSourceManager.java @@ -71,8 +71,7 @@ public class SpotifyPlaylistSourceManager implements AudioSourceManager, Playlis //https://regex101.com/r/AEWyxi/3 private static final Pattern PLAYLIST_PATTERN = Pattern.compile("https?://.*\\.spotify\\.com/user/(.*)/playlist/([^?/\\s]*)"); - //Take care when deciding on upping the core pool size: The threads may hog database connections - // (for selfhosters running on the SQLite db) when loading an uncached playlist. + //Take care when deciding on upping the core pool size: The threads may hog database connections when loading an uncached playlist. // Upping the threads will also fire search requests more aggressively against Youtube which is probably better avoided. public static ScheduledExecutorService loader = Executors.newScheduledThreadPool(1); diff --git a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java index 07132f161..537371400 100644 --- a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java +++ b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java @@ -47,7 +47,6 @@ public class TestCommand extends Command implements ICommandRestricted { private enum Result {WORKING, SUCCESS, FAILED} - // the SQL syntax used here work with both SQLite and PostgreSQL, beware when altering private final String DROP_TEST_TABLE = "DROP TABLE IF EXISTS test;"; private final String CREATE_TEST_TABLE = "CREATE TABLE IF NOT EXISTS test (id serial, val integer, PRIMARY KEY (id));"; private final String INSERT_TEST_TABLE = "INSERT INTO test (val) VALUES (:val) "; From f3d772c5027bece288b137f1287ed371b04f9b14 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 26 Nov 2017 01:20:03 +0100 Subject: [PATCH 14/62] Bump deps --- FredBoat/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 6a3584120..885ef8a1c 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -31,9 +31,9 @@ shadowJar { dependencies { compile project(':Shared') - compile group: 'net.dv8tion', name: 'JDA', version: '3.3.1_306' - compile group: 'com.github.FredBoat', name: 'lavaplayer', version: '1.2.44.2-FredBoat' - compile group: 'com.github.FredBoat', name: 'jda-nas', version: '1.0.5.1-JDA' + compile group: 'net.dv8tion', name: 'JDA', version: '3.3.1_307' + compile group: 'com.sedmelluq', name: 'lavaplayer', version: '1.2.45' + compile group: 'com.sedmelluq', name: 'jda-nas', version: '1.0.6' if (System.getenv('dev') == 'true') { compile(group: 'lavalink', name: 'Lavalink-Client', version: '-SNAPSHOT') From 60b54e3daa8962cec02f810b8ecf3489c5b61db3 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 26 Nov 2017 01:26:26 +0100 Subject: [PATCH 15/62] Use proper notation for lavalink client + bump --- FredBoat/build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 885ef8a1c..eac3127bc 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -39,9 +39,7 @@ dependencies { compile(group: 'lavalink', name: 'Lavalink-Client', version: '-SNAPSHOT') } else { //production - compile(group: 'com.github.Frederikam', name: 'Lavalink', version: '69c54a9c0efa0e364dd45e837c97ed4990ce460c') { - exclude(module: 'Lavalink-Server') - } + compile(group: 'com.github.Frederikam.Lavalink', name: 'Lavalink-Client', version: 'f5d50964f89fea0bc3224feebe2d8a1e560f4155') } compile group: 'org.apache.commons', name: 'commons-text', version: '1.1' From 8e65ab898850d20d77eb1a81010cc862a63e60c2 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 26 Nov 2017 22:28:30 +0100 Subject: [PATCH 16/62] Add darwin native missing in official jda-nas build --- .../resources/natives/darwin/libudpqueue.dylib | Bin 0 -> 20492 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 FredBoat/src/main/resources/natives/darwin/libudpqueue.dylib diff --git a/FredBoat/src/main/resources/natives/darwin/libudpqueue.dylib b/FredBoat/src/main/resources/natives/darwin/libudpqueue.dylib new file mode 100755 index 0000000000000000000000000000000000000000..f1ef2e3995be58daf40440ed009846b234cdcda9 GIT binary patch literal 20492 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 Date: Wed, 29 Nov 2017 09:45:00 +0100 Subject: [PATCH 17/62] Improve version warning handling --- FredBoat/src/main/java/fredboat/FredBoat.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index b9e911b11..c88884a96 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -66,6 +66,7 @@ import java.io.IOException; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -108,15 +109,20 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc Runtime.getRuntime().addShutdownHook(new Thread(ON_SHUTDOWN, "FredBoat main shutdownhook")); log.info(getVersionInfo()); - String javaVersionMinor = System.getProperty("java.version").split("\\.")[1]; + String javaVersionMinor = null; + try { + javaVersionMinor = System.getProperty("java.version").split("\\.")[1]; + } catch (Exception e) { + log.error("Exception while checking if java 8", e); + } - if (!javaVersionMinor.equals("8")) { + if (!Objects.equals(javaVersionMinor, "8")) { log.warn("\n\t\t __ ___ ___ _ _ ___ _ _ ___ \n" + "\t\t \\ \\ / /_\\ | _ \\ \\| |_ _| \\| |/ __|\n" + "\t\t \\ \\/\\/ / _ \\| / .` || || .` | (_ |\n" + "\t\t \\_/\\_/_/ \\_\\_|_\\_|\\_|___|_|\\_|\\___|\n" + "\t\t "); - log.warn("FredBoat only supports Java 8. You are running Java " + javaVersionMinor); + log.warn("FredBoat only officially supports Java 8. You are running Java {}", System.getProperty("java.version")); } I18n.start(); From 6e3d1e4e018a06c2e8c2af62413f17c0b9352a73 Mon Sep 17 00:00:00 2001 From: Frederikam Date: Wed, 29 Nov 2017 09:45:11 +0100 Subject: [PATCH 18/62] Update lavalink client --- FredBoat/build.gradle | 2 +- .../main/java/fredboat/audio/player/AbstractPlayer.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index eac3127bc..a46a4442d 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -39,7 +39,7 @@ dependencies { compile(group: 'lavalink', name: 'Lavalink-Client', version: '-SNAPSHOT') } else { //production - compile(group: 'com.github.Frederikam.Lavalink', name: 'Lavalink-Client', version: 'f5d50964f89fea0bc3224feebe2d8a1e560f4155') + compile(group: 'com.github.Frederikam.Lavalink', name: 'Lavalink-Client', version: 'f58ae576aa8a59ef01b98d7c8638f187c5349b1a') } compile group: 'org.apache.commons', name: 'commons-text', version: '1.1' diff --git a/FredBoat/src/main/java/fredboat/audio/player/AbstractPlayer.java b/FredBoat/src/main/java/fredboat/audio/player/AbstractPlayer.java index ebbc1e652..e5fab7b19 100644 --- a/FredBoat/src/main/java/fredboat/audio/player/AbstractPlayer.java +++ b/FredBoat/src/main/java/fredboat/audio/player/AbstractPlayer.java @@ -76,12 +76,12 @@ public abstract class AbstractPlayer extends AudioEventAdapterWrapped implements protected AudioTrackContext context; private final AudioLossCounter audioLossCounter = new AudioLossCounter(); - protected Consumer onPlayHook; - protected Consumer onErrorHook; + Consumer onPlayHook; + Consumer onErrorHook; private static final int MAX_HISTORY_SIZE = 20; private AudioTrackContext queuedTrackInHistory = null; - protected ConcurrentLinkedQueue historyQueue = new ConcurrentLinkedQueue<>(); + private ConcurrentLinkedQueue historyQueue = new ConcurrentLinkedQueue<>(); @SuppressWarnings("LeakingThisInConstructor") AbstractPlayer(String guildId) { @@ -322,7 +322,7 @@ private void updateHistoryQueue() { *

* Silently playing a track will not trigger the onPlayHook (which announces the track usually) */ - protected void playTrack(AudioTrackContext trackContext, boolean... silent) { + private void playTrack(AudioTrackContext trackContext, boolean... silent) { log.debug("playTrack({})", trackContext.getEffectiveTitle()); context = trackContext; From 0c92abd4006416fcb15eea1e13a2f792b96e0913 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 3 Dec 2017 06:12:29 +0100 Subject: [PATCH 19/62] Add mock credentials to docker image The reason this is an ok idea is due to the volumes used to mount the config and credentials files. If a file is not present when the image is started, docker creates an empty directory in its place. This is easy to take care outside of the container, but a bit harder to do so inside of it. Having a dummy credentials file inside the container makes the process of fixing it after accidentally starting it without the credentials files much easier for the selfhosters. --- FredBoat/.dockerignore | 1 + FredBoat/Dockerfile | 1 + 2 files changed, 2 insertions(+) diff --git a/FredBoat/.dockerignore b/FredBoat/.dockerignore index f49ddd863..fc46b7361 100644 --- a/FredBoat/.dockerignore +++ b/FredBoat/.dockerignore @@ -3,3 +3,4 @@ !Dockerfile !FredBoat.jar !config.yaml +!credentials.yaml.example diff --git a/FredBoat/Dockerfile b/FredBoat/Dockerfile index 6bbe8cd76..998a465e5 100644 --- a/FredBoat/Dockerfile +++ b/FredBoat/Dockerfile @@ -6,6 +6,7 @@ RUN mkdir /opt RUN mkdir /opt/FredBoat COPY config.yaml /opt/FredBoat/config.yaml +COPY credentials.yaml.example /opt/FredBoat/credentials.yaml COPY FredBoat.jar /opt/FredBoat/FredBoat.jar EXPOSE 1356 From 2e1dc4115bcdc730acb928d9da655fd9a251e86c Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 3 Dec 2017 06:52:52 +0100 Subject: [PATCH 20/62] Fix dependency badge; bump deps; add THE DOTS #388 --- FredBoat/build.gradle | 10 +++++----- README.md | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index a46a4442d..d255c8bba 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -31,7 +31,7 @@ shadowJar { dependencies { compile project(':Shared') - compile group: 'net.dv8tion', name: 'JDA', version: '3.3.1_307' + compile group: 'net.dv8tion', name: 'JDA', version: '3.3.1_308' compile group: 'com.sedmelluq', name: 'lavaplayer', version: '1.2.45' compile group: 'com.sedmelluq', name: 'jda-nas', version: '1.0.6' @@ -52,7 +52,7 @@ dependencies { compile group: 'com.sparkjava', name: 'spark-core', version: '2.7.1' compile group: 'org.yaml', name: 'snakeyaml', version: '1.19' compile group: 'it.unimi.dsi', name: 'fastutil', version: '8.1.1' - compile group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: '3.1.0' + compile group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: '3.1.1' compile group: 'io.prometheus', name: 'simpleclient', version: '0.1.0' compile group: 'io.prometheus', name: 'simpleclient_hotspot', version: '0.1.0' compile group: 'io.prometheus', name: 'simpleclient_logback', version: '0.1.0' @@ -63,12 +63,12 @@ dependencies { compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final' compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.12.Final' compile group: 'org.hibernate', name: 'hibernate-hikaricp', version: '5.2.12.Final' - compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.8.RELEASE' - compile group: 'org.springframework', name: 'spring-orm', version: '4.3.12.RELEASE'//v5 breaks things (spring boot) + compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.9.RELEASE' + compile group: 'org.springframework', name: 'spring-orm', version: '4.3.13.RELEASE'//v5 breaks things (spring boot) compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4' compile group: 'com.jcraft', name: 'jsch', version: '0.1.54' compile group: 'org.togglz', name: 'togglz-core', version: '2.5.0.Final' - compile group: 'com.google.guava', name: 'guava', version: '23.4-jre' + compile group: 'com.google.guava', name: 'guava', version: '23.5-jre' compile group: 'com.github.vladimir-bukhtoyarov', name: 'bucket4j-core', version: '3.0.2' //tests diff --git a/README.md b/README.md index 6da833d81..8b15fb56c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![FredBoat](https://fred.moe/YY1.png) -# FredBoat [![Build Status](https://travis-ci.org/Frederikam/FredBoat.svg?branch=master)](https://travis-ci.org/Frederikam/FredBoat) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/fredboat/localized.svg)](https://crowdin.com/project/fredboat) [![Twitter Follow](https://img.shields.io/twitter/follow/DiscordFredBoat.svg?style=social&label=Follow)]() [![Dependency Status](https://www.versioneye.com/user/projects/59ff43de15f0d72f79c07210/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/59ff43de15f0d72f79c07210) +# FredBoat [![Build Status](https://travis-ci.org/Frederikam/FredBoat.svg?branch=master)](https://travis-ci.org/Frederikam/FredBoat) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/fredboat/localized.svg)](https://crowdin.com/project/fredboat) [![Twitter Follow](https://img.shields.io/twitter/follow/DiscordFredBoat.svg?style=social&label=Follow)]() [![Dependency Status](https://www.versioneye.com/user/projects/5a238bc60fb24f793c0be65b/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/5a238bc60fb24f793c0be65b) FredBoat is a bot that has various features, but most notably is that it can play music. Pull requests are welcome and please report any issues you find in [issues](https://github.com/Frederikam/FredBoat/issues). FredBoat is licensed under the MIT license, so feel free to copy small or large parts of the code here without having to ask. I would love to see what you can create with it! @@ -8,9 +8,9 @@ FredBoat is licensed under the MIT license, so feel free to copy small or large [![Join FredBoat Hangout](https://discordapp.com/api/guilds/174820236481134592/embed.png?style=banner2)](https://discord.gg/cgPFW4q) ## Documentation -Help can be found at https://fredboat.com/docs +Help can be found at [https://fredboat.com/docs](https://fredboat.com/docs). -For installation instructions, go to https://fredboat.com/docs/selfhosting +For installation instructions, go to [https://fredboat.com/docs/selfhosting](https://fredboat.com/docs/selfhosting). ## Contributing If you are interested, you can read about contributing to this project [here](https://github.com/Frederikam/FredBoat/blob/master/CONTRIBUTING.md). From b97216e3a041ee4236e50cb78b575558d81f19a8 Mon Sep 17 00:00:00 2001 From: Napster Date: Mon, 4 Dec 2017 12:09:45 +0100 Subject: [PATCH 21/62] Fireworks make everything better --- Branding/Event/Music-fireworks-santa.png | Bin 0 -> 70555 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Branding/Event/Music-fireworks-santa.png diff --git a/Branding/Event/Music-fireworks-santa.png b/Branding/Event/Music-fireworks-santa.png new file mode 100644 index 0000000000000000000000000000000000000000..0a050cb7cad832a1c54d6c61bf02ea54a72a2edc GIT binary patch literal 70555 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 literal 0 HcmV?d00001 From e042c1f70130c5c1b3c3f7d253546b791399aa64 Mon Sep 17 00:00:00 2001 From: Napster Date: Mon, 4 Dec 2017 12:13:03 +0100 Subject: [PATCH 22/62] Even more hats and fireworks --- Branding/Event/Patreon-fireworks-santa.png | Bin 0 -> 71332 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Branding/Event/Patreon-fireworks-santa.png diff --git a/Branding/Event/Patreon-fireworks-santa.png b/Branding/Event/Patreon-fireworks-santa.png new file mode 100644 index 0000000000000000000000000000000000000000..0a52c5f4cd9e47f733c88c6549295aa3581b1a54 GIT binary patch literal 71332 zcmXt<1yEG)-^J-%U}>a5T0mk+>F$>9?nb)1yO!>hltwzFOF%+WO8C*8@AW_P%IttU zgX6vXJm2S>&p9_*MM)Y1jTj9E1_nb`MnVk+2A28X3k3;y$J;-_1NeqyDlaVo^Y-tn z@Owon@D8f8jE)-&4Cdg!7wo80r8)2>vb(IJB=R;00Ue#{K0~Ms28I$wRzg(6YxU&2 zcdq_{&cT!ajIOWNO`YM-uTxFtD=D=(0jj znWh_p0b9g+fr0bjx3Tl0v-6W=@ml?!l#hOHJXNJ5t986xPvh6+JASuUYY*3fFY2!k zuV-psWjAU~Bok?7k<5dojNdyWHW0Tn`AnHIkJyoYHYPmB-*WnR3DrQ`@a~#g{Y+ee zMElnIU8(~lN-1La_?-@XST1o0ZU;x$b_GKkcXh_o(GWsz_j#w{RlrFyLDC`|u+UX> zG5AtA8b$R)Fl87e0xAkD5+yT+L6C(l0*85d+UVWLPZINl2zy-I-9ZQsS8^QB{9+4| z5%FP|wOYu5+s^Elk;}nc(ytc-jMlULGbpv+;*Xarm&R%Q!D?Xsh5HS>`IP&fL_)8h zwuRUsAQ2I!g%QHn$C~He<(|ado_o}9%(2tcO2i~2HVzK7nG;3F{Miafn|F;4B!g^8 zYQ;9hCPZpg8Vs2e3JMC8W#;zwaogJ_)r(BwV%ru5l#bU7uqAG-X9%4^Wqs+`SuL>3 za32WHYKFbysWG1sk`n4B0^yksy2~{}4sP#31f z#4l9hoMy&WNznK+O=}y7%~JGcJZAvL(MBN4$Aw{KFvEzY z!j5&6+jm6^ZE$&EN>@WIk_{`T%7xq8VVFm$^cLy?%_4;Lz~KsqEtnC!J$kWG zB?uKFL73g+RnIa~Lv$ScCQk(;EO0P^xAo@;1{-a|C6p#Jw1^!gG*f2`B^_Z17fvx$ z_cN`v6oWe(uC^xn!?+`H3U|D$Gbav)%rCSfNYU+kE);)64X6rRCtVY2V!*8GBk-!Jrq&Ly{M=6JR+`nrO0_F;YjJFy1e zp|1ee2<{c-e8&6r=ex06da{hV`NnTBky>KkWjJh7i&18|P-uyubfPmUwui=jE;4jG z<~#gl5sN69gMD`aT zb%ncIzAI0s$vhsZdROWmtd}>!l1W8+&>wkfRjXoY4Wgs#`-UKfJ_m|7rJ?~*UNcc5 zT8B_F>@J~cOkmcfY3Ng|g|yQik~klog{lpI->T~PTV2zBknh|6u%DyT8z49}HFec@ zxb9VTz&uf%nLcKI*}V+m=H}qzlNBnkGByrUs~S2#XPXhY0wH6P8k?Gi=zje&_SOQc z5=CxR?DRcUb$=1j9*$eOdzspcWh9Y=e->>Wof-ZWhA7Kd5Q)uMYR8W1qic;mX*G=u zqwEkO2cE(q4hsUj7@Na<2P+uq3$qlzi3whfhAsG>aylsd#L8D5)>FXOF~G;{kDQCB33T)`F}QK~OA9z57Z z1Pv=vl|0Nr(jWtODphTn4j1X?i1L8UiPYTW@X!}D$gt>Pgb_X=sr@|>LQp4^F;!Uj z?LVG1jkK*+wS^C#^U!IbZl3XEw=-iy@<%2+l za)G6-?cbC;qbQVlgSj&;sgm%TkA6YQ~Ermor0=rYA%GMP_|;DaOzF?zNLPS zzE*b#73!c$aC#9(O@w)z!uSxK1QucuQu-y0dWks1s%|8P2Pd`#TbbT^l9n-(9@P(P zV*Xc`71nz*#7ATkODRzwA~{=&S%_%kpOh$Z7hAa5WDb!wNX#%tKBy9D3q4)}E<*YK z8q0teR~J|n1@}Yr|5nMyy%USULBglgE#L)X?CzchEQjsE$cM+}-s!uZJHhhu^5QE} z>M{w#o$-n7!y?Hb4`gS;2Bbq8U7Brs?(amg7p^;=K^}c)aLCiJEESJvo=j9I0`p@; za4oY|UUi`+mb2#2rB=h+|31kurAx4}$7*?Op_TZGAA*4;9v>PzN%?9c5ay~CRwJ%C<_Z&nq7qAsI&BJ0Zu7#-x$HC0$QW61*^V` zs8=Kn`7LBPdXzatJo)g$EXavhoZL!3y1+Axz7g#D#lkD%%qUCS`oO60tBYgr%PkMR z^6Zk7yga&tgF~%ObA-{`jggh5Wkf|m0Mse)X-(km`6?5n-HZ(<9efeRW`MR1_l)N} zwd3DLBrNreaBdX*h9q!dd%_kL^WMgmt#Oj64om8*8s$P7qG{<`ooV@X{T~kEMqUL1 z7^5R9ND)U4jO--Nkb7_$B0|tHnxBa=5%~&@Idk5(s$_0j0-PPBbid?MviH}vX_tfd zi^NAG1aaELg6E8J`9*4ORhmd+SP>_uBo>>fKa@YjFkSaY1vm6FA|r^U7nk{whcJn8 zM$vP4L5JvvFpN77=K|qI=x2@2d(PtN3+ZEkTM4GG%I|YK$2ljWGKb zwTz}ZJ&ymKEAQXGCl&BYdM};827!c~J$=lxl@8(}ztE2i`ipBNL38Z`j_xHSI zYSF;3lXZ<&pMy8XKmXA8DHvoM?vi|<8<&ZD22Z+mr+S&Ab+3ql@RRB9sJ%FX_9Cs`F!kskLy4#Lx-9z13#)=Kq)rlE)SI~=OE8LIps)NJ%fV7e(#afpPK^T*W)1H*T zQDelvcuAsV;Zqx<;XtY4!v)8M_8@$+RLvSQTcyHXu!^#3K3V6HdTV%mx{_N33t-7v zRPl15w#eZ#3PP|4n|7@`!;d@DJ~$s*r$gPguP*wr0+L2XMkZc&*g&CEIXuk)FFtZ* zIMRvad(rgyTXWJB7Bl&Rafyk&wJ&)Hujsa8J}l?ahk9=81iLAXNVHWK!J86{e~eTm ziBJTTaj1WcSk`;~?sKDKztId!-;Uv0ZrshTPnM-;$Y7$`HHH>aQ6`1e#U6(qSK~`S zqR_1y5HMOPEskhR>7W)WjG2{7`ouW092W>sm_d&7bw&hwku{h@gaIq(2CVlc4QIa? zA|s9MA*;ex77r#U`S9UtGW58vk z?L)ER1HvDbXa8p;V0jc_Ch@)Q-b3Fmxr&K7)M#UsW=jDT`^Aw`WlcBjEHhPvMCMMp1ZaPAx zw6q8f3=Hg7n!?A%WWStkOu5Ynj!x%&;`6?w85|spi;p)zI~Z%88-z)aAl&}kCr8;5 zrA&yxjMa`sOSRGz6kLOSPsA31laBVDcCA)1pY0}`zc9JNIG?NdBHLAhw za21-ONNByGY$Nxjf3jaxs`c*?fT`5#_&dhoW86e#RaF&hIuRL}#b^SV{bo$vi}XaxD&y+ zPwW$B&BqKNybsSzt%^`hp$6sZicGeSl_DbP#z|1iZ)ved1t*s|jLAvm|5nsfa=xdz z4~_uQbfU0hEUxD^QJLA5DvC1ImDq)-;A+%hN{)^aBt_G+aRuWqH`>P*6)k*gZN-g9 z5evwj9|C__@Nw;6wX}p&N(lS8&*t7)*C#92GGAo_mJ2?U9e@c@+4;oEk=1`E@3-59 zb#?N}-W^+ever8FcynyT!}XNI4hZohcW9Y>W)m=)TJ2W`0O{>@+Ht_^bxs+HNoMMG zKfL@UW^PwI?UX{|E8PZ8dTeY_E@uGMj?=4?FyOi%!;ecw>tV>2Q>Lr_$9j}SS%i+$DLTmw zrY`*JHThHj8+d+c>>SpgU^T3!o~IViP_ojA1r{@x7D zeq!J!Uj1GtX34JEw{I!0T&qv(z*_h+$LSg0eqEw=Cs=a@Y@%2k* zDl=om07Wpl-1`Fgl)v^;Okb;6)9C;7C4pQpW|!CgS3|Hpw>({{$rO~!{mU2AHSQd4 z2Os%b%AVY)(cN|T1x0<&-yZ9}XWs>Gf0_N;$`$!OG5!7hnSQ-k&t&J;X*zxg+D(11 zHK-PMSESV}e*xyyn>%49j%f2>e_#UOBz7k^*6FE7ATxDV$j(kUp;WMO>FO+|pa zYvxs?tY=3bp3N9`J?D{UyN!ncn;jv=5kGZUe8#MbPj+kX%CM*7CbFP1wLAbu2p)Z( zC^#YfGLd+0D7Ht201LPSVBAubmG<^hthF{W$Lh06b7T*(fuK-mgF_AgJyOPK0AE_G z-;vVV$_*McUabD?)X}7d0{GOd^065F4?p%??N`4=_xFqD``_y1`}}46_xR+GoY;!!EbDK`qWaD7|28 z-aV2&B&~{?ugvF$J z3OE}S*sl+?dhDR4W@VRZ)Uxv#Q0GVO@(Bf>8Lts9JWwk+5U+E5VIE5<`%jzhkP3le zUQW)!q*}V2whWF_uso<{2gQ*0)a6-PnUl?HKSg=f{_VFuR&{XjRjS4UBzo8s0)aHx zE;0dAj!iN3bB$)B`52DpJ zQ|>?WNfX30^ZZ3=VLei1JG=Kn0Ys)pNea-zq6k*|5VpdT&kW1e<_k8LxbMxOI9V5X zC8G&*b6gnxZ2U-HJLq;YM(hjP+Jg|kfuc##(vXgS7XFFuXDa){mG44Jx|2NT?+8c)D`6Xx%zUf&D`G?}dwt z>vz|+xfhH~ZoFJ)0H6wW*31k4x9+Q>!fP2LL?O^K(>U2cLQ`Tm4v*CO)c0J2r8l%$ z*k=mWqxMoFU1H-1e8`tu^S>naU+{VGkY)PFl^6b+HOfx(w`p$v`+>?5QpHrRjzO4Rz1 zNmi|t?blOaFOFX24mF?boBjRc%fpT_4w4FEf3!{XZch{Lt*ZehD_*!*uxrQU>@3*d z-(TRo51s}GRaaN{AHM-^hraKBE!_u#XC2JG1RwE$H=ZYFoxq~Kll-3*2<^44_9bJCqLq_FIrBf{H4Du!h_1;y*sDRY_ORC5x0vGr!0 z2sXJE>T~E+=emqTAiDymV)L{hi&0Om0-d-3c|}bPIwP&3qGEfU9x^MVg?~`kE-%3A zq@<;f#c2R%outOW$?0b3WC%t;5DnVpRZvn|YCHSY80yYHHHalVS&}Fu2W$=CzSQcq zC7hl*W-#lBF?o2a)pzJ8=(CPCSxjhmx-%{t`m&5BQXKq9elPHJ(tNVnTacZd?R}OV zL;glFKK-DSX8SrtQwa(tES_{G8^?NEj48t|xMQo{i)LuP|L}8XNbJAmZgLChtCho8 zhX8yURKHmaQC4)WdZx<6Vt+=>PgC^n(o@e%3C#wj8Vvx+7v%DkSRDqS~f zS9~(ed|pa=Py{UhYf{5+qynuS)|z8TPHzauB>^k_m&bsG1$x>9z8q%>SVN}V?2jv5 zCvR-)fXbkw7~^cx4UVdzak?Nu?A*_v62Jxj<9949Ebi{^4K@pO(3~9EiUnr9R?xD? z@$K+|REzF#6LZY4slWD6G%h_6IXN9j9Jr@^?uX#cI!-pWLTK%T#pQ#af1yMnF=>?s zlLk|IXQ$sSkyFPWL0#uxCe5$9!!65(z|lpOIySqy8e?M^;ByEJY+zb>jegn?EmPa> zN2d6*9Z9jj)gKDN#N=RSSM^MQA&TLMrB_`DYK0LLIZ-^n~ubf!#=SbCg8EDU0S(ZWh((^wiv#c?{|GR3v*JR^8_o+|v1`mL=k zRjFbQf?=?HAd6=R!ZU5u&dUKnkiUO#v(7JOBEAIiz(8SW`NaVG$MdaFEZ09jumN{T zL_}2Cd%EsS8YxZg9R>*TS|PF8s;cN5r=Dyq|3mRwgRa}Ap7WgxUe8T`9?uPL`h|rB zfrme-0H{R8_x*MxV8{LlY)oEt^LvpA`4Jf` zADx{Y990z5;obxP;?pkxwpe)1O{Gf>?Yf+H9* zat-$1{D02BNeA!q+;b8!JXurF3f{j&S#@CF$5W*G;;KH}y-5jd)Ltbc`_aRl&M>R= zb;5f&X;5p;$f}THnO-0)s$rM(e1?aJinE3uw+~5#WGoprwIW8u9*eaQtGUr6d|+3A zh0>4^YIiDgr&8xNT$uMA71`+9sMUF!rxM4t&<=A;t&T}GR)x7ffqrRhiDfzwhuWvTE z^ve0>K%P-lL?tC9#p|{Y0wmOx;U@@WXm(a-;USe?xhe2105}m2PfslY%MVx(!!Lx} z_8nb-c=%@;05(m+ZNF7jk-r0Q4db(o@9nC54HOnOZY;JEI%gza>wD^WBH5L%&XGUN0jYywi=- z1o#Dt=PhKvU6M`X%^rWE2vIjTH$iv^Xtya%wsgU!uIJJAwCBkYfCaq%kB~AoRACf` zNGfI6O_8cTEm+izUsMe_szP@&lIVzuFcqrvaS9qe-{;>Du`J{TJqf({R=<2iUq~ru z8Mmk4kDPEd(4McITPG?G{EHRfnL`JGbLSG}OVg0&9QsN_jlw`+wDs`ax9TSXJ~9&* ziU+(=n7LU}Q-bchSP{{35EwzEkl9ftFst-l6zMn+#Nw zAKEw+x{aynk8V%iza#gt)y8%RN`ua`<>D4RtsmSk8ohkx=jUgQC0S;Rd#qmFpUUaD zn*Q_#ddJMtsPu{X&A%mCM4pG>STHh+ z`04WbBfFM7w7(CCy#1_rz2Y{28<0T5P<-SKw=r#`DJ-%JwGTYRE}xK_GOV+m{0TQN z`(wCJRLqQDvU6_#Pd1}mT?C;Q-o)%eMrlbItZdAgfY8uvC15bQR0hIMSwr{8Wcl^@ z!D3d%?qOuUklhc_+)kTv-4iF#$zo;lJ zja;P>QzD(X<4uk~&HW=khNF(B`r}-jNHY&yN`=bbmmU=RXNFxLS_D671l`mFn5D5w z$f>Cbs(tjd3lmf3L4KyIqU)X-?h9wZ$YJw1gSMc|dFBToOR;mseG=%*))%)cdFv4<|ar|r3# zMHoi&>Y+SOpRWFn@1tkt?(xNVG$oh#uhm;JYIzJ*%c@^?Iyi(@KI8mIIS>lmhHaK@ zE3TTTz_qoFk$+Sl;0-pmw*T1R($W%tG+BfRSs$PVR$A-`6NO)S0oi%jnQ+|cl`kzo z-h0v~zw7~wtkDPz5{7iSKUd!66&0xOXMK37D>&!gUm%fL(aUAbQly8QRaUW$zTdJ5 zKpb6)C7y4HeHa)!I^=YU7P=CP)fgfa8e4gY=)sDxDRf%99bL=SMU`L1E)P$_sn;B? zN{=oh?(_Kdu^z@W;huPls?}7XDNCUTt<;)NHPMhcu>5hwAQkq`-L;a-CBAjGoisxMvMj(U{b>t0 zZe!K!-;7Tl;)1B5eM>AlI0zLy50oKgS>>&P}7(i)HxBsmNzP;q~xkV%- zB>2eB?h#}wM0`5yPAxB|1DK*<{n(@N5JgLgF5d=&47aKye58t@G1d63C$d~k%Mt#` zf|#PbkmvLn)z*L5nQgPw1h6-|m8$N|>>T?gfnU}roW!wa2bm60!Eo|~AgsHEU)>1X z$hpK`x$vV(uGd*Ot}OpWaD68xV__H2;t((_+>wz>7#WI_o(|c_K#*Tei93Mrc^JaO z-L>6Q9{+JBB_;r?b(`h>jXTBe$DC(%;_Dm-J(7NIb=Ii0WwVaZbrDvh$MI5It=?g6 z?f@I8X@waul=>cvpVz&119N;T9n8$jH9lolfE0!^6X$tTac4B4e3C=>U(} zbt2SdLd0y)nZ}~mIy*Ple>EeVc;Fp|9qEqn>z#|9)6lvEwuP!)G4rvEgtmh8-gXrO zx-VbQDye_#Xtpp5UtExnyoA)pQgG$|Inw^8RXLHjNvl=|PKDsJ$wCsw0TpR$HV(g# z{Z>cF?^2ERnYx279BiO+L@k4&#^Qwm0yd#-Hje*_*JSDFZFz;Rzi7L2(b?F>T&)Mg z3H!8GuiA)Vf8HDaKt~YzAv4Fl)zZevVNc@C<&mE0`ljn=wJCYv;>yaH)7!1n!s23! z@$0Vr8eQhZ+~VReu(Y+izOYPWeypgdhy(}?usrIHfx<=QqV2zI)1d1MI|s+V{3Bg1 z99Rt#)e3Q=yVtk3O^(0$L4$=V3_mMg6r43*w~8UED?D37dhh!t;pwTJv*YBtbl%1` zGLubOB%k;)gM@J}v~!A=SxVVdS|y%}o4S;!{2tZUT5X_xHA-fObWqFCSriNWPXvQt zf`}higUG$Z8i-I5lPR0B5(Vg9ktxH znGanI&ZMu}0!e;N-MyvF_1R09o<4^3`0jll|I>fIi=VYFNO~_woZdZUXz6m)8GeVh z^}hVK{$SFPMbp2i?-is0$?pd2;sSlX<+K_D*j4-z0MPnCHG4!|9fG*#>GGwA^%Wq9n*LB zDOb3(AHGgX2hVDW}T*@_XCt zji}c;I+?YW%ei;_p|Mi26MA5yfG@63!Qa$S`(B*M#`Ru1eDpRWd-{Vj4waR>m(q&v_f&R9h8-Vx|0WFgbYl^)bE*~GC_M0U=K0q=^C+1IyK1UtALv-Aa zKa#YMfpKdU$c=YNn^}ne2ye}yI&!GL8zrgdc&rZK^wWNnQ{Wn@etG^`)ir>s& zJwd})2oaqaCu*Katu|+v&F$%Lr71o|b)*3itMWs&i!?st;m~baYnj2nr@Sj!!H%@| z+h*@c-@$CgUl%mx>ro{WA${YPr**KN2A1VmQ9q+nyhsa&aC7_9X;;U8t!o6yOlXP= z4a~6sII^;$uhIN!3Q#qDw<#`Q&8Ene5m8WBnVJ@FeDgo~#ST~zVBz=Hj_&|44nXby zDiDCguD_$19;ZMmIkB8N_OqALAikBzp55RxhDwidWJqNHl9%LP-F(UY+&gn>N39KK=Z7jMe=F2L zt(0nR>xL;uOA&k52{rj_1tQ5i3K=c&{SX)b;gcDSOi^gs4QS#USMrx9Rc5JfY^+nbubdE*<=tYgSn$yO7b60{NVQx5U`cJ=tT5UR4!i4xSsK| zT;mo7TN7Kq(nM_I$eck$=yLTplsQ2KB&H>z0({`&R;?Td< z4U}@!E0h)sQn3rJ1**&TZ%6~Eia|$EltQIxZ%4@Lk`L-Ap7hrcp$Wfjcf=Oz#~$GF z?j&?FUb7w6T2X02k_!K-RVfzPa1$e4NaUtgU@ologk%+6Ome;rpi5WCj;8VXbs+7g z;wVPu6CB#MMA4g(l2kSwv`aU_Q0e}r7jx0F$`iMsanNo>(ELIhWkY8+jP~?YJxMmr z(IwUnuHfn==JBFVE(AnZi`{aQ&y8(e`wp6}p58lRVpHIfu5WIVr!0?-jymkeH}OAc z0*pmYsGvTFB}7f;PO?m!$VH~!>fIt4th&+A*QrYte{AP6)?m9XxO>lOoT+AG{Wutx z6}aw%g}DPBa|Tg{%k`)-A|ZA~J$VpzY|-!nihy5RL{ZsF!!`lAUopiX+-PJKTw2U* z55hbu+3zNXPU6ugGA0YID&%Pj26nqX%CNsftbDNeqqM0?Npjh_@-^BSE$#gGOvCtE z`u+c2-|sdi-X{tSX!Ts;_dHBF&Ckw?03-?!6&_cEJihDxcfYT%ueZF(0i?3t%_xIa zR4aGcH&dc{ZCFownWq{Jm1aSkyrmb2(p~AMgKI@6OC+~2Ig@(#h<_lkoOpTInH_F( z?TJ-b)lDxU6OAojOv2rAS<3%eYSX;s-bdCB}0bhlujpzHc5Q z<${lqaMgP{ST*1x$t&fVr(5Jrb>h011DvoB^8x-?cQ+WjrBHu%!|(0e5hV8u!Y}Ii z0gpES=mKCg?{^4$z49rZa>#R^j3$v}lOGo!2%6P5w zn|${hPe()cc2(s%h;Zws6Ja(9$3Q)bnk#l>pMYtPQNWY9l!o9~0_iij!T!icH)lQ# zEv1N)Emf;9HCmJjdj}rg$~G<`R1bH25`w1q=~Jhb*?v`6~1*8Jn{XrvEzG}7FUSudgKB3gB1Htulr8gZKt)IK2f?RzMy-& z^Ska}%;j1<9I6@Dz6a-;q6qwfL9R6I+RV}zq=Id^WHC*(;o43_LFG28+$E?3BJcAI zV-A)X2&E}O4WLjl7ZkBz3zmwSlGv(lb4$4nZgbA07}S$e(HOw%>gH!gT{#_Vk|hBJOZFPe7e{u3Jy^O-&F{i5XReH2o(JJ-kV0`b_^ zFK2{ar=Kdv1f-3^COU6&9ms86-7ShNwVB?b&2fqFjB&Sca&ZM8C>Ot8Lz0nKnkFpnCyW1KNwKJb@aXZHRZoDW zAAX4087^-dJ8~y(yi`HG7*&+W=G}mCfZ->*1tB|1+pTSOw2WY48964N2B;x9!8l_vqyOR71DFSQ@6DYo40X(0?H8=b` z$qX9ogzw)2H>*4ETSgEP*L7y`^C1o{Wxtw%#wJRM2Rdd?mOel)0D!ZW_F)@Pa*$TS!|yf~=LpqGKNd~1Oeg}+eN z?Tj3ApAQ-!CySNnE@X`(OQildFkOh1PLr$(M9BY`&G^%~TU(Ix)05goIdyPZ+KuWB zVCjC^askN%@B?7vfxe~~3h8J+M3E_7&fu9if(jrXa%E!tdF2{R$ucxi!=~0yDPLdT z-|kL;egpz*poo6t?t|@bC<@3e0MFj%Z9b4`)@t_?_M9W4g*P9EVUAmDZ!_C63( zB*xF1yl|ZtsFZxSoah$aI#XfcrO3I;m(U;x;2H-Vxaz#&rRNBuBQ~Ij1MY7D(e^9b z-#dAlWJ`iJHqjQX{nazR@CFA8}Q)GeoBN zNpr5x{ja)TfQJ2n_pjSy;jdp+7})+-*R96_09XxhxB_KwdZpY#-LFe}5pn(6~6-F+~rcjdcd<} zr`bSof#a^V4n-AW}W`nr_Bc?pwl=#UnbviF+wtC z+3X>FzcO+#+%ti$e-hDuApGV%!1iat=+*Uil?S&{$;ezFDVJPN=<-teey?QUmEELP z9afNpXwqLd8|!L^7e1|gO>I8E-uwztBq zxb@uOHf=j{sRO@cU8^itp-tBqSZt}0Y9>qdFMFlhuK74Z=O(WFLqDIdIBF?TrgMm{ zbccZE*28UE?-T&YD>Z8r6cyP81r>`_3bmQlSTi@1-e_j7{`xHge)ZuX@YM?NGtm+u z0HlEd&d9%=4z55O45+QfqId+)LgEwsPt1Un?EGOSF#qD>;>z$!85`x<^C#19yLW+M zx<|fSx&I*t3nTUP>C7FerNvME`AU`CHNK!uVDv9!wr7p_?X+gw`K3m%LhNvl{RAMI5|1#eEDZg z%L7N@tEL(76bGPMT>uXTg!aQ5-+jF=$LO=Ovb;V!C3Vnl*;{fwHJ97mY=%-&f(Fqu zV%(bh8XFt0T7~b{-Tp;Iz;(<5dBS-5hht38G62L)k9g@jySh5=Hhdc$asV@!=>N2@ zw;x}$j?>g9&1-~wV>=?Z<*EATfzz$Et1>+3lwnN|$K~@G?CWi=zX0O1^)`$q_LN*c zZ6Sm!#*RQX!=NL-k@J12E9QT{Yu@?1dUt+Bv(vmY7XBVfDWW6TT@0-Zpx;GI5kq8F zFCJ~jt&J$35TP2c%L6bC&FLMSVHty(qG)s`p@;La1sKJ7ci z4x9dSHGb!z6n`F%>*=!<{wYuHobSvPlD$wsL_Ywvp%{lX`?c2i;NW0%OWj?Dt}JrH zE~>gVxLypuv@6-0UXd}@01S)K=Kwr*;kGaVcmZO;Ourg<%`#pEYW#F8XaWUV7~O2L z9I_KjiP~{!p+sF#Y{1OmRgAue1rMrT)w&?P3KIIqdg|IMEi^I@Qu?jQQa3{`!TN%)&=m7VD9Tj~%_lv-*L zTLso@*6=2To;}?J8ZncO{%Zh2O4(mEGK~BrUKK zOMGD8l(%k|&v_kTPxt)V=3wpvsb`7$wyLkrn8`5zH_)wT-H~mC6{}Duw01RB{lazri^|Rg-gfhueP7g%JWH z98~>r=9sotgQ=dV0h3(dM<|xi4||D^D;FF=mB%-6UhOnx?3tc;$( z%<7zbxBNKONj^E*L>UAFgx*r%L~7cYG)BYGZmqt#%O76cIZ?I&Bl2;CRUv1|=-cTi8DA1Zvfxna@RZ^z?i# zI|vm@c{|9$_pqA)fOz-ro%a}yQ)_Nc4j-_TEp%=QjLxzqJPamBe%-xvwsVsw?shto z^;rfxw1%CWomKSq8vUkmaOgfCK>r8c{$=)l53ayi?${FfKoEN|ml%L&u>3Ht)iVGr z_-VHqFQOLe%s7s(%OTkMgy|8;e1YrB0co1d;g@6l-qTkWX|}yVO|9NF5wByL_hSy7 zD>1AJrFcYQ;?^NxGAj64NJ{ze;V(wl_`G(}Y;j+5%bTV$(!auEb8{{N%JB{K#3#(( zeuO%G(VsrqLN$O_tlq|@yAMFn=NMv3e+n%R)?2Lnxo^YrVD;1~OIaEmpt{8KefQ|Z zoOG>KwoDBuJ0;1LH89uYV;joY7_nxqba{T7Hc=b*$?j4yT_{)l zM=*YOd2+I|yO1k;AuaZ{!P4@vdEJyDuvDgxow)?KU9rU&FJ}oK76*_Oo@8o$Pv>OD zeoRA4HFsll7e{6WU!H8CC|60fgj+RSvC z@yFofen$d`TCS-yh%Jfm+SJt`^XSM1crfqdy=c!xywf=lofQDxT23I3JwHE>?G*T5 z(V9A0#u!T1S-0%;+$J_tY(jK1!;|9xbOc&-%e0yEJre-1{II&*GqRf~taKaLc(=dp z@_X^+?bt1Ig~wsZQZ@rpsZ6^DekU4Q~hF*!`rHkT@HWpO%H5mXSY~(bMX(7ciDb+_C!U2Hs$O@t1|o z?@QlJQ8w`Gu1B)i$aI$oIE-jcSh;<$>tC|@&7TQ7AtUXg4He8!RoYVdt!;@W*)H7` zn32Sgt2H)jOd+I{}Dt#g|NU8l~0;46;cC z5LRdkZT7o&p+LE?uC7j%x(BGcEiGxbI&DtZ8FY;xGU^cgXo{KGBWAf+cf3PXohfL$ ze!x5T;Lr0C$e*h>=K#v1G^t~%LiKHJo@pQK9URI^NUrM#c=ab$`Eu2+KAx}Qov*ex*f-3wyhV2dWXxsi>zVh6Id7s5tIDJTa$S4SX`by8Ih7Pi$EqLe6VbGaZw_mA#P~P@R5Iwp^n*V zw7<>Tafuy-KA0jy`xO<|u5ou`4FQ3{R5=i%Lp zt*ZxT{=AB#J}DuAK62UB4mbLbJ@-46mjR^`nu{I1a3)9dWq5dav+L^utBOKg)O|VG zafkD6eKvbma?`&RrrP93mh22Tv|x|T+CJA77XSY5WGiu9}b7$bwZ#`2&}@MI%XYzCxqTs|cpuOcL7&dV}F@El`{`(Fw|%z~1e z1?^& z_NgO6w-kTES={aImjIy5=W;kp#l*y<-C*3`wezZ>rRBDlt~I~Dt{^WjzvOmnIX)!( z3E5ARrQsvIZfZOY7*U8DxSBzp89gJN7Sfd#lm&%gaZzrn`L#rPyoTTR9Ck;7qF9X^ zyMMfCH~g-6nDsSA8e6}7Ii-;DNLuMPgHQh3kSA&J@Td1b#A^Crna>Wo@)`e~DNekG zorhCqgRLKrEdI#E21poZ#~*i=a#K_c22YR-9HVdF_(;oM#d3bBu^awnbnQFwkR_VeU5T_3Sx>?3=NeW99SYu8i0o~YIB!V zPcESHSvuS0A>ZSQxzr<+=q4x6z9poFF1VpJoObv3_7vOlDH)Mv{H4aG7yyP~9A3;? zG!37~kE|au1By*&433}o`uaDq(Xy>&^T?b$w{LbLcnNfaIhwU6e;JvEN}rR z_f&W|UYw3)-l8aBlpnGD44rxVb|WPulAxuWt^q2RD+4f?!;16Q+n4z#DF*9Sye+OS zr62g`!vF*e=Ud(gY%)RLTj%?86QIA_s13@Tkfdbe$vF~30Y0$GuV4274MfVvu|x=w zvyA6&r518RD(EHB^K1zn^EE;}Nx%E-2L6U8Gw)lB5$J+5tS;i(5E^7_m%#iUwwiDv zWp19XiJEE~c15(ZGN`U@7cT;inJKiL72FiZywV)i#8gz~&b%Peroenv>Rk{%<@wHL zA%g=Yi7flwz&8vZ_)&VzBDrk)sWbd_FUhDL>!ea=tCykr`ud8Vp8T4+&X~tXpMh;Q zKu0dyV5Sl7nz#RUTzBNjuwduql>weEhL-1P22cQxc+CX9UTJ7(05wc3XW%KCX6J1& z0rHvL$8|(9ALx+)0BL&M=0&fZ=1HLShgXCOAaG|L+2LR1>TR;bcYHfXvDkvY;_LNMX2PabTP#TDCYy%=(1LSwQC} zT?Uji=WlI!bx{Vz*%2mgYG~~Sa0SxTf3#4%XrCQ%>ph2Teu}|f3aIQv&Ib(*JdoQm z`Tf**_~pqq)pvehQ@)?cdw-Slq5s;=o>FGsIpIm_q5kdhBk&(*`1ldI@9a+9z+kFA z@Z~u6&^_X0VB2}??#ZR=w>6a8QjC%~{$JY&;G$9h73k>+n6_*&tj~;yKmsISR{8=* zqk+ig&=-`vu_Xzc@{{L5nu!6&lVL(Pmb3J;*M+Ue*H^sQzjec(wL{fYqCmGhH%Lha zw`!=1+hQsIIq+6nBroyHj;`^2J7Zxw_*ne4E7aL2rHCqumh!7k={%jy6pcfcbp&h{ zFDZvmeQa@%m|{n2Oj4v|87tF)H^YZZj@}{h01?`m`pczPgzfxB)6wD2dqOk=V{o{=a|!j)1H8_V(<5civEQVBWhsaXMcVhxpJ&W^L)*>+=sc^q4FCw5cl<=vjGbpKQL?$brg5C(ZxS zbX8$hb={hl?w0OuBn0W$beD7^-6=>*muxyE6p@zh?v!qj76B=d@XY=F&$;4~wbq_7 z##=*2u29rkMN&v*=R%-XF+Q}1(Ak7I8(S^9u(^9=2icTRq`NkFlSM<7=^;2ouRI#O z^yt`_gOgKxvyv0O>jEC<;M8a8bD*Y) ziK?6&GAO~pNo|{_{3uffMy$2T|W>^CseBc%I$!ttpS zjqq8rd^&QBHB!@-<&unM zXq@?Q=qhWn3MJ2UDr-Z78XNF-VirU44Cv$pQq0YHL0^jZ9M+V&mcr zJA*`k0S?wdjfb8 zAp?H0T6mR|QMlJERkB*CltMC;0dwxAzP2*HTjyOwsDu5d3MJ1#&I#sN2zg@tFR}T> z#e$jI25>w_MMcFeFCe*tH`g*V!;v&KrBcq|Ds62g*VW}!O>+|tTDb!nC75U%(3-4 zF;FFV7M3O%e5aDqv2kPH((5^aUidNQa)lm4H7NK}OK8wmd#8#}#VX=AOYzbDhH?J* zm)7PkY-DMt5E2su&hHqK=gYfFE4mG84ZQE!HAM>1qoH zRW0|hkcQMc#FM`a5j`yI0pXb`w_gW3c6ns+yWy@s&kIp+Gd3I6}TLQESl`<(`zDk>LplYE4be9w2^( z(D6bYj*gFa05Zf0ib0EkSR&7|G*V2Imi=r;@PjGnO}*vUrt-1OInTo~kHO@=RvvT- z54OXEZ!%w<97pRmYJY!Shwy5E=1~6vS(J>%+;>1c92?1IctcTy2F12r>7VAX9_wb!`6JF393B4}&uPh!0%bcGJ+%kObx0<^F_~y}dmq zZJt^=P!m$;A7#=x3_RVXyjQ-1slil_jrfSI z2}tE5WE-gGmF9%LD-3nRVLO?z%RG}o)UId5GoT^!`E2mvp!-C_@ANBq<0-qaouv00 zV5ssi%JBvF9xSy0*w_ulQ#Ux>&pK}FJoZNU^ACL5K7(?ou<#vlvC~A5^6P>^735iL zeQnw({`Bd6adELo?Q(fl6|h|zt*ox1MfX{WesXX+yDrA;@_ON7^=*ki>KVWBvY#e` zarmiT_T@WWedYyaXk>ik6eoR-1KStwf#;R|+h{z~>+!@V(#qu*k;IljJYr3Uh6YI` zB|jcwWrWE6g_L~+5QsTKY|Wf`G+mKs_bEaF#_vb;JNRd`UD2CAKV@p>zbW&pblUb3 z1!~{xw(Jifpj$1|>78F#_+5na78R1}2l|3KQAbQHtc%}c+`C?)utl{Wu{YK3f9VIb zTCm`E z_H!wBOU8Sik3&btKMR|8JR(*TB&AW&LM4@%roYjOd8ArsB!mBv z$P&5xb^P@^3Blql{Hs>5^}kgPHQbhqTC<=FLzoCSUb`nb=b3-%Z@uMTo0Epvh@@8c z`nU{}UW!nlr}XR+?zbs2s3$ApOs~w_al5+>`{|$+$P_hCtGjEy3#!gIFzezOJvcfy z*tL00UmtS@oynj7q7Q^8bNriFNC+H;brJ3DVt@bsmCrD5=bwAy;zBiH92XaN5#Sj( zX6oR;3IsU7MgdBxY$C;t$#YHRGQ&DnvYJ5tzJvslxOXVFKAji6ZU%yt8E_C3UESf! z(c!w0I^_%+5#lhXnYlWQ0aBVWoD?&6qOz)YjJTPo5JsZ2XPmJzF*B>{QmYrQ2uBzW z36Ut-Xfwil=_DfWsB%-&GJH&h!vvov0h8Q&T+304(P8_kHuwhM7w+V}%+yW*Us6*~ z50+&iE-r4UV6+i@?`-<^S{EH19XNv=CSM!q>+5S98jesuoj?0~e?O#1wX>96A#E2fi`5*x65!tr-RlUoIS-`_vqiAlIMql%Uys$ z2CeDdMuHgp2|_oG9(DVN`z=my8$F$_5}r=x>(wbNrg=nOH1`@4)JaUw%#0e)vyAvLHFi@}Ah2nC zjJr$4!eYCmHTL@Y8n_ibCy&34j*c2Mxva;FK`SagK%t3M1glN1o0)3aHioivcrb&* z@o{lUNyN_1PHsm?MTHiqO+hW7kVrxHajvfBT8mz8S8&cR@d1;$(HEiH=-t z;Q-oYuk;<T| zj|i1`1bxRTZ<412b{X(o*SS~as-JOFs<2S zrn{hk!137MH zLlnq_tgaw74O~X!bwtzkG;#UjIgY>%5DeIi~G5BA+4Q)NAyzMhP z(V$n9yE+wGdsz%Ak#sZM&sUNUQ_>-DX14sGpKB zgdW{T5GxH9j*>9N+}`F|)9mh0STB#KzKc zFswt&eA(~dsbwB5QfpD$u&EhKbDARx%Szry>R#ey51!o!a~;ZoRW*BbMaG$iLn-Pd zKaDS4^Y;Em1W^wQ3u_L_ukwNd`x)5n5z@43xx!L_gkQJ>$l%f8Aq^>Jo!fSAE>YHK z-FO%>1}YK)SVS{3ym~jw38zLzfl-x5-`y;g>7T4}cUhgxs&MxC%+sNe6Pp2P6dgkv z3<5HO3>n<>miO4QpG|+8S}&{KUI_7yOZ9Gl^jk+JBr=QH^H`e_Pc2N#9=$_)bV2zWXn*!=-#l;zx#JLQb_)wykcBl)7IFgsJ|u)tcLkk_FJG9i zgsZTBi!t&DB<%8t)vx$h zN-R;4KiSIKEy*Yqns#x>8mL4f@@qaBd9kKe<3kW=8H~BILbtIID$@K)azgWEK4g#- z8j?HbonDbbI7Xx{Yr`;tx6i&?iR6L$_HGZ7um&^VgHEJUwtem>SDUhr`|XkPf%jl_ zadFtgLlEo;*xE8*@B}vmOr_Y`nk^Scym$4;$<193x=V?ti=?aDq{uA#rMhUxthJg3 zdTruP;YoLrn@ly;Dg-^#S0|_5S6kOh>(Uq)(R91+W6cbap+yX1CsjpFffBf-P31X$ zPVY4=@FH#WiFMcd85%->eoSvm2s0cgeSvXvcxp<*QR*ZTQ&-op z#vGn1DH?dlli-gC8;zxg7BpIz;0^A&o0wQI)|VDWM9>Ueni@>!oSUZ16}LP>tHPZi ze;%;KD#G&Bc)HqAms81(B_?AChH8HxMd6iK9E%U<(=p5;z^kcK)!O554eZz-(3&nU zs)>FsR8$LS^-7G?F8St9^3Xe!!!D*Rbp9Q9{!_k%6UWHz_oLT((%NOJG#hh)g%b*D zCQu?7GQzPk#eLXvin@|p65YRFrr!5u`>VinQ!`Bt<{%(HH zsJimr9(1 z1OyT+S5o%0n5QAAEEx+^U!)`jMKBixc}ROaCJ1e8?Na{}27v$6sQ;dlpBNR)PGcu= zzg&4UBfb=8^e+%U$;L8HeaO*St|qcVj|)Lh%r-^EK-LO3MoJ7j8y_Da6y}V1&c_x!$>eK$TnK?p*%T)H+k_;QcpRqs90lLUJ#62P#okrm>BfNs$ zhgg5GQ=jgvJwqW!mm=~~;qdl;D(mSDn>zpvF2D{|Ww8+sxMB%;Tnw4O;BHTzyA>lu zcZWG)m#mU(#DgjP$o+m|ChZQI{tz|26Mo;pHa8BPZL|Ut-NK~=BjTQ6n^4-v)$l5EFW|CsO z`!p-DnKh^F+A=z2RM2B6jkyVn9nE?)4uVD`pohN_FVPMV84=P&Gve=-E&F+@OG+5Z zWBy3ebTeichvCAA!KAF*!@gfsT;@R`>||}vg-s0=qYhd_*G`C)${alPT5atN&{XN1 zC0E`Vkf%CeCG)0&n>k1EIU0va-w}R^cXk+PKxBdY}#c4aIkU^jZ@?gxcZbSQX`v4C`O;^=g zSDv4PgCO=dQG|ttL9)6SnOr7$E0^LSIbsUS(FdtmO9AWy)3&p?R2#{nbtz(oU?L*UQJThQSN z_4#=^xoEA_?Q3huZLUmL_l?eL3vnrq!{c)kn=<~1>d$e7Ii~~75n3KhH0}D~TV<9y z$n=?lfoP0%tn~^*zG9J85n9{_+u6-!we_7ZBix_hhwBM6*WRZLBVp?(Zxzb8DWY}niu2z77M;ry+>YkeixQe z(a{coB|tX<`96R*DP%#9BjKKOm}X;PF~8Uu00Om{jSV%vEHSKxjox1Lp*8ZOiYu~ zLJkCkDYlD=1@EAeyw1fM-h@RJv{jwQ_-~Xb{Sb)NZhyAI^Y>WUunXGl*ug~4+Unxo z8#eg$wG?84ph&%2J9q^=F>Ab4H%g1%|Jg-B#1c*)&+s0M*C}{9Drg2ClR9X05`0eG zx#3>CtL8_m=TCB;34L`WS-F+A+Gy{w(4wAk?w}n~hkf88jg>n`{taQGg-$D$&9PKS z4l@ylMIhhb{zIYPuw2Y2gWK*U$X2(p;T$6-A{dQcX3`uTw7PqIavp@G;{{o+W0|5Ty z!WDiqka?Q-NuG+mFTB(vr7yLnhOf{jJ6UZdPbM0Xu)L5(T}~0A6c-nRGcc{Is4QA$ zldN=%Sz@z;7M{$WP>iYl?T|@wFcm4a7?TeG#etDj#c@U(!(_Xvov`w_s-&JM$t>OXmt+QW|uv-%z)2TR>Z+1HpTo{gOw zi0I+l@(6vbAwsQ;U$byqqQh4vP#vZ4Ys=9H#j!ZD&mKHCk3B4mk>Q1u6}lQ&4LNep z1qP`Po>4N4B(3U>KE#qk_0sXr$2)V}8WCo}l^P!$@9QAbQAZoAP%`9kz40f_<4ht#MUwA1b`lLtJK{+E`D_hBb(4AEAVYUpY(kXcA`*jki%dm*A&P4g34{Hw}P z#C(Jw0g<$!d)Y~ICUUwEv@sHriPoItgrRIDsGyjb3IjgbE=C9!+=-6cGVBR$U)O7n z@?^QStv?(UJh1}X;lCHZM1YnFoOCg;gf@_|G54;tf(^U~EC2$OFYphTeiW}~-O83? zoryDFQV?5q*et(`w24zx;OEpf&)&L{<~gJ(J{srNaZ@6O*1Rt>=Xp~+{K5c>5eZt# zJN1QjL^NIZ3vMilH5oruxYu*mj~UJ(nR%sh{&zl~6X7Z>9t?Ax1>M(U)49Q5;ZFL&%H`z-Wr0?*VsrXSM|g{{H@Vnen4%xAp#) z`}|K%qIvnebnR7DE)Cxuot%CkQvZPiS!i^5YDupV7Ut*kzS(~1?0m}gusSF;PG&eh zIq?TxA%IpIK+^^1R_g7h>_0Nu)z+rS((wjNKnlrLv$j>LFtL_QU$+zn zWrSYScUv3ohU@XLoZoSv{KZ0-=Az&VO-6R0{EMPGOMaz5BWkTlfh6P}6iiY|lo5(b zi$<_cF{t8ov8J4Na7}jtfYv?eYnX1o1!QO%)Z1c#+VEqpDh)0TeoXuY7dHooHPA90 zczb7To>A{j$vfqMa(o#;eV_v`0!Z3PRX<>*gRj4ssRqIi0(G@VYn;#V<7*K70}hX= zR#7L0G-pT0-MTTZ9Jg_1eOS}c+biw!b4f~!N+L^>PXr_DjT8K5?hM!(93@t3lAC6B zZ|JMB!7f4DizI#DPfE@cQ)=!u&2$`zv?r%FYeYRS80XgV<)^V49|Viy;9rN^dAqUk z+qdGd0Ewb#DobF?f+chP{_O#{M1>&-`9Y1r*9`#G$*07A%`72N&=Gh$ySON{Pcc>pOHeIysIwf1twbDb zA*4#OYv>23;6$rQK=HYyYwl#E;LYqG?uU^x)jp=hkKtiY!S)hVAZ8-eMpD!n1hi)% z$?;I$V5 zr3j+I?)P_P{&ivv;Nyf5FndK{Q##jlk*&1SeIWW1!^DZeB}JD$<1(P&j^*9XH$kEeOWL@Ks{)O zV9jHU(=h2ZbO3Oxet(b3>!FD)2H4LK;6X~T53KrC`+I=tgt5N{R|$!fWnFii zHHl?4P*=k_7QS<$k5~tWqXpBKV?Tz264_;pWya_5!1@k{O73 zW(1rkjc;L*&n_){P{`2)wpG&6I94|wW(4Cj7EfeN&lo-?cJJy}Jf+_{Fn)i`hkL$< zhjFFXtzpQThiX^$4=%H)@A9{OkyuaN7325r>Du*`{OSI4x=R`9=@V$IeOWMi7rb?d z^wt>&>cBAj(_2D(w66tA2MpRmq!!-wr~EPaezF8kITg<0WpddZU7xdIiMCs_j6#Zl zF}7kkZB{pNNG22F+v!>O?H+-?TGK?TN6OEBm$}1Xlg#FMF$y_}|A=|m3NlY+`J)iCx<-P?BE#Wtp+}nluhnRmB2dIb;Y}sl~SaheDe?x4-3%L+TLf ztP!=?oQngH>ky)7NvXoz)WfpzC0dbDL%Uy43JUaGa4l`(%jq)){KfX9Yrmy4SH-Jg z@_b8wppM+WFB)<^33K8#|9iUs{OJ?vZ7$d&uoWoMX9o`>K7(%R3v2)h3QE21#`3IF zy=d)ht{YHg>_00z`ZvHIf-@Rw-6dNlm8UNb9$wQ>X zapZ13)g0?*iv6_2wGeNf87xxrD7PUrB@B~4;b(3^xIV1QYfx)*ngk0bkK@P<@PUw5 zO+DGnRc#-atTXHY<=AmD+M~Ujs?4B{kHI-h)b_G6t2?22fZ;$HOEgS9Y)Ex6%+g4;^XxS9b1NN+X2 zNw`M%t;$a93`7P7LP8`2TKU$n@?4ut^Gt(}k%gS$i{4{UQBt>J0+f&BaqN5&1(13M zL);k2dv{cYRM{!KFHIn|!r>)RJc+u*;}!Dyu^17RBgpGWLs|576v_PRg^d!vn|}!e zofl~Z57v{$mszqUcuwLAPS^t{&)#+;&8anV#LYw!##&k&?hqD=ipz62Frb0nw_5tJ1Ay(f4ZCNk@6vpMa$Vh#3{& zZHqA->&W)o(w(STGoC+xu72<4*ij7Ziib=OC15k=Mn1-h^roGZi@(t}R z3|ZJH#8GTIJ)ap&y}IWBVFV&4LO-CKuj{ah3*ulEE{sbgEEhm{W2gPpxmx!n#eeLg zS-g5tnT48z=x)oYVs@`B4e;X|ZC=rS8K6v~zC?k}as zz=0NFS+07spBul~=4IPm#{o9-o+)WJFx2>e3`Rpj4QsOA`fUPGGDbD zgpk~ccY@r9cEO=Nqslg7T%O-oP4s?xo9*7&EN9IhEvH6y5OYu=HxbC%e#{6>fftwZ z`m<)HqpeKm5@sF2j`S0s#sUl5izBD5LA4_Kva zy);?W(5Zu*>7Qrk+kHXcNyH|?gckvHprxxT=$?-7Gk;*Q5Gjb3%`vxs7SVv6k|OA( zsu!sj0WJchu_pfFYnpnv!wphNSGc_yv^7Pd_i;&&D)2q zXIP>ZELcKASCIKEuWwrtHN{(MNO5*1RJ@peO1}He+WNq8)EntY_o!zCgnMHQ_$UD@ zlawKiFA({ua8=4&>mJ^K zxkK?{WXp_i;;l1U0y;nqPPSJzNn~*M82qdKQmymmTlGcOR1iwFP@5~L)1Skv9-fT? zUM}4xG(;)2JPMFMXcwb(-}Dhk zDG&x6&IANf;3*A}>EGgcO)`~z#2S-J>r7EyfqnCMj4*ZN&wy;0sZKEf&(Y?4whtRN zz~=pDp{a8Kbl|X9iy?u0+d!mnDVTo`$cXuViD-i1NBM@C7ObC3A zF$>}y+x!NLeDj|Q+~@#iv(eUjsnN(u(G#hJSuno)mMImQ-jv!FHl@3L-| z65_?s4VD+y?BYPD+i?Q_1)SI?CFR;)q{VhRT_PJvw$!Ud?S+}+*EYe z)*ldrVpr2LK}X7F#Xym};*mHINAmGRbhXi0W@?s60vxVHL`2{QB4UY6B?$4AM#b#g z%GrF_Z=OYglW=>kAv(s#X|wtTAXA}x@n<@rgeC=^+5W|;($zABz zBCVf^1*IoIwTtf5L7Y2BN#Mx^>z`nuVUG=W-*^m8(eRd+-b!I8I$!PC51-V7-VMd zwu%_X^A8QPXc`(We=0Ht(1fAyply!El`*_7z}5g1{?cx-4FoBJ6m=??r2sE(V35KU z;0Q2>q6lIoxYWTNFlpZ@1hkSANC@yKC@6!-99V&;i)`JzaU0xxVb@0J_`Hgw=44E< z$1bSA;K@@uXMNF{N#%K;Dz(UHVoukBKVDvkyxM zNX>Y5r$T@^6o?4U13H@5f06mCsLm|`GX<=iU|ZcH+&ISW=8xN8*5a{NK363u#ydQY z-Uue($0|cPbv|FA-aTxctZW*s$y|bh1{ugo0V(=+kZNwv1D2JlGTi3S zJ=X1%Hl)OU!tgt``xIWLsVkKnlNo6yB0(APt=lK@#GO>b7LNC;Hnce?sW!><#=C87 zTn!&AK$*A}bU7jRcs0k*^jD1N6IZ`d6VS2#21%;6;xFpv&S4w;;($onZKpqmY(gzh zjTyv?N`2Qxz6l1j3)dn+5|Ybt{;Bb$Z-8Lu zPbA8c6smV@srbIa$YYb0iZ3Nch7?Z2r_AJ3!}}9n$~qNIcmvtBX^^G*yv9BzY!Rcv zOKSt}1rKeSW(K;~ZgIs`kd6Mq}%7+`1nTR-Glf7iBV z#5xrKl^kE@`j+Jd$oD{Yu;EwNvWKz^hBt5C)V&$oAPclJG-NrIu$@`4Dt?(qNX$;S zA3i4NVL@DxikC=+Vi2Z-nb;t$d=IC5{QFa7vimTxBGdl+H&)+oxi2ABXkL_Fr^RZH zT-N&Z5r2V!S*)ZXC%b_i+>W9FmemNP zn1DJuj~B~dJ+(CRjj@;myts1nIK-sP2L(y=Kub!CJi) zjTLJpv9~DvZKd&XX}fVR3GOGdo~X~t_K-Hr4-wwkO>NDYPJ3QH-@H%sK@X`8n|Fn zZes`%^RD7MO#?%FmXQoH%qq0DG86|nqM}v3;48+sPB^q_ve5ChY##aVB{>BEC#ij(q)rLiKTe8BqZO0cx3EQAHmSTa#X6 zVlQRQvyfZ)V%jX1HAYx~tiPjX=`nZVS^T}!fynV{9XJ0 ztpJb}^*3YimmwH{Nn#=&Nd?iynf6jCRBMCH;btAA*c=db+1$|=8M21!uwK~O<}Dr` zb6J=h@CX;~CgXFM;?vobyvKQcn3We%<`AdEcvteUT|E2N)~YWG>!X!8KN%?Fwx90L z3TmBsVJ8}xw*UZ2p@YZ0br+!`jrVykeQmGDMFH6j3m67;R$lGFm7mzh@Ud^-z5#A2 zFC{#i1>oQzPX{5SP+fF=@P%TlQ=4Xr>kJ?WQBC3mLT$Q|5!`9SN)ya?) zLLP~bRnC!XemUB^5(L_%++W&ClFEgSH(lI=Kc}kXiTz-~?EHh;&Pz2GdOlB+OfDVQ zdarJ3lWZomK*$_-#}z)%i}BwCNu$DqGQfZVlV6>lp4#PE+y!;==idi9wPhJ<;s=-@ zG`*oyX3Fx$8;Ik1R#xtiVr*2-4prwIPt-CfW{oY@bM;BEKq z0)iUK0I|FBWk%Gij~q(Xn}2QW!K$MhE|GbJZToIefb=V3WDP&JNnfKp@y)HgRxcki zbWVb3^xGm3F!BRD85p8bY5%~SvLMf){Lw(I+*2zd6mbbd&ki~I`qq)8vYJcVP@|Y9 zB%fxpTH65i32s=8^k~g!$)qpELsO6A{w4eF3$~x3_H(!lT7^fDc2kllm%`_by>EYP z82_lT#qlMIk%iSSuz_u_==aRPd800V{k?%?VBZLIgun#`Vu`>sMk|bRYd(mx^Jz1^ z_#9fn)DWou?f{401KLNR6g_IdM2f_H_%kF?_U)Uu^j0j~+0?lK2?YqH>PtU4xXT;o z*80qqV%X3vwp3-9jbkJZTV_r&+QP<`afIA^z^u=e-S-8vzAl{3bJNg0aqkEY`!5|#~ z$Y8*vhTY1Sf%F#HOalW0A0zHST>DGsu1cW|zi=Sy`RK6nXX;rHoB=P!uWviEN{2@$ z3^wEjz0&yjMPkg@8B#Q#v|g#xrYyYg$5Ok(X#HDA@5DRpTI{%hs#9S5;AE7n7FzXM zu`V>Sn}>q~vR~}swO{w;XmD6@LghjSR+9c6rWa|uKd+Ryw#kAy?129W1oQCh{{iPU zaDcAH-<^!rsQ_*P)O|2<6>wRpv(#p?pkrXTi{=?lps6P;(@~{&bsgEAjIrtCq7u;^ zA&6(uP*F1FE2Ri%m2e^w5KQn)d#72?GNjijIv}W$WDSHfAp~kxlq``gD$3g&;+MHB z?-eq@qg=*v*&5gp0K_EgMN9{XcYFmbwm^w2YPAPq1lDh>SpG4^O47WmsDR;PR*6_R zI0WebnWJrg-s$MV27$E$xL~+$TyW7?h6XqDH>{TWQr)TKde+aOE8f_?EnQum@$bT{ z!02qmY`nd~@v~_V;-zC%NplG_Swc~g=#$%2_BL{r!p zJ~CvVq@h0WEth~<9vqP`6)^dpUl#n!1!Esn{WcJ`-fT&`T6|ax@qY{eCghSH zowv_!N=68mBOGAuJGKX=%{7TmYTqFw`aFnCs<>Q1yw? zuC$i#6gsUgj-y!cpQy6s`(gwLEpRHys&U$hn}J2fl@SM83L&egf@ja3fiXU70ViL< z2?jckkMDGKboyaYo2(L1We$K!xr+~Z-ic|hYwFhhx9eYxX>WJYs84wh-y!v(g`aQ? z$KLLR9=_Y2wx;oTY6U)&YxrZGBIBmbmd6`KuE4Q+1{G4gOj|f5MP{inrnOVuN)pKJ zk==`b7u5fF9sd2!8n2Ka?P@91lF$d5T43>m%?%>|NVO=CAWPQ+;0p_5uEqGu<_w!G zV0D-V!&5*z4~{xxAoSCI$}0%`B?1N}Fi-BkyM_NoLSEB(-lATaVS}Ss*Rg1*cM%}% z_m*~+6+@dLQ~+C79{RR97aoBMC!NuhSg+YYr%1!p37<{Cy_J&zIajTX@Vgfe$1>9@ zBdbjFYp|EIdDF$i`O|exIQ}tFOQSvnOVk>~Q@-?xKWYc46Yzn9Tk$a-8d=?OLmrJo zZ3_bOU%Rx}XdPdtBs0Vu6okBTtl#=xQzLX}99#r{0%ea{bgU(ApF~RCt9xA?i#Ydr z3!Qjp@=H&SenOQnDJhk_x1>cdZr5h?=IOwh51xii>^e#$ZCtw;TJ@r=&r;uPluM|E z7@z~i4_npT-7lI)??D|)VrC6Sun^>@!Brt_1cJx@ zEthxFmlr7FWBp9rxtf4d_`MVMu5KP`pOws)o&F>C(!x)~8TIi7Di-!E2{lN;1sVRx zwEILTSs4e9|CR$U4_l8ff8AcL&Sf!Agxe@XpOLBKz8;jMiJ_&Hi76uFBV_h>&{tY( zLw)Ot-(}*OYP+6X)?jj`w6TG3s=EF|+9)6tNvfBEp8?4-XD00jr0%Q#tILMlr*(b+pnj**B=0#5A?0=pao8AU5mtpMJof_`jmm$!puhn z|J?*3FneRL(Yf=_0C)b(35+Rl_|{yB=#uH(Yh)A5ogTw0wgfTTv`B31QaH)q^swJN zQ^fqXGtbWwn^^XV#>Bn~HMDNvgFe>)0SmpW2via^oUbbba4kfow4*YnY;@>*QaSGz z84f+;xiE!DPAgYU6Uf9Zu7l2L>=(@#EX1L!o>;Jh1pim=9vLDG8?51@8N=JHdQe z)*!+d*T5QAP;JkfRPDUUM}gT8PQmZLW(9z*U69-^%4~9N`PbKC%cJG| z{t*UE%pSr*X<+1wAv*EnX4VRhbN0ouRw>4)-w_>1T&QeWPOG+KX z2`7tG!KC&4;rXJaq5q7t?|^;ifV;GzILutQ--`Q+Q2$bZt}x_JbO@>XoNaN9smebt zF@VB@te|ax?B)Ru226mn``X|}SGWAr-81y8vrpri>HoC=_gt`F<#R=a=-vsaN4r3} zs^8^=kh)nhoJ;Ni@Qq%gziNtH#EL2T*yVDd>ZLkB_+s|Mk5Za~aBFEkQA`C)yCH7U zsN-0qOExWzPpW*?*2xvqno7}08swipmQ;o|8!42uV)t!I_U9)_)S&u(X--uS2e5m> z7iut0lD=~Y}xI5dIL@h>qw)CM}bU_>b5lX~_`sV_4 zMPb*vz`q5P(ixI0NF2^`d&0v+uY05EX{hW}Ntai1>YgC_h1YeX-Sbt_(C#+i?s=jt zlE?NyCN{uUlR?04t`AQ@s}c@x?u)Wzz7mbG(Yt&e9hD=N$V7QsvS<8X%(Ja%E9r6* z)yK#)ER$zv0)$i*?%C2w;`_G^x_)S=L#<3cVqy;|?(H%Vte2#ASkHd6r%L~t)UIhf zP~Hs+H$YWvfgOEsWpak*kUb#`cnTqiM`zK6vp`CMSkGR-}RRVQ5ND!(9zNH=P}r_cF8@-*W0@mxVB)!HLc|*wT+BmJDmvTintgG z{ySFyGVfcpeY*8^bTj}vrRK#fLq62nY2AqWrJ5uv%IN|Ac^~pkW^`c!7J`mKH$1JB znuZxmGSs&Z)aekvJ+5%YmNc5=MQfF!9qL z@c%cmm;k+_8fRs5bBa6UZY*sj4EWD-1^$ZiGUlp|ahICQoc#=7(@vdkSf*5P{@zGg zH|xb*O3~Dq(R(4vv6EZtzAH}^__NmX>oFbdu7vwfbpdF-vRrC0z#4!>H#%OTS}_U+ zgfN%-!L%PCmqH=@-p-11WrBnB7J8KOL`7&D%$)bR*m^w5-<+Ah3S1_}|L#9JVa>%#lk}U{k1JZBUVN1cVw-_wjb@3J27@6044wHQj1eCV2-Zu^XxED{;~z8gU=Rk={Buy01Q2tHbyD-@Ou&+|-2a?!U-(3L4wOqgI)Gb@S^O0! zwj>_sB)~)wJusyTS9LmRS!7WG{pUm>c6@J6QIb`u0oiFPP9)C7?49v*^fEUar zDA2Op2Xx#v%uV4BniWz~QsJ*V_V5l{=Nu+;bLbaKHy0(|mV``$t=qapxLen~y~tri zamE}Kv!5`@Bi5-NI%%FX`XK~loK^b-@87`42apgl@cj&5=^5a5!T4m6ql_sqIq43h zyM?Tgssh>@yelir9{H-kb+EV+G_$uqflXr86XXB}frJLwoU*d|dQYRF`mB!PHoe21 zI_4`2v_PlHsM^*KZcc3+Cyy_Xc^m5wucc{_Y%D%;=^JPiX?D>l$|*8`BK_k{-D3`y zq)*T8iHV(nAP3)t0IP4nwGk`p9a9#bBjozZ=BnQ7Xm%HMtkD^aj~!ig?V3;k+1U;; zXL;B#<09}uz9hh~c?)(pkr=XS2*4HMIAN8O*ml$ylJVOqj;f zL#OWBze$&*XC?R~rzFERLXpDhncmWq*)IBiRMe5nH3PND?E3lycr^9rB8!WQ>LO-; zPR#yg2mWfY8x+{g$;oK}mGd2lSQerms&{XwKFah2}2+YOL&E^5}>Ir9~Cw(iPUK!fP7}fd{-%mWHCy94l=_uG2G< z6<=BLb@4K|&~8&{%%nY^T58Pn;wNNXbYQ2<@=g$;3-LVuogY;D z2Dzb{<3-9AAV|aZbM!fjmfZ&Zc19Yy1*AFbh!bedoY#^)I zW(V+hY-YAsQLBJyGx5(0>%Q^TDS2$g_y9hia^ zu8305n1t8W6ENq^-s`QP5nD7&)cNi#PctnET(pMok zhQ`2i04}U}p?yGL9MA#xfz0foTa|#bJ$54H`G8gxC6Ed!qX;y?MUF%H?de3{)iuK6 z7O-_lik*UdSHi=`GPpU7*@432$ong+Fs2G0igfsIDH2BUPpZE2fJj7|h@VyrY#o?& zKm`b3gLa;0`b#F{Wo=`#6U%?WbAY1-ye8mKabGmzZa|HRs7O|2mE#=>U;;qH^Zh3$ zwn7hWGgmGCFD-{|gm%sFc5}P*;X~3qD<1KMVW?>Gv3YIk0;0^k+r~!G1}|of%~m{1 zPVD&Z`^mq(vufPsO^Zk1CUJBr0R|`un#z^5dVJt}0P-Kn3YLZc{^Q8G#2F=dxF$WV%)>+YATPslF zU7Vj!a+$WTqs<(ij8LS0bo@=tu!4on<%*$SjAC(pU0>lTl7|-flt6!&8^XT&J+`Vl zS0poHL?|>g`2!3haQQkA*2+nE&;@`BDO!eO0F_nA?$n*GjOY9_PI6r+TstlE=R9wc zgvo`Zapx*wNxj^$cW4$C2$#U)VAZ3*Gz_f60o`VDWT!Rb!aU=`4tv{i5<<;Oe6BgK z4A=uYp_cT8;6>n24s0+$O01-jkJhC*jZ9~jj5aV5*?v0A z&1LNea`5ZkhuOfr_bn?n>2E(lg{@fctZ`^n!2)l(sppSK1?&P=Tzoe&x(LFrKbbgw zVRNi8BH7DB#isIC1Wwqgsv&4_B8oDnYpcUz>Q_jTl-1dxFg8N5G8(iu$|y@_sZsb< zv}^PUy{n^%<(={|rJeGCx;8fr{|6`naMOzNo^NhIyajw9IRKBtfJ;Quq(NyEZftrk zp?oV7ya}a4lK2L;(?!%AJB2J|ezPt)Cg$U-H-o&X9IQ!l9h-T*ju?=M`5lZtNF6-D zprPBpR;u4P2%TrcQq&qP>P-wONEJ!o!qRZofo3QRu(%OZ|Ma?VN}KxMf1r)$yZ@NW z#Qy~T^z;ZrKf+DI~~0?QorVkMyYIBQOCm-Yi4F`y-}0E{DmVQVqW z7+j1Y-(Rm39tUAVU;wYrmu_9gC(*x+N(0PLjwxhl(bBEua-3oCPmRZXVl<*`5q@kO zrH+qNR_b)w!xks7sdHd6Xv?smWqgS$4=0<(DfvzA)lOqa*UtxBnE@e;+3L3I9Vo+G zOrGXj2pJ3E)YO

OHvH<;-$aO2c`D%>21lR0PvWoOCT0;w(W8C`f~p7?90_4kF%^ zRr-ii6Fv+^+KMX&RyqSNnq0o&k%@Ba6>&0U!Q=C`yK_8OkK0wuWomc*m@0#9iHpE_ z)O$K1zJ&K$@yi@=Ap_3hoQ3~d01DRK>2hvUgUv%oY@Gll6P+zg%xAvw70kk2_nmv1 zWQn{+OxsFK%tcf46)IsWIhvxu^T3dsopyS$Djof?lVU}E*Tp;anr=Li zXS@)n!CO5cHRPLG#3SeU1Suxu5L>;=wuk5*lrtV;p-Kd==FGghs19Y74jgwiLcPZr zl#t6*wSKb?bjHLtHj6KpsVexi)Og=m*mx$ljfDk$H*S&Lrz3_m6p*6QC(JcSs=h@1 zo3ld$6vWzPWa@Oi(gkCfI=9AYb0}J9FnTbFyEUe{xrBR}2IqSv z_Ic$%8~oy}??r5v90FxVWm1%og#$S?q(2ZoLZgUTIaOa`NZ~$x`dt=eJz^TN^kek*o0TQQz;L36>{P|n$OXepS+MYBk>;cx;akI1 zRfVB4&gnFn(sKJ z+P?Av=(l^&bF22LU~E26@gqAnNn2qAuI&PBVn%N#T2`-rkZk^xwsAz1&^@km6`RET zr;IY;0zYn{4UctVN2>QZO3wXc!UrG%Qfqg-FC;JX{Z@nyB03_AtI#9lZ$*{GkXK|) zpSZMKgXradEX#Twoqy_{}G2NG}@L(~(_+VhpzXylHP6VkKUG+`Eq^_&H z+{Q=3jwxP)lo5zGj%16gV1mi-z&53l{3}67=l?gUgXte2Tl9rK7Nwh`kaYV01c(C) zP98h?OpHRwgLs2s#5rjZ_=9Gw>sr}lc+hsg5OfbVObCZC%8jkY;|hf*{-fk~OO|Lv zjgz0xRJ#7#T`2IhD|AoX5Ft(K6hOzo@p=3(UhfU;*jtbb#AN*q(_}V+0zUjIsk)M8 z(E9`^Qq)6vD{`9s0nT24yz6N=hM2X{|3#4wkgI@caUoE^ZS4G)unb&d-XDU*>%85I z*L8s#4?%_#ShoxMqK4lpn5aA$*1{Yy@!2ppBtYa&6o`1nATjR^3qP|%QPTHn1lS@; zb=;$$uEtGVNF5bMrw??tRR*Pb5}GY15DLD<%VAAw!D73thr2Ts69d~cP3%e5A^wa! za~HV3*fJ|msY)xms>Z$fbQfqzCl;Oo9wP!=5WsFRs8b{$g>h_o;mNMD=lWl%7I+*o zbJPYHYuIa2+^JTCQ?U)<`!S3j&Gw(MkhE9O@~n8q?3`Nm7V_yJGA_uDDokt^fCjba znL=-Z-h=(Ah(3d8x2~8`ROhN2v`-zV*I|Ov-d5kDgR;>G0u}Cki$6t>i;|-;7}fhI zZ72iLb#SCevN#k^LKLo5If`##OS%t>7eLK`ub{TdRs^DeTnPw6Kqm}vECEV0Iroka zpG2sV@@s3IFwlG6pHBhdV@CUmXd5^p?Er170!oa#ZrZ2<5c+igc#9M@*_9J0^Wg~d)yq7q1@ z!yD_4>ClvB!qYpD3V_lda1acb0Ac>Jgp;uaUhqP!3*bltIJ`o8&vUN;#9Z;ON37ns7dP?GumZOUC_=*xiZaR^u zF~%tP*i0q|+ zvV@$p{OpJ&$fC+utriW@GM9m(}=!vX>&fIx|vl5R7 zTe7vX%*che`_c!SV*^5p*BZU9fzZY`-M7PUDyPfoW+_M1gSY|rD8!3Ufq=R(kqbV6 zj6$_L7qQ#_%H-)9%k}y%5)2ghbq^T~*hmzC)f8}EXemaYqzo9M={GJn1CJQ2QJ1zI zcC7f30Ur?{Y64r#UN}&y;Q;RG%bs(+yT1pcxUCLvGdhEMnSY)#O9W%x)0CwuGTA9_ zwIUAaMfKR@rF_;3)P&WAxE|_$HEO9lx# zpcfQOSqvtAYNv7*x-$U93BYrliSxTHw6W>NNtR}o33mVYv6DuRZPb^MLeCnKE7F={ zJoUY(1JXdH{#?cH?$OiBZ;jdJJQ{RKgM25>v!7hd*FmJiaD!~x4+sU5$3tzv{mxYU zIQUtK^nl+$eGa(B_^J8F!+$6&?EVf&PPFFWqdj>7Qu334-?__msVM_~qQMK0F~K>y zvBOeNvk&UaCnQmArxyD}Qvc8JDYJoC$?6;?s$mtMj`$w&;{@*gub&D2xzx$euR@no zn6n37t5QdvoO-IuGP*v`E$CA-`~*9Ep!I_PU0jp^kbEF{zuU-d4EXB64&KJ~*eDo( zM?n1q7jd-q9RgQ5ux&B~2R0qvdo~U^7Hf(ViYUj5Wh6U&wA(TzZluSJvFg6S_SSV0YiFeWbC5r$*<_AQkWF(Hm1c$|Xi z8?jE^G&&bkoQOs?aitjhQL&gNEG8y7v&B5!y1JEW8eO|VE-|pb3J6|YT>J%o%>~89 z2U!J72H+rgQY=V_3qoC^7?=-4Mn>A8Yv!*B`g9{y7C0gp`eQljh}k|u%m_dD|9;7~ zx_ZeH%ccG`s9|f|dIL|Z5G9GBWVN zo_Js+1*Y6TZ25oaEVc)uCGA^682&it1Q$i`6=Q2?fGK|9dJCX$o%dkIu&l$#^+%Ui zlN29{(7247aB-gs{$E({2Wv!9SYmqx{GMJ&K= zb=vJk792G2YH3k5)19>hMEeG3?xCZ(61(%OiZ zXHi=P9cIh~+u#@H7+ne?g@nufM;%rGvNv!~h z`{)*K%o9s3LvKoc&kF&It1bfRCKD>N%W`DhCV(>Z5in7yjDKrPhx@UfGxmDlG--9Xt5}tCImRN|$O3erP`H0vZH(k`B0zegV70N8?~I4WeI02dZ7@75=^ANts2 z4H4HI3p&)my0t)7)1Mw&Kr?czc@DH{1CKQarypQ_m;yR*DMghaPsjtiA~3)kZ1g|7 zBQl%QMY)8G`T0p3rV6gH3ien#Yu-8Co-3^22P+3r3nC4^V_cwo3e2l<3eqkpz)_~t zFkEUYcbL~Ze>Q(B0(rgNlRLNF5$`)T^og2#qZcjUa%(FNyM5R+6?A3yHQ5TPepTLy2{hl*VdVS%q-KTJon2 zuhV)1>}DQ?UE>~tOocv@RY)s9Vg$UpR@F1=%9#wvH(Z>YG0cOml=WhtEej+rSMhtN z572*!sq<(BzfJ?U7q@_%X^6-2aCvxODWV3T5z;zs`WKzIW>}YF-~3#BxLxR4m1MRM zB^Cq7Svpa@e9r!L*N4+VL@UV9mdeq;jJy-VJhKvaF7* zC<^avv+YrNlo28CDMn38nZd@z&I6|byO2CGHon5+$Pb0pvRvR7AVp#C+{hk!U|X7B zwG)`6DL`xm_>}>r%w50WVbE##m}xk0bnO_i)hfdAwl!s>S?S%= zOAuH3WOcxN%FAa16K;5P@xb7I}1haY-q>t>k z61u@N^tqA*3RQ%Tp9Jb$qk}!51x1!u_H43-=grLgaf+-<3R@|uUmc(`8i5g3!6_5N zME~hkVFeS%P)Mu@7SuJiqXuay0>=g^GvrExGYfCGe7JK##TADNq@BW;C}Pw+qW1g| zX<8&}t*%8L`?rp+xTeYtWOoDY-FDzY1aACVX$6r3g4V7b&^5#3joE!Sb2rRa|MQ0s z*-$_C9k8Mt>MK^{ohg%)la;(T{HZtl1Qz#O8;*gvSKN!i(trP50thv)PNH2@|HlCe z!3Qv+e}3M@5FW|c*m%2$KZNU&<8n#+mSdEI!Ya6M-xL?FO&_IYEe0*no-3+=Mh(R< zia;n*U%mX&%KsWKun#s_LXNlf-)E0=?-*ro%661$X+AuqRSC1i2b5p`Y0&PwCU%`C z-VaP~|4y&_D6=)zQ&JD9h{kCTgv`9NQ^zM*M~>OUt11*MubXux)F< zwbRezL@z|_HiFh5zgxBJ>r^uGztueDNk;h1si6YzfFj^D$aJj!&!;e+FGt1@Hn9WT zSABZQe{ltf2LXWPkC@a_iFKiY0p+XEB-lX@?DP@reqALtUR{Pjh2ObHAq`@CjhdF0 zG$1(wDo_#7kqnE34S+GQqw;O=0oM*GehlyguDl2rIMBa#pzzkhbU#z)7PQ;a?ika4 z(gT>h&-`R5DS+)rZvAz;!IkbRVslcS-f?Q38F6dToX5XKj?VycM-0B#MKbAkT6 zW1#iBr3D9c&N=$b*7~-mRsVgl2_`6|@!T)w?Zr=8(t+|yJyKjcF5wGHM(D;lZ^eXL zDBN{t)7R(W3&jZ^e*tL~5pI$+*x_WU2|9@W<(;`S`q@ol{}+B>|anwp#S&fZqE20BTFE<-@n3kRy`RvQj@ z(lUXR7dWFH44$@2O{W0ZsuBNJY4A2}^AW2BTupa}q5vtm2!Pa#kIR9R0Kn-E7`sMS zj{%KZ2{Q3A6tnh_C5%V^{z)%t2nc=6m5+(kD-*pK{D`JYq)0__)s zd*x{l`DK^C?9!&>OuCf`1=mu4%1^}{iXkmyfvz*s9M*~!Mk>qWqN6WI$>Sz*O$6T` z_g+tX-cN1(mw`eCU>gRx01mqN*DN^FN$eX zNWg@-DB{`%!i(kVD6zAKqp27y4sa~frrN)W6^1$wRILgCvwQ@JgetUlcA8IN`f~rZe1^n6j^p>n2=h=w1u<>3 zq@x{?AP5$bDV0~Jg9?sBqbe?Tei9QM5a4c4u~hN>Qv1(`ptitxH8D08lW2q_6@q{u z4bG3*d_F#_PL?G2=1_~dh0UM1O7}kw`aw?C6T0wapsn(2N71NVf!~vxxm9Gk!8{*2 z@IQdN4}jsvCJxpNbIW2HdO+&a{E&M*y4~uR2>%R@)oNo^*5- zJHiX9h#+kwESXLW-hNFC9Y58fkcKY9*7QKZrL7*xWA{#ZShp85Mj0O8Zl^&?7;>Wo zH0OeGj7xiMosp)_Ab$!O6##ii$;9o|2{n{z&K_;UoH-p^$myX?k^ggg!-!$e|6^pk z%3}iOtnUIChg}h6i+wB%rCa)-W$-X_DoDxz06Z}K%E@Ps;1P(n2>qR%MFT8S5MUJG zD3;^xmpaD{zV6Eq<~qN(@4)=SRcUS=4?WdXoQ;~*9eQm%2oqNqK9@Rp61rKf52p;C zGG-)RMvpSbt%!J?c=Rt-Xd>Mal=uW_l`Z8?{_{y7v3^BdqBG~(!&|KKAPGJe;c?5+ zNsu~WFx)#ttJ~Np4aEZNwQG2Vh+!xs5{?&5b;b7A9)g|4WzXwwpd;`Uo0W~9~>Sha@r1;BWhF9@fX6e3AU_az#a0jlw8mZBpA)_)pE z>Z6Av`h_6_dI@=H#(9D26=~)SLnjBU*sF-29u}t~o(3a`Hdwq#Ja%zsLZb5!*~3Fr za>2rXp6lefj^lI7d`L0Lv^mxBGOW)iVwduPqO5Y#pJM zNz+o_vs7((XOi#;hspGgS= zwB-`#^66ksGv%zS7>8y%8FU*0TeddFoH+viGxp*bNiYl_f`AnJJBL|!vwbDP0+9i+ zpgyX{l>r$_)$5Y={e+I}(FYxaHB*5~ezTf|#XeECuhz(M0NZ&%I(6EcGyM40I@=Z- z#KnIRl}<2v;6fc!1gQMuU^D;#m{ZDx>jt`e!C{A8Kv+({eFfT2{&&j<#4&fkHdp0m zIJF07Us{&UenZk}U4tfML~E%ey1-G@I5^H9G&#Q{L&eZr(g0O4o^_l_foQot{4e0N z_7=2SU@M_%X0m4?5%$H+gP1glUG@)Gq0SMp^B*$g77;9r9)fkpvMSZ9PaFm0-h4mo z)v}x@5;0Lh6wB#ljW>brWpi-2%Q13af(j|(wekZO2EMs zy3Gd>8QLafu2WQf1GTKIJw{#K#T)j^=K-1eGDtV1qFo8OtHzjuz5@J^IA1p*tOOT* z+u)z284vg8MJ<(K3Y#U|i06VppoydJG%2_r4N-Kk7L85=SJ5(pQgj8%M1C@hA}zj* zuGOuqrV7d@o$Z^d7@Z|M2i@2qQNL>N!Ymzyz{j%?rlj*giXsjt2oNR5$g0$K02m9n za}RLQD}1l1t&Pk5cs+bw_J6|xe4H7#K7b|(4qUfvc&sJY=3@1`92;9@XYyyuk~-j! zjQ+wG@}~__fnC!S{Q@JWaZP)vi_t&?e!fm zT#L9zAjP#nIVX)9Bd~8VS#Lb>r%qZ zVLjuQi5vw(0|SHCwVpSE$O3Q=E1)5H?}XrZ-LF~!N7&5kbfCoooNWR)$%3wtRfPR) zZlMJrGP;#E22G*3zf8b1ARMN@6`5IVf+Qp+TWgGx?MN)X!Hut70fi7wqqm{hSNzA$h!#xDYd_ zjdPtzcD69ztM?E#ms?&j<}2XnFY2=v5T!zWD>UnfF{@(`K|HH>`nm@9%M)G^KGT8! z0aA{2mu|OUB%>JpeYa<03|jbwllj%-A-P7wsp}3K9ND_^5`ZTSmns~g6;KE^!38Q^ zzwQ8d2;j6*?0RuyTX@Bz;fHfWPX`&{piAP8JP=l4RaR5IXT2;WeLgcgW|<_Bp1iV=QOE^Kfb$pm;wyYap*TgFYd?;Z2{9q^ zdMeybxnp|wOmIbfM#QIc8lZCuRPQkXl09%x?J3F6H&OC)bPydB-|K%eZ{U6YgdxKZD?*|l zkm6WeRS?kZ`vVYU)@JKDtoae8Ur3HL%PN}N3g+_KY$$K+YDrS>F%Uy!hdWmMote9? zRG!UP2-V<29I%rII_bE*^B0Obo9vXvu4gK)#;;NTQPr5P|}scqR6sWlkRAnfq1nM!S%>>eRLTSP?_ zX$(q=YkqsT#90A$t56XQOu@!rtTaZex}Hp+cj@{fN7JL*6ITNrd4z3WaZH9`qA%9) z`l)=41jv|yQ!}j}yIB-fSc*|&=0F!Of>feSQ6dba#lfQ6`Kl-lt_#eweL#VYb_G<0 zqI*d1frpfIRKXl)V2DNy?SMpC+e0mQ`QY+17_n zpqbCphGKZf-W44YPA>4n%$bxnAKd($fDjL>TQ+BDi3@2W`8{M^8QvzZ-s1(Ty%}Pn z%qW4tU$Ic1W)`(fRbFFJQ1m5GOyj(?GD<9C`)0LFLYYtUt?QD@|7H(cs+5F*6y|if z_7LnsTUZu>&Ybg#uGuu1&j?fJ3t6kpJ9Qu2m8F}I1O4FKtjvbBt_#!X>a?}!0WhTN^ z-V8mB*V34@uTb1w124n&=jhx*lBGF>z9CQQ*aADp_5&Ve5b|dsAIZqgd`QEM?mQWN$w|C|@4MVTMn0U@FeE|G z7}+lpqUcaN_him$Dn^Qu8)3NTc2;h!&~e}LDgqOof7(0R7Q2Hp!$MaPyqSoxUzU1D zS;Wazc6A8O1g_KrF%ZfeT}l+0(()VoXMnTk93eL15w_}z#H;h0^wMnIBOIm{V@2tw zg~-Hlx+u$7|{KF(SJ+xXBXzGWjIx znMX3AUKk3Cta|Fjq186XD57-a&ZoS{j6pL$oG4+Y1kxwlLM^2#3Q}dO`4nffgDO`+hYaQSwY?@FHP4e}#9BXo zTAtyH`q1Dx*VPMb07P&iT#^`_c?(ppOf}Z)yOh?(o%p?)#?#b5{~9oJ5AJ75EiwF}1m9 z_<@12%a=~TbCU`|kLri|AFM_yXH`MX-#BFflTk~RGoCAJ{tnMB+2KHarNrL~$Wu?2 zGFCg<%(wSqOxyvuZ-#{NlpHRYJeg4G!Y-piwZeptbRYBE_^Pef;{t zC_|w>o%)rC4nqt5FuROv%TTr#$9#+a11H}YPpnenAq}HSJCImAa2J6DlpkK7KG6(G zpm$<6HjYb+aJ+I_j@U)65_^ZN;5`j)`#J>@Vg;>2y7O+|)8{>i(;UALoO=q@mF!(D zv$>sF^b4U{N>MufRsI?3Vog)KJ+QnLVAwE;J~&=1JN$x6C?K=8qhyuwN0UVn$v|sN zH_=RxYhxpRnvP~g>7!mll|`Q`075)=(C#jr@2Yc!&hPgy=7eil-d_kLF@ph+$34v+eT7tJnHLaDNJn+$p>k z6NP?TwDOqgY(+vlLAmWdBSF5lwb)QI;e%g+lcl$!Tehs4IND2Qk0lrp0lX(vHXGL|jEJ&ov>QX$$~{4$29A(=px4*~P4 zY@ieS3vx}}+DSOPB&Z;EYFh!`-QmSo_CTzWs_2WD6$aw3WZB8{cs#LP553k`mYzQ( zNi+F$_=`<9*8J;{>KamNtg&wQI}c&UMCW@wTRPJpfB3Y46RKr&m1CC&gq}4`MPLbi zx~imHW>pFm=e#J}syxY(Xs16ax%3vPdRw^iqKnVL1k3Bq94B||RC|mFnL2Df&z*@R zx*IXSn3L1LBG+1jj#NPD)#q52leZ$tgf$Wwn#KAaO9bNM#)1!_7u6a|$S)F*8F6O5 zfkGrJo$b8%)~9jtTGc2k9XID^jmrPfnAno_PBjHFP|eC=x&RtX5aUuDb~s~{&!d^Q zIcfanWo7o1Uo-IPjfO0$=+2v39X~;Hw)O+fB&ZQ45?7wO7`HY8i${S(g>$&N>^u;~ z*RiVAi5Fd)0il_t4!vl>dz`$Oun~6E4X$=(qE{q&`rYqY>eDg)+0Mf9cjrnIzpDls z;JdL>R3{K#2gYqbCEh>Ix@@A&SA7p2Iv%SbQ9F%MKj25*0*qm*y{L|C@k>HR%P=!1VM z0|Q6?VqewO7jjd(Ad4vV3p&46Ms>J?x}-h!U!Nbr2|~M5O`?b2{b-mAk&;aScN>XN$jJwWAtiY16Tk ziHY(;dlNFj>Nd1)kyU`}oE`U`<|&CI^TyuDun==8-Bv?;i)i+^SEkpH`tY?lYn7IV zOL+HaE*Vt->$-HNi5OxzXygH=qUU2FRFor6n8ob}>o{%FUxe7HvSh*r4(U7?W9pW^W4LbC*XBXu1j7w;I!9DW(3Te-Mo^yb2i)VZ9;Y3p_L^}mW@r+p2(9*`)Q z+}ynIRMY};z6_<`a^Lea-QTMrQj2A78Ga-t7Q$1ApqiB=sMa|j@i4!S-2_{RHt`MZ zgbB-;Jzwo=FXGCy+ph~u=;3S@5mA%$y2E0J#l%FPa_93;JM;|Q2DeYmI@)QrG|`iy znXZ$3=CFmDNl8{KOP-Ki=_Z>0>XzWr*)V`Q>rZvy@P5p*CuxHiHRQ()r$>L`<=4AA zuVTpm0Hu?vR>5P;p@OJ_IFN6=(xQJVPS{5ig=a~wl(Qa!gt~r>O1$-1^J8%P(tY9bpdwBp%BNy@udd?yGqeh@DLa~6pM#&=I@NNJ!h0U;^l}K&Nw`wl=YL$`n zEXN;VDHps2n{e4mX^z|g%iS)^|MZ)6^WRlGg*unJb$(2ozBn-WI7Qy<@dk1N8|9yz z4tgrqO%glqpR)SpLS5lL<2+E&(3Kuwa08$_Khp&)R=WF#qL@Lx4%swJ&Xacr_xG+q zaA|dwu55e5E1(lvyG3O355FIS+3<4`(p^QtzC6C82qnWD!2$A%1K-OVlqU>4{Y7?J z_smH3>H2Q$#!6m{q|5}3?5_-=UUk<1(H`kaUFu5#2HH3Hf&@xM5km%u*t90r-A<}EUw)KomcYLHjBDi`dI#mub^DXkXu|CAiTlg)n1L? z)Pj!Z*S27_Q3Y?&at=3)eqve8!owDes9r~5FY^$oG{aS5mch;=C#r+~Mto!O+qs=0s;mFiP!Bn$Yz!Mhy^qb4{%>h{HHQ0Q(^SX zD=W}of8ofck~yf7s9PPJOgqOS{hwI-8#*q|GAKTnfgxvmhdnOQPO@doiUYr))hqnq zfL&zp;(`yzfI_XUX~`yWnNW(@igQFd6Dj&OAd2M`iKki@a9EjH$vDNYi+=(->;})y z&N{H`-&5eKF3>V8;Ppkf`8i4t>n&ma7>9_!eIcP!P-48k+!KyMhZNJ5sHq<~)o;6$ zUf0&4uHTjsb<}TeR^w_0NOe|KP>oC&5|rtBjC0z_gunS{FK}fcXTmhacllXX?emIA zB0{4>e;|_wvBJ*kyag#}!_hiEonGkE%QEO7|M-E~g8!suOU4|r&wAuEj@2jk~N zNK#0qOur9A>o!SYq?IjIkZ>-s77Z8g1~W_&nR$H2o3WeSn7DeyK&tlM9h_hF%Urzk zpSqvsJHKa=I()PUQyr7ejLtjR(W*2Tm#@W9sez$*is!-RDVU^bDq78^?Q=H(v|R+- zra!(9n|vEWDGKSx?Vd`AH$rr z>%LOI{Z`;d7yM};vfSCaLaWEr{KnT)O;Z6e8(&nc4m}UHznVdfU8jmz>UODP89|)n z_)Yk7wAc1Bgy*IsinGJGXQ+85vMR5h%L{#`W9&z9d4i*|)f6oVZOt6iajH%Xv*%Si zpP2GXW!Mx`*XPcwX?i&?N#z*mPsyPyXeSJmz8aYC4a0T4apk^&;1Rso{E(J~TncTK^Qcs2**p~P)cg*0`HWELoqV|Z9zROD zJ78+DJ3DK_J0V+aA*wWn zIzs9r-msDwQC})|6LhR~Z@}?g<+1(0}?rE^Me^3Wn9W4XDTWKTO>y48>Iis2*>jMv%teRG{K+|b>6d+ z{}V{&A-oW!Yfh+5wvOr(Vd8(PbRjecW{u`7lj*jKpzBEv?+n+2Kd|H7VM`fWh8+@# zlJNPU{dj9k69utUN_dJTZK{$A2Ij9Mv1T4zOJnTLgmDqhiK}DcMdf7f6$+fObo!u1e!kG{nUM4(;}S$$C88dB_x*c+cVbJjQuxn6 zms2|lwyCMa>q1AjQG2caYV#&b<<^KAgf_d*+k*q!-wM#QN$Uofa11}_xVg2C|0-X@o_i>ik{>-VieY;d-TcE|b`niV zezh&TKXGU5Q4-qt6OIy^18xc}-!)#csG(_3sP^BNF2}Z$l=g?G1GsCLbW@h6VgW|Q8QPwglJSmn8pVaoS@m*yN?#pRm+xPx`nf5R7D zk%%xz6b+*}-G=XzAUFSE7o_AA_q|K$_uL=|^SoN|dl$-*ZKz5Q1YKm(4d5I%wM7iD zXz3bQZJEY+{0w~bk#gRVe!`+WD0fSQ6LDF2x;j#)LRvN5a&1{^nKfvd)Ia(2H0V-z z0F%BipGkyR@E1*%#f;&*Oo}m~^9^@P6k<|&gYkutIk7y|7-cA;p2@b~%(HP{;t>lu z2NH@G7@?kC^B|y;Ce~b|+FMn3)955rqL&b; zh-z0~EK`>9X^!|ux^!rMbIDJOF0r` z1hM$f2U;VWWQI}WO+q$s4rAozS5{ULp*r5Zlzva07{(z35#Qw1!icrP)bHhp2=<}=dU6gb zY=l?Zc>z<0Q+KH@-@m1qdC~$8^GIiB>w1F(BdqfB^6;b=!o5(+0b=;_zNY9BG1{Ka zuYAWW)cscd-$OdH9AmVQH7vE48rtJ6e-w z%tT8Yv_n&8;Z15xWx@h&$BOr53LN8nl8s}iVh{q{;ERPV%{X=#Kt}f0ASJWISgm__scUlZ@aiaWt)CV*fOi z!1AKKz3n`^VAV$7aN$kWadgoagT zQMabwbxqANo}sBzx45x$aM%+u$GTiwn_%%!bHITg^WxGD<*fgyf-{6blP2XbfbJKF z_ii?<)$fiF>EF|6wu+QBAHgAy|2ypSSUd+aRrC&;$6Bg+R=4eBuHc3-(jP00okN%8 zF2SpCGQ1#LojDqLuICKfa*1vDM3b*tI-xdVlrRTB>npaSxBiL8LdtJ>i^Vc7AyOvp z%+BKBH}gZo$)Y-S@))3ewUP8lS6`vRZaW9Vzpb)E)bWKQ z#+{M*e?1XS(p82!R_+cV@5W!%hak^9Df6k4P_$z0WY!O-epyD?{EW6i> zsWB?%$4khDscx9X-|OfHduY{lIE-!PC-~xsxOnb2z;fm^U-N&&xA;_JAE7XuE5%)G zGEw+mW<`;AAqiBcgkZGX6R3^E$CVJ5if`uo$+ZN;uC0Df?C^bvE>XM9(tT;5({BlT@XDaPTzPPVN0LJcSFD)MSuh|m zP{qjgLN0g)(ZXn_U5I@lj3!N-uA8EYN?%*&AVm1}kWlwsrTcM_o3&=g%I`MeQ}3M< zTAAOSt6GR*CeEH`-hyeL5JSQrbP!>}o#VD7zrJ^vSAZTOf} zn>^(h_a7nVI?d*uFJ2izrx4qk>M`iIKT=I>YPfF3eKw10|V2Zed z>Jp8z|M{AsZ{EaikFt)`)pcYT<&f0U`Papilgq{8;gS22YyryKj!+w;(zxKa9WBBl zm;-ATD6=SxX}_LtO`H3U_AZ2B<>j=|tPh8@J3DRh6Anw`(DgdmQ{Ca(8 zcP)GS1G>F!W^GEIN@iysV|sFtVVn|{9GW$#S7CeWj{izZK!K}7@p=FyC7#fTJfmDQ zI2If&=?@HNFTBNLXB?D)Mli#nnMa5cOWrxl^UwVYPQLF)@h3lsHU*{qmtT1cM@D?+ z6Hhzvm{9l~wRNz`vNR%1Mrdmgo{JT3akEtx*LBIVge=qezK;+&d7d#EjR-3SDaAdMuwJjf zYZ=9T0a)|R8q*WUnOk@YWC`pZj_1*sd=FMQn9Slx&Hl!>xq0nXVgu5Z+)*U;{b*lVwo#RHV5Kuz$-k9?5xXMcxg)u&PtG-{So2=Sm; zMba8nE*NH(!O+qh7&`r&tq>|6Oiw9lRe>uko{~fcva@gT#KRt*Tc+&Rc=ECLp_Jv) z#n*Z5xqrd?KKdxatK-RWth8|X(wD!+XFmPW2cY#A09OCu&*bRLlIxT#ODF{)O1dP; zXe@3Tq-P3FU?lk{CmD^!gD=5?470W0{;d0*#E}-aa=kzryy)w+P)W+>K zYJBODWfm#!WWS|pN|webbqBE0G-Y*l^}aNX0ys0RgB(5jA!d#}JszbLmFf%x6|6D1 z3W&E^x%LuSK1An|C{M`pVn1pyR0wIle*x>ydWhoW?_k4avRNj}GH^Ux-=*6fqLe}y zL7HTk6gmULk;5TNqnt}uGqMa!CdaVz-QaZVu43@Vh~y3C(E?OW}vko9SP#0Vb3k5IM3JA>dtLh{xZqCk|NQU& z3+G<{ZGP>4{Kf;|`XPYoAN;&QX9j^o6!q|RKs1Udmuh&fN1CK4N0R3;Hj4<#kdGiU zhThQPs0vH-Cz+aCVs_~me!0nBXT-&~Z!&*yo>PxJg%{LNkp{a)x4%!lehi^((PN<~jtWUWy!|{io;>glL_IJL?&6UeE7iVas8+1EsM1wZM$&n%>HyUdsNt$7$i(4w8 zGmX$1osEsBCPxZ`=id9-2!i0g{daSgj(mU<@BMesUL7SZ$si`IEMQgP%_2?MzV=O` zy=&B`n{3?NV%RsN8lnX9#9+857w?CshGSq^m~PN0yR2`u@hfFi;1Q)Mj^`l}#lo|N z-Q9$ARAs8+F+Y=$rZDUqvQ!jzvUfWK8S}$ig%@|Od@n^D^kB1R+1T4-&|Rm#kb+;O z*?f$gkSx`>zDp%Egkef&cWi()7FPg1=&1NOW|<((EjW^70HfH@-UY|8I1V%?Ec1O> zZNJ8kJ)wE_iHDJ%JUUspoNu|_WF6+D=*XEyFw7QNDizsF?R~L)I>-R z9A~WN+G3gus;JUQTGL0ESXyQM;w!}6Z;_5NT;bF0ZDXxVk`B>EV@-~=2Av7OML6IH zg&IdJCrM1;tGhn_f;`XfU%)zi>NA-7A*=vv1*!I_)F!}=yJn+3HsAhJMBc-z)XDQT zvK)qqA=8kI3K3hXyQY=zd!TwpEQ|oxfu*Gx!m`WO)+UvD4duBEMiH%vO7S=H96x~d zZP;3kICj`$=|Gj8P7&&tWn;9uy`cDx=k+~AEm7bA(iZ-*-U!zAw&?7yv!I6{t28H@ z915rC$Lsih3E#^o`)Oeq)e`9#e7^uJD--Ye~d_QM% z_f>SX&&NLaEP)en>hL3c>*W{OSp5b|Q=cQ(8J_e>6M+-VvUL1Ovi^BQvd*VJaD(d` zZO&dj`2e`S2Uz_Vf7>TZEpZ;ULRyBM0ZC?9 ze&|Pd=7S$b`Aa~bx39cPn!$;Oo<#-=<0I#cxO1Ktzxf3emP3aYnLG0sl}ZE9tX}#e z*VcD<|A&7G*KZ*FfH(oa>{3L21J=Q#M&(wd!H>eF9I>9S%vg zVmQi4G}I~rp$tkwmT9bp(P%_DaPCrJEc^TW_pj(4wjM=~#}R8RUTv}v2@NQn5p~~W zYx@G88j&ZOcHa^k7z_ka&!TN%jQpWqy0AER=}Vr1i84&p8ff9Ow%2BIrViGUWeN3( zazQ_>#HA3tg^j4xLzWi=n{C0xp2gb21taC1H5|uboW*64cSXA2j%OYR1~w)NFzfeW z(1+EX5#9bx@Vbz-P@>Lz-uq!*c>Oo1mnF5pFwuaZ41?5Q^5Xrdc!G(lrK881g17}- z7A13h2mBJ0%Eh8|;6f#UatXe3^*XMT^3405WoD|yM?dxqE7zW9>G)6J`z@@sq`AO4 z;QJ5Jm^ekhy+*4wqL<`+u)YSbE<6COyMXE+{=z)_8&`?@1}AW_NMul=x4(nuc_`OM z2MMDj!VMKh=2+#>844y_hk4}mBebR;LzHIdrUSOuRtUT*i$^|&?>EP}-wFM_6}E1^ zLfYTv)ZtkwVHxEp(tNA>`%Jc4Of>d^ z?c481mSuFiT^fzXedon;j9UUU$~YJcD)6yZ;7DM&%g*WxbbD)5s~&llGD^UBlF`7> z>yP_Vtt={vet^jeKzX+4FB~T?NDHlLk7lz*qFpv)SQG-tu+|U+C3Iet4mt`ZLU2RC z6)aA|p#_gCmy+8w&-Eb5ZW*)mUA%Kl{p>9&TTENZfvL&DbsvoiDmNTh_Bw0yIyb4+ z4}o-f^vNIP`R9L~U_wz1EX^vELl|@lg+I-JOjDnNUJr6B@I1?86Ut>pIe4t&1;1+)^XnV`1@&2obxdw_#yeu0B0e~j0j|3A5O?yJ;lKAvbZRF+;m!u14>a0$u{mJTd4 z-I}N5y@cb4+eYa)j_Gtd)a&*853saJaVTNN)Jzq{U0`y0`&YPm^BleIF0NMxYj9i% zS|WtS*gGpOcMI8nzE)LCHQKzx)*xZ35l}BXWSM5Y4--`voej~Mz?BvH!#x~NQm%r^ zB~fHpyD{XIO~yV&Awmgu?Q`4VYOk>+45zAL%8 zv&CR%i&`}Xuf*XaAEecq#d8h5?@%slTsP+~F9kvtOW;x!lVr(<>z8uf4$Z!utr0 z9H4dRB$rL~cYB?!wGmpUXq%AdF^=!ys1mNzD)zvXgA5#$ z&`7Jfaq){>zxo0vp8O2W*(Y%vfiMzZ>EcdqB}f;P59$DqJ@cP&^!R7Eap^a?dj1co z);yXr0}N%q&iu?_(nPYm-o+OQwNTOS7N5~5inx6F@_m`u;1nTa7O5oGh%sdm5T~@a z&T`}WS+q$QjfQ9hjwcxG=C>8?yZu-82g=d2g;u2RGIR4}2F~AIfDYOPHI6TveD_+~GiLf)f+7Y_7h@p;8^kv_Mpe zg&+v)Odk9gn;Vztbl+fS`x8#$GTgt)(y70NDm}@`_aC4+f1Ed8_yU`&=Lkv`uM{#{JHgEK2@V{260dd;QJKZK z4ZN^{LqO=b*fAB*Ss$JDzz)fhHc@*Wk@e{8b;z;^sRC5BLO#-XehFWem~yK)u8$NF z$MMHyEtXQK(QzLW@6+Ae=K6EL&Q|SDIe6yNlqQ$4o{tu$7!m--f>jb!h06RXPB;G% z2Ty*Cm%sI!B-^i0Z-z9d<{6DLdfhFy*Vgb=m&v+&8?cfj;e{7o;Mr%N9hbP?M}SrA zs7NfJ^TKIP97A@My{${Y0Oi7P6q6c(>j-u_<5^7P-)kN42SBcI0+z6NKAbu+PqpN- zz1=3T;7G-A*r8kw@x2fs1divT0;sx*QP;9NfX(fM*0j&zdCi+Qa<<~J)j)8Y4!)aP z>{b)B<3c%rdR0O$sDzd{g=i$%??qgG^JNY`{7JN&K?28)J;lX0|CouH37Qj{MwlRk zMU0*Hxdy2uu4|Ffj`tWHbY{ttJEP^@2M>;fuwH%ZoK;n-c{73|4gM zw$J0bIpqllui}#li&Lp{=;#MoySPbv=Nj$qE^b&yIWBgX;#h&>NdA-0`utD7o&2=} zt>r1rFaESaDwmC|6^w?3)=?%(6|P?XI_>r)9{=Ef3c&)?hkus$*G}@rOTUfHFLC6^ z5tN$7^$ro|lLVzBIKdRcuYjY_6nWfP9-#+4N>U?6UADHbkPi2X2=6eUQmZl?x@gCz zT5C`Zn+O?#3PCu$*#yF%v@Z7o6tsL-WS{t(ap)D!Hle3R$C{(rN*{x;=u#P;46VHk4YK#5xAPMk>; zMST71U+43m|NQ+Yx_e%LwFYAp#)8lpN?2N& zW^pd%#Bveqf-b~#q4V4Mrtj3z7+W$Nr=Wy^XYfjbFtkK5^i!A>aN+z5d_)Y2!v!Iz zPdtIK9)T|@dzM;Q2=7T!OmN0PrUij7#y&M}FE>hQZ_{TX3TuPoffqodE}3f?Dkbm? zq>1H)7vG>!uJQO|vjjoFaI}jb&Jf321mS`4uK9yRT-};KW?}2N1O7ma;;w0CuUE{`$J*w3zjYfl&o0oCjkcGJ;JaYOJ zZ(V$oKl~9Cq6jC%7u{d$us}}AOJ~3K~%5Mk1SL3CkblH)ch7m zAEYW`j1rA@UEFj?kf#`ibT+Rt*k7emQq=1LVHIi8CP_v}1fHrwmNMw=V5LCoj3^z^ z>9*Nz?~tZ3)gYi5R;kt|CLsQWq1%AGH2p69&r#vAl{JxZn0eKuiP zr`TJvwrHR+2I4(NoejGC>u4<9VMb;w!Y}fvqalb?BQ-y~UsOtrHn;udo(FR+pP6P8 zDLl5@Jt~zdSu9B70n3Y1sKCW@iqW{{fU69Znu8xmu5TnDe5RTnM-P^G<&6-Cn>Rmr_7ssqj50If8l!d;8EETBHzcv{xARwy9MM0lztSl&~@jdO%6R zWL*>n(s34;(J+cF$`OUrew_VvYe8G7;!oErfUa7T_#xCn7uUB~$01Gbr!1eDw& zzURp^KA)bf@#R0BxbJ{#c}ny7&oyv_VAzXz=;SFzNlcn$V_`YxwYOfuH~~iwo#ybN zQ=GqimRG;^&zU`Rg)>k8JWk^XhadfWm@GjCA=Y}}fE608yCg|WSe`5f^ida+-e7a( zJhd>RRgc)&UT1H2n^D}S6iSp#$a6uO zX->_uxO|$WqfbzqJ&i9X32IfEQ;IxK=5p8qe=))+_6tq(5@h+IcO3+v`<030d zoO$bk1Qq| z?XtCcnSOr{EnK$tN4O;qS80Z^C5{T8lDys4`~wEd2m!|4UU&w9<66#~nxX8M808M@ zTWuQk23eNT>&Mh;EwoiQp2TWFSxB->qh!kDT#KEqVWT}@d8x)?OVgT)*>8{es`(x! zQtr~p#~JOu3%;_{%TV&6-O(t|V?@I0jW>9x^z}vtzOt6 z@~rrsQQuN66{nSHa?2YAHn(JBtA(pT8c@a{bBOv0?OlPkDS?X^uxGUhV*rh#ZJV^P8($%WNt~*oc$PfN1DKi zxV9T{^6(CD{JsILqy6VmHcY4~Hx+&VV!|si9JxAxlNkL1-l< z&nM|+Aixm`M-EnbYh{DuhaY095p#I1$J&}@I4Gdh=HE?UtpIBTQrwlcFt&75!a`Hp z?`gCw;gN9p{I_}N%)gJRw2(sb8|y_7pw11$fuRT+1_M!CcNl9XW-f5*Ou+d!5B-$| zuH`As$KQLSh$Yq@##lV5$gN?NXl|};aQN_HqCt<05!Lb>LNqa+Pv6uz_V`B-Y8qiB zl!78L$)tEvf)z+y>eVVrDbi?%ZvS=Odgb@ox%oO1^`b;q8coTQlzf91NR))#c7!$o zJ^^{2P%edpt|lII7)2RrYKv=<tVG9V z+*lKFc%emm54JW3G^!rUO}ID>YdNIZoxP!VTOqpl)KKEPma=DXRFT4vIf|-qxc2rd z==>7VXo{*QsaD@hy*k67Gos`P>U9UmZ=XaaF-2Cre8+W^0%H)$;`stUu#`eUr3$IG zY;QxJN)nS(DHmqaLF_P9QJg>b5|fQ-KJ?+A2jieI^gFwRMls4Qa>7HEnmGC~W}2Hs zyE`n+?i1ZuCo=|RBqlZ3yf~eA5m;A|=7u+}j0o%Jd3H%~bLFp&TYh;;^QmVyF-9Y- zVwC1&iDqJ=$$Lr+tmJqg|v2nTBoX$npXY1(J6 zy+*ZKrBx=5%jRVZOX!srxDdkNFHSjJ1N?@5D1(=;g<#RaDZQ( zLKz1=%qY7)d8Ldt9bC^P)ft&p7*j;NxSmH?4JrE`aWo`N(xQ9?k2Fo#=w2a@`s}T* zvfukd=4KDGeB?dUTZi#0$525PqXIM*=?IV(bxSHmAcQQeJh?!T@%ZDP zK7l0!B=cKL%^qXaU!@!dG-`%&DJLBjWfWOn)Yx+?F~Zyd07n&KyHXY} zC}OI;z>q|Rmble6=rOo-x`M$lBd#mLn$I`C{rk+$E^*?-CmCu%hNQc{M^FlhdpndX z%iv72aP&vn@2s#G^;qBP(j5-*J%KlZn8LQzJbCDAZkK&e3 zfL|j{9rC1&@)V9&!SzF;ewSph&rG$Bs}%A61^jXoL4#K7BxPV{?G=unev0Pcz;5z|fDJ053 zvBn~eLMcg}fz=+zmQOG{zl6o(_=!1Yrzcst@-i=d?f+uo&?y#=yodVCqqy~1&^2%s zLOElPe9;0WZ=0iCT66zjb#MA)*?HgheV*qz>)mhPzP+!rVpd=P5&$U@5=AK#L`D)R zRcI#_T6QUPqP$4?MG|W%2Ch^pm4Co-QhpJaB8TOaY*~v%%dx~oBuD}vK`evWr@N=S zZ+G8)JLjI|IZs}ko`J$F*5V}4tLf^hshT<6=X-y@-*;Q#!lmnf>J>D!S}k^Wce!}+ z;$NW&i_A`H@3L9Z6$xm2>Bx;=;M>Sd{2?It&L#bX&JTlduYU{Slz8DIzYP8w#pY%F$_A6^ zJCxmdywW0_!`lqnJ2dJxUa87xni7SEC=x_T#$-06FxNn0lZ6_QX)NJl$rw$H>qrC& z%Vd;Yi-M&H;{;_XQX`lKnzfZJZru0?N#fuY>MSg7angCjtFL{VAH4oG`hx?yqt|Ko z{sgbEM!EVF^UK#*+kO^G>j=vMlc7w`9;QYRYmmxfb8DM=tww(^c=DWo`?r6a%a<>+ zwzl?HWWpjtDarBPJ^W&oV0fRCNB2n6lt)Jat&`lcGITYQz%ZR=|3~fBUtkY>Uk@cf z30&WBe#yu8eUdcc{%#kYg5%rtdLi}Ic@QOpQeY%mcIpvK1=9#BvBFUr+sdd{8r*sJ z9_yQP9L+-J?vLpA^PT0dj#2~Xg1u!!X%|^_A zm|-%Q%peRh!Z@aAoKtpF^V|RQf8+~)V~J|>3dWgZ=6Q_9eHz{jla3IgM!9~Cb1!_3 zAPJcCJKUOfDU=`_7(7=HriLgs)JuYen#IXD&2MWniwCWQ#nK7C^b1XPAMNq4zO(%Q zI&f{zYrgPP0j}dxt6pYlb)C7nd4zH~YVFbO4$;Y&qGzz(45WkaEa7yRdjNZFjUZZjRWh@%m`?(6gq?(+1w~zAe)gSEt-p0x&7KdB@KG?dVL;sGsdHQo$*c&?$hv8za}|V#{b2( zLaFlBWR!#F$2|SiDnck`vk|Rcj8_1+Cn*tgJEV`*>-C?MRHs?_riD@e3A#PLV3#c}F7+ zNxr(Bv>y?Ue}L_;V1$KV+Gcs}5_<=);@cU`8az5U)vD$W4$|y28(icE{`VaP;ClJ= z6^6NRRvSSW7}lDK(L^&G<$3v|K%$jG#|buhQ|)we#Bcti|CV3;;wxmzP+hu)Hi}S> za77VJh>;~0&ipL(x4*|~ZJ%Kv}^P10pa*ULcQl(C%T%}SdqobJp-ADBLeGDm;s!yrz zF&GSqqLfBu8KqK8GNKcN1X-D9pZ^TS`qkWRZrPYjBeFJ!yWb}4?9ypHWHcP|k&k|k zr!L)KJgSjupW{PK|D?xT-}w8)!48{Oei7j~__~R|I7h8{mcYEqYGIBay!sUuYaUgv zMCuJ`GzzqP6NcjezgWPri@7c@bxA{w$P_xxa6EEDw6ZyDMU<CT)advGL%O3IY%`V-8TU>qN zbIhVKcA<%KO9*Tbf{o1$KKHp_;LBhBGTCXp)4{<3H*enL^5x4oj`M*BEcN$ZdF7Qf z9^;A(M8x;M^*%!HGHjR=^WEA)JXS6#xlXhv{ zMT!J1QdU=1SzP@%#&QtCMx=*4dhlIlaZE21JZfp;+52FgJ!$R{PgZ9o!7V_ktblxK zwUi(XVKC5aE=r6vjHmgtuGb73s}3qlu$4uerYO%N2?q?jM{I3wqBDz1W1W-?V;L;r zl4?+{$9!drgPpf2m8SHE1GJKlKXph9lsrkjY++gXL^&O2%mP8I4QUqg?Bz2^t=T#5 zF~25{)#{7JRerF$%rC3rj z31gf>ktj+CCjlk_+qTHEj3|x}GEbz7MN1C`Gx{0GYGX zT7wXhX)xjUfA9AgkH=4*e-uUBxN(Dpg@q43V7>C|zxK+ww~u2th{7Lm>-)b)5cIio zIOEoyp?exVoTl&Vi~iDf93k>cR%SpbwwE&g)@MJ0R1WXly~`hdt3|ykdFlBE2m3uf z`icL5T78RP{D>qt;PChX!!V>jj5!%-PKGd7R){oadA`oMvl~3Pzt2K#p3I3j?uYE| zoGxRhX$?}I0+xcgnj(xcgoJD7ZRQFNkr3>)LXJ-I1LpO!9=4kyMT)WnSFU^t;gmrr zY^L15`Bma{LO;?R9BIa*_jBcq5t!54l{igR^}PIcmv<}X{z9DzCR0NYz*56dt0}r; zm`tHo6)ZOmo+Gg=n>0;`G?Ys&(@~3fGNMwf;`&wm>Ly91nayGxsSrY9`Bj?DMIPRM z6=fxKf(a(e&FirS+cMP4HjZx-#~IU+W;`}zQZPv(mg_!Cb8`qIXm$FGqlA@42OTy3 z!l1Q1uld4{xA@RiL36G~y;dPjQ`+qlTCEnAW3$kl$Msxx9z3Mo?og|)u)KJlN@bnQ z)KR5P&RqQz&CO5Y6qZ4{n0P`wx=-ugAJe}7baV^s>>N?8)j4?Z&*`1K!_I!2 zdk30_hcFKEPld-fn8%IH{AJX!r`69&ApSnR1rhMbAo4oqwfR#myk3CoA z(N3S2f9^j+$RbH_Of=bL|L_6RIHEs}>GU!VI^a5n<(fmm6P!PHjzGXvN5yyk2F2|`xZ zHaU0pDxSTHu&b07&vNGJPqBRF6WFCQfFOyE3Ho<9diW}X{ntsSJA~6irqg4hsE3Ki zoE+_P@BUqumeyHXeU8P2GVi_n18UVZDwS1?Q=nFFU`b6Jbg=A{(dY;zY)bwd!nQF= zAgp<;(kAPh7dbg;F`bRcl9VJ!@N9=L7-Ojn$9G7Lq2G@IwbC^BcVM%qE?|nBV{A zJKWu!v9WCN%sG!vH{z2o{|c#rWZa^EaEs&aF4H(-6h?H08T~#OX;^GXd{?o&utd?V zu)nuYwO(YF#yo7#7<5nnFPyS-e*QA9E?G!)9%Bb!QVK#-erHs{; zGFcojiXygFuCloC0!CR#shAG$vGd^jXkj?%B^-A%vLC7wQ&xWKbKKmDV>$23vXmu= zqnuSt)BNvUI`1P$>GX3zsh174s)cO{eAh;28DSJrC|7VS$;qP!RLdSo6jQA)qwG19 zV>1g9q?I8ZMRWc-!|pvq)~4I(6D9e|J4?Y;8NO>%v@Ir4M4G`g1%t}T2_16n;u*Bg z==BGrTF@P)?CrhDul^Tb;!9up`+Vh}{e%Bo;M$(oeDz;^g;n>M;pC8OFTOy*vFIM{ z(;o~e)oN5q6-L7`$HynwUV)8`bDTYYjaqdD<<4Ojmsvgc63bgJVHMWV0^-RI?St65Sg?Y437z;DVDF8r6F-L!LtPDm`C^TP;y-6mp)FVQsU0dH}T6WRGM2z z%c9w=lBN^VXw0OuLp*NbS{a@@4^D+xW}tkev&8!PRaBNR>>OfQDPB3l@hm3Oh*=;| zvc@w{zr>ZxAE8=p((iXUZa<_yxW$`qf0J9c-y)7C#IqSnDs*N@bVihDj4_nU3fBVL z%56Q;QsmsOAw!+&{t}FiNR43{&Ip1DIu1ytU6N@BWs*ET*>bRzi0lb(aU zy*)NIHhAv2=RVkg_3OX(cVBVrB9HF;3AbDXT-w;2FJH)4|W-a zA+sc*KQZjJpjH9f*HnB-wcv67`~^Dg4z6R9>WEe;@(Bd42gPy@Tx-jUX{d=4 z*xGd1S}HId&lpT&4!bZKLUT#*)OLe7oRB33-}Sik%+HhA4l)xE4cWQ>O~UDr;Y8Ew z=Y)XxQ@LA@J%puVJ~2rvH*zZ_(ONJIvpgsx&OvK)!)2jv^QavWOrczc`HIA~Qe59f zNti_mCX*D4K9Y!&<2_1+0`v0=D65Hdi#U#l(V8flk*SQ;=2_l+{ST1FFb=19ULHl` z2!kUH1=lA{X9z3T1jmV?;Cb|>6E+sgEX|imlbB9_iZ*#v&fQzz=954E%xn?ck}n@wC-~0;$>>JB@!KRcyK}xM3hTap1N?I=brs2 zmNUox(FC`!z}d?`!s6K<#q%~G8xoE0GdO;iN&gN}xXWy^iz~-uvo67SAJ-0vqY-<1 zdq^C-!W;|Bo2+eYbLQL{LQXmC?6bV`V>A|;Jlx$uxgO=l1uW0QHXg&HhuppOI<`m| zbz78c2G4DxRE0E^7zENPFjv38`o;=7`?s*2j40M5v0`K6Dlb0&6Ra$5F&>ZE-MvY> z^MLygUuXaDHj~K&q(u}a%)%Ld!NT$sT0)d07$LER!IBnPD#?r_O9g2rNF#&J3_8uo zbgrdzd>7C2Fvbv0dnDnA>A1~wI-pW^5NHa;3THPq_>F(^yH9>Tv)PR0OA}6-zH9Hq~m@12k&yy-y_Om!ZfBkfrFM|VP4`p z5=SHy9mB@zCiS^FIwu|6f@Ct8aOWUnI?d_9av7S<{64j^ED1xyB+RF+v#TD{QOG#R z=!J$}7b^3DE87+F##WfdnvZ_+Kf*{CA)x4Jjt^d=cf89a5gd&&hQnM}^?1s%ocwO( zdjg?yfoQP+8IpKrh@+g~NE1PtLa7#Ual67S4A?sWuOwKmL&4G5o{N+cp$)-!N~2c6 zas?Vqw?Dv=1r`^!Fwz6ZM=BfJl87wDwtTjh&-38HxAEPOei)Hy3#BqVCGdO?r{ogF zGjy7_V$Y(Ka>=IEIpWIdB94?yqZz445CU`@^7^Y^=h+)C^NauS-{qJ8_80leZ~X)6 z1;fAmjsJwFwrzUd9*Z$=e6s)m712pVK~(EE5Pp&Q<~HB_qc1b+9I(8wz}(z2w(YU8 zw#nA!IV|b2zuzM>CC**=5Sv@iVmb3?G3-2K*nU6~wn?Wg^sGn0&6tk5blL|@ zXH$Cp0a|MswK}Cz3CDHOWK6>;$0tX0IxY5h-y?~~EU!IJb9tS~Yy`r^vFC8CGNp0_ z<-yV6F4eNb;lVuy?Hwvk8Q-g*EE|o5bUZ9?gO%lT96Y*@Fg`E7@Nq6&xIi!)v9ouZ zot<~-bRKYYa2u@yj1eShhBgUWCrBwVQlYgZ${@-NNI{kwK%%5VNr@6*DTx%hH&N>h zfkbPGI!)vCY=P@2P=;_8GY&?aw00?ZnskTkMBm0zwi2R z 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 T4$&`;00000NkvXXu0mjf`VGL| literal 0 HcmV?d00001 From 135a212fe853e2f75242e3e237926b4632780c58 Mon Sep 17 00:00:00 2001 From: Charalampos Fanoulis <31324630+babdab9@users.noreply.github.com> Date: Wed, 6 Dec 2017 18:11:59 +0200 Subject: [PATCH 23/62] Ehem. Removed the old bot mentions in helpDM (#413) --- FredBoat/src/main/resources/lang/en_US.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/src/main/resources/lang/en_US.properties b/FredBoat/src/main/resources/lang/en_US.properties index 79b315c68..5ab83fd7b 100644 --- a/FredBoat/src/main/resources/lang/en_US.properties +++ b/FredBoat/src/main/resources/lang/en_US.properties @@ -215,7 +215,7 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite the bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d helpSent=Documentation has been sent to your DMs! helpProperUsage=Proper usage: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. From d162194d60ffa895023a07c89f6bed0f7151e4ee Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 7 Dec 2017 10:19:20 +0100 Subject: [PATCH 24/62] Fix NPE on private message --- FredBoat/src/main/java/fredboat/event/EventListenerBoat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java index 15dd58575..797f27256 100644 --- a/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java +++ b/FredBoat/src/main/java/fredboat/event/EventListenerBoat.java @@ -83,7 +83,7 @@ public EventListenerBoat() { @Override public void onMessageReceived(MessageReceivedEvent event) { try (// before execution set some variables that can help with finding traces that belong to each other - MDC.MDCCloseable _guild = MDC.putCloseable("guild", event.getGuild().getId()); + MDC.MDCCloseable _guild = MDC.putCloseable("guild", event.getGuild() != null ? event.getGuild().getId() : "PRIVATE"); MDC.MDCCloseable _channel = MDC.putCloseable("channel", event.getChannel().getId()); MDC.MDCCloseable _invoker = MDC.putCloseable("invoker", event.getAuthor().getId()); ) { From caa5d233c8ceb184fe4c98c2da3b4cc05514ac15 Mon Sep 17 00:00:00 2001 From: "Frederik Ar. Mikkelsen" Date: Sat, 9 Dec 2017 15:09:15 +0100 Subject: [PATCH 25/62] Update CONTRIBUTING.md --- CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 20c9a6d77..31a8c10a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,8 @@ +# Submitting issues +When submitting issues please state if you are using the publicly hosted FredBoat or if you are selfhosting. If you are selfhosting please state which version you are using. You can find the version by running the `;;mstats` command. + +**If your issue is about an exploit please email `frogkr@gmail.com` about it. Do not publicly disclose exploits.** + # Contributing FredBoat is built using Gradle, so you should just be able to import the project in your favorite IDE and download all dependencies while building. Check out the [issues](https://github.com/Frederikam/FredBoat/issues) to find out what needs to be done. From 0be57296446087893757d7e0d5f17256ff823770 Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 10 Dec 2017 15:19:41 +0100 Subject: [PATCH 26/62] Chose better base image for docker The jre is missing debugging tools like jstack or jmap The alpine base does not play nice with some lavaplayer features --- FredBoat/Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/FredBoat/Dockerfile b/FredBoat/Dockerfile index 998a465e5..0f4cca099 100644 --- a/FredBoat/Dockerfile +++ b/FredBoat/Dockerfile @@ -1,9 +1,8 @@ -FROM openjdk:8-jre-alpine +FROM openjdk:8-jdk-slim ENV ENV docker -RUN mkdir /opt -RUN mkdir /opt/FredBoat +RUN mkdir -p /opt/FredBoat COPY config.yaml /opt/FredBoat/config.yaml COPY credentials.yaml.example /opt/FredBoat/credentials.yaml From 5ad965c7b49ccb4b568ebb0ebfac40a3c287c3a1 Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Tue, 12 Dec 2017 12:52:29 +0100 Subject: [PATCH 27/62] Fix for being stuck in catastrophic backtracking Resolves #399 (#410) * Change splitSelect regex to a splitter based approach * Change to a duplicate removing collection * Touch up Javadoc, since the input is never empty When the string does happen to be empty, an empty collection is returned * Fix blanks needing to be allowed as well * Allow a limited distance on split select strings to be fixed up Tested empty, long strings(see test class), short strings(play q) --- .../command/music/control/SelectCommand.java | 23 +------ .../main/java/fredboat/util/TextUtils.java | 65 ++++++++++++++++-- .../java/fredboat/util/TextUtilsTest.java | 68 +++++++++++++++++++ 3 files changed, 129 insertions(+), 27 deletions(-) create mode 100644 FredBoat/src/test/java/fredboat/util/TextUtilsTest.java diff --git a/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java b/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java index 16d0ee0bb..d696da9b5 100644 --- a/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java +++ b/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java @@ -75,19 +75,11 @@ static void select(CommandContext context) { // Combine all args and the command trigger. if the trigger is not a number it will be sanitized away String commandOptions = (context.trigger + " " + context.rawArgs).trim(); - String sanitizedQuery = sanitizeQueryForMultiSelect(commandOptions).trim(); if (StringUtils.isNumeric(commandOptions)) { requestChoices.add(Integer.valueOf(commandOptions)); - } else if (TextUtils.isSplitSelect(sanitizedQuery)) { - // Remove all non comma or number characters - String[] querySplit = sanitizedQuery.split(",|\\s"); - - for (String value : querySplit) { - if (StringUtils.isNumeric(value)) { - requestChoices.add(Integer.valueOf(value)); - } - } + } else if (TextUtils.isSplitSelect(commandOptions)) { + requestChoices.addAll(TextUtils.getSplitSelect(commandOptions)); } //Step 2: Use only valid numbers (usually 1-5) @@ -147,15 +139,4 @@ public String help(@Nonnull Context context) { public PermissionLevel getMinimumPerms() { return PermissionLevel.USER; } - - /** - * Helper method to remove all characters from arg that is not numerical or comma. - * - * @param arg String to be sanitized. - * @return Sanitized string. - */ - private static String sanitizeQueryForMultiSelect(@Nonnull String arg) { - return arg.replaceAll("[^0-9$., ]", ""); - } - } diff --git a/FredBoat/src/main/java/fredboat/util/TextUtils.java b/FredBoat/src/main/java/fredboat/util/TextUtils.java index bb897b352..b2a8d8fb8 100644 --- a/FredBoat/src/main/java/fredboat/util/TextUtils.java +++ b/FredBoat/src/main/java/fredboat/util/TextUtils.java @@ -25,6 +25,9 @@ package fredboat.util; +import com.google.common.base.CharMatcher; +import com.google.common.base.Splitter; +import com.google.common.collect.Streams; import fredboat.Config; import fredboat.commandmeta.MessagingException; import fredboat.messaging.CentralMessaging; @@ -33,6 +36,8 @@ import net.dv8tion.jda.core.MessageBuilder; import net.dv8tion.jda.core.entities.Member; import net.dv8tion.jda.core.entities.Message; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; import org.json.JSONException; import org.slf4j.LoggerFactory; @@ -44,9 +49,14 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class TextUtils { @@ -54,6 +64,18 @@ public class TextUtils { private static final List markdownChars = Arrays.asList('*', '`', '~', '_'); + public static final CharMatcher SPLIT_SELECT_SEPARATOR = + CharMatcher.whitespace().or(CharMatcher.is(',')) + .precomputed(); + + public static final CharMatcher SPLIT_SELECT_ALLOWED = + SPLIT_SELECT_SEPARATOR.or(CharMatcher.inRange('0', '9')) + .precomputed(); + + public static final Splitter COMMA_OR_WHITESPACE = Splitter.on(SPLIT_SELECT_SEPARATOR) + .omitEmptyStrings() // 1,,2 doesn't sound right + .trimResults();// have it nice and trim + public static final DateTimeFormatter TIME_IN_CENTRAL_EUROPE = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss z") .withZone(ZoneId.of("Europe/Copenhagen")); @@ -283,17 +305,48 @@ public static String padWithSpaces(@Nullable String str, int totalLength, boolea } /** - * Helper method to check for string that matches ONLY contain digit(s), comma(s) or space(s). + * Helper method to check for string that matches ONLY a comma-separated string of numeric values. * - * @param arg String of the argument. - * @return True if it matches, false if empty string or not match. + * @param arg the string to test. + * @return whether the string matches */ public static boolean isSplitSelect(@Nonnull String arg) { - String temp = arg.replaceAll(" +", " "); + String cleaned = SPLIT_SELECT_ALLOWED.negate().collapseFrom(arg, ' '); + int numberOfCollapsed = arg.length() - cleaned.length(); + if (numberOfCollapsed >= 5) { + // rationale: prefix will be collapsed to 1 char, won't matter that much + // small typos (1q 2 3 4) will be collapsed in place, won't matter that much + // longer strings will be collapsed, words reduced to 1 char + // when enough changes happen, it's not a split select + return false; + } + AtomicBoolean empty = new AtomicBoolean(true); + boolean allDigits = splitSelectStream(arg) + .peek(__ -> empty.set(false)) + .allMatch(NumberUtils::isDigits); + return !empty.get() && allDigits; + } - return arg.length() > 0 && temp.matches("(\\d*,*\\s*)*"); + /** + * Helper method that decodes a split select string, as identified by {@link #isSplitSelect(String)}. + *

+ * NOTE: an empty string produces an empty Collection. + * + * @param arg the string to decode + * @return the split select + */ + public static Collection getSplitSelect(@Nonnull String arg) { + return splitSelectStream(arg) + .map(Integer::valueOf) + .collect(Collectors.toCollection(LinkedHashSet::new)); } - + + private static Stream splitSelectStream(@Nonnull String arg) { + return Streams.stream(COMMA_OR_WHITESPACE.split(arg)) + .map(SPLIT_SELECT_ALLOWED::retainFrom) + .filter(StringUtils::isNotEmpty); + } + public static String getTimeInCentralEurope() { return asTimeInCentralEurope(System.currentTimeMillis()); } diff --git a/FredBoat/src/test/java/fredboat/util/TextUtilsTest.java b/FredBoat/src/test/java/fredboat/util/TextUtilsTest.java new file mode 100644 index 000000000..d4569c9d3 --- /dev/null +++ b/FredBoat/src/test/java/fredboat/util/TextUtilsTest.java @@ -0,0 +1,68 @@ +package fredboat.util; + +import org.junit.jupiter.api.*; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Stream; + +class TextUtilsTest { + + private final List one_two_three = Arrays.asList(1, 2, 3); + + @TestFactory + Stream simpleSplitSelect() { + String[] testCases = { + "1,2,3", + "1 2 3", + "1, 2, 3", + }; + + return DynamicTest.stream(Arrays.asList(testCases).iterator(), + testCase -> String.format("split select of `%s`", testCase), + testCase -> assertSplitSelect(one_two_three, testCase) + ); + } + + @Test + void blanksInSplitSelect() { + assertSplitSelect( + Arrays.asList(1, 2, 3, 4), + "1, ,2 ,, 3, 4"); + } + + @TestFactory + Stream nonDigitsInSplitSelect() { + return Stream.concat( + DynamicTest.stream(Arrays.asList( + "1q 2 3", + "play 1q 2 3" + ).iterator(), + testCase -> String.format("split select of `%s`", testCase), + testCase -> assertSplitSelect(one_two_three, testCase)), + + DynamicTest.stream(Arrays.asList( + "play q", + "We are number 1 but this string doesn't match", + "1, 2, 3, 4, 5 Once we caught a fish alive" + ).iterator(), + testCase -> String.format("not matching split select of `%s`", testCase), + testCase -> assertNoSplitSelect(testCase) + ) + ); + } + + private void assertSplitSelect(Collection expected, String testCase) { + Assertions.assertTrue( + TextUtils.isSplitSelect(testCase), + () -> String.format("`%s` is not a split select", testCase)); + Assertions.assertIterableEquals( + expected, TextUtils.getSplitSelect(testCase) + ); + } + + private void assertNoSplitSelect(String testCase) { + Assertions.assertFalse(TextUtils.isSplitSelect(testCase)); + } +} From 0d745d1afeb3c30dd9d967e09505916b4e91cbd3 Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 12 Dec 2017 13:02:23 +0100 Subject: [PATCH 28/62] Split HelpMessage string, adjust wording --- .../fredboat/command/util/HelpCommand.java | 42 +++++++++++++++---- .../src/main/resources/lang/en_US.properties | 6 ++- .../shared/constant/BotConstants.java | 4 ++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/command/util/HelpCommand.java b/FredBoat/src/main/java/fredboat/command/util/HelpCommand.java index a173deadb..ddd9a107e 100644 --- a/FredBoat/src/main/java/fredboat/command/util/HelpCommand.java +++ b/FredBoat/src/main/java/fredboat/command/util/HelpCommand.java @@ -34,26 +34,25 @@ import fredboat.commandmeta.abs.CommandContext; import fredboat.commandmeta.abs.ICommandRestricted; import fredboat.commandmeta.abs.IUtilCommand; -import fredboat.feature.I18n; import fredboat.messaging.CentralMessaging; import fredboat.messaging.internal.Context; import fredboat.perms.PermissionLevel; +import fredboat.shared.constant.BotConstants; import fredboat.util.Emojis; import fredboat.util.TextUtils; import net.dv8tion.jda.core.Permission; import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.Member; +import net.dv8tion.jda.core.entities.TextChannel; +import net.dv8tion.jda.core.entities.User; import net.dv8tion.jda.core.events.message.priv.PrivateMessageReceivedEvent; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.text.MessageFormat; import java.util.concurrent.TimeUnit; public class HelpCommand extends Command implements IUtilCommand { - //This can be set using eval in case we need to change it in the future ~Fre_d - public static String inviteLink = "https://discord.gg/cgPFW4q"; - //keeps track of whether a user received help lately to avoid spamming/clogging up DMs which are rather harshly ratelimited public static final Cache HELP_RECEIVED_RECENTLY = CacheBuilder.newBuilder() .recordStats() @@ -87,7 +86,7 @@ public static void sendGeneralHelp(@Nonnull CommandContext context) { return; } - context.replyPrivate(getHelpDmMsg(context.guild), + context.replyPrivate(getHelpDmMsg(context), success -> { HELP_RECEIVED_RECENTLY.put(userId, true); String out = context.i18n("helpSent"); @@ -113,7 +112,27 @@ public static void sendGeneralHelp(@Nonnull PrivateMessageReceivedEvent event) { } HELP_RECEIVED_RECENTLY.put(event.getAuthor().getIdLong(), true); - CentralMessaging.sendMessage(event.getChannel(), getHelpDmMsg(null)); + CentralMessaging.sendMessage(event.getChannel(), getHelpDmMsg(new Context() { //yeah this is ugly ¯\_(ツ)_/¯ + @Override + public TextChannel getTextChannel() { + return null; + } + + @Override + public Guild getGuild() { + return null; + } + + @Override + public Member getMember() { + return null; + } + + @Override + public User getUser() { + return event.getAuthor(); + } + })); } public static String getFormattedCommandHelp(Context context, Command command, String commandOrAlias) { @@ -154,7 +173,12 @@ private static void sendFormattedCommandHelp(CommandContext context, String trig context.replyWithName(out); } - public static String getHelpDmMsg(@Nullable Guild guild) { - return MessageFormat.format(I18n.get(guild).getString("helpDM"), inviteLink); + @Nonnull + public static String getHelpDmMsg(@Nonnull Context context) { + String docsLocation = context.i18n("helpDocsLocation") + "\n" + BotConstants.DOCS_URL; + String botInvite = context.i18n("helpBotInvite") + "\n<" + BotConstants.botInvite + ">"; + String hangoutInvite = context.i18n("helpHangoutInvite") + "\n" + BotConstants.hangoutInvite; + String footer = context.i18n("helpNoDmCommands") + "\n" + context.i18n("helpCredits"); + return docsLocation + "\n\n" + botInvite + "\n\n" + hangoutInvite + "\n\n" + footer; } } diff --git a/FredBoat/src/main/resources/lang/en_US.properties b/FredBoat/src/main/resources/lang/en_US.properties index 5ab83fd7b..f711baa10 100644 --- a/FredBoat/src/main/resources/lang/en_US.properties +++ b/FredBoat/src/main/resources/lang/en_US.properties @@ -215,7 +215,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite the bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs! helpProperUsage=Proper usage: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/Shared/src/main/java/fredboat/shared/constant/BotConstants.java b/Shared/src/main/java/fredboat/shared/constant/BotConstants.java index d08ff5035..7e8ec0959 100644 --- a/Shared/src/main/java/fredboat/shared/constant/BotConstants.java +++ b/Shared/src/main/java/fredboat/shared/constant/BotConstants.java @@ -42,6 +42,10 @@ public class BotConstants { public static final String DOCS_PERMISSIONS_URL = DOCS_URL + "/permissions"; public static final String DOCS_DONATE_URL = DOCS_URL + "/donate"; + //These can be set using eval in case we need to change it in the future ~Fre_d + public static String hangoutInvite = "https://discord.gg/cgPFW4q"; + public static String botInvite = "https://goo.gl/cFs5M9"; + private BotConstants() { } From db9baff0102111ee5ff520b07d5bf37beeeff079 Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 12 Dec 2017 14:05:27 +0100 Subject: [PATCH 29/62] Update translations files from crowdin --- .../src/main/resources/lang/af_ZA.properties | 10 +- .../src/main/resources/lang/ar_SA.properties | 96 +++++++------- .../src/main/resources/lang/bg_BG.properties | 10 +- .../src/main/resources/lang/ca_ES.properties | 10 +- .../src/main/resources/lang/cs_CZ.properties | 10 +- .../src/main/resources/lang/cy_GB.properties | 10 +- .../src/main/resources/lang/da_DK.properties | 118 +++++++++--------- .../src/main/resources/lang/de_DE.properties | 26 ++-- .../src/main/resources/lang/el_GR.properties | 18 +-- .../src/main/resources/lang/en_PT.properties | 10 +- .../src/main/resources/lang/en_TS.properties | 16 ++- .../src/main/resources/lang/es_ES.properties | 18 +-- .../src/main/resources/lang/et_EE.properties | 10 +- .../src/main/resources/lang/fa_IR.properties | 10 +- .../src/main/resources/lang/fi_FI.properties | 10 +- .../src/main/resources/lang/fil_PH.properties | 10 +- .../src/main/resources/lang/fr_FR.properties | 20 +-- .../src/main/resources/lang/he_IL.properties | 10 +- .../src/main/resources/lang/hr_HR.properties | 10 +- .../src/main/resources/lang/hu_HU.properties | 34 ++--- .../src/main/resources/lang/id_ID.properties | 92 +++++++------- .../src/main/resources/lang/it_IT.properties | 18 +-- .../src/main/resources/lang/ja_JP.properties | 20 +-- .../src/main/resources/lang/ko_KR.properties | 66 +++++----- .../src/main/resources/lang/ms_MY.properties | 10 +- .../src/main/resources/lang/nl_NL.properties | 16 ++- .../src/main/resources/lang/no_NO.properties | 10 +- .../src/main/resources/lang/pl_PL.properties | 20 +-- .../src/main/resources/lang/pt_BR.properties | 16 ++- .../src/main/resources/lang/pt_PT.properties | 10 +- .../src/main/resources/lang/ro_RO.properties | 16 ++- .../src/main/resources/lang/ru_RU.properties | 10 +- .../src/main/resources/lang/sr_SP.properties | 10 +- .../src/main/resources/lang/sv_SE.properties | 18 +-- .../src/main/resources/lang/th_TH.properties | 12 +- .../src/main/resources/lang/tr_TR.properties | 14 ++- .../src/main/resources/lang/uk_UA.properties | 10 +- .../src/main/resources/lang/vi_VN.properties | 16 ++- .../src/main/resources/lang/zh_CN.properties | 18 +-- .../src/main/resources/lang/zh_TW.properties | 36 +++--- 40 files changed, 532 insertions(+), 372 deletions(-) diff --git a/FredBoat/src/main/resources/lang/af_ZA.properties b/FredBoat/src/main/resources/lang/af_ZA.properties index 7e485a852..33d4b21bb 100644 --- a/FredBoat/src/main/resources/lang/af_ZA.properties +++ b/FredBoat/src/main/resources/lang/af_ZA.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Jy is koers beperk word\! Asseblief vertraag. ratelimitedSkipCommand=Jy kan meer as een liedjie slaan deur die gebruik van hierdie opdrag\: {0} ratelimitedGuildSlowLoadingPlaylist=Hierdie bediener is nie toegelaat om by te voeg meer speellyste op hierdie oomblik. Asseblief Moenie lang speellyste spam. unblacklisted=Verwyder {0} uit die swartlys. -serverinfoTitle=Inligting oor * *{0} * *\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Gebruikers aanlyn\: serverinfoTotalUsers=Totale gebruikers\: serverinfoRoles=Rolle\: @@ -193,7 +193,7 @@ serverinfoGuildID=Gilde ID\: serverinfoCreationDate=Skepping datum\: serverinfoOwner=Eienaar\: serverinfoVLv=Verifikasie vlak\: -userinfoTitle=Inligting oor * *{0} * *\: +userinfoTitle=Information about {0}\: userinfoUsername=Gebruikersnaam\: userinfoId=ID\: userinfoNick=Bynaam\: @@ -212,7 +212,11 @@ commandsMaintenance=Onderhoud commandsBotOwner=Bot eienaar commandsMoreHelp=S\u00ea {0} om meer inligting oor ''n spesifieke opdrag te kry. helpUnknownCommand=Onbekende bevel. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Dokumentasie is aan jou DMs gestuur\! helpProperUsage=Behoorlike gebruik\: helpCommandOwnerRestricted=Hierdie bevel is beperk tot die eienaar van die bot. diff --git a/FredBoat/src/main/resources/lang/ar_SA.properties b/FredBoat/src/main/resources/lang/ar_SA.properties index cfe6587b8..d34bca1f0 100644 --- a/FredBoat/src/main/resources/lang/ar_SA.properties +++ b/FredBoat/src/main/resources/lang/ar_SA.properties @@ -45,7 +45,7 @@ exportPlaylistFail=\u0641\u0634\u0644 \u0641\u064a \u062a\u062d\u0645\u064a\u064 listShowShuffled=\u0639\u0631\u0636 \u062a\u0639\u062f\u064a\u0644\u0627\u064b \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0634\u063a\u064a\u0644. listShowRepeatSingle=\u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0623\u063a\u0646\u064a\u0629 \u0627\u0644\u062d\u0627\u0644\u064a\u0629. listShowRepeatAll=\u062a\u0643\u0631\u0627\u0631 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631 \u0627\u0644\u062d\u0627\u0644\u064a\u0629. -listShowHistory=Showing tracks in history. +listShowHistory=\u0639\u0631\u0636 \u0627\u0644\u0645\u0633\u0627\u0631\u0627\u062a \u0641\u064a \u0627\u0644\u0645\u0634\u063a\u0644. listAddedBy=* *{0} * * \u0625\u0636\u0627\u0641\u062a\u0647\u0627 \u0628\u0648\u0627\u0633\u0637\u0629 * *{1} * * ''[{2}]'' listStreamsOnlySingle=\u0647\u0646\u0627\u0643 * *{0} * * {1} \u064a\u0639\u064a\u0634 \u0641\u064a \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631. listStreamsOnlyMultiple=\u0648\u0647\u0646\u0627\u0643 * *{0} * * {1} \u064a\u0639\u064a\u0634 \u0641\u064a \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631. @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=\u060c \u0643\u0630\u0644\u0643 * *{0} * * {1} \u0644\u0 trackSingular=\u0645\u0633\u0627\u0631 trackPlural=\u0627\u0644\u0645\u0633\u0627\u0631\u0627\u062a npNotPlaying=\u0644\u0627 \u062d\u0627\u0644\u064a\u0627 \u062a\u0634\u063a\u064a\u0644 \u0623\u064a \u0634\u064a\u0621. -npNotInHistory=Currently no tracks in history. +npNotInHistory=\u0644\u0627 \u062a\u0648\u062c\u062f \u0627\u064a \u0645\u0633\u0627\u0631\u0627\u062a \u0641\u064a \u0627\u0644\u0633\u062c\u0644. npDescription=\u0627\u0644\u0648\u0635\u0641 npLoadedSoundcloud=[{0}/{1}] \u062a\u062d\u0645\u064a\u0644 \u0645\u0646 \u0633\u0648\u0646\u062f\u0643\u0644\u0648\u062f npLoadedBandcamp={0} \u062a\u062d\u0645\u064a\u0644 \u0645\u0646 Bandcamp @@ -79,7 +79,7 @@ restartSuccess=**{0}** \u062a\u0645 \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\ queueEmpty=\u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0641\u0627\u0631\u063a\u0629. rewSuccess=\u0625\u0639\u0627\u062f\u0629 \u062a\u0648\u062c\u064a\u0647 **{0}** \u0628 {1}. seekSuccess=\u062a\u0633\u0639\u0649 * *{0} * * \u0625\u0644\u0649 {1}. -seekDeniedLiveTrack=You can't seek a live track. +seekDeniedLiveTrack=\u0644\u0627 \u064a\u0645\u0643\u0646 \u0628\u062d\u062b \u0627\u0644\u0645\u0633\u0627\u0631 \u0645\u0628\u0627\u0634\u0631. loadPlaySplitListFail=\u064a\u0624\u062f\u064a \u0647\u0630\u0627 \u0627\u0644\u0627\u0631\u062a\u0628\u0627\u0637 \u0625\u0644\u0649 \u0642\u0627\u0626\u0645\u0629 \u062a\u0634\u063a\u064a\u0644\u060c \u0644\u0627 \u0639\u0644\u0649 \u0645\u0633\u0627\u0631. \u062d\u0627\u0648\u0644 '\u061b\u061b \u0627\u0644\u0644\u0639\u0628 ' \u0628\u062f\u0644\u0627\u064b \u0645\u0646 \u0630\u0644\u0643. loadListSuccess=\u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 \u0648\u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0623\u063a\u0627\u0646\u064a ''{0}'' \u0645\u0646 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0634\u063a\u064a\u0644 * *{1} * *. loadNoMatches=\u062a\u0639\u0630\u0631 \u0627\u0644\u062d\u0636\u0644 \u0639\u0644\u0649 \u0627\u064a \u0635\u0648\u062a \u0644`{0}`. @@ -125,15 +125,15 @@ luaError=\ \u062d\u062f\u062b \u062e\u0637\u0623 \u0641\u064a \u0644\u0648\u0627 luaErrorOutputTooBig=\ \u0627\u0644\u0645\u062e\u0632\u0646 \u0627\u0644\u0645\u0624\u0642\u062a \u0644\u0644\u0625\u062e\u0631\u0627\u062c \u0647\u0648 \:anger\: \u0643\u0628\u064a\u0631 \u062c\u062f\u0627\u064b \u0627\u0644\u0634\u0642\u0627\u0642 \u064a\u0633\u0645\u062d \u0641\u0642\u0637 \u0627\u0644\u0623\u062d\u0631\u0641 2000 \u0643\u0644 \u0631\u0633\u0627\u0644\u0629\u060c \u062d\u0635\u0644\u062a \u0639\u0644\u0649 {0} luaTimeout=\ \u0645\u0647\u0644\u0629 \u062f\u0627\u0644\u0629 \:anger\: \u064a\u0633\u0645\u062d \u0628\u062d\u0633\u0627\u0628 \u0627\u0644\u0648\u0642\u062a {0} \u062b\u0627\u0646\u064a\u0629. helpSuccess=\u062a\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0648\u062b\u0627\u0626\u0642 \u0625\u0644\u0649 \u0631\u0633\u0627\u0626\u0644\u0643 \u0627\u0644\u0645\u0628\u0627\u0634\u0631\u0629\!\n \n\u0627\u0644\u0633\u064a\u0627\u0642 | \u0633\u064a\u0627\u0642 \u0627\u0644\u0637\u0644\u0628\! -helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! +helpDmFailed=\u062a\u0639\u0630\u0631 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0645\u0633\u062a\u0646\u062f \u0641\u064a \u0627\u0644 \u062f\u0645 \u0627\u0644\u062e\u0627\u0635 \u0628\u0643. \u064a\u0631\u062c\u0649 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0639\u062f\u0645 \u062a\u0639\u0637\u064a\u0644\u0647\u0627\! helpCommandsPromotion=\u0642\u0648\u0644 {0} \u0644\u0645\u0639\u0631\u0641\u0629 \u0645\u0627 \u064a\u0645\u0643\u0646 \u0627\u0644\u0642\u064a\u0627\u0645 \u0628\u0647 \u0647\u0630\u0627 \u0628\u0648\u062a\! fuzzyNoResults=\u0644\u0627 \u064a\u0648\u062c\u062f \u0645\u0633\u062a\u062e\u062f\u0645 \u0628\u0627\u0633\u0645 %s brainfuckCycleLimit=\u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062c \u062a\u062c\u0627\u0648\u0632 \u062f\u0648\u0631\u0629 \u0643\u062d\u062f \u0623\u0642\u0635\u0649 \u0627\u0644\u0639\u062f\u062f \u0645\u0646 {0} brainfuckDataPointerOutOfBounds=\u0645\u0624\u0634\u0631 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u062e\u0627\u0631\u062c \u0627\u0644\u062d\u062f\u0648\u062f\: {0} brainfuckInputOOB=\u0627\u0644\u0625\u062f\u062e\u0627\u0644 \u062e\u0627\u0631\u062c \u0627\u0644\u062d\u062f\u0648\u062f \u0641\u064a \u0627\u0644\u0645\u0648\u0636\u0639\: {0} brainfuckNoOutput=\ \u0648\u0643\u0627\u0646 \u0647\u0646\u0627\u0643 \u0623\u064a\u0629 \u0627\u0644\u0625\u062e\u0631\u0627\u062c -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} +weatherLocationNotFound=\u062a\u0639\u0630\u0631 \u0639\u0644\u0649 \u0625\u064a\u062c\u0627\u062f \u0627\u0644\u0645\u0648\u0642\u0639. \u064a\u0631\u062c\u0649 \u0627\u0644\u062a\u062d\u0642\u0642 \u0639\u0646 \u0627\u0644\u0627\u062f\u062e\u0627\u0644. +weatherError=\u062d\u062f\u062b \u062e\u0637\u0623 \u0623\u062b\u0646\u0627\u0621 \u0627\u0633\u062a\u0631\u062f\u0627\u062f \u0627\u0644\u0637\u0642\u0633 \u0644 avatarSuccess=\ \u0648\u062c\u062a\u0647 configNoArgs=\u0627\u0644\u062a\u0643\u0648\u064a\u0646 \u0644 * *{0} * *\: '''' '' configSetTo=\u064a\u062a\u0645 \u0627\u0644\u0622\u0646 \u062a\u0639\u064a\u064a\u0646 \u0625\u0644\u0649 ''{0}''. @@ -171,7 +171,7 @@ hugSuccess=\u0627\u0644\u0639\u0646\u0627\u0642 {0}. patBot=\u0634\u0643\u0631\u0627 \u0639\u0644\u0649 \:blush\: \u0627\u0644\u0631\u0628\u062a\u0627\u062a\: patSuccess={0} \u0627\u0644\u0631\u0628\u062a\u0627\u062a. rollSuccess=\u062d\u0648\u0644 \u0627\u0644\u0642\u0648\u0627\u0626\u0645 {0} \u0639\u0644\u0649 \u0627\u0644\u0623\u0631\u0636. -facedeskSuccess={0} facedesks. +facedeskSuccess=\u0645\u062d\u0637 \u0648\u062c\u0647\u0647. langInvalidCode={0} \u0631\u0645\u0632 \u0627\u0644\u0644\u063a\u0629 \u063a\u064a\u0631 \u0645\u0648\u062c\u0648\u062f \u0623\u0648 \u0623\u0646\u0647 \u063a\u064a\u0631 \u0645\u0639\u062a\u0645\u062f. langSuccess=\u062a\u062d\u0648\u0644\u062a \u0625\u0644\u0649\: \u062a\u0643\u0644\u0645 {0}. langInfo=\u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a \u064a\u062f\u0639\u0645 \u0639\u062f\u0629 \u0644\u063a\u0627\u062a \u0633\u0627\u0647\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0627\u0644\u062a\u064a \u064a\u0645\u0643\u0646\u0643 \u062a\u062d\u062f\u064a\u062f\u0647\u0627 \u0645\u0639 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631. \u0627\u0644\u0645\u0634\u0631\u0641\u0648\u0646 \u0639\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u0645\u0644\u0642\u0645 \u064a\u0645\u0643\u0646 \u062a\u062d\u062f\u064a\u062f \u0644\u063a\u0629 \u0645\u0639 '\u061b\u061b \u0644\u0627\u0646\u062c ' \u0625\u0644\u064a\u0643 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0643\u0627\u0645\u0644\u0629 \u0644\u0644\u063a\u0627\u062a \u0627\u0644\u0645\u062f\u0639\u0648\u0645\u0629\: @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u0623\u0646\u062a \u064a\u062c\u0631\u064a \u0645\u0639\ ratelimitedSkipCommand=\u064a\u0645\u0643\u0646\u0643 \u062a\u062e\u0637\u064a \u0623\u063a\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629 \u0623\u0648 \u0623\u0643\u062b\u0631 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631\: {0} ratelimitedGuildSlowLoadingPlaylist=\u0644\u0627 \u064a\u0633\u0645\u062d \u0647\u0630\u0627 \u0627\u0644\u0645\u0644\u0642\u0645 \u0644\u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0645\u0632\u064a\u062f \u0645\u0646 \u0642\u0648\u0627\u0626\u0645 \u0627\u0644\u062a\u0634\u063a\u064a\u0644 \u0641\u064a \u0647\u0630\u0647 \u0627\u0644\u0644\u062d\u0638\u0629. \u0627\u0644\u0631\u062c\u0627\u0621 \u0644\u0627 \u063a\u064a\u0631 \u0627\u0644\u0645\u0631\u063a\u0648\u0628\u0629 \u0642\u0648\u0627\u0626\u0645 \u0637\u0648\u064a\u0644\u0629. unblacklisted=\u0625\u0632\u0627\u0644\u0629 {0} \u0645\u0646 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0633\u0648\u062f\u0627\u0621. -serverinfoTitle=\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0639\u0646 * *{0} * *\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u0648\u0646 \u0627\u0644\u0645\u062a\u0648\u0627\u062c\u062f\u0648\u0646 \u062d\u0627\u0644\u064a\u0640\u0651\u0640\u0627\: serverinfoTotalUsers=\u0625\u062c\u0645\u0627\u0644\u064a \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646\: serverinfoRoles=\u0623\u062f\u0648\u0627\u0631\: @@ -193,17 +193,17 @@ serverinfoGuildID=\u0645\u0639\u0631\u0641 \u0627\u0644\u0646\u0642\u0627\u0628\ serverinfoCreationDate=\u062a\u0627\u0631\u064a\u062e \u0627\u0644\u0625\u0646\u0634\u0627\u0621\: serverinfoOwner=\u0627\u0644\u0645\u0627\u0644\u0643\: serverinfoVLv=\u0645\u0633\u062a\u0648\u0649 \u0627\u0644\u062a\u062d\u0642\u0642\: -userinfoTitle=\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0639\u0646 * *{0} * *\: +userinfoTitle=Information about {0}\: userinfoUsername=\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\: userinfoId=ID\: userinfoNick=\u0644\u0642\u0628\: userinfoKnownServer=\u0645\u0644\u0642\u0645\u0627\u062a \u0645\u0639\u0631\u0648\u0641\u0629\: userinfoJoinDate=\u062a\u0627\u0631\u064a\u062e \u0627\u0644\u0627\u0646\u062a\u062f\u0627\u0628\: userinfoCreationTime=\u062a\u0627\u0631\u064a\u062e \u0627\u0644\u0625\u0646\u0634\u0627\u0621\: -userinfoBlacklisted=Blacklisted\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +userinfoBlacklisted=\u0627\u0644\u0642\u0627\u0621\u0645\u0629 \u0627\u0644\u0633\u0648\u062f\u0627\u0621\: +skipDeniedTooManyTracks=\u0644\u0627 \u064a\u0645\u0643\u0646\u0643 \u062a\u062e\u0637\u064a \u0645\u0633\u0627\u0631\u0627\u062a \u0634\u062e\u0635 \u0623\u062e\u0631 \u0625\u0630\u0627 \u0644\u0645 \u062a\u0643\u0646 DJ. \u0641\u0643\u0631 \u0641\u064a \u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0627\u0644\u0627\u0645\u0631 Voteskip. eventUsersLeftVC=\u0648\u062a\u0631\u0643\u062a \u062c\u0645\u064a\u0639 \u0645\u0633\u062a\u062e\u062f\u0645\u064a \u0642\u0646\u0627\u0629 \u0635\u0648\u062a. \u062a\u0645 \u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u0644\u0627\u0639\u0628. -eventAutoResumed=User presence detected, automatically resuming the player. +eventAutoResumed=\u062a\u0645 \u0623\u0643\u062a\u0634\u0627\u0641 \u0648\u062c\u0648\u062f \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u060c \u0633\u064a\u0643\u0645\u0644 \u0627\u0644\u0645\u0634\u063a\u0644 \u062a\u0644\u0642\u0627\u0621\u064a\u0627. commandsFun=\u0645\u062a\u0639\u0629 commandsMemes=Memes commandsUtility=\u0627\u0644\u0623\u062f\u0648\u0627\u062a @@ -212,7 +212,11 @@ commandsMaintenance=\u0627\u0644\u0635\u064a\u0627\u0646\u0629 commandsBotOwner=\u0645\u0627\u0644\u0643 \u0628\u0648\u062a commandsMoreHelp=\u0648\u064a\u0642\u0648\u0644 {0} \u0644\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0645\u0632\u064a\u062f \u0645\u0646 \u0627\u0644\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u062d\u0648\u0644 \u0623\u0645\u0631 \u0645\u0639\u064a\u0646. helpUnknownCommand=\u0623\u0645\u0631 \u063a\u064a\u0631 \u0645\u0639\u0631\u0648\u0641. -helpDM=\u0648\u064a\u0645\u0643\u0646 \u0627\u0644\u0627\u0637\u0644\u0627\u0639 \u0639\u0644\u0649 \u0627\u0644\u0648\u062b\u0627\u0626\u0642 \u0639\u0644\u0649 \u0627\u0644\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u062a\u0627\u0644\u064a\:\nhttps\://fredboat.com/docs\n\n\u062a\u0631\u064a\u062f \u0625\u0636\u0627\u0641\u0629 \u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a \u0625\u0644\u0649 \u0627\u0644\u062e\u0627\u062f\u0645 \u0627\u0644\u062e\u0627\u0635 \u0628\u0643\u061f \u0625\u0630\u0627 \u0643\u0627\u0646 \u0644\u062f\u064a\u0643 \u0623\u0630\u0648\u0646\u0627\u062a \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u062e\u0627\u062f\u0645 \u0644\u0646\u0642\u064a\u0628\u062a\u0643\u060c \u0641\u064a\u0645\u0643\u0646\u0643 \u062f\u0639\u0648\u062a\u0647\u0627 \u0647\u0646\u0627\:\n* \u0647\u0630\u0627 \u0648\u0627\u062d\u062f \u0644\u0627 \u062a\u0644\u0639\u0628 \u0627\u0644\u0645\u0648\u0633\u064a\u0642\u0649 *\n\n\n\u0625\u0630\u0627 \u0643\u0646\u062a \u062a\u0631\u063a\u0628 \u0641\u064a \u0625\u0636\u0627\u0641\u0629 \u0628\u0648\u062a \u0627\u0644\u0645\u0648\u0633\u064a\u0642\u0649\u060c \u0648\u0633\u0648\u0641 \u062a\u062d\u062a\u0627\u062c \u0625\u0644\u0649 \u062f\u0639\u0648\u0629 \u0647\u0630\u0627 \u0628\u0648\u062a\:\n\n\n\u062a\u062d\u062a\u0627\u062c \u0625\u0644\u0649 \u0645\u0633\u0627\u0639\u062f\u0629 \u0623\u0648 \u0644\u062f\u064a\u0643 \u0623\u064a \u0623\u0641\u0643\u0627\u0631 \u0644\u0644\u0628\u0648\u062a\u061f \u0631\u0628\u0645\u0627 \u0643\u0646\u062a \u062a\u0631\u063a\u0628 \u0641\u0642\u0637 \u0641\u064a \u0634\u0646\u0642\u061f \u0647\u064a\u0627 \u0625\u0644\u0649 \u0641\u0631\u064a\u062f\u0628\u0648\u062a \u0647\u0646\u063a\u0648\u062a\!\n{0}\n\n\u0644\u0627 \u064a\u0645\u0643\u0646\u0643 \u0625\u0631\u0633\u0627\u0644 \u0647\u0630\u0647 \u0627\u0644\u0623\u0648\u0627\u0645\u0631 \u0628\u0648\u062a \u0645\u0646 \u062e\u0644\u0627\u0644 \u062f\u0645.\n\u0628\u0648\u062a \u0627\u0644\u062a\u064a \u0623\u0646\u0634\u0623\u062a\u0647\u0627 Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u062a\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0648\u062b\u0627\u0626\u0642 \u0625\u0644\u0649 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0648\u062c\u0647\u0627\u062a \u0627\u0644\u0633\u064a\u0627\u062d\u064a\u0629 \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0643\! helpProperUsage=\u0627\u0644\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0627\u0644\u0635\u062d\u064a\u062d\: helpCommandOwnerRestricted=\u064a\u0642\u062a\u0635\u0631 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631 \u0639\u0644\u0649 \u0645\u0627\u0644\u0643 \u0627\u0644\u0628\u0648\u062a. @@ -225,20 +229,20 @@ helpMusicCommandsHeader=\u0623\u0648\u0627\u0645\u0631 \u0627\u0644\u0645\u0648\ helpJoinCommand=\u062c\u0639\u0644 \u0628\u0648\u062a \u0627\u0644\u0627\u0646\u0636\u0645\u0627\u0645 \u0625\u0644\u0649 \u0642\u0646\u0627\u0629 \u0627\u0644\u0635\u0648\u062a \u0627\u0644\u062d\u0627\u0644\u064a \u0627\u0644\u062e\u0627\u0635 \u0628\u0643. helpLeaveCommand=\u062c\u0639\u0644 \u0628\u0648\u062a \u0645\u063a\u0627\u062f\u0631\u0629 \u0627\u0644\u0642\u0646\u0627\u0629 \u0627\u0644\u0635\u0648\u062a\u064a\u0629 \u0627\u0644\u062d\u0627\u0644\u064a\u0629. helpPauseCommand=\u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u0644\u0627\u0639\u0628. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=\u062a\u0634\u063a\u064a\u0644 \u0627\u0644\u0645\u0648\u0633\u064a\u0642\u0649 \u0645\u0646 \u0639\u0646\u0648\u0627\u0646 URL \u0645\u0639\u064a\u0646 \u0623\u0648 \u0627\u0644\u0628\u062d\u062b \u0639\u0646 \u0645\u0633\u0627\u0631. \u0644\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0642\u0627\u0626\u0645\u0629 \u0643\u0627\u0645\u0644\u0629 \u0645\u0646 \u0627\u0644\u0645\u0635\u0627\u062f\u0631 \u064a\u0631\u062c\u0649 \u0632\u064a\u0627\u0631\u0629 helpPlaySplitCommand=\u062a\u0642\u0633\u064a\u0645 \u0641\u064a\u062f\u064a\u0648 \u064a\u0648\u062a\u064a\u0648\u0628 \u0625\u0644\u0649 \u0627\u0644\u062a\u0633\u0637\u064a\u0628 \u0627\u0644\u0645\u0646\u0635\u0648\u0635 \u0639\u0644\u064a\u0647\u0627 \u0641\u064a \u0648\u0635\u0641 \u0623\u0646\u0647\u0627. helpRepeatCommand=\u0627\u0644\u062a\u0628\u062f\u064a\u0644 \u0628\u064a\u0646 \u0648\u0636\u0639\u064a \u062a\u0643\u0631\u0627\u0631. helpReshuffleCommand=\u062a\u0639\u062f\u064a\u0644 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631 \u0627\u0644\u062d\u0627\u0644\u064a\u0629. helpSelectCommand=\u062d\u062f\u062f \u0623\u062d\u062f \u0627\u0644\u0645\u0633\u0627\u0631\u0627\u062a \u0627\u0644\u0645\u0642\u062f\u0645\u0629 \u0628\u0639\u062f \u0628\u062d\u062b \u0644\u0644\u0639\u0628. helpShuffleCommand=\u062a\u0628\u062f\u064a\u0644 \u0648\u0636\u0639 \u0627\u0644\u0645\u0631\u0627\u0648\u063a\u0629 \u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631 \u0627\u0644\u062d\u0627\u0644\u064a\u0629. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpSkipCommand=\u062a\u062e\u0637\u064a \u0627\u0644\u0623\u063a\u0646\u064a\u0629 \u0627\u0644\u062d\u0627\u0644\u064a\u0629\u060c \u0623\u063a\u0646\u064a\u0629 n&\#39; th \u0641\u064a \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631\u060c \u062c\u0645\u064a\u0639 \u0627\u0644\u0623\u063a\u0627\u0646\u064a \u0645\u0646 n \u0625\u0644\u0649 m\u060c \u0623\u0648 \u062c\u0645\u064a\u0639 \u0627\u0644\u0623\u063a\u0627\u0646\u064a \u0645\u0646 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646 \u0627\u0644\u0645\u0630\u0643\u0648\u0631\u0629. \u0627\u0644\u0631\u062c\u0627\u0621 \u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0644\u0644\u0627\u0639\u062a\u062f\u0627\u0644. helpStopCommand=\u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u0644\u0627\u0639\u0628 \u0648\u0645\u0633\u062d \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0634\u063a\u064a\u0644. \u0645\u062d\u0641\u0648\u0638\u0629 \u0644\u0644\u0645\u0634\u0631\u0641\u064a\u0646 \u0645\u0639 "\u0625\u062f\u0627\u0631\u0629 \u0631\u0633\u0627\u0626\u0644" \u0627\u0644\u0625\u0630\u0646. helpUnpauseCommand=\u0625\u0644\u063a\u0627\u0621 \u0627\u0644\u0625\u064a\u0642\u0627\u0641 \u0627\u0644\u0645\u0624\u0642\u062a \u0644\u0644\u0627\u0639\u0628. helpVolumeCommand=\u062a\u063a\u064a\u064a\u0631 \u0648\u062d\u062f\u0629 \u0627\u0644\u062a\u062e\u0632\u064a\u0646. \u062a\u0643\u0648\u0646 \u0627\u0644\u0642\u064a\u0645 0-150 \u0648 100 \u0647\u0648 \u0627\u0644\u0625\u0639\u062f\u0627\u062f \u0627\u0644\u0627\u0641\u062a\u0631\u0627\u0636\u064a. \u062a\u0645 \u0625\u0647\u0645\u0627\u0644 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631 \u0648\u062d\u062f\u0629 \u0627\u0644\u062a\u062e\u0632\u064a\u0646 \u0639\u0644\u0649 \u0628\u0648\u062a \u0627\u0644\u0639\u0627\u0645\u0629. helpExportCommand=\u062a\u0635\u062f\u064a\u0631 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631 \u0627\u0644\u062d\u0627\u0644\u064a\u0629 \u0625\u0644\u0649 \u0627\u0631\u062a\u0628\u0627\u0637 \u0647\u0627\u0633\u062a\u064a\u0628\u064a\u0646\u060c \u0648\u064a\u0645\u0643\u0646 \u0627\u0633\u062a\u062e\u062f\u0627\u0645\u0647\u0627 \u0641\u064a \u0648\u0642\u062a \u0644\u0627\u062d\u0642 \u0643\u0642\u0627\u0626\u0645\u0629 \u062a\u0634\u063a\u064a\u0644. helpGensokyoRadioCommand=\u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0623\u063a\u0646\u064a\u0629 \u0627\u0644\u062d\u0627\u0644\u064a\u0629 \u0644\u0639\u0628\u062a \u0639\u0644\u0649 gensokyoradio.net helpListCommand=\u0639\u0631\u0636 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0623\u063a\u0627\u0646\u064a \u0627\u0644\u062d\u0627\u0644\u064a\u0629 \u0641\u064a \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0634\u063a\u064a\u0644. -helpHistoryCommand=Display a list of the songs in playlist history. +helpHistoryCommand=\u0639\u0631\u0636 \u0642\u0627\u0626\u0645\u0629 \u0628\u0627\u0644\u0623\u063a\u0627\u0646\u064a \u0641\u064a \u0633\u062c\u0644 \u0642\u0648\u0627\u0626\u0645 \u0627\u0644\u062a\u0634\u063a\u064a\u0644. helpNowplayingCommand=\u0639\u0631\u0636 \u0627\u0644\u0623\u063a\u0646\u064a\u0629 \u0642\u064a\u062f \u0627\u0644\u062a\u0634\u063a\u064a\u0644 \u062d\u0627\u0644\u064a\u0627. helpForwardCommand=\u0625\u0644\u0649 \u0627\u0644\u0623\u0645\u0627\u0645 \u0639\u0644\u0649 \u0627\u0644\u0645\u0633\u0627\u0631 \u0628\u0645\u0642\u062f\u0627\u0631 \u0645\u0639\u064a\u0646 \u0645\u0646 \u0627\u0644\u0648\u0642\u062a. \u0639\u0644\u0649 \u0633\u0628\u064a\u0644 \u0627\u0644\u0645\u062b\u0627\u0644\: helpRestartCommand=\u0642\u0645 \u0628\u0625\u0639\u0627\u062f\u0629 \u062a\u0634\u063a\u064a\u0644 \u0627\u0644\u0645\u0633\u0627\u0631 \u0642\u064a\u062f \u0627\u0644\u062a\u0634\u063a\u064a\u0644 \u062d\u0627\u0644\u064a\u0627. @@ -246,7 +250,7 @@ helpRewindCommand=\u0625\u0631\u062c\u0627\u0639 \u0627\u0644\u0645\u0633\u0627\ helpSeekCommand=\u062a\u0639\u064a\u064a\u0646 \u0645\u0648\u0636\u0639 \u0627\u0644\u0645\u0633\u0627\u0631 \u0644\u0648\u0642\u062a \u0645\u0639\u064a\u0646. \u0639\u0644\u0649 \u0633\u0628\u064a\u0644 \u0627\u0644\u0645\u062b\u0627\u0644\: helpAvatarCommand=\u0639\u0631\u0636 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0631\u0645\u0632\u064a\u0629 \u0644\u0644\u0645\u0633\u062a\u062e\u062f\u0645. helpBrainfuckCommand=\u064a\u0646\u0641\u0630 \u0627\u0644\u062a\u0639\u0644\u064a\u0645\u0627\u062a \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0629 \u0628\u0631\u064a\u0646\u0641\u0648\u0643. \u0639\u0644\u0649 \u0633\u0628\u064a\u0644 \u0627\u0644\u0645\u062b\u0627\u0644\: -helpWeatherCommand=Display current weather by location. +helpWeatherCommand=\u0639\u0631\u0636 \u0627\u0644\u0637\u0642\u0635 \u0627\u0644\u062d\u0627\u0644\u064a \u0645\u0646 \u0645\u0648\u0642\u0639\u0643. helpClearCommand=\u062d\u0630\u0641 \u0643\u0627\u0641\u0629 \u0627\u0644\u0631\u0633\u0627\u0626\u0644 \u0628\u0647\u0630\u0627 \u0628\u0648\u062a \u0641\u064a \u0622\u062e\u0631 50 \u0631\u0633\u0627\u0626\u0644 \u0647\u0630\u0647 \u0627\u0644\u0642\u0646\u0627\u0629. helpCommandsCommand=\u062a\u0638\u0647\u0631 \u0627\u0644\u0623\u0648\u0627\u0645\u0631 \u0627\u0644\u0645\u062a\u0648\u0641\u0631\u0629. helpHelpCommand=\u0627\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u062a\u0639\u0644\u064a\u0645\u0627\u062a \u062d\u0648\u0644 \u0647\u0630\u0627 \u0628\u0648\u062a \u0623\u0648 \u0645\u0633\u0627\u0639\u062f\u0629 \u0644\u0623\u064a \u0623\u0645\u0631. @@ -257,16 +261,16 @@ helpSayCommand=\u062c\u0639\u0644 \u0628\u0648\u062a \u0635\u062f\u0649 \u0634\u helpServerInfoCommand=\u0639\u0631\u0636 \u0628\u0639\u0636 \u0627\u0644\u0625\u062d\u0635\u0627\u0626\u064a\u0627\u062a \u062d\u0648\u0644 \u0647\u0630\u0647 \u0627\u0644\u0646\u0642\u0627\u0628\u0629. helpUserInfoCommand=\u0639\u0631\u0636 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u062d\u0648\u0644 \u0646\u0641\u0633\u0643 \u0623\u0648 \u0645\u0633\u062a\u062e\u062f\u0645 \u0645\u0639\u0631\u0648\u0641 \u0627\u0644\u0628\u0648\u062a. helpPerms=\u0644\u0627\u0644\u0633\u0645\u0627\u062d \u0644\u0623\u0639\u0636\u0627\u0621 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0628\u064a\u0636\u0627\u0621 \u0648\u0627\u0644\u0623\u062f\u0648\u0627\u0631 \u0644\u0631\u062a\u0628\u0629 {0}. -helpPrefixCommand=Set the prefix for this guild. -helpVoteSkip=Vote to skip the current song. Needs 50% of all users in the voice chat to vote. -helpMathOperationAdd=Print the sum of num1 and num2. -helpMathOperationSub=Print the difference of subtracting num2 from num1. -helpMathOperationMult=Print the product of num1*num2. -helpMathOperationDiv=Print the quotient of dividing num1 by num2. -helpMathOperationMod=Print the remainder of dividing num1 by num2. -helpMathOperationPerc=Print the percentage represented by num1 in num2. -helpMathOperationSqrt=Print the square root of num. -helpMathOperationPow=Print the result of num1^num2. +helpPrefixCommand=\u0642\u0645 \u0628\u062a\u0639\u064a\u064a\u0646 \u0627\u0644\u0628\u0627\u062f\u0626\u0629 \u0644\u0647\u0630\u0647 \u0627\u0644\u0646\u0642\u0627\u0628\u0629. +helpVoteSkip=\u0627\u0644\u062a\u0635\u0648\u064a\u062a \u0644\u062a\u062e\u0637\u064a \u0627\u0644\u0623\u063a\u0646\u064a\u0629 \u0627\u0644\u062d\u0627\u0644\u064a\u0629. \u064a\u062d\u062a\u0627\u062c \u0625\u0644\u0649 50 \u0641\u064a \u0627\u0644\u0645\u0627\u0626\u0629 \u0645\u0646 \u0643\u0627\u0641\u0629 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646 \u0641\u064a \u0627\u0644\u0645\u062d\u0627\u062f\u062b\u0629 \u0627\u0644\u0635\u0648\u062a\u064a\u0629 \u0627\u0644\u062a\u0635\u0648\u064a\u062a. +helpMathOperationAdd=\u0627\u0637\u0628\u0639 \u0645\u062c\u0645\u0648\u0639 num1 \u0648 num2. +helpMathOperationSub=\u0627\u0637\u0628\u0639 \u0627\u0644\u0641\u0631\u0642 \u0645\u0646 \u0637\u0631\u062d num2 \u0645\u0646 num1. +helpMathOperationMult=\u0627\u0637\u0628\u0639 \u0627\u0644\u0636\u0631\u0628 num1 * num2. +helpMathOperationDiv=\u0627\u0637\u0628\u0639 \u062d\u0627\u0635\u0644 \u0642\u0633\u0645\u0629 num1 / num2. +helpMathOperationMod=\u0627\u0637\u0628\u0639 \u0645\u0627 \u062a\u0628\u0642\u0649 \u0645\u0646 \u0642\u0633\u0645\u0629 num1 / num2. +helpMathOperationPerc=\u0627\u0637\u0628\u0639 \u0627\u0644\u0646\u0633\u0628\u0629 \u0627\u0644\u0645\u0626\u0648\u064a\u0629 \u0627\u0644\u062a\u064a \u064a\u0645\u062b\u0644\u0647\u0627 num1 \u0641\u064a num2. +helpMathOperationSqrt=\u0637\u0628\u0627\u0639\u0629 \u0627\u0644\u062c\u0630\u0631 \u0627\u0644\u062a\u0631\u0628\u064a\u0639\u064a \u0644num. +helpMathOperationPow=\u0627\u0637\u0628\u0639 \u0646\u062a\u064a\u062c\u0629 num1 \u0645\u0631\u0641\u0648\u0639 \u0628 num2. \u0627\u0648 num1^num2. destroyDenied=\u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0644\u062f\u064a\u0643 \u0627\u0644\u0625\u0630\u0646 \u0631\u0633\u0627\u0626\u0644 \u0625\u062f\u0627\u0631\u0629 \u0644\u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0644\u0627\u0639\u0628. destroyHelp=\u0625\u0639\u0627\u062f\u0629 \u062a\u0639\u064a\u064a\u0646 \u0627\u0644\u0644\u0627\u0639\u0628 \u0648\u0645\u0633\u062d \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062a\u0634\u063a\u064a\u0644. \u0645\u062d\u0641\u0648\u0638\u0629 \u0644\u0644\u0645\u0634\u0631\u0641\u064a\u0646 \u0645\u0639 "\u0625\u062f\u0627\u0631\u0629 \u0631\u0633\u0627\u0626\u0644" \u0627\u0644\u0625\u0630\u0646. destroySucc=\u0625\u0639\u0627\u062f\u0629 \u062a\u0639\u064a\u064a\u0646 \u0627\u0644\u0644\u0627\u0639\u0628 \u0648\u0645\u0633\u062d \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631. @@ -275,27 +279,27 @@ permsListTitle=\u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646 \u06 permsAdded=\u0648\u0623\u0636\u0627\u0641 ''{0}'' \u0625\u0644\u0649 ''{1}''. permsRemoved=\u0625\u0632\u0627\u0644\u0629 ''{0}'' \u0645\u0646 ''{1}''. permsFailSelfDemotion=\u0644\u0627 \u064a\u0645\u0643\u0646\u0643 \u0625\u0632\u0627\u0644\u0629 \u0647\u0630\u0627 \u0643\u0645\u0627 \u0623\u0646\u0647 \u0633\u064a\u062c\u0639\u0644 \u0644\u0643 \u062f\u0648\u0646 \u0623\u0630\u0648\u0646\u0627\u062a \u0627\u0644\u0645\u0633\u0624\u0648\u0644\! -permsAlreadyAdded={0} already added to {1} -permsNotAdded={0} is not in {1} +permsAlreadyAdded=\u062a\u0645\u062a \u0627\u0644\u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0649 +permsNotAdded=\u0644\u064a\u0633\u062a \u0641\u064a fuzzyMultiple=\u062a\u0645 \u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 \u0639\u0646\u0627\u0635\u0631 \u0645\u062a\u0639\u062f\u062f\u0629. \u0647\u0644 \u062a\u0642\u0635\u062f \u0623\u064a \u0645\u0646 \u0647\u0630\u0647\u061f fuzzyNothingFound=\u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 \u0623\u064a \u0634\u064a\u0621 \u0639\u0646 ''{0}''. cmdPermsTooLow=\u0644\u064a\u0633 \u0644\u062f\u064a\u0643 \u0627\u0644\u0625\u0630\u0646 \u0644\u062a\u0634\u063a\u064a\u0644 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631\! \u0648\u064a\u062a\u0637\u0644\u0628 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631 ''{0}'' \u0648\u0644\u0643\u0646 \u0644\u062f\u064a\u0643 \u0641\u0642\u0637 ''{1}''. playersLimited=\u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a \u062d\u0627\u0644\u064a\u0627 \u0628\u0623\u0642\u0635\u0649 \u0637\u0627\u0642\u062a\u0647\u0627\! \u064a\u062a\u0645 \u062d\u0627\u0644\u064a\u0627 \u0625\u0635\u0644\u0627\u062d \u0627\u0644\u0628\u0648\u062a \u0644\u0644\u0639\u0628 \u0641\u0642\u0637 \u0644\u062a\u064a\u0627\u0631\u0627\u062a ''{0}''\u060c \u0648\u0625\u0644\u0627 \u0633\u0648\u0641 \u0646\u062e\u0627\u0637\u0631 \u0628\u0642\u0637\u0639 \u0627\u0644\u0634\u0642\u0627\u0642 \u062a\u062d\u062a \u062a\u062d\u0645\u064a\u0644 \u0627\u0644\u0634\u0628\u0643\u0629. \u0625\u0630\u0627 \u0623\u0631\u062f\u062a \u0623\u0646 \u062a\u0633\u0627\u0639\u062f\u0646\u0627 \u0639\u0644\u0649 \u0632\u064a\u0627\u062f\u0629 \u0627\u0644\u062d\u062f \u0623\u0648 \u062a\u0631\u064a\u062f \u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0644\u062f\u064a\u0646\u0627 \u0628\u0648\u062a \u063a\u064a\u0631 \u0645\u0643\u062a\u0638\u0629\u060c \u064a\u0631\u062c\u0649 \u062f\u0639\u0645 \u0639\u0645\u0644\u0646\u0627 \u0641\u064a \u0628\u062a\u0631\u0648\u0646\:{1} \u0639\u0630\u0631\u0627\u064b \u0644\u0644\u0625\u0632\u0639\u0627\u062c\! \u0642\u062f \u062a\u0631\u063a\u0628 \u0641\u064a \u0627\u0644\u0645\u062d\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062e\u0631\u0649 \u0644\u0627\u062d\u0642\u0627\u064b. \u0648\u0639\u0627\u062f\u0629 \u0645\u0627 \u062a\u0638\u0647\u0631 \u0647\u0630\u0647 \u0627\u0644\u0631\u0633\u0627\u0644\u0629 \u0641\u0642\u0637 \u0641\u064a \u0648\u0642\u062a \u0627\u0644\u0630\u0631\u0648\u0629. -tryLater=Please try again later. -skipUserSingle=Skipped {0} added by {1}. -skipUserMultiple=Skipped {0} tracks added by {1}. -skipUsersMultiple=Skipped {0} tracks added by {1} users. -skipUserNoTracks=None of the mentioned users have any tracks queued. -voteSkipAdded=Your vote has been added\! -voteSkipAlreadyVoted=You already voted to skip this track\! -voteSkipSkipping={0} have voted to skip. Skipping track {1}. -voteSkipNotEnough={0} have voted to skip. At least {1} needed. -voteSkipEmbedNoVotes=No votes to skip this track yet. -voteSkipEmbedVoters={0} out of {1} have voted to skip the current track -mathOperationResult=The result is -mathOperationDivisionByZeroError=I cannot divide by zero. -mathOperationInfinity=The number is too big to be displayed\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +tryLater=\u064a\u0631\u062c\u0649 \u0627\u0644\u0645\u062d\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062e\u0631\u0649 \u0644\u0627\u062d\u0642\u0627. +skipUserSingle=\u062a\u0645 \u062a\u062e\u0637 0 \u062a\u0645\u062a \u0625\u0636\u0627\u0641\u062a\u0647 \u0628\u0648\u0627\u0633\u0637\u0629 1. +skipUserMultiple=\u062a\u0645 \u062a\u062e\u0637\u064a 0 \u0645\u0633\u0627\u0631 \u062a\u0645\u062a \u0625\u0636\u0627\u0641\u062a\u0647 \u0628\u0648\u0627\u0633\u0637\u0629 1. +skipUsersMultiple=\u062a\u0645 \u062a\u062e\u0637\u064a 0 \u0645\u0633\u0627\u0631 \u062a\u0645\u062a \u0625\u0636\u0627\u0641\u062a\u0647 \u0628\u0648\u0627\u0633\u0637\u0629 1 \u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646. +skipUserNoTracks=\u0644\u064a\u0633 \u0644\u062f\u0649 \u0623\u064a \u0645\u0646 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646 \u0627\u0644\u0645\u0630\u0643\u0648\u0631\u064a\u0646 \u0623\u064a \u0645\u0633\u0627\u0631\u0627\u062a \u0641\u064a \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631. +voteSkipAdded=\u062a\u0645\u062a \u0625\u0636\u0627\u0641\u0629 \u062a\u0635\u0648\u064a\u062a\u0643\! +voteSkipAlreadyVoted=\u0644\u0642\u062f \u0635\u0648\u062a\u062a \u0628\u0627\u0644\u0641\u0639\u0644 \u0644\u062a\u062e\u0637\u064a \u0647\u0630\u0627 \u0627\u0644\u0645\u0633\u0627\u0631\! +voteSkipSkipping={0} \u0635\u0648\u062a\u0648\u0627 \u0644\u0644\u062a\u062e\u0637\u064a. \u062a\u062e\u0637\u064a \u0627\u0644\u0645\u0633\u0627\u0631 {1}. +voteSkipNotEnough={0} \u0635\u0648\u062a\u0648\u0627 \u0644\u0644\u062a\u062e\u0637\u064a. \u062a\u062d\u062a\u0627\u062c {1} \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644. +voteSkipEmbedNoVotes=\u0644\u0627 \u062a\u0648\u062c\u062f \u0627\u0635\u0648\u0627\u062a \u0644\u062a\u062e\u0637\u064a \u0647\u0630\u0627 \u0627\u0644\u0645\u0633\u0627\u0631 \u0628\u0639\u062f. +voteSkipEmbedVoters={0} \u0645\u0646 {1} \u0635\u0648\u062a\u0648\u0627 \u0644\u062a\u062e\u0637\u064a \u0627\u0644\u0645\u0633\u0627\u0631 \u0627\u0644\u062d\u0627\u0644\u064a +mathOperationResult=\u0648\u0627\u0644\u0646\u062a\u064a\u062c\u0629 \u0647\u064a +mathOperationDivisionByZeroError=\u0644\u0627 \u0627\u0633\u062a\u0637\u064a\u0639 \u0627\u0644\u0642\u0633\u0645\u0629 \u0639\u0644\u0649 \u0635\u0641\u0631. +mathOperationInfinity=\u0627\u0644\u0631\u0642\u0645 \u0643\u0628\u064a\u0631 \u062c\u062f\u0627 \u0644\u064a\u062a\u0645 \u0639\u0631\u0636\u0647\! +prefix=\u0627\u0644\u0628\u0627\u062f\u0626\u0629 +prefixGuild=\u0627\u0644\u0628\u0627\u062f\u0626\u0629 \u0644\u0647\u0630\u0647 \u0627\u0644\u0646\u0642\u0627\u0628\u0629 \u0647\u064a {0} +prefixShowAgain=\u064a\u0645\u0643\u0646\u0643 \u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0628\u0627\u062f\u0626\u0629 \u0641\u064a \u0623\u064a \u0648\u0642\u062a \u0645\u0631\u0629 \u0623\u062e\u0631\u0649 \u0645\u0646 \u062e\u0644\u0627\u0644 \u0630\u0643\u0631 \u0644\u064a. diff --git a/FredBoat/src/main/resources/lang/bg_BG.properties b/FredBoat/src/main/resources/lang/bg_BG.properties index 8be48b3ed..33cd5e1df 100644 --- a/FredBoat/src/main/resources/lang/bg_BG.properties +++ b/FredBoat/src/main/resources/lang/bg_BG.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u0412\u0438\u0435 \u0441\u0442\u0435 \u043e\u0433\u0440\ ratelimitedSkipCommand=\u041c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u043f\u0440\u043e\u043f\u0443\u0441\u043d\u0435\u0442\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u043e\u0442 \u0435\u0434\u043d\u0430 \u043f\u0435\u0441\u0435\u043d \u0441 \u0442\u0430\u0437\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\: {0} ratelimitedGuildSlowLoadingPlaylist=\u0422\u043e\u0437\u0438 \u0441\u044a\u0440\u0432\u044a\u0440 \u043d\u0435 \u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d \u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u044f \u043f\u043e\u0432\u0435\u0447\u0435 playlists \u0432 \u0442\u043e\u0437\u0438 \u043c\u043e\u043c\u0435\u043d\u0442. \u041c\u043e\u043b\u044f \u043d\u0435 \u0441\u043f\u0430\u043c\u0435\u0442\u0435 \u0434\u044a\u043b\u0433\u0438 playlists. unblacklisted=\u041f\u0440\u0435\u043c\u0430\u0445\u043d\u0430\u0442 {0} \u043e\u0442 \u0447\u0435\u0440\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u044a\u043a. -serverinfoTitle=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u041e\u043d\u043b\u0430\u0439\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\: serverinfoTotalUsers=\u041e\u0431\u0449\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\: serverinfoRoles=\u0420\u043e\u043b\u0438\: @@ -193,7 +193,7 @@ serverinfoGuildID=\u0413\u0438\u043b\u0434\u0438\u044f\u0442\u0430 \u0418\u0414\ serverinfoCreationDate=\u0414\u0430\u0442\u0430 \u043d\u0430 \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435\: serverinfoOwner=\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u0438\u043a\: serverinfoVLv=\u041a\u043e\u0434 \u0437\u0430 \u043f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0430\u0432\u0430\u043d\u0435\: -userinfoTitle=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e \u0438\u043c\u0435\: userinfoId=ID\: userinfoNick=\u041f\u0440\u044f\u043a\u043e\u0440\: @@ -212,7 +212,11 @@ commandsMaintenance=\u0422\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0430 commandsBotOwner=\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u0438\u043a \u043d\u0430 \u0431\u043e\u0442\u0430 commandsMoreHelp=\u041a\u0430\u0436\u0430 {0} \u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent={0}\: \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0435 \u0438\u0437\u043f\u0440\u0430\u0442\u0435\u043d\u0430 \u0434\u043e \u0432\u0430\u0448\u0438\u0442\u0435 \u043b\u0438\u0447\u043d\u0438 \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u044f\! helpProperUsage=\u041f\u0440\u0430\u0432\u0438\u043b\u043d\u043e\u0442\u043e \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435\: helpCommandOwnerRestricted=\u0422\u0430\u0437\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0441\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0430\u0432\u0430 \u0434\u043e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u0438\u043a\u0430 \u043d\u0430 \u0431\u043e\u0442\u0430. diff --git a/FredBoat/src/main/resources/lang/ca_ES.properties b/FredBoat/src/main/resources/lang/ca_ES.properties index 4de1033a1..a437e2251 100644 --- a/FredBoat/src/main/resources/lang/ca_ES.properties +++ b/FredBoat/src/main/resources/lang/ca_ES.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Informaci\u00f3 sobre ''{0}''\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Usuaris en l\u00ednia\: serverinfoTotalUsers=Usuaris totals serverinfoRoles=Rols\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Data de Creaci\u00f3\: serverinfoOwner=Propietari\: serverinfoVLv=Verification Level\: -userinfoTitle=Informaci\u00f3 sobre ''{0}''\: +userinfoTitle=Information about {0}\: userinfoUsername=Nom d'usuari/a\: userinfoId=ID\: userinfoNick=\u00c0lies\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/cs_CZ.properties b/FredBoat/src/main/resources/lang/cs_CZ.properties index 7504fa382..66167e045 100644 --- a/FredBoat/src/main/resources/lang/cs_CZ.properties +++ b/FredBoat/src/main/resources/lang/cs_CZ.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Informace o **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online u\u017eivatel\u016f\: serverinfoTotalUsers=Celkem u\u017eivatel\u016f\: serverinfoRoles=Role\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Datum vytvo\u0159en\u00ed\: serverinfoOwner=Vlastn\u00edk\: serverinfoVLv=Verification Level\: -userinfoTitle=Informace o **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=U\u017eivatelsk\u00e9 jm\u00e9no\: userinfoId=ID\: userinfoNick=P\u0159ezd\u00edvka\: @@ -212,7 +212,11 @@ commandsMaintenance=\u00dadr\u017eba commandsBotOwner=Vlastn\u00edk bota commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Nezn\u00e1m\u00fd p\u0159\u00edkaz. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Spr\u00e1vn\u00e9 pou\u017eit\u00ed\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/cy_GB.properties b/FredBoat/src/main/resources/lang/cy_GB.properties index 1d9a22deb..eff733512 100644 --- a/FredBoat/src/main/resources/lang/cy_GB.properties +++ b/FredBoat/src/main/resources/lang/cy_GB.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Yr ydych yn gyfradd cyfyngedig\! Os gwelwch yn dda yn ara ratelimitedSkipCommand=Gall anwybyddu''r mwy nag un g\u00e2n gan ddefnyddio Gorchymyn hwn\: {0} ratelimitedGuildSlowLoadingPlaylist=Ni chaiff y gweinydd hwn i ychwanegu rhestri chwarae mwy ar hyn o bryd. Os gwelwch yn dda Peidiwch \u00e2 sbam rhestri chwarae hir. unblacklisted={0} wedi ei dynnu oddi wrth y chynaliadwy. -serverinfoTitle=Gwybodaeth am **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Defnyddwyr ar-lein\: serverinfoTotalUsers=Cyfanswm defnyddwyr\: serverinfoRoles=Swyddogaethau\: @@ -193,7 +193,7 @@ serverinfoGuildID=Urdd ID\: serverinfoCreationDate=Dyddiad creu\: serverinfoOwner=Perchennog\: serverinfoVLv=Gwirio lefel\: -userinfoTitle=Gwybodaeth am **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=Enw defnyddiwr\: userinfoId=ID\: userinfoNick=Llysenw\: @@ -212,7 +212,11 @@ commandsMaintenance=Cynnal commandsBotOwner=Perchennog bot commandsMoreHelp=Dweud {0} i gael rhagor o wybodaeth ar Gorchymyn penodol. helpUnknownCommand=Gorchymyn anhysbys. -helpDM=Gellir dod o hyd i ddogfennau yn\:\nhttps\://fredboat.com/docs\n\nYdych chi eisiau ychwanegu FredBoat at eich gweinydd? Os oes gennych ganiat\u00e2d Rheoli Gweinyddwr ar gyfer eich urdd, gallwch ei wahodd yma\:\n* Nid yw hyn yn chwarae cerddoriaeth *\n\n\nOs ydych chi am ychwanegu''r bot cerddoriaeth, byddwch am wahodd y bot hwn\:\n\n\nAngen help neu a oes gennych unrhyw syniadau ar gyfer y bot? Efallai eich bod chi eisiau hongian allan? Dewch draw i FredBoat hangout\!\n{0}\n\nNi allwch chi anfon y gorchmynion bot yma trwy DM.\nBot wedi''i greu gan Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Mae dogfennaeth wedi'i anfon at eich negeseuon uniongyrchol\! helpProperUsage=Defnydd priodol\: helpCommandOwnerRestricted=Gorchymyn hwn wedi'i gyfyngu i berchennog y bot. diff --git a/FredBoat/src/main/resources/lang/da_DK.properties b/FredBoat/src/main/resources/lang/da_DK.properties index 616da3de4..fdc5db773 100644 --- a/FredBoat/src/main/resources/lang/da_DK.properties +++ b/FredBoat/src/main/resources/lang/da_DK.properties @@ -45,7 +45,7 @@ exportPlaylistFail=Fejlede at uploade playlist til hastebin.com listShowShuffled=Viser blandet playlist.\n\n listShowRepeatSingle=Gentager aktuelle sang. listShowRepeatAll=Gentager nuv\u00e6rende k\u00f8. -listShowHistory=Showing tracks in history. +listShowHistory=Viser spor i historien. listAddedBy=**{0} ** tilf\u00f8jet af **{1} ** ''[{2}]'' listStreamsOnlySingle=Der er **{0}** live {1} i k\u00f8en. listStreamsOnlyMultiple=Der er **{0}** live {1} i k\u00f8en. @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=, s\u00e5 vel som **{0}** live {1} trackSingular=track trackPlural=tracks npNotPlaying=Spiller i \u00f8jeblikket ikke noget. -npNotInHistory=Currently no tracks in history. +npNotInHistory=I \u00f8jeblikket ingen spor i historien. npDescription=Beskrivelse npLoadedSoundcloud=[{0}/{1}]\nIndl\u00e6st fra Soundcloud npLoadedBandcamp={0}\n\nIndl\u00e6st fra Bandcamp @@ -79,7 +79,7 @@ restartSuccess=**{0}** er blevet genstartet. queueEmpty=K\u00f8en er tom. rewSuccess=Tilbagespoler **{0}** med {1}. seekSuccess=Spoler **{0}** til {1}. -seekDeniedLiveTrack=You can't seek a live track. +seekDeniedLiveTrack=Du kan ikke s\u00f8ge et live spor. loadPlaySplitListFail=Dette link f\u00f8rer til en afspilningsliste, ikke et spor. Pr\u00f8v `;;play` i stedet. loadListSuccess=Fandt og tilf\u00f8jede ''{0}'' sange fra playlisten **{1} **. loadNoMatches=Ingen lyd kunne findes for ''{0}''. @@ -125,15 +125,15 @@ luaError=\ Opstod en fejl i Lua \:anger\: ''''''{0} '''''' luaErrorOutputTooBig=\ Outputbuffer er for stor \:anger\: Discord tillader kun 2000 tegn pr. besked, fik {0} luaTimeout=\ Funktionen timeout \:anger\: tilladt computation tid er {0} sekunder. helpSuccess=Dokumentation er blevet sendt til dine direkte meddelelser\! -helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! +helpDmFailed=Kunne ikke sende dokumentationen til DMs. Kontroller, at du ikke har deaktiveret dem\! helpCommandsPromotion=Sig {0} for at f\u00e5 at vide hvad denne bot kan g\u00f8re\! fuzzyNoResults=Ingen s\u00e5danne brugere brainfuckCycleLimit=Programet overskrev det maksimale antal cyklusser af {0} brainfuckDataPointerOutOfBounds=Data pointer out of bounds\: {0} brainfuckInputOOB=Input out of bounds p\u00e5 position\: {0} brainfuckNoOutput=\ Der var ingen output -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} +weatherLocationNotFound=Kan ikke finde lokation, tjek venligst dit input {0}. +weatherError=Fejl under hentning af vejret for {0} avatarSuccess=\ fandt den\n{0} configNoArgs=Konfiguration for **{0} **\:'''' '' configSetTo=er nu sat til ''{0}''. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Du bliver bredb\u00e5nds begr\u00e6nset\! S\u00e6t venlig ratelimitedSkipCommand=Du kan springe over flere sange ved hj\u00e6lp af kommandoen\: {0} ratelimitedGuildSlowLoadingPlaylist=Denne server har ikke tilladelse til at tilf\u00f8je flere spillelister p\u00e5 dette tidspunkt. Venligst, ikke spam lange spillelister. unblacklisted=Fjernede {0} fra blacklist. -serverinfoTitle=Info om **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online brugere\: serverinfoTotalUsers=Antal brugere\: serverinfoRoles=Roller\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Oprettelsesdato\: serverinfoOwner=Ejer\: serverinfoVLv=Verifikation niveau\: -userinfoTitle=Oplysninger om **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=Brugernavn\: userinfoId=ID\: userinfoNick=Kaldenavn\: @@ -201,9 +201,9 @@ userinfoKnownServer=Kendte servere\: userinfoJoinDate=Join dato\: userinfoCreationTime=Oprettelsesdato\: userinfoBlacklisted=sortlisted"\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +skipDeniedTooManyTracks=Du kan ikke springe en andens spor, hvis du ikke er en DJ. Overvej at bruge kommandoen Voteskip. eventUsersLeftVC=Alle brugere har forladt tale kanalen. Musikken er midlertidigt afbrudt. -eventAutoResumed=User presence detected, automatically resuming the player. +eventAutoResumed=Bruger tilstedev\u00e6relse opdaget, automatisk genoptagelse. commandsFun=Sjov commandsMemes=Memes commandsUtility=Nytte @@ -212,7 +212,11 @@ commandsMaintenance=Vedligeholdelse commandsBotOwner=Bot ejeren commandsMoreHelp=Sig {0} for at f\u00e5 flere oplysninger om en bestemt kommando. helpUnknownCommand=Ukendt kommando. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Dokumentation er blevet sendt til dine DMs\! helpProperUsage=Korrekt anvendelse\: helpCommandOwnerRestricted=Denne kommando er begr\u00e6nset til ejeren af botten. @@ -225,28 +229,28 @@ helpMusicCommandsHeader=FredBoat musik kommandoer helpJoinCommand=F\u00e5 botten til at joine din tale kanal. helpLeaveCommand=F\u00e5 botten til at leave din tale kanal. helpPauseCommand=Pause musikken. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=Afspil musik fra den givne URL eller S\u00f8g efter et spor. For en komplet liste over kilder kan du bes\u00f8ge {0} helpPlaySplitCommand=Opdele en YouTube-video i en playliste i sin beskrivelse. helpRepeatCommand=Skift mellem gentagelsesfunktioner. helpReshuffleCommand=Shuffle nuv\u00e6rende k\u00f8en. helpSelectCommand=V\u00e6lg en af de tilbudte sange efter en s\u00f8gning for at spille. helpShuffleCommand=Skift shuffle tilstand for den aktuelle k\u00f8. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpSkipCommand=Springe den aktuelle sang, n'th sang i k\u00f8en, alle sange fra n til m eller alle sange fra n\u00e6vnte brugere. Brug i moderation. helpStopCommand=Stop spilleren og fjern afspilningslisten. Forbeholdt redakt\u00f8rer med Administrer meddelelser om tilladelse. helpUnpauseCommand=Genoptag spilleren. helpVolumeCommand=\u00c6ndr lydstyrken. V\u00e6rdierne er 0-150 og 100 er standard. Kommandoen volumen frar\u00e5des p\u00e5 det offentlige bot. helpExportCommand=Eksportere den aktuelle k\u00f8 til en hastebin link, kan bruges senere som en afspilningsliste. helpGensokyoRadioCommand=Vis den aktuelle sang spillet p\u00e5 gensokyoradio.net helpListCommand=F\u00e5 vist en liste over de aktuelle sange i afspilningslisten. -helpHistoryCommand=Display a list of the songs in playlist history. +helpHistoryCommand=Vis en liste over sangene i afspilningslisten historie. helpNowplayingCommand=F\u00e5 vist den sang, der aktuelt afspilles. helpForwardCommand=Fremad banen af en given m\u00e6ngde tid. Eksempel\: helpRestartCommand=Genstart den aktuelle sang. helpRewindCommand=Spol frem i sangen med en given m\u00e6ngde tid. Eksempel\: -helpSeekCommand=Set the position of the track to the given time. Example\: +helpSeekCommand=Angiv placeringen af sporet til den givne tid. Eksempel\: helpAvatarCommand=Vis en brugers avatar. helpBrainfuckCommand=Udf\u00f8rer Brainfuck kode. Eksempel\: -helpWeatherCommand=Display current weather by location. +helpWeatherCommand=F\u00e5 vist aktuelt vejr ved placering. helpClearCommand=Slet bottens seneste 50 beskeder i denne kanal. helpCommandsCommand=Vis tilg\u00e6ngelige kommandoer. helpHelpCommand=Modtag hj\u00e6lp til denne bot eller hj\u00e6lp til en kommando. @@ -256,46 +260,46 @@ helpMusicHelpCommand=Vis kommandoer til musik og deres anvendelse. helpSayCommand=F\u00e5 botten til at gentage noget. helpServerInfoCommand=F\u00e5 vist nogle stats om denne guild. helpUserInfoCommand=Vis oplysninger om dig selv eller en bruger, der er kendt til botten. -helpPerms=Allows whitelisting members and roles for the {0} rank. -helpPrefixCommand=Set the prefix for this guild. -helpVoteSkip=Vote to skip the current song. Needs 50% of all users in the voice chat to vote. -helpMathOperationAdd=Print the sum of num1 and num2. -helpMathOperationSub=Print the difference of subtracting num2 from num1. -helpMathOperationMult=Print the product of num1*num2. -helpMathOperationDiv=Print the quotient of dividing num1 by num2. -helpMathOperationMod=Print the remainder of dividing num1 by num2. -helpMathOperationPerc=Print the percentage represented by num1 in num2. -helpMathOperationSqrt=Print the square root of num. -helpMathOperationPow=Print the result of num1^num2. -destroyDenied=You must have the manage messages permission to reset the player. -destroyHelp=Reset the player and clear the playlist. Reserved for moderators with Manage Messages permission. -destroySucc=Reset the player and cleared the queue. -listPageNum=Page **{0}** of **{1}**. -permsListTitle=Users and roles with the {0} permissions -permsAdded=Added `{0}` to `{1}`. -permsRemoved=Removed `{0}` from `{1}`. -permsFailSelfDemotion=You cannot remove this as it would render you without admin permissions\! -permsAlreadyAdded={0} already added to {1} -permsNotAdded={0} is not in {1} -fuzzyMultiple=Multiple items were found. Did you mean any of these? -fuzzyNothingFound=Nothing found for `{0}`. -cmdPermsTooLow=You don''t have permission to run this command\! This command requires `{0}` but you only have `{1}`. -playersLimited=FredBoat is currently at maximum capacity\! The bot is currently fixed to only play up to `{0}` streams, otherwise we would risk disconnecting from Discord under the network load.\nIf you want to help us increase the limit or you want to use our non-overcrowded bot, please support our work on Patreon\:\n{1}\n\nSorry for the inconvenience\! You might want to try again later. This message usually only appears at peak time. -tryLater=Please try again later. -skipUserSingle=Skipped {0} added by {1}. -skipUserMultiple=Skipped {0} tracks added by {1}. -skipUsersMultiple=Skipped {0} tracks added by {1} users. -skipUserNoTracks=None of the mentioned users have any tracks queued. +helpPerms=Tillader whitelisting medlemmer og roller for {0} rang. +helpPrefixCommand=Angiv pr\u00e6fiks for denne guild. +helpVoteSkip=Stem for at springe den aktuelle sang over. Har brug for 50% af alle brugere i tale-chat til at stemme. +helpMathOperationAdd=Udskriv summen af num1 og num2. +helpMathOperationSub=Udskriv forskellen p\u00e5 at fratr\u00e6kke num2 fra num1. +helpMathOperationMult=Udskriv produktet af num1 * num2. +helpMathOperationDiv=Udskriv kvotienten af at dividere num1 med num2. +helpMathOperationMod=Udskriv resten fra at dividere num1 med num2. +helpMathOperationPerc=Udskriv den procentdel, der er repr\u00e6senteret ved num1 i num2. +helpMathOperationSqrt=Udskriv kvadratroden af num. +helpMathOperationPow=Udskriv resultatet af num1 ^ num2. +destroyDenied=Du skal have tilladelsen administrer beskeder for at nulstille afspilleren. +destroyHelp=Nulstil afspilleren og fjern p\u00e5 afspilningslisten. Forbeholdt redakt\u00f8rer med Administrer meddelelsers tilladelse. +destroySucc=Nulstillede afspilleren og ryddede k\u00f8en. +listPageNum=Side **{0} ** af **{1} **. +permsListTitle=Brugere og roller med {0} tilladelser +permsAdded=Tilf\u00f8jet ''{0}'' til ''{1}''. +permsRemoved=Fjernede ''{0}'' fra ''{1}''. +permsFailSelfDemotion=Du kan ikke fjerne dette, da det ville g\u00f8re dig uden admin-tilladelser\! +permsAlreadyAdded={0} allerede f\u00f8jet til {1} +permsNotAdded={0} er ikke i {1} +fuzzyMultiple=Der blev fundet flere elementer. Mente du nogen af disse? +fuzzyNothingFound=Intet fundet for ''{0}''. +cmdPermsTooLow=Du har ikke tilladelse til at k\u00f8re denne kommando\! Denne kommando kr\u00e6ver ''{0}'' men du kun har ''{1}''. +playersLimited=FredBoat er i \u00f8jeblikket p\u00e5 maksimal kapacitet\! Botten er i \u00f8jeblikket fastsat til at kun spille til \u00ab{0}\u00bb streams, ellers ville vi risikerer frakobling fra Discord under netv\u00e6rksbelastning. Hvis du \u00f8nsker at hj\u00e6lpe os med at \u00f8ge gr\u00e6nsen eller du \u00f8nsker at bruge vores ikke-overfyldte bot, st\u00f8t vores arbejde p\u00e5 Patreon\:\n{1} \nBeklager ulejligheden\! Du kan pr\u00f8ve igen senere. Denne besked vises normalt kun i spidsbelastningen. +tryLater=Pr\u00f8v venligst igen senere. +skipUserSingle=Oversprunget {0} tilf\u00f8jet af {1}. +skipUserMultiple=Oversprunget {0} spor, tilf\u00f8jet af {1}. +skipUsersMultiple=Oversprunget {0} spor, tilf\u00f8jet af {1} brugere. +skipUserNoTracks=Ingen af de n\u00e6vnte brugere har nogen spor i k\u00f8. voteSkipAdded=Dit valg er tilf\u00f8jet\! -voteSkipAlreadyVoted=You already voted to skip this track\! -voteSkipSkipping={0} have voted to skip. Skipping track {1}. -voteSkipNotEnough={0} have voted to skip. At least {1} needed. -voteSkipEmbedNoVotes=No votes to skip this track yet. -voteSkipEmbedVoters={0} out of {1} have voted to skip the current track -mathOperationResult=The result is -mathOperationDivisionByZeroError=I cannot divide by zero. -mathOperationInfinity=The number is too big to be displayed\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +voteSkipAlreadyVoted=Du har allerede stemt for at springe dette spor over\! +voteSkipSkipping={0} har stemt for at springe. Spring spor {1}. +voteSkipNotEnough={0} har stemt for at springe. Mindst {1} behov. +voteSkipEmbedNoVotes=Ingen stemmer for at springe dette spor over endnu. +voteSkipEmbedVoters={0} ud af {1} har stemt at overspringe det aktuelle spor +mathOperationResult=Resultatet er +mathOperationDivisionByZeroError=Jeg kan ikke dividere med nul. +mathOperationInfinity=Antallet er for stort til at blive vist\! +prefix=Pr\u00e6fiks +prefixGuild=Pr\u00e6fikset for denne guild er {0} +prefixShowAgain=Du kan vise pr\u00e6fikset igen til en hver tid ved at n\u00e6vne mig. diff --git a/FredBoat/src/main/resources/lang/de_DE.properties b/FredBoat/src/main/resources/lang/de_DE.properties index f57800d96..ab251ffe9 100644 --- a/FredBoat/src/main/resources/lang/de_DE.properties +++ b/FredBoat/src/main/resources/lang/de_DE.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Du benutzt diesen Command zu schnell\! Bitte warte einen ratelimitedSkipCommand=Du kannst mehr als einen Titel mit diesem Befehl \u00fcberspringen\: {0} ratelimitedGuildSlowLoadingPlaylist=Diesem Server ist es zur Zeit nicht mehr gestattet, weitere Playlists zu laden. Bitte spamme keine langen Playlists. unblacklisted={0} wurde von der Blacklist entfernt. -serverinfoTitle=Informationen \u00fcber **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Nutzer online\: serverinfoTotalUsers=Nutzer gesamt\: serverinfoRoles=Rollen\: @@ -193,7 +193,7 @@ serverinfoGuildID=Gilden-ID\: serverinfoCreationDate=Erstellungsdatum\: serverinfoOwner=Eigent\u00fcmer\: serverinfoVLv=Verifizierungslevel\: -userinfoTitle=Informationen \u00fcber **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Benutzername\: userinfoId=ID\: userinfoNick=Spitzname\: @@ -212,7 +212,11 @@ commandsMaintenance=Wartung commandsBotOwner=Boteigent\u00fcmer commandsMoreHelp=Sag {0}, um mehr Informationen zu einem bestimmten Befehl zu erhalten. helpUnknownCommand=Unbekannter Befehl. -helpDM=Dokumentationen findest du auf\: https\://fredboat.com/docs\n\nM\u00f6chtest du FredBoat zu deinem Server hinzuf\u00fcgen? Wenn du die Berechtigung zum Verwalten des Servers hast, kannst du FredBoat von hier aus hinzuf\u00fcgen\:\n*Dieser spielt keine Musik*\n\n\nWenn du jedoch den Musik Bot hinzuf\u00fcgen willst, solltest du diesen hier nehmen\:\n\n\nBrauchst du Hilfe oder hast Ideen f\u00fcr den Bot? Vielleicht m\u00f6chtest du auch nur mit uns abh\u00e4ngen? Dann h\u00fcpf doch r\u00fcber zu FredBoat Hangout\!\n{0}\n\nDu kannst diesem Bot keine Befehle im privaten Chat schicken.\nBot entwickelt von Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Die Dokumentation wurde dir privat zugesendet\! helpProperUsage=Ordnungsgem\u00e4\u00dfe Verwendung\: helpCommandOwnerRestricted=Dieser Befehl beschr\u00e4nkt sich auf den Besitzer des Bots. @@ -257,16 +261,16 @@ helpSayCommand=L\u00e4sst den Bot Deine Nachricht wiederholen. helpServerInfoCommand=Zeigen Sie einige Statistiken \u00fcber diese Gilde an. helpUserInfoCommand=Zeigen Sie Informationen \u00fcber sich selbst oder einen Benutzer an, der dem Bot bekannt ist. helpPerms=Erm\u00f6glicht das whitelisten von Mitgliedern und Rollen f\u00fcr den {0} Rang. -helpPrefixCommand=Set the prefix for this guild. -helpVoteSkip=Voten um Song zu \u00fcberspringen. Es m\u00fcssen mindestens 50% von allen Usern gevotet haben um den Song zu \u00fcberspringen. +helpPrefixCommand=Legt einen Pr\u00e4fix f\u00fcr diese Gilde fest. +helpVoteSkip=Abstimmen um den aktuellen Track zu \u00fcberspringen. Es m\u00fcssen mindestens 50% aller Benutzern abgestimmt haben, um einen Track zu \u00fcberspringen. helpMathOperationAdd=Ergibt die Summe von Num1 und Num2. -helpMathOperationSub=Gebe die Differenz von num1-num2 aus. +helpMathOperationSub=Gibt die Differenz von num1-num2 aus. helpMathOperationMult=Gebe das Produkt von num1*num2 aus. helpMathOperationDiv=Gebe den Quotienten von num1/num2 aus. helpMathOperationMod=Gebe den Restwert von num1/num2 aus. helpMathOperationPerc=Gebe den Prozentsatz num1 in num2 aus. helpMathOperationSqrt=Gebe die Quadratwurzel von num aus. -helpMathOperationPow=Print the result of num1^num2. +helpMathOperationPow=Gebe das Ergebnis von num1^num2 aus. destroyDenied=Du ben\u00f6tigst die Nachrichten-Verwalten Berechtigung um den Spieler zur\u00fcckzusetzen. destroyHelp=Setzt den Player zur\u00fcck und leert die Playlist. Nur f\u00fcr Moderatoren mit Berechtigung zum Verwalten von Nachrichten. destroySucc=Setzt den Player zur\u00fcck und leert die Wiedergabeliste. @@ -294,8 +298,8 @@ voteSkipEmbedNoVotes=Aktuell gibt es keine stimmen um das Lied zu \u00fcbersprin voteSkipEmbedVoters={0} von {1} haben f\u00fcr das \u00dcberspringen des aktuellen Liedes abgestimmt. mathOperationResult=Das Ergebnis ist mathOperationDivisionByZeroError=Ich kann keine Zahl durch Null dividieren. -mathOperationInfinity=Dieese Zahl ist zu gro\u00df, um angezeigt zu werden\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +mathOperationInfinity=Diese Zahl ist zu gro\u00df, um angezeigt zu werden\! +prefix=Pr\u00e4fix +prefixGuild=Das Pr\u00e4fix f\u00fcr diese Gilde ist {0} +prefixShowAgain=Du kannst das Pr\u00e4fix jederzeit wieder anzeigen indem du mich erw\u00e4hnst. diff --git a/FredBoat/src/main/resources/lang/el_GR.properties b/FredBoat/src/main/resources/lang/el_GR.properties index 433b805d0..a6e0744e8 100644 --- a/FredBoat/src/main/resources/lang/el_GR.properties +++ b/FredBoat/src/main/resources/lang/el_GR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u0388\u03c7\u03b5\u03c4\u03b5 \u03c6\u03c4\u03ac\u03c3\u ratelimitedSkipCommand=\u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c2 \u03bd\u03b1 \u03c0\u03b1\u03c1\u03b1\u03bb\u03b5\u03af\u03c8\u03b5\u03b9\u03c2 \u03c0\u03bf\u03bb\u03bb\u03ac \u03c4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1 \u03bc\u03b5 \u03c4\u03b7\u03bd \u03b5\u03bd\u03c4\u03bf\u03bb\u03ae {0} ratelimitedGuildSlowLoadingPlaylist=\u0391\u03c5\u03c4\u03cc\u03c2 \u03bf \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae\u03c2 \u03b4\u03b5\u03bd \u03b5\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c3\u03b5\u03c4\u03b5 \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03bb\u03af\u03c3\u03c4\u03b5\u03c2 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7 \u03c3\u03c4\u03b9\u03b3\u03bc\u03ae. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03bc\u03b7\u03bd spam\u03ac\u03c1\u03b5\u03c4\u03b5 \u03bc\u03b5\u03b3\u03ac\u03bb\u03b5\u03c2 \u03bb\u03af\u03c3\u03c4\u03b5\u03c2 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2. unblacklisted=\u0391\u03c6\u03b1\u03b9\u03c1\u03b5\u03b8\u03b5\u03af\u03ba\u03b5 {0} \u03b1\u03c0\u03cc \u03c4\u03b7 \u03bc\u03b1\u03cd\u03c1\u03b7 \u03bb\u03af\u03c3\u03c4\u03b1. -serverinfoTitle=\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03bf **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u03a3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03b9 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b5\u03c2\: serverinfoTotalUsers=\u03a3\u03cd\u03bd\u03bf\u03bb\u03bf \u03a7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd\: serverinfoRoles=\u03a1\u03cc\u03bb\u03bf\u03b9\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1\u03c2\: serverinfoOwner=\u0399\u03b4\u03b9\u03bf\u03ba\u03c4\u03ae\u03c4\u03b7\u03c2\: serverinfoVLv=\u0395\u03c0\u03af\u03c0\u03b5\u03b4\u03bf \u03b5\u03c0\u03b1\u03bb\u03ae\u03b8\u03b5\u03c5\u03c3\u03b7\u03c2\: -userinfoTitle=\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03bf **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=\u038c\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\: userinfoId=\u0391\u039d\u0391\u0393\u039d\u03a9\u03a1\u0399\u03a3\u03a4\u0399\u039a\u038c\: userinfoNick=\u03a8\u03b5\u03c5\u03b4\u03ce\u03bd\u03c5\u03bc\u03bf\: @@ -212,7 +212,11 @@ commandsMaintenance=\u03a3\u03c5\u03bd\u03c4\u03ae\u03c1\u03b7\u03c3\u03b7 commandsBotOwner=\u0399\u03b4\u03b9\u03bf\u03ba\u03c4\u03ae\u03c4\u03b7\u03c2 bot commandsMoreHelp=\u03a0\u03b5\u03af\u03c4\u03b5 {0} \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03c0\u03ac\u03c1\u03b5\u03c4\u03b5 \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03bc\u03b9\u03b1 \u03c3\u03c5\u03b3\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03b7 \u03b5\u03bd\u03c4\u03bf\u03bb\u03ae. helpUnknownCommand=\u0386\u03b3\u03bd\u03c9\u03c3\u03c4\u03b7 \u0395\u03bd\u03c4\u03bf\u03bb\u03ae. -helpDM=\u0397 \u03c4\u03b5\u03ba\u03bc\u03b7\u03c1\u03af\u03c9\u03c3\u03b7 \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b2\u03c1\u03b5\u03b8\u03b5\u03af \u03c3\u03c4\u03b9\u03c2 GitHub \u03c3\u03b5\u03bb\u03af\u03b4\u03b5\u03c2 \u03c4\u03bf\u03c5 bot\: \nhttp\://docs.frederikam.com\n\n\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf FredBoat \u03c3\u03c4\u03bf \u03c3\u03ad\u03c1\u03b2\u03b5\u03c1 \u03c3\u03b1\u03c2; \u0395\u03ac\u03bd \u03ad\u03c7\u03b5\u03c4\u03b5 \u03b4\u03b9\u03ba\u03b1\u03b9\u03ce\u03bc\u03b1\u03c4\u03b1 \u03b4\u03b9\u03b1\u03c7\u03b5\u03af\u03c1\u03b9\u03c3\u03b7\u03c2 \u03c3\u03b5\u03c1\u03b2\u03b5\u03c1 \u03b3\u03b9\u03b1 \u03c4\u03b7\u03bd \u03bf\u03bc\u03ac\u03b4\u03b1 \u03c3\u03b1\u03c2, \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03ba\u03b1\u03bb\u03ad\u03c3\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc \u03b5\u03b4\u03ce\:\n *\u03b1\u03c5\u03c4\u03cc \u03b4\u03b5\u03bd \u03c0\u03b1\u03af\u03b6\u03b5\u03b9 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae *\nhttps\://discordapp.com/oauth2/authorize?&client_id\=168686772216135681&scope\=bot\n\n\u0391\u03bd \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf bot \u03b3\u03b9\u03b1 \u03bc\u03bf\u03c5\u03c3\u03b9\u03ba\u03ae\:\nhttps\://discordapp.com/oauth2/authorize?&client_id\=184405253028970496&scope\=bot \n\n\u03a7\u03c1\u03b5\u03b9\u03ac\u03b6\u03b5\u03c3\u03c4\u03b5 \u03b2\u03bf\u03ae\u03b8\u03b5\u03b9\u03b1 \u03ae \u03ad\u03c7\u03b5\u03c4\u03b5 \u03ba\u03ac\u03c0\u03bf\u03b9\u03b1 \u03b9\u03b4\u03ad\u03b1 \u03b3\u03b9\u03b1 \u03c4\u03bf bot; \u0388\u03bb\u03ac\u03c4\u03b5 \u03c3\u03c4\u03bf \u03c3\u03c4\u03ad\u03ba\u03b9 \u03c4\u03bf\u03c5 FredBoat\!{0} \n\n\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c4\u03b5\u03af\u03bb\u03b5\u03c4\u03b5 \u03c3\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf bot \u03b5\u03bd\u03c4\u03bf\u03bb\u03ad\u03c2 \u03bc\u03ad\u03c3\u03c9 DM. \n\u03a4\u03bf Bot \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03b8\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u0397 \u03c4\u03b5\u03ba\u03bc\u03b7\u03c1\u03af\u03c9\u03c3\u03b7 \u03ad\u03c7\u03b5\u03b9 \u03b1\u03c0\u03bf\u03c3\u03c4\u03b1\u03bb\u03b5\u03af \u03c3\u03c4\u03bf DM \u03c3\u03b1\u03c2\! helpProperUsage=\u03a3\u03c9\u03c3\u03c4\u03ae \u03c7\u03c1\u03ae\u03c3\u03b7\: helpCommandOwnerRestricted=\u0391\u03c5\u03c4\u03ae \u03b7 \u03b5\u03bd\u03c4\u03bf\u03bb\u03ae \u03b5\u03af\u03bd\u03b1\u03b9 \u03c0\u03b5\u03c1\u03b9\u03bf\u03c1\u03b9\u03c3\u03bc\u03ad\u03bd\u03b7 \u03c3\u03c4\u03bf\u03bd \u03b9\u03b4\u03b9\u03bf\u03ba\u03c4\u03ae\u03c4\u03b7 \u03c4\u03bf\u03c5 bot. @@ -257,7 +261,7 @@ helpSayCommand=\u039a\u03ac\u03bd\u03b5\u03b9 \u03c4\u03bf bot \u03bd\u03b1 \u03 helpServerInfoCommand=\u0395\u03bc\u03c6\u03b1\u03bd\u03af\u03b6\u03b5\u03b9 \u03ba\u03ac\u03c0\u03bf\u03b9\u03b1 \u03c3\u03c4\u03b1\u03c4\u03b9\u03c3\u03c4\u03b9\u03ba\u03ac \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf guild. helpUserInfoCommand=\u0395\u03bc\u03c6\u03b1\u03bd\u03af\u03b6\u03b5\u03b9 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03bf\u03bd \u03b5\u03b1\u03c5\u03c4\u03cc \u03c3\u03b1\u03c2 \u03ae \u03ad\u03bd\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03c0\u03bf\u03c5 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b3\u03bd\u03c9\u03c3\u03c4\u03cc\u03c2 \u03c3\u03c4\u03bf bot. helpPerms=\u0395\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03b9 \u03c4\u03bf whitelisting \u03bc\u03b5\u03bb\u03ce\u03bd \u03ba\u03b1\u03b9 \u03c1\u03cc\u03bb\u03c9\u03bd \u03b3\u03b9\u03b1 \u03c4\u03bf \u03b2\u03b1\u03b8\u03bc\u03cc \u03c4\u03bf\u03c5 {0}. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=\u039f\u03c1\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7 prefix \u03b3\u03b9\u03b1 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf guild. helpVoteSkip=\u03a8\u03b7\u03c6\u03af\u03b6\u03b5\u03b9 \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03c0\u03b1\u03c1\u03b1\u03ba\u03ac\u03bc\u03c8\u03b5\u03b9 \u03c4\u03bf \u03c4\u03c1\u03ad\u03c7\u03bf\u03bd \u03c4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9. \u03a7\u03c1\u03b5\u03b9\u03ac\u03b6\u03b5\u03c4\u03b1\u03b9 \u03c4\u03bf 50% \u03cc\u03bb\u03c9\u03bd \u03c4\u03c9\u03bd \u03c7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd \u03bc\u03b5 \u03c4\u03b7 \u03b4\u03c5\u03bd\u03b1\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1 \u03c6\u03c9\u03bd\u03b7\u03c4\u03b9\u03ba\u03ae\u03c2 \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1\u03c2 \u03bd\u03b1 \u03c8\u03b7\u03c6\u03af\u03c3\u03bf\u03c5\u03bd. helpMathOperationAdd=\u0395\u03ba\u03c4\u03c5\u03c0\u03ce\u03bd\u03b5\u03b9 \u03c4\u03bf \u03ac\u03b8\u03c1\u03bf\u03b9\u03c3\u03bc\u03b1 \u03c4\u03c9\u03bd num1 \u03ba\u03b1\u03b9 num2. helpMathOperationSub=\u0395\u03ba\u03c4\u03c5\u03c0\u03ce\u03bd\u03b5\u03b9 \u03c4\u03b7 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03ac \u03c4\u03b7\u03c2 \u03b1\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 num2 \u03b1\u03c0\u03cc \u03c4\u03bf num1. @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} \u03b1\u03c0\u03cc {1} \u03c8\u03ae\u03c6\u03b9\u03c3\u0 mathOperationResult=\u03a4\u03bf \u03b1\u03c0\u03bf\u03c4\u03ad\u03bb\u03b5\u03c3\u03bc\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 mathOperationDivisionByZeroError=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03ce \u03bd\u03b1 \u03c7\u03c9\u03c1\u03af\u03c3\u03c9 \u03bc\u03b5 \u03c4\u03bf \u03bc\u03b7\u03b4\u03ad\u03bd. mathOperationInfinity=\u039f \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03c0\u03ac\u03c1\u03b1 \u03c0\u03bf\u03bb\u03cd \u03bc\u03b5\u03b3\u03ac\u03bb\u03bf\u03c2 \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03b5\u03bc\u03c6\u03b1\u03bd\u03b9\u03c3\u03c4\u03b5\u03af\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=\u03a0\u03c1\u03cc\u03b8\u03b5\u03bc\u03b1 +prefixGuild=H prefix \u03b3\u03b9\u03b1 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf guild \u03b5\u03af\u03bd\u03b1\u03b9 {0} +prefixShowAgain=\u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03bc\u03c6\u03b1\u03bd\u03af\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf prefix \u03b1\u03bd\u03ac \u03c0\u03ac\u03c3\u03b1 \u03c3\u03c4\u03b9\u03b3\u03bc\u03ae \u03b1\u03bd\u03b1\u03c6\u03ad\u03c1\u03bf\u03bd\u03c4\u03ac\u03c2 \u03bc\u03b5. diff --git a/FredBoat/src/main/resources/lang/en_PT.properties b/FredBoat/src/main/resources/lang/en_PT.properties index 2b0b82ee7..813e783c8 100644 --- a/FredBoat/src/main/resources/lang/en_PT.properties +++ b/FredBoat/src/main/resources/lang/en_PT.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Tales ''bout **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Lively hands\: serverinfoTotalUsers=All ye mates\: serverinfoRoles=Ranks\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate='Tis made on\: serverinfoOwner=Captain\: serverinfoVLv=Verification Level\: -userinfoTitle=Tales ''bout **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Ye name\: userinfoId=Flag\: userinfoNick=How we call ye\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/en_TS.properties b/FredBoat/src/main/resources/lang/en_TS.properties index 995b7dc23..7006118d0 100644 --- a/FredBoat/src/main/resources/lang/en_TS.properties +++ b/FredBoat/src/main/resources/lang/en_TS.properties @@ -19,7 +19,7 @@ selectInterval=Must be a number 1-{0} you dummy. selectSelectionNotGiven=I haven't given you any choices yet, you can't just ask on your own\! shuffleOn=I'll mix the song list for you... but only once\! shuffleOff=But I just shuffled it\! Now you want me to sort it... Fine\! This is so labor intensive... I hate you\! -reshufflePlaylist=Queue reshuffled. +reshufflePlaylist=I put your stupid playlist back in order, it was tough FYI\! reshufflePlayerNotShuffling=You big dummy\! If you want me to shuffle the queue you have to tun it on\! Type {0}shuffle. skipEmpty=Why would you even want to empty a queue when it is already empty? Call me again when you've figured out how to actually add tracks. skipOutOfBounds=Are you blind\! Track {0} doesn''t exist\! chose between 1-{1} idiot\! @@ -87,9 +87,9 @@ loadSplitNotYouTube=This is not from YouTube\! You can't use `;;split` with that loadSplitNotResolves=I can't resolve that video's tracklist. Use `;;play` silly. loadFollowingTracksAdded=I've added some tracks\: loadPlaylistTooMany=I added {0} tracks... But, there''s too many. No way am I typing that out. -loadErrorCommon=Error occurred when loading info for `{0}`\:\n{1} +loadErrorCommon=Something''s not right\! I couldn''t load the info for `{0}`\: \n{1}\nMust be your fault.. m-mostly. loadErrorSusp=That''s.. weird. It''s strange and I don''t like it\! I couldn''t load the info for '' {0} ''. -loadQueueTrackLimit=You can''t add tracks to a queue with more than {0} tracks\! This is to prevent abuse. +loadQueueTrackLimit=Why should I add something when there''s already {0} tracks? Anyone (like you) trying to do that would be naughty. loadAnnouncePlaylist=About to load playlist **{0}** with up to `{1}` tracks. This may take a while, please be patient. playerUserNotInChannel=You're not in a voice channel, it's rude if you're asking for a song and not gonna listen to it idiot\! playerJoinConnectDenied=I won't go into that voice channel because you want me to\! @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Jeez, would you cool it? I'm going to have to rate limit ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=This should tell you more about {0} +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Users Online right now\: serverinfoTotalUsers=Everyone here\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=I was created on\: serverinfoOwner=The Owner is\: serverinfoVLv=Verification Level\: -userinfoTitle=This should tell you more about {0} +userinfoTitle=Information about {0}\: userinfoUsername=Username\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=I don't even know what you want from me. That command makes no sense. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=This is how you do it b-baka\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/es_ES.properties b/FredBoat/src/main/resources/lang/es_ES.properties index e59015399..277bfb425 100644 --- a/FredBoat/src/main/resources/lang/es_ES.properties +++ b/FredBoat/src/main/resources/lang/es_ES.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u00a1Estas llegando al limite\! Por favor, c\u00e1lmate. ratelimitedSkipCommand=Puedes omitir m\u00e1s de una canci\u00f3n usando este comando\: {0} ratelimitedGuildSlowLoadingPlaylist=Este servidor no est\u00e1 permitido a\u00f1adir m\u00e1s listas en este momento. Por favor no a\u00f1adas largas listas de reproducci\u00f3n. unblacklisted={0} fue eliminado de la lista negra. -serverinfoTitle=Informaci\u00f3n sobre **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Usuarios en l\u00ednea\: serverinfoTotalUsers=Usuarios totales\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID del servidor\: serverinfoCreationDate=Fecha de creaci\u00f3n\: serverinfoOwner=Due\u00f1o\: serverinfoVLv=Nivel de verificaci\u00f3n\: -userinfoTitle=Informaci\u00f3n sobre **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Nombre de usuario\: userinfoId=ID\: userinfoNick=Apodo\: @@ -212,7 +212,11 @@ commandsMaintenance=Mantenimiento commandsBotOwner=Due\u00f1o del bot commandsMoreHelp=Di {0} para obtener m\u00e1s informaci\u00f3n sobre un comando espec\u00edfico. helpUnknownCommand=Comando desconocido. -helpDM=La documentaci\u00f3n se puede encontrar en\:\n https\://fredboat.com/docs\n\u00bfQuieres a\u00f1adir FredBoat a tu servidor? Si tienes permisos de Manage Server para tu gremio, puedes invitarlo aqu\u00ed\:\n* Este no reproduce m\u00fasica *\n\n\nSi quieres a\u00f1adir el bot musical, deber\u00e1s invitar Este bot\:\n \n\n\u00bfNecesita ayuda o tiene alguna idea para el bot? Tal vez usted s\u00f3lo quiere salir? \u00a1Venga al hangout de FredBoat\!\n{0}\n\nNo puedes enviar este bot comandos a trav\u00e9s de DM.\nBot creado por Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u00a1La documentaci\u00f3n ha sido enviada a tus mensajes privados\! helpProperUsage=Uso correcto\: helpCommandOwnerRestricted=Este comando se limita al due\u00f1o del bot. @@ -257,7 +261,7 @@ helpSayCommand=Hacer que el bot haga eco de algo. helpServerInfoCommand=Mostrar algunas estad\u00edsticas sobre este servidor. helpUserInfoCommand=Mostrar informaci\u00f3n acerca de usted o un usuario conocido por el bot. helpPerms=Permite la inclusi\u00f3n de miembros y roles para el rango {0}. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Configura el prefijo para este gremio. helpVoteSkip=Vota para saltar la canci\u00f3n. Se requiere que el 50% de los usuarios vote. helpMathOperationAdd=Muesta la suma de n\u00famero 1 y n\u00famero 2. helpMathOperationSub=Muestra el resultado de n\u00famero 2 menos n\u00famero 1. @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} de {1} han votado para saltar la canci\u00f3n actual mathOperationResult=El resultado es mathOperationDivisionByZeroError=No puedo dividir entre cero. mathOperationInfinity=\u00a1Este n\u00famero es muy grande para mostrarse\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=Prefijo +prefixGuild=El prefijo para el gremio es {0} +prefixShowAgain=Usted puede mostrar el prefijo de cualquier momento de nuevo por mencion\u00e1ndome. diff --git a/FredBoat/src/main/resources/lang/et_EE.properties b/FredBoat/src/main/resources/lang/et_EE.properties index 7ed9f697a..b07cfdd26 100644 --- a/FredBoat/src/main/resources/lang/et_EE.properties +++ b/FredBoat/src/main/resources/lang/et_EE.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Users\: serverinfoTotalUsers=Total Users\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Creation Date\: serverinfoOwner=Owner\: serverinfoVLv=Verification Level\: -userinfoTitle=Information about **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Username\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/fa_IR.properties b/FredBoat/src/main/resources/lang/fa_IR.properties index d1a7c5093..2a9fc9828 100644 --- a/FredBoat/src/main/resources/lang/fa_IR.properties +++ b/FredBoat/src/main/resources/lang/fa_IR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Users\: serverinfoTotalUsers=Total Users\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Creation Date\: serverinfoOwner=Owner\: serverinfoVLv=Verification Level\: -userinfoTitle=Information about **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Username\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=\u062a\u0639\u0645\u06cc\u0631\u0627\u062a commandsBotOwner=\u0635\u0627\u062d\u0628 \u0631\u0628\u0627\u062a commandsMoreHelp=\u0628\u0627 \u06af\u0641\u062a\u0646 {0} \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0628\u06cc\u0634\u062a\u0631\u06cc \u062f\u0631\u0628\u0627\u0631\u0647 \u06cc\u06a9 \u0641\u0631\u0645\u0627\u0646 \u06a9\u0633\u0628 \u0645\u06cc\u06a9\u0646\u06cc\u062f. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=\u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0635\u062d\u06cc\u062d\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/fi_FI.properties b/FredBoat/src/main/resources/lang/fi_FI.properties index eafdef9fb..eee789ee8 100644 --- a/FredBoat/src/main/resources/lang/fi_FI.properties +++ b/FredBoat/src/main/resources/lang/fi_FI.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Sinut on rajoitettu k\u00e4ytt\u00e4m\u00e4st\u00e4 liika ratelimitedSkipCommand=Voit ohittaa useamman kuin yhden kappaleen k\u00e4ytt\u00e4m\u00e4ll\u00e4 t\u00e4t\u00e4 komentoa\: {0} ratelimitedGuildSlowLoadingPlaylist=T\u00e4m\u00e4 serveri ei saa lis\u00e4t\u00e4 yht\u00e4\u00e4n enemp\u00e4\u00e4 soittolistaa t\u00e4ll\u00e4 hetkell\u00e4. \u00c4l\u00e4 lis\u00e4\u00e4 ylti\u00f6m\u00e4\u00e4r\u00e4\u00e4 pitki\u00e4 soittolistoja. unblacklisted={0} poistettiin mustalta listalta. -serverinfoTitle=Tietoja t\u00e4st\u00e4 serverist\u00e4 **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=K\u00e4ytt\u00e4ji\u00e4 paikalla\: serverinfoTotalUsers=K\u00e4ytt\u00e4ji\u00e4 yhteens\u00e4\: serverinfoRoles=Roolit\: @@ -193,7 +193,7 @@ serverinfoGuildID=Palvelimen tunniste\: serverinfoCreationDate=Luontip\u00e4iv\u00e4m\u00e4\u00e4r\u00e4\: serverinfoOwner=Omistaja\: serverinfoVLv=Vahvistustaso\: -userinfoTitle=Tietoja t\u00e4st\u00e4 henkil\u00f6st\u00e4 **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=K\u00e4ytt\u00e4j\u00e4nimi\: userinfoId=Tunnus\: userinfoNick=Nimimerkki\: @@ -212,7 +212,11 @@ commandsMaintenance=Huolto commandsBotOwner=Botin omistaja commandsMoreHelp=Sano {0} saadaksesi lis\u00e4tietoa tietyst\u00e4 komennosta. helpUnknownCommand=Tuntematon komento. -helpDM=Haluatko lis\u00e4t\u00e4 Fredboardin serverillesi? Jos sinulla on manage servers permissionit serverill\u00e4, voit lis\u00e4t\u00e4 sen t\u00e4ll\u00e4 linkill\u00e4 (t\u00e4m\u00e4 ei soita musiikkia)\: \n\nJos haluat lis\u00e4t\u00e4 musiikki botin, lis\u00e4\u00e4 t\u00e4m\u00e4\: \n\nTarvitsetko apua tai sinulla on ideoita bottia varten? Tai haluat vain olla jossain? Tule FredBoat hangouttiin\: {0}\n\nEt voi l\u00e4hett\u00e4\u00e4 t\u00e4lle botilla viestej\u00e4 yksityisesti\!\n\nBotin teki Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Dokumentaatio on l\u00e4hetetty sinun yksityisviesteihisi\! helpProperUsage=Asianmukainen k\u00e4ytt\u00f6\: helpCommandOwnerRestricted=T\u00e4m\u00e4 komento on rajoitettu vain botin omistajalle. diff --git a/FredBoat/src/main/resources/lang/fil_PH.properties b/FredBoat/src/main/resources/lang/fil_PH.properties index d1fb1c530..a8cb884ca 100644 --- a/FredBoat/src/main/resources/lang/fil_PH.properties +++ b/FredBoat/src/main/resources/lang/fil_PH.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Users\: serverinfoTotalUsers=Total Users\: serverinfoRoles=Mga tungkulin\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Creation Date\: serverinfoOwner=Owner\: serverinfoVLv=Verification Level\: -userinfoTitle=Information about **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Username\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/fr_FR.properties b/FredBoat/src/main/resources/lang/fr_FR.properties index cc6c60495..39287ad16 100644 --- a/FredBoat/src/main/resources/lang/fr_FR.properties +++ b/FredBoat/src/main/resources/lang/fr_FR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Vous \u00eates en taux limit\u00e9\u00a0\! S\u2019il vous ratelimitedSkipCommand=Vous pouvez passer plus d''une chanson en utilisant la commande suivante \: {0} ratelimitedGuildSlowLoadingPlaylist=Ce serveur ne peut pas charger plus de listes de lecture pour le moment. S'il vous pla\u00eet, ne spammez pas de longues listes de lecture. unblacklisted={0} a \u00e9t\u00e9 retir\u00e9 de la liste noire. -serverinfoTitle=Informations sur **{0}** \: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Utilisateurs en ligne \: serverinfoTotalUsers=Nombre total d'utilisateurs \: serverinfoRoles=R\u00f4les \: @@ -193,7 +193,7 @@ serverinfoGuildID=Identifiant de la guilde \: serverinfoCreationDate=Date de cr\u00e9ation \: serverinfoOwner=Propri\u00e9taire \: serverinfoVLv=Niveau de v\u00e9rification\u00a0\: -userinfoTitle=Informations sur **{0}** \: +userinfoTitle=Information about {0}\: userinfoUsername=Nom d'utilisateur \: userinfoId=Identifiant \: userinfoNick=Pseudonyme \: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Propri\u00e9taire du bot commandsMoreHelp=Dites {0} pour obtenir plus d\u2019informations sur une commande sp\u00e9cifique. helpUnknownCommand=Commande inconnue. -helpDM=Vous pouvez acc\u00e9der \u00e0 la documentation du bot via ce lien \:\nhttp\://docs.frederikam.com\n\nEnvie d''ajouter FredBoat \u00e0 votre serveur ? Si vous avez les permissions requises pour g\u00e9rer le serveur, vous pouvez l''inviter via ce lien \:\n*Celui-ci ne joue pas de musique*\n\n\nSi vous recherchez plut\u00f4t un bot musical, invitez ce bot \:\n\n\nVous avez besoin d''aide ou souhaitez contribuer \u00e0 l''am\u00e9lioration du bot ? Ou vous voulez juste passer le temps ? Venez donc faire un tour dans le repaire de FredBoat \!\n{0}\n\nVous ne pouvez pas utiliser les commandes de ce bot via MP.\nBot cr\u00e9\u00e9 par Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=La documentation a \u00e9t\u00e9 envoy\u00e9 dans votre messagerie priv\u00e9e \! helpProperUsage=Utilisation ad\u00e9quate \: helpCommandOwnerRestricted=Cette commande est r\u00e9serv\u00e9e au propri\u00e9taire du bot. @@ -225,7 +229,7 @@ helpMusicCommandsHeader=Commandes musicales de Fredboat helpJoinCommand=Fait venir le bot dans votre canal vocal actuel. helpLeaveCommand=Fait partir le bot de votre canal vocal actuel. helpPauseCommand=Met le lecteur en pause. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=Joue de la musique \u00e0 partir d''un lien ou recherche une piste. Pour une liste compl\u00e8te des sources, veuillez visiter {0} helpPlaySplitCommand=Divise une vid\u00e9o YouTube en une liste de lecture fournie depuis sa description. helpRepeatCommand=Bascule entre les modes de r\u00e9p\u00e9tition. helpReshuffleCommand=Remet en mode al\u00e9atoire la file d'attente actuelle. @@ -257,7 +261,7 @@ helpSayCommand=Faire dire quelque chose au bot. helpServerInfoCommand=Affiche les statistiques sur cette guilde. helpUserInfoCommand=Affiche les informations sur vous ou un autre utilisateur connu du bot. helpPerms=Permet d''ajouter les membres et les r\u00f4les \u00e0 la liste blanche pour le grade {0}. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Configure le pr\u00e9fixe pour le serveur. helpVoteSkip=Vote pour passer la musique en cours. A besoin de 50 % de tous les d'utilisateurs dans le salon vocal pour voter. helpMathOperationAdd=\u00c9crit la somme de num1 et num2. helpMathOperationSub=\u00c9crit le r\u00e9sultat de la soustraction de num1 moins num2. @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} sur {1} ont vot\u00e9 pour passer la musique en cours mathOperationResult=Le r\u00e9sultat est mathOperationDivisionByZeroError=Je ne peux pas diviser par z\u00e9ro. mathOperationInfinity=Le nombre est trop grand pour \u00eatre affich\u00e9 \! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=Pr\u00e9fixe +prefixGuild=Le pr\u00e9fixe pour cette guilde est {0} +prefixShowAgain=Vous pouvez montrer le pr\u00e9fixe quand vous le voulez en me mentionnant. diff --git a/FredBoat/src/main/resources/lang/he_IL.properties b/FredBoat/src/main/resources/lang/he_IL.properties index 2b4cd07e8..77c6dcc0b 100644 --- a/FredBoat/src/main/resources/lang/he_IL.properties +++ b/FredBoat/src/main/resources/lang/he_IL.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd \u05de\u05d7\u05d5\u05d1\u05e8\u05d9\u05dd\: serverinfoTotalUsers=\u05e1\u05da \u05d4\u05db\u05dc \u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd\: serverinfoRoles=\u05ea\u05e4\u05e7\u05d9\u05d3\u05d9\u05dd\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Creation Date\: serverinfoOwner=\u05d1\u05e2\u05dc\u05d9\u05dd\: serverinfoVLv=Verification Level\: -userinfoTitle=Information about **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=\u05e9\u05dd \u05de\u05e9\u05ea\u05de\u05e9\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/hr_HR.properties b/FredBoat/src/main/resources/lang/hr_HR.properties index 458b71ce4..b8e1b56c7 100644 --- a/FredBoat/src/main/resources/lang/hr_HR.properties +++ b/FredBoat/src/main/resources/lang/hr_HR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Informacije o **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online korisnika\: serverinfoTotalUsers=Ukupno korisnika\: serverinfoRoles=Uloge\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID guilda\: serverinfoCreationDate=Datum kreiranja\: serverinfoOwner=Vlasnik\: serverinfoVLv=Provjera razine\: -userinfoTitle=Informacije o **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=Korisni\u010dko ime\: userinfoId=ID\: userinfoNick=Nadimak\: @@ -212,7 +212,11 @@ commandsMaintenance=Odr\u017eavanje commandsBotOwner=Vlasnik bota commandsMoreHelp=Napi\u0161ite {0} da biste dobili vi\u0161e informacija o odre\u0111enoj naredbi. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Upute su poslane u va\u0161 sandu\u010di\u0107 s porukama\! helpProperUsage=Pravilno kori\u0161tenje\: helpCommandOwnerRestricted=Ova naredba je ograni\u010dena na vlasnika bota. diff --git a/FredBoat/src/main/resources/lang/hu_HU.properties b/FredBoat/src/main/resources/lang/hu_HU.properties index 7fd848139..2279835ce 100644 --- a/FredBoat/src/main/resources/lang/hu_HU.properties +++ b/FredBoat/src/main/resources/lang/hu_HU.properties @@ -36,7 +36,7 @@ unpauseQueueEmpty=A lista \u00fcres. unpausePlayerNotPaused=A lej\u00e1tsz\u00f3 nem le\u00e1ll\u00edtott. unpauseNoUsers=Nincsenek felhaszn\u00e1l\u00f3k a voice chat-en. unpauseSuccess=A lej\u00e1tsz\u00f3 most elindult. -volumeApology=Bocsi\! A ;;volume parancs le\u00e1llt a publikus bot-on. Ez az\u00e9rt van mert id\u00f6 kell az audio feldolgoz\u00e1s\u00e1ra, csak 5 zen\u00e9t tud lej\u00e1tszani egyszerre, nehogy mindenkinek megzavarja a f\u00fcl\u00e9t. A FredBot kikapcsol\u00e1s\u00e1val t\u00f6bb zen\u00e9t tudsz j\u00e1tszani kevesebb lagg-al. Aj\u00e1nlom a bot be\u00e1ll\u00edt\u00e1s\u00e1t a dropdown men\u00fc-n\u00e9l https\://fred.moe/1vD.png +volumeApology=Bocsi\! A ;;volume parancs le\u00e1llt a publikus bot-on. Ez az\u00e9rt t\u00f6rt\u00e9nt mert id\u0151 kell a hang feldolgoz\u00e1s\u00e1ra, egy p\u00e1r sz\u00e1mn\u00e1l ak\u00e1r \u00f6tsz\u00f6r t\u00f6bb ideig, hang akad\u00e1s\u00e1t okozva mindenkin\u00e9l. Ennek a funkci\u00f3nak a kikapcsol\u00e1s\u00e1val t\u00f6bb zen\u00e9t tudsz j\u00e1tszani kevesebb lagg-al. Aj\u00e1nlom a bot hang erej\u00e9nek a be\u00e1ll\u00edt\u00e1s\u00e1t a dropdown men\u00fc-n\u00e9l https\://fred.moe/1vD.png volumeSyntax=Haszn\u00e1ld a `;;volume <0-150>`. {0}% az alap. A lej\u00e1tsz\u00f3 most **{1}%** n\u00e1l van. volumeSuccess=A hanger\u00f6t **{0}%** r\u00f3l **{1}%** ra v\u00e1ltoztattad. exportEmpty=Semmi sincs hogy kibontsad, a lista \u00fcres. @@ -45,7 +45,7 @@ exportPlaylistFail=Hiba a lej\u00e1tsz\u00e1si lista felt\u00f6lt\u00e9s\u00e9n\ listShowShuffled=\u00d6sszekevert lista mutat\u00e1sa. listShowRepeatSingle=Mostani zene ism\u00e9tl\u00e9se. listShowRepeatAll=Mostani sor ism\u00e9tl\u00e9se. -listShowHistory=Showing tracks in history. +listShowHistory=Sz\u00e1mok mutat\u00e1sa az el\u0151zm\u00e9nyekben. listAddedBy=**{0}** hozz\u00e1 lett adva **{1}** `[{2}]` listStreamsOnlySingle=Itt csak **{0}** \u00e9l {1} a sorban. listStreamsOnlyMultiple=Itt **{0}** \u00e9l {1} a sor-ban. @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=, meg **{0}** \u00e9l\u00f6 {1} trackSingular=zene trackPlural=zen\u00e9k npNotPlaying=Nem j\u00e1tszik semmit. -npNotInHistory=Currently no tracks in history. +npNotInHistory=Jelenleg nincsenek sz\u00e1mok az el\u0151zm\u00e9nyekben. npDescription=Le\u00edr\u00e1s npLoadedSoundcloud=[{0}/{1}]\n\nBet\u00f6lt\u00f6tt a Soundcloud-r\u00f3l npLoadedBandcamp={0}\n\nBet\u00f6lt\u00f6tt a Bandcamp-r\u00f6l @@ -79,7 +79,7 @@ restartSuccess=**{0}** \u00fajraindult. queueEmpty=A lista \u00fcres. rewSuccess=Felh\u00faz\u00e1s **{0}** {1}. seekSuccess=Keres\u00e9s **{0}** {1}. -seekDeniedLiveTrack=You can't seek a live track. +seekDeniedLiveTrack=Nem kereshetsz egy \u00e9l\u0151 sz\u00e1mban. loadPlaySplitListFail=A link egy lej\u00e1tsz\u00e1si list\u00e1hoz vezet, nem zen\u00e9hez. Pr\u00f3b\u00e1ld meg `;;play` helyett. loadListSuccess=Tal\u00e1lt \u00e9s hozz\u00e1adott `{0}` zen\u00e9t a lej\u00e1tsz\u00e1si list\u00e1r\u00f3l **{1}**. loadNoMatches=Nincs tal\u00e1lhat\u00f3 zene erre `{0}`. @@ -132,8 +132,8 @@ brainfuckCycleLimit=A program meghaladta a maximum ciklus sz\u00e1m\u00e1t\n{0} brainfuckDataPointerOutOfBounds=Adat mutat\u00f3nak nincs t\u00f6bb helye\: {0} brainfuckInputOOB=Glm helyzete\: {0} brainfuckNoOutput=\ Nem volt semmi -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} +weatherLocationNotFound=Hely keres\u00e9se sikertelen, k\u00e9rj\u00fck ellen\u0151rizd a bevitelt {0}. +weatherError=Hiba az id\u0151j\u00e1r\u00e1si adatok lek\u00e9r\u00e9s\u00e9ben {0}-hoz avatarSuccess=\ megtal\u00e1ltam\n{0} configNoArgs=Konfigur\u00e1ci\u00f3 ehhez **{0}**\:``` configSetTo=\u00e1llitva van erre `{0}`. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Lelet\u00e9l sebess\u00e9g korl\u00e1t\u00f3zva\! K\u00e9 ratelimitedSkipCommand=E parancs haszn\u00e1lat\u00e1val \u00e1tugorhat egyn\u00e9l t\u00f6bb sz\u00e1mot\: {0} ratelimitedGuildSlowLoadingPlaylist=Ez a szerver nem enged\u00e9lyezett ahoz t\u00f6bb lej\u00e1tsz\u00e1si list\u00e1t j\u00e1tsz\u00f3n le, ebben a pillanatban. K\u00e9rj\u00fck, ne spamelj hossz\u00fa list\u00e1kat. unblacklisted=Elt\u00e1volitva {0} a a feketelist\u00e1ra. -serverinfoTitle=Inf\u00f3 err\u00f6l **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Felhaszn\u00e1l\u00f3k\: serverinfoTotalUsers=\u00d6sszes Felhaszn\u00e1l\u00f3\: serverinfoRoles=Szerepk\u00f6r\u00f6k\: @@ -193,17 +193,17 @@ serverinfoGuildID=Guild Azonos\u00edt\u00f3\: serverinfoCreationDate=L\u00e9trehoz\u00e1s D\u00e1tuma\: serverinfoOwner=Tulajdonos\: serverinfoVLv=Ellen\u00f6rz\u00e9si Szint\: -userinfoTitle=Inf\u00f3 r\u00f3la **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Felhaszn\u00e1l\u00f3n\u00e9v\: userinfoId=Azonos\u00edt\u00f3\: userinfoNick=Becen\u00e9v\: userinfoKnownServer=Ismert Szerverek\: userinfoJoinDate=Csatlakoz\u00e1s D\u00e1tuma\: userinfoCreationTime=L\u00e9trehoz\u00e1s D\u00e1tuma\: -userinfoBlacklisted=Blacklisted\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +userinfoBlacklisted=Tilt\u00f3list\u00e1n\: +skipDeniedTooManyTracks=Nem ugorhatod \u00e1t valaki m\u00e1s sz\u00e1m\u00e1t ha nem vagy DJ.\nFontold meg a Voteskip parancs haszn\u00e1lat\u00e1t. eventUsersLeftVC=Minden felhaszn\u00e1l\u00f3 lel\u00e9pett. A lej\u00e1tsz\u00f3 meg lett \u00e1ll\u00edtva. -eventAutoResumed=User presence detected, automatically resuming the player. +eventAutoResumed=Felhaszn\u00e1l\u00f3 \u00e9szlelve, lej\u00e1tsz\u00f3 automatikus ind\u00edt\u00e1sa. commandsFun=Sz\u00f3rakoz\u00e1s commandsMemes=M\u00e9mek commandsUtility=Seg\u00e9dprogram @@ -212,7 +212,11 @@ commandsMaintenance=Karbantart\u00e1s alatt commandsBotOwner=Bot tulajdonos commandsMoreHelp=Irj {0} hogy kapj t\u00f6bb inform\u00e1ci\u00f3t. helpUnknownCommand=Ismeretlen parancs. -helpDM=Dokument\u00e1ci\u00f3 itt tal\u00e1lhat\u00f3\:\nhttps\://fredboat.com/docs\n\nHozz\u00e1 akarod adni FredBoat-ot a szerveredhez? Ha van Manage Server enged\u00e9lyed a sz\u00f6vets\u00e9gedhez, itt h\u00edvhatod meg\:\n*Ez nem j\u00e1tszik zen\u00e9t*\n\n\nHa a zenebotot akarod akkor itt kell megh\u00edvni\:\n\n\nKell seg\u00edts\u00e9g vagy van b\u00e1rmi \u00f6tleted a bothoz? Esetleg csak l\u00f3gni akarsz? Gyere \u00e1t a FredBoat hangout-ba\!\n{0}\n\nNem tudod elk\u00fcldeni ennek a botnak a parancsait K\u00f6zvetlen \u00dczenetben.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=A dokumentum el lett k\u00fcldve a DM edhez\! helpProperUsage=Megfelel\u00f6 haszn\u00e1lat\: helpCommandOwnerRestricted=Ez a command csak a tulajdonosra \u00e9s a botra tartozik. @@ -225,7 +229,7 @@ helpMusicCommandsHeader=FredBoat Zene Parancsok helpJoinCommand=Csin\u00e1ld meg a botot hogy csatlakozzon a voice channelhez. helpLeaveCommand=Csin\u00e1ld meg a botot hogy lel\u00e9pjen a voice channelr\u00f6l. helpPauseCommand=Sz\u00fcneteld a lej\u00e1tsz\u00f3t. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=J\u00e1tssz le egy zen\u00e9t a megadott URL alapj\u00e1n vagy keress egy sz\u00e1mo. A forr\u00e1sok teljes list\u00e1j\u00e1hoz k\u00e9rj\u00fck l\u00e1togasd meg a {0} oldalt helpPlaySplitCommand=YouTube vide\u00f3 feloszt\u00e1sa a list\u00e1ba. helpRepeatCommand=Ism\u00e9tl\u00f6 m\u00f3d k\u00f6z\u00f6tt kapcsold be. helpReshuffleCommand=Keverd \u00f6ssze a list\u00e1t. @@ -259,7 +263,7 @@ helpUserInfoCommand=Inform\u00e1ci\u00f3k megjelen\u00edt\u00e9se r\u00f3lad vag helpPerms=Allows whitelisting members and roles for the {0} rank. helpPrefixCommand=Set the prefix for this guild. helpVoteSkip=Vote to skip the current song. Needs 50% of all users in the voice chat to vote. -helpMathOperationAdd=Print the sum of num1 and num2. +helpMathOperationAdd=Ki\u00edrja num1 \u00e9s num2 \u00f6sszeg\u00e9t. helpMathOperationSub=Print the difference of subtracting num2 from num1. helpMathOperationMult=Print the product of num1*num2. helpMathOperationDiv=Print the quotient of dividing num1 by num2. @@ -281,7 +285,7 @@ fuzzyMultiple=Multiple items were found. Did you mean any of these? fuzzyNothingFound=Nem talalom ''{0}''. cmdPermsTooLow=Ehhez nincs jogod\! playersLimited=FredBoat \u00e9ppen maximum kapacit\u00e1son van\! A bot \u00e9ppen r\u00f6gz\u00edtett hogy csak `{0}` helyen \u00e1ramoljon, m\u00e1sk\u00e9ppen megkock\u00e1ztatn\u00e1nk, hogy lecsatlakozzon a Discord-r\u00f3l h\u00e1l\u00f3zat t\u00f6lt\u00e9se k\u00f6zben.\nHa seg\u00edteni akarsz n\u00f6velni a limitet vagy nem t\u00falzs\u00fafolt botot akarsz haszn\u00e1lni, k\u00e9rlek seg\u00edts a munk\u00e1nkon a Patreon oldalon\:\n{1}\n\nEln\u00e9z\u00e9st a k\u00e9nyelmetlens\u00e9g\u00e9rt. Tal\u00e1n pr\u00f3b\u00e1ld \u00fajra k\u00e9s\u00f6bb. Ez az \u00fczenet \u00e1ltal\u00e1ban cs\u00facsid\u0151k\u00f6n szokott megjelenni. -tryLater=Please try again later. +tryLater=K\u00e9rj\u00fck, pr\u00f3b\u00e1lja \u00fajra k\u00e9s\u0151bb. skipUserSingle=Skipped {0} added by {1}. skipUserMultiple=Skipped {0} tracks added by {1}. skipUsersMultiple=Skipped {0} tracks added by {1} users. diff --git a/FredBoat/src/main/resources/lang/id_ID.properties b/FredBoat/src/main/resources/lang/id_ID.properties index 72dba6480..3e31e8757 100644 --- a/FredBoat/src/main/resources/lang/id_ID.properties +++ b/FredBoat/src/main/resources/lang/id_ID.properties @@ -45,8 +45,8 @@ exportPlaylistFail=Gagal mengupload Playlist ke hastebin.com listShowShuffled=Menampilkan Playlist Acak.\n\n listShowRepeatSingle=Mengulang trek saat ini. listShowRepeatAll=Mengulang antrian lagu saat ini. -listShowHistory=Showing tracks in history. -listAddedBy=**{0}** added by **{1}** `[{2}]` +listShowHistory=Menampilkan trek dalam sejarah. +listAddedBy=**{0}** ditambahkan oleh **{1}** `[{2}]` listStreamsOnlySingle=Ada **{0} ** stream {1} dalam antrian. listStreamsOnlyMultiple=Ada **{0} ** stream {1} dalam antrian. listStreamsOrTracksSingle=Ada **{0} ** {1} dengan waktu tersisa ** [{2}] **{3} dalam antrian. @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=serta **{0}** sedang diputar {1} trackSingular=track trackPlural=tracks npNotPlaying=Tidak sedang memainkan apapun. -npNotInHistory=Currently no tracks in history. +npNotInHistory=Saat ini tidak ada jejak dalam sejarah. npDescription=Deskripsi npLoadedSoundcloud=[{0}/{1}]\n\nmengambil dari Soundcloud npLoadedBandcamp={0}\n\nMengambil dari Bandcamp @@ -79,7 +79,7 @@ restartSuccess=**{0}** telah di restart. queueEmpty=Antrian lagu kosong. rewSuccess=Memutar balik **{0}** ke {1}. seekSuccess=Mencari **{0} ** untuk {1}. -seekDeniedLiveTrack=You can't seek a live track. +seekDeniedLiveTrack=Anda tidak bisa mencari lagu live. loadPlaySplitListFail=Link tersebut mengarah ke Playlist. Bukan track. Gunakan `;;play`. loadListSuccess=Menemukan dan menambahkan `{0}` dari playlist **{1}**. loadNoMatches=Tidak ada Audio ditemukan dari `{0}`. @@ -125,15 +125,15 @@ luaError=\ A Lua error occured \:anger\:\n```{0}``` luaErrorOutputTooBig=\ Output buffer terlalu besar \:anger\: Discord membatasi 2000 karakter per pesan, terdapat {0} Karakter luaTimeout=\ Fungsi habis \:anger\: memungkinkan perhitungan waktu {0} detik. helpSuccess=Dokumentasi telah dikirim ke pesan langsung kamu\! -helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! +helpDmFailed=Tidak dapat mengirim dokumentasi ke DM Anda. Harap periksa apakah Anda tidak memilikinya dinonaktifkan\! helpCommandsPromotion=Sebut {0} untuk mempelajari apa yang dapat bot ini lakukan\! fuzzyNoResults=Tidak ada pengguna tersebut brainfuckCycleLimit=Program melebihi jumlah maksimum siklus {0} brainfuckDataPointerOutOfBounds=Data pointer out of bounds\: {0} brainfuckInputOOB=Input out of bounds at position\: {0} brainfuckNoOutput=\ Tidak ada Output -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} +weatherLocationNotFound=Tidak dapat menemukan lokasi, harap periksa masukan Anda {0}. +weatherError=Terjadi kesalahan saat mengambil cuaca untuk {0} avatarSuccess=\ aku menemukannya\n{0} configNoArgs=Konfigurasi untuk **{0}**\:``` configSetTo=sekarang diatur ke ''{0}''. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Kamu mencapai tingkatan batas\! Harap perlambat. ratelimitedSkipCommand=Anda Dapat Melewati Lebih Dari Satu Lagu Dengan Menggunakan Perintah\: {0} ratelimitedGuildSlowLoadingPlaylist=Server ini tidak diizinkan untuk menambahkan playlist lebih untuk saat ini. Harap jangan spam playlist panjang. unblacklisted=Menghapus {0} dari blacklist. -serverinfoTitle=Info tentang **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Pengguna Online\: serverinfoTotalUsers=Total Pengguna\: serverinfoRoles=Peran\: @@ -193,17 +193,17 @@ serverinfoGuildID=Server ID\: serverinfoCreationDate=Tanggal Pembuatan\: serverinfoOwner=Pemilik\: serverinfoVLv=Tingkat verifikasi\: -userinfoTitle=Informasi tentang **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=Nama Pengguna\: userinfoId=ID\: userinfoNick=Nama Panggilan\: userinfoKnownServer=Server yang dikenal\: userinfoJoinDate=Tanggal Bergabung\: userinfoCreationTime=Tanggal Pembuatan\: -userinfoBlacklisted=Blacklisted\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +userinfoBlacklisted=Daftar hitam\: +skipDeniedTooManyTracks=Anda tidak bisa melewati jejak orang lain jika Anda bukan seorang DJ. Pertimbangkan untuk menggunakan perintah Voteskip. eventUsersLeftVC=Semua pengguna telah meninggalkan channel suara. Pemutar musik telah dijeda. -eventAutoResumed=User presence detected, automatically resuming the player. +eventAutoResumed=Kehadiran pengguna terdeteksi, otomatis melanjutkan player. commandsFun=Kesenangan commandsMemes=Meme commandsUtility=Kegunaan @@ -212,7 +212,11 @@ commandsMaintenance=Perbaikan commandsBotOwner=Pemilik bot commandsMoreHelp=Katakanlah {0} untuk mendapatkan informasi lebih lanjut tentang perintah tertentu helpUnknownCommand=Perintah Tidak Ditemukan. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Dokumentasi telah dikirim ke DMS Anda\! helpProperUsage=Penggunaan yang tepat\: helpCommandOwnerRestricted=Perintah ini di ban oleh pemilik bot. @@ -225,20 +229,20 @@ helpMusicCommandsHeader=FredBoat Perintah Musik helpJoinCommand=Membuat bot bergabung kedalam voice channel yang Anda masuki. helpLeaveCommand=Membuat bot meninggalkan voice channel yang telah masuki. helpPauseCommand=Menjeda pemutar musik. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=Mainkan musik dari URL yang diberikan atau cari trek. Untuk daftar lengkap sumber silakan kunjungi {0} helpPlaySplitCommand=Membagi YouTube video ke dalam daftar lagu yang disediakan dalam deskripsi tersebut. helpRepeatCommand=Beralih antara mode berulang. helpReshuffleCommand=Mengacak ulang antrian lagu saat ini. helpSelectCommand=Pilih salah satu trek yang ditawarkan setelah pencarian untuk memainkannya. helpShuffleCommand=Beralih mode acak untuk antrian lagu saat ini. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpSkipCommand=Lewati lagu saat ini, lagu n'th dalam antrian, semua lagu dari n ke m, atau semua lagu dari pengguna yang disebutkan di atas. Mohon gunakan secukupnya. helpStopCommand=Menghentikan pemutar musik dan membersihkan daftar lagu. Diperuntukkan bagi moderator dengan izin mengelola pesan. helpUnpauseCommand=Menjalankan kembali pemutar musik. helpVolumeCommand=Mengubah volume. Nilainya dari 0-150 dan 100 adalah default. Perintah volume tidak digunakan lagi pada bot publik. helpExportCommand=Ekspor antrian saat ini ke tautan hastebin, dapat digunakan nanti sebagai daftar putar. helpGensokyoRadioCommand=Menampilkan lagu saat ini yang dimainkan di gensokyoradio.net helpListCommand=Menampilkan daftar lagu saat ini dalam daftar putar. -helpHistoryCommand=Display a list of the songs in playlist history. +helpHistoryCommand=Tampilkan daftar lagu dalam riwayat daftar putar. helpNowplayingCommand=Menampilkan lagu yang sedang diputar. helpForwardCommand=Meneruskan trek dengan jumlah waktu yang ditentukan. \nContoh\: helpRestartCommand=Restart trek yang sedang diputar. @@ -246,7 +250,7 @@ helpRewindCommand=Memundurkan trek dengan jumlah waktu yang ditentukan.\nContoh\ helpSeekCommand=Mengatur posisi trek ke waktu yang ditentukan.\nContoh\: helpAvatarCommand=Menampilkan avatar pengguna. helpBrainfuckCommand=Mengeksekusi kode Brainfuck. Contoh\: -helpWeatherCommand=Display current weather by location. +helpWeatherCommand=Tampilkan cuaca saat ini menurut lokasi. helpClearCommand=Menghapus semua pesan oleh bot ini dalam pesan terakhir 50 channel ini. helpCommandsCommand=Menampilkan perintah yang tersedia. helpHelpCommand=Menerima bantuan untuk bot ini atau bantuan untuk setiap perintah. @@ -257,16 +261,16 @@ helpSayCommand=Membuat bot mengatakan sesuatu. helpServerInfoCommand=Menampilkan beberapa statistik tentang server ini. helpUserInfoCommand=Menampilkan informasi yang diketahui bot tentang diri kamu atau pengguna. helpPerms=Membolehkan Anggota Untuk Mengakses Dan Peran Untuk Peringkat. {0} -helpPrefixCommand=Set the prefix for this guild. -helpVoteSkip=Vote to skip the current song. Needs 50% of all users in the voice chat to vote. -helpMathOperationAdd=Print the sum of num1 and num2. -helpMathOperationSub=Print the difference of subtracting num2 from num1. -helpMathOperationMult=Print the product of num1*num2. -helpMathOperationDiv=Print the quotient of dividing num1 by num2. -helpMathOperationMod=Print the remainder of dividing num1 by num2. -helpMathOperationPerc=Print the percentage represented by num1 in num2. -helpMathOperationSqrt=Print the square root of num. -helpMathOperationPow=Print the result of num1^num2. +helpPrefixCommand=Tetapkan awalan untuk guild ini. +helpVoteSkip=Pilih untuk melewatkan lagu yang sedang diputar. Membutuhkan 50% dari semua pengguna di voice chat untuk memilih. +helpMathOperationAdd=Cetak jumlah num1 dan num2. +helpMathOperationSub=Cetak perbedaan penguraian num2 dari num1. +helpMathOperationMult=Cetak produk num1 * num2. +helpMathOperationDiv=Cetak hasil bagi membagi num1 dengan num2. +helpMathOperationMod=Cetak sisa membagi num1 dengan num2. +helpMathOperationPerc=Cetak persentase yang ditunjukkan oleh num1 di num2. +helpMathOperationSqrt=Cetak akar kuadrat num. +helpMathOperationPow=Cetak hasil num1 ^ num2. destroyDenied=Kamu Harus Memiliki Izin Pengaturan Pesan Untuk Mengatur Ulang Pemutar. destroyHelp=Mengatur Ulang Pemutar Dan Membersihkan Daftar Lagu. Diperuntukkan Untuk Moderator Dengan Izin Mengelola Pesan. destroySucc=Mengatur Kembali Pemutar Dan Membersihkan Antrian. @@ -275,27 +279,27 @@ permsListTitle=Pengguna Dan Peran Dengan Izin {0} permsAdded=Menambahkan ''{0}'' Ke ''{1}''. permsRemoved=Menghapus ''{0}'' Dari ''{1}''. permsFailSelfDemotion=Kamu Tidak Bisa Menghapus Ini Karena akan membuat Anda tanpa izin Admin\! -permsAlreadyAdded={0} already added to {1} -permsNotAdded={0} is not in {1} +permsAlreadyAdded={0} sudah ditambahkan ke {1} +permsNotAdded={0} tidak di {1} fuzzyMultiple=Beberapa Lagu Yang Ditemukan. Apa Yang Kamu Cari Dengan Lagu ini? fuzzyNothingFound=Tidak Ada Yang Ditemukan Untuk ''{0}''. cmdPermsTooLow=Anda tidak memiliki izin untuk menjalankan perintah ini\! Perintah ini Membutuhkan ''{0}'' tetapi Anda hanya memiliki ''{1}''. -playersLimited=FredBoat is currently at maximum capacity\! The bot is currently fixed to only play up to `{0}` streams, otherwise we would risk disconnecting from Discord under the network load.\nIf you want to help us increase the limit or you want to use our non-overcrowded bot, please support our work on Patreon\:\n{1}\n\nSorry for the inconvenience\! You might want to try again later. This message usually only appears at peak time. +playersLimited=FredBoat saat ini kapasitas maksimal\! Bot saat ini diperbaiki hanya untuk bermain dengan aliran ` {0} `, jika tidak, kami akan mengambil risiko melepaskan diri dari Discord di bawah beban jaringan. Jika Anda ingin membantu kami meningkatkan batas atau Anda ingin menggunakan bot kami yang tidak terlalu penuh, tolong dukung pekerjaan kami di Patreon\:\n {1} \n\nMaaf atas ketidaknyamanannya\! Anda mungkin ingin mencoba lagi nanti. Pesan ini biasanya hanya muncul pada waktu puncak. tryLater=Silakan coba sesaat lagi. -skipUserSingle=Skipped {0} added by {1}. -skipUserMultiple=Skipped {0} tracks added by {1}. -skipUsersMultiple=Skipped {0} tracks added by {1} users. -skipUserNoTracks=None of the mentioned users have any tracks queued. -voteSkipAdded=Your vote has been added\! -voteSkipAlreadyVoted=You already voted to skip this track\! -voteSkipSkipping={0} have voted to skip. Skipping track {1}. -voteSkipNotEnough={0} have voted to skip. At least {1} needed. -voteSkipEmbedNoVotes=No votes to skip this track yet. -voteSkipEmbedVoters={0} out of {1} have voted to skip the current track -mathOperationResult=The result is +skipUserSingle=Dilewati {0} ditambahkan oleh {1}. +skipUserMultiple=Melewati {0} trek yang ditambahkan oleh {1}. +skipUsersMultiple=Melewati {0} trek yang ditambahkan oleh {1} pengguna. +skipUserNoTracks=Tidak satu pun pengguna yang disebutkan memiliki antrean. +voteSkipAdded=Suara Anda telah ditambahkan\! +voteSkipAlreadyVoted=Anda telah memilih untuk melewati jalur ini\! +voteSkipSkipping={0} telah memilih untuk melompati Melewati lintasan {1}. +voteSkipNotEnough={0} telah memilih untuk melompati Paling sedikit dibutuhkan {1}. +voteSkipEmbedNoVotes=Tidak ada suara untuk melewati jalur ini. +voteSkipEmbedVoters={0} dari {1} telah memilih untuk melewati jalur saat ini +mathOperationResult=Hasilnya adalah mathOperationDivisionByZeroError=Gua ga bisa bagi nol dengan nol >\:(. mathOperationInfinity=Angkanya terlalu besar untuk ditampilkan\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=Awalan +prefixGuild=Awalan untuk guild ini adalah {0} +prefixShowAgain=Anda bisa menunjukkan awalan kapan saja dengan menyebutkan saya. diff --git a/FredBoat/src/main/resources/lang/it_IT.properties b/FredBoat/src/main/resources/lang/it_IT.properties index f5ac79384..73811407d 100644 --- a/FredBoat/src/main/resources/lang/it_IT.properties +++ b/FredBoat/src/main/resources/lang/it_IT.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Sei limitato\! Per favore rallenta. ratelimitedSkipCommand=Si pu\u00f2 saltare pi\u00f9 di una canzone utilizzando questo comando\: {0} ratelimitedGuildSlowLoadingPlaylist=A questo server non \u00e8 consentito aggiungere pi\u00f9 playlist in questo momento. Per favore, non spam le liste di gioco lunghe. unblacklisted=Rimosso {0} dalla lista nera. -serverinfoTitle=Info su **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Utenti online\: serverinfoTotalUsers=Utenti totali\: serverinfoRoles=Ruoli\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID della gilda\: serverinfoCreationDate=Data di creazione\: serverinfoOwner=Proprietario\: serverinfoVLv=Verifica del testo\: -userinfoTitle=Informazioni su **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Nome utente\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Manutenzione commandsBotOwner=Proprietario di Bot commandsMoreHelp=Dire {0} per ottenere ulteriori informazioni su un comando specifico. helpUnknownCommand=Comando sconosciuto. -helpDM=La documentazione si trova a\:\nhttps\://fredboat.com/docs\n\nVuoi aggiungere FredBoat al tuo server? Se hai le autorizzazioni di Gestione Server per la tua gilda, puoi invitarlo qui\:\n* Questo non suona musica *\n\n\nSe vuoi aggiungere il bot di musica, vuoi invitare questo bot\:\n\n\nHai bisogno di aiuto o hai qualche idea per il bot? Forse vuoi solo uscire? Vieni al hangout di FredBoat\!\n{0}\n\nNon \u00e8 possibile inviare i comandi di bot tramite DM.\nBot creato da Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=La documentazione \u00e8 stata inviata ai vostri DM\! helpProperUsage=Utilizzo corretto\: helpCommandOwnerRestricted=Questo comando \u00e8 limitato al proprietario del bot. @@ -257,7 +261,7 @@ helpSayCommand=Fare il bot eco qualcosa. helpServerInfoCommand=Visualizzare alcune statistiche circa questa gilda. helpUserInfoCommand=Visualizzare le informazioni su di te o un utente noto al bot. helpPerms=Concedi ai ruoli e membri autorizzati il rank {0}. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Imposta il prefisso per questa gilda. helpVoteSkip=Votare per saltare il brano corrente. Ha bisogno del 50% di tutti gli utenti nella chat vocale per saltare. helpMathOperationAdd=Ti dice la somma del numero 1 e del numero 2. helpMathOperationSub=Ti dice la differenza tra il numero 1 e il numero 2. @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} su {1} hanno votato per saltare il brano mathOperationResult=Il risultato \u00e8 mathOperationDivisionByZeroError=Io non posso dividere per zero. mathOperationInfinity=Il numero \u00e8 troppo grande per essere visualizzato\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=Prefisso +prefixGuild=Il prefisso per questa gilda \u00e8 {0} +prefixShowAgain=Puoi visualizzare il prefisso ogni volta menzionandomi. diff --git a/FredBoat/src/main/resources/lang/ja_JP.properties b/FredBoat/src/main/resources/lang/ja_JP.properties index 49cfe5ff2..9b488f333 100644 --- a/FredBoat/src/main/resources/lang/ja_JP.properties +++ b/FredBoat/src/main/resources/lang/ja_JP.properties @@ -19,7 +19,7 @@ selectInterval=\u756a\u53f7 1-{0} \u3092\u9078\u629e\u3059\u308b\u5fc5\u8981\u30 selectSelectionNotGiven=\u6700\u521d\u306b\u9078\u629e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 shuffleOn=\u3053\u306e\u30d7\u30ec\u30a4\u30e4\u30fc\u306f\u30b7\u30e3\u30c3\u30d5\u30eb\u3055\u308c\u307e\u3057\u305f\u3002 shuffleOff=\u30d7\u30ec\u30a4\u30e4\u30fc\u306f\u30b7\u30e3\u30c3\u30d5\u30eb\u3055\u308c\u306a\u304f\u306a\u308a\u307e\u3057\u305f\u3002 -reshufflePlaylist=\u30ad\u30e5\u30fc\u304c\u518d\u7de8\u3055\u308c\u307e\u3057\u305f\u3002 +reshufflePlaylist=\u30ad\u30e5\u30fc\u3092\u3082\u3046\u4e00\u5ea6\u30b7\u30e3\u30c3\u30d5\u30eb\u3057\u307e\u3059\u3002 reshufflePlayerNotShuffling=\u307e\u305a\u3001\u30b7\u30e3\u30c3\u30d5\u30eb \u30e2\u30fc\u30c9\u3092\u30aa\u30f3\u306b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 skipEmpty=\u30ad\u30e5\u30fc\u306b\u4f55\u3082\u3042\u308a\u307e\u305b\u3093\uff01 skipOutOfBounds={1} \u30c8\u30e9\u30c3\u30af\u304c\u304c\u3042\u308b\u3068\u304d\u306f\u3001\u30c8\u30e9\u30c3\u30af\u756a\u53f7 {0} \u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002 @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u3042\u306a\u305f\u306f\u30ec\u30fc\u30c8\u5236\u9650\u3 ratelimitedSkipCommand=\u6b21\u306e\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u7528\u3057\u3066\u8907\u6570\u306e\u66f2\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff1a{0} ratelimitedGuildSlowLoadingPlaylist=\u73fe\u5728\u3001\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u3067\u306f\u3001\u3053\u308c\u4ee5\u4e0a\u30d7\u30ec\u30a4\u30ea\u30b9\u30c8\u3092\u8ffd\u52a0\u3059\u308b\u3053\u3068\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u9577\u3044\u30d7\u30ec\u30a4\u30ea\u30b9\u30c8\u3092\u30b9\u30d1\u30e0\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002 unblacklisted={0} \u3092\u30d6\u30e9\u30c3\u30af\u30ea\u30b9\u30c8\u304b\u3089\u6d88\u53bb\u3057\u307e\u3057\u305f\u3002 -serverinfoTitle=**{0}** \u306b\u95a2\u3057\u3066\u306e\u60c5\u5831\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u30aa\u30f3\u30e9\u30a4\u30f3\u30e6\u30fc\u30b6\u30fc\: serverinfoTotalUsers=\u5408\u8a08\u30e6\u30fc\u30b6\u30fc\u6570\uff1a serverinfoRoles=\u5f79\u5272\: @@ -193,7 +193,7 @@ serverinfoGuildID=\u30ae\u30eb\u30c9ID\: serverinfoCreationDate=\u4f5c\u6210\u65e5\: serverinfoOwner=\u30aa\u30fc\u30ca\u30fc\: serverinfoVLv=\u8a8d\u8a3c\u30ec\u30d9\u30eb\: -userinfoTitle=**{0}** \u306b\u95a2\u3059\u308b\u60c5\u5831\: +userinfoTitle=Information about {0}\: userinfoUsername=\u30e6\u30fc\u30b6\u30fc\u540d\uff1a userinfoId=ID\: userinfoNick=\u30cb\u30c3\u30af\u30cd\u30fc\u30e0\: @@ -212,7 +212,11 @@ commandsMaintenance=\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9 commandsBotOwner=bot\u306e\u30aa\u30fc\u30ca\u30fc commandsMoreHelp={0} \u3068\u767a\u8a00\u3059\u308b\u3053\u3068\u3067\u3001\u7279\u5b9a\u306e\u30b3\u30de\u30f3\u30c9\u306b\u3064\u3044\u3066\u306e\u60c5\u5831\u3092\u8a73\u3057\u304f\u8868\u793a\u3067\u304d\u307e\u3059\u3002 helpUnknownCommand=\u4e0d\u660e\u306a\u30b3\u30de\u30f3\u30c9\u3002 -helpDM=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306fhttps\://fredboat.com/docs\u306b\u3042\u308a\u307e\u3059\u3002\u30b5\u30fc\u30d0\u30fc\u306bFredBoat\u3092\u8ffd\u52a0\u3057\u307e\u3059\u304b\uff1f\u3042\u306a\u305f\u306e\u30ae\u30eb\u30c9\u306e\u30b5\u30fc\u30d0\u7ba1\u7406\u6a29\u9650\u304c\u3042\u308b\u5834\u5408\u306f\u3001\u3053\u3053\u306b\u62db\u5f85\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff1a*\u3053\u308c\u306f\u97f3\u697d\u3092\u518d\u751f\u3057\u307e\u305b\u3093\u3002*\n \n\n\u97f3\u697d\u30dc\u30c3\u30c8\u3092\u8ffd\u52a0\u3057\u305f\u3044\u5834\u5408\u306f\u3001\u3053\u306e\u30dc\u30c3\u30c8\uff1a\u30dc\u30c3\u30c8\u306e\n \n\n\u52a9\u3051\u3084\u30a2\u30a4\u30c7\u30a2\u304c\u5fc5\u8981\u3067\u3059\u304b\uff1f\u305f\u3076\u3093\u3042\u306a\u305f\u306f\u30cf\u30f3\u30b0\u30a2\u30a6\u30c8\u3057\u305f\u3044\u306e\u3067\u3059\u304b\uff1fFredBoat\u30cf\u30f3\u30b0\u30a2\u30a6\u30c8\u306b\u6765\u3066\u304f\u3060\u3055\u3044\uff01\n{0} \n\n\u3053\u306e\u30dc\u30c3\u30c8\u30b3\u30de\u30f3\u30c9\u3092DM\u7d4c\u7531\u3067\u9001\u4fe1\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002Fre_d\u306b\u3088\u3063\u3066\u4f5c\u6210\u3055\u308c\u305f\u30dc\u30c3\u30c8 +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u30d8\u30eb\u30d7\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092DM\u3067\u9001\u308a\u307e\u3057\u305f\uff01 helpProperUsage=\u9069\u5207\u306a\u4f7f\u7528\u65b9\u6cd5\: helpCommandOwnerRestricted=\u3053\u306e\u30b3\u30de\u30f3\u30c9\u306fbot\u306e\u30aa\u30fc\u30ca\u30fc\u306b\u3088\u3063\u3066\u5236\u9650\u3055\u308c\u3066\u3044\u307e\u3059\u3002 @@ -257,7 +261,7 @@ helpSayCommand=\u30dc\u30c3\u30c8\u30a8\u30b3\u30fc\u3092\u4f55\u304b\u306b\u305 helpServerInfoCommand=\u3053\u306e\u30ae\u30eb\u30c9\u306b\u95a2\u3057\u3066\u306e\u60c5\u5831\u3092\u3001\u3044\u304f\u3064\u304b\u8868\u793a\u3002 helpUserInfoCommand=\u81ea\u5206\u307e\u305f\u306f\u30dc\u30c3\u30c8\u306b\u77e5\u3089\u308c\u3066\u3044\u308b\u30e6\u30fc\u30b6\u30fc\u306b\u95a2\u3059\u308b\u60c5\u5831\u3092\u8868\u793a\u3057\u307e\u3059\u3002 helpPerms={0} \u30e9\u30f3\u30af\u306e\u30db\u30ef\u30a4\u30c8\u30ea\u30b9\u30c8\u30e1\u30f3\u30d0\u30fc\u3068\u30ed\u30fc\u30eb\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=\u3053\u306e\u30ae\u30eb\u30c9\u306e\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u8a2d\u5b9a\u3057\u307e\u3059\u3002 helpVoteSkip=\u73fe\u5728\u306e\u66f2\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b\u305f\u3081\u306b\u6295\u7968\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30dc\u30a4\u30b9\u30c1\u30e3\u30c3\u30c8\u306e\u5168\u30e6\u30fc\u30b6\u30fc\u306e50\uff05\u304c\u6295\u7968\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 helpMathOperationAdd=num1\u3068num2\u306e\u5408\u8a08\u3092\u51fa\u529b\u3057\u307e\u3059\u3002 helpMathOperationSub=num2\u304b\u3089num1\u3092\u5f15\u3044\u305f\u5dee\u3092\u51fa\u529b\u3057\u307e\u3059\u3002 @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} \u304b\u3089{1} \u3001\u73fe\u5728\u306e\u30c8\u30e9\u30 mathOperationResult=\u7d50\u679c\u306f\u6b21\u306e\u3068\u304a\u308a\u3067\u3059\u3002 mathOperationDivisionByZeroError=\u79c1\u306f\u30bc\u30ed\u3067\u5272\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002 mathOperationInfinity=\u6570\u5b57\u304c\u5927\u304d\u3059\u304e\u3066\u8868\u793a\u3067\u304d\u307e\u305b\u3093\u3002 -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9 +prefixGuild=\u3053\u306e\u30ae\u30eb\u30c9\u306e\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u306f {0} +prefixShowAgain=\u79c1\u306b\u8a00\u53ca\u3001\u3044\u3064\u3067\u3082\u518d\u3073\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u8868\u793a\u3067\u304d\u307e\u3059\u3002 diff --git a/FredBoat/src/main/resources/lang/ko_KR.properties b/FredBoat/src/main/resources/lang/ko_KR.properties index 641dfdbee..9409ad676 100644 --- a/FredBoat/src/main/resources/lang/ko_KR.properties +++ b/FredBoat/src/main/resources/lang/ko_KR.properties @@ -45,7 +45,7 @@ exportPlaylistFail=hastebin.com \uc5d0 \ud50c\ub808\uc774\ub9ac\uc2a4\ud2b8\ub97 listShowShuffled=\uc154\ud50c(\ub79c\ub364) \uae30\ub2a5\uc774 \uc801\uc6a9\ub41c \ud50c\ub808\uc774\ub9ac\uc2a4\ud2b8 \uc785\ub2c8\ub2e4.\n\n listShowRepeatSingle=\ud604\uc7ac \ud2b8\ub799\uc744 \ubc18\ubcf5\ud569\ub2c8\ub2e4 listShowRepeatAll=\ud604\uc7ac \ub300\uae30 \ubaa9\ub85d\uc744 \ubc18\ubcf5 \ud569\ub2c8\ub2e4 -listShowHistory=Showing tracks in history. +listShowHistory=\uc5ed\uc0ac\uc758 \ud754\uc801\ubcf4\uae30. listAddedBy=**{0}**, **{1}**\uc5d0 \uc758\ud574 \ucd94\uac00\ub428. `[{2}]` listStreamsOnlySingle=\ucd1d **{0}** \uac1c\uc758 \ub77c\uc774\ube0c {1} \uac00 \uc7ac\uc0dd \ud050\uc5d0 \uc788\uc2b5\ub2c8\ub2e4. listStreamsOnlyMultiple=\ucd1d **{0}** \uac1c\uc758 \ub77c\uc774\ube0c {1} \uac00 \uc7ac\uc0dd \ud050\uc5d0 \uc788\uc2b5\ub2c8\ub2e4. @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=, \ucd1d **{0}** \uac1c\uc758 \ub77c\uc774\ube0c {1} trackSingular=\ud2b8\ub799 trackPlural=\ud2b8\ub799 npNotPlaying=\ud604\uc7ac \uc7ac\uc0dd\uc911\uc778 \uc74c\uc545\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. -npNotInHistory=Currently no tracks in history. +npNotInHistory=\uc774\uc804 \ub0a0\uc528\ub97c \ucc3e\uc2b5\ub2c8\ub2e4 npDescription=\uc124\uba85 npLoadedSoundcloud=[{0}/{1}]\n\nSoundCloud\uc5d0\uc11c \ubd88\ub7ec\uc634 npLoadedBandcamp={0}\n\nBandcamp\uc5d0\uc11c \ubd88\ub7ec\uc634 @@ -133,7 +133,7 @@ brainfuckDataPointerOutOfBounds=\ub370\uc774\ud130 \ud3ec\uc778\ud130\uac00 \ubc brainfuckInputOOB={0} \uc704\uce58\uc5d0\uc11c \ud55c\uacc4\ub97c \ubc97\uc5b4\ub0ac\uc2b5\ub2c8\ub2e4. brainfuckNoOutput=\ucd9c\ub825\uc774 \uc5c6\uc5c8\ub2e4. weatherLocationNotFound=\uc704\uce58\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc785\ub825\uac12 {0}\uc744 \ud655\uc778\ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4. -weatherError=Error retrieving weather for {0} +weatherError={0} \uc5d0 \ub300 \ud55c \ub0a0\uc528\ub97c \uac80\uc0c9 \ud558\ub358 \ub3c4\uc911 \uc624\ub958 avatarSuccess=\uadf8\uac83\uc744 \ubc1c\uacac\n{0} configNoArgs=** {0} **\uc5d0 \ub300\ud55c \uad6c\uc131 \:``` configSetTo=\uc774\uc81c`{0}`\uc73c\ub85c \uc124\uc815\ub429\ub2c8\ub2e4. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\ub2f9\uc2e0\uc740 \uc18d\ub3c4\uac00 \uc81c\ud55c\ub418\ ratelimitedSkipCommand={0} \uba85\ub839\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud558\ub098 \uc774\uc0c1\uc758 \uace1\uc744 \uac74\ub108\ub6f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4. ratelimitedGuildSlowLoadingPlaylist=\uc774 \uc11c\ubc84\ub294 \ud604\uc7ac \uc7ac\uc0dd \ubaa9\ub85d\uc744 \ub354 \uc774\uc0c1 \ucd94\uac00\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uae34 \uc7ac\uc0dd \ubaa9\ub85d\uc744 \uc7ac\uc0dd\ud558\uc9c0 \ub9c8\uc2ed\uc2dc\uc624. unblacklisted=\ube14\ub799 \ub9ac\uc2a4\ud2b8\uc5d0\uc11c {0} \uc744(\ub97c) \uc81c\uac70\ud588\uc2b5\ub2c8\ub2e4. -serverinfoTitle=**{0}**\uc5d0 \ub300\ud55c \uc815\ubcf4. +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\uc628\ub77c\uc778 \uc720\uc800\ub4e4\: serverinfoTotalUsers=\ucd1d \uc720\uc800\ub4e4\: serverinfoRoles=\uc5ed\ud560\ub4e4\: @@ -193,17 +193,17 @@ serverinfoGuildID=\uae38\ub4dc \uc544\uc774\ub514\: serverinfoCreationDate=\uc0dd\uc131 \ub0a0\uc9dc\: serverinfoOwner=\uc8fc\uc778\: serverinfoVLv=\uc778\uc99d \ub808\ubca8\: -userinfoTitle=**{0}**\uc5d0 \ub300\ud55c \uc815\ubcf4. +userinfoTitle=Information about {0}\: userinfoUsername=\uc720\uc800\ub124\uc784\: userinfoId=\uc544\uc774\ub514\: userinfoNick=\ubcc4\uba85\: userinfoKnownServer=\uc544\ub294 \uc11c\ubc84\ub4e4\: userinfoJoinDate=\uac00\uc785 \ub0a0\uc9dc\: userinfoCreationTime=\uc0dd\uc131 \ub0a0\uc9dc\: -userinfoBlacklisted=Blacklisted\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +userinfoBlacklisted=\ube14\ub799 \ub9ac\uc2a4\ud2b8\: +skipDeniedTooManyTracks=Dj\uac00 \uc544\ub2cc\uacbd\uc6b0 \ub2e4\ub978\uc0ac\ub78c\uc758 \ub178\ub798\ub97c \uac74\ub108\ub6f8 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. Voteskip \uba85\ub839\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc2dc\ub294\uac83\uc774 \uc88b\uc2b5\ub2c8\ub2e4. eventUsersLeftVC=\ubaa8\ub4e0 \uc720\uc800\ub4e4\uc774 \uc74c\uc131 \ucc44\ub110\uc744 \ub5a0\ub0ac\uc2b5\ub2c8\ub2e4. \uc74c\uc545 \ud50c\ub808\uc774\uc5b4\uac00 \uc77c\uc2dc\uc911\uc9c0 \ub418\uc5c8\uc2b5\ub2c8\ub2e4. -eventAutoResumed=User presence detected, automatically resuming the player. +eventAutoResumed=\uc74c\uc131\uccb4\ub123\uc758 \uc0ac\uc6a9\uc790 \uac10\uc9c0\! \uc790\ub3d9\uc73c\ub85c \ub178\ub798\ub97c \ub2e4\uc2dc \uc2dc\uc791 \ud569\ub2c8\ub2e4\! commandsFun=\uc7ac\ubbf8 commandsMemes=\ubc08\ub4e4 commandsUtility=\uc720\ud2f8\ub9ac\ud2f0 @@ -212,7 +212,11 @@ commandsMaintenance=\uc810\uac80 commandsBotOwner=\ubd07 \uc8fc\uc778 commandsMoreHelp={0} \uc744 \ub9d0\ud558\uc5ec \ud2b9\uc815 \uba85\ub839\uc5b4\uc5d0 \ub300\ud55c \ub354 \ub9ce\uc740\uac83\uc744 \uc54c\uc544\ubcf4\uc138\uc694. helpUnknownCommand=\uc54c \uc218 \uc5c6\ub294 \uba85\ub839\uc5b4\uc785\ub2c8\ub2e4. -helpDM=\ubb38\uc11c\ub294 \uc774\uacf3\uc5d0\uc11c \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4.\nhttps\://fredboat.com/docs\n\n\ud504\ub808\ub4dc\ubcf4\ud2b8\ub97c \ub2f9\uc2e0\uc758 \uc11c\ubc84\uc5d0 \ucd94\uac00\ud558\uace0 \uc2f6\uc73c\uc2e0\uac00\uc694?\n\ub2f9\uc2e0\uc774 \uad00\ub9ac \uad8c\ud55c\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uba74 \uc5ec\uae30\uc11c \ucd08\ub300\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n*\uc774 \ubd07\uc740 \ubba4\uc9c1 \ud50c\ub808\uc774\uc5b4 \uae30\ub2a5\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.*\n\n\n\ubba4\uc9c1 \ud50c\ub808\uc774\uc5b4 \uae30\ub2a5\uc774 \uc788\ub294 \ubd07\uc740 \uc5ec\uae30\uc11c \ucd08\ub300\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\n\n\ub3c4\uc6c0\uc774 \ud544\uc694\ud558\uac70\ub098, \ubd07\uc5d0 \ub300\ud55c \uc544\uc774\ub514\uc5b4\uac00 \uc788\ub098\uc694?\n\uc544\ub2c8\uba74 \uadf8\uc800 \ub180\uace0\uc2f6\uc740\uac00\uc694? \ud504\ub808\ub4dc\ubcf4\ud2b8 \ud589\uc544\uc6c3\uc73c\ub85c \uc624\uc138\uc694\!\n{0}\n\n\ubd07 \uba85\ub839\uc5b4\ub294 DM\uc73c\ub85c \ubcf4\ub0bc \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uc774 \ubd07\uc740 Fre_d\uc5d0 \uc758\ud574 \uc81c\uc791\ub418\uc5c8\uc2b5\ub2c8\ub2e4. +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\ubb38\uc11c \uadc0\ud558\uc758 DMs\ub97c \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4\! helpProperUsage=\uc815\ud655\ud55c \uc0ac\uc6a9\ubc95\: helpCommandOwnerRestricted=\uc774 \uba85\ub839\uc5b4\ub294 \ubd07 \uc8fc\uc778\ub9cc \uc0ac\uc6a9 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. @@ -225,20 +229,20 @@ helpMusicCommandsHeader=\ud504\ub808\ub4dc\ubcf4\ud2b8 \uc74c\uc545 \uba85\ub839 helpJoinCommand=\ubd07\uc744 \ub2f9\uc2e0\uc774 \ud604\uc7ac \ub4e4\uc5b4\uac00 \uc788\ub294 \uc74c\uc131 \ucc44\ub110\uc5d0 \ub4e4\uc5b4\uac00\uac8c \ud558\uc138\uc694. helpLeaveCommand=\ubd07\uc744 \ud604\uc7ac \uc74c\uc131 \ucc44\ub110\uc5d0\uc11c \ub5a0\ub098\uac8c \ud558\uc138\uc694. helpPauseCommand=\ud50c\ub808\uc774\uc5b4\ub97c \uc77c\uc2dc \uc911\uc9c0 \ud569\ub2c8\ub2e4. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=\uc9c0\uc815\ub41c URL\uc5d0\uc11c \uc74c\uc545\uc744 \uc7ac\uc0dd\ud558\uac70\ub098 \ud2b8\ub799\uc744 \uac80\uc0c9\ud569\ub2c8\ub2e4. \uc804\uccb4 \uc18c\uc2a4 \ubaa9\ub85d\uc744 \ubcf4\ub824\uba74{0} \uc744(\ub97c) \ubc29\ubb38\ud558\uc2ed\uc2dc\uc624. helpPlaySplitCommand=\uc720\ud29c\ube0c \uc601\uc0c1\uc744 \uc124\uba85\uc5d0 \uc81c\uacf5\ub41c \ud2b8\ub799\ubaa9\ub85d\uc73c\ub85c \ub098\ub204\uc138\uc694. helpRepeatCommand=\ubc18\ubcf5 \ubaa8\ub4dc \uc5d0\uc11c \uc804\ud658\ud568 helpReshuffleCommand=\ud604\uc7ac \ub300\uae30 \ubaa9\ub85d\uc744 \ub2e4\uc2dc \uc154\ud50c \ud558\uc138\uc694. helpSelectCommand=\uac80\uc0c9 \ud6c4 \uc81c\uacf5\ub41c \ud2b8\ub799\uc911\uc5d0\uc11c \uc120\ud0dd\uc744 \ud558\uc5ec \uc7ac\uc0dd\ud558\uc138\uc694. helpShuffleCommand=\ud604\uc7ac \ub300\uae30\ubaa9\ub85d\uc744 \uc704\ud55c \uc154\ud50c \ubaa8\ub4dc\ub97c \ud0b5\ub2c8\ub2e4. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpSkipCommand=\ud604\uc7ac \uace1, N\ubc88\uc9f8 \uace1, \ubaa8\ub4e0 \ub178\ub798, \ub610\ub294 \uc5b8\uae09\ub41c \uc0ac\uc6a9\uc790\uc758 \ubaa8\ub4e0 \ub178\ub798\ub97c \uac74\ub108\ub701\ub2c8\ub2e4. \uc801\ub2f9\ud788 \uc0ac\uc6a9\ud574 \uc8fc\uc138\uc694. helpStopCommand=\ud50c\ub808\uc774\uc5b4\ub97c \uc911\uc9c0\ud558\uace0 \ud50c\ub808\uc774\ub9ac\uc2a4\ud2b8\ub97c \uae54\ub054\ud558\uac8c \uc0ad\uc81c\ud569\ub2c8\ub2e4. \uba54\uc2dc\uc9c0 \uad00\ub9ac \uad8c\ud55c\uc774 \uc788\ub294 \uad00\ub9ac\uc790\ub4e4\ud55c\ud14c \uad8c\ud55c\uc774 \uc788\uc2b5\ub2c8\ub2e4. helpUnpauseCommand=\ud50c\ub808\uc774\uc5b4\ub97c \ub2e4\uc2dc \uc7ac\uc0dd \ud569\ub2c8\ub2e4. helpVolumeCommand=\uc74c\uc545\uc758 \ubcfc\ub968\uc744 \uc870\uc808\ud569\ub2c8\ub2e4. \uc22b\uc790 0-150 \uc0ac\uc774\uc5d0\uc11c \uc870\uc808\uc774 \uac00\ub2a5\ud569\ub2c8\ub2e4 \uae30\ubcf8 \uac12\uc740 100 \uc785\ub2c8\ub2e4. \ubcfc\ub968 \uba85\ub839\uc5b4\ub294 \uc77c\ubc18\ubd07\uc5d0\uc11c\ub294 \uc0ac\uc6a9\uc744 \ud558\uc2e4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. helpExportCommand=Hastebin \ub9c1\ud06c\ub85c \ud604\uc7ac \ub300\uae30 \ubaa9\ub85d\uc744 \ube7c\uac11\ub2c8\ub2e4, \ub098\uc911\uc5d0 \uc7ac\uc0dd \ubaa9\ub85d\uc73c\ub85c \uc0ac\uc6a9 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. helpGensokyoRadioCommand=\uc9c0\uae08 gensokyoradio.net \uc5d0\uc11c \uc7ac\uc0dd\ub418\uace0 \uc788\ub294 \uc74c\uc545\uc744 \ubcf4\uc5ec\uc90d\ub2c8\ub2e4. helpListCommand=\uc7ac\uc0dd \ubaa9\ub85d\uc5d0 \uc788\ub294 \ud604\uc7ac \uc74c\uc545\uc758 \ubaa9\ub85d\uc744 \ubcf4\uc5ec\uc90d\ub2c8\ub2e4. -helpHistoryCommand=Display a list of the songs in playlist history. +helpHistoryCommand=\uc7ac\uc0dd \ubaa9\ub85d \ubaa9\ub85d\uc5d0 \uace1 \ubaa9\ub85d\uc744 \ud45c\uc2dc\ud569\ub2c8\ub2e4. helpNowplayingCommand=\ud604\uc7ac \uc7ac\uc0dd\ub418\uace0 \uc788\ub294 \uc74c\uc545\uc744 \ubcf4\uc5ec\uc90d\ub2c8\ub2e4. helpForwardCommand=\ud2b8\ub799\uc744 \uc8fc\uc5b4\uc9c4 \uc2dc\uac04\uc73c\ub85c \ud2b8\ub799\uc744 \ub418\uac10\uc2b5\ub2c8\ub2e4.\n\uc608\: helpRestartCommand=\ud604\uc7ac \ud2b8\ub799\uc744 \uc7ac\uc2dc\uc791 \ud569\ub2c8\ub2e4. @@ -246,7 +250,7 @@ helpRewindCommand=\ud2b8\ub799\uc744 \uc8fc\uc5b4\uc9c4 \uc2dc\uac04\uc73c\ub85c helpSeekCommand=\uc8fc\uc5b4\uc9c4 \uc2dc\uac04\uc73c\ub85c \ud2b8\ub799\uc758 \uc704\uce58\ub97c \uc124\uc815\ud569\ub2c8\ub2e4.\n\uc608\: helpAvatarCommand=\uc720\uc800\uc758 \uc544\ubc14\ud0c0\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4. helpBrainfuckCommand=Brainfuck \ucf54\ub4dc\ub97c \uc2e4\ud589\ud569\ub2c8\ub2e4. \uc608\: -helpWeatherCommand=Display current weather by location. +helpWeatherCommand=\ud604\uc7ac \uc704\uce58\ubcc4\ub85c \ud604\uc7ac \ub0a0\uc528\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4. helpClearCommand=\uc774 \ubd07\uc758 50\uac1c\uc758 \uba54\uc2dc\uc9c0\ub97c \uc774 \ucc44\ub110\uc5d0\uc11c \uc0ad\uc81c \ud569\ub2c8\ub2e4. helpCommandsCommand=\uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uba85\ub839\uc744 \ud45c\uc2dc \ud569\ub2c8\ub2e4. helpHelpCommand=\uc774 \ubd07\uc5d0 \ub300\ud55c \ub3c4\uc6c0\uc744 \ubc1b\uac70\ub098 \uc544\ubb34 \uba85\ub839\uc5b4\uc5d0 \ub300\ud55c \ub3c4\uc6c0\uc744 \ubc1b\uc73c\uc138\uc694. @@ -257,16 +261,16 @@ helpSayCommand=\ubd07\uc774 \ubb34\uc5b8\uac00\ub97c \uc5d0\ucf54\ud558\uac8c \u helpServerInfoCommand=\uc774 \uae38\ub4dc\uc5d0 \ub300\ud55c \uba87 \uac00\uc9c0 \ud1b5\uacc4\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4. helpUserInfoCommand=\ub2f9\uc2e0\uc758 \ub300\ud55c \uc815\ubcf4\ub098 \ubd07\uc774 \uc544\ub294 \ub2e4\ub978 \uc720\uc800\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4. helpPerms={0} \uad8c\ud55c\uc758 \uc720\uc800\uc640 \uc5ed\ud560\uc5d0 \ub300\ud55c \ud654\uc774\ud2b8\ub9ac\uc2a4\ud305\uc744 \ud5c8\uc6a9\ud569\ub2c8\ub2e4. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=\uc774 \uc11c\ubc84\uc758 \uc811\ub450\uc0ac( prefix) \ub97c \uc124\uc815\ud558\uc138\uc694. helpVoteSkip=\uc774 \uc74c\uc545\uc744 \uac74\ub108\ub6f0\uae30 \uc704\ud574 \ud22c\ud45c\ud558\uc2ed\uc2dc\uc624. \uc74c\uc131 \ucc44\ud305\ubc29\uc5d0 \uc788\ub294 50% \uc774\uc0c1\uc758 \uc720\uc800\uc758 \ud22c\ud45c\uac00 \ud544\uc694\ud569\ub2c8\ub2e4. -helpMathOperationAdd=Print the sum of num1 and num2. -helpMathOperationSub=Print the difference of subtracting num2 from num1. -helpMathOperationMult=Print the product of num1*num2. -helpMathOperationDiv=Print the quotient of dividing num1 by num2. -helpMathOperationMod=Print the remainder of dividing num1 by num2. -helpMathOperationPerc=Print the percentage represented by num1 in num2. -helpMathOperationSqrt=Print the square root of num. -helpMathOperationPow=Print the result of num1^num2. +helpMathOperationAdd=Num1\uacfc num2\uc758 \ud569\uacc4\ub97c \ucd9c\ub825\ud569\ub2c8\ub2e4. +helpMathOperationSub=Num1 \uc5d0\uc11c num2\ub97c \ube80 \ucc28\uc774\ub97c \ucd9c\ub825\ud569\ub2c8\ub2e4. +helpMathOperationMult=Num1\uacfcnum2 \ub97c \uacf1\ud55c\uac12\uc744 \ucd9c\ub825\ud569\ub2c8\ub2e4 +helpMathOperationDiv=Num2 num1 \ub098\ub208 \ubaab\uc744 \ucd9c\ub825 \ud569\ub2c8\ub2e4. +helpMathOperationMod=Num2 num1 \ub098\ub208 \ub098\uba38\uc9c0\ub97c \ucd9c\ub825 \ud569\ub2c8\ub2e4. +helpMathOperationPerc=Num1 num2\uc5d0\uc11c \ub098\ud0c0\ub0b4\ub294 \ubc31\ubd84\uc728\uc744 \ucd9c\ub825 \ud569\ub2c8\ub2e4. +helpMathOperationSqrt=\uc22b\uc790\uc758 \uc81c\uacf1\uadfc\uc744 \ucd9c\ub825 +helpMathOperationPow=Num1^num2 \uc758 \uac12\uc744 \ucd9c\ub825 destroyDenied=\ud50c\ub808\uc774\uc5b4\ub97c \uc7ac\uc124\uc815\ud558\ub824\uba74 \uba54\uc2dc\uc9c0 \uad00\ub9ac \uad8c\ud55c\uc774 \uc788\uc5b4\uc57c \ud569\ub2c8\ub2e4. destroyHelp=\ud50c\ub808\uc774\uc5b4\ub97c \uc7ac\uc124\uc815\ud558\uace0 \uc7ac\uc0dd \ubaa9\ub85d\uc744 \uc9c0\uc6c1\ub2c8\ub2e4. \uba54\uc2dc\uc9c0 \uad00\ub9ac \uad8c\ud55c\uc744 \uac00\uc9c4 \uc870\uc815\uc790\uc6a9\uc73c\ub85c \uc608\uc57d\ub418\uc5c8\uc2b5\ub2c8\ub2e4. destroySucc=\ud50c\ub808\uc774\uc5b4\ub97c \uc7ac\uc124\uc815\ud558\uace0 \ud050\ub97c \uc0ad\uc81c\ud569\ub2c8\ub2e4. @@ -275,21 +279,21 @@ permsListTitle={0} \uad8c\ud55c\uc758 \uc720\uc800\uc640 \uc5ed\ud560 permsAdded=`{0}`\uc744 `{1}`\uc5d0 \ucd94\uac00\ud588\uc2b5\ub2c8\ub2e4. permsRemoved=`{0}`\uc744 `{1}`\uc5d0\uc11c \uc81c\uac70\ud588\uc2b5\ub2c8\ub2e4. permsFailSelfDemotion=\uad00\ub9ac\uc790 \uad8c\ud55c\uc774 \uc5c6\uc774\ub294 \uc81c\uac70\uac00 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4. -permsAlreadyAdded={0} already added to {1} -permsNotAdded={0} is not in {1} +permsAlreadyAdded={0} \uc774(\uac00) \uc774\ubbf8{1} \uc5d0 \ucd94\uac00\ub418\uc5c8\uc2b5\ub2c8\ub2e4. +permsNotAdded={0} \uc774(\uac00){1} \uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4. fuzzyMultiple=\uc5ec\ub7ec \ud56d\ubaa9\uc744 \ucc3e\uc558\uc2b5\ub2c8\ub2e4. \ubb34\uc5c7\uc744 \uc120\ud0dd\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c? fuzzyNothingFound=`{0}`\uc744 \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. cmdPermsTooLow=\uc774 \uba85\ub839\uc5b4\ub97c \uc2e4\ud589\ud558\uae30 \uc704\ud55c \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. \uc2e4\ud589\ud558\uae30 \uc704\ud574\uc11c\ub294 `{0}` \uad8c\ud55c\uc774 \ud544\uc694\ud569\ub2c8\ub2e4. playersLimited=\ud504\ub808\ub4dc\ubcf4\ud2b8\uc758 \uc6a9\ub7c9\uc774 \uac00\ub4dd \ucc3c\uc2b5\ub2c8\ub2e4\! \uc9c0\uae08 \ud504\ub808\ub4dc\ubcf4\ud2b8\ub294 \ucd5c\ub300 `{0}`\uacf3\uc5d0\uc11c \uc5f0\uacb0\ud560 \uc218 \uc788\ub3c4\ub85d \uc81c\ud55c\ub418\uc5b4\uc788\uc73c\uba70, \uadf8\ub807\uc9c0 \uc54a\uc73c\uba74 \ub124\ud2b8\uc6cc\ud06c \ubd80\ud558\ub85c \uc778\ud574 \ub514\uc2a4\ucf54\ub4dc\uc5d0\uc11c \uc5f0\uacb0\uc774 \ub04a\uc5b4\uc9d1\ub2c8\ub2e4.\n\uc6b0\ub9ac\ub97c \ub3c4\uc640 \uc81c\ud55c\uc744 \uc62c\ub9ac\uac70\ub098 \ubd80\ud558\ub418\uc9c0 \uc54a\uc740 \ubd07\uc744 \uc0ac\uc6a9\ud558\uace0\uc2f6\ub2e4\uba74, \ud30c\ud2b8\ub808\uc628\uc5d0\uc11c \uc791\uc5c5\uc744 \ub3c4\uc640\uc8fc\uc2ed\uc2dc\uc624.\n{1}\n\n\ubd88\ud3b8\uc744 \ub07c\uccd0 \ub4dc\ub824 \uc8c4\uc1a1\ud569\ub2c8\ub2e4\! \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574 \uc8fc\uc138\uc694.\n\uc774 \uba54\uc2dc\uc9c0\ub294 \ubcf4\ud1b5 \ud53c\ud06c\ud0c0\uc784\uc5d0 \ub098\ud0c0\ub0a9\ub2c8\ub2e4. tryLater=\ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574 \uc8fc\uc138\uc694. skipUserSingle={1}\uac00 \ucd94\uac00\ud55c {0}\uc744 \uac74\ub108\ub6f0\uc5c8\uc2b5\ub2c8\ub2e4. -skipUserMultiple=Skipped {0} tracks added by {1}. -skipUsersMultiple=Skipped {0} tracks added by {1} users. -skipUserNoTracks=None of the mentioned users have any tracks queued. -voteSkipAdded=Your vote has been added\! -voteSkipAlreadyVoted=You already voted to skip this track\! -voteSkipSkipping={0} have voted to skip. Skipping track {1}. -voteSkipNotEnough={0} have voted to skip. At least {1} needed. +skipUserMultiple={1} \uac1c\uc758 \ucd94\uc801\ub41c{0} \uac1c\uc758 \ud2b8\ub799\uc774 \ucd94\uac00\ub418\uc5c8\uc2b5\ub2c8\ub2e4. +skipUsersMultiple={1} \uc0ac\uc6a9\uc790\uac00 \ucd94\uac00\ud55c \uac74\ub108\ub6f4\ub41c {0} \ucd94\uc801 \ud569\ub2c8\ub2e4. +skipUserNoTracks=\uc5b8\uae09 \ud55c \uc0ac\uc6a9\uc790 \uc911 \ub204\uad6c\ub3c4 \uc5b4\ub5a4 \ud2b8\ub799 \ub300\uae30. +voteSkipAdded=\ud22c\ud45c \ucd94\uac00 \ub418\uc5c8\uc2b5\ub2c8\ub2e4\! +voteSkipAlreadyVoted=\ub2f9\uc2e0\uc740 \uc774\ubbf8\uc774 \ud2b8\ub799\uc744 \uac74\ub108\ub6f8 \ud558\uae30\ub85c \uacb0\uc815\! +voteSkipSkipping={0} \uba85\uc774 \uc2a4\ud0b5\uc5d0 \ub3d9\uc758\ud574 {1} \ud2b8\ub799\uc744 \uc2a4\ud0b5\ud569\ub2c8\ub2e4. +voteSkipNotEnough={0} \uba85\uc774 \uc2a4\ud0b5\uc5d0 \ub3d9\uc758\ud588\uc9c0\ub9cc \uc2a4\ud0b5 \ucd5c\uc18c \uc778\uc6d0 ({1} \uba85) \uc5d0 \ubbf8\uce58\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4. voteSkipEmbedNoVotes=No votes to skip this track yet. voteSkipEmbedVoters={0} out of {1} have voted to skip the current track mathOperationResult=\uacb0\uacfc\uac12\uc740 diff --git a/FredBoat/src/main/resources/lang/ms_MY.properties b/FredBoat/src/main/resources/lang/ms_MY.properties index a6c6602c3..795bccc61 100644 --- a/FredBoat/src/main/resources/lang/ms_MY.properties +++ b/FredBoat/src/main/resources/lang/ms_MY.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Kadar anda sedang dihadkan\! Sila perlahankan. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=Server ini tidak dibenarkan untuk menambah lagi senarai main buat masa sekarang. Mohon jangan spam senerai main yang panjang. unblacklisted={0} dibuang dari senarai hitam. -serverinfoTitle=Info about **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Users\: serverinfoTotalUsers=Total Users\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Creation Date\: serverinfoOwner=Owner\: serverinfoVLv=Verification Level\: -userinfoTitle=Information about **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Username\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/nl_NL.properties b/FredBoat/src/main/resources/lang/nl_NL.properties index 61a4f6c05..c0750636a 100644 --- a/FredBoat/src/main/resources/lang/nl_NL.properties +++ b/FredBoat/src/main/resources/lang/nl_NL.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Je gebruikt de opdrachten te snel\! Langzamer aan, alsjeb ratelimitedSkipCommand=Je kunt meer dan 1 nummer overslaan met deze opdracht\: {0} ratelimitedGuildSlowLoadingPlaylist=Op deze server is niet toegestaan om meer afspeellijsten toe te voegen op dit moment, gelieve geen lange afspeellijsten herhaaldelijk aan te vragen. unblacklisted={0} is verwijderd van de Zwarte lijst. -serverinfoTitle=Info over **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Gebruikers\: serverinfoTotalUsers=Totaal Aantal Gebruikers\: serverinfoRoles=Rollen\: @@ -193,7 +193,7 @@ serverinfoGuildID=Gilde ID\: serverinfoCreationDate=Aanmaakdatum\: serverinfoOwner=Eigenaar\: serverinfoVLv=Verificatie Level\: -userinfoTitle=Informatie over **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Gebruikersnaam\: userinfoId=ID\: userinfoNick=Bijnaam\: @@ -212,7 +212,11 @@ commandsMaintenance=Onderhoud commandsBotOwner=Bot eigenaar commandsMoreHelp=Zeg {0} om meer informatie te krijgen over een specifieke opdracht. helpUnknownCommand=Onbekende opdracht. -helpDM=De documentatie kan hier worden gevonden\:\nhttps\://fredboat.com/docs\n\nWil je FredBoat op je eigen server? Als je server beheer rechten hebt voor je Gilde, dan kan je het hier uitnodigen\:\n*Deze bot speelt geen muziek*\n\n\nAls je muziek bot wilt toevoegen, dan kan je deze bot hier uitnodigen\:\n\n\nHeb je hulp nodig of heb je idee\u00ebn voor de bot? Of wil je lekker rondhangen? Kom dan lekker naar de FredBoat Hangout\!\n{0}\n\nJe kan geen opdrachten via DM naar deze bot versturen.\nBot is gemaakt door Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=De documenten met instructies zijn naar Uw Directe Berichten verstuurd\! helpProperUsage=Correcte gebruik\: helpCommandOwnerRestricted=Deze opdracht is beperkt tot de eigenaar van de bot. @@ -257,7 +261,7 @@ helpSayCommand=Laat de bot iets echo\u00ebn. helpServerInfoCommand=Laat een aantal statistieken zien over deze gild. helpUserInfoCommand=Toon informatie over jezelf of een gebruiker die bekend is met de bot. helpPerms=Laat de {0} rang leden en rollen op de witte lijst zetten. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Stel de prefix in voor deze guild. helpVoteSkip=Stem om het huidige nummer te kunnen overslaan. Minstens 50% van alle gebruikers in de voice chat moeten mee stemmen. helpMathOperationAdd=Print de sum van num 1 en num2. helpMathOperationSub=Print het verschil tussen het aftrekken van num2 en van num1. @@ -296,6 +300,6 @@ mathOperationResult=Het resultaat is mathOperationDivisionByZeroError=Ik kan niet delen door nul. mathOperationInfinity=Het nummer is te groot om te laten zien\! prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefixGuild=De prefix van deze guild is {0} +prefixShowAgain=Je kan de prefix zien als je mij pinged. diff --git a/FredBoat/src/main/resources/lang/no_NO.properties b/FredBoat/src/main/resources/lang/no_NO.properties index 2fcd2849d..8f4095c6b 100644 --- a/FredBoat/src/main/resources/lang/no_NO.properties +++ b/FredBoat/src/main/resources/lang/no_NO.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Du sender kommandoer for fort\! Ro ned tempoet. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=Denne serveren f\u00e5r ikke legge til flere spillelister for \u00f8yeblikket. Vennligst unng\u00e5 \u00e5 spamme lange spillelister. unblacklisted=Fjernet {0} fra sperrelisten. -serverinfoTitle=Info om **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=P\u00e5loggede brukere\: serverinfoTotalUsers=Totalt antall brukere\: serverinfoRoles=Roller\: @@ -193,7 +193,7 @@ serverinfoGuildID=Laug-ID\: serverinfoCreationDate=Opprettelsesdato\: serverinfoOwner=Eier\: serverinfoVLv=Verifikasjon niv\u00e5\: -userinfoTitle=Informasjon om **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=Brukernavn\: userinfoId=ID\: userinfoNick=Kallenavn\: @@ -212,7 +212,11 @@ commandsMaintenance=Vedlikehold commandsBotOwner=Bot eier commandsMoreHelp=Si {0} for \u00e5 f\u00e5 mer informasjon om en bestemt kommando. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Dokumentasjon er sendt til DMs\! helpProperUsage=Riktig bruk\: helpCommandOwnerRestricted=Denne kommandoen er begrenset til eieren av botten. diff --git a/FredBoat/src/main/resources/lang/pl_PL.properties b/FredBoat/src/main/resources/lang/pl_PL.properties index f9e5fffac..e74e524ba 100644 --- a/FredBoat/src/main/resources/lang/pl_PL.properties +++ b/FredBoat/src/main/resources/lang/pl_PL.properties @@ -45,7 +45,7 @@ exportPlaylistFail=Wyst\u0105pi\u0142 b\u0142\u0105d podczas przesy\u0142ania pl listShowShuffled=Pokazano wymieszan\u0105 list\u0119 odtwarzania.\n\n listShowRepeatSingle=Powtarzanie bie\u017c\u0105cych utwor\u00f3w. listShowRepeatAll=Powtarzanie bie\u017c\u0105cej kolejki. -listShowHistory=poka\u017c histori\u0119 utwor\u00f3w +listShowHistory=Pokazuj\u0119 histori\u0119 utwor\u00f3w. listAddedBy=**{0} ** dodane przez **{1} ** ''[{2}]'' listStreamsOnlySingle=Znajduje si\u0119 **{0}** na \u017cywo {1} w kolejce. listStreamsOnlyMultiple=Znajduj\u0105 si\u0119 **{0}** na \u017cywo {1} w kolejce. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Jeste\u015b ograniczony od stawek. Prosz\u0119 zwolnij. ratelimitedSkipCommand=Za pomoc\u0105 tego polecenia mo\u017cna pomin\u0105\u0107 wi\u0119cej ni\u017c jednej piosenk\u0119\: {0} ratelimitedGuildSlowLoadingPlaylist=W tej chwili nie mo\u017cna doda\u0107 wi\u0119cej list na tym serwerze. Prosz\u0119 nie spam d\u0142ugimi listami. unblacklisted={0} usuni\u0119ty z czarnej listy. -serverinfoTitle=Informacje o **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=U\u017cytkownik\u00f3w online\: serverinfoTotalUsers=U\u017cytkownik\u00f3w razem\: serverinfoRoles=Role\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID Gildii\: serverinfoCreationDate=Data Utworzenia\: serverinfoOwner=W\u0142a\u015bciciel\: serverinfoVLv=Poziom weryfikacji\: -userinfoTitle=Informacje o **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=Nazwa u\u017cytkownika\: userinfoId=ID\: userinfoNick=Nick\: @@ -212,7 +212,11 @@ commandsMaintenance=Przerwa Techniczna commandsBotOwner=W\u0142a\u015bciciel bota commandsMoreHelp=Napisz {0} aby dosta\u0107 wi\u0119cej informacji o specyficznej komendzie. helpUnknownCommand=Nieznana komenda. -helpDM=Dokumentacje znajdziesz poni\u017cej\:\nhttps\://fredboat.com/docs\n\nChcesz zaprosi\u0107 FredBoata na sw\u00f3j serwer? Je\u017celi masz uprawnienia do zarz\u0105dzania swoj\u0105 gildi\u0105, zapro\u015b go tu\:\n*Ten bot nie odtwarza muzyki*\n\n\nJe\u017celi chcesz doda\u0107 Musicbota, zapro\u015b go tu.\:\n\n\nPotrzebujesz pomocy lub masz pomys\u0142y jak ulepszy\u0107 bota? A mo\u017ce tylko chcesz sp\u0119dzi\u0107 sw\u00f3j czas? Cho\u0107 na sp\u0119dzanie czasu z FredBoatem\!\n{0}\n\nNie mozesz wysylac komend poprzez prywatna wiadomosc.\nBot stworzony przez Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Dokumentacja zosta\u0142a wys\u0142ana do swojego Na prywatn\u0105 wiadomo\u015b\u0107\! helpProperUsage=Poprawne zastosowanie\: helpCommandOwnerRestricted=Ta komenda jest tylko ograniczona dla W\u0142a\u015bciciela bota. @@ -257,7 +261,7 @@ helpSayCommand=Zr\u00f3b Botowi Echo Co\u015b. helpServerInfoCommand=Wy\u015bwietl niekt\u00f3re statystyki dotycz\u0105ce tej gildii. helpUserInfoCommand=Wy\u015bwietlanie informacji o sobie lub u\u017cytkowniku znanemu przez bot'a. helpPerms=Pozwala gracz\u0105 kt\u00f3rzy s\u0105 w bia\u0142ej li\u015bcie oraz rangach z {0} rang. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Ustaw prefiks dla tego serwera. helpVoteSkip=G\u0142osuj, aby pomin\u0105\u0107 bie\u017c\u0105c\u0105 piosenk\u0119. Do g\u0142osowania potrzeba 50% wszystkich u\u017cytkownik\u00f3w czatu g\u0142osowego. helpMathOperationAdd=Wydrukuj sum\u0119 liczb1 i num2. helpMathOperationSub=Print the difference of subtracting num2 from num1. @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} spo\u015br\u00f3d {1} g\u0142osowali, aby pomin\u0105\u0 mathOperationResult=Wynik jest mathOperationDivisionByZeroError=Ja nie mo\u017cna dzieli\u0107 przez zero. mathOperationInfinity=Liczba jest zbyt du\u017ca, aby by\u0107 wy\u015bwietlane\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=Prefiks +prefixGuild=Prefiks tego serwera to {0} +prefixShowAgain=Mo\u017cesz wy\u015bwietli\u0107 prefiks, za ka\u017cdym razem, kiedy mnie wspomnisz. diff --git a/FredBoat/src/main/resources/lang/pt_BR.properties b/FredBoat/src/main/resources/lang/pt_BR.properties index 06a130c89..c482e3c31 100644 --- a/FredBoat/src/main/resources/lang/pt_BR.properties +++ b/FredBoat/src/main/resources/lang/pt_BR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Voc\u00ea est\u00e1 sendo taxa limitada\! Por favor, deva ratelimitedSkipCommand=Voc\u00ea pode pular mais de uma m\u00fasica usando este comando\: {0} ratelimitedGuildSlowLoadingPlaylist=Neste servidor n\u00e3o \u00e9 permitido adicionar playlists mais neste momento. Por favor n\u00e3o spam longas listas de reprodu\u00e7\u00e3o. unblacklisted={0} removido da lista negra. -serverinfoTitle=Informa\u00e7\u00e3o sobre * *{0} * *\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Usu\u00e1rios online\: serverinfoTotalUsers=Total de usu\u00e1rios\: serverinfoRoles=Pap\u00e9is\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID da Guilda\: serverinfoCreationDate=Data de cria\u00e7\u00e3o\: serverinfoOwner=Dono\: serverinfoVLv=N\u00edvel de Verifica\u00e7\u00e3o\: -userinfoTitle=Informa\u00e7\u00f5es sobre * *{0} * *\: +userinfoTitle=Information about {0}\: userinfoUsername=Nome de Usu\u00e1rio\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Manuten\u00e7\u00e3o commandsBotOwner=Dono do Bot commandsMoreHelp=Diga {0} para obter mais informa\u00e7\u00f5es sobre um comando espec\u00edfico. helpUnknownCommand=Comando desconhecido. -helpDM=A documenta\u00e7\u00e3o pode ser encontrada em\:\nhttps\://fredboat.com/docs\n\nQuer adicionar o FredBoat ao seu servidor? Se voc\u00ea tem as permiss\u00f5es de Gerenciar Servidor na sua guilda, voc\u00ea pode convida-lo aqui\:\n*Esse n\u00e3o reproduz m\u00fasica*\n\n\nSe voc\u00ea quer adicionar o bot de m\u00fasica, voc\u00ea vai querer convidar esse bot\:\n\n\nPrecisa de ajuda ou tem alguma ideia para o bot? Talvez voc\u00ea s\u00f3 queira relaxar? Venha para o FredBoat hangout\!\n{0}\n\nVoc\u00ea n\u00e3o pode mandar comandos para esse bot por DM.\nBot criado por Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documenta\u00e7\u00e3o foi enviada para seus DMs\! helpProperUsage=Uso correto\: helpCommandOwnerRestricted=Este comando \u00e9 restrito para o dono do bot. @@ -257,7 +261,7 @@ helpSayCommand=Fazer o bot ecoar algo. helpServerInfoCommand=Exibe algumas estat\u00edsticas sobre esta guilda. helpUserInfoCommand=Exibe informa\u00e7\u00f5es sobre voc\u00ea ou um usu\u00e1rio conhecido para o bot. helpPerms=Permite que membros de whitelisting e fun\u00e7\u00f5es para o posto de {0}. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Defina o prefixo para essa guilda. helpVoteSkip=Vote para ignorar a m\u00fasica atual. Precisa que 50% de todos os usu\u00e1rios no bate-papo votem. helpMathOperationAdd=Imprime a soma do num1 e num2. helpMathOperationSub=Mostra a diferen\u00e7a entre a sub-faixa num2 para a num1. @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} de {1} votaram para pular a faixa atual mathOperationResult=O resultado \u00e9 mathOperationDivisionByZeroError=Eu n\u00e3o posso dividir por zero. mathOperationInfinity=O n\u00famero \u00e9 muito grande para ser exibido\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} +prefix=Prefixo +prefixGuild=O prefixo para essa guild \u00e9 {0} prefixShowAgain=You can show the prefix anytime again by mentioning me. diff --git a/FredBoat/src/main/resources/lang/pt_PT.properties b/FredBoat/src/main/resources/lang/pt_PT.properties index eba02c434..063a33098 100644 --- a/FredBoat/src/main/resources/lang/pt_PT.properties +++ b/FredBoat/src/main/resources/lang/pt_PT.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Voc\u00ea est\u00e1 sendo taxa limitada\! Por favor, abra ratelimitedSkipCommand=Voc\u00ea podes pular mais que uma m\u00fasica usando este comando\: {0} ratelimitedGuildSlowLoadingPlaylist=Neste servidor n\u00e3o \u00e9 permitido adicionar mais playlists de momento. Por favor n\u00e3o spame longas listas de reprodu\u00e7\u00e3o. unblacklisted={0} removido da lista negra. -serverinfoTitle=Informa\u00e7\u00e3o sobre * *{0} * *\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Usu\u00e1rios online\: serverinfoTotalUsers=Total de usu\u00e1rios\: serverinfoRoles=Fun\u00e7\u00f5es\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID de guilda\: serverinfoCreationDate=Data de cria\u00e7\u00e3o\: serverinfoOwner=Propriet\u00e1rio\: serverinfoVLv=N\u00edvel de verifica\u00e7\u00e3o\: -userinfoTitle=Informa\u00e7\u00f5es sobre * *{0} * *\: +userinfoTitle=Information about {0}\: userinfoUsername=Nome de usu\u00e1rio\: userinfoId=ID\: userinfoNick=Usu\u00e1rio\: @@ -212,7 +212,11 @@ commandsMaintenance=Manuten\u00e7\u00e3o commandsBotOwner=Dono do bot commandsMoreHelp=Diga {0} para obter mais informa\u00e7\u00f5es sobre um comando espec\u00edfico. helpUnknownCommand=Comando desconhecido. -helpDM=A documenta\u00e7\u00e3o pode ser encontrada em\:\nhttps\://fredboat.com/docs\n\nQuer adicionar o FredBoat ao seu servidor? Se voc\u00ea tem as permiss\u00f5es de Gerenciar Servidor em seu servidor, voc\u00ea pode convida-lo aqui\:\n*Esse n\u00e3o reproduz m\u00fasica*\n\n\nSe voc\u00ea quer adicionar o bot de m\u00fasica, voc\u00ea vai querer convidar esse bot\:\n\n\nPrecisa de ajuda ou tem alguma ideia para o bot? Talvez voc\u00ea s\u00f3 queira relaxar? Venha para o FredBoat Hangout\!\n{0}\n\nVoc\u00ea n\u00e3o pode mandar comandos para esse bot por DM.\nBot criado por Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=A documenta\u00e7\u00e3o foi enviada para as suas mensagens privadas\! helpProperUsage=Uso correto\: helpCommandOwnerRestricted=Este comando \u00e9 restrito para o dono do bot. diff --git a/FredBoat/src/main/resources/lang/ro_RO.properties b/FredBoat/src/main/resources/lang/ro_RO.properties index 8e004edb0..55dfa3ed5 100644 --- a/FredBoat/src/main/resources/lang/ro_RO.properties +++ b/FredBoat/src/main/resources/lang/ro_RO.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Viteza dumneavoastr\u0103 este limitat\u0103\! V\u0103 ru ratelimitedSkipCommand=Pute\u021bi s\u0103ro mai mult de o pies\u0103 folosind comanda\: {0} ratelimitedGuildSlowLoadingPlaylist=Acestui server nu-i este permis s\u0103 adauge mai multe liste de redare \u00een acest moment. V\u0103 rug\u0103m s\u0103 nu spama\u021bi liste de redare lungi. unblacklisted=Am \u0219ters {0} de pe lista neagr\u0103. -serverinfoTitle=Informa\u0163ii despre **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Utilizatori online\: serverinfoTotalUsers=Total de utilizatori\: serverinfoRoles=Roluri\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID-ul server-ului\: serverinfoCreationDate=Data Cre\u0103rii\: serverinfoOwner=Proprietar\: serverinfoVLv=Nivel de verificare\: -userinfoTitle=Informa\u0163ii despre **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Nume de utilizator\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Mentenan\u0163\u0103 commandsBotOwner=Proprietarul bot-ului commandsMoreHelp=Spune {0} pentru a ob\u021bine mai multe informa\u021bii despre o anumit\u0103 comand\u0103. helpUnknownCommand=Comand\u0103 necunoscut\u0103. -helpDM=Documenta\u021bia poate fi g\u0103sit\u0103 pe\:\nhttps\://fredboat.com/docs\n\n\u00cel vrei pe FredBoat \u00een server-ul t\u0103u? Dac\u0103 ai permisiunea Manage Server pentru server-ul t\u0103u, \u00eel po\u021bi invita de aici\:\n*Acesta nu red\u0103 muzic\u0103*\n\n\nDac\u0103 vrei s\u0103 adaugi botul care red\u0103 muzica, vei dori s\u0103 invi\u021bi acest bot\:\n\n\nAi nevoie de ajutor sau idei pentru bot? Poate doar vrei s\u0103 por\u021bi discu\u021bii? Vino \u00een FredBoat hangout\!\n{0}\n\nNu po\u021bi trimite comenzi prin DM acestui bot.\nBot creat de Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documenta\u021bia \u021bi-a fost trimis\u0103 \u00een DM-uri\! helpProperUsage=Utilizare corect\u0103\: helpCommandOwnerRestricted=Aceast\u0103 comand\u0103 este restric\u021bionat\u0103 proprietarului bot-ului. @@ -257,7 +261,7 @@ helpSayCommand=Face ca bot-ul s\u0103 spun\u0103 ceva. helpServerInfoCommand=Afi\u015feaz\u0103 unele statistici despre acest server. helpUserInfoCommand=Afi\u015feaz\u0103 informa\u0163ii despre tine sau despre un utilizator cunoscut de bot. helpPerms=Permite ad\u0103ugarea membrilor la lista alb\u0103 \u0219i a rolurilor pentru rangul {0}. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Seteaz\u0103 prefixul pentru serverul acesta. helpVoteSkip=Voteaz\u0103 pentru a s\u0103ri piesa curent\u0103. Este necesar c\u0103 50% din utilizatorii din chatul vocal s\u0103 voteze. helpMathOperationAdd=Scrie suma lui num1 cu num2. helpMathOperationSub=Scrie diferen\u021ba sc\u0103derii lui num2 din num1. @@ -296,6 +300,6 @@ mathOperationResult=Rezultatul este mathOperationDivisionByZeroError=Nu pot \u00eemp\u0103r\u021bi la zero. mathOperationInfinity=Num\u0103rul este prea marea pentru a fi ar\u0103tat\! prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefixGuild=Prefixul pentru acest server este {0} +prefixShowAgain=Po\u021bi afi\u0219a prefixul oric\u00e2nd vrei men\u021bion\u00e2ndu-m\u0103. diff --git a/FredBoat/src/main/resources/lang/ru_RU.properties b/FredBoat/src/main/resources/lang/ru_RU.properties index 13c9f5b83..c9228ad43 100644 --- a/FredBoat/src/main/resources/lang/ru_RU.properties +++ b/FredBoat/src/main/resources/lang/ru_RU.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d \u043b\u ratelimitedSkipCommand=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043e\u0434\u043d\u0443 \u043f\u0435\u0441\u043d\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\: {0} ratelimitedGuildSlowLoadingPlaylist=\u041d\u0430 \u044d\u0442\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043b\u0435\u0439\u043b\u0438\u0441\u0442\u044b \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043d\u0435 \u043d\u0430\u0434\u043e \u0441\u043f\u0430\u043c\u0438\u0442\u044c \u0434\u043b\u0438\u043d\u043d\u044b\u043c\u0438 \u043f\u043b\u0435\u0439\u043b\u0438\u0441\u0442\u0430\u043c\u0438. unblacklisted={0} \u0443\u0431\u0440\u0430\u043d \u0438\u0437 \u0447\u0451\u0440\u043d\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430. -serverinfoTitle=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u043d\u043b\u0430\u0439\u043d\: serverinfoTotalUsers=\u0412\u0441\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\: serverinfoRoles=\u0420\u043e\u043b\u0438\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID \u0421\u0435\u0440\u0432\u0435\u0440\u0430\: serverinfoCreationDate=\u0414\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f\: serverinfoOwner=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446\: serverinfoVLv=\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438\: -userinfoTitle=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\: userinfoId=ID\: userinfoNick=\u041d\u0438\u043a\: @@ -212,7 +212,11 @@ commandsMaintenance=\u0422\u0435\u0445\u043e\u0431\u0441\u043b\u0443\u0436\u0438 commandsBotOwner=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0431\u043e\u0442\u0430 commandsMoreHelp=\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 {0} \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435. helpUnknownCommand=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430. -helpDM=\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430\:\nhttps\://fredboat.com/docs\n\n\u0425\u043e\u0442\u0438\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c FredBoat \u043d\u0430 \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440? \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u043c\u043e\u0447\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c\:\n*\u042d\u0442\u043e\u0442 \u043c\u0443\u0437\u044b\u043a\u0443 \u043d\u0435 \u0438\u0433\u0440\u0430\u0435\u0442*\n\n\n*\u0410 \u044d\u0442\u043e\u0442 \u0438\u0433\u0440\u0430\u0435\u0442*\:\n\n\n\u041d\u0443\u0436\u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0438\u043b\u0438 \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u0438 \u0434\u043b\u044f \u0431\u043e\u0442\u0430? \u0418\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u0440\u0430\u0437\u0432\u043b\u0435\u044c\u0447\u0441\u044f? \u0417\u0430\u0445\u043e\u0434\u0438 \u043d\u0430 FredBoat \u0441\u0435\u0440\u0432\u0435\u0440\!\n{0}\n\n\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u044d\u0442\u043e\u043c\u0443 \u0431\u043e\u0442\u0443 \u0447\u0435\u0440\u0435\u0437 \u041b\u0421.\n\u0411\u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u043d Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0431\u044b\u043b\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u0442\u0435\u0431\u0435 \u0432 \u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\! helpProperUsage=\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\: helpCommandOwnerRestricted=\u042d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0443 \u0431\u043e\u0442\u0430. diff --git a/FredBoat/src/main/resources/lang/sr_SP.properties b/FredBoat/src/main/resources/lang/sr_SP.properties index b2104ac13..7fbb0965f 100644 --- a/FredBoat/src/main/resources/lang/sr_SP.properties +++ b/FredBoat/src/main/resources/lang/sr_SP.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Users\: serverinfoTotalUsers=Total Users\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Creation Date\: serverinfoOwner=Owner\: serverinfoVLv=Verification Level\: -userinfoTitle=Information about **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Username\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/sv_SE.properties b/FredBoat/src/main/resources/lang/sv_SE.properties index 556d4bc4e..52e9a68bf 100644 --- a/FredBoat/src/main/resources/lang/sv_SE.properties +++ b/FredBoat/src/main/resources/lang/sv_SE.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Du skickar kommandon f\u00f6r snabbt\! Sakta ner grabben. ratelimitedSkipCommand=Du kan hoppa \u00f6ver mer \u00e4n en l\u00e5t genom att anv\u00e4nda detta kommando\: {0} ratelimitedGuildSlowLoadingPlaylist=Denna server f\u00e5r inte skapa mer spellistor f\u00f6r tillf\u00e4llet. Var sn\u00e4ll och spamma inte med l\u00e5nga spellistor. unblacklisted=Tog bort {0} fr\u00e5n svarta listan. -serverinfoTitle=Info om **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Anv\u00e4ndare online\: serverinfoTotalUsers=Antal anv\u00e4ndare\: serverinfoRoles=Roller\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Skapades\: serverinfoOwner=\u00c4gare\: serverinfoVLv=Kontroll niv\u00e5\: -userinfoTitle=Info om **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Anv\u00e4ndarnamn\: userinfoId=ID\: userinfoNick=Smeknamn\: @@ -212,7 +212,11 @@ commandsMaintenance=Underh\u00e5ll commandsBotOwner=Bot\u00e4gare commandsMoreHelp=Skriv {0} f\u00f6r att f\u00e5 specifik information f\u00f6r ett kommando. helpUnknownCommand=Ok\u00e4nt kommando. -helpDM=Info kan hittas p\u00e5 botens GitHub-sida\nhttp\://docs.frederikam.com\n\nVill du ha FredBoat p\u00e5 din server? Om du har till\u00e5telsen "Hantera Server" p\u00e5 den s\u00e5 kan du bjuda in den h\u00e4r\: \n*Denna spelar inte musik*\n\n\nOm du vill l\u00e4gga till musikboten s\u00e5 b\u00f6r du bjuda in denna bot\:\n\n\nOm du beh\u00f6ver hj\u00e4lp, om du har id\u00e9er f\u00f6r boten eller om du bara vill h\u00e4nga s\u00e5 kan du g\u00f6ra p\u00e5 FredBoat Hangout\! \n{0}\n\nDu kan inte skicka kommandon till denna bot genom DM.\nBot skapad av Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Info har skickats direkt till dig\! helpProperUsage=R\u00e4tt anv\u00e4ndning\: helpCommandOwnerRestricted=Detta kommando \u00e4r endast tillg\u00e4ngligt f\u00f6r bot\u00e4garen. @@ -225,7 +229,7 @@ helpMusicCommandsHeader=FredBoat-Musics kommandon helpJoinCommand=F\u00e5 botten att ansluta till din nuvarande r\u00f6stkanal. helpLeaveCommand=F\u00e5 botten att l\u00e4mna den nuvarande r\u00f6stkanalen. helpPauseCommand=Pausa spelaren. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=Spela upp musik fr\u00e5n den angivna URLen eller s\u00f6k efter ett sp\u00e5r. F\u00f6r en full lista av k\u00e4llor v\u00e4nligen bes\u00f6k {0} helpPlaySplitCommand=Dela upp en YouTube-video i en l\u00e5tlista angiven i beskrivningen. helpRepeatCommand=V\u00e4xla mellan upprepningsl\u00e4gen. helpReshuffleCommand=Blandar om den aktuella k\u00f6n. @@ -257,7 +261,7 @@ helpSayCommand=F\u00e5 boten att s\u00e4ga n\u00e5got. helpServerInfoCommand=Visa lite statistik om denna server. helpUserInfoCommand=Visa information om dig sj\u00e4lv eller en anv\u00e4ndare som \u00e4r k\u00e4nd av boten. helpPerms=Till\u00e5ter vitlistning medlemmar och roller f\u00f6r {0} rang. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=S\u00e4tt prefixen f\u00f6r denna server. helpVoteSkip=R\u00f6sta f\u00f6r att hoppa \u00f6ver den nuvarande l\u00e5ten. 50% av alla anv\u00e4ndare m\u00e5ste r\u00f6sta f\u00f6r att det ska funka. helpMathOperationAdd=Skriv ut summan av num1 och num2. helpMathOperationSub=Skriv ut differensen av att subtrahera num2 fr\u00e5n num1. @@ -296,6 +300,6 @@ mathOperationResult=Resultatet \u00e4r mathOperationDivisionByZeroError=Jag kan inte dela med noll. mathOperationInfinity=Numret \u00e4r f\u00f6r stort f\u00f6r att visas\! prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefixGuild=Prefixen f\u00f6r denna server \u00e4r {0} +prefixShowAgain=Du kan se prefixen n\u00e4r som helst igen genom att @a mig. diff --git a/FredBoat/src/main/resources/lang/th_TH.properties b/FredBoat/src/main/resources/lang/th_TH.properties index 8175c7818..f407ff197 100644 --- a/FredBoat/src/main/resources/lang/th_TH.properties +++ b/FredBoat/src/main/resources/lang/th_TH.properties @@ -45,7 +45,7 @@ exportPlaylistFail=\u0e01\u0e32\u0e23\u0e2d\u0e31\u0e1e\u0e42\u0e2b\u0e25\u0e14\ listShowShuffled=\u0e01\u0e33\u0e25\u0e31\u0e07\u0e40\u0e40\u0e2a\u0e14\u0e07\u0e40\u0e1e\u0e25\u0e22\u0e4c\u0e25\u0e34\u0e2a\u0e15\u0e4c\u0e17\u0e35\u0e48\u0e1c\u0e48\u0e32\u0e19\u0e01\u0e32\u0e23\u0e2a\u0e31\u0e1a\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19[shuffle] \u0e40\u0e40\u0e25\u0e49\u0e27 listShowRepeatSingle=\u0e40\u0e14\u0e35\u0e4b\u0e22\u0e27\u0e40\u0e1b\u0e34\u0e14\u0e40\u0e40\u0e17\u0e23\u0e47\u0e04\u0e19\u0e35\u0e49\u0e43\u0e2b\u0e49\u0e2d\u0e35\u0e01\u0e23\u0e2d\u0e1a\u0e19\u0e30 listShowRepeatAll=\u0e40\u0e14\u0e35\u0e4b\u0e22\u0e27\u0e40\u0e1b\u0e34\u0e14\u0e40\u0e1e\u0e25\u0e07\u0e43\u0e19\u0e04\u0e34\u0e27\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e2d\u0e35\u0e01\u0e23\u0e2d\u0e1a\u0e43\u0e2b\u0e49\u0e19\u0e30 -listShowHistory=Showing tracks in history. +listShowHistory=\u0e1f\u0e31\u0e07\u0e40\u0e1e\u0e25\u0e07 listAddedBy=**{0}** \u0e16\u0e39\u0e01\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e02\u0e49\u0e32\u0e44\u0e1b\u0e43\u0e19\u0e04\u0e34\u0e27\u0e42\u0e14\u0e22 **{1}** `[{2}]` listStreamsOnlySingle=\u0e21\u0e35\u0e44\u0e25\u0e1f\u0e2a\u0e15\u0e23\u0e35\u0e21 **{0}** \u0e44\u0e25\u0e1f {1} \u0e43\u0e19\u0e04\u0e34\u0e27 listStreamsOnlyMultiple=\u0e21\u0e35\u0e44\u0e25\u0e1f\u0e2a\u0e15\u0e23\u0e35\u0e21 **{0}** \u0e44\u0e25\u0e1f {1} \u0e43\u0e19\u0e04\u0e34\u0e27 @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u0e04\u0e38\u0e13\u0e08\u0e30\u0e16\u0e39\u0e01\u0e08\u0 ratelimitedSkipCommand=\u0e04\u0e38\u0e13\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e02\u0e49\u0e32\u0e21\u0e40\u0e1e\u0e25\u0e07\u0e17\u0e35\u0e48\u0e21\u0e32\u0e01\u0e01\u0e27\u0e48\u0e32\u0e2b\u0e19\u0e36\u0e48\u0e07 \u0e42\u0e14\u0e22\u0e43\u0e0a\u0e49\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e19\u0e35\u0e49\: {0} ratelimitedGuildSlowLoadingPlaylist=\u0e40\u0e0b\u0e34\u0e23\u0e4c\u0e1f\u0e40\u0e27\u0e2d\u0e23\u0e4c\u0e19\u0e35\u0e49\u0e44\u0e21\u0e48\u0e2d\u0e19\u0e38\u0e0d\u0e32\u0e15\u0e43\u0e2b\u0e49\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e15\u0e34\u0e21\u0e43\u0e19\u0e02\u0e13\u0e30\u0e19\u0e35\u0e49 \u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48\u0e40\u0e25\u0e48\u0e19\u0e22\u0e32\u0e27\u0e2a\u0e41\u0e1b\u0e21 unblacklisted={0} \u0e2d\u0e2d\u0e01\u0e08\u0e32\u0e01\u0e1a\u0e31\u0e0d\u0e0a\u0e35\u0e14\u0e33 -serverinfoTitle=\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a **{0} **\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e2d\u0e2d\u0e19\u0e44\u0e25\u0e19\u0e4c\: serverinfoTotalUsers=\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\u0e23\u0e27\u0e21\: serverinfoRoles=\u0e1a\u0e17\u0e1a\u0e32\u0e17\: @@ -193,7 +193,7 @@ serverinfoGuildID=\u0e01\u0e34\u0e25\u0e14\u0e4c ID\: serverinfoCreationDate=\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48\u0e2a\u0e23\u0e49\u0e32\u0e07\: serverinfoOwner=\u0e40\u0e08\u0e49\u0e32\u0e02\u0e2d\u0e07\: serverinfoVLv=\u0e23\u0e30\u0e14\u0e31\u0e1a\u0e01\u0e32\u0e23\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\: -userinfoTitle=\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a **{0} **\: +userinfoTitle=Information about {0}\: userinfoUsername=\u0e0a\u0e37\u0e48\u0e2d\u0e1c\u0e39\u0e49\u0e43\u0e0a\u0e49\: userinfoId=\u0e23\u0e2b\u0e31\u0e2a\: userinfoNick=\u0e0a\u0e37\u0e48\u0e2d\u0e40\u0e25\u0e48\u0e19\: @@ -212,7 +212,11 @@ commandsMaintenance=\u0e01\u0e32\u0e23\u0e1a\u0e33\u0e23\u0e38\u0e07\u0e23\u0e31 commandsBotOwner=\u0e40\u0e08\u0e49\u0e32\u0e02\u0e2d\u0e07\u0e1a\u0e2d\u0e17 commandsMoreHelp=\u0e1a\u0e2d\u0e01 {0} \u0e08\u0e30\u0e44\u0e14\u0e49\u0e23\u0e31\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e40\u0e15\u0e34\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e40\u0e09\u0e1e\u0e32\u0e30 helpUnknownCommand=\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e17\u0e35\u0e48\u0e44\u0e21\u0e48\u0e23\u0e39\u0e49\u0e08\u0e31\u0e01 -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e16\u0e39\u0e01\u0e2a\u0e48\u0e07\u0e44\u0e1b\u0e22\u0e31\u0e07\u0e41\u0e0a\u0e17\u0e42\u0e14\u0e22\u0e15\u0e23\u0e07\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e41\u0e25\u0e49\u0e27\! helpProperUsage=\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e17\u0e35\u0e48\u0e40\u0e2b\u0e21\u0e32\u0e30\u0e2a\u0e21\: helpCommandOwnerRestricted=\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e19\u0e35\u0e49\u0e16\u0e39\u0e01\u0e08\u0e33\u0e01\u0e31\u0e14\u0e44\u0e1b\u0e22\u0e31\u0e07\u0e40\u0e08\u0e49\u0e32\u0e02\u0e2d\u0e07\u0e1a\u0e2d\u0e17 diff --git a/FredBoat/src/main/resources/lang/tr_TR.properties b/FredBoat/src/main/resources/lang/tr_TR.properties index 44cde7551..12aa1c77e 100644 --- a/FredBoat/src/main/resources/lang/tr_TR.properties +++ b/FredBoat/src/main/resources/lang/tr_TR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Oran\u0131 k\u0131s\u0131tl\u0131yorsun\! L\u00fctfen yav ratelimitedSkipCommand=Bu komutu kullanarak birden fazla \u015fark\u0131 ge\u00e7ebilirsiniz\: {0} ratelimitedGuildSlowLoadingPlaylist=Bu sunucunun \u015fu anda daha fazla oynatma listesi eklemesine izin verilmez. L\u00fctfen uzun \u00e7alma listeleriyle spam g\u00f6ndermeyin. unblacklisted=Kara listeden {0} kald\u0131r\u0131ld\u0131. -serverinfoTitle=**{0}** hakk\u0131nda bilgi\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Aktif kullan\u0131c\u0131lar\: serverinfoTotalUsers=Toplam Kullan\u0131c\u0131\: serverinfoRoles=Roller\: @@ -193,7 +193,7 @@ serverinfoGuildID=Klan ID\: serverinfoCreationDate=Olu\u015fturulma Tarihi\: serverinfoOwner=Sahibi\: serverinfoVLv=Do\u011frulama Seviyesi\: -userinfoTitle=**{0}** hakk\u0131nda bilgi\: +userinfoTitle=Information about {0}\: userinfoUsername=Kullan\u0131c\u0131 ad\u0131\: userinfoId=ID\: userinfoNick=Rumuzu\: @@ -212,7 +212,11 @@ commandsMaintenance=Bak\u0131m commandsBotOwner=Bot sahibi commandsMoreHelp=Belirli bir komutla ilgili daha fazla bilgi almak i\u00e7in {0} yaz. helpUnknownCommand=Bilinmeyen komut. -helpDM=D\u00f6k\u00fcmasyonlara buradan ula\u015fabilirsiniz\:\nhttps\://fredboat.com/docs\n\nSunucuza FredBoat''\u0131 eklemek istiyor musunuz? E\u011fer sunucunun izinlerini y\u00f6netebiliyorsan, botu buradan davet edebilirsin\:\n*Bu bot m\u00fczik \u00e7almaz*\n\n\nM\u00fczik botu eklemek istiyorsan ve hala bu botu davet etmek istersen\:\n\n\nBot i\u00e7in yard\u0131ma ihtiyac\u0131n m\u0131 var? yada akl\u0131na g\u00fczel bir fikir mi geldi? Yoksa sadece tak\u0131lmak m\u0131 istiyorsun? Buraya gel ve FredBoat ile tak\u0131l\! {0}\n\nBot komutlar\u0131n\u0131 \u00f6zel mesaj yoluyla g\u00f6nderemezsin\nBot Fre_d taraf\u0131ndan yap\u0131lm\u0131\u015ft\u0131r +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=D\u00f6k\u00fcmanlar DM ile g\u00f6nderildi\! helpProperUsage=Do\u011fru kullan\u0131m\: helpCommandOwnerRestricted=Bu komutu sadece bot sahibi kullanabilir. @@ -295,7 +299,7 @@ voteSkipEmbedVoters={1} ki\u015fiden {0} ki\u015fi \u00e7alan par\u00e7an\u0131n mathOperationResult=Sonu\u00e7 mathOperationDivisionByZeroError=S\u0131f\u0131ra b\u00f6lemem. mathOperationInfinity=Say\u0131 g\u00f6r\u00fcnt\u00fclemek i\u00e7in \u00e7ok b\u00fcy\u00fck\! -prefix=Prefix +prefix=\u00d6n ek prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefixShowAgain=Her zaman benden bahsederek (mention) \u00f6n eki ortaya \u00e7\u0131karabilirsiniz. diff --git a/FredBoat/src/main/resources/lang/uk_UA.properties b/FredBoat/src/main/resources/lang/uk_UA.properties index f031ba696..8242cdcd8 100644 --- a/FredBoat/src/main/resources/lang/uk_UA.properties +++ b/FredBoat/src/main/resources/lang/uk_UA.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Online Users\: serverinfoTotalUsers=Total Users\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Creation Date\: serverinfoOwner=Owner\: serverinfoVLv=Verification Level\: -userinfoTitle=Information about **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=Username\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,7 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. helpUnknownCommand=Unknown command. -helpDM=Documentation can be found at\:\nhttps\://fredboat.com/docs\n\nWant to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite it here\:\n*This one doesn''t play music*\n\n\nIf you want to add the music bot, you will want to invite this bot\:\n\n\nNeed help or have any ideas for the bot? Perhaps you just want to hang out? Come on over to FredBoat hangout\!\n{0}\n\nYou cannot send this bot commands through DM.\nBot created by Fre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=Documentation has been sent to your DMs\! helpProperUsage=Proper usage\: helpCommandOwnerRestricted=This command is restricted to the owner of the bot. diff --git a/FredBoat/src/main/resources/lang/vi_VN.properties b/FredBoat/src/main/resources/lang/vi_VN.properties index fb8d26c86..8cf6f2cbc 100644 --- a/FredBoat/src/main/resources/lang/vi_VN.properties +++ b/FredBoat/src/main/resources/lang/vi_VN.properties @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=, c\u0169ng nh\u01b0 **{0}** tr\u1ef1c ti\u1ebfp {1} trackSingular=b\u00e0i nha\u0323c trackPlural=b\u00e0i h\u00e1t npNotPlaying=Hi\u1ec7n \u0111ang kh\u00f4ng ch\u01a1i b\u00e0i g\u00ec. -npNotInHistory=Currently no tracks in history. +npNotInHistory=Hi\u1ec7n kh\u00f4ng c\u00f3 b\u00e0i h\u00e1t trong l\u1ecbch s\u1eed. npDescription=Mi\u00eau t\u1ea3 npLoadedSoundcloud=[{0}/{1}]\n\n\u0110\u00e3 n\u1ea1p t\u1eeb Soundcloud npLoadedBandcamp={0}\n\n\u0110\u00e3 n\u1ea1p t\u1eeb Bandcamp @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=B\u1ea1n \u0111ang b\u1ecb gi\u1edbi h\u1ea1n\! H\u00e3y ratelimitedSkipCommand=B\u1ea1n c\u00f3 th\u1ec3 b\u1ecf qua nhi\u1ec1u h\u01a1n m\u1ed9t b\u00e0i h\u00e1t b\u1eb1ng c\u00e1ch d\u00f9ng l\u1ec7nh\: {0} ratelimitedGuildSlowLoadingPlaylist=M\u00e1y ch\u1ee7 n\u00e0y kh\u00f4ng \u0111\u01b0\u1ee3c cho ph\u00e9p \u0111\u1ec3 th\u00eam nhi\u1ec1u danh s\u00e1ch ph\u00e1t t\u1ea1i l\u00fac n\u00e0y. Xin \u0111\u1eebng spam danh s\u00e1ch ph\u00e1t d\u00e0i. unblacklisted=\u0110\u00e3 lo\u1ea1i b\u1ecf {0} kh\u1ecfi danh s\u00e1ch \u0111en. -serverinfoTitle=Xem th\u00f4ng tin v\u1ec1 **{0}**\: +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=Ng\u01b0\u1eddi \u0111ang online\: serverinfoTotalUsers=T\u1ed5ng s\u1ed1 ng\u01b0\u1eddi d\u00f9ng\: serverinfoRoles=Vai tro\u0300\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Ng\u00e0y t\u1ea1o\: serverinfoOwner=Ch\u1ee7 s\u1edf h\u1eefu\: serverinfoVLv=C\u1ea5p \u0111\u1ed9 x\u00e1c minh\: -userinfoTitle=Th\u00f4ng tin v\u1ec1 **{0}**\: +userinfoTitle=Information about {0}\: userinfoUsername=T\u00ean \u0111\u0103ng nh\u1eadp\: userinfoId=ID\: userinfoNick=Bi\u1ec7t danh\: @@ -212,7 +212,11 @@ commandsMaintenance=B\u1ea3o tr\u00ec commandsBotOwner=Ch\u1ee7 s\u1edf h\u1eefu bot commandsMoreHelp=Chat {0} \u0111\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 m\u1ed9t l\u1ec7nh c\u1ee5 th\u1ec3. helpUnknownCommand=L\u1ec7nh kh\u00f4ng r\u00f5. -helpDM=T\u00e0i li\u1ec7u c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y t\u1ea1i\:\nhttps\://fredboat.com/docs\n\nB\u1ea1n mu\u1ed1n th\u00eam FredBoat v\u00e0o m\u00e1y ch\u1ee7 c\u1ee7a m\u00ecnh? N\u1ebfu b\u1ea1n c\u00f3 quy\u1ec1n qu\u1ea3i l\u00ed m\u00e1y ch\u1ee7 cho guild c\u1ee7a b\u1ea1n, b\u1ea1n c\u00f3 th\u1ec3 m\u1eddi bot v\u00e0o \u1edf \u0111\u00e2y\:\n*con n\u00e0y kh\u00f4ng bi\u1ebft ch\u01a1i nh\u1ea1c*\n\n\nN\u1ebfu b\u1ea1n mu\u1ed1n th\u00eam con bi\u1ebft ch\u01a1i nh\u1ea1c, b\u1ea1n s\u1ebd ph\u1ea3i m\u1eddi bot n\u00e0y\:\n\n\nC\u1ea7n gi\u00fap \u0111\u1ee1ho\u1eb7c c\u00f3 \u00fd t\u01b0\u1edfng m\u1edbi cho bot? C\u00f3 th\u1ec3 b\u1ea1n ch\u1ec9 mu\u1ed1n vui \u0111\u00f9a? H\u00e3y \u0111\u1ebfn khu vui \u0111\u00f9a c\u1ee7a FredBoat\!\n{0}\n\nB\u1ea1n kh\u00f4ng th\u1ec3 g\u1eedi l\u1ec7nh cho bot th\u00f4ng qua DM (Tin nh\u1eafn tr\u1ef1c ti\u1ebfp)\nBot \u0111\u01b0\u1ee3c t\u1ea1o b\u1edfi Fre_d, d\u1ecbch ti\u1ebfng Vi\u1ec7t b\u1edfi phjtieudoc (Drake Srike) +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=T\u00e0i li\u1ec7u \u0111\u00e3 \u0111\u01b0\u1ee3c g\u1eedi tr\u1ef1c ti\u1ebfp cho b\u1ea1n\! helpProperUsage=C\u00e1ch d\u00f9ng ch\u00ednh x\u00e1c\: helpCommandOwnerRestricted=L\u1ec7nh n\u00e0y ch\u1ec9 \u0111\u01b0\u1ee3c gi\u1edbi h\u1ea1n cho c\u00e1c ch\u1ee7 s\u1edf h\u1eefu c\u1ee7a bot. @@ -275,13 +279,13 @@ permsListTitle=Ng\u01b0\u1eddi d\u00f9ng v\u00e0 c\u00e1c vai tr\u00f2 v\u1edbi permsAdded=\u0110\u00e3 th\u00eam `{0}` t\u1edbi `{1}`. permsRemoved=\u0110\u00e3 lo\u1ea1i b\u1ecf `{0}` t\u1eeb `{1}`. permsFailSelfDemotion=B\u1ea1n kh\u00f4ng th\u1ec3 lo\u1ea1i b\u1ecf \u0111i\u1ec1u n\u00e0y v\u00ec n\u00f3 s\u1ebd khi\u1ebfn b\u1ea1n kh\u00f4ng c\u00f3 quy\u1ec1n qu\u1ea3n tr\u1ecb\! -permsAlreadyAdded={0} already added to {1} +permsAlreadyAdded={0} \u0111\u00e3 \u0111\u01b0\u1ee3c th\u00eam v\u00e0o {1} permsNotAdded={0} is not in {1} fuzzyMultiple=Nhi\u1ec1u kho\u1ea3n m\u1ee5c \u0111\u00e3 \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y. B\u1ea1n c\u00f3 hi\u1ec3u b\u1ea5t k\u00ec g\u00ec kh\u00f4ng? fuzzyNothingFound=Kh\u00f4ng t\u00ecm th\u1ea5y g\u00ec cho `{0}`. cmdPermsTooLow=B\u1ea1n kh\u00f4ng c\u00f3 quy\u1ec1n \u0111\u1ec3 ch\u1ea1y l\u1ec7nh n\u00e0y\! L\u1ec7nh n\u00e0y y\u00eau c\u1ea7u `{0}`, nh\u01b0ng b\u1ea1n ch\u1ec9 c\u00f3 `{1}`. playersLimited=FredBoat hi\u1ec7n \u0111\u00e3 \u0111\u1ea1t t\u1ed1i \u0111a n\u0103ng l\u1ef1c\! Bot n\u00e0y hi\u1ec7n \u0111ang \u0111\u01b0\u1ee3c s\u1eeda \u0111\u1ec3 ph\u00e1t nh\u1ea1c \u0111\u1ebfn `{0}` b\u00e0i, n\u1ebfu kh\u00f4ng ch\u00fang t\u00f4i ph\u1ea3i ng\u1eaft k\u1ebft n\u1ed1i kh\u1ecfi Discord d\u01b0\u1edbi trang t\u1ea3i m\u1ea1ng.\nN\u1ebfu b\u1ea1n mu\u1ed1n h\u1ed7 tr\u1ee3 ch\u00fang t\u00f4i t\u0103ng th\u00eam gi\u1edbi h\u1ea1n hay b\u1ea1n mu\u1ed1n s\u1eed d\u1ee5ng bot t\u1ed1i thi\u1ec3u c\u1ee7a ch\u00fang t\u00f4i, h\u00e3y h\u1ed7 tr\u1ee3 ch\u00fang t\u00f4i qua Patreon\:\n{1}\n\nXin l\u1ed7i v\u00ec s\u1ef1 b\u1ea5t ti\u1ec7n\! B\u1ea1n c\u00f3 th\u1ec3 ph\u1ea3i th\u1eed l\u1ea1i sau. Tin nh\u1eafn n\u00e0y th\u01b0\u1eddng ch\u1ec9 xu\u1ea5t hi\u1ec7n m\u1ed9t v\u00e0i l\u1ea7n. -tryLater=Please try again later. +tryLater=Vui l\u00f2ng th\u1eed l\u1ea1i sau. skipUserSingle=Skipped {0} added by {1}. skipUserMultiple=Skipped {0} tracks added by {1}. skipUsersMultiple=Skipped {0} tracks added by {1} users. diff --git a/FredBoat/src/main/resources/lang/zh_CN.properties b/FredBoat/src/main/resources/lang/zh_CN.properties index d415cac40..f7b77d34f 100644 --- a/FredBoat/src/main/resources/lang/zh_CN.properties +++ b/FredBoat/src/main/resources/lang/zh_CN.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u4f60\u7684\u901f\u5ea6\u6709\u9650\! \u8bf7\u6162\u4e00 ratelimitedSkipCommand=\u60a8\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u8df3\u8fc7\u591a\u4e2a\u6b4c\u66f2\: {0} ratelimitedGuildSlowLoadingPlaylist=\u6b64\u670d\u52a1\u5668\u4e0d\u5141\u8bb8\u5728\u6b64\u65f6\u6dfb\u52a0\u66f4\u591a\u64ad\u653e\u5217\u8868\u3002\u8bf7\u4e0d\u8981\u5783\u573e\u90ae\u4ef6\u957f\u64ad\u653e\u5217\u8868\u3002 unblacklisted=\u5df2\u4ece\u9ed1\u540d\u5355\u4e2d\u5220\u9664{0}\u3002 -serverinfoTitle=**{0}** \u7684\u76f8\u5173\u4fe1\u606f\uff1a +serverinfoTitle=Info about {0}\: serverinfoOnlineUsers=\u5728\u7ebf\u7528\u6237\uff1a serverinfoTotalUsers=\u7528\u6237\u603b\u6570\uff1a serverinfoRoles=\u8eab\u4efd\u7ec4\uff1a @@ -193,7 +193,7 @@ serverinfoGuildID=\u516c\u4f1a ID\uff1a serverinfoCreationDate=\u521b\u5efa\u65e5\u671f\uff1a serverinfoOwner=\u62e5\u6709\u8005\uff1a serverinfoVLv=\u9a8c\u8bc1\u7b49\u7ea7\uff1a -userinfoTitle=**{0}** \u7684\u76f8\u5173\u4fe1\u606f\uff1a +userinfoTitle=Information about {0}\: userinfoUsername=\u7528\u6237\u540d\uff1a userinfoId=ID\uff1a userinfoNick=\u6635\u79f0\uff1a @@ -212,7 +212,11 @@ commandsMaintenance=\u7cfb\u7edf\u7ef4\u62a4 commandsBotOwner=\u673a\u5668\u4eba\u4e3b\u4eba commandsMoreHelp=\u8bf4{0} \u83b7\u53d6\u6709\u5173\u7279\u5b9a\u547d\u4ee4\u7684\u66f4\u591a\u4fe1\u606f\u3002 helpUnknownCommand=\u672a\u77e5\u7684\u6307\u4ee4\u3002 -helpDM=\u6587\u6863\u53ef\u4ee5\u5728 bot \u7684 GitHub \u9875\u9762\u627e\u5230\uff1a\nhttp\://docs.frederikam.com\n\n\u60f3\u6dfb\u52a0 FredBoat \u5230\u60a8\u7684\u670d\u52a1\u5668\uff1f\u5982\u679c\u60a8\u6709\u60a8\u7684\u516c\u4f1a\u7684\u7ba1\u7406\u670d\u52a1\u5668\u6743\u9650\uff0c\u5373\u53ef\u901a\u8fc7\u4e0b\u9762\u7684\u94fe\u63a5\u9080\u8bf7 bot\uff1a\n*This one doesn't play music*\nhttps\://discordapp.com/oauth2/authorize?&client_id\=168686772216135681&scope\=bot\n\n\u5982\u679c\u60f3\u6dfb\u52a0\u97f3\u4e50 bot\uff0c\u53ef\u901a\u8fc7\u4e0b\u9762\u7684\u94fe\u63a5\u9080\u8bf7\uff1a\nhttps\://discordapp.com/oauth2/authorize?&client_id\=184405253028970496&scope\=bot\n\n\u9700\u8981\u5e2e\u52a9\uff1f\u6709\u5173\u4e8e bot \u7684\u70b9\u5b50\uff1f\u6216\u8005\u53ea\u662f\u60f3\u901b\u901b\uff1f\u5feb\u6765 FredBoat \u7684 Discord \u516c\u4f1a\u5427\uff01\nhttps\://discord.gg/0yXhQ9c36F4zsJMG/0yXhQ9c36F4zsJMG\n\n\u60a8\u4e0d\u80fd\u5728\u4e0e bot \u7684\u79c1\u804a\u4e2d\u4f7f\u7528\u547d\u4ee4\u3002\nBot \u4f5c\u8005\uff1aFre_d +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u5e2e\u52a9\u6587\u6863\u5df2\u901a\u8fc7\u79c1\u804a\u53d1\u7ed9\u60a8\uff01 helpProperUsage=\u6b63\u786e\u4f7f\u7528\: helpCommandOwnerRestricted=\u6b64\u547d\u4ee4\u4ec5\u9650\u4e8e \n\u673a\u5668\u4eba\u4e3b\u4eba @@ -257,7 +261,7 @@ helpSayCommand=\u8ba9\u673a\u5668\u4eba\u56de\u58f0\u7684\u4e1c\u897f\u3002 helpServerInfoCommand=\u663e\u793a\u5173\u4e8e\u8fd9\u4e2a\u884c\u4f1a\u7684\u4e00\u4e9b\u7edf\u8ba1\u6570\u636e\u3002 helpUserInfoCommand=\u663e\u793a\u6709\u5173\u60a8\u81ea\u5df1\u6216 bot \u6240\u77e5\u7528\u6237\u7684\u4fe1\u606f\u3002 helpPerms=\u5141\u8bb8{0} \u79e9\u7684\u540d\u5355\u6210\u5458\u548c\u89d2\u8272\u3002 -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=\u8bbe\u7f6e\u8be5\u884c\u4f1a\u7684\u524d\u7f00\u3002 helpVoteSkip=\u6295\u7968\u8df3\u8fc7\u5f53\u524d\u7684\u6b4c\u66f2\u3002\u9700\u898150% \u7684\u6240\u6709\u7528\u6237\u5728\u8bed\u97f3\u804a\u5929\u4e2d\u6295\u7968\u3002 helpMathOperationAdd=\u6253\u5370 num1 \u548c num2 \u7684\u603b\u548c\u3002 helpMathOperationSub=\u6253\u5370\u4ece num1 \u4e2d\u51cf\u53bb num2 \u7684\u5dee\u5f02\u3002 @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} \u51fa\u4e86{1} \u5df2\u7ecf\u6295\u7968\u8df3\u8fc7\u5f mathOperationResult=\u5176\u7ed3\u679c\u662f mathOperationDivisionByZeroError=\u6211\u4e0d\u80fd\u9664\u4ee5\u96f6\u3002 mathOperationInfinity=\u6570\u5b57\u592a\u5927, \u4e0d\u80fd\u663e\u793a\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=\u524d\u7f00 +prefixGuild=\u8fd9\u4e2a\u516c\u4f1a\u7684\u524d\u7f00\u662f{0} +prefixShowAgain=\u60a8\u53ef\u4ee5\u968f\u65f6\u901a\u8fc7\u63d0\u53ca\u6211\u6765\u663e\u793a\u524d\u7f00\u3002 diff --git a/FredBoat/src/main/resources/lang/zh_TW.properties b/FredBoat/src/main/resources/lang/zh_TW.properties index 022ff0476..4d48ba772 100644 --- a/FredBoat/src/main/resources/lang/zh_TW.properties +++ b/FredBoat/src/main/resources/lang/zh_TW.properties @@ -45,9 +45,9 @@ exportPlaylistFail=\u7121\u6cd5\u5c07\u64ad\u653e\u6e05\u55ae\u4e0a\u50b3\u81f3 listShowShuffled=\u76ee\u524d\u7684\u64ad\u653e\u5e8f\u5217\uff1a\n\n listShowRepeatSingle=\u91cd\u8907\u64ad\u653e\u76ee\u524d\u97f3\u8ecc listShowRepeatAll=\u91cd\u8907\u64ad\u653e\u76ee\u524d\u64ad\u653e\u5e8f\u5217 -listShowHistory=Musica +listShowHistory=\u986f\u793a\u6b77\u53f2\u64ad\u653e\u66f2\u76ee\u3002 listAddedBy=**{0}** \u7531 **{1}** `[{2}]` \u6dfb\u52a0 -listStreamsOnlySingle=\u5e8f\u5217\u4e2d\u6709 **{0}** \u500b\u53ca\u6642 {1} +listStreamsOnlySingle=\u5e8f\u5217\u4e2d\u6709 **{0}** \u500b\u5373\u6642 {1}\u3002 listStreamsOnlyMultiple=\u5e8f\u5217\u4e2d\u6709 **{0}** \u500b\u53ca\u6642 {1} listStreamsOrTracksSingle=\u5e8f\u5217\u4e2d\u76ee\u524d\u6709 **{0}** \u500b {1} \uff0c\u9577\u5ea6\u662f **[{2}]**{3} listStreamsOrTracksMultiple=\u5e8f\u5217\u4e2d\u76ee\u524d\u6709 **{0}** \u500b {1} \uff0c\u9577\u5ea6\u662f **[{2}]**{3} @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=\uff0c\u4ee5\u53ca **{0}** \u500b\u53ca\u6642 {1} trackSingular=\u66f2\u76ee trackPlural=\u66f2\u76ee npNotPlaying=\u76ee\u524d\u6c92\u6709\u5728\u64ad\u653e\u4efb\u4f55\u6771\u897f -npNotInHistory=\#musica +npNotInHistory=\u76ee\u524d\u6b77\u53f2\u7d00\u9304\u6c92\u6709\u64ad\u653e\u66f2\u76ee\u3002 npDescription=\u63cf\u8ff0 npLoadedSoundcloud=[{0}/{1}]\n\n\u5df2\u5f9e Soundcloud \u4e2d\u8f09\u5165 npLoadedBandcamp={0} \n\n\u5df2\u5f9e Bandcamp \u4e2d\u8f09\u5165 @@ -75,11 +75,11 @@ npLoadedDefault={0}\n\n\u5df2\u5f9e {1} \u8f09\u5165 noneYet=\u6c92\u6771\u897f npRatingRange={0}/5 \u4f86\u81ea\u6295\u7968 {1} fwdSuccess=\u6b63\u5728\u5c07 **{0}** \u5feb\u8f49 {1}. -restartSuccess=**{0}** \u5df2\u5f9e\u65b0\u958b\u59cb +restartSuccess=**{0}** \u5df2\u91cd\u65b0\u958b\u59cb\u3002 queueEmpty=\u64ad\u653e\u5e8f\u5217\u662f\u7a7a\u7684 rewSuccess=\u6b63\u5728\u5c07 **{0}** \u5012\u5e36 {1} seekSuccess=\u6b63\u5728\u5c07 **{0}** \u79fb\u52d5\u5230 {1} -seekDeniedLiveTrack=\u4f60\u4e0d\u80fd\u79fb\u52d5\u73fe\u5834\u97f3\u8ecc\u3002 +seekDeniedLiveTrack=\u4f60\u4e0d\u80fd\u79fb\u52d5\u5373\u6642\u4e32\u6d41\u7684\u97f3\u8ecc\u3002 loadPlaySplitListFail=\u8a72\u9023\u7d50\u6307\u5411\u4e00\u500b\u64ad\u653e\u6e05\u55ae\uff0c\u4e0d\u662f\u4e00\u9996\u6b4c\u3002\u8acb\u4f7f\u7528 `;;play` loadListSuccess=\u5df2\u5f9e\u64ad\u653e\u6e05\u55ae **{1}** \u65b0\u589e `{0}` \u9996\u6b4c loadNoMatches=\u5728 `{0}` \u627e\u4e0d\u5230\u4efb\u4f55\u97f3\u8a0a @@ -183,24 +183,24 @@ ratelimitedGeneralInfo=\u60a8\u5373\u5c07\u9054\u5230\u4fe1\u606f\u4e0a\u9650\uf ratelimitedSkipCommand=\u60a8\u53ef\u4ee5\u901a\u904e\u4f7f\u7528\u6b64\u547d\u4ee4\u8df3\u904e\u8d85\u904e\u4e00\u9996\u6b4c\uff1a {0} ratelimitedGuildSlowLoadingPlaylist=\u6b64\u4f3a\u670d\u5668\u4e0d\u5141\u8a31\u5728\u6b64\u6642\u65b0\u589e\u66f4\u591a\u64ad\u653e\u6e05\u55ae\u3002\u8acb\u4e0d\u8981\u5237\u5f88\u9577\u7684\u64ad\u653e\u6e05\u55ae unblacklisted=\u5f9e\u9ed1\u540d\u55ae\u79fb\u9664 {0} -serverinfoTitle=\u95dc\u65bc **{0}** \u7684\u8cc7\u8a0a -serverinfoOnlineUsers=\u5df2\u4e0a\u7dda\u7528\u6236\uff1a -serverinfoTotalUsers=\u7528\u6236\u7e3d\u6578\uff1a -serverinfoRoles=\u8077\u8cac\uff1a +serverinfoTitle=Info about {0}\: +serverinfoOnlineUsers=\u7dda\u4e0a\u4f7f\u7528\u8005\uff1a +serverinfoTotalUsers=\u4f7f\u7528\u8005\u7e3d\u6578\: +serverinfoRoles=\u8eab\u4efd\uff1a serverinfoText=\u6587\u5b57\u983b\u9053\uff1a serverinfoVoice=\u8a9e\u97f3\u983b\u9053\uff1a serverinfoGuildID=\u516c\u6703ID\: serverinfoCreationDate=\u5efa\u7acb\u65e5\u671f\: serverinfoOwner=\u64c1\u6709\u8005\uff1a serverinfoVLv=\u9a57\u8b49\u7d1a\u5225\ufe30 -userinfoTitle=\u95dc\u65bc **{0}** \u7684\u8cc7\u8a0a +userinfoTitle=Information about {0}\: userinfoUsername=\u7528\u6236\u540d\uff1a userinfoId=ID\uff1a userinfoNick=\u66b1\u7a31\uff1a userinfoKnownServer=\u5df2\u77e5\u4f3a\u670d\u5668\uff1a userinfoJoinDate=\u52a0\u5165\u65e5\u671f\uff1a userinfoCreationTime=\u5efa\u7acb\u65e5\u671f\uff1a -userinfoBlacklisted="\u5df2\u5217\u5165\u9ed1\u540d\u55ae\: +userinfoBlacklisted=\u5df2\u5217\u5165\u9ed1\u540d\u55ae\: skipDeniedTooManyTracks=\u5982\u679c\u4f60\u4e0d\u662f DJ, \u4f60\u4e0d\u80fd\u8df3\u904e\u5225\u4eba\u7684\u66f2\u76ee\u3002\u8acb\u8003\u616e\u4f7f\u7528 Voteskip \u547d\u4ee4\u3002 eventUsersLeftVC=\u6240\u6709\u7528\u6236\u5df2\u7d93\u96e2\u958b\u4e86\u983b\u9053\uff0c\u64ad\u653e\u5668\u5df2\u7d93\u66ab\u505c eventAutoResumed=\u6aa2\u6e2c\u5230\u4f7f\u7528\u8005\u72c0\u614b, \u81ea\u52d5\u5fa9\u539f\u64ad\u653e\u6a5f\u3002 @@ -212,7 +212,11 @@ commandsMaintenance=\u7dad\u8b77 commandsBotOwner=Bot \u64c1\u6709\u8005 commandsMoreHelp=\u8aaa {0} \u4ee5\u7372\u5f97\u7279\u5b9a\u6307\u4ee4\u7684\u66f4\u591a\u8cc7\u8a0a helpUnknownCommand=\u672a\u77e5\u7684\u6307\u4ee4 -helpDM=\u6587\u6a94\u53ef\u4ee5\u5728\u4ee5\u4e0b\u4f4d\u5740\u627e\u5230\: HTTPs\://fredboat.com/docs \u8981\u5c07 fredboat \u6dfb\u52a0\u5230\u60a8\u7684\u4f3a\u670d\u5668\uff1f\u5982\u679c\u60a8\u6709\u7ba1\u7406\u884c\u6703\u7684\u4f3a\u670d\u5668\u8a31\u53ef\u6b0a, \u60a8\u53ef\u4ee5\u5728\u9019\u88e1\u9080\u8acb\u5b83\: * \u9019\u500b\u4e0d\u64ad\u653e\u97f3\u6a02 * \u5982\u679c\u60a8\u8981\u6dfb\u52a0\u97f3\u6a02 bot, \u60a8\u5c07\u5e0c\u671b\u9080\u8acb\u6b64 bot\: \u9700\u8981\u5e6b\u52a9\u6216\u5c0d bot \u6709\u4ec0\u9ebc\u60f3\u6cd5\uff1f\u4e5f\u8a31\u4f60\u53ea\u662f\u60f3\u51fa\u53bb\u73a9\uff1f\u5feb\u4f86 FredBoat \u7684\u4f4f\u8655\!{0} \u60a8\u4e0d\u80fd\u901a\u904e DM \u767c\u9001\u6b64 bot \u547d\u4ee4. Fre_d \u5275\u5efa\u7684 bot +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors helpSent=\u6587\u4ef6\u5df2\u7d93\u79c1\u8a0a\u7d66\u4f60 helpProperUsage=\u6b63\u78ba\u7528\u6cd5\: helpCommandOwnerRestricted=\u6b64\u6307\u4ee4\u53ea\u9650Bot\u7684\u64c1\u6709\u8005\u4f7f\u7528 @@ -257,7 +261,7 @@ helpSayCommand=\u8b93 Bot \u91cd\u8907\u60a8\u8aaa\u7684\u5b57 helpServerInfoCommand=\u986f\u793a\u6b64\u516c\u6703\u7684\u4e00\u4e9b\u72c0\u614b helpUserInfoCommand=\u986f\u793a\u95dc\u65bc\u60a8\u81ea\u5df1\u6216\u5df2\u77e5Bot\u4f7f\u7528\u8005\u7684\u8cc7\u8a0a helpPerms=\u5141\u8a31{0} \u79e9\u7684\u540d\u55ae\u6210\u54e1\u548c\u89d2\u8272\u3002 -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=\u8a2d\u7f6e\u8a72\u884c\u6703\u7684\u9996\u78bc\u3002 helpVoteSkip=\u6295\u7968\u8df3\u904e\u7576\u524d\u7684\u6b4c\u66f2\u3002\u9700\u898150% \u7684\u6240\u6709\u4f7f\u7528\u8005\u5728\u8a9e\u97f3\u804a\u5929\u4e2d\u6295\u7968\u3002 helpMathOperationAdd=\u5217\u5370 num1 \u548c num2 \u7684\u7e3d\u548c\u3002 helpMathOperationSub=\u5217\u5370\u5f9e num1 \u4e2d\u6e1b\u53bb num2 \u7684\u5dee\u7570\u3002 @@ -295,7 +299,7 @@ voteSkipEmbedVoters={0} \u51fa\u4e86{1} \u5df2\u7d93\u6295\u7968\u8df3\u904e\u75 mathOperationResult=\u7d50\u679c\u662f mathOperationDivisionByZeroError=\u4e0d\u80fd\u9664\u4ee5 0\u3002 mathOperationInfinity=\u6578\u5b57\u904e\u5927\u7121\u6cd5\u986f\u793a\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=\u9996\u78bc +prefixGuild=\u9019\u500b\u516c\u6703\u7684\u9996\u78bc\u662f{0} +prefixShowAgain=\u60a8\u53ef\u4ee5\u96a8\u6642\u901a\u904e\u63d0\u53ca\u6211\u4f86\u986f\u793a\u9996\u78bc\u3002 From b33e00aaf4b61505d5a7b057f4a80e6f1e821e57 Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 28 Nov 2017 06:24:17 +0100 Subject: [PATCH 30/62] Migrate to sqlsauce --- FredBoat/build.gradle | 7 +- FredBoat/src/main/java/fredboat/FredBoat.java | 25 +- .../agent/DBConnectionWatchdogAgent.java | 24 +- .../fredboat/command/admin/TestCommand.java | 34 +- .../java/fredboat/db/DatabaseManager.java | 337 +++--------------- .../main/java/fredboat/db/EntityReader.java | 39 +- .../main/java/fredboat/db/EntityWriter.java | 38 +- .../java/fredboat/db/entity/GuildConfig.java | 23 +- .../java/fredboat/db/entity/SearchResult.java | 40 +-- 9 files changed, 141 insertions(+), 426 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index d255c8bba..9d927b533 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -60,13 +60,8 @@ dependencies { compile group: 'io.prometheus', name: 'simpleclient_guava', version: '0.1.0' compile group: 'io.prometheus', name: 'simpleclient_servlet', version: '0.1.0' - compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final' + compile group: 'space.npstr.SqlSauce', name: 'sqlsauce-core', version: '6f65ef5493595165a5f2c7695ad3edad4ec30046' compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.12.Final' - compile group: 'org.hibernate', name: 'hibernate-hikaricp', version: '5.2.12.Final' - compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.9.RELEASE' - compile group: 'org.springframework', name: 'spring-orm', version: '4.3.13.RELEASE'//v5 breaks things (spring boot) - compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4' - compile group: 'com.jcraft', name: 'jsch', version: '0.1.54' compile group: 'org.togglz', name: 'togglz-core', version: '2.5.0.Final' compile group: 'com.google.guava', name: 'guava', version: '23.5-jre' compile group: 'com.github.vladimir-bukhtoyarov', name: 'bucket4j-core', version: '3.0.2' diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index c88884a96..e04bae322 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -59,6 +59,8 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseConnection; +import space.npstr.sqlsauce.DatabaseException; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -90,10 +92,11 @@ public abstract class FredBoat { protected final static StatsAgent jdaEntityCountAgent = new StatsAgent("jda entity counter"); private final static JdaEntityCounts jdaEntityCountsTotal = new JdaEntityCounts(); - private static DatabaseManager dbManager; + private static DatabaseConnection dbConn; private static final List shards = new CopyOnWriteArrayList<>(); - public static void main(String[] args) throws LoginException, IllegalArgumentException, InterruptedException, IOException { + public static void main(String[] args) throws LoginException, IllegalArgumentException, InterruptedException, + IOException, DatabaseException { //just post the info to the console if (args.length > 0 && (args[0].equalsIgnoreCase("-v") @@ -133,24 +136,24 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc log.info("Failed to ignite Spark, FredBoat API unavailable", e); } - dbManager = DatabaseManager.postgres(); + dbConn = DatabaseManager.postgres(); //attempt to connect to the database a few times // this is relevant in a dockerized environment because after a reboot there is no guarantee that the db // container will be started before the fredboat one int dbConnectionAttempts = 0; - while (!dbManager.isAvailable() && dbConnectionAttempts++ < 10) { + while (!dbConn.isAvailable() && dbConnectionAttempts++ < 10) { try { - dbManager.startup(); + dbConn = DatabaseManager.postgres(); } catch (Exception e) { log.error("Could not connect to the database. Retrying in a moment...", e); Thread.sleep(5000); } } - if (!dbManager.isAvailable()) { + if (!dbConn.isAvailable()) { log.error("Could not establish database connection. Exiting..."); shutdown(ExitCodes.EXIT_CODE_ERROR); } - FredBoatAgent.start(new DBConnectionWatchdogAgent(dbManager)); + FredBoatAgent.start(new DBConnectionWatchdogAgent(dbConn)); //Initialise event listeners mainEventListener = new EventListenerBoat(); @@ -334,7 +337,7 @@ private static boolean areWeReadyYet() { } executor.shutdown(); - dbManager.shutdown(); + dbConn.shutdown(); }; public static void shutdown(int code) { @@ -443,9 +446,9 @@ public static FredBoat getShard(int id) { return shards.get(id); } - @Nullable - public static DatabaseManager getDbManager() { - return dbManager; + @Nonnull + public static DatabaseConnection getDbConnection() { + return dbConn; } private static String getVersionInfo() { diff --git a/FredBoat/src/main/java/fredboat/agent/DBConnectionWatchdogAgent.java b/FredBoat/src/main/java/fredboat/agent/DBConnectionWatchdogAgent.java index 72f66b88d..ebb95fb6c 100644 --- a/FredBoat/src/main/java/fredboat/agent/DBConnectionWatchdogAgent.java +++ b/FredBoat/src/main/java/fredboat/agent/DBConnectionWatchdogAgent.java @@ -24,9 +24,9 @@ package fredboat.agent; -import fredboat.db.DatabaseManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseConnection; import java.util.concurrent.TimeUnit; @@ -40,31 +40,21 @@ public class DBConnectionWatchdogAgent extends FredBoatAgent { private static final Logger log = LoggerFactory.getLogger(DBConnectionWatchdogAgent.class); - private DatabaseManager dbManager; + private DatabaseConnection dbConn; - public DBConnectionWatchdogAgent(DatabaseManager dbManager) { + public DBConnectionWatchdogAgent(DatabaseConnection dbConn) { super("database connection", 5, TimeUnit.SECONDS); - this.dbManager = dbManager; + this.dbConn = dbConn; } @Override public void doRun() { - try { - - //we have to proactively call this, as it checks the ssh tunnel for connectivity and does a validation - //query against the DB - //the ssh tunnel does detect a disconnect, but doesn't provide a callback for that, so we have to check - //it ourselves - dbManager.isAvailable(); - - //only recover the database from a failed state - if (dbManager.getState() == DatabaseManager.DatabaseState.FAILED) { - log.info("Attempting to recover failed database connection"); - dbManager.reconnectSSH(); + if (!dbConn.healthCheck()) { + log.warn("Database connection not available!"); } } catch (Exception e) { - log.error("Caught an exception while trying to recover database connection!", e); + log.error("Caught an exception while performing healthcheck on database connection.", e); } } } diff --git a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java index 537371400..c0f4b8305 100644 --- a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java +++ b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java @@ -29,14 +29,17 @@ import fredboat.commandmeta.abs.Command; import fredboat.commandmeta.abs.CommandContext; import fredboat.commandmeta.abs.ICommandRestricted; -import fredboat.db.DatabaseManager; +import fredboat.db.DatabaseNotReadyException; import fredboat.messaging.internal.Context; import fredboat.perms.PermissionLevel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseConnection; +import space.npstr.sqlsauce.DatabaseException; import javax.annotation.Nonnull; import javax.persistence.EntityManager; +import javax.persistence.PersistenceException; /** * Stress tests the database @@ -57,10 +60,10 @@ public TestCommand(String name, String... aliases) { @Override public void onInvoke(@Nonnull CommandContext context) { - FredBoat.executor.submit(() -> invoke(FredBoat.getDbManager(), context, context.args)); + FredBoat.executor.submit(() -> invoke(FredBoat.getDbConnection(), context, context.args)); } - boolean invoke(DatabaseManager dbm, Context context, String args[]) { + boolean invoke(DatabaseConnection dbConn, Context context, String args[]) { boolean result = false; @@ -76,14 +79,14 @@ boolean invoke(DatabaseManager dbm, Context context, String args[]) { context.replyWithName("Beginning stress test with " + threads + " threads each doing " + operations + " operations"); } - prepareStressTest(dbm); + prepareStressTest(dbConn); long started = System.currentTimeMillis(); Result[] results = new Result[threads]; Throwable[] exceptions = new Throwable[threads]; for (int i = 0; i < threads; i++) { results[i] = Result.WORKING; - new StressTestThread(i, operations, results, exceptions, dbm).start(); + new StressTestThread(i, operations, results, exceptions, dbConn).start(); } //wait for when it's done and report the results @@ -133,16 +136,21 @@ private boolean doneYet(Result[] results) { return true; } - private void prepareStressTest(DatabaseManager dbm) { + private void prepareStressTest(DatabaseConnection dbConn) { //drop and recreate the test table - EntityManager em = dbm.getEntityManager(); + EntityManager em = null; try { + em = dbConn.getEntityManager(); em.getTransaction().begin(); em.createNativeQuery(DROP_TEST_TABLE).executeUpdate(); em.createNativeQuery(CREATE_TEST_TABLE).executeUpdate(); em.getTransaction().commit(); + } catch (DatabaseException | PersistenceException e) { + throw new DatabaseNotReadyException(e); } finally { - em.close(); + if (em != null) { + em.close(); + } } } @@ -152,16 +160,16 @@ private class StressTestThread extends Thread { private int operations; private Result[] results; private Throwable[] exceptions; - private DatabaseManager dbm; + private DatabaseConnection dbConn; + - - StressTestThread(int number, int operations, Result[] results, Throwable[] exceptions, DatabaseManager dbm) { + StressTestThread(int number, int operations, Result[] results, Throwable[] exceptions, DatabaseConnection dbConn) { super(StressTestThread.class.getSimpleName() + " number"); this.number = number; this.operations = operations; this.results = results; this.exceptions = exceptions; - this.dbm = dbm; + this.dbConn = dbConn; } @Override @@ -170,7 +178,7 @@ public void run() { EntityManager em = null; try { for (int i = 0; i < operations; i++) { - em = dbm.getEntityManager(); + em = dbConn.getEntityManager(); try { em.getTransaction().begin(); em.createNativeQuery(INSERT_TEST_TABLE) diff --git a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java index 55ab4a565..d5b8f535f 100644 --- a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java +++ b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java @@ -25,25 +25,18 @@ package fredboat.db; -import com.jcraft.jsch.JSch; -import com.jcraft.jsch.Session; -import com.zaxxer.hikari.HikariDataSource; +import com.zaxxer.hikari.HikariConfig; import fredboat.Config; -import fredboat.FredBoat; import fredboat.feature.metrics.Metrics; import net.sf.ehcache.CacheManager; import net.sf.ehcache.config.CacheConfiguration; import net.sf.ehcache.config.PersistenceConfiguration; -import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.internal.SessionFactoryImpl; -import org.hibernate.jpa.HibernatePersistenceProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import space.npstr.sqlsauce.DatabaseConnection; +import space.npstr.sqlsauce.DatabaseException; +import space.npstr.sqlsauce.ssh.SshTunnel; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; import java.util.Properties; public class DatabaseManager { @@ -52,305 +45,57 @@ public class DatabaseManager { private static final String DEFAULT_PERSISTENCE_UNIT_NAME = "fredboat.default"; - //see https://github.com/brettwooldridge/HikariCP connectionTimeout - private static final int HIKARI_TIMEOUT_MILLISECONDS = 10000; - - private EntityManagerFactory emf; - private Session sshTunnel; - private DatabaseState state = DatabaseState.UNINITIALIZED; - //local port, if using SSH tunnel point your jdbc to this, e.g. jdbc:postgresql://localhost:9333/... private static final int SSH_TUNNEL_PORT = 9333; - private final String jdbcUrl; - private final int poolSize; - - /** - * @param jdbcUrl connection to the database - * @param poolSize max size of the connection pool - */ - private DatabaseManager(String jdbcUrl, int poolSize) { - this.jdbcUrl = jdbcUrl; - this.poolSize = poolSize; - } - - public static DatabaseManager postgres() { + public static DatabaseConnection postgres() throws DatabaseException { String jdbc = Config.CONFIG.getJdbcUrl(); if (jdbc == null || jdbc.isEmpty()) { log.info("No JDBC URL found, assuming this is a docker environment. Trying default docker JDBC url"); jdbc = "jdbc:postgresql://db:5432/fredboat?user=fredboat"; } - return new DatabaseManager(jdbc, Config.CONFIG.getHikariPoolSize()); - } - - /** - * Starts the database connection. - * - * @throws IllegalStateException if trying to start a database that is READY or INITIALIZING - */ - public synchronized DatabaseManager startup() { - if (state == DatabaseState.READY || state == DatabaseState.INITIALIZING) { - throw new IllegalStateException("Can't start the database, when it's current state is " + state); - } - - state = DatabaseState.INITIALIZING; - - try { - if (Config.CONFIG.isUseSshTunnel()) { - //don't connect again if it's already connected - if (sshTunnel == null || !sshTunnel.isConnected()) { - connectSSH(); - } - } - - //These are now located in the resources directory as XML - Properties properties = new Properties(); - properties.put("configLocation", "hibernate.cfg.xml"); - - properties.put("hibernate.connection.provider_class", "org.hibernate.hikaricp.internal.HikariCPConnectionProvider"); - properties.put("hibernate.connection.url", jdbcUrl); - properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL95Dialect"); - properties.put("hibernate.cache.use_second_level_cache", "true"); - properties.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache.xml"); - properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); - - //this does a lot of logs - //properties.put("hibernate.show_sql", "true"); - - //automatically update the tables we need - //caution: only add new columns, don't remove or alter old ones, otherwise manual db table migration needed - properties.put("hibernate.hbm2ddl.auto", "update"); - - //disable autocommit, it is not recommended for our usecases, and interferes with some of them - // see https://vladmihalcea.com/2017/05/17/why-you-should-always-use-hibernate-connection-provider_disables_autocommit-for-resource-local-jpa-transactions/ - // this also means all EntityManager interactions need to be wrapped into em.getTransaction.begin() and - // em.getTransaction.commit() to prevent a rollback spam at the database - properties.put("hibernate.connection.autocommit", "true"); - properties.put("hibernate.connection.provider_disables_autocommit", "false"); - - properties.put("hibernate.hikari.maximumPoolSize", Integer.toString(poolSize)); - - //how long to wait for a connection becoming available, also the timeout when a DB fails - properties.put("hibernate.hikari.connectionTimeout", Integer.toString(HIKARI_TIMEOUT_MILLISECONDS)); - //this helps with sorting out connections in pgAdmin - properties.put("hibernate.hikari.dataSource.ApplicationName", "FredBoat_" + Config.CONFIG.getDistribution()); - - //timeout the validation query (will be done automatically through Connection.isValid()) - properties.put("hibernate.hikari.validationTimeout", "1000"); - - properties.put("hibernate.hikari.driverClassName", "org.postgresql.Driver"); - - - LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean(); - emfb.setPackagesToScan("fredboat.db.entity"); - emfb.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); - emfb.setJpaProperties(properties); - emfb.setPersistenceUnitName(DEFAULT_PERSISTENCE_UNIT_NAME); - emfb.setPersistenceProviderClass(HibernatePersistenceProvider.class); - emfb.afterPropertiesSet(); - - //leak prevention, close existing factory if possible - closeEntityManagerFactory(); - - emf = emfb.getObject(); - - try { - //add metrics to hikari and hibernate - SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class); - sessionFactory.getServiceRegistry().getService(ConnectionProvider.class) - .unwrap(HikariDataSource.class) - .setMetricsTrackerFactory(Metrics.instance().hikariStats); - //NOTE the register() on the HibernateCollector may only be called once so this will break in case we create 2 connections - Metrics.instance().hibernateStats.add(sessionFactory, DEFAULT_PERSISTENCE_UNIT_NAME).register(); - } catch (Exception e) { - log.warn("Exception when registering database metrics. This is not expected to happen outside of tests.", e); - } - - //adjusting the ehcache config - if (!Config.CONFIG.isUseSshTunnel()) { - //local database: turn off overflow to disk of the cache - for (CacheManager cacheManager : CacheManager.ALL_CACHE_MANAGERS) { - for (String cacheName : cacheManager.getCacheNames()) { - CacheConfiguration cacheConfig = cacheManager.getCache(cacheName).getCacheConfiguration(); - cacheConfig.getPersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.NONE); - } - } - } - for (CacheManager cacheManager : CacheManager.ALL_CACHE_MANAGERS) { - log.debug(cacheManager.getActiveConfigurationText()); - } - - log.info("Started Hibernate"); - state = DatabaseState.READY; - } catch (Exception ex) { - state = DatabaseState.FAILED; - throw new RuntimeException("Failed starting database connection", ex); - } - return this; - } - - public void reconnectSSH() { - connectSSH(); - //try a test query and if successful set state to ready - EntityManager em = getEntityManager(); - try { - em.getTransaction().begin(); - em.createNativeQuery("SELECT 1;").getResultList(); - em.getTransaction().commit(); - state = DatabaseState.READY; - } finally { - em.close(); - } - } - private synchronized void connectSSH() { + HikariConfig hikariConfig = DatabaseConnection.Builder.getDefaultHikariConfig(); + hikariConfig.setMaximumPoolSize(Config.CONFIG.getHikariPoolSize()); + + Properties hibernateProps = DatabaseConnection.Builder.getDefaultHibernateProps(); + hibernateProps.put("configLocation", "hibernate.cfg.xml"); + hibernateProps.put("hibernate.cache.use_second_level_cache", "true"); + hibernateProps.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache.xml"); + hibernateProps.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); + + DatabaseConnection databaseConnection = new DatabaseConnection.Builder(DEFAULT_PERSISTENCE_UNIT_NAME, jdbc) + .setHikariConfig(hikariConfig) + .setHibernateProps(hibernateProps) + .setDialect("org.hibernate.dialect.PostgreSQL95Dialect") + .addEntityPackage("fredboat.db.entity") + .setAppName("FredBoat_" + Config.CONFIG.getDistribution()) + .setSshDetails(!Config.CONFIG.isUseSshTunnel() ? null : + new SshTunnel.SshDetails(Config.CONFIG.getSshHost(), Config.CONFIG.getSshUser()) + .setLocalPort(SSH_TUNNEL_PORT) + .setRemotePort(Config.CONFIG.getForwardToPort()) + .setKeyFile(Config.CONFIG.getSshPrivateKeyFile()) + ) + .setHikariStats(Metrics.instance().hikariStats) + .setHibernateStats(Metrics.instance().hibernateStats) + .build(); + Metrics.instance().hibernateStats.register(); + + //adjusting the ehcache config if (!Config.CONFIG.isUseSshTunnel()) { - log.warn("Cannot connect ssh tunnel as it is not specified in the config"); - return; - } - if (sshTunnel != null && sshTunnel.isConnected()) { - log.info("Tunnel is already connected, disconnect first before reconnecting"); - return; - } - try { - //establish the tunnel - log.info("Starting SSH tunnel"); - - java.util.Properties config = new java.util.Properties(); - JSch jsch = new JSch(); - JSch.setLogger(new JSchLogger()); - - //Parse host:port - String sshHost = Config.CONFIG.getSshHost().split(":")[0]; - int sshPort = Integer.parseInt(Config.CONFIG.getSshHost().split(":")[1]); - - Session session = jsch.getSession(Config.CONFIG.getSshUser(), - sshHost, - sshPort - ); - jsch.addIdentity(Config.CONFIG.getSshPrivateKeyFile()); - config.put("StrictHostKeyChecking", "no"); - config.put("ConnectionAttempts", "3"); - session.setConfig(config); - session.setServerAliveInterval(1000);//milliseconds - session.connect(); - - log.info("SSH Connected"); - - //forward the port - int assignedPort = session.setPortForwardingL( - SSH_TUNNEL_PORT, - "localhost", - Config.CONFIG.getForwardToPort() - ); - - sshTunnel = session; - - log.info("localhost:" + assignedPort + " -> " + sshHost + ":" + Config.CONFIG.getForwardToPort()); - log.info("Port Forwarded"); - } catch (Exception e) { - throw new RuntimeException("Failed to start SSH tunnel", e); - } - } - - /** - * Please call close() on the EntityManager object you receive after you are done to let the pool recycle the - * connection and save the nature from environmental toxins like open database connections. - */ - public EntityManager getEntityManager() { - return emf.createEntityManager(); - } - - /** - * Performs health checks on the ssh tunnel and database - * - * @return true if the database is operational, false if not - */ - public boolean isAvailable() { - if (state != DatabaseState.READY) { - return false; - } - - //is the ssh connection still alive? - if (sshTunnel != null && !sshTunnel.isConnected()) { - log.error("SSH tunnel lost connection."); - state = DatabaseState.FAILED; - //immediately try to reconnect the tunnel - //DBConnectionWatchdogAgent should take further care of this - FredBoat.executor.submit(this::reconnectSSH); - return false; - } - - return state == DatabaseState.READY; - } - - /** - * Avoid multiple threads calling a close on the factory by wrapping it into this synchronized method - */ - private synchronized void closeEntityManagerFactory() { - if (emf != null && emf.isOpen()) { - try { - emf.close(); - } catch (IllegalStateException ignored) { - //it has already been closed, nothing to catch here + //local database: turn off overflow to disk of the cache + for (CacheManager cacheManager : CacheManager.ALL_CACHE_MANAGERS) { + for (String cacheName : cacheManager.getCacheNames()) { + CacheConfiguration cacheConfig = cacheManager.getCache(cacheName).getCacheConfiguration(); + cacheConfig.getPersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.NONE); + } } } - } - - public DatabaseState getState() { - return state; - } - - public enum DatabaseState { - UNINITIALIZED, - INITIALIZING, - FAILED, - READY, - SHUTDOWN - } - - /** - * Shutdown, close, stop, halt, burn down all resources this object has been using - */ - public void shutdown() { - log.info("DatabaseManager shutdown call received, shutting down"); - state = DatabaseState.SHUTDOWN; - closeEntityManagerFactory(); - - if (sshTunnel != null) - sshTunnel.disconnect(); - } - - private static class JSchLogger implements com.jcraft.jsch.Logger { - - private static final Logger logger = LoggerFactory.getLogger("JSch"); - - @Override - public boolean isEnabled(int level) { - return true; + for (CacheManager cacheManager : CacheManager.ALL_CACHE_MANAGERS) { + log.debug(cacheManager.getActiveConfigurationText()); } - @Override - public void log(int level, String message) { - switch (level) { - case com.jcraft.jsch.Logger.DEBUG: - logger.debug(message); - break; - case com.jcraft.jsch.Logger.INFO: - logger.info(message); - break; - case com.jcraft.jsch.Logger.WARN: - logger.warn(message); - break; - case com.jcraft.jsch.Logger.ERROR: - case com.jcraft.jsch.Logger.FATAL: - logger.error(message); - break; - default: - throw new RuntimeException("Invalid log level"); - } - } + return databaseConnection; } - } diff --git a/FredBoat/src/main/java/fredboat/db/EntityReader.java b/FredBoat/src/main/java/fredboat/db/EntityReader.java index 82c75a3b5..71afb519b 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityReader.java +++ b/FredBoat/src/main/java/fredboat/db/EntityReader.java @@ -27,14 +27,11 @@ import fredboat.FredBoat; -import fredboat.db.entity.BlacklistEntry; -import fredboat.db.entity.GuildConfig; -import fredboat.db.entity.GuildPermissions; -import fredboat.db.entity.IEntity; -import fredboat.db.entity.UConfig; +import fredboat.db.entity.*; import net.dv8tion.jda.core.entities.Guild; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseException; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; @@ -57,22 +54,20 @@ public static GuildPermissions getGuildPermissions(Guild guild) { } private static E getEntity(String id, Class clazz) throws DatabaseNotReadyException { - DatabaseManager dbManager = FredBoat.getDbManager(); - if (dbManager == null || !dbManager.isAvailable()) { - throw new DatabaseNotReadyException(); - } - - EntityManager em = dbManager.getEntityManager(); - E config = null; + EntityManager em = null; + E config; try { + em = FredBoat.getDbConnection().getEntityManager(); em.getTransaction().begin(); config = em.find(clazz, id); em.getTransaction().commit(); - } catch (PersistenceException e) { - log.error("Error while trying to find entity of class {} from DB for id {}", clazz.getName(), id, e); + } catch (DatabaseException | PersistenceException e) { + log.error("Failed to find entity of class {} from DB for id {}", clazz.getName(), id, e); throw new DatabaseNotReadyException(e); } finally { - em.close(); + if (em != null) { + em.close(); + } } //return a fresh object if we didn't find the one we were looking for if (config == null) config = newInstance(id, clazz); @@ -90,18 +85,20 @@ private static E newInstance(String id, Class clazz) { } public static List loadBlacklist() { - DatabaseManager dbManager = FredBoat.getDbManager(); - if (dbManager == null || !dbManager.isAvailable()) { - throw new DatabaseNotReadyException("The database is not available currently. Please try again later."); - } - EntityManager em = dbManager.getEntityManager(); + EntityManager em = null; List result; try { + em = FredBoat.getDbConnection().getEntityManager(); em.getTransaction().begin(); result = em.createQuery("SELECT b FROM BlacklistEntry b", BlacklistEntry.class).getResultList(); em.getTransaction().commit(); + } catch (DatabaseException | PersistenceException e) { + log.error("Failed to load blacklist", e); + throw new DatabaseNotReadyException(e); } finally { - em.close(); + if (em != null) { + em.close(); + } } return result; } diff --git a/FredBoat/src/main/java/fredboat/db/EntityWriter.java b/FredBoat/src/main/java/fredboat/db/EntityWriter.java index 4b69b4dc2..dbb1a43a9 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityWriter.java +++ b/FredBoat/src/main/java/fredboat/db/EntityWriter.java @@ -26,16 +26,13 @@ package fredboat.db; import fredboat.FredBoat; -import fredboat.db.entity.BlacklistEntry; -import fredboat.db.entity.GuildConfig; -import fredboat.db.entity.GuildPermissions; -import fredboat.db.entity.IEntity; -import fredboat.db.entity.UConfig; -import org.hibernate.exception.JDBCConnectionException; +import fredboat.db.entity.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseException; import javax.persistence.EntityManager; +import javax.persistence.PersistenceException; public class EntityWriter { @@ -58,32 +55,26 @@ public static void mergeGuildPermissions(GuildPermissions guildPermissions) { } private static void merge(IEntity entity) { - DatabaseManager dbManager = FredBoat.getDbManager(); - if (dbManager == null || !dbManager.isAvailable()) { - throw new DatabaseNotReadyException(); - } - - EntityManager em = dbManager.getEntityManager(); + EntityManager em = null; try { + em = FredBoat.getDbConnection().getEntityManager(); em.getTransaction().begin(); em.merge(entity); em.getTransaction().commit(); - } catch (JDBCConnectionException e) { + } catch (PersistenceException | DatabaseException e) { log.error("Failed to merge entity {}", entity, e); throw new DatabaseNotReadyException(e); } finally { - em.close(); + if (em != null) { + em.close(); + } } } public static void deleteBlacklistEntry(long id) { - DatabaseManager dbManager = FredBoat.getDbManager(); - if (dbManager == null || !dbManager.isAvailable()) { - throw new DatabaseNotReadyException("The database is not available currently. Please try again later."); - } - - EntityManager em = dbManager.getEntityManager(); + EntityManager em = null; try { + em = FredBoat.getDbConnection().getEntityManager(); em.getTransaction().begin(); BlacklistEntry ble = em.find(BlacklistEntry.class, id); em.getTransaction().commit(); @@ -93,8 +84,13 @@ public static void deleteBlacklistEntry(long id) { em.remove(ble); em.getTransaction().commit(); } + } catch (DatabaseException | PersistenceException e) { + log.error("Db blew up while deleting black list entry for id {}", id, e); + throw new DatabaseNotReadyException("The database is not available currently. Please try again later."); } finally { - em.close(); + if (em != null) { + em.close(); + } } } } diff --git a/FredBoat/src/main/java/fredboat/db/entity/GuildConfig.java b/FredBoat/src/main/java/fredboat/db/entity/GuildConfig.java index 8c1ec9d2a..da35272d0 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/GuildConfig.java +++ b/FredBoat/src/main/java/fredboat/db/entity/GuildConfig.java @@ -26,21 +26,15 @@ package fredboat.db.entity; import fredboat.FredBoat; -import fredboat.db.DatabaseManager; import fredboat.db.DatabaseNotReadyException; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseException; import javax.annotation.Nullable; -import javax.persistence.Cacheable; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EntityManager; -import javax.persistence.Id; -import javax.persistence.PersistenceException; -import javax.persistence.Table; +import javax.persistence.*; import java.io.Serializable; import java.util.List; import java.util.Optional; @@ -161,14 +155,11 @@ public long getGuildId() { @Nullable public static Optional getPrefix(long guildId) { log.debug("loading prefix for guild {}", guildId); - DatabaseManager dbManager = FredBoat.getDbManager(); - if (dbManager == null || !dbManager.isAvailable()) { - throw new DatabaseNotReadyException(); - } //language=JPAQL String query = "SELECT gf.prefix FROM GuildConfig gf WHERE gf.guildId = :guildId"; - EntityManager em = dbManager.getEntityManager(); + EntityManager em = null; try { + em = FredBoat.getDbConnection().getEntityManager(); em.getTransaction().begin(); List result = em.createQuery(query, String.class) .setParameter("guildId", Long.toString(guildId)) @@ -179,11 +170,13 @@ public static Optional getPrefix(long guildId) { } else { return Optional.ofNullable(result.get(0)); } - } catch (PersistenceException e) { + } catch (DatabaseException | PersistenceException e) { log.error("Failed to load prefix for guild {}", guildId, e); throw new DatabaseNotReadyException(e); } finally { - em.close(); + if (em != null) { + em.close(); + } } } } diff --git a/FredBoat/src/main/java/fredboat/db/entity/SearchResult.java b/FredBoat/src/main/java/fredboat/db/entity/SearchResult.java index 355010a65..3ee2ed660 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/SearchResult.java +++ b/FredBoat/src/main/java/fredboat/db/entity/SearchResult.java @@ -32,7 +32,6 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack; import com.sedmelluq.discord.lavaplayer.track.BasicAudioPlaylist; import fredboat.FredBoat; -import fredboat.db.DatabaseManager; import fredboat.db.DatabaseNotReadyException; import fredboat.util.rest.SearchUtil; import org.apache.commons.lang3.SerializationUtils; @@ -40,16 +39,9 @@ import org.hibernate.annotations.CacheConcurrencyStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseException; -import javax.persistence.Cacheable; -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.Entity; -import javax.persistence.EntityManager; -import javax.persistence.Id; -import javax.persistence.Lob; -import javax.persistence.PersistenceException; -import javax.persistence.Table; +import javax.persistence.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -106,23 +98,21 @@ public SearchResult(AudioPlayerManager playerManager, SearchUtil.SearchProvider */ public static AudioPlaylist load(AudioPlayerManager playerManager, SearchUtil.SearchProvider provider, String searchTerm, long maxAgeMillis) throws DatabaseNotReadyException { - DatabaseManager dbManager = FredBoat.getDbManager(); - if (dbManager == null || !dbManager.isAvailable()) { - throw new DatabaseNotReadyException(); - } - - EntityManager em = dbManager.getEntityManager(); + EntityManager em = null; SearchResult sr; SearchResultId sId = new SearchResultId(provider, searchTerm); try { + em = FredBoat.getDbConnection().getEntityManager(); em.getTransaction().begin(); sr = em.find(SearchResult.class, sId); em.getTransaction().commit(); - } catch (PersistenceException e) { + } catch (DatabaseException | PersistenceException e) { log.error("Unexpected error while trying to look up a search result for provider {} and search term {}", provider.name(), searchTerm, e); throw new DatabaseNotReadyException(e); } finally { - em.close(); + if (em != null) { + em.close(); + } } if (sr != null && (maxAgeMillis < 0 || System.currentTimeMillis() < sr.timestamp + maxAgeMillis)) { @@ -138,23 +128,21 @@ public static AudioPlaylist load(AudioPlayerManager playerManager, SearchUtil.Se * @return the merged SearchResult object */ public SearchResult save() { - DatabaseManager dbManager = FredBoat.getDbManager(); - if (dbManager == null || !dbManager.isAvailable()) { - throw new DatabaseNotReadyException(); - } - - EntityManager em = dbManager.getEntityManager(); + EntityManager em = null; try { + em = FredBoat.getDbConnection().getEntityManager(); em.getTransaction().begin(); SearchResult managed = em.merge(this); em.getTransaction().commit(); return managed; - } catch (PersistenceException e) { + } catch (DatabaseException | PersistenceException e) { log.error("Unexpected error while saving a search result for provider {} and search term {}", searchResultId.provider, searchResultId.searchTerm, e); throw new DatabaseNotReadyException(e); } finally { - em.close(); + if (em != null) { + em.close(); + } } } From 11524e4250cd48fad2ff0ede71798aad7e528391 Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 12 Dec 2017 18:18:26 +0100 Subject: [PATCH 31/62] Turn on translations for six new languages Criteria: >= 85% on crowdin Arabic, Suomi, Greek, Magyar, Japanese, Thai --- FredBoat/src/main/java/fredboat/feature/I18n.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/FredBoat/src/main/java/fredboat/feature/I18n.java b/FredBoat/src/main/java/fredboat/feature/I18n.java index 07d4bc5b5..e192d2fe4 100644 --- a/FredBoat/src/main/java/fredboat/feature/I18n.java +++ b/FredBoat/src/main/java/fredboat/feature/I18n.java @@ -50,6 +50,7 @@ public class I18n { public static void start() { LANGS.put("en_US", DEFAULT); LANGS.put("af_ZA", new FredBoatLocale(new Locale("af", "ZA"), "af_ZA", "Afrikaans")); + LANGS.put("ar_SA", new FredBoatLocale(new Locale("ar", "SA"), "ar_SA", "ﺔﻴﺐﺮﻌﻠﺍ")); LANGS.put("bg_BG", new FredBoatLocale(new Locale("bg", "BG"), "bg_BG", "български език")); LANGS.put("ca_ES", new FredBoatLocale(new Locale("ca", "ES"), "ca_ES", "Catalan")); LANGS.put("zh_CN", new FredBoatLocale(new Locale("zh", "CN"), "zh_CN", "简体中文")); @@ -58,11 +59,15 @@ public static void start() { LANGS.put("hr_HR", new FredBoatLocale(new Locale("hr", "HR"), "hr_HR", "Hrvatski")); LANGS.put("da_DK", new FredBoatLocale(new Locale("da", "DK"), "da_DK", "Dansk")); LANGS.put("nl_NL", new FredBoatLocale(new Locale("nl", "NL"), "nl_NL", "Nederlands")); + LANGS.put("fi_FI", new FredBoatLocale(new Locale("fi", "FI"), "fi_FI", "suomi")); LANGS.put("fr_FR", new FredBoatLocale(new Locale("fr", "FR"), "fr_FR", "Français")); LANGS.put("de_DE", new FredBoatLocale(new Locale("de", "DE"), "de_DE", "Deutsch")); + LANGS.put("el_GR", new FredBoatLocale(new Locale("el", "GR"), "el_GR", "ελληνικά")); LANGS.put("he_IL", new FredBoatLocale(new Locale("he", "IL"), "he_IL", "עברית")); + LANGS.put("hu_HU", new FredBoatLocale(new Locale("hu", "HU"), "hu_HU", "magyar")); LANGS.put("id_ID", new FredBoatLocale(new Locale("id", "ID"), "id_ID", "Bahasa Indonesia")); LANGS.put("it_IT", new FredBoatLocale(new Locale("it", "IT"), "it_IT", "Italiano")); + LANGS.put("ja_JP", new FredBoatLocale(new Locale("ja", "JP"), "ja_JP", "日本語")); LANGS.put("ko_KR", new FredBoatLocale(new Locale("ko", "KR"), "ko_KR", "한국어")); LANGS.put("pl_PL", new FredBoatLocale(new Locale("pl", "PL"), "pl_PL", "Polski")); LANGS.put("pt_BR", new FredBoatLocale(new Locale("pt", "BR"), "pt_BR", "Português (Brazil)")); @@ -71,6 +76,7 @@ public static void start() { LANGS.put("ru_RU", new FredBoatLocale(new Locale("ru", "RU"), "ru_RU", "Русский")); LANGS.put("es_ES", new FredBoatLocale(new Locale("es", "ES"), "es_ES", "Español")); LANGS.put("sv_SE", new FredBoatLocale(new Locale("sv", "SE"), "sv_SE", "Svenska")); + LANGS.put("th_TH", new FredBoatLocale(new Locale("th", "TH"), "th_TH", "ไทย")); LANGS.put("tr_TR", new FredBoatLocale(new Locale("tr", "TR"), "tr_TR", "Türkçe")); LANGS.put("vi_VN", new FredBoatLocale(new Locale("vi", "VN"), "vi_VN", "Tiếng Việt")); LANGS.put("cy_GB", new FredBoatLocale(new Locale("cy", "GB"), "cy_GB", "Cymraeg")); From af12346d32f985ba356a7536a2f27b9add342f88 Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 12 Dec 2017 19:10:45 +0100 Subject: [PATCH 32/62] Listening status is badly formatted in Discord clients --- FredBoat/src/main/java/fredboat/FredBoatShard.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/FredBoatShard.java b/FredBoat/src/main/java/fredboat/FredBoatShard.java index 29d5282f4..857206e68 100644 --- a/FredBoat/src/main/java/fredboat/FredBoatShard.java +++ b/FredBoat/src/main/java/fredboat/FredBoatShard.java @@ -284,7 +284,7 @@ protected synchronized static JDABuilder getDefaultShardBuilder(@Nonnull EventLi if (defaultShardBuilder == null) { JDABuilder builder = new JDABuilder(AccountType.BOT) .setToken(Config.CONFIG.getBotToken()) - .setGame(Game.listening(Config.CONFIG.getGame())) + .setGame(Game.playing(Config.CONFIG.getGame())) .setBulkDeleteSplittingEnabled(false) .setEnableShutdownHook(false) .setAudioEnabled(true) From 8ef8122f76afe9f9ab2a186194f9972a3381826f Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 14 Dec 2017 14:07:07 +0100 Subject: [PATCH 33/62] Parse unicode whitespace for commands --- .../src/main/java/fredboat/commandmeta/abs/CommandContext.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java b/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java index 486a83f4c..2159a0fb9 100644 --- a/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java +++ b/FredBoat/src/main/java/fredboat/commandmeta/abs/CommandContext.java @@ -118,7 +118,8 @@ public static CommandContext parse(MessageReceivedEvent event) { } } - String[] args = input.split("\\s+"); //split by any length of white space characters (including new lines) + // the \p{javaSpaceChar} instead of the better known \s is used because it actually includes unicode whitespaces + String[] args = input.split("\\p{javaSpaceChar}+"); if (args.length < 1) { return null; //while this shouldn't technically be possible due to the preprocessing of the input, better be safe than throw exceptions } From 6cf8ae68713dc5231dcc549a5c4559cdf23a6488 Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 15 Dec 2017 05:16:36 +0100 Subject: [PATCH 34/62] Proper usage of the BrainfuckException --- .../src/main/java/fredboat/util/BrainfuckException.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/util/BrainfuckException.java b/FredBoat/src/main/java/fredboat/util/BrainfuckException.java index bb248cc39..016671cff 100644 --- a/FredBoat/src/main/java/fredboat/util/BrainfuckException.java +++ b/FredBoat/src/main/java/fredboat/util/BrainfuckException.java @@ -25,11 +25,12 @@ package fredboat.util; -public class BrainfuckException extends RuntimeException { +import fredboat.commandmeta.MessagingException; + +public class BrainfuckException extends MessagingException { + + private static final long serialVersionUID = -8343893398101119524L; - private BrainfuckException() { - } - public BrainfuckException(String string, Throwable thrwbl) { super(string, thrwbl); } From 58b3c3f3c9cf3f887e4cfec15e3f33084ffb493d Mon Sep 17 00:00:00 2001 From: "Frederik Ar. Mikkelsen" Date: Sun, 17 Dec 2017 14:33:04 +0100 Subject: [PATCH 35/62] Update lavalink --- FredBoat/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index d255c8bba..68f72c48e 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -39,7 +39,7 @@ dependencies { compile(group: 'lavalink', name: 'Lavalink-Client', version: '-SNAPSHOT') } else { //production - compile(group: 'com.github.Frederikam.Lavalink', name: 'Lavalink-Client', version: 'f58ae576aa8a59ef01b98d7c8638f187c5349b1a') + compile(group: 'com.github.Frederikam.Lavalink', name: 'Lavalink-Client', version: '3b25a66378d985b585d2b059d97935a2780b93c1') } compile group: 'org.apache.commons', name: 'commons-text', version: '1.1' From efaddb85e37a01dd73ff45f8cbbc7b5d43692f5e Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 19 Dec 2017 22:20:07 +0100 Subject: [PATCH 36/62] Split database in main and cache credentials file has been upgraded, updated and documented This also fixes and migrates and the databases for docker users To the best of my knowledge, this commit fully backwards compatible with all kinds of docker and non-docker selfhosters. --- FredBoat/build.gradle | 2 +- FredBoat/credentials.yaml.example | 20 ++- FredBoat/docker-compose.yml | 2 +- FredBoat/docker/database/Dockerfile | 6 +- FredBoat/docker/database/initdb.sh | 20 ++- .../docker/database/postgres-healthcheck.sh | 21 ---- FredBoat/docker/database/run.sh | 35 ++++++ FredBoat/src/main/java/fredboat/Config.java | 119 ++++++++++++++---- FredBoat/src/main/java/fredboat/FredBoat.java | 46 ++++--- .../fredboat/audio/player/GuildPlayer.java | 2 +- .../fredboat/command/admin/TestCommand.java | 2 +- .../command/moderation/ConfigCommand.java | 2 +- .../moderation/PermissionsCommand.java | 2 +- .../command/moderation/PrefixCommand.java | 2 +- .../java/fredboat/db/DatabaseManager.java | 83 +++++++----- .../main/java/fredboat/db/EntityReader.java | 10 +- .../main/java/fredboat/db/EntityWriter.java | 10 +- .../db/entity/{ => cache}/SearchResult.java | 6 +- .../db/entity/{ => main}/BlacklistEntry.java | 4 +- .../db/entity/{ => main}/GuildConfig.java | 5 +- .../entity/{ => main}/GuildPermissions.java | 3 +- .../db/entity/{ => main}/UConfig.java | 4 +- .../src/main/java/fredboat/feature/I18n.java | 2 +- .../main/java/fredboat/perms/PermsUtil.java | 2 +- .../fredboat/util/ratelimit/Blacklist.java | 2 +- .../java/fredboat/util/rest/SearchUtil.java | 4 +- FredBoat/src/main/resources/ehcache_cache.xml | 63 ++++++++++ .../{ehcache.xml => ehcache_main.xml} | 9 +- FredBoat/src/main/resources/hibernate.cfg.xml | 36 ------ docker-compose.yml | 2 +- 30 files changed, 358 insertions(+), 168 deletions(-) mode change 100644 => 100755 FredBoat/docker/database/initdb.sh delete mode 100644 FredBoat/docker/database/postgres-healthcheck.sh create mode 100755 FredBoat/docker/database/run.sh rename FredBoat/src/main/java/fredboat/db/entity/{ => cache}/SearchResult.java (98%) rename FredBoat/src/main/java/fredboat/db/entity/{ => main}/BlacklistEntry.java (98%) rename FredBoat/src/main/java/fredboat/db/entity/{ => main}/GuildConfig.java (97%) rename FredBoat/src/main/java/fredboat/db/entity/{ => main}/GuildPermissions.java (98%) rename FredBoat/src/main/java/fredboat/db/entity/{ => main}/UConfig.java (97%) create mode 100644 FredBoat/src/main/resources/ehcache_cache.xml rename FredBoat/src/main/resources/{ehcache.xml => ehcache_main.xml} (91%) delete mode 100644 FredBoat/src/main/resources/hibernate.cfg.xml diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 9d927b533..b26650e21 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -60,7 +60,7 @@ dependencies { compile group: 'io.prometheus', name: 'simpleclient_guava', version: '0.1.0' compile group: 'io.prometheus', name: 'simpleclient_servlet', version: '0.1.0' - compile group: 'space.npstr.SqlSauce', name: 'sqlsauce-core', version: '6f65ef5493595165a5f2c7695ad3edad4ec30046' + compile group: 'space.npstr.SqlSauce', name: 'sqlsauce-core', version: '0.0.3' compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.12.Final' compile group: 'org.togglz', name: 'togglz-core', version: '2.5.0.Final' compile group: 'com.google.guava', name: 'guava', version: '23.5-jre' diff --git a/FredBoat/credentials.yaml.example b/FredBoat/credentials.yaml.example index 578696892..d51f62959 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/credentials.yaml.example @@ -88,7 +88,7 @@ openWeatherKey: "" # Learn more about the postgres jdbc url here: https://jdbc.postgresql.org/documentation/head/connect.html # If you are using an SSH tunnel, you need to point your jdbc url to localhost:9333 # Example jdbc: "jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass" -jdbcUrl: "" +jdbcUrl: "" # Ssh tunnel for a remote database. this is useful for when you don't want to expose your database on the remote server @@ -99,7 +99,23 @@ useSshTunnel: false sshHost: "" # add the ssh port to the ip / url, usually 22, for example: "db.example.com:22" sshUser: "" # user on the remote machine sshPrivateKeyFile: "" # path to an ssh private key file which is authorized to log in to the sshUser on the remote machine. learn how to create these: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04#step-four-—-add-public-key-authentication-(recommended) -forwardToPort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default +sshKeyPassphrase: "" # optional passphrase for the ssh key file +tunnelLocalPort: 5432 # endpoint port of the tunnel on the machine running fredboat; makes sure these dont collide; this one needs to be used in the jdbc url +tunnelRemotePort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default + +# Database for caching things, see config of main database above for details. +# You only need this if you want to have these in two different places (which we recommend, can be two databases in a single postgres database) +# The main benefit is that you don't have to backup/migrate the cache database, it can just be dropped/recreated +# If you are going to use a ssh tunnels for both database connections, make sure the local tunnel ports don't collide +cacheJdbcUrl: "" +cacheUseSshTunnel: false +cacheSshHost: "" +cacheSshUser: "" +cacheSshPrivateKeyFile: "" +cacheSshKeyPassphrase: "" +cacheTunnelLocalPort: 5433 +cacheTunnelRemotePort: 5432 + # Additional google keys diff --git a/FredBoat/docker-compose.yml b/FredBoat/docker-compose.yml index 5f8580fdc..371856951 100644 --- a/FredBoat/docker-compose.yml +++ b/FredBoat/docker-compose.yml @@ -25,7 +25,7 @@ services: ################################################################################ db: build: ./docker/database/ - restart: on-failure:3 + restart: always # WINDOWS ONLY: if you are running under windows you need to comment out the following two lines: volumes: diff --git a/FredBoat/docker/database/Dockerfile b/FredBoat/docker/database/Dockerfile index 971390c75..33e287936 100644 --- a/FredBoat/docker/database/Dockerfile +++ b/FredBoat/docker/database/Dockerfile @@ -1,5 +1,5 @@ FROM postgres:10.0 ENV POSTGRES_USER fredboat -COPY postgres-healthcheck.sh /usr/local/bin/ -COPY initdb.sh /docker-entrypoint-initdb.d/ -HEALTHCHECK CMD ["postgres-healthcheck.sh"] +COPY initdb.sh /usr/local/bin/ +COPY run.sh /usr/local/bin/ +ENTRYPOINT ["/bin/bash", "run.sh"] diff --git a/FredBoat/docker/database/initdb.sh b/FredBoat/docker/database/initdb.sh old mode 100644 new mode 100755 index 5fd6fa1d5..347246115 --- a/FredBoat/docker/database/initdb.sh +++ b/FredBoat/docker/database/initdb.sh @@ -1,5 +1,21 @@ #!/bin/bash set -e -psql -v ON_ERROR_STOP=1 --username "postgres" -d fredboat -c "CREATE EXTENSION hstore;" -psql -v ON_ERROR_STOP=1 --username "postgres" -d fredboat -c "CREATE EXTENSION pg_trgm;" +# make sure the fredboat user exists +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -tAc "SELECT 1 FROM pg_roles WHERE rolname='fredboat'" | grep -q 1 || createuser -U "$POSTGRES_USER" fredboat + +# make sure the fredboat database exists +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -tc "SELECT 1 FROM pg_database WHERE datname = 'fredboat';" | grep -q 1 || psql -U "$POSTGRES_USER" -c "CREATE DATABASE fredboat WITH OWNER = fredboat;" +# make sure the fredboat datbase is owned by the user fredboat +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -c "ALTER DATABASE fredboat OWNER TO fredboat;" +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -c "GRANT ALL PRIVILEGES ON DATABASE fredboat TO fredboat;" +# make sure HSTORE extension is enabled +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d fredboat -c "CREATE EXTENSION IF NOT EXISTS hstore;" + +# make sure the cache database exists +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -tc "SELECT 1 FROM pg_database WHERE datname = 'fredboat_cache';" | grep -q 1 || psql -U "$POSTGRES_USER" -c "CREATE DATABASE fredboat_cache WITH OWNER = fredboat;" +# make sure the cache database is owned by the user fredboat +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -c "ALTER DATABASE fredboat_cache OWNER TO fredboat;" +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -c "GRANT ALL PRIVILEGES ON DATABASE fredboat_cache TO fredboat;" +# make sure HSTORE extension is enabled +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d fredboat_cache -c "CREATE EXTENSION IF NOT EXISTS hstore;" diff --git a/FredBoat/docker/database/postgres-healthcheck.sh b/FredBoat/docker/database/postgres-healthcheck.sh deleted file mode 100644 index 299416740..000000000 --- a/FredBoat/docker/database/postgres-healthcheck.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -set -eo pipefail - -host="$(hostname -i || echo '127.0.0.1')" -user="${POSTGRES_USER:-postgres}" -db="${POSTGRES_DB:-$POSTGRES_USER}" -export PGPASSWORD="${POSTGRES_PASSWORD:-}" - -args=( - # force postgres to not use the local unix socket (test "external" connectibility) - --host "$host" - --username "$user" - --dbname "$db" - --quiet --no-align --tuples-only -) - -if select="$(echo 'SELECT 1' | psql "${args[@]}")" && [ "$select" = '1' ]; then - exit 0 -fi - -exit 1 diff --git a/FredBoat/docker/database/run.sh b/FredBoat/docker/database/run.sh new file mode 100755 index 000000000..7ae3e3823 --- /dev/null +++ b/FredBoat/docker/database/run.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# We are using this script, because we need to reliably execute a script on each start of the db container, +# to migrate the database for containers with an external volume persisting the database data, where the scripts in +# /docker-entrypoint-initdb.d/ are getting skipped. +# Relevant issue: https://github.com/docker-library/postgres/issues/191 + +set -e + +_term() { + echo "Caught SIGTERM signal!" + # sending SIGINT to postgres tells it to do a fast shutdown, which is what we want here due to the default 10 seconds + # which docker waits until send a SIGKILL which we want to avoid. + # Relevant docs: https://www.postgresql.org/docs/10/static/server-shutdown.html + kill -INT "$child" 2>/dev/null +} +trap _term SIGTERM + +# running the official postgres entry script in the background +echo "Running entry point" +docker-entrypoint.sh postgres & + +# wait until the database is ready +while ! pg_isready -U postgres; do + echo "Waiting on postgres to be ready" + sleep 1 +done + +# run our own init script +echo "Running init db" +initdb.sh + +# Wait on the "docker-entrypoint.sh postgres &" process that we started in the background +child=$! +wait "$child" diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java index 11444376b..a21754e31 100644 --- a/FredBoat/src/main/java/fredboat/Config.java +++ b/FredBoat/src/main/java/fredboat/Config.java @@ -36,7 +36,9 @@ import org.slf4j.LoggerFactory; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.error.YAMLException; +import space.npstr.sqlsauce.ssh.SshTunnel; +import javax.annotation.Nullable; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -106,13 +108,15 @@ public class Config { private String spotifySecret; private String openWeatherKey; - // database + SSH tunnel + // main database + SSH tunnel private String jdbcUrl; - private boolean useSshTunnel; - private String sshHost; //Eg localhost:22 - private String sshUser; //Eg fredboat - private String sshPrivateKeyFile; - private int forwardToPort; //port where the remote database is listening, postgres default: 5432 + @Nullable + private SshTunnel.SshDetails mainSshTunnelConfig; + + // cache database + SSH tunnel + private String cacheJdbcUrl; + @Nullable + private SshTunnel.SshDetails cacheSshTunnelConfig; // misc private String sentryDsn; @@ -228,15 +232,84 @@ public Config(File credentialsFile, File configFile) { openWeatherKey = (String) creds.getOrDefault("openWeatherKey", ""); - // database + // main database jdbcUrl = (String) creds.getOrDefault("jdbcUrl", ""); - useSshTunnel = (boolean) creds.getOrDefault("useSshTunnel", false); - sshHost = (String) creds.getOrDefault("sshHost", "localhost:22"); - sshUser = (String) creds.getOrDefault("sshUser", "fredboat"); - sshPrivateKeyFile = (String) creds.getOrDefault("sshPrivateKeyFile", "database.ppk"); - forwardToPort = (int) creds.getOrDefault("forwardToPort", 5432); + if (jdbcUrl == null || jdbcUrl.isEmpty()) { + if ("docker".equals(System.getenv("ENV"))) { + log.info("No main JDBC URL found, docker environment detected. Using default docker JDBC url"); + jdbcUrl = "jdbc:postgresql://db:5432/fredboat?user=fredboat"; + } else { + String message = "No main jdbcUrl provided in a non-docker environment."; + log.error(message); + throw new RuntimeException(message); + } + } + boolean useSshTunnel = (boolean) creds.getOrDefault("useSshTunnel", false); + if (useSshTunnel) { + //Parse host:port + String sshHostRaw = (String) creds.getOrDefault("sshHost", "localhost:22"); + String sshHost = sshHostRaw.split(":")[0]; + int sshPort; + try { + sshPort = Integer.parseInt(sshHostRaw.split(":")[1]); + } catch (Exception e) { + sshPort = 22; + } + String sshUser = (String) creds.getOrDefault("sshUser", "fredboat"); + String sshPrivateKeyFile = (String) creds.getOrDefault("sshPrivateKeyFile", "database.ppk"); + String sshKeyPassphrase = (String) creds.getOrDefault("sshKeyPassphrase", ""); + int tunnelLocalPort = (int) creds.getOrDefault("tunnelLocalPort", 9333);//9333 is a legacy port for backwards compatibility + String tunnelRemotePortKey = "tunnelRemotePort"; + if (creds.containsKey("forwardToPort")) {//legacy check + tunnelRemotePortKey = "forwardToPort"; + } + int tunnelRemotePort = (int) creds.getOrDefault(tunnelRemotePortKey, 5432); + + mainSshTunnelConfig = new SshTunnel.SshDetails(sshHost, sshUser) + .setKeyFile(sshPrivateKeyFile) + .setPassphrase(sshKeyPassphrase == null || sshKeyPassphrase.isEmpty() ? null : sshKeyPassphrase) + .setSshPort(sshPort) + .setLocalPort(tunnelLocalPort) + .setRemotePort(tunnelRemotePort); + } + // cache database + cacheJdbcUrl = (String) creds.getOrDefault("cacheJdbcUrl", ""); + if (cacheJdbcUrl == null || cacheJdbcUrl.isEmpty()) { + if ("docker".equals(System.getenv("ENV"))) { + log.info("No cacheJdbcUrl found, docker environment detected. Using default docker JDBC url"); + cacheJdbcUrl = "jdbc:postgresql://db:5432/fredboat_cache?user=fredboat"; + } else { + log.warn("No cacheJdbcUrl provided in a non-docker environment. Falling back to the main one."); + cacheJdbcUrl = jdbcUrl; + } + } + boolean cacheUseSshTunnel = (boolean) creds.getOrDefault("cacheUseSshTunnel", false); + if (cacheUseSshTunnel) { + //Parse host:port + String cacheSshHostRaw = (String) creds.getOrDefault("cacheSshHost", "localhost:22"); + String cacheSshHost = cacheSshHostRaw.split(":")[0]; + int cacheSshPort; + try { + cacheSshPort = Integer.parseInt(cacheSshHostRaw.split(":")[1]); + } catch (Exception e) { + cacheSshPort = 22; + } + String cacheSshUser = (String) creds.getOrDefault("cacheSshUser", "fredboat"); + String cacheSshPrivateKeyFile = (String) creds.getOrDefault("cacheSshPrivateKeyFile", "database.ppk"); + String cacheSshKeyPassphrase = (String) creds.getOrDefault("cacheSshKeyPassphrase", ""); + int cacheTunnelLocalPort = (int) creds.getOrDefault("cacheTunnelLocalPort", 5433); + int cacheTunnelRemotePort = (int) creds.getOrDefault("cacheTunnelRemotePort", 5432); + + cacheSshTunnelConfig = new SshTunnel.SshDetails(cacheSshHost, cacheSshUser) + .setKeyFile(cacheSshPrivateKeyFile) + .setPassphrase(cacheSshKeyPassphrase == null || cacheSshKeyPassphrase.isEmpty() ? null : cacheSshKeyPassphrase) + .setSshPort(cacheSshPort) + .setLocalPort(cacheTunnelLocalPort) + .setRemotePort(cacheTunnelRemotePort); + } + // misc Map linkNodes = (Map) creds.get("lavalinkHosts"); if (linkNodes != null) { @@ -466,24 +539,18 @@ public String getJdbcUrl() { return jdbcUrl; } - public boolean isUseSshTunnel() { - return useSshTunnel; - } - - public String getSshHost() { - return sshHost; - } - - public String getSshUser() { - return sshUser; + @Nullable + public SshTunnel.SshDetails getMainSshTunnelConfig() { + return mainSshTunnelConfig; } - public String getSshPrivateKeyFile() { - return sshPrivateKeyFile; + public String getCacheJdbcUrl() { + return cacheJdbcUrl; } - public int getForwardToPort() { - return forwardToPort; + @Nullable + public SshTunnel.SshDetails getCacheSshTunnelConfig() { + return cacheSshTunnelConfig; } public List getLavalinkHosts() { diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index e04bae322..4c1895b36 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -39,11 +39,7 @@ import fredboat.feature.metrics.Metrics; import fredboat.shared.constant.DistributionEnum; import fredboat.shared.constant.ExitCodes; -import fredboat.util.AppInfo; -import fredboat.util.ConnectQueue; -import fredboat.util.GitRepoState; -import fredboat.util.JDAUtil; -import fredboat.util.TextUtils; +import fredboat.util.*; import fredboat.util.rest.Http; import fredboat.util.rest.OpenWeatherAPI; import fredboat.util.rest.models.weather.RetrievedWeather; @@ -92,7 +88,8 @@ public abstract class FredBoat { protected final static StatsAgent jdaEntityCountAgent = new StatsAgent("jda entity counter"); private final static JdaEntityCounts jdaEntityCountsTotal = new JdaEntityCounts(); - private static DatabaseConnection dbConn; + private static DatabaseConnection mainDbConn; + private static DatabaseConnection cacheDbConn; private static final List shards = new CopyOnWriteArrayList<>(); public static void main(String[] args) throws LoginException, IllegalArgumentException, InterruptedException, @@ -136,24 +133,35 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc log.info("Failed to ignite Spark, FredBoat API unavailable", e); } - dbConn = DatabaseManager.postgres(); + try { + mainDbConn = DatabaseManager.main(); + } catch (Exception e) { + shutdown(ExitCodes.EXIT_CODE_ERROR); + } //attempt to connect to the database a few times // this is relevant in a dockerized environment because after a reboot there is no guarantee that the db // container will be started before the fredboat one int dbConnectionAttempts = 0; - while (!dbConn.isAvailable() && dbConnectionAttempts++ < 10) { + while (!mainDbConn.isAvailable() && dbConnectionAttempts++ < 10) { try { - dbConn = DatabaseManager.postgres(); + mainDbConn = DatabaseManager.main(); } catch (Exception e) { log.error("Could not connect to the database. Retrying in a moment...", e); Thread.sleep(5000); } } - if (!dbConn.isAvailable()) { + if (!mainDbConn.isAvailable()) { log.error("Could not establish database connection. Exiting..."); shutdown(ExitCodes.EXIT_CODE_ERROR); } - FredBoatAgent.start(new DBConnectionWatchdogAgent(dbConn)); + FredBoatAgent.start(new DBConnectionWatchdogAgent(mainDbConn)); + + try { + cacheDbConn = DatabaseManager.cache(); + } catch (Exception e) { + shutdown(ExitCodes.EXIT_CODE_ERROR); + } + Metrics.instance().hibernateStats.register(); //call this exactly once after all db connections have been created //Initialise event listeners mainEventListener = new EventListenerBoat(); @@ -337,7 +345,12 @@ private static boolean areWeReadyYet() { } executor.shutdown(); - dbConn.shutdown(); + if (cacheDbConn != null) { + cacheDbConn.shutdown(); + } + if (mainDbConn != null) { + mainDbConn.shutdown(); + } }; public static void shutdown(int code) { @@ -447,8 +460,13 @@ public static FredBoat getShard(int id) { } @Nonnull - public static DatabaseConnection getDbConnection() { - return dbConn; + public static DatabaseConnection getMainDbConnection() { + return mainDbConn; + } + + @Nonnull + public static DatabaseConnection getCacheDbConnection() { + return cacheDbConn; } private static String getVersionInfo() { diff --git a/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java b/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java index 0a34e2832..088dcb012 100644 --- a/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java +++ b/FredBoat/src/main/java/fredboat/audio/player/GuildPlayer.java @@ -39,7 +39,7 @@ import fredboat.commandmeta.abs.CommandContext; import fredboat.db.DatabaseNotReadyException; import fredboat.db.EntityReader; -import fredboat.db.entity.GuildConfig; +import fredboat.db.entity.main.GuildConfig; import fredboat.feature.I18n; import fredboat.messaging.CentralMessaging; import fredboat.perms.PermissionLevel; diff --git a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java index c0f4b8305..15918b08f 100644 --- a/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java +++ b/FredBoat/src/main/java/fredboat/command/admin/TestCommand.java @@ -60,7 +60,7 @@ public TestCommand(String name, String... aliases) { @Override public void onInvoke(@Nonnull CommandContext context) { - FredBoat.executor.submit(() -> invoke(FredBoat.getDbConnection(), context, context.args)); + FredBoat.executor.submit(() -> invoke(FredBoat.getMainDbConnection(), context, context.args)); } boolean invoke(DatabaseConnection dbConn, Context context, String args[]) { diff --git a/FredBoat/src/main/java/fredboat/command/moderation/ConfigCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/ConfigCommand.java index d53b498a1..1302cc881 100644 --- a/FredBoat/src/main/java/fredboat/command/moderation/ConfigCommand.java +++ b/FredBoat/src/main/java/fredboat/command/moderation/ConfigCommand.java @@ -32,7 +32,7 @@ import fredboat.commandmeta.abs.IModerationCommand; import fredboat.db.EntityReader; import fredboat.db.EntityWriter; -import fredboat.db.entity.GuildConfig; +import fredboat.db.entity.main.GuildConfig; import fredboat.messaging.CentralMessaging; import fredboat.messaging.internal.Context; import fredboat.perms.PermissionLevel; diff --git a/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java index f92c7c442..8717b08ce 100644 --- a/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java +++ b/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java @@ -31,7 +31,7 @@ import fredboat.commandmeta.abs.IModerationCommand; import fredboat.db.EntityReader; import fredboat.db.EntityWriter; -import fredboat.db.entity.GuildPermissions; +import fredboat.db.entity.main.GuildPermissions; import fredboat.feature.togglz.FeatureFlags; import fredboat.messaging.CentralMessaging; import fredboat.messaging.internal.Context; diff --git a/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java index 8336e7e61..81a4ca3d2 100644 --- a/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java +++ b/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java @@ -36,7 +36,7 @@ import fredboat.commandmeta.abs.IModerationCommand; import fredboat.db.EntityReader; import fredboat.db.EntityWriter; -import fredboat.db.entity.GuildConfig; +import fredboat.db.entity.main.GuildConfig; import fredboat.messaging.internal.Context; import fredboat.perms.PermissionLevel; import fredboat.perms.PermsUtil; diff --git a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java index d5b8f535f..c70db7d9e 100644 --- a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java +++ b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java @@ -35,7 +35,6 @@ import org.slf4j.LoggerFactory; import space.npstr.sqlsauce.DatabaseConnection; import space.npstr.sqlsauce.DatabaseException; -import space.npstr.sqlsauce.ssh.SshTunnel; import java.util.Properties; @@ -43,58 +42,84 @@ public class DatabaseManager { private static final Logger log = LoggerFactory.getLogger(DatabaseManager.class); - private static final String DEFAULT_PERSISTENCE_UNIT_NAME = "fredboat.default"; + private static final String MAIN_PERSISTENCE_UNIT_NAME = "fredboat.main"; + private static final String CACHE_PERSISTENCE_UNIT_NAME = "fredboat.cache"; - //local port, if using SSH tunnel point your jdbc to this, e.g. jdbc:postgresql://localhost:9333/... - private static final int SSH_TUNNEL_PORT = 9333; + public static DatabaseConnection main() throws DatabaseException { + String jdbc = Config.CONFIG.getJdbcUrl(); + HikariConfig hikariConfig = DatabaseConnection.Builder.getDefaultHikariConfig(); + hikariConfig.setMaximumPoolSize(Config.CONFIG.getHikariPoolSize()); - public static DatabaseConnection postgres() throws DatabaseException { - String jdbc = Config.CONFIG.getJdbcUrl(); - if (jdbc == null || jdbc.isEmpty()) { - log.info("No JDBC URL found, assuming this is a docker environment. Trying default docker JDBC url"); - jdbc = "jdbc:postgresql://db:5432/fredboat?user=fredboat"; + Properties hibernateProps = DatabaseConnection.Builder.getDefaultHibernateProps(); + hibernateProps.put("hibernate.cache.use_second_level_cache", "true"); + hibernateProps.put("hibernate.cache.use_query_cache", "true"); + hibernateProps.put("net.sf.ehcache.configurationResourceName", "/ehcache_main.xml"); + hibernateProps.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache_main.xml"); + hibernateProps.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); + + DatabaseConnection databaseConnection = new DatabaseConnection.Builder(MAIN_PERSISTENCE_UNIT_NAME, jdbc) + .setHikariConfig(hikariConfig) + .setHibernateProps(hibernateProps) + .setDialect("org.hibernate.dialect.PostgreSQL95Dialect") + .addEntityPackage("fredboat.db.entity.main") + .setAppName("FredBoat_" + Config.CONFIG.getDistribution()) + .setSshDetails(Config.CONFIG.getMainSshTunnelConfig()) + .setHikariStats(Metrics.instance().hikariStats) + .setHibernateStats(Metrics.instance().hibernateStats) + .setCheckConnection(false) + .build(); + + //adjusting the ehcache config + if (Config.CONFIG.getMainSshTunnelConfig() == null) { + //local database: turn off overflow to disk of the cache + CacheManager cacheManager = CacheManager.getCacheManager("MAIN_CACHEMANAGER"); + for (String cacheName : cacheManager.getCacheNames()) { + CacheConfiguration cacheConfig = cacheManager.getCache(cacheName).getCacheConfiguration(); + cacheConfig.getPersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.NONE); + } } + log.debug(CacheManager.getCacheManager("MAIN_CACHEMANAGER").getActiveConfigurationText()); + + return databaseConnection; + } + + + public static DatabaseConnection cache() throws DatabaseException { + String cacheJdbc = Config.CONFIG.getCacheJdbcUrl(); HikariConfig hikariConfig = DatabaseConnection.Builder.getDefaultHikariConfig(); hikariConfig.setMaximumPoolSize(Config.CONFIG.getHikariPoolSize()); Properties hibernateProps = DatabaseConnection.Builder.getDefaultHibernateProps(); - hibernateProps.put("configLocation", "hibernate.cfg.xml"); hibernateProps.put("hibernate.cache.use_second_level_cache", "true"); - hibernateProps.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache.xml"); + hibernateProps.put("hibernate.cache.use_query_cache", "true"); + hibernateProps.put("net.sf.ehcache.configurationResourceName", "/ehcache_cache.xml"); + hibernateProps.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache_cache.xml"); hibernateProps.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); - DatabaseConnection databaseConnection = new DatabaseConnection.Builder(DEFAULT_PERSISTENCE_UNIT_NAME, jdbc) + + DatabaseConnection databaseConnection = new DatabaseConnection.Builder(CACHE_PERSISTENCE_UNIT_NAME, cacheJdbc) .setHikariConfig(hikariConfig) .setHibernateProps(hibernateProps) .setDialect("org.hibernate.dialect.PostgreSQL95Dialect") - .addEntityPackage("fredboat.db.entity") + .addEntityPackage("fredboat.db.entity.cache") .setAppName("FredBoat_" + Config.CONFIG.getDistribution()) - .setSshDetails(!Config.CONFIG.isUseSshTunnel() ? null : - new SshTunnel.SshDetails(Config.CONFIG.getSshHost(), Config.CONFIG.getSshUser()) - .setLocalPort(SSH_TUNNEL_PORT) - .setRemotePort(Config.CONFIG.getForwardToPort()) - .setKeyFile(Config.CONFIG.getSshPrivateKeyFile()) - ) + .setSshDetails(Config.CONFIG.getCacheSshTunnelConfig()) .setHikariStats(Metrics.instance().hikariStats) .setHibernateStats(Metrics.instance().hibernateStats) .build(); - Metrics.instance().hibernateStats.register(); //adjusting the ehcache config - if (!Config.CONFIG.isUseSshTunnel()) { + if (Config.CONFIG.getMainSshTunnelConfig() == null) { //local database: turn off overflow to disk of the cache - for (CacheManager cacheManager : CacheManager.ALL_CACHE_MANAGERS) { - for (String cacheName : cacheManager.getCacheNames()) { - CacheConfiguration cacheConfig = cacheManager.getCache(cacheName).getCacheConfiguration(); - cacheConfig.getPersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.NONE); - } + CacheManager cacheManager = CacheManager.getCacheManager("CACHE_CACHEMANAGER"); + for (String cacheName : cacheManager.getCacheNames()) { + CacheConfiguration cacheConfig = cacheManager.getCache(cacheName).getCacheConfiguration(); + cacheConfig.getPersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.NONE); } } - for (CacheManager cacheManager : CacheManager.ALL_CACHE_MANAGERS) { - log.debug(cacheManager.getActiveConfigurationText()); - } + log.debug(CacheManager.getCacheManager("CACHE_CACHEMANAGER").getActiveConfigurationText()); return databaseConnection; } diff --git a/FredBoat/src/main/java/fredboat/db/EntityReader.java b/FredBoat/src/main/java/fredboat/db/EntityReader.java index 71afb519b..e1200cd7d 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityReader.java +++ b/FredBoat/src/main/java/fredboat/db/EntityReader.java @@ -27,7 +27,11 @@ import fredboat.FredBoat; -import fredboat.db.entity.*; +import fredboat.db.entity.IEntity; +import fredboat.db.entity.main.BlacklistEntry; +import fredboat.db.entity.main.GuildConfig; +import fredboat.db.entity.main.GuildPermissions; +import fredboat.db.entity.main.UConfig; import net.dv8tion.jda.core.entities.Guild; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,7 +61,7 @@ private static E getEntity(String id, Class clazz) throws EntityManager em = null; E config; try { - em = FredBoat.getDbConnection().getEntityManager(); + em = FredBoat.getMainDbConnection().getEntityManager(); em.getTransaction().begin(); config = em.find(clazz, id); em.getTransaction().commit(); @@ -88,7 +92,7 @@ public static List loadBlacklist() { EntityManager em = null; List result; try { - em = FredBoat.getDbConnection().getEntityManager(); + em = FredBoat.getMainDbConnection().getEntityManager(); em.getTransaction().begin(); result = em.createQuery("SELECT b FROM BlacklistEntry b", BlacklistEntry.class).getResultList(); em.getTransaction().commit(); diff --git a/FredBoat/src/main/java/fredboat/db/EntityWriter.java b/FredBoat/src/main/java/fredboat/db/EntityWriter.java index dbb1a43a9..c5be1dab2 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityWriter.java +++ b/FredBoat/src/main/java/fredboat/db/EntityWriter.java @@ -26,7 +26,11 @@ package fredboat.db; import fredboat.FredBoat; -import fredboat.db.entity.*; +import fredboat.db.entity.IEntity; +import fredboat.db.entity.main.BlacklistEntry; +import fredboat.db.entity.main.GuildConfig; +import fredboat.db.entity.main.GuildPermissions; +import fredboat.db.entity.main.UConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import space.npstr.sqlsauce.DatabaseException; @@ -57,7 +61,7 @@ public static void mergeGuildPermissions(GuildPermissions guildPermissions) { private static void merge(IEntity entity) { EntityManager em = null; try { - em = FredBoat.getDbConnection().getEntityManager(); + em = FredBoat.getMainDbConnection().getEntityManager(); em.getTransaction().begin(); em.merge(entity); em.getTransaction().commit(); @@ -74,7 +78,7 @@ private static void merge(IEntity entity) { public static void deleteBlacklistEntry(long id) { EntityManager em = null; try { - em = FredBoat.getDbConnection().getEntityManager(); + em = FredBoat.getMainDbConnection().getEntityManager(); em.getTransaction().begin(); BlacklistEntry ble = em.find(BlacklistEntry.class, id); em.getTransaction().commit(); diff --git a/FredBoat/src/main/java/fredboat/db/entity/SearchResult.java b/FredBoat/src/main/java/fredboat/db/entity/cache/SearchResult.java similarity index 98% rename from FredBoat/src/main/java/fredboat/db/entity/SearchResult.java rename to FredBoat/src/main/java/fredboat/db/entity/cache/SearchResult.java index 3ee2ed660..972258572 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/SearchResult.java +++ b/FredBoat/src/main/java/fredboat/db/entity/cache/SearchResult.java @@ -23,7 +23,7 @@ * SOFTWARE. */ -package fredboat.db.entity; +package fredboat.db.entity.cache; import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager; import com.sedmelluq.discord.lavaplayer.tools.io.MessageInput; @@ -102,7 +102,7 @@ public static AudioPlaylist load(AudioPlayerManager playerManager, SearchUtil.Se SearchResult sr; SearchResultId sId = new SearchResultId(provider, searchTerm); try { - em = FredBoat.getDbConnection().getEntityManager(); + em = FredBoat.getCacheDbConnection().getEntityManager(); em.getTransaction().begin(); sr = em.find(SearchResult.class, sId); em.getTransaction().commit(); @@ -130,7 +130,7 @@ public static AudioPlaylist load(AudioPlayerManager playerManager, SearchUtil.Se public SearchResult save() { EntityManager em = null; try { - em = FredBoat.getDbConnection().getEntityManager(); + em = FredBoat.getCacheDbConnection().getEntityManager(); em.getTransaction().begin(); SearchResult managed = em.merge(this); em.getTransaction().commit(); diff --git a/FredBoat/src/main/java/fredboat/db/entity/BlacklistEntry.java b/FredBoat/src/main/java/fredboat/db/entity/main/BlacklistEntry.java similarity index 98% rename from FredBoat/src/main/java/fredboat/db/entity/BlacklistEntry.java rename to FredBoat/src/main/java/fredboat/db/entity/main/BlacklistEntry.java index 295fc2f83..908f51dcb 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/BlacklistEntry.java +++ b/FredBoat/src/main/java/fredboat/db/entity/main/BlacklistEntry.java @@ -1,4 +1,5 @@ /* + * * MIT License * * Copyright (c) 2017 Frederik Ar. Mikkelsen @@ -22,8 +23,9 @@ * SOFTWARE. */ -package fredboat.db.entity; +package fredboat.db.entity.main; +import fredboat.db.entity.IEntity; import org.hibernate.annotations.ColumnDefault; import javax.persistence.Column; diff --git a/FredBoat/src/main/java/fredboat/db/entity/GuildConfig.java b/FredBoat/src/main/java/fredboat/db/entity/main/GuildConfig.java similarity index 97% rename from FredBoat/src/main/java/fredboat/db/entity/GuildConfig.java rename to FredBoat/src/main/java/fredboat/db/entity/main/GuildConfig.java index da35272d0..dfc6a69bb 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/GuildConfig.java +++ b/FredBoat/src/main/java/fredboat/db/entity/main/GuildConfig.java @@ -23,10 +23,11 @@ * */ -package fredboat.db.entity; +package fredboat.db.entity.main; import fredboat.FredBoat; import fredboat.db.DatabaseNotReadyException; +import fredboat.db.entity.IEntity; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.slf4j.Logger; @@ -159,7 +160,7 @@ public static Optional getPrefix(long guildId) { String query = "SELECT gf.prefix FROM GuildConfig gf WHERE gf.guildId = :guildId"; EntityManager em = null; try { - em = FredBoat.getDbConnection().getEntityManager(); + em = FredBoat.getMainDbConnection().getEntityManager(); em.getTransaction().begin(); List result = em.createQuery(query, String.class) .setParameter("guildId", Long.toString(guildId)) diff --git a/FredBoat/src/main/java/fredboat/db/entity/GuildPermissions.java b/FredBoat/src/main/java/fredboat/db/entity/main/GuildPermissions.java similarity index 98% rename from FredBoat/src/main/java/fredboat/db/entity/GuildPermissions.java rename to FredBoat/src/main/java/fredboat/db/entity/main/GuildPermissions.java index 7336db097..c782dc3b6 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/GuildPermissions.java +++ b/FredBoat/src/main/java/fredboat/db/entity/main/GuildPermissions.java @@ -23,8 +23,9 @@ * */ -package fredboat.db.entity; +package fredboat.db.entity.main; +import fredboat.db.entity.IEntity; import fredboat.perms.PermissionLevel; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; diff --git a/FredBoat/src/main/java/fredboat/db/entity/UConfig.java b/FredBoat/src/main/java/fredboat/db/entity/main/UConfig.java similarity index 97% rename from FredBoat/src/main/java/fredboat/db/entity/UConfig.java rename to FredBoat/src/main/java/fredboat/db/entity/main/UConfig.java index 64282fac3..df11b13f6 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/UConfig.java +++ b/FredBoat/src/main/java/fredboat/db/entity/main/UConfig.java @@ -23,7 +23,9 @@ * */ -package fredboat.db.entity; +package fredboat.db.entity.main; + +import fredboat.db.entity.IEntity; import javax.persistence.Entity; import javax.persistence.Id; diff --git a/FredBoat/src/main/java/fredboat/feature/I18n.java b/FredBoat/src/main/java/fredboat/feature/I18n.java index 07d4bc5b5..76548dd3e 100644 --- a/FredBoat/src/main/java/fredboat/feature/I18n.java +++ b/FredBoat/src/main/java/fredboat/feature/I18n.java @@ -28,7 +28,7 @@ import fredboat.db.DatabaseNotReadyException; import fredboat.db.EntityReader; import fredboat.db.EntityWriter; -import fredboat.db.entity.GuildConfig; +import fredboat.db.entity.main.GuildConfig; import net.dv8tion.jda.core.entities.Guild; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java index d666c9d45..8b07b3146 100644 --- a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java +++ b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java @@ -28,7 +28,7 @@ import fredboat.Config; import fredboat.commandmeta.abs.CommandContext; import fredboat.db.EntityReader; -import fredboat.db.entity.GuildPermissions; +import fredboat.db.entity.main.GuildPermissions; import fredboat.feature.togglz.FeatureFlags; import fredboat.util.DiscordUtil; import net.dv8tion.jda.core.Permission; diff --git a/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java b/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java index 812788975..377dbaae0 100644 --- a/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java +++ b/FredBoat/src/main/java/fredboat/util/ratelimit/Blacklist.java @@ -26,7 +26,7 @@ import fredboat.db.EntityReader; import fredboat.db.EntityWriter; -import fredboat.db.entity.BlacklistEntry; +import fredboat.db.entity.main.BlacklistEntry; import fredboat.feature.metrics.Metrics; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; diff --git a/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java b/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java index 2aafd47f0..347fac3f4 100644 --- a/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java +++ b/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java @@ -37,7 +37,7 @@ import fredboat.Config; import fredboat.FredBoat; import fredboat.db.DatabaseNotReadyException; -import fredboat.db.entity.SearchResult; +import fredboat.db.entity.cache.SearchResult; import fredboat.feature.metrics.Metrics; import fredboat.feature.togglz.FeatureFlags; import org.apache.http.client.config.CookieSpecs; @@ -86,7 +86,7 @@ public static AudioPlaylist searchForTracks(String query, List p /** * @param query The search term - * @param cacheMaxAge Age of acceptable results from cache. See {@link fredboat.db.entity.SearchResult#load} for details. + * @param cacheMaxAge Age of acceptable results from cache. See {@link SearchResult#load} for details. * @param timeoutMillis How long to wait for each lavaplayer search to answer * @param providers Providers that shall be used for the search. They will be used in the order they are provided, the * result of the first successful one will be returned diff --git a/FredBoat/src/main/resources/ehcache_cache.xml b/FredBoat/src/main/resources/ehcache_cache.xml new file mode 100644 index 000000000..50f7ea5e9 --- /dev/null +++ b/FredBoat/src/main/resources/ehcache_cache.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FredBoat/src/main/resources/ehcache.xml b/FredBoat/src/main/resources/ehcache_main.xml similarity index 91% rename from FredBoat/src/main/resources/ehcache.xml rename to FredBoat/src/main/resources/ehcache_main.xml index f9b8a22f8..529cec9ed 100644 --- a/FredBoat/src/main/resources/ehcache.xml +++ b/FredBoat/src/main/resources/ehcache_main.xml @@ -26,7 +26,7 @@ + monitoring="autodetect" dynamicConfig="true" name="MAIN_CACHEMANAGER"> @@ -57,13 +57,6 @@ - - - - - - - - - - - true - true - /ehcache.xml - org.hibernate.cache.ehcache.EhCacheRegionFactory - - \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 0c7702c8d..948fd2acd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,7 @@ services: ################################################################################ db: image: fredboat/postgres - restart: on-failure:3 + restart: always # WINDOWS ONLY: if you are running under windows you need to comment out the following two lines: volumes: From ea9a091a46abe376972e45c63c8e402d911b8808 Mon Sep 17 00:00:00 2001 From: Napster Date: Tue, 19 Dec 2017 22:47:29 +0100 Subject: [PATCH 37/62] Log exceptions before shutting down --- FredBoat/src/main/java/fredboat/FredBoat.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index 4c1895b36..4e8587c0a 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -136,6 +136,7 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc try { mainDbConn = DatabaseManager.main(); } catch (Exception e) { + log.error("Exception when connecting to main db", e); shutdown(ExitCodes.EXIT_CODE_ERROR); } //attempt to connect to the database a few times @@ -159,6 +160,7 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc try { cacheDbConn = DatabaseManager.cache(); } catch (Exception e) { + log.error("Exception when connecting to cache db", e); shutdown(ExitCodes.EXIT_CODE_ERROR); } Metrics.instance().hibernateStats.register(); //call this exactly once after all db connections have been created From c9d5e160c804860f680b017ced28d51bb8d91e0f Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 20 Dec 2017 01:18:04 +0100 Subject: [PATCH 38/62] Add threadpool queue size metric --- .../feature/metrics/collectors/ThreadPoolCollector.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FredBoat/src/main/java/fredboat/feature/metrics/collectors/ThreadPoolCollector.java b/FredBoat/src/main/java/fredboat/feature/metrics/collectors/ThreadPoolCollector.java index 8ed9199dc..ca6b2691c 100644 --- a/FredBoat/src/main/java/fredboat/feature/metrics/collectors/ThreadPoolCollector.java +++ b/FredBoat/src/main/java/fredboat/feature/metrics/collectors/ThreadPoolCollector.java @@ -87,6 +87,10 @@ public List collect() { "Amount of active threads in a thread pool", labelNames); mfs.add(activeThreads); + GaugeMetricFamily queueSize = new GaugeMetricFamily("fredboat_threadpool_queue_size_current", + "Size of queue of a thread pool (including scheduled tasks)", labelNames); + mfs.add(queueSize); + CounterMetricFamily completedTasks = new CounterMetricFamily("fredboat_threadpool_completed_tasks_total", "Total completed tasks by a thread pool", labelNames); mfs.add(completedTasks); @@ -97,6 +101,7 @@ public List collect() { List labels = Collections.singletonList(poolName); activeThreads.addMetric(labels, pool.getActiveCount()); + queueSize.addMetric(labels, pool.getQueue().size()); completedTasks.addMetric(labels, pool.getCompletedTaskCount()); //guaranteed to always increase, ergo good fit for a counter } From f3f99e528ae963088d8e30f376ef609037f7c893 Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 20 Dec 2017 10:14:17 +0100 Subject: [PATCH 39/62] Clarify docs for cache db --- FredBoat/credentials.yaml.example | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/FredBoat/credentials.yaml.example b/FredBoat/credentials.yaml.example index d51f62959..d9699cfe0 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/credentials.yaml.example @@ -103,10 +103,11 @@ sshKeyPassphrase: "" # optional passphrase for the ssh key file tunnelLocalPort: 5432 # endpoint port of the tunnel on the machine running fredboat; makes sure these dont collide; this one needs to be used in the jdbc url tunnelRemotePort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default -# Database for caching things, see config of main database above for details. -# You only need this if you want to have these in two different places (which we recommend, can be two databases in a single postgres database) +# Database for caching things, see config of main database above for details about the individual values. +# You only need to configure this if you want to have these in two different places (can be two databases in a single postgres). +# By default (= if not configured) the cache database will use the same jdbc url as the main database. # The main benefit is that you don't have to backup/migrate the cache database, it can just be dropped/recreated -# If you are going to use a ssh tunnels for both database connections, make sure the local tunnel ports don't collide +# If you are going to use ssh tunnels for both database connections, make sure that the local tunnel ports don't collide cacheJdbcUrl: "" cacheUseSshTunnel: false cacheSshHost: "" From 08c39bd14ea87f6fd9da770d30b723f52925786b Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 20 Dec 2017 17:35:20 +0100 Subject: [PATCH 40/62] Omit command trigger from select if its not numeric (#420) * Omit command trigger from select if its not numeric * Adjust TextUtilsTest tests The trigger is only included if it's numeric, so this updates it to reflect real usage, in case tweaks and adjustments need to happen. --- .../java/fredboat/command/music/control/SelectCommand.java | 7 +++++-- FredBoat/src/test/java/fredboat/util/TextUtilsTest.java | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java b/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java index d696da9b5..c9859637c 100644 --- a/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java +++ b/FredBoat/src/main/java/fredboat/command/music/control/SelectCommand.java @@ -73,8 +73,11 @@ static void select(CommandContext context) { // LinkedHashSet to handle order of choices + duplicates LinkedHashSet requestChoices = new LinkedHashSet<>(); - // Combine all args and the command trigger. if the trigger is not a number it will be sanitized away - String commandOptions = (context.trigger + " " + context.rawArgs).trim(); + // Combine all args and the command trigger if it is numeric + String commandOptions = context.rawArgs; + if (StringUtils.isNumeric(context.trigger)) { + commandOptions = (context.trigger + " " + commandOptions).trim(); + } if (StringUtils.isNumeric(commandOptions)) { requestChoices.add(Integer.valueOf(commandOptions)); diff --git a/FredBoat/src/test/java/fredboat/util/TextUtilsTest.java b/FredBoat/src/test/java/fredboat/util/TextUtilsTest.java index d4569c9d3..3b4b1f78f 100644 --- a/FredBoat/src/test/java/fredboat/util/TextUtilsTest.java +++ b/FredBoat/src/test/java/fredboat/util/TextUtilsTest.java @@ -37,13 +37,13 @@ Stream nonDigitsInSplitSelect() { return Stream.concat( DynamicTest.stream(Arrays.asList( "1q 2 3", - "play 1q 2 3" + "1q 2what 3" ).iterator(), testCase -> String.format("split select of `%s`", testCase), testCase -> assertSplitSelect(one_two_three, testCase)), DynamicTest.stream(Arrays.asList( - "play q", + "q", "We are number 1 but this string doesn't match", "1, 2, 3, 4, 5 Once we caught a fish alive" ).iterator(), From a6a5542a5976dbf93a1b305ea08b98299b0fcce5 Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 20 Dec 2017 19:26:51 +0100 Subject: [PATCH 41/62] Post close codes with event logs; remove summaries, always full logs --- .../main/java/fredboat/event/EventLogger.java | 122 +++++------------- 1 file changed, 34 insertions(+), 88 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/event/EventLogger.java b/FredBoat/src/main/java/fredboat/event/EventLogger.java index ecba58176..e4fea736d 100644 --- a/FredBoat/src/main/java/fredboat/event/EventLogger.java +++ b/FredBoat/src/main/java/fredboat/event/EventLogger.java @@ -29,14 +29,9 @@ import fredboat.messaging.CentralMessaging; import fredboat.util.Emojis; import fredboat.util.TextUtils; -import net.dv8tion.jda.core.MessageBuilder; import net.dv8tion.jda.core.entities.Message; import net.dv8tion.jda.core.entities.MessageEmbed; -import net.dv8tion.jda.core.events.DisconnectEvent; -import net.dv8tion.jda.core.events.ReadyEvent; -import net.dv8tion.jda.core.events.ReconnectedEvent; -import net.dv8tion.jda.core.events.ResumedEvent; -import net.dv8tion.jda.core.events.ShutdownEvent; +import net.dv8tion.jda.core.events.*; import net.dv8tion.jda.core.events.guild.GuildJoinEvent; import net.dv8tion.jda.core.events.guild.GuildLeaveEvent; import net.dv8tion.jda.core.hooks.ListenerAdapter; @@ -45,19 +40,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; /** * This overengineered class logs some events via a webhook into Discord. @@ -96,27 +87,34 @@ public EventLogger(String eventLogWebhookUrl) { @Override public void onReady(ReadyEvent event) { - statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), ShardStatusEvent.StatusEvent.READY)); + statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), + ShardStatusEvent.StatusEvent.READY, "")); } @Override public void onResume(ResumedEvent event) { - statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), ShardStatusEvent.StatusEvent.RESUME)); + statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), + ShardStatusEvent.StatusEvent.RESUME, "")); } @Override public void onReconnect(ReconnectedEvent event) { - statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), ShardStatusEvent.StatusEvent.RECONNECT)); + statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), + ShardStatusEvent.StatusEvent.RECONNECT, "")); } @Override public void onDisconnect(DisconnectEvent event) { - statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), ShardStatusEvent.StatusEvent.DISCONNECT)); + String closeCodeStr = "close code " + (event.getCloseCode() == null ? "null" : event.getCloseCode().getCode()); + statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), + ShardStatusEvent.StatusEvent.DISCONNECT, "with " + closeCodeStr)); } @Override public void onShutdown(ShutdownEvent event) { - statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), ShardStatusEvent.StatusEvent.SHUTDOWN)); + String closeCodeStr = "close code " + (event.getCloseCode() == null ? "null" : event.getCloseCode().getCode()); + statusStats.add(new ShardStatusEvent(event.getJDA().getShardInfo().getShardId(), + ShardStatusEvent.StatusEvent.SHUTDOWN, "with " + closeCodeStr)); } @Override @@ -202,78 +200,21 @@ private void sendShardStatusSummary() { return;//nothing to report } - //~35 lines fit into a 2k char message, if we can get away with a max of 5 messages, post those, otherwise post a summary - if (events.size() <= 35 * 5) { - List sublist = new ArrayList<>(); - for (int i = 0; i < events.size(); i++) { - sublist.add(events.get(i)); - if (i != 0 && (i % 35 == 0 || i == events.size() - 1)) { - addMessageToWebhookQueue(CentralMessaging.getClearThreadLocalMessageBuilder() - .appendCodeBlock(String.join("\n", sublist.stream().map(ShardStatusEvent::toString).collect(Collectors.toList())), - "diff") - .build()); - sublist.clear(); - } - } - drainMessageQueue(); - return; - } - - //too many events in a short time. sum them up - List readied = new ArrayList<>(); - List resumed = new ArrayList<>(); - List reconnected = new ArrayList<>(); - List disconnected = new ArrayList<>(); - List shutdown = new ArrayList<>(); - + //split into messages of acceptable size (2k chars max) + StringBuilder msg = new StringBuilder(); for (ShardStatusEvent event : events) { - switch (event.event) { - case READY: - readied.add(event.shardId); - break; - case RESUME: - resumed.add(event.shardId); - break; - case RECONNECT: - reconnected.add(event.shardId); - break; - case DISCONNECT: - disconnected.add(event.shardId); - break; - case SHUTDOWN: - shutdown.add(event.shardId); - break; - default: - log.error("Unexpected status event type: {}", event.event.name()); + String eventStr = event.toString(); + if (msg.length() + eventStr.length() > 1900) { + addMessageToWebhookQueue(CentralMessaging.getClearThreadLocalMessageBuilder() + .appendCodeBlock(msg.toString(), "diff").build()); + msg = new StringBuilder(); } + msg.append("\n").append(eventStr); } - - String output = TextUtils.getTimeInCentralEurope() + " **Shard Events Summary:**\n"; - if (!readied.isEmpty()) { - String shards = String.join(", ", readied.stream().map(i -> Integer.toString(i)).collect(Collectors.toList())); - output += TextUtils.asCodeBlock("+ " + readied.size() + " shard ready events:\n+ " + shards, "diff") + "\n"; + if (msg.length() > 0) {//any leftovers? + addMessageToWebhookQueue(CentralMessaging.getClearThreadLocalMessageBuilder() + .appendCodeBlock(msg.toString(), "diff").build()); } - if (!resumed.isEmpty()) { - String shards = String.join(", ", resumed.stream().map(i -> Integer.toString(i)).collect(Collectors.toList())); - output += TextUtils.asCodeBlock("+ " + resumed.size() + " shard resume events:\n+ " + shards, "diff") + "\n"; - } - if (!reconnected.isEmpty()) { - String shards = String.join(", ", reconnected.stream().map(i -> Integer.toString(i)).collect(Collectors.toList())); - output += TextUtils.asCodeBlock("+" + reconnected.size() + " shard reconnect events:\n+ " + shards, "diff") + "\n"; - } - if (!disconnected.isEmpty()) { - String shards = String.join(", ", disconnected.stream().map(i -> Integer.toString(i)).collect(Collectors.toList())); - output += TextUtils.asCodeBlock("-" + disconnected.size() + " shard disconnect events:\n- " + shards, "diff") + "\n"; - } - if (!shutdown.isEmpty()) { - String shards = String.join(", ", shutdown.stream().map(i -> Integer.toString(i)).collect(Collectors.toList())); - output += TextUtils.asCodeBlock("- " + shutdown.size() + " shard shutdown events:\n- " + shards, "diff") + "\n"; - } - - CentralMessaging.getClearThreadLocalMessageBuilder() - .append(output) - .buildAll(MessageBuilder.SplitPolicy.NEWLINE) - .forEach(this::addMessageToWebhookQueue); drainMessageQueue(); } @@ -302,12 +243,16 @@ private void addMessageToWebhookQueue(Message message) { private static class ShardStatusEvent { final int shardId; + @Nonnull final StatusEvent event; + @Nonnull + final String additionalInfo; final long timestamp; - private ShardStatusEvent(int shardId, StatusEvent event) { + private ShardStatusEvent(int shardId, @Nonnull StatusEvent event, @Nonnull String additionalInfo) { this.shardId = shardId; this.event = event; + this.additionalInfo = additionalInfo; this.timestamp = System.currentTimeMillis(); } @@ -329,8 +274,9 @@ enum StatusEvent { @Override public String toString() { - return String.format("%s [%s] Shard %s %s", //NOTE when changing this, make sure the max message size is still respected in those place using this method - event.diff, TextUtils.asTimeInCentralEurope(timestamp), TextUtils.forceNDigits(shardId, 3), event.str); + return String.format("%s [%s] Shard %s %s %s", + event.diff, TextUtils.asTimeInCentralEurope(timestamp), + TextUtils.forceNDigits(shardId, 3), event.str, additionalInfo); } @Override From ae972ced0eea0d3f9494edf1204e2d79800be31a Mon Sep 17 00:00:00 2001 From: Napster Date: Wed, 20 Dec 2017 21:04:01 +0100 Subject: [PATCH 42/62] Split shard events from guild stats in the event logger; Resolves #409 --- FredBoat/credentials.yaml.example | 7 +- FredBoat/src/main/java/fredboat/Config.java | 20 +++ .../src/main/java/fredboat/FredBoatShard.java | 2 +- .../main/java/fredboat/event/EventLogger.java | 139 +++++++++++------- 4 files changed, 109 insertions(+), 59 deletions(-) diff --git a/FredBoat/credentials.yaml.example b/FredBoat/credentials.yaml.example index 578696892..5d135047a 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/credentials.yaml.example @@ -122,10 +122,13 @@ sentryDsn: "" #"ws://lavalink.example.com:5557": "youshallnotpass" -# Webhook to a Discord channel that will post some guild stats and shard status changes +# Webhooks to Discord channels that will post some guild stats and shard status changes # More information on webhooks: https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks # Example: "https://canary.discordapp.com/api/webhooks/1234567890/QWERTZUIOPasdfghjklYXCVBNM" (no, this one will not work) -eventLogWebhook: "" +eventLogWebhook: "" # webhook url for connect / disconnect events +eventLogInterval: 1 # interval at which connect / disconnect events are posted in minutes +guildStatsWebhook: "" # webhook url for guild stats +guildStatsInterval: 60 # interval at which guild stats are posted in minutes # Post build tool test results into a discord channel. The token must be a discord bot token. diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java index 11444376b..25d7f4968 100644 --- a/FredBoat/src/main/java/fredboat/Config.java +++ b/FredBoat/src/main/java/fredboat/Config.java @@ -118,6 +118,9 @@ public class Config { private String sentryDsn; private List lavalinkHosts = new ArrayList<>(); private String eventLogWebhook; + private int eventLogInterval; + private String guildStatsWebhook; + private int guildStatsInterval; private String testBotToken; private String testChannelId; @@ -251,6 +254,9 @@ public Config(File credentialsFile, File configFile) { } eventLogWebhook = (String) creds.getOrDefault("eventLogWebhook", ""); + eventLogInterval = (int) creds.getOrDefault("eventLogInterval", 1); //minutes + guildStatsWebhook = (String) creds.getOrDefault("guildStatsWebhook", ""); + guildStatsInterval = (int) creds.getOrDefault("guildStatsInterval", 60); //minutes testBotToken = (String) creds.getOrDefault("testToken", ""); testChannelId = creds.getOrDefault("testChannelId", "") + ""; @@ -494,6 +500,20 @@ public String getEventLogWebhook() { return eventLogWebhook; } + //minutes + public int getEventLogInterval() { + return eventLogInterval; + } + + public String getGuildStatsWebhook() { + return guildStatsWebhook; + } + + //minutes + public int getGuildStatsInterval() { + return guildStatsInterval; + } + public String getTestBotToken() { return testBotToken; } diff --git a/FredBoat/src/main/java/fredboat/FredBoatShard.java b/FredBoat/src/main/java/fredboat/FredBoatShard.java index 857206e68..93ac1be6e 100644 --- a/FredBoat/src/main/java/fredboat/FredBoatShard.java +++ b/FredBoat/src/main/java/fredboat/FredBoatShard.java @@ -298,7 +298,7 @@ protected synchronized static JDABuilder getDefaultShardBuilder(@Nonnull EventLi String eventLogWebhook = Config.CONFIG.getEventLogWebhook(); if (eventLogWebhook != null && !eventLogWebhook.isEmpty()) { try { - builder.addEventListener(new EventLogger(Config.CONFIG.getEventLogWebhook())); + builder.addEventListener(new EventLogger()); } catch (Exception e) { log.error("Failed to create Eventlogger, events will not be logged to discord via webhook", e); } diff --git a/FredBoat/src/main/java/fredboat/event/EventLogger.java b/FredBoat/src/main/java/fredboat/event/EventLogger.java index e4fea736d..44ab3bb81 100644 --- a/FredBoat/src/main/java/fredboat/event/EventLogger.java +++ b/FredBoat/src/main/java/fredboat/event/EventLogger.java @@ -25,12 +25,14 @@ package fredboat.event; +import fredboat.Config; import fredboat.FredBoat; import fredboat.messaging.CentralMessaging; import fredboat.util.Emojis; import fredboat.util.TextUtils; +import net.dv8tion.jda.core.EmbedBuilder; import net.dv8tion.jda.core.entities.Message; -import net.dv8tion.jda.core.entities.MessageEmbed; +import net.dv8tion.jda.core.entities.User; import net.dv8tion.jda.core.events.*; import net.dv8tion.jda.core.events.guild.GuildJoinEvent; import net.dv8tion.jda.core.events.guild.GuildLeaveEvent; @@ -62,26 +64,24 @@ public class EventLogger extends ListenerAdapter { public static final Logger log = LoggerFactory.getLogger(EventLogger.class); - private final static int MAX_MESSAGE_QUEUE_SIZE = 30; - private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( runnable -> new Thread(runnable, "eventlogger")); @Nullable - private WebhookClient eventLoggerWebhook; + private WebhookClient eventLogWebhook; + @Nullable + private WebhookClient guildStatsWebhook; //saves some messages, so that in case we run into occasional connection issues we dont just drop them due to the webhook timing out - private final Queue toBeSent = new ConcurrentLinkedQueue<>(); + private final Queue toBeSentEventLog = new ConcurrentLinkedQueue<>(); + private final Queue toBeSentGuildStats = new ConcurrentLinkedQueue<>(); private final List statusStats = new CopyOnWriteArrayList<>(); private final AtomicInteger guildsJoinedEvents = new AtomicInteger(0); private final AtomicInteger guildsLeftEvents = new AtomicInteger(0); - public EventLogger(long id, String token) { - this(new WebhookClientBuilder(id, token).build()); - } - - public EventLogger(String eventLogWebhookUrl) { - this(new WebhookClientBuilder(eventLogWebhookUrl).build()); + public EventLogger() { + this(new WebhookClientBuilder(Config.CONFIG.getEventLogWebhook()).build(), + new WebhookClientBuilder(Config.CONFIG.getGuildStatsWebhook()).build()); } @@ -137,20 +137,26 @@ public void onGuildLeave(GuildLeaveEvent event) { message = Emojis.DOOR + "Exiting with unknown code."; } log.info(message); - if (eventLoggerWebhook != null) { - eventLoggerWebhook.send(message); + Future elw = null; + Future gsw = null; + if (eventLogWebhook != null) elw = eventLogWebhook.send(message); + if (guildStatsWebhook != null) gsw = guildStatsWebhook.send(message); + try { + if (elw != null) elw.get(); + if (gsw != null) gsw.get(); + } catch (ExecutionException | InterruptedException ignored) { } }; //actual constructor - private EventLogger(WebhookClient eventLoggerWebhook) { + private EventLogger(@Nonnull WebhookClient eventLoggerWebhook, @Nonnull WebhookClient guildStatsWebhook) { Runtime.getRuntime().addShutdownHook(new Thread(ON_SHUTDOWN, EventLogger.class.getSimpleName() + " shutdownhook")); - //test the provided webhook before assigning it, otherwise it will spam our logs with exceptions + //test the provided webhooks before assigning them, otherwise they will spam our logs with exceptions WebhookClient workingWebhook = null; if (eventLoggerWebhook.getIdLong() > 0) { //id is 0 when there is no webhookid configured in the config; skip this in that case try { - eventLoggerWebhook.send(Emojis.PENCIL + "Eventlogger started.") + eventLoggerWebhook.send(Emojis.PENCIL + "Event logger started.") .get(); workingWebhook = eventLoggerWebhook; //webhook test was successful; FIXME occasionally this might fail during the start due to connection issues, while the provided values are actually valid } catch (Exception e) { @@ -160,39 +166,70 @@ private EventLogger(WebhookClient eventLoggerWebhook) { } else { eventLoggerWebhook.close(); } + this.eventLogWebhook = workingWebhook; + + if (eventLogWebhook != null) { + scheduler.scheduleAtFixedRate(() -> { + try { + sendEventLogs(); + } catch (Exception e) { + log.error("Failed to send shard status summary to event log webhook", e); + } + }, 0, Math.max(Config.CONFIG.getEventLogInterval(), 1), TimeUnit.MINUTES); + } - this.eventLoggerWebhook = workingWebhook; - - scheduler.scheduleAtFixedRate(() -> { - try { - sendShardStatusSummary(); - } catch (Exception e) { - log.error("Failed to send shard status summary to event log webhook", e); - } - }, 0, 1, TimeUnit.MINUTES); - - scheduler.scheduleAtFixedRate(() -> { + workingWebhook = null; + if (guildStatsWebhook.getIdLong() > 0) { //id is 0 when there is no webhookid configured in the config; skip this in that case try { - sendGuildsSummary(); + guildStatsWebhook.send(Emojis.PENCIL + "Guild stats logger started.") + .get(); + workingWebhook = guildStatsWebhook; //webhook test was successful; FIXME occasionally this might fail during the start due to connection issues, while the provided values are actually valid } catch (Exception e) { - log.error("Failed to send guilds summary to event log webhook", e); + log.error("Failed to create guild stats webhook. Guild stats will not be available. Doublecheck your configuration values."); + guildStatsWebhook.close(); } - }, 0, 1, TimeUnit.HOURS); + } else { + guildStatsWebhook.close(); + } + this.guildStatsWebhook = workingWebhook; + + int interval = Math.max(Config.CONFIG.getGuildStatsInterval(), 1); + if (this.guildStatsWebhook != null) { + scheduler.scheduleAtFixedRate(() -> { + try { + sendGuildStats(); + } catch (Exception e) { + log.error("Failed to send guilds summary to guild stats webhook", e); + } + }, interval, interval, TimeUnit.MINUTES); + } } - private void sendGuildsSummary() { - MessageEmbed embed = CentralMessaging.getColoredEmbedBuilder() + private void sendGuildStats() { + if (guildStatsWebhook == null) { + return; + } + + EmbedBuilder eb = CentralMessaging.getColoredEmbedBuilder() .setTimestamp(LocalDateTime.now()) .setTitle("Joins and Leaves since the last update") .addField("Guilds joined", Integer.toString(guildsJoinedEvents.getAndSet(0)), true) - .addField("Guilds left", Integer.toString(guildsLeftEvents.getAndSet(0)), true) - .build(); + .addField("Guilds left", Integer.toString(guildsLeftEvents.getAndSet(0)), true); - addMessageToWebhookQueue(CentralMessaging.getClearThreadLocalMessageBuilder().setEmbed(embed).build()); - drainMessageQueue(); + if (!FredBoat.getShards().isEmpty()) { + FredBoat anyShard = FredBoat.getShards().get(0); + User self = anyShard.getJda().getSelfUser(); + eb.setFooter(self.getName(), self.getEffectiveAvatarUrl()); + } + + toBeSentGuildStats.add(CentralMessaging.from(eb.build())); + drainMessageQueue(toBeSentGuildStats, guildStatsWebhook); } - private void sendShardStatusSummary() { + private void sendEventLogs() { + if (eventLogWebhook == null) { + return; + } List events = new ArrayList<>(statusStats); statusStats.removeAll(events); @@ -205,39 +242,29 @@ private void sendShardStatusSummary() { for (ShardStatusEvent event : events) { String eventStr = event.toString(); if (msg.length() + eventStr.length() > 1900) { - addMessageToWebhookQueue(CentralMessaging.getClearThreadLocalMessageBuilder() + toBeSentEventLog.add(CentralMessaging.getClearThreadLocalMessageBuilder() .appendCodeBlock(msg.toString(), "diff").build()); msg = new StringBuilder(); } msg.append("\n").append(eventStr); } if (msg.length() > 0) {//any leftovers? - addMessageToWebhookQueue(CentralMessaging.getClearThreadLocalMessageBuilder() + toBeSentEventLog.add(CentralMessaging.getClearThreadLocalMessageBuilder() .appendCodeBlock(msg.toString(), "diff").build()); } - drainMessageQueue(); + drainMessageQueue(toBeSentEventLog, eventLogWebhook); } - private synchronized void drainMessageQueue() { - if (eventLoggerWebhook == null) { - return; - } + private static void drainMessageQueue(@Nonnull Queue queue, @Nonnull WebhookClient webhook) { try { - while (!toBeSent.isEmpty()) { - Message message = toBeSent.peek(); - eventLoggerWebhook.send(message).get(); - toBeSent.poll(); + while (!queue.isEmpty()) { + Message message = queue.peek(); + webhook.send(message).get(); + queue.poll(); } } catch (Exception e) { - log.warn("Event log webhook failed to send a message. Will try again later.", e); - } - } - - private void addMessageToWebhookQueue(Message message) { - while (toBeSent.size() > MAX_MESSAGE_QUEUE_SIZE) { - toBeSent.poll(); //drop messages above max size + log.warn("Webhook failed to send a message. Will try again next time.", e); } - toBeSent.add(message); } private static class ShardStatusEvent { From 9e51b005ecffd031b6f678ed5d2397f5e327e517 Mon Sep 17 00:00:00 2001 From: "Frederik Ar. Mikkelsen" Date: Thu, 21 Dec 2017 14:31:08 +0100 Subject: [PATCH 43/62] Remove dependency status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b15fb56c..484a83176 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![FredBoat](https://fred.moe/YY1.png) -# FredBoat [![Build Status](https://travis-ci.org/Frederikam/FredBoat.svg?branch=master)](https://travis-ci.org/Frederikam/FredBoat) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/fredboat/localized.svg)](https://crowdin.com/project/fredboat) [![Twitter Follow](https://img.shields.io/twitter/follow/DiscordFredBoat.svg?style=social&label=Follow)]() [![Dependency Status](https://www.versioneye.com/user/projects/5a238bc60fb24f793c0be65b/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/5a238bc60fb24f793c0be65b) +# FredBoat [![Build Status](https://travis-ci.org/Frederikam/FredBoat.svg?branch=master)](https://travis-ci.org/Frederikam/FredBoat) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/fredboat/localized.svg)](https://crowdin.com/project/fredboat) [![Twitter Follow](https://img.shields.io/twitter/follow/DiscordFredBoat.svg?style=social&label=Follow)]() FredBoat is a bot that has various features, but most notably is that it can play music. Pull requests are welcome and please report any issues you find in [issues](https://github.com/Frederikam/FredBoat/issues). FredBoat is licensed under the MIT license, so feel free to copy small or large parts of the code here without having to ask. I would love to see what you can create with it! From 1f489a8c396000f9d7586e5f46422a591a9213b1 Mon Sep 17 00:00:00 2001 From: "Frederik Ar. Mikkelsen" Date: Thu, 21 Dec 2017 15:26:37 +0100 Subject: [PATCH 44/62] Create dbl.html --- Branding/html/dbl.html | 169 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 Branding/html/dbl.html diff --git a/Branding/html/dbl.html b/Branding/html/dbl.html new file mode 100644 index 000000000..387a2434b --- /dev/null +++ b/Branding/html/dbl.html @@ -0,0 +1,169 @@ + +

+

Meet FredBoat♪♪

+
+ +
+
+
+

FredBoat♪♪ is one of the most popular music bots around.

+

Features:

+
+
    +
  • Online 24/7
  • +
  • No setup required
  • +
  • Plays music
  • +
  • Minimum loss of quality
  • +
  • Search YouTube from the chat
  • +
  • Skip, pause, unpause and stop
  • +
  • Shuffle and repeat
  • +
  • Forwarding, rewinding and seeking
  • +
  • Persistent playlist
  • +
  • Constant updates
  • +
+
+ +

With support for:

+
+
    +
  • Playlists
  • +
  • YouTube
  • +
  • Soundcloud
  • +
  • Bandcamp
  • +
  • Twitch
  • +
  • Beam.pro
  • +
  • Vimeo
  • +
+
+
+ + +
+ +

What are you waiting for?

+ +
+ + + + +
From 3083b37ca51658de0096dec8b604c90ae4e36904 Mon Sep 17 00:00:00 2001 From: "Frederik Ar. Mikkelsen" Date: Thu, 21 Dec 2017 16:29:10 +0100 Subject: [PATCH 45/62] Update lavalink, fixes #403 --- FredBoat/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 68f72c48e..a40e99faa 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -39,7 +39,7 @@ dependencies { compile(group: 'lavalink', name: 'Lavalink-Client', version: '-SNAPSHOT') } else { //production - compile(group: 'com.github.Frederikam.Lavalink', name: 'Lavalink-Client', version: '3b25a66378d985b585d2b059d97935a2780b93c1') + compile(group: 'com.github.Frederikam.Lavalink', name: 'Lavalink-Client', version: '8fa6dd5d5013cbb2eb0d35be077048022f08c0eb') } compile group: 'org.apache.commons', name: 'commons-text', version: '1.1' From 597c588db5db95ba34847af6c5f5a63c2c752948 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 02:09:07 +0100 Subject: [PATCH 46/62] Properly retry establishing db connection before exiting --- FredBoat/src/main/java/fredboat/FredBoat.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index 4e8587c0a..258e6681f 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -133,17 +133,11 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc log.info("Failed to ignite Spark, FredBoat API unavailable", e); } - try { - mainDbConn = DatabaseManager.main(); - } catch (Exception e) { - log.error("Exception when connecting to main db", e); - shutdown(ExitCodes.EXIT_CODE_ERROR); - } //attempt to connect to the database a few times // this is relevant in a dockerized environment because after a reboot there is no guarantee that the db // container will be started before the fredboat one int dbConnectionAttempts = 0; - while (!mainDbConn.isAvailable() && dbConnectionAttempts++ < 10) { + while ((mainDbConn == null || !mainDbConn.isAvailable()) && dbConnectionAttempts++ < 10) { try { mainDbConn = DatabaseManager.main(); } catch (Exception e) { @@ -151,7 +145,7 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc Thread.sleep(5000); } } - if (!mainDbConn.isAvailable()) { + if (mainDbConn == null || !mainDbConn.isAvailable()) { log.error("Could not establish database connection. Exiting..."); shutdown(ExitCodes.EXIT_CODE_ERROR); } From 71302f9d15cca83c5590b12d1882c11f8752bbb1 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 02:10:44 +0100 Subject: [PATCH 47/62] Use distinct disk places for ehcache managers --- FredBoat/src/main/resources/ehcache_cache.xml | 2 +- FredBoat/src/main/resources/ehcache_main.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FredBoat/src/main/resources/ehcache_cache.xml b/FredBoat/src/main/resources/ehcache_cache.xml index 50f7ea5e9..b71010032 100644 --- a/FredBoat/src/main/resources/ehcache_cache.xml +++ b/FredBoat/src/main/resources/ehcache_cache.xml @@ -28,7 +28,7 @@ xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true" name="CACHE_CACHEMANAGER"> - + - + Date: Sat, 23 Dec 2017 14:32:33 +0100 Subject: [PATCH 48/62] Fix User Agent Related: https://github.com/DV8FromTheWorld/JDA/issues/441 https://discordapp.com/developers/docs/reference#user-agent --- FredBoat/src/main/java/fredboat/util/DiscordUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/util/DiscordUtil.java b/FredBoat/src/main/java/fredboat/util/DiscordUtil.java index 54790c356..836533fc5 100644 --- a/FredBoat/src/main/java/fredboat/util/DiscordUtil.java +++ b/FredBoat/src/main/java/fredboat/util/DiscordUtil.java @@ -53,7 +53,8 @@ public class DiscordUtil { private static final Logger log = LoggerFactory.getLogger(DiscordUtil.class); - private static final String USER_AGENT = "FredBoat DiscordBot (https://github.com/Frederikam/FredBoat, 1.0)"; + private static final String USER_AGENT = String.format("DiscordBot (https://github.com/Frederikam/FredBoat, %s)", + AppInfo.getAppInfo().getVersionBuild()); private static volatile DiscordAppInfo selfDiscordAppInfo; //access this object through getApplicationInfo(jda) private static final Object selfDiscordAppInfoLock = new Object(); From a7d66a833eff98741e844de10fdfe97de3db1391 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 14:37:03 +0100 Subject: [PATCH 49/62] Cache bot id retrieval --- .../audio/player/LavalinkManager.java | 4 +-- .../main/java/fredboat/util/DiscordUtil.java | 33 ++++++++++++++++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/audio/player/LavalinkManager.java b/FredBoat/src/main/java/fredboat/audio/player/LavalinkManager.java index 23a49ff8f..e312a2b53 100644 --- a/FredBoat/src/main/java/fredboat/audio/player/LavalinkManager.java +++ b/FredBoat/src/main/java/fredboat/audio/player/LavalinkManager.java @@ -49,10 +49,8 @@ private LavalinkManager() { public void start() { if (!isEnabled()) return; - String userId = DiscordUtil.getUserId(Config.CONFIG.getBotToken()); - lavalink = new Lavalink( - userId, + Long.toString(DiscordUtil.getBotId()), Config.getNumShards(), shardId -> FredBoat.getShard(shardId).getJda() ); diff --git a/FredBoat/src/main/java/fredboat/util/DiscordUtil.java b/FredBoat/src/main/java/fredboat/util/DiscordUtil.java index 836533fc5..1c85e3714 100644 --- a/FredBoat/src/main/java/fredboat/util/DiscordUtil.java +++ b/FredBoat/src/main/java/fredboat/util/DiscordUtil.java @@ -25,6 +25,11 @@ package fredboat.util; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import fredboat.Config; +import fredboat.FredBoat; import fredboat.commandmeta.abs.CommandContext; import fredboat.feature.I18n; import fredboat.feature.metrics.Metrics; @@ -133,8 +138,18 @@ public static DiscordAppInfo getApplicationInfo(@Nonnull JDA jda) { return info; } + //token <-> botid @Nonnull - public static String getUserId(@Nonnull String token) { + public static final LoadingCache BOT_ID = CacheBuilder.newBuilder() + .build(CacheLoader.asyncReloading(CacheLoader.from(DiscordUtil::getUserId), FredBoat.executor)); + + + //uses our configured bot token to retrieve our own userid + public static long getBotId() { + return BOT_ID.getUnchecked(Config.CONFIG.getBotToken()); + } + + private static long getUserId(@Nonnull String token) { Http.SimpleRequest request = Http.get(Requester.DISCORD_API_PREFIX + "/users/@me") .auth("Bot " + token) .header("User-agent", USER_AGENT); @@ -154,9 +169,19 @@ public static String getUserId(@Nonnull String token) { } } if (result.isEmpty()) { - throw new RuntimeException("Failed to retrieve my own userId from Discord"); + throw new RuntimeException("Failed to retrieve my own userId from Discord, the result is empty"); } - return result; + + long botId; + try { + botId = Long.parseUnsignedLong(result); + } catch (NumberFormatException e) { + //logging the error and rethrowing a new one, because it might expose information that we dont want users to see + log.error("Failed to retrieve my own userId from Discord", e); + throw new RuntimeException("Failed to retrieve my own userId from Discord, see error log for more information."); + } + + return botId; } // ########## Moderation related helper functions @@ -199,7 +224,7 @@ public DiscordAppInfo(ApplicationInfo applicationInfo) { // when rightclick -> copy Id or mentioning, but a different one, an application id. due to risks of // introducing bugs on the public boat when using this (as happened with the mention prefix) it has been // commented out and shall stay this way as a warning to not use it. Usually the JDA#getSelfUser() method is - // accessible to gain access to our own bot id + // accessible to gain access to our own bot id, otherwise use DiscordUtil.getDefaultBotId() //this.botIdLong = applicationInfo.getIdLong(); //this.botId = applicationInfo.getId(); this.iconId = applicationInfo.getIconId(); From cddf1919d0d576f3160326cc62cd009015b4ff2d Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 18:11:11 +0100 Subject: [PATCH 50/62] Prevent db connection leakage when retrying --- FredBoat/src/main/java/fredboat/FredBoat.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index 258e6681f..676cd7332 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -139,6 +139,9 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc int dbConnectionAttempts = 0; while ((mainDbConn == null || !mainDbConn.isAvailable()) && dbConnectionAttempts++ < 10) { try { + if (mainDbConn != null) { + mainDbConn.shutdown(); + } mainDbConn = DatabaseManager.main(); } catch (Exception e) { log.error("Could not connect to the database. Retrying in a moment...", e); From 278cc1a642f77c449c4fc4e0ef20b5ffb0928af3 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 18:28:54 +0100 Subject: [PATCH 51/62] Implement flyway migrations Add some missing Column annotations to entities Remove unused UConfig Create V1 Initial Schemas for main and cache dbs --- FredBoat/build.gradle | 2 + FredBoat/src/main/java/fredboat/Config.java | 2 +- .../java/fredboat/db/DatabaseManager.java | 30 ++++- .../main/java/fredboat/db/EntityReader.java | 5 - .../main/java/fredboat/db/EntityWriter.java | 5 - .../db/entity/main/BlacklistEntry.java | 3 +- .../fredboat/db/entity/main/GuildConfig.java | 1 + .../db/entity/main/GuildPermissions.java | 1 + .../java/fredboat/db/entity/main/UConfig.java | 91 --------------- .../migrations/cache/V1__InitialSchema.java | 66 +++++++++++ .../db/migrations/main/V1__InitialSchema.java | 106 ++++++++++++++++++ 11 files changed, 206 insertions(+), 106 deletions(-) delete mode 100644 FredBoat/src/main/java/fredboat/db/entity/main/UConfig.java create mode 100644 FredBoat/src/main/java/fredboat/db/migrations/cache/V1__InitialSchema.java create mode 100644 FredBoat/src/main/java/fredboat/db/migrations/main/V1__InitialSchema.java diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index f9c081c2d..e824feb73 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -62,6 +62,8 @@ dependencies { compile group: 'space.npstr.SqlSauce', name: 'sqlsauce-core', version: '0.0.3' compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.12.Final' + compile group: 'org.flywaydb', name: 'flyway-core', version: '5.0.3' + compile group: 'org.togglz', name: 'togglz-core', version: '2.5.0.Final' compile group: 'com.google.guava', name: 'guava', version: '23.5-jre' compile group: 'com.github.vladimir-bukhtoyarov', name: 'bucket4j-core', version: '3.0.2' diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java index ccb8e516b..c04b766c0 100644 --- a/FredBoat/src/main/java/fredboat/Config.java +++ b/FredBoat/src/main/java/fredboat/Config.java @@ -541,7 +541,7 @@ public String getOpenWeatherKey() { return openWeatherKey; } - public String getJdbcUrl() { + public String getMainJdbcUrl() { return jdbcUrl; } diff --git a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java index c70db7d9e..8cbde8ec8 100644 --- a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java +++ b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java @@ -31,6 +31,8 @@ import net.sf.ehcache.CacheManager; import net.sf.ehcache.config.CacheConfiguration; import net.sf.ehcache.config.PersistenceConfiguration; +import org.flywaydb.core.Flyway; +import org.flywaydb.core.api.MigrationVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import space.npstr.sqlsauce.DatabaseConnection; @@ -46,7 +48,18 @@ public class DatabaseManager { private static final String CACHE_PERSISTENCE_UNIT_NAME = "fredboat.cache"; public static DatabaseConnection main() throws DatabaseException { - String jdbc = Config.CONFIG.getJdbcUrl(); + String jdbc = Config.CONFIG.getMainJdbcUrl(); + + //run flyway migrations ahead of connecting to the database, because hibernate will run + // additional validations on the schema + Flyway flyway = new Flyway(); + flyway.setDataSource(jdbc, null, null); //user and pass are part of the jdbc url + flyway.setBaselineOnMigrate(true); + flyway.setBaselineVersion(MigrationVersion.fromVersion("0")); + flyway.setBaselineDescription("Base Migration"); + flyway.setLocations("classpath:fredboat/db/migrations/main"); + flyway.migrate(); + HikariConfig hikariConfig = DatabaseConnection.Builder.getDefaultHikariConfig(); hikariConfig.setMaximumPoolSize(Config.CONFIG.getHikariPoolSize()); @@ -57,6 +70,8 @@ public static DatabaseConnection main() throws DatabaseException { hibernateProps.put("net.sf.ehcache.configurationResourceName", "/ehcache_main.xml"); hibernateProps.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache_main.xml"); hibernateProps.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); + //we use flyway db now for migrations, hibernate shall only run validations + hibernateProps.put("hibernate.hbm2ddl.auto", "validate"); DatabaseConnection databaseConnection = new DatabaseConnection.Builder(MAIN_PERSISTENCE_UNIT_NAME, jdbc) .setHikariConfig(hikariConfig) @@ -88,6 +103,16 @@ public static DatabaseConnection main() throws DatabaseException { public static DatabaseConnection cache() throws DatabaseException { String cacheJdbc = Config.CONFIG.getCacheJdbcUrl(); + //run flyway migrations ahead of connecting to the database, because hibernate will run + // additional validations on the schema + Flyway flyway = new Flyway(); + flyway.setDataSource(cacheJdbc, null, null); //user and pass are part of the jdbc url + flyway.setBaselineOnMigrate(true); + flyway.setBaselineVersion(MigrationVersion.fromVersion("0")); + flyway.setBaselineDescription("Base Migration"); + flyway.setLocations("classpath:fredboat/db/migrations/cache"); + flyway.migrate(); + HikariConfig hikariConfig = DatabaseConnection.Builder.getDefaultHikariConfig(); hikariConfig.setMaximumPoolSize(Config.CONFIG.getHikariPoolSize()); @@ -97,7 +122,8 @@ public static DatabaseConnection cache() throws DatabaseException { hibernateProps.put("net.sf.ehcache.configurationResourceName", "/ehcache_cache.xml"); hibernateProps.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache_cache.xml"); hibernateProps.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); - + //we use flyway db now for migrations, hibernate shall only run validations + hibernateProps.put("hibernate.hbm2ddl.auto", "validate"); DatabaseConnection databaseConnection = new DatabaseConnection.Builder(CACHE_PERSISTENCE_UNIT_NAME, cacheJdbc) .setHikariConfig(hikariConfig) diff --git a/FredBoat/src/main/java/fredboat/db/EntityReader.java b/FredBoat/src/main/java/fredboat/db/EntityReader.java index e1200cd7d..d3151bbc9 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityReader.java +++ b/FredBoat/src/main/java/fredboat/db/EntityReader.java @@ -31,7 +31,6 @@ import fredboat.db.entity.main.BlacklistEntry; import fredboat.db.entity.main.GuildConfig; import fredboat.db.entity.main.GuildPermissions; -import fredboat.db.entity.main.UConfig; import net.dv8tion.jda.core.entities.Guild; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,10 +44,6 @@ public class EntityReader { private static final Logger log = LoggerFactory.getLogger(EntityReader.class); - public static UConfig getUConfig(String id) { - return getEntity(id, UConfig.class); - } - public static GuildConfig getGuildConfig(String id) { return getEntity(id, GuildConfig.class); } diff --git a/FredBoat/src/main/java/fredboat/db/EntityWriter.java b/FredBoat/src/main/java/fredboat/db/EntityWriter.java index c5be1dab2..725e2080b 100644 --- a/FredBoat/src/main/java/fredboat/db/EntityWriter.java +++ b/FredBoat/src/main/java/fredboat/db/EntityWriter.java @@ -30,7 +30,6 @@ import fredboat.db.entity.main.BlacklistEntry; import fredboat.db.entity.main.GuildConfig; import fredboat.db.entity.main.GuildPermissions; -import fredboat.db.entity.main.UConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import space.npstr.sqlsauce.DatabaseException; @@ -42,10 +41,6 @@ public class EntityWriter { private static final Logger log = LoggerFactory.getLogger(EntityWriter.class); - public static void mergeUConfig(UConfig config) { - merge(config); - } - public static void mergeGuildConfig(GuildConfig config) { merge(config); } diff --git a/FredBoat/src/main/java/fredboat/db/entity/main/BlacklistEntry.java b/FredBoat/src/main/java/fredboat/db/entity/main/BlacklistEntry.java index 908f51dcb..a09e61837 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/main/BlacklistEntry.java +++ b/FredBoat/src/main/java/fredboat/db/entity/main/BlacklistEntry.java @@ -26,7 +26,6 @@ package fredboat.db.entity.main; import fredboat.db.entity.IEntity; -import org.hibernate.annotations.ColumnDefault; import javax.persistence.Column; import javax.persistence.Entity; @@ -44,6 +43,7 @@ public class BlacklistEntry implements IEntity { //id of the user or guild that this blacklist entry belongs to @Id + @Column(name = "id", nullable = false) public long id; //blacklist level that the user or guild is on @@ -57,7 +57,6 @@ public class BlacklistEntry implements IEntity { //when was the ratelimit hit the last time? @Column(name = "rate_limit_timestamp", nullable = false) - @ColumnDefault("0") //tells hibernate ddl how to fill this by default with a zero public long rateLimitReachedTimestamp; //time when the id was blacklisted diff --git a/FredBoat/src/main/java/fredboat/db/entity/main/GuildConfig.java b/FredBoat/src/main/java/fredboat/db/entity/main/GuildConfig.java index dfc6a69bb..3d916f8f8 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/main/GuildConfig.java +++ b/FredBoat/src/main/java/fredboat/db/entity/main/GuildConfig.java @@ -51,6 +51,7 @@ public class GuildConfig implements IEntity, Serializable { private static final long serialVersionUID = 5055243002380106205L; @Id + @Column(name = "guildid", nullable = false) private String guildId; @Column(name = "track_announce", nullable = false) diff --git a/FredBoat/src/main/java/fredboat/db/entity/main/GuildPermissions.java b/FredBoat/src/main/java/fredboat/db/entity/main/GuildPermissions.java index c782dc3b6..fcd91f1d4 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/main/GuildPermissions.java +++ b/FredBoat/src/main/java/fredboat/db/entity/main/GuildPermissions.java @@ -50,6 +50,7 @@ public class GuildPermissions implements IEntity, Serializable { // Guild ID @Id + @Column(name = "id") private String id; public GuildPermissions() {} diff --git a/FredBoat/src/main/java/fredboat/db/entity/main/UConfig.java b/FredBoat/src/main/java/fredboat/db/entity/main/UConfig.java deleted file mode 100644 index df11b13f6..000000000 --- a/FredBoat/src/main/java/fredboat/db/entity/main/UConfig.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 Frederik Ar. Mikkelsen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -package fredboat.db.entity.main; - -import fredboat.db.entity.IEntity; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name = "user_config") -public class UConfig implements IEntity { - - @Id - private String userId; - private String bearer; - private String refresh; - private long bearerexpiration; - - public String getBearer() { - return bearer; - } - - public String getRefresh() { - return refresh; - } - - public String getUserId() { - return userId; - } - - public long getBearerExpiration() { - return bearerexpiration; - } - - public UConfig(String id) { - this.userId = id; - } - - @Override - public void setId(String id) { - this.userId = id; - } - - public UConfig() { - } - - public UConfig setBearer(String bearer) { - this.bearer = bearer; - return this; - } - - public UConfig setRefresh(String refresh) { - this.refresh = refresh; - return this; - } - - public UConfig setUserId(String userId) { - this.userId = userId; - return this; - } - - public UConfig setBearerExpiration(long bearerExpiration) { - this.bearerexpiration = bearerExpiration; - return this; - } -} \ No newline at end of file diff --git a/FredBoat/src/main/java/fredboat/db/migrations/cache/V1__InitialSchema.java b/FredBoat/src/main/java/fredboat/db/migrations/cache/V1__InitialSchema.java new file mode 100644 index 000000000..75cd1d33f --- /dev/null +++ b/FredBoat/src/main/java/fredboat/db/migrations/cache/V1__InitialSchema.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2017 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.migrations.cache; + +import org.flywaydb.core.api.migration.jdbc.JdbcMigration; + +import java.sql.Connection; +import java.sql.Statement; + +/** + * Created by napster on 23.12.17. + */ +public class V1__InitialSchema implements JdbcMigration { + @Override + public void migrate(Connection connection) throws Exception { + + //SearchResult + String createSearchResultsSql + = "CREATE TABLE IF NOT EXISTS public.search_results " + + "( " + + " provider CHARACTER VARYING(255) COLLATE pg_catalog.\"default\" NOT NULL, " + + " search_term TEXT COLLATE pg_catalog.\"default\" NOT NULL, " + + " search_result OID, " + + " \"timestamp\" BIGINT, " + + " CONSTRAINT search_results_pkey PRIMARY KEY (provider, search_term) " + + ");"; + try (Statement createSearchResults = connection.createStatement()) { + createSearchResults.execute(createSearchResultsSql); + } + + //HStorex (from sqlsauce, requires hstore extension to be enabled) + String createHstorexSql + = "CREATE TABLE IF NOT EXISTS public.hstorex " + + "( " + + " name TEXT COLLATE pg_catalog.\"default\" NOT NULL, " + + " hstorex HSTORE, " + + " CONSTRAINT hstorex_pkey PRIMARY KEY (name) " + + ")"; + try (Statement createHstorex = connection.createStatement()) { + createHstorex.execute(createHstorexSql); + } + } +} diff --git a/FredBoat/src/main/java/fredboat/db/migrations/main/V1__InitialSchema.java b/FredBoat/src/main/java/fredboat/db/migrations/main/V1__InitialSchema.java new file mode 100644 index 000000000..1068c19b4 --- /dev/null +++ b/FredBoat/src/main/java/fredboat/db/migrations/main/V1__InitialSchema.java @@ -0,0 +1,106 @@ +/* + * + * MIT License + * + * Copyright (c) 2017 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.db.migrations.main; + +import org.flywaydb.core.api.migration.jdbc.JdbcMigration; + +import java.sql.Connection; +import java.sql.Statement; + +/** + * Created by napster on 23.12.17. + *

+ * This initializes our schema at the point where we turned off hibernate-auto-ddl + */ +public class V1__InitialSchema implements JdbcMigration { + + @Override + public void migrate(Connection connection) throws Exception { + + //UConfig + //drop UConfig if exists; it was never used anyways, and can be readded later if we actually use it + String dropUConfigSql = "DROP TABLE IF EXISTS public.user_config;"; + try (Statement dropUConfig = connection.createStatement()) { + dropUConfig.execute(dropUConfigSql); + } + + //BlacklistEntry + String createBlacklistSql + = "CREATE TABLE IF NOT EXISTS public.blacklist " + + "( " + + " id BIGINT NOT NULL, " + + " level INTEGER NOT NULL, " + + " rate_limit_reached INTEGER NOT NULL, " + + " rate_limit_timestamp BIGINT NOT NULL, " + + " blacklisted_timestamp BIGINT NOT NULL, " + + " CONSTRAINT blacklist_pkey PRIMARY KEY (id) " + + ");"; + try (Statement createBlacklist = connection.createStatement()) { + createBlacklist.execute(createBlacklistSql); + } + + //GuildConfig + String createGuildConfigSql + = "CREATE TABLE IF NOT EXISTS public.guild_config " + + "( " + + " guildid CHARACTER VARYING(255) COLLATE pg_catalog.\"default\" NOT NULL, " + + " track_announce BOOLEAN NOT NULL, " + + " auto_resume BOOLEAN NOT NULL, " + + " lang CHARACTER VARYING(255) COLLATE pg_catalog.\"default\" NOT NULL, " + + " prefix TEXT COLLATE pg_catalog.\"default\", " + + " CONSTRAINT guild_config_pkey PRIMARY KEY(guildid) " + + ");"; + try (Statement createGuildConfig = connection.createStatement()) { + createGuildConfig.execute(createGuildConfigSql); + } + + //GuildPermissions + String createGuildPermissionsSql + = "CREATE TABLE IF NOT EXISTS public.guild_permissions " + + "( " + + " id CHARACTER VARYING(255) COLLATE pg_catalog.\"default\" NOT NULL, " + + " list_admin TEXT COLLATE pg_catalog.\"default\" NOT NULL, " + + " list_dj TEXT COLLATE pg_catalog.\"default\" NOT NULL, " + + " list_user TEXT COLLATE pg_catalog.\"default\" NOT NULL, " + + " CONSTRAINT guild_permissions_pkey PRIMARY KEY (id) " + + ");"; + try (Statement createGuildPermissions = connection.createStatement()) { + createGuildPermissions.execute(createGuildPermissionsSql); + } + + //HStorex (from sqlsauce, requires hstore extension to be enabled) + String createHstorexSql + = "CREATE TABLE IF NOT EXISTS public.hstorex " + + "( " + + " name TEXT COLLATE pg_catalog.\"default\" NOT NULL, " + + " hstorex HSTORE, " + + " CONSTRAINT hstorex_pkey PRIMARY KEY (name) " + + ")"; + try (Statement createHstorex = connection.createStatement()) { + createHstorex.execute(createHstorexSql); + } + } +} From 4eedf4cd9bbb77ee41198f7a1f31ac0dd86c05af Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 19:34:20 +0100 Subject: [PATCH 52/62] Cache db needs to be distinct from main db; FredBoat will start and work without it though --- FredBoat/credentials.yaml.example | 14 ++++++---- FredBoat/src/main/java/fredboat/Config.java | 26 ++++++++++++++----- FredBoat/src/main/java/fredboat/FredBoat.java | 4 ++- .../java/fredboat/db/DatabaseManager.java | 7 +++++ .../db/entity/cache/SearchResult.java | 21 ++++++++++++--- 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/FredBoat/credentials.yaml.example b/FredBoat/credentials.yaml.example index 8e7d22544..3d0cb2b6a 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/credentials.yaml.example @@ -86,7 +86,7 @@ openWeatherKey: "" # Learn more about roles here: https://www.postgresql.org/docs/10/static/database-roles.html # Learn more about creating databases here: https://www.postgresql.org/docs/10/static/manage-ag-createdb.html # Learn more about the postgres jdbc url here: https://jdbc.postgresql.org/documentation/head/connect.html -# If you are using an SSH tunnel, you need to point your jdbc url to localhost:9333 +# If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort # Example jdbc: "jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass" jdbcUrl: "" @@ -94,7 +94,7 @@ jdbcUrl: "" # Ssh tunnel for a remote database. this is useful for when you don't want to expose your database on the remote server # and instead use ssh tunneling to access it # If you are running with docker-compose then you don't need to change any ssh value here. -# If you are using an SSH tunnel, you need to point your jdbc url to localhost:9333 +# If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort useSshTunnel: false sshHost: "" # add the ssh port to the ip / url, usually 22, for example: "db.example.com:22" sshUser: "" # user on the remote machine @@ -104,11 +104,15 @@ tunnelLocalPort: 5432 # endpoint port of the tunnel on the machine runni tunnelRemotePort: 5432 # port of the PostgreSQL on the remote machine, 5432 by default # Database for caching things, see config of main database above for details about the individual values. -# You only need to configure this if you want to have these in two different places (can be two databases in a single postgres). -# By default (= if not configured) the cache database will use the same jdbc url as the main database. +# If you are running with docker-compose then you don't need to change the cache jdbcUrl here. +# The main and cache databases can be two databases inside a single postgres instance. +# They CANNOT be the same database due to the way flyway migrations work. # The main benefit is that you don't have to backup/migrate the cache database, it can just be dropped/recreated -# If you are going to use ssh tunnels for both database connections, make sure that the local tunnel ports don't collide +# If you do not provide a jdbc url for the cache database, FredBoat will still work (most likely), but may have a degraded +# performance, especially in high usage environments and when using Spotify playlists. +# If you are going to use two different ssh tunnels for both database connections, make sure that the local tunnel ports don't collide cacheJdbcUrl: "" + cacheUseSshTunnel: false cacheSshHost: "" cacheSshUser: "" diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java index c04b766c0..bb99c9791 100644 --- a/FredBoat/src/main/java/fredboat/Config.java +++ b/FredBoat/src/main/java/fredboat/Config.java @@ -38,6 +38,7 @@ import org.yaml.snakeyaml.error.YAMLException; import space.npstr.sqlsauce.ssh.SshTunnel; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.File; import java.io.FileNotFoundException; @@ -109,11 +110,13 @@ public class Config { private String openWeatherKey; // main database + SSH tunnel + @Nonnull private String jdbcUrl; @Nullable private SshTunnel.SshDetails mainSshTunnelConfig; // cache database + SSH tunnel + @Nullable private String cacheJdbcUrl; @Nullable private SshTunnel.SshDetails cacheSshTunnelConfig; @@ -239,10 +242,10 @@ public Config(File credentialsFile, File configFile) { jdbcUrl = (String) creds.getOrDefault("jdbcUrl", ""); if (jdbcUrl == null || jdbcUrl.isEmpty()) { if ("docker".equals(System.getenv("ENV"))) { - log.info("No main JDBC URL found, docker environment detected. Using default docker JDBC url"); + log.info("No main JDBC URL found, docker environment detected. Using default docker main JDBC url"); jdbcUrl = "jdbc:postgresql://db:5432/fredboat?user=fredboat"; } else { - String message = "No main jdbcUrl provided in a non-docker environment."; + String message = "No main jdbcUrl provided in a non-docker environment. FredBoat cannot work without a database."; log.error(message); throw new RuntimeException(message); } @@ -281,13 +284,21 @@ public Config(File credentialsFile, File configFile) { cacheJdbcUrl = (String) creds.getOrDefault("cacheJdbcUrl", ""); if (cacheJdbcUrl == null || cacheJdbcUrl.isEmpty()) { if ("docker".equals(System.getenv("ENV"))) { - log.info("No cacheJdbcUrl found, docker environment detected. Using default docker JDBC url"); + log.info("No cache jdbcUrl found, docker environment detected. Using default docker cache JDBC url"); cacheJdbcUrl = "jdbc:postgresql://db:5432/fredboat_cache?user=fredboat"; } else { - log.warn("No cacheJdbcUrl provided in a non-docker environment. Falling back to the main one."); - cacheJdbcUrl = jdbcUrl; + log.warn("No cache jdbcUrl provided in a non-docker environment. This may lead to a degraded performance, " + + "especially in a high usage environment, or when using Spotify playlists."); + cacheJdbcUrl = null; } } + if (jdbcUrl.equals(cacheJdbcUrl)) { + log.warn("The main and cache jdbc urls may not point to the same database due to how flyway handles migrations. " + + "Please read (an updated version of) the credentials.yaml.example on configuring the cache jdbc url. " + + "The cache database will not be available in this execution of FredBoat. This may lead to a degraded performance, " + + "especially in a high usage environment, or when using Spotify playlists."); + cacheJdbcUrl = null; + } boolean cacheUseSshTunnel = (boolean) creds.getOrDefault("cacheUseSshTunnel", false); if (cacheUseSshTunnel) { //Parse host:port @@ -365,7 +376,7 @@ public Config(File credentialsFile, File configFile) { PlayerLimitManager.setLimit((Integer) config.getOrDefault("playerLimit", -1)); } catch (IOException e) { log.error("Failed to read config and or credentials files into strings.", e); - throw new RuntimeException(e); + throw new RuntimeException("Failed to read config and or credentials files into strings.", e); } catch (YAMLException | ClassCastException e) { log.error("Could not parse the credentials and/or config yaml files! They are probably misformatted. " + "Try using an online yaml validator.", e); @@ -541,6 +552,7 @@ public String getOpenWeatherKey() { return openWeatherKey; } + @Nonnull public String getMainJdbcUrl() { return jdbcUrl; } @@ -550,6 +562,8 @@ public SshTunnel.SshDetails getMainSshTunnelConfig() { return mainSshTunnelConfig; } + @Nullable + //may return null if no cache database was provided. public String getCacheJdbcUrl() { return cacheJdbcUrl; } diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index 676cd7332..4b2880963 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -89,6 +89,8 @@ public abstract class FredBoat { private final static JdaEntityCounts jdaEntityCountsTotal = new JdaEntityCounts(); private static DatabaseConnection mainDbConn; + + @Nullable //will be null if no cache database has been configured private static DatabaseConnection cacheDbConn; private static final List shards = new CopyOnWriteArrayList<>(); @@ -463,7 +465,7 @@ public static DatabaseConnection getMainDbConnection() { return mainDbConn; } - @Nonnull + @Nullable //may return null if no cache database has been configured public static DatabaseConnection getCacheDbConnection() { return cacheDbConn; } diff --git a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java index 8cbde8ec8..d8840ad7f 100644 --- a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java +++ b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java @@ -38,6 +38,8 @@ import space.npstr.sqlsauce.DatabaseConnection; import space.npstr.sqlsauce.DatabaseException; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.Properties; public class DatabaseManager { @@ -47,6 +49,7 @@ public class DatabaseManager { private static final String MAIN_PERSISTENCE_UNIT_NAME = "fredboat.main"; private static final String CACHE_PERSISTENCE_UNIT_NAME = "fredboat.cache"; + @Nonnull public static DatabaseConnection main() throws DatabaseException { String jdbc = Config.CONFIG.getMainJdbcUrl(); @@ -100,8 +103,12 @@ public static DatabaseConnection main() throws DatabaseException { } + @Nullable //may return null of no cache db has been configured public static DatabaseConnection cache() throws DatabaseException { String cacheJdbc = Config.CONFIG.getCacheJdbcUrl(); + if (cacheJdbc == null) { + return null; + } //run flyway migrations ahead of connecting to the database, because hibernate will run // additional validations on the schema diff --git a/FredBoat/src/main/java/fredboat/db/entity/cache/SearchResult.java b/FredBoat/src/main/java/fredboat/db/entity/cache/SearchResult.java index 972258572..29921d257 100644 --- a/FredBoat/src/main/java/fredboat/db/entity/cache/SearchResult.java +++ b/FredBoat/src/main/java/fredboat/db/entity/cache/SearchResult.java @@ -39,8 +39,10 @@ import org.hibernate.annotations.CacheConcurrencyStrategy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import space.npstr.sqlsauce.DatabaseConnection; import space.npstr.sqlsauce.DatabaseException; +import javax.annotation.Nullable; import javax.persistence.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -94,15 +96,21 @@ public SearchResult(AudioPlayerManager playerManager, SearchUtil.SearchProvider * @param provider the search provider that shall be used for this search * @param searchTerm the query to search for * @param maxAgeMillis the maximum age of the cached search result; provide a negative value for eternal cache - * @return the cached search result; may return null for a non-existing or outdated search + * @return the cached search result; may return null for a non-existing or outdated search, or when there is no + * cache database */ + @Nullable public static AudioPlaylist load(AudioPlayerManager playerManager, SearchUtil.SearchProvider provider, String searchTerm, long maxAgeMillis) throws DatabaseNotReadyException { EntityManager em = null; SearchResult sr; SearchResultId sId = new SearchResultId(provider, searchTerm); + DatabaseConnection cacheDbConn = FredBoat.getCacheDbConnection(); + if (cacheDbConn == null) { + return null; + } try { - em = FredBoat.getCacheDbConnection().getEntityManager(); + em = cacheDbConn.getEntityManager(); em.getTransaction().begin(); sr = em.find(SearchResult.class, sId); em.getTransaction().commit(); @@ -125,12 +133,17 @@ public static AudioPlaylist load(AudioPlayerManager playerManager, SearchUtil.Se /** * Persist a search in the database. * - * @return the merged SearchResult object + * @return the merged SearchResult object, or null when there is no cache database */ + @Nullable public SearchResult save() { + DatabaseConnection cacheDbConn = FredBoat.getCacheDbConnection(); + if (cacheDbConn == null) { + return null; + } EntityManager em = null; try { - em = FredBoat.getCacheDbConnection().getEntityManager(); + em = cacheDbConn.getEntityManager(); em.getTransaction().begin(); SearchResult managed = em.merge(this); em.getTransaction().commit(); From 3285c4ce5e5bbe5f814450b41c0e1f26c6671bdc Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 21:07:11 +0100 Subject: [PATCH 53/62] Improve the start up of the database image --- FredBoat/docker/database/initdb.sh | 10 ++++++++++ FredBoat/docker/database/run.sh | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/FredBoat/docker/database/initdb.sh b/FredBoat/docker/database/initdb.sh index 347246115..be44a8813 100755 --- a/FredBoat/docker/database/initdb.sh +++ b/FredBoat/docker/database/initdb.sh @@ -1,6 +1,16 @@ #!/bin/bash set -e +while ! psql -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='$POSTGRES_USER'" | grep -q 1; do + echo "Waiting on postgres own initial setup to finish" + sleep 1 +done +sleep 1 +while ! pg_isready -U postgres; do + echo "Waiting on postgres to be ready" + sleep 1 +done + # make sure the fredboat user exists psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -tAc "SELECT 1 FROM pg_roles WHERE rolname='fredboat'" | grep -q 1 || createuser -U "$POSTGRES_USER" fredboat diff --git a/FredBoat/docker/database/run.sh b/FredBoat/docker/database/run.sh index 7ae3e3823..593f835da 100755 --- a/FredBoat/docker/database/run.sh +++ b/FredBoat/docker/database/run.sh @@ -20,12 +20,6 @@ trap _term SIGTERM echo "Running entry point" docker-entrypoint.sh postgres & -# wait until the database is ready -while ! pg_isready -U postgres; do - echo "Waiting on postgres to be ready" - sleep 1 -done - # run our own init script echo "Running init db" initdb.sh From 37849a7534083b938161d96edc968fed3fe9a829 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 21:31:24 +0100 Subject: [PATCH 54/62] Adjust log level and waiting time for database connection --- FredBoat/src/main/java/fredboat/FredBoat.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index 4b2880963..13122f610 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -146,8 +146,8 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc } mainDbConn = DatabaseManager.main(); } catch (Exception e) { - log.error("Could not connect to the database. Retrying in a moment...", e); - Thread.sleep(5000); + log.info("Could not connect to the database. Retrying in a moment...", e); + Thread.sleep(6000); } } if (mainDbConn == null || !mainDbConn.isAvailable()) { From 6f4afa0701c5a554c1cf87cf5f329a557f579cc1 Mon Sep 17 00:00:00 2001 From: Napster Date: Sat, 23 Dec 2017 21:32:47 +0100 Subject: [PATCH 55/62] Add the database wrapper --- FredBoat/src/main/java/fredboat/FredBoat.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java index 13122f610..29c3ac020 100644 --- a/FredBoat/src/main/java/fredboat/FredBoat.java +++ b/FredBoat/src/main/java/fredboat/FredBoat.java @@ -57,6 +57,7 @@ import org.slf4j.LoggerFactory; import space.npstr.sqlsauce.DatabaseConnection; import space.npstr.sqlsauce.DatabaseException; +import space.npstr.sqlsauce.DatabaseWrapper; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -88,7 +89,7 @@ public abstract class FredBoat { protected final static StatsAgent jdaEntityCountAgent = new StatsAgent("jda entity counter"); private final static JdaEntityCounts jdaEntityCountsTotal = new JdaEntityCounts(); - private static DatabaseConnection mainDbConn; + private static DatabaseWrapper mainDbWrapper; @Nullable //will be null if no cache database has been configured private static DatabaseConnection cacheDbConn; @@ -139,6 +140,7 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc // this is relevant in a dockerized environment because after a reboot there is no guarantee that the db // container will be started before the fredboat one int dbConnectionAttempts = 0; + DatabaseConnection mainDbConn = null; while ((mainDbConn == null || !mainDbConn.isAvailable()) && dbConnectionAttempts++ < 10) { try { if (mainDbConn != null) { @@ -153,8 +155,10 @@ public static void main(String[] args) throws LoginException, IllegalArgumentExc if (mainDbConn == null || !mainDbConn.isAvailable()) { log.error("Could not establish database connection. Exiting..."); shutdown(ExitCodes.EXIT_CODE_ERROR); + return; } FredBoatAgent.start(new DBConnectionWatchdogAgent(mainDbConn)); + mainDbWrapper = new DatabaseWrapper(mainDbConn); try { cacheDbConn = DatabaseManager.cache(); @@ -349,8 +353,8 @@ private static boolean areWeReadyYet() { if (cacheDbConn != null) { cacheDbConn.shutdown(); } - if (mainDbConn != null) { - mainDbConn.shutdown(); + if (mainDbWrapper != null) { + mainDbWrapper.unwrap().shutdown(); } }; @@ -462,7 +466,12 @@ public static FredBoat getShard(int id) { @Nonnull public static DatabaseConnection getMainDbConnection() { - return mainDbConn; + return mainDbWrapper.unwrap(); + } + + @Nonnull + public static DatabaseWrapper getMainDbWrapper() { + return mainDbWrapper; } @Nullable //may return null if no cache database has been configured From c3cf1e3334a08cd2454ecfec83ceadea5195501f Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 24 Dec 2017 01:29:05 +0100 Subject: [PATCH 56/62] We need more magic --- .../fredboat/command/fun/MagicCommand.java | 60 +++++++++++++++++++ .../init/MainCommandInitializer.java | 2 +- .../java/fredboat/util/AsciiArtConstant.java | 2 +- .../main/java/fredboat/util/TextUtils.java | 7 +++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 FredBoat/src/main/java/fredboat/command/fun/MagicCommand.java diff --git a/FredBoat/src/main/java/fredboat/command/fun/MagicCommand.java b/FredBoat/src/main/java/fredboat/command/fun/MagicCommand.java new file mode 100644 index 000000000..f39347b8c --- /dev/null +++ b/FredBoat/src/main/java/fredboat/command/fun/MagicCommand.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2017 Frederik Ar. Mikkelsen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fredboat.command.fun; + +import fredboat.commandmeta.abs.Command; +import fredboat.commandmeta.abs.CommandContext; +import fredboat.commandmeta.abs.IFunCommand; +import fredboat.messaging.internal.Context; +import fredboat.util.AsciiArtConstant; +import fredboat.util.TextUtils; + +import javax.annotation.Nonnull; + +/** + * Created by napster on 24.12.17. + */ +public class MagicCommand extends Command implements IFunCommand { + public MagicCommand(@Nonnull String name, String... aliases) { + super(name, aliases); + } + + @Override + public void onInvoke(@Nonnull CommandContext context) { + String message = "ABRA KADABRA..."; + if (context.hasArguments()) { + message = TextUtils.defuseMentions(context.rawArgs); + } + + context.reply(AsciiArtConstant.MAGICAL_LENNY + message); + } + + @Nonnull + @Override + public String help(@Nonnull Context context) { + return "{0}{1} [message]\n#This command is magic ( ͡° ͜ʖ ͡°)"; + } +} diff --git a/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java b/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java index de476a3c0..021a5ef61 100644 --- a/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java +++ b/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java @@ -116,7 +116,7 @@ public static void initCommands() { CommandRegistry.registerCommand(new TextCommand("/╲/╭( ͡° ͡° ͜ʖ ͡° ͡°)╮/╱\\", "spiderlenny")); CommandRegistry.registerCommand(new TextCommand("( ͡° ͜ʖ ͡°)", "lenny")); CommandRegistry.registerCommand(new TextCommand("┬┴┬┴┤ ͜ʖ ͡°) ├┬┴┬┴", "peeking", "peekinglenny", "peek")); - CommandRegistry.registerCommand(new TextCommand(AsciiArtConstant.MAGICAL_LENNY, "magicallenny", "lennymagical")); + CommandRegistry.registerCommand(new MagicCommand("magic", "magicallenny", "lennymagical")); CommandRegistry.registerCommand(new TextCommand(AsciiArtConstant.EAGLE_OF_LENNY, "eagleoflenny", "eol", "lennyeagle")); /* Misc - All commands under this line fall in this category */ diff --git a/FredBoat/src/main/java/fredboat/util/AsciiArtConstant.java b/FredBoat/src/main/java/fredboat/util/AsciiArtConstant.java index 7be3bd351..f79ef11b1 100644 --- a/FredBoat/src/main/java/fredboat/util/AsciiArtConstant.java +++ b/FredBoat/src/main/java/fredboat/util/AsciiArtConstant.java @@ -13,7 +13,7 @@ public final class AsciiArtConstant { "⊂   ノ    ・゜+.", " しーJ   °。+ ´¨)", "         .· ´¸.·´¨) ¸.·*¨)", - "          (¸.·´ (¸.·' ☆ ABRA KADABRA..." + "          (¸.·´ (¸.·' ☆ " ); public static final String EAGLE_OF_LENNY = String.join("\n", diff --git a/FredBoat/src/main/java/fredboat/util/TextUtils.java b/FredBoat/src/main/java/fredboat/util/TextUtils.java index b2a8d8fb8..9a0fc0070 100644 --- a/FredBoat/src/main/java/fredboat/util/TextUtils.java +++ b/FredBoat/src/main/java/fredboat/util/TextUtils.java @@ -376,4 +376,11 @@ public static String shorten(@Nonnull String input, int size) { } return shortened.toString(); } + + //put a zero width space between any @ and "here" and "everyone" in the input string + @Nonnull + public static String defuseMentions(@Nonnull String input) { + return input.replaceAll("@here", "@" + ZERO_WIDTH_CHAR + "here") + .replaceAll("@everyone", "@" + ZERO_WIDTH_CHAR + "everyone"); + } } From ed43554a2443c0bcd591b41c30c81a89bc83ea3c Mon Sep 17 00:00:00 2001 From: Napster Date: Sun, 24 Dec 2017 15:42:41 +0100 Subject: [PATCH 57/62] Use long ids --- .../fredboat/command/moderation/PrefixCommand.java | 4 ++-- .../main/java/fredboat/commandmeta/CommandManager.java | 4 ++-- .../java/fredboat/shared/constant/BotConstants.java | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java index 81a4ca3d2..497c683a9 100644 --- a/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java +++ b/FredBoat/src/main/java/fredboat/command/moderation/PrefixCommand.java @@ -84,7 +84,7 @@ public static String giefPrefix(@Nullable Guild guild) { return Config.CONFIG.getPrefix(); } - if (guild.getJDA().getSelfUser().getId().equalsIgnoreCase(BotConstants.PATRON_BOT_ID)) { + if (guild.getJDA().getSelfUser().getIdLong() == BotConstants.PATRON_BOT_ID) { return Config.CONFIG.getPrefix(); //todo lift this limitation after sorting out a data strategy } @@ -103,7 +103,7 @@ public void onInvoke(@Nonnull CommandContext context) { return; } - if (context.guild.getJDA().getSelfUser().getId().equalsIgnoreCase(BotConstants.PATRON_BOT_ID)) { + if (context.guild.getJDA().getSelfUser().getIdLong() == BotConstants.PATRON_BOT_ID) { context.reply("Sorry, this feature has not yet been enabled for the PatronBot! Have a picture of a wombat instead."); wombats.onInvoke(context); return; diff --git a/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java b/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java index e1d7d4e47..d225f1714 100644 --- a/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java +++ b/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java @@ -83,8 +83,8 @@ public static void prefixCalled(CommandContext context) { //Hardcode music commands in FredBoatHangout. Blacklist any channel that isn't #general or #staff, but whitelist Frederikam if ((invoked instanceof IMusicCommand || invoked instanceof AkinatorCommand) // the hate is real - && guild.getId().equals(BotConstants.FREDBOAT_HANGOUT_ID) - && guild.getJDA().getSelfUser().getId().equals(BotConstants.MUSIC_BOT_ID)) { + && guild.getIdLong() == BotConstants.FREDBOAT_HANGOUT_ID + && guild.getJDA().getSelfUser().getIdLong() == BotConstants.MUSIC_BOT_ID) { if (!channel.getId().equals("174821093633294338") // #spam_and_music && !channel.getId().equals("217526705298866177") // #staff && !invoker.getUser().getId().equals("203330266461110272")//Cynth diff --git a/Shared/src/main/java/fredboat/shared/constant/BotConstants.java b/Shared/src/main/java/fredboat/shared/constant/BotConstants.java index 7e8ec0959..655c9dc4a 100644 --- a/Shared/src/main/java/fredboat/shared/constant/BotConstants.java +++ b/Shared/src/main/java/fredboat/shared/constant/BotConstants.java @@ -29,12 +29,12 @@ public class BotConstants { - public static final String MUSIC_BOT_ID = "184405311681986560"; - public static final String BETA_BOT_ID = "152691313123393536"; - public static final String MAIN_BOT_ID = "150376112944447488"; - public static final String PATRON_BOT_ID = "241950106125860865"; + public static final long MUSIC_BOT_ID = 184405311681986560L; + public static final long BETA_BOT_ID = 152691313123393536L; + public static final long MAIN_BOT_ID = 150376112944447488L; + public static final long PATRON_BOT_ID = 241950106125860865L; - public static final String FREDBOAT_HANGOUT_ID = "174820236481134592"; + public static final long FREDBOAT_HANGOUT_ID = 174820236481134592L; public static final Color FREDBOAT_COLOR = new Color(28, 191, 226); //#1CBFE2 public static final String FREDBOAT_URL = "https://fredboat.com"; From 36ba2fa600b1095ffd88752e4fac1d9d40062a53 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 28 Dec 2017 17:58:09 +0100 Subject: [PATCH 58/62] Make flyway work through tunnels --- FredBoat/build.gradle | 2 +- .../src/main/java/fredboat/db/DatabaseManager.java | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index e824feb73..44e733253 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -60,7 +60,7 @@ dependencies { compile group: 'io.prometheus', name: 'simpleclient_guava', version: '0.1.0' compile group: 'io.prometheus', name: 'simpleclient_servlet', version: '0.1.0' - compile group: 'space.npstr.SqlSauce', name: 'sqlsauce-core', version: '0.0.3' + compile group: 'space.npstr.SqlSauce', name: 'sqlsauce-core', version: 'a5c9afd96d1928d9a51e799249a6eb5b08b4f473' compile group: 'org.hibernate', name: 'hibernate-ehcache', version: '5.2.12.Final' compile group: 'org.flywaydb', name: 'flyway-core', version: '5.0.3' diff --git a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java index d8840ad7f..9fd32a57f 100644 --- a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java +++ b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java @@ -53,16 +53,11 @@ public class DatabaseManager { public static DatabaseConnection main() throws DatabaseException { String jdbc = Config.CONFIG.getMainJdbcUrl(); - //run flyway migrations ahead of connecting to the database, because hibernate will run - // additional validations on the schema Flyway flyway = new Flyway(); - flyway.setDataSource(jdbc, null, null); //user and pass are part of the jdbc url flyway.setBaselineOnMigrate(true); flyway.setBaselineVersion(MigrationVersion.fromVersion("0")); flyway.setBaselineDescription("Base Migration"); flyway.setLocations("classpath:fredboat/db/migrations/main"); - flyway.migrate(); - HikariConfig hikariConfig = DatabaseConnection.Builder.getDefaultHikariConfig(); hikariConfig.setMaximumPoolSize(Config.CONFIG.getHikariPoolSize()); @@ -86,6 +81,7 @@ public static DatabaseConnection main() throws DatabaseException { .setHikariStats(Metrics.instance().hikariStats) .setHibernateStats(Metrics.instance().hibernateStats) .setCheckConnection(false) + .setFlyway(flyway) .build(); //adjusting the ehcache config @@ -110,15 +106,11 @@ public static DatabaseConnection cache() throws DatabaseException { return null; } - //run flyway migrations ahead of connecting to the database, because hibernate will run - // additional validations on the schema Flyway flyway = new Flyway(); - flyway.setDataSource(cacheJdbc, null, null); //user and pass are part of the jdbc url flyway.setBaselineOnMigrate(true); flyway.setBaselineVersion(MigrationVersion.fromVersion("0")); flyway.setBaselineDescription("Base Migration"); flyway.setLocations("classpath:fredboat/db/migrations/cache"); - flyway.migrate(); HikariConfig hikariConfig = DatabaseConnection.Builder.getDefaultHikariConfig(); hikariConfig.setMaximumPoolSize(Config.CONFIG.getHikariPoolSize()); @@ -141,6 +133,7 @@ public static DatabaseConnection cache() throws DatabaseException { .setSshDetails(Config.CONFIG.getCacheSshTunnelConfig()) .setHikariStats(Metrics.instance().hikariStats) .setHibernateStats(Metrics.instance().hibernateStats) + .setFlyway(flyway) .build(); //adjusting the ehcache config From dc1d72aa34178271901f0e6e591ecc9e977abaf3 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 28 Dec 2017 18:08:56 +0100 Subject: [PATCH 59/62] Update documentation wrt Hstore requirement --- FredBoat/credentials.yaml.example | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FredBoat/credentials.yaml.example b/FredBoat/credentials.yaml.example index 3d0cb2b6a..700cffcfc 100644 --- a/FredBoat/credentials.yaml.example +++ b/FredBoat/credentials.yaml.example @@ -83,9 +83,11 @@ openWeatherKey: "" # In PostgreSQL, role means user and vice versa. Keep that in mind when reading the following help and the provided links. # If you are running your own PostgreSQL database, you will need to provide a role and a database belonging to that role. # The role needs at least the permission to log in. +# All postgres databases used by FredBoat are required to have the Hstore extension enabled. # Learn more about roles here: https://www.postgresql.org/docs/10/static/database-roles.html # Learn more about creating databases here: https://www.postgresql.org/docs/10/static/manage-ag-createdb.html # Learn more about the postgres jdbc url here: https://jdbc.postgresql.org/documentation/head/connect.html +# Learn more about creating extensions here: https://www.postgresql.org/docs/current/static/sql-createextension.html # If you are using an SSH tunnel, you need to point your jdbc url to localhost and the configured tunnelLocalPort # Example jdbc: "jdbc:postgresql://localhost:5432/fredboat?user=fredboat&password=youshallnotpass" jdbcUrl: "" From d5904c371e21c868b2c406c7e4897961f9ad13e4 Mon Sep 17 00:00:00 2001 From: Napster Date: Thu, 28 Dec 2017 19:46:16 +0100 Subject: [PATCH 60/62] Cache SearchResults for 48h instead of 24h --- FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java b/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java index 347fac3f4..13fda1298 100644 --- a/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java +++ b/FredBoat/src/main/java/fredboat/util/rest/SearchUtil.java @@ -57,7 +57,7 @@ public class SearchUtil { public static final int MAX_RESULTS = 5; - public static final long DEFAULT_CACHE_MAX_AGE = TimeUnit.HOURS.toMillis(24); //24 hours + public static final long DEFAULT_CACHE_MAX_AGE = TimeUnit.HOURS.toMillis(48); public static final String PUNCTUATION_REGEX = "[.,/#!$%^&*;:{}=\\-_`~()\"\']"; private static final Logger log = LoggerFactory.getLogger(SearchUtil.class); From 09008a665a9e7e278f370142215bc206c0b3f74d Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 29 Dec 2017 02:55:21 +0100 Subject: [PATCH 61/62] Update translations --- FredBoat/src/main/resources/lang/README.md | 2 +- .../src/main/resources/lang/ar_SA.properties | 16 +- .../src/main/resources/lang/bn_BD.properties | 305 ++++++++++++++++++ .../src/main/resources/lang/de_DE.properties | 16 +- .../src/main/resources/lang/el_GR.properties | 14 +- .../src/main/resources/lang/en_PT.properties | 4 +- .../src/main/resources/lang/es_ES.properties | 14 +- .../src/main/resources/lang/fi_FI.properties | 58 ++-- .../src/main/resources/lang/fil_PH.properties | 286 ++++++++-------- .../src/main/resources/lang/fr_FR.properties | 14 +- .../src/main/resources/lang/he_IL.properties | 8 +- .../src/main/resources/lang/id_ID.properties | 14 +- .../src/main/resources/lang/it_IT.properties | 14 +- .../src/main/resources/lang/ja_JP.properties | 16 +- .../src/main/resources/lang/ko_KR.properties | 24 +- .../src/main/resources/lang/ms_MY.properties | 156 ++++----- .../src/main/resources/lang/nl_NL.properties | 16 +- .../src/main/resources/lang/pt_BR.properties | 16 +- .../src/main/resources/lang/pt_PT.properties | 38 +-- .../src/main/resources/lang/sv_SE.properties | 14 +- .../src/main/resources/lang/tr_TR.properties | 18 +- .../src/main/resources/lang/vi_VN.properties | 86 ++--- .../src/main/resources/lang/zh_CN.properties | 18 +- .../src/main/resources/lang/zh_TW.properties | 14 +- 24 files changed, 743 insertions(+), 438 deletions(-) create mode 100644 FredBoat/src/main/resources/lang/bn_BD.properties diff --git a/FredBoat/src/main/resources/lang/README.md b/FredBoat/src/main/resources/lang/README.md index b10533074..edf38103a 100644 --- a/FredBoat/src/main/resources/lang/README.md +++ b/FredBoat/src/main/resources/lang/README.md @@ -1,4 +1,4 @@ -# FredBoat-i13n +# FredBoat-i18n Localization for FredBoat See https://crowdin.com/project/fredboat diff --git a/FredBoat/src/main/resources/lang/ar_SA.properties b/FredBoat/src/main/resources/lang/ar_SA.properties index d34bca1f0..0151e0d27 100644 --- a/FredBoat/src/main/resources/lang/ar_SA.properties +++ b/FredBoat/src/main/resources/lang/ar_SA.properties @@ -14,7 +14,7 @@ pauseSuccess=\u062a\u0645 \u0625\u064a\u0642\u0627\u0641 \u0644\u0644\u0627\u063 repeatOnSingle=\u0627\u0644\u0645\u0648\u0633\u064a\u0642\u0627\u0631 \u0633\u0648\u0641 \u064a\u0642\u0648\u0645 \u0628\u062a\u0643\u0631\u0627\u0631 \u0627\u0644\u0623\u063a\u0646\u064a\u0629 \u0627\u0644\u062d\u0627\u0644\u064a\u0629. repeatOnAll=\u0627\u0644\u0645\u0648\u0633\u064a\u0642\u0627\u0631 \u0633\u0648\u0641 \u064a\u0642\u0648\u0645 \u0628\u062a\u0643\u0631\u0627\u0631 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0627\u0646\u062a\u0638\u0627\u0631. repeatOff=\u0627\u0644\u0644\u0627\u0639\u0628 \u0644\u0646 \u064a\u0643\u0631\u0631 \u0627\u0644\u0623\u063a\u0646\u064a\u0629. -selectSuccess=\u0642\u062f \u062a\u0645 \u0627\u062e\u062a\u064a\u0627\u0631\: * *{1} * * ({2}) \u0623\u063a\u0646\u064a\u0629 * * \#{0} * * +selectSuccess=\u0642\u062f \u062a\u0645 \u0627\u062e\u062a\u064a\u0627\u0631\: **{1}** ({2}) \u0623\u063a\u0646\u064a\u0629 **\#{0} ** selectInterval=\u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0631\u0642\u0645 1-{0}. selectSelectionNotGiven=\ \u064a\u062c\u0628 \u0623\u0646 \u062a\u0639\u0637\u0649 \u0645\u062c\u0645\u0648\u0639\u0629 \u0644\u0644\u0627\u062e\u062a\u064a\u0627\u0631 \u0645\u0646\u0647\u0627. shuffleOn=\u062a\u0645 \u062e\u0644\u0637 \u0627\u0644\u0644\u0627\u0639\u0628. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u0623\u0646\u062a \u064a\u062c\u0631\u064a \u0645\u0639\ ratelimitedSkipCommand=\u064a\u0645\u0643\u0646\u0643 \u062a\u062e\u0637\u064a \u0623\u063a\u0646\u064a\u0629 \u0648\u0627\u062d\u062f\u0629 \u0623\u0648 \u0623\u0643\u062b\u0631 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631\: {0} ratelimitedGuildSlowLoadingPlaylist=\u0644\u0627 \u064a\u0633\u0645\u062d \u0647\u0630\u0627 \u0627\u0644\u0645\u0644\u0642\u0645 \u0644\u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0645\u0632\u064a\u062f \u0645\u0646 \u0642\u0648\u0627\u0626\u0645 \u0627\u0644\u062a\u0634\u063a\u064a\u0644 \u0641\u064a \u0647\u0630\u0647 \u0627\u0644\u0644\u062d\u0638\u0629. \u0627\u0644\u0631\u062c\u0627\u0621 \u0644\u0627 \u063a\u064a\u0631 \u0627\u0644\u0645\u0631\u063a\u0648\u0628\u0629 \u0642\u0648\u0627\u0626\u0645 \u0637\u0648\u064a\u0644\u0629. unblacklisted=\u0625\u0632\u0627\u0644\u0629 {0} \u0645\u0646 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0633\u0648\u062f\u0627\u0621. -serverinfoTitle=Info about {0}\: +serverinfoTitle=\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0639\u0646 * *{0} * *\: serverinfoOnlineUsers=\u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u0648\u0646 \u0627\u0644\u0645\u062a\u0648\u0627\u062c\u062f\u0648\u0646 \u062d\u0627\u0644\u064a\u0640\u0651\u0640\u0627\: serverinfoTotalUsers=\u0625\u062c\u0645\u0627\u0644\u064a \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646\: serverinfoRoles=\u0623\u062f\u0648\u0627\u0631\: @@ -193,7 +193,7 @@ serverinfoGuildID=\u0645\u0639\u0631\u0641 \u0627\u0644\u0646\u0642\u0627\u0628\ serverinfoCreationDate=\u062a\u0627\u0631\u064a\u062e \u0627\u0644\u0625\u0646\u0634\u0627\u0621\: serverinfoOwner=\u0627\u0644\u0645\u0627\u0644\u0643\: serverinfoVLv=\u0645\u0633\u062a\u0648\u0649 \u0627\u0644\u062a\u062d\u0642\u0642\: -userinfoTitle=Information about {0}\: +userinfoTitle=\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0639\u0646 * *{0} * *\: userinfoUsername=\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\: userinfoId=ID\: userinfoNick=\u0644\u0642\u0628\: @@ -212,11 +212,11 @@ commandsMaintenance=\u0627\u0644\u0635\u064a\u0627\u0646\u0629 commandsBotOwner=\u0645\u0627\u0644\u0643 \u0628\u0648\u062a commandsMoreHelp=\u0648\u064a\u0642\u0648\u0644 {0} \u0644\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0645\u0632\u064a\u062f \u0645\u0646 \u0627\u0644\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u062d\u0648\u0644 \u0623\u0645\u0631 \u0645\u0639\u064a\u0646. helpUnknownCommand=\u0623\u0645\u0631 \u063a\u064a\u0631 \u0645\u0639\u0631\u0648\u0641. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=\u064a\u0645\u0643\u0646 \u0627\u0644\u0627\u0637\u0644\u0627\u0639 \u0639\u0644\u0649 \u0627\u0644\u0648\u062b\u0627\u0626\u0642 \u0641\u064a\: +helpBotInvite=\u0647\u0644 \u062a\u0631\u064a\u062f \u0625\u0636\u0627\u0641\u0629 \u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a \u0625\u0644\u0649 \u0627\u0644\u062e\u0627\u062f\u0645 \u0627\u0644\u062e\u0627\u0635 \u0628\u0643\u061f \u0625\u0630\u0627 \u0643\u0627\u0646 \u0644\u062f\u064a\u0643 \u0623\u0630\u0648\u0646\u0627\u062a "\u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0645\u0644\u0642\u0645" \u0644\u0644\u0646\u0642\u0627\u0628\u0629 \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0643\u060c \u064a\u0645\u0643\u0646\u0643 \u062f\u0639\u0648\u0629 \u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a\: +helpHangoutInvite=\u0628\u062d\u0627\u062c\u0629 \u0625\u0644\u0649 \u0645\u0633\u0627\u0639\u062f\u0629 \u0623\u0648 \u0644\u062f\u064a\u0643 \u0623\u064a \u0623\u0641\u0643\u0627\u0631 \u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a\u061f \u0631\u0628\u0645\u0627 \u0643\u0646\u062a \u062a\u0631\u063a\u0628 \u0641\u0642\u0637 \u0634\u0646\u0642\u061f \u0627\u0644\u0627\u0646\u0636\u0645\u0627\u0645 \u0625\u0644\u0649 \u0627\u0644\u0645\u062c\u062a\u0645\u0639 \u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a\! +helpNoDmCommands=\u0644\u0627 \u064a\u0645\u0643\u0646\u0643 \u0625\u0631\u0633\u0627\u0644 \u0623\u0648\u0627\u0645\u0631 \u0641\u0631\u064a\u062f\u0628\u0648\u0627\u062a \u0645\u0646 \u062e\u0644\u0627\u0644 \u0646\u0638\u0627\u0645 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0648\u062c\u0647\u0627\u062a \u0627\u0644\u0633\u064a\u0627\u062d\u064a\u0629. +helpCredits=\u062a\u0645 \u0625\u0646\u0634\u0627\u0624\u0647\u0627 \u0628\u0648\u0627\u0633\u0637\u0629 Fre_d \u0648\u0627\u0644\u0645\u0633\u0627\u0647\u0645\u064a\u0646 \u0645\u0641\u062a\u0648\u062d\u0629 \u0627\u0644\u0645\u0635\u062f\u0631 helpSent=\u062a\u0645 \u0625\u0631\u0633\u0627\u0644 \u0627\u0644\u0648\u062b\u0627\u0626\u0642 \u0625\u0644\u0649 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0648\u062c\u0647\u0627\u062a \u0627\u0644\u0633\u064a\u0627\u062d\u064a\u0629 \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0643\! helpProperUsage=\u0627\u0644\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0627\u0644\u0635\u062d\u064a\u062d\: helpCommandOwnerRestricted=\u064a\u0642\u062a\u0635\u0631 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631 \u0639\u0644\u0649 \u0645\u0627\u0644\u0643 \u0627\u0644\u0628\u0648\u062a. diff --git a/FredBoat/src/main/resources/lang/bn_BD.properties b/FredBoat/src/main/resources/lang/bn_BD.properties new file mode 100644 index 000000000..a2e81a5a2 --- /dev/null +++ b/FredBoat/src/main/resources/lang/bn_BD.properties @@ -0,0 +1,305 @@ +#X-Generator: crowdin.com +playQueueEmpty=\u0996\u09c7\u09b2\u09cb\u09af\u09bc\u09be\u09a1\u09bc \u09ac\u09b0\u09cd\u09a4\u09ae\u09be\u09a8\u09c7 \u0995\u09cb\u09a8 \u0996\u09c7\u09b2\u09be \u09a8\u09af\u09bc\u0964 \u0997\u09be\u09a8 \u09af\u09cb\u0997 \u0995\u09b0\u09c1\u09a8 \u09a8\u09bf\u09ae\u09cd\u09a8\u09c7\u09b0 \u09ac\u09be\u0995\u09cd\u09af\u09b0\u09c0\u09a4\u09bf \u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0 \u0995\u09b0\u09c1\u09a8\u0964\u0964\u0964\: ;;\u0996\u09c7\u09b2\u09be +playAlreadyPlaying=\u0987\u099f \u0987\u09b8 \u0985\u09b2\u09b0\u09c7\u09a1\u09bf \u09aa\u09cd\u09b2\u09c7\u09df\u09bf\u0982. +playVCEmpty=\u09ad\u09af\u09bc\u09c7\u09b8 \u099a\u09cd\u09af\u09be\u099f\u09c7 \u0995\u09cb\u09a8 \u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0\u0995\u09be\u09b0\u09c0. +playWillNowPlay=\u09aa\u09cd\u09b2\u09c7\u09af\u09bc\u09be\u09b0 \u098f\u0996\u09a8 \u0996\u09c7\u09b2\u09be \u09b9\u09ac\u09c7. +playSearching=\u09b2\u09c1\u0995\u09bf\u0982 \u09ab\u09b0 `{q}`\u0987\u09a8 YouTube... +playYoutubeSearchError=\u0987\u0989\u099f\u09bf\u0989\u09ac \u09b8\u09a8\u09cd\u09a7\u09be\u09a8 \u0995\u09b0\u09be\u09b0 \u09b8\u09ae\u09af\u09bc \u098f\u0995\u099f\u09bf \u09a4\u09cd\u09b0\u09c1\u099f\u09bf \u09b8\u0982\u0998\u099f\u09bf\u09a4 \u09b9\u09af\u09bc\u09c7\u099b\u09c7\u0964 \u098f\u09b0 \u09aa\u09b0\u09bf\u09ac\u09b0\u09cd\u09a4\u09c7 \u09b8\u09b0\u09be\u09b8\u09b0\u09bf \u0985\u09a1\u09bf\u0993 \u0989\u09ce\u09b8\u09c7\u09b0 \u09b8\u09be\u09a5\u09c7 \u09ac\u09bf\u09ac\u09c7\u099a\u09a8\u09be \u0995\u09b0\u09ac\u09cb\u0964 ``` ;; \u0996\u09c7\u09b2\u09be "\u0964 +playSearchNoResults=''{q}''-\u098f\u09b0 \u099c\u09a8\u09cd\u09af \u0995\u09cb\u09a8\u09cb \u09ab\u09b2\u09be\u09ab\u09b2 \u09a8\u09c7\u0987 +playSelectVideo=* * \u09a6\u09af\u09bc\u09be \u0995\u09b0\u09c7 \u099f\u09cd\u09b0\u09cd\u09af\u09be\u0995 \u09a6\u09bf\u09af\u09bc\u09c7 \u09a8\u09bf\u09b0\u09cd\u09ac\u09be\u099a\u09a8 ''{0}play 1-5'' \u0995\u09ae\u09be\u09a8\u09cd\u09a1\: * * +joinJoining=\u098f\u09a8\u09cd\u099f\u09be\u09b0\u09bf\u0982 {0} +joinErrorAlreadyJoining=\u098f\u0995\u099f\u09bf \u09a4\u09cd\u09b0\u09c1\u099f\u09bf \u09b8\u0982\u0998\u099f\u09bf\u09a4 \u09b9\u09af\u09bc\u09c7\u099b\u09c7\u0964 {0} \u09af\u09cb\u0997 \u09a6\u09bf\u09a4\u09c7 \u09aa\u09be\u09b0\u09b2\u09be\u09ae \u09a8\u09be \u0995\u09be\u09b0\u09a8 \u0986\u09ae\u09bf \u0987\u09a4\u09bf\u09ae\u09a7\u09cd\u09af\u09c7\u0987 \u0993\u0987 \u099a\u09cd\u09af\u09be\u09a8\u09c7\u09b2\u09c7\u09b0 \u09b8\u09be\u09a5\u09c7 \u09b8\u0982\u09af\u09cb\u0997 \u0995\u09b0\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u099b\u09bf\u0964 \u0985\u09a8\u09c1\u0997\u09cd\u09b0\u09b9 \u0995\u09b0\u09c7 \u0986\u09ac\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u09c1\u09a8\u0964. +pauseAlreadyPaused=\u09aa\u09cd\u09b2\u09c7\u09af\u09bc\u09be\u09b0 \u0987\u09a4\u09bf\u09ae\u09a7\u09cd\u09af\u09c7 \u09a5\u09be\u09ae\u09be\u09a8\u09cb \u09b9\u09af\u09bc\u09c7\u099b\u09c7. +pauseSuccess=\u0996\u09c7\u09b2\u09cb\u09af\u09bc\u09be\u09a1\u09bc \u098f\u0996\u09a8 \u09b9\u09a4\u09c7 \u09ac\u09bf\u09b0\u09a4 \u09b0\u09be\u0996\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7\u0964 \u0986\u09aa\u09a8\u09bf \u098f\u099f\u09bf{0}unpause \u09b8\u09be\u09a5\u09c7 unpause \u0995\u09b0\u09a4\u09c7 \u09aa\u09be\u09b0\u09c7\u09a8\u0964. +repeatOnSingle=\u09ac\u09b0\u09cd\u09a4\u09ae\u09be\u09a8 \u099f\u09cd\u09b0\u09cd\u09af\u09be\u0995 \u0996\u09c7\u09b2\u09cb\u09af\u09bc\u09be\u09a1\u09bc \u098f\u0996\u09a8 \u09aa\u09c1\u09a8\u09b0\u09be\u09ac\u09c3\u09a4\u09cd\u09a4\u09bf \u09b9\u09ac\u09c7\u0964. +repeatOnAll=\u09a8\u09be\u0989 \u09b0\u09bf\u09aa\u09bf\u099f\u09bf\u0982. +repeatOff=\u09b0\u09bf\u09aa\u09bf\u099f\u09bf\u0982 \u09b8\u09cd\u099f\u09aa\u09c7\u09a1. +selectSuccess=\u09b8\u0982 **\#{0}** \u09b8\u09bf\u09b2\u09c7\u0995\u09cd\u099f\u09c7\u09a1\: **{1}** ({2}) +selectInterval=\u09b8\u0982\u0996\u09cd\u09af\u09be\u099f\u09bf \u09b9\u09b2 1-{0}. +selectSelectionNotGiven=\u0986\u09aa\u09a8\u09bf \u09aa\u09cd\u09b0\u09a5\u09ae \u09a5\u09c7\u0995\u09c7 \u09aa\u099b\u09a8\u09cd\u09a6 \u0995\u09b0\u09c7 \u09a8\u09bf\u09a8 \u09a8\u09bf\u09b0\u09cd\u09ac\u09be\u099a\u09a8 \u09a6\u09c7\u0993\u09af\u09bc\u09be \u0989\u099a\u09bf\u09a4\u0964 +shuffleOn=\u09b8\u09cd\u09ac\u09aa \u0995\u09ae\u09aa\u09cd\u09b2\u09bf\u099f +shuffleOff=\u09b8\u09cd\u09ac\u09aa \u0995\u09ae\u09aa\u09cd\u09b2\u09bf\u099f. +reshufflePlaylist=\u09b8\u09be\u09b0\u09bf \u09b8\u09cd\u09a5\u09b2\u09c7\u0964. +reshufflePlayerNotShuffling=\u0986\u09aa\u09a8\u09bf \u09aa\u09cd\u09b0\u09a5\u09ae\u09c7 \u0993\u09b2\u099f\u09aa\u09be\u09b2\u099f \u0995\u09b0\u09be\u09b0 \u09ae\u09cb\u09a1 \u098f \u099a\u09be\u09b2\u09c1 \u0995\u09b0\u09a4\u09c7 \u09b9\u09ac\u09c7\u0964. +skipEmpty=\u0987\u099f \u0987\u099c \u098f\u09ae\u09cd\u09aa\u099f\u09bf\! +skipOutOfBounds=\u099f\u09cd\u09b0\u09cd\u09af\u09be\u0995 \u09a8\u09ae\u09cd\u09ac\u09b0 {0} \u09af\u0996\u09a8 {1} \u099f\u09cd\u09b0\u09be\u0995 \u098f\u0995\u09ae\u09be\u09a4\u09cd\u09b0 \u0985\u09aa\u09b8\u09be\u09b0\u09a3 \u0995\u09b0\u09a4\u09c7 \u09aa\u09be\u09b0\u099b\u09bf \u09a8\u09be\u0964. +skipNumberTooLow=\u09a8\u09ae\u09cd\u09ac\u09b0 \u09a6\u09c7\u0993\u09af\u09bc\u09be 0 \u099a\u09c7\u09af\u09bc\u09c7 \u09ac\u09c7\u09b6\u09bf \u09b9\u09ac\u09c7\u0964\! +skipSuccess=\u099f\u09cd\u09b0\u09cd\u09af\u09be\u0995 \#{0} \u098f\u09a1\u09bc\u09bf\u09af\u09bc\u09c7 \u09af\u09be\u0993\u09af\u09bc\u09be, * *{1} * * +skipRangeInvalid=Specified track range is invalid. +skipRangeSuccess=Tracks \#{0} to \#{1} have been removed. +skipTrackNotFound=Couldn't find track to skip. +stopAlreadyEmpty=The queue was already empty. +stopEmptyOne=The queue has been emptied, `1` track has been removed. +stopEmptySeveral=The queue has been emptied, `{0}` tracks have been removed. +stopAccessDenied=In order to prevent abuse, this command is only available to those who can manage messages. +unpauseQueueEmpty=The queue is empty. +unpausePlayerNotPaused=The player is not paused. +unpauseNoUsers=There are no users in the voice chat. +unpauseSuccess=The player is now unpaused. +volumeApology=Sorry\! The ;;volume command has now been deprecated on the public music bot. This is because of how it causes the bot to spend a lot more time processing audio, some tracks up to 5 times more, causing everyone to hear stutter. By disabling this feature FredBoat can play much more music without lag.\nI recommend setting the bot's volume via the dropdown menu https\://fred.moe/1vD.png +volumeSyntax=Use `;;volume <0-150>`. {0}% is the default.\nThe player is currently at **{1}%**. +volumeSuccess=Changed volume from **{0}%** to **{1}%**. +exportEmpty=Nothing to export, the queue is empty. +exportPlaylistResulted=Exported playlist\: {0}\nYou can provide this URL to play the current playlist later. +exportPlaylistFail=Failed to upload playlist to hastebin.com +listShowShuffled=Showing shuffled playlist. +listShowRepeatSingle=Repeating current track. +listShowRepeatAll=Repeating current queue. +listShowHistory=Showing tracks in history. +listAddedBy=**{0}** added by **{1}** `[{2}]` +listStreamsOnlySingle=There is **{0}** live {1} in the queue. +listStreamsOnlyMultiple=There are **{0}** live {1} in the queue. +listStreamsOrTracksSingle=There is **{0}** {1} with a remaining length of **[{2}]**{3} in the queue. +listStreamsOrTracksMultiple=There are **{0}** {1} with a remaining length of **[{2}]**{3} in the queue. +streamSingular=stream +streamPlural=streams +listAsWellAsLiveStreams=, as well as **{0}** live {1} +trackSingular=track +trackPlural=tracks +npNotPlaying=Not currently playing anything. +npNotInHistory=Currently no tracks in history. +npDescription=Description +npLoadedSoundcloud=[{0}/{1}]\n\nLoaded from Soundcloud +npLoadedBandcamp={0}\n\nLoaded from Bandcamp +npLoadedTwitch=Loaded from Twitch +permissionMissingBot=I need the following permission to perform that action\: +permissionEmbedLinks=Embed Links +rating=Rating +listeners=Listeners +year=Year +album=Album +artist=Artist +circle=Circle +npLoadedFromHTTP={0}\n\nLoaded from {1} +npLoadedDefault={0}\n\nLoaded from {1} +noneYet=None yet +npRatingRange={0}/5 from {1} vote(s) +fwdSuccess=Forwarding **{0}** by {1}. +restartSuccess=**{0}** has been restarted. +queueEmpty=The queue is empty. +rewSuccess=Rewinding **{0}** by {1}. +seekSuccess=Seeking **{0}** to {1}. +seekDeniedLiveTrack=You can't seek a live track. +loadPlaySplitListFail=That link leads to a playlist, not a track. Try `;;play` instead. +loadListSuccess=Found and added `{0}` songs from playlist **{1}**. +loadNoMatches=No audio could be found for `{0}`. +loadSplitNotYouTube=This is not a YouTube track. Only YouTube tracks are supported with the `;;split` command. Try using `;;play` instead. +loadSplitNotResolves=Couldn't resolve that video's tracklist. Try using `;;play` instead. +loadFollowingTracksAdded=The following tracks were added\: +loadPlaylistTooMany=Added {0} tracks. Found too many tracks to display. +loadErrorCommon=Error occurred when loading info for `{0}`\:\n{1} +loadErrorSusp=Suspicious error when loading info for `{0}`. +loadQueueTrackLimit=You can''t add tracks to a queue with more than {0} tracks\! This is to prevent abuse. +loadAnnouncePlaylist=About to load playlist **{0}** with up to `{1}` tracks. This may take a while, please be patient. +playerUserNotInChannel=You must join a voice channel first. +playerJoinConnectDenied=I am not permitted to connect to that voice channel. +playerJoinSpeakDenied=I am not permitted to play music in that voice channel. +playerNotInChannel=Not currently in a channel. +playerLeftChannel=Left channel {0}. +shutdownUpdating=FredBoat\u266a\u266a is updating. This should only take a minute and will reload the current playlist. +shutdownRestarting=FredBoat\u266a\u266a is restarting. This should only take a minute and will reload the current playlist. +shutdownIndef=FredBoat\u266a\u266a is shutting down. Once the bot comes back the current playlist will reload. +shutdownPersistenceFail=Error occurred when saving persistence file\: {0} +reloadSuccess=Reloading playlist. `{0}` tracks found. +trackAnnounce=Now playing **{0}**. +cmdAccessDenied=You are not allowed to use that command\! +utilErrorOccurred=\ an error occured \:anger\: ```java\n{0}\n +errorOccurredTooLong=An error occurred \:anger\: Error was too long to display.\n{0}.txt +errorOccurredTooLongAndUnirestException=An error occurred \:anger\: Was too long and was unable to post to Hastebin\! +malRevealAnime={0}\: Search revealed an anime.\n +malTitle={0}**Title\: **{1}\n +malEnglishTitle={0}**English\: **{1}\n +malSynonyms={0}**Synonyms\: **{1}\n +malEpisodes={0}**Episodes\: **{1}\n +malScore={0}**Score\: **{1}\n +malType={0}**Type\: **{1}\n +malStatus={0}**Status\: **{1}\n +malStartDate={0}**Start date\: **{1}\n +malEndDate={0}**End date\: **{1} +malSynopsis={0}**Synopsis\: **"{1}"\n +malUserReveal={0}\: Search revealed a user.\n +malNoResults={0}\: No results. +malUserName={0}**Name\: **{1}\n +malUrl={0}**URL\: **{1}\n +luaError=\ A Lua error occured \:anger\:\n```{0}``` +luaErrorOutputTooBig=\ Output buffer is too large \:anger\: Discord only allows 2000 characters per message, got {0} +luaTimeout=\ Function timed out \:anger\: allowed computation time is {0} seconds. +helpSuccess=Documentation has been sent to your direct messages\! +helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! +helpCommandsPromotion=Say {0} to learn what this bot can do\! +fuzzyNoResults=No such users +brainfuckCycleLimit=Program exceeded the maximum cycle count of {0} +brainfuckDataPointerOutOfBounds=Data pointer out of bounds\: {0} +brainfuckInputOOB=Input out of bounds at position\: {0} +brainfuckNoOutput=\ There was no output +weatherLocationNotFound=Unable to find location, please check your input {0}. +weatherError=Error retrieving weather for {0} +avatarSuccess=\ found it\n{0} +configNoArgs=Configuration for **{0}**\:``` +configSetTo=is now set to `{0}`. +configUnknownKey={0}\: Unknown key. +configMustBeBoolean={0}\: Value must be true or false. +modReason=Reason +modAuditLogMessage=Action issued by {0}\#{1} [{2}] +modFailUserHierarchy=You do not have a higher role than {0}. +modFailBotHierarchy=I need to have a higher role than {0}. +modBanFail=Failed to ban {0} +modKickBanFailUserPerms=You must have permission to kick and ban to be able to use this command. +modBanBotPerms=I need to have permission to ban members. +modKickBotPerms=I need to have permission to kick members. +kickSuccess=User {0}\#{1} [{2}] has been kicked. +kickFail=Failed to kick {0} +kickFailSelf=You can't kick yourself. +kickFailOwner=You can't kick the server owner. +kickFailMyself=I can't kick myself. +kickFailUserPerms=You must have permission to kick to be able to use this command. +softbanSuccess=User {0}\#{1} [{2}] has been softbanned. +softbanFailSelf=You can't softban yourself. +softbanFailOwner=You can't softban the server owner. +softbanFailMyself=I can't softban myself. +hardbanSuccess=User {0}\#{1} [{2}] has been banned. +hardbanFailSelf=You can't ban yourself. +hardbanFailOwner=You can't ban the server owner. +hardbanFailMyself=I can't ban myself. +getidSuccess=The id of this guild is {0}. The id of this text channel is {1}. +statsParagraph=\ This bot has been running for {0} days, {1} hours, {2} minutes and {3} seconds.\nThis bot has executed {4} commands this session. +statsRate={0}That''s a rate of {1} commands per hour +catgirlFail=Failed to extract image from {0} +catgirlFailConn=Failed to connect to {0} +hugBot=Thanks for the hugs \:blush\: +hugSuccess=Hugs {0}. +patBot=Thanks for the pats \:blush\: +patSuccess=Pats {0}. +rollSuccess={0} rolls around on the floor. +facedeskSuccess={0} facedesks. +langInvalidCode=The language code {0} doesn''t exist or is unsupported. +langSuccess=Switched to speaking {0}. +langInfo=FredBoat supports several user-contributed languages that you can select with this command. Admins on this server can select a language with `;;lang ` Here is the full list of supported languages\: +langDisclaimer=Translations may not be 100% accurate or complete. Missing translations may be contributed at . +loadSingleTrack=**{0}** has been added to the queue. +loadSingleTrackAndPlay=**{0}** will now play. +invite=Invite link for **{0}**\: +ratelimitedGeneralInfo=You are being rate limited\! Please slow down. +ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} +ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. +unblacklisted=Removed {0} from the blacklist. +serverinfoTitle=Info about {0}\: +serverinfoOnlineUsers=Online Users\: +serverinfoTotalUsers=Total Users\: +serverinfoRoles=Roles\: +serverinfoText=Text Channels\: +serverinfoVoice=Voice Channels\: +serverinfoGuildID=Guild ID\: +serverinfoCreationDate=Creation Date\: +serverinfoOwner=Owner\: +serverinfoVLv=Verification Level\: +userinfoTitle=Information about {0}\: +userinfoUsername=Username\: +userinfoId=ID\: +userinfoNick=Nickname\: +userinfoKnownServer=Known Servers\: +userinfoJoinDate=Join Date\: +userinfoCreationTime=Creation Date\: +userinfoBlacklisted=Blacklisted\: +skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +eventUsersLeftVC=All users have left the voice channel. The player has been paused. +eventAutoResumed=User presence detected, automatically resuming the player. +commandsFun=Fun +commandsMemes=Memes +commandsUtility=Utility +commandsModeration=Moderation +commandsMaintenance=Maintenance +commandsBotOwner=Bot owner +commandsMoreHelp=Say {0} to get more information on a specific command. +helpUnknownCommand=Unknown command. +helpDocsLocation=Documentation can be found at\: +helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: +helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! +helpNoDmCommands=You cannot send FredBoat commands through DMs. +helpCredits=Created by Fre_d and open source contributors +helpSent=Documentation has been sent to your DMs\! +helpProperUsage=Proper usage\: +helpCommandOwnerRestricted=This command is restricted to the owner of the bot. +helpConfigCommand=Show the config of this guild or adjust settings. +helpLanguageCommand=Show available languages or set a language for this guild. +helpHardbanCommand=Ban a user and delete his messages from the last 7 days. +helpKickCommand=Kick a user from this guild. +helpSoftbanCommand=Softban a user by kicking him and deleting his messages from the last 7 days. +helpMusicCommandsHeader=FredBoat Music Commands +helpJoinCommand=Make the bot join your current voice channel. +helpLeaveCommand=Make the bot leave the current voice channel. +helpPauseCommand=Pause the player. +helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlaySplitCommand=Split a YouTube video into a tracklist provided in it's description. +helpRepeatCommand=Toggle between repeat modes. +helpReshuffleCommand=Reshuffle the current queue. +helpSelectCommand=Select one of the offered tracks after a search to play. +helpShuffleCommand=Toggle shuffle mode for the current queue. +helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpStopCommand=Stop the player and clear the playlist. Reserved for moderators with Manage Messages permission. +helpUnpauseCommand=Unpause the player. +helpVolumeCommand=Changes the volume. Values are 0-150 and 100 is the default. The volume command is deprecated on the public bot. +helpExportCommand=Export the current queue to a hastebin link, can be later used as a playlist. +helpGensokyoRadioCommand=Show the current song played on gensokyoradio.net +helpListCommand=Display a list of the current songs in the playlist. +helpHistoryCommand=Display a list of the songs in playlist history. +helpNowplayingCommand=Display the currently playing song. +helpForwardCommand=Forward the track by a given amount of time. Example\: +helpRestartCommand=Restart the currently playing track. +helpRewindCommand=Rewind the track by a given amount of time. Example\: +helpSeekCommand=Set the position of the track to the given time. Example\: +helpAvatarCommand=Display the avatar of a user. +helpBrainfuckCommand=Executes Brainfuck code. Example\: +helpWeatherCommand=Display current weather by location. +helpClearCommand=Delete all messages by this bot in the last 50 messages of this channel. +helpCommandsCommand=Show available commands. +helpHelpCommand=Receive help for this bot or help for any command. +helpInviteCommand=Post invite link for this bot. +helpMALCommand=Search MyAnimeList and display an anime or profile of a user. +helpMusicHelpCommand=Show music commands and their usage. +helpSayCommand=Make the bot echo something. +helpServerInfoCommand=Display some stats about this guild. +helpUserInfoCommand=Display information about yourself or a user known to the bot. +helpPerms=Allows whitelisting members and roles for the {0} rank. +helpPrefixCommand=Set the prefix for this guild. +helpVoteSkip=Vote to skip the current song. Needs 50% of all users in the voice chat to vote. +helpMathOperationAdd=Print the sum of num1 and num2. +helpMathOperationSub=Print the difference of subtracting num2 from num1. +helpMathOperationMult=Print the product of num1*num2. +helpMathOperationDiv=Print the quotient of dividing num1 by num2. +helpMathOperationMod=Print the remainder of dividing num1 by num2. +helpMathOperationPerc=Print the percentage represented by num1 in num2. +helpMathOperationSqrt=Print the square root of num. +helpMathOperationPow=Print the result of num1^num2. +destroyDenied=You must have the manage messages permission to reset the player. +destroyHelp=Reset the player and clear the playlist. Reserved for moderators with Manage Messages permission. +destroySucc=Reset the player and cleared the queue. +listPageNum=Page **{0}** of **{1}**. +permsListTitle=Users and roles with the {0} permissions +permsAdded=Added `{0}` to `{1}`. +permsRemoved=Removed `{0}` from `{1}`. +permsFailSelfDemotion=You cannot remove this as it would render you without admin permissions\! +permsAlreadyAdded={0} already added to {1} +permsNotAdded={0} is not in {1} +fuzzyMultiple=Multiple items were found. Did you mean any of these? +fuzzyNothingFound=Nothing found for `{0}`. +cmdPermsTooLow=You don''t have permission to run this command\! This command requires `{0}` but you only have `{1}`. +playersLimited=FredBoat is currently at maximum capacity\! The bot is currently fixed to only play up to `{0}` streams, otherwise we would risk disconnecting from Discord under the network load.\nIf you want to help us increase the limit or you want to use our non-overcrowded bot, please support our work on Patreon\:\n{1}\n\nSorry for the inconvenience\! You might want to try again later. This message usually only appears at peak time. +tryLater=Please try again later. +skipUserSingle=Skipped {0} added by {1}. +skipUserMultiple=Skipped {0} tracks added by {1}. +skipUsersMultiple=Skipped {0} tracks added by {1} users. +skipUserNoTracks=None of the mentioned users have any tracks queued. +voteSkipAdded=Your vote has been added\! +voteSkipAlreadyVoted=You already voted to skip this track\! +voteSkipSkipping={0} have voted to skip. Skipping track {1}. +voteSkipNotEnough={0} have voted to skip. At least {1} needed. +voteSkipEmbedNoVotes=No votes to skip this track yet. +voteSkipEmbedVoters={0} out of {1} have voted to skip the current track +mathOperationResult=The result is +mathOperationDivisionByZeroError=I cannot divide by zero. +mathOperationInfinity=The number is too big to be displayed\! +prefix=Prefix +prefixGuild=The prefix for this guild is {0} +prefixShowAgain=You can show the prefix anytime again by mentioning me. + diff --git a/FredBoat/src/main/resources/lang/de_DE.properties b/FredBoat/src/main/resources/lang/de_DE.properties index ab251ffe9..8995a7e05 100644 --- a/FredBoat/src/main/resources/lang/de_DE.properties +++ b/FredBoat/src/main/resources/lang/de_DE.properties @@ -125,7 +125,7 @@ luaError=\ Ein Lua-Fehler ist aufgetreten \:anger\:\n```{0}``` luaErrorOutputTooBig=\ Ausgabepuffer ist zu gro\u00df \:anger\: Discord erlaubt nur 2000 Zeichen pro Nachricht, statt **{0}** luaTimeout=\ Zeit\u00fcberschreitung der Funktion. \:anger\: erlaubte Berechnungszeit betr\u00e4gt {0} Sekunden. helpSuccess=Dokumentation wurde zu Deinen Direktnachrichten gesendet\! -helpDmFailed=Konnte Dokumentation nicht senden. Bitte schaue ob du DM's aktiviert hast\! +helpDmFailed=Konnte Dokumentation nicht senden. Bitte \u00fcberpr\u00fcfe ob du DMs aktiviert hast\! helpCommandsPromotion=Sag {0}, um zu erfahren, was dieser Bot machen kann\! fuzzyNoResults=Besagter Nutzer existiert nicht brainfuckCycleLimit=Programm \u00fcberschritt die maximale Zyklenzahl von {0} @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Du benutzt diesen Command zu schnell\! Bitte warte einen ratelimitedSkipCommand=Du kannst mehr als einen Titel mit diesem Befehl \u00fcberspringen\: {0} ratelimitedGuildSlowLoadingPlaylist=Diesem Server ist es zur Zeit nicht mehr gestattet, weitere Playlists zu laden. Bitte spamme keine langen Playlists. unblacklisted={0} wurde von der Blacklist entfernt. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Infos \u00fcber {0}\: serverinfoOnlineUsers=Nutzer online\: serverinfoTotalUsers=Nutzer gesamt\: serverinfoRoles=Rollen\: @@ -193,7 +193,7 @@ serverinfoGuildID=Gilden-ID\: serverinfoCreationDate=Erstellungsdatum\: serverinfoOwner=Eigent\u00fcmer\: serverinfoVLv=Verifizierungslevel\: -userinfoTitle=Information about {0}\: +userinfoTitle=Infos \u00fcber {0}\: userinfoUsername=Benutzername\: userinfoId=ID\: userinfoNick=Spitzname\: @@ -212,11 +212,11 @@ commandsMaintenance=Wartung commandsBotOwner=Boteigent\u00fcmer commandsMoreHelp=Sag {0}, um mehr Informationen zu einem bestimmten Befehl zu erhalten. helpUnknownCommand=Unbekannter Befehl. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Die Dokumentation befindet sich hier\: +helpBotInvite=Willst du FredBoat zu deinem Server hinzuf\u00fcgen? Wenn du die "Server verwalten"-Berechtigung f\u00fcr deine Gilde hast, kannst du FredBoat einladen\: +helpHangoutInvite=Brauchst du Hilfe oder hast du irgendwelche Ideen f\u00fcr FredBoat? Vielleicht willst du nur abh\u00e4ngen? Tritt der FredBoat-Community bei\! +helpNoDmCommands=Du kannst FredBoat keine Befehle per DM senden. +helpCredits=Erstellt von Fre_d und Open-Source-Mitwirkenden helpSent=Die Dokumentation wurde dir privat zugesendet\! helpProperUsage=Ordnungsgem\u00e4\u00dfe Verwendung\: helpCommandOwnerRestricted=Dieser Befehl beschr\u00e4nkt sich auf den Besitzer des Bots. diff --git a/FredBoat/src/main/resources/lang/el_GR.properties b/FredBoat/src/main/resources/lang/el_GR.properties index a6e0744e8..21be1d880 100644 --- a/FredBoat/src/main/resources/lang/el_GR.properties +++ b/FredBoat/src/main/resources/lang/el_GR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u0388\u03c7\u03b5\u03c4\u03b5 \u03c6\u03c4\u03ac\u03c3\u ratelimitedSkipCommand=\u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c2 \u03bd\u03b1 \u03c0\u03b1\u03c1\u03b1\u03bb\u03b5\u03af\u03c8\u03b5\u03b9\u03c2 \u03c0\u03bf\u03bb\u03bb\u03ac \u03c4\u03c1\u03b1\u03b3\u03bf\u03cd\u03b4\u03b9\u03b1 \u03bc\u03b5 \u03c4\u03b7\u03bd \u03b5\u03bd\u03c4\u03bf\u03bb\u03ae {0} ratelimitedGuildSlowLoadingPlaylist=\u0391\u03c5\u03c4\u03cc\u03c2 \u03bf \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae\u03c2 \u03b4\u03b5\u03bd \u03b5\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c3\u03b5\u03c4\u03b5 \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03bb\u03af\u03c3\u03c4\u03b5\u03c2 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2 \u03b1\u03c5\u03c4\u03ae \u03c4\u03b7 \u03c3\u03c4\u03b9\u03b3\u03bc\u03ae. \u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03bc\u03b7\u03bd spam\u03ac\u03c1\u03b5\u03c4\u03b5 \u03bc\u03b5\u03b3\u03ac\u03bb\u03b5\u03c2 \u03bb\u03af\u03c3\u03c4\u03b5\u03c2 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2. unblacklisted=\u0391\u03c6\u03b1\u03b9\u03c1\u03b5\u03b8\u03b5\u03af\u03ba\u03b5 {0} \u03b1\u03c0\u03cc \u03c4\u03b7 \u03bc\u03b1\u03cd\u03c1\u03b7 \u03bb\u03af\u03c3\u03c4\u03b1. -serverinfoTitle=Info about {0}\: +serverinfoTitle=\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03bf **{0} **\: serverinfoOnlineUsers=\u03a3\u03c5\u03bd\u03b4\u03b5\u03b4\u03b5\u03bc\u03ad\u03bd\u03bf\u03b9 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b5\u03c2\: serverinfoTotalUsers=\u03a3\u03cd\u03bd\u03bf\u03bb\u03bf \u03a7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd\: serverinfoRoles=\u03a1\u03cc\u03bb\u03bf\u03b9\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=\u0397\u03bc\u03b5\u03c1\u03bf\u03bc\u03b7\u03bd\u03af\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1\u03c2\: serverinfoOwner=\u0399\u03b4\u03b9\u03bf\u03ba\u03c4\u03ae\u03c4\u03b7\u03c2\: serverinfoVLv=\u0395\u03c0\u03af\u03c0\u03b5\u03b4\u03bf \u03b5\u03c0\u03b1\u03bb\u03ae\u03b8\u03b5\u03c5\u03c3\u03b7\u03c2\: -userinfoTitle=Information about {0}\: +userinfoTitle=\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03c4\u03bf **{0} **\: userinfoUsername=\u038c\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\: userinfoId=\u0391\u039d\u0391\u0393\u039d\u03a9\u03a1\u0399\u03a3\u03a4\u0399\u039a\u038c\: userinfoNick=\u03a8\u03b5\u03c5\u03b4\u03ce\u03bd\u03c5\u03bc\u03bf\: @@ -212,11 +212,11 @@ commandsMaintenance=\u03a3\u03c5\u03bd\u03c4\u03ae\u03c1\u03b7\u03c3\u03b7 commandsBotOwner=\u0399\u03b4\u03b9\u03bf\u03ba\u03c4\u03ae\u03c4\u03b7\u03c2 bot commandsMoreHelp=\u03a0\u03b5\u03af\u03c4\u03b5 {0} \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03c0\u03ac\u03c1\u03b5\u03c4\u03b5 \u03c0\u03b5\u03c1\u03b9\u03c3\u03c3\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03c3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac \u03bc\u03b5 \u03bc\u03b9\u03b1 \u03c3\u03c5\u03b3\u03ba\u03b5\u03ba\u03c1\u03b9\u03bc\u03ad\u03bd\u03b7 \u03b5\u03bd\u03c4\u03bf\u03bb\u03ae. helpUnknownCommand=\u0386\u03b3\u03bd\u03c9\u03c3\u03c4\u03b7 \u0395\u03bd\u03c4\u03bf\u03bb\u03ae. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=\u03a4\u03b5\u03ba\u03bc\u03b7\u03c1\u03af\u03c9\u03c3\u03b7 \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b2\u03c1\u03b5\u03b8\u03b5\u03af \u03c3\u03b5\: +helpBotInvite=\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03b8\u03ad\u03c3\u03b5\u03c4\u03b5 FredBoat \u03c3\u03c4\u03bf \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae \u03c3\u03b1\u03c2; \u0395\u03ac\u03bd \u03ad\u03c7\u03b5\u03c4\u03b5 \u03b4\u03b9\u03ba\u03b1\u03b9\u03ce\u03bc\u03b1\u03c4\u03b1 \u03b4\u03b9\u03b1\u03c7\u03b5\u03af\u03c1\u03b9\u03c3\u03b7\u03c2 \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae \u03b3\u03b9\u03b1 \u03c4\u03b7\u03bd \u03c3\u03c5\u03bd\u03c4\u03b5\u03c7\u03bd\u03af\u03b1 \u03c3\u03b1\u03c2, \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03ba\u03b1\u03bb\u03ad\u03c3\u03b5\u03c4\u03b5 FredBoat\: +helpHangoutInvite=\u03a7\u03c1\u03b5\u03b9\u03ac\u03b6\u03b5\u03c3\u03c4\u03b5 \u03b2\u03bf\u03ae\u03b8\u03b5\u03b9\u03b1 \u03ae \u03ad\u03c7\u03b5\u03c4\u03b5 \u03bf\u03c0\u03bf\u03b9\u03b5\u03c3\u03b4\u03ae\u03c0\u03bf\u03c4\u03b5 \u03b9\u03b4\u03ad\u03b5\u03c2 \u03b3\u03b9\u03b1 FredBoat; \u038a\u03c3\u03c9\u03c2 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03b1\u03ba\u03c1\u03b9\u03b2\u03ce\u03c2 \u03bd\u03b1 \u03ba\u03c1\u03b5\u03bc\u03ac\u03c3\u03b5\u03b9 \u03ad\u03be\u03c9; \u0393\u03af\u03bd\u03b5\u03c4\u03b5 \u03bc\u03ad\u03bb\u03bf\u03c2 \u03c4\u03b7\u03c2 \u039a\u03bf\u03b9\u03bd\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 FredBoat\! +helpNoDmCommands=\u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c4\u03b5\u03af\u03bb\u03b5\u03c4\u03b5 FredBoat \u03b5\u03bd\u03c4\u03bf\u03bb\u03ad\u03c2 \u03bc\u03ad\u03c3\u03c9 DMs. +helpCredits=\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03b8\u03b7\u03ba\u03b5 \u03b1\u03c0\u03cc Fre_d \u03ba\u03b1\u03b9 \u03b1\u03bd\u03bf\u03b9\u03ba\u03c4\u03bf\u03cd\u03c2 \u03c0\u03b7\u03b3\u03b1\u03af\u03bf\u03c5\u03c2 helpSent=\u0397 \u03c4\u03b5\u03ba\u03bc\u03b7\u03c1\u03af\u03c9\u03c3\u03b7 \u03ad\u03c7\u03b5\u03b9 \u03b1\u03c0\u03bf\u03c3\u03c4\u03b1\u03bb\u03b5\u03af \u03c3\u03c4\u03bf DM \u03c3\u03b1\u03c2\! helpProperUsage=\u03a3\u03c9\u03c3\u03c4\u03ae \u03c7\u03c1\u03ae\u03c3\u03b7\: helpCommandOwnerRestricted=\u0391\u03c5\u03c4\u03ae \u03b7 \u03b5\u03bd\u03c4\u03bf\u03bb\u03ae \u03b5\u03af\u03bd\u03b1\u03b9 \u03c0\u03b5\u03c1\u03b9\u03bf\u03c1\u03b9\u03c3\u03bc\u03ad\u03bd\u03b7 \u03c3\u03c4\u03bf\u03bd \u03b9\u03b4\u03b9\u03bf\u03ba\u03c4\u03ae\u03c4\u03b7 \u03c4\u03bf\u03c5 bot. diff --git a/FredBoat/src/main/resources/lang/en_PT.properties b/FredBoat/src/main/resources/lang/en_PT.properties index 813e783c8..f92062410 100644 --- a/FredBoat/src/main/resources/lang/en_PT.properties +++ b/FredBoat/src/main/resources/lang/en_PT.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=You are being rate limited\! Please slow down. ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Tales ''bout {0}\: serverinfoOnlineUsers=Lively hands\: serverinfoTotalUsers=All ye mates\: serverinfoRoles=Ranks\: @@ -211,7 +211,7 @@ commandsModeration=Captains commandsMaintenance=Maintenance commandsBotOwner=Bot owner commandsMoreHelp=Say {0} to get more information on a specific command. -helpUnknownCommand=Unknown command. +helpUnknownCommand=The crew dunno yer order. helpDocsLocation=Documentation can be found at\: helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! diff --git a/FredBoat/src/main/resources/lang/es_ES.properties b/FredBoat/src/main/resources/lang/es_ES.properties index 277bfb425..5a9da4dd2 100644 --- a/FredBoat/src/main/resources/lang/es_ES.properties +++ b/FredBoat/src/main/resources/lang/es_ES.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u00a1Estas llegando al limite\! Por favor, c\u00e1lmate. ratelimitedSkipCommand=Puedes omitir m\u00e1s de una canci\u00f3n usando este comando\: {0} ratelimitedGuildSlowLoadingPlaylist=Este servidor no est\u00e1 permitido a\u00f1adir m\u00e1s listas en este momento. Por favor no a\u00f1adas largas listas de reproducci\u00f3n. unblacklisted={0} fue eliminado de la lista negra. -serverinfoTitle=Info about {0}\: +serverinfoTitle=informaci\u00f3n sobre {0}\: serverinfoOnlineUsers=Usuarios en l\u00ednea\: serverinfoTotalUsers=Usuarios totales\: serverinfoRoles=Roles\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID del servidor\: serverinfoCreationDate=Fecha de creaci\u00f3n\: serverinfoOwner=Due\u00f1o\: serverinfoVLv=Nivel de verificaci\u00f3n\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informaci\u00f3n sobre {0}\: userinfoUsername=Nombre de usuario\: userinfoId=ID\: userinfoNick=Apodo\: @@ -212,11 +212,11 @@ commandsMaintenance=Mantenimiento commandsBotOwner=Due\u00f1o del bot commandsMoreHelp=Di {0} para obtener m\u00e1s informaci\u00f3n sobre un comando espec\u00edfico. helpUnknownCommand=Comando desconocido. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Documentaci\u00f3n se puede contrar en\: +helpBotInvite="Quieres agregar FredBoat a tu servidor? Si tienes permisos administrativos en tu servidor, puedes invitar a FredBoat"\: +helpHangoutInvite=Necesitas ayuda o tienes algun idea para FredBoat? Ta vez s\u00f3lo quieres pasar el rato? \u00danete a la communidad de FredBoat\! +helpNoDmCommands=Usted no puede mandar FredBoat commandos a trav\u00e9s de DMs. +helpCredits=Creado por Fr_ed y de abierto c\u00f3digo colaboradores helpSent=\u00a1La documentaci\u00f3n ha sido enviada a tus mensajes privados\! helpProperUsage=Uso correcto\: helpCommandOwnerRestricted=Este comando se limita al due\u00f1o del bot. diff --git a/FredBoat/src/main/resources/lang/fi_FI.properties b/FredBoat/src/main/resources/lang/fi_FI.properties index eee789ee8..73f78187b 100644 --- a/FredBoat/src/main/resources/lang/fi_FI.properties +++ b/FredBoat/src/main/resources/lang/fi_FI.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Sinut on rajoitettu k\u00e4ytt\u00e4m\u00e4st\u00e4 liika ratelimitedSkipCommand=Voit ohittaa useamman kuin yhden kappaleen k\u00e4ytt\u00e4m\u00e4ll\u00e4 t\u00e4t\u00e4 komentoa\: {0} ratelimitedGuildSlowLoadingPlaylist=T\u00e4m\u00e4 serveri ei saa lis\u00e4t\u00e4 yht\u00e4\u00e4n enemp\u00e4\u00e4 soittolistaa t\u00e4ll\u00e4 hetkell\u00e4. \u00c4l\u00e4 lis\u00e4\u00e4 ylti\u00f6m\u00e4\u00e4r\u00e4\u00e4 pitki\u00e4 soittolistoja. unblacklisted={0} poistettiin mustalta listalta. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Tietoja t\u00e4st\u00e4 serverist\u00e4 {0}\: serverinfoOnlineUsers=K\u00e4ytt\u00e4ji\u00e4 paikalla\: serverinfoTotalUsers=K\u00e4ytt\u00e4ji\u00e4 yhteens\u00e4\: serverinfoRoles=Roolit\: @@ -193,7 +193,7 @@ serverinfoGuildID=Palvelimen tunniste\: serverinfoCreationDate=Luontip\u00e4iv\u00e4m\u00e4\u00e4r\u00e4\: serverinfoOwner=Omistaja\: serverinfoVLv=Vahvistustaso\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informaatio {0}\: userinfoUsername=K\u00e4ytt\u00e4j\u00e4nimi\: userinfoId=Tunnus\: userinfoNick=Nimimerkki\: @@ -212,11 +212,11 @@ commandsMaintenance=Huolto commandsBotOwner=Botin omistaja commandsMoreHelp=Sano {0} saadaksesi lis\u00e4tietoa tietyst\u00e4 komennosta. helpUnknownCommand=Tuntematon komento. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Dokumentit l\u00f6yt\u00e4\u00e4\: +helpBotInvite=Haluatko lis\u00e4t\u00e4 FredBoatin serverillesi? Jos sinulla on Serverin Muutto oikeudet, voit lis\u00e4t\u00e4 FredBoatin\: +helpHangoutInvite=Tarvitko apua tai ideoita FredBoattia varten? Vai haluatko vain hengailla? Liity FredBoatin ryhm\u00e4\u00e4n\! +helpNoDmCommands=Et voi l\u00e4hett\u00e4\u00e4 FredBoatille komentoja yksityisviestill\u00e4. +helpCredits=Tekij\u00e4\: Fre_d ja avoimenl\u00e4hteen avustajat helpSent=Dokumentaatio on l\u00e4hetetty sinun yksityisviesteihisi\! helpProperUsage=Asianmukainen k\u00e4ytt\u00f6\: helpCommandOwnerRestricted=T\u00e4m\u00e4 komento on rajoitettu vain botin omistajalle. @@ -235,14 +235,14 @@ helpRepeatCommand=Vaihda toistomuotojen v\u00e4lill\u00e4. helpReshuffleCommand=Sekoita nykyinen soittolista. helpSelectCommand=Valitse yksi tarjotuista kappaleista haun j\u00e4lkeen soittaaksesi sen. helpShuffleCommand=Vaihda sekoitustila p\u00e4\u00e4lle nykyiselle soittolistalle. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpSkipCommand=Ohita nykyinen laulu, Muut laulut jonosta, tai kaikki laulut. K\u00e4yt\u00e4 moderaattorina. helpStopCommand=Pys\u00e4yt\u00e4 soitin ja raivaa t\u00e4m\u00e4nhetkinen soittolista. K\u00e4yt\u00f6ss\u00e4 moderaattoreille jotka pystyv\u00e4t hallitsemaan viestej\u00e4. helpUnpauseCommand=Anna soittimen jatkaa. helpVolumeCommand=S\u00e4\u00e4t\u00e4 \u00e4\u00e4nenvoimakkuutta. Arvot ovat 0-150 ja 100 on oletusarvo. \u00c4\u00e4nenvoimakkuus komento on poistettu k\u00e4yt\u00f6st\u00e4 julkisella botilla. helpExportCommand=Vie t\u00e4m\u00e4nhetkinen soittolista hastebin linkkiin, jotta voit k\u00e4ytt\u00e4\u00e4 sit\u00e4 my\u00f6hemmin soittolistana. helpGensokyoRadioCommand=N\u00e4yt\u00e4 t\u00e4m\u00e4nhetkinen kappale gensokyoradio.netiss\u00e4 helpListCommand=N\u00e4yt\u00e4 luettelo t\u00e4m\u00e4nhetkisist\u00e4 kappaleista soittolistassa. -helpHistoryCommand=Display a list of the songs in playlist history. +helpHistoryCommand=N\u00e4yt\u00e4 lista musiikeista soittohistoriassa. helpNowplayingCommand=N\u00e4yt\u00e4 parhaillaan toistettava kappale. helpForwardCommand=Vie kappaletta eteenp\u00e4in tietyll\u00e4 m\u00e4\u00e4r\u00e4ll\u00e4 aikaa. Esimerkiksi\: helpRestartCommand=K\u00e4ynnist\u00e4 parhaillaan soiva kappale uudelleen. @@ -261,16 +261,16 @@ helpSayCommand=Laita botti toistamaan jotain kaikuna. helpServerInfoCommand=N\u00e4yt\u00e4 joitakin tilastoja t\u00e4st\u00e4 killasta. helpUserInfoCommand=N\u00e4yt\u00e4 tietoja itsest\u00e4si tai botin tiedossa olevista k\u00e4ytt\u00e4jist\u00e4. helpPerms=Sallii k\u00e4ytt\u00e4jien ja roolien valkolistaamisen {0} arvolle. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=Aseta etuliite t\u00e4lle ryhm\u00e4lle. helpVoteSkip=\u00c4\u00e4nest\u00e4 skipataksesi biisi. 50% k\u00e4ytt\u00e4jist\u00e4 puhekanavalle t\u00e4ytyy \u00e4\u00e4nest\u00e4\u00e4. helpMathOperationAdd=Laske numero 1 + numero 2. -helpMathOperationSub=Print the difference of subtracting num2 from num1. -helpMathOperationMult=Print the product of num1*num2. -helpMathOperationDiv=Print the quotient of dividing num1 by num2. -helpMathOperationMod=Print the remainder of dividing num1 by num2. -helpMathOperationPerc=Print the percentage represented by num1 in num2. -helpMathOperationSqrt=Print the square root of num. -helpMathOperationPow=Print the result of num1^num2. +helpMathOperationSub=Muuta ero numero 2\:n v\u00e4henemisest\u00e4 numero 1\:seen +helpMathOperationMult=Muunna numero 1\: sen ja numero 2\: sen ero. +helpMathOperationDiv=Munna numero 1\: sen ja numero 2\: sen jakautuminen. +helpMathOperationMod=Muunna nykyinen tulos jaetun kanssa. +helpMathOperationPerc=Muunna numeron 1 ja 2 prosenttiosuus. +helpMathOperationSqrt=Muunna numeroiden neli\u00f6juuri. +helpMathOperationPow=Muunna numero 1\: sen ja 2\: sen ero. destroyDenied=Sinulla pit\u00e4\u00e4 olla hallitse viestej\u00e4 oikeus nollataksesi soittimen. destroyHelp=Nollaa soitin ja tyhjenn\u00e4 jono. Tarkoitettu yll\u00e4pit\u00e4jille joilla on hallitse viestej\u00e4 oikeus. destroySucc=Soitin on nollattu ja jono tyhjennetty. @@ -279,27 +279,27 @@ permsListTitle=K\u00e4ytt\u00e4j\u00e4t ja roolit joilla on oikeus\: {0} permsAdded=Lis\u00e4ttiin `{0}` kohteeseen `{1}`. permsRemoved=Poistettiin `{0}`kohteesta `{1}`. permsFailSelfDemotion=Et voi poistaa t\u00e4t\u00e4, koska se poistaisi sinulta j\u00e4rjestelm\u00e4valvojan oikeuden\! -permsAlreadyAdded={0} already added to {1} -permsNotAdded={0} is not in {1} +permsAlreadyAdded={0} on jo lis\u00e4tty {1} +permsNotAdded={0} ei ole {1} fuzzyMultiple=L\u00f6ydettiin useita kohteita. Tarkoititko mit\u00e4\u00e4n n\u00e4ist\u00e4? fuzzyNothingFound=Ei tuloksia haulla `{0}`. cmdPermsTooLow=Sinulla ei ole tarvittavia oikeuksia kyseisen komennon k\u00e4ytt\u00e4miseen\! T\u00e4m\u00e4 komento vaatii `{0}`, mutta sinulla on vain `{1}`. -playersLimited=FredBoat is currently at maximum capacity\! The bot is currently fixed to only play up to `{0}` streams, otherwise we would risk disconnecting from Discord under the network load.\nIf you want to help us increase the limit or you want to use our non-overcrowded bot, please support our work on Patreon\:\n{1}\n\nSorry for the inconvenience\! You might want to try again later. This message usually only appears at peak time. +playersLimited=FredBoat on t\u00e4ll\u00e4 hetkell\u00e4 t\u00e4ynn\u00e4. Botti on t\u00e4ll\u00e4 hetkell\u00e4 korjattavana ja voi toistaa yli `{0}`\nStriimi\u00e4, muuten se voi menett\u00e4\u00e4 yhteytens\u00e4 discordiin netti loadin alla. Jos haluat meid\u00e4n lis\u00e4\u00e4v\u00e4n maksimim\u00e4\u00e4r\u00e4\u00e4 tai haluat k\u00e4ytt\u00e4\u00e4 loputonta m\u00e4\u00e4r\u00e4\u00e4, Ota yhteytt\u00e4 Patreoniin\:\n{1}\n\nAnteeksi h\u00e4iri\u00f6st\u00e4\! Voit yritt\u00e4\u00e4 pian uudelleen. T\u00e4m\u00e4 viesti yleens\u00e4 tulee vain aikana, jolloin botti kaatuu. tryLater=Yrit\u00e4 uudestaan my\u00f6hemmin. -skipUserSingle=Skipped {0} added by {1}. -skipUserMultiple=Skipped {0} tracks added by {1}. -skipUsersMultiple=Skipped {0} tracks added by {1} users. -skipUserNoTracks=None of the mentioned users have any tracks queued. +skipUserSingle=Skipattu {0} ja lis\u00e4tty {1}. +skipUserMultiple=Skipattu {0} Musiikkej\u00e4 lis\u00e4si\: {1}. +skipUsersMultiple=Skipattu {0} Musiikkeja lis\u00e4tty {1} k\u00e4ytt\u00e4j\u00e4. +skipUserNoTracks=Yksik\u00e4\u00e4n mainituista k\u00e4ytt\u00e4jist\u00e4 ei omista lauluja musiikkijonossa. voteSkipAdded=\u00c4\u00e4nesi on otettu huomioon\! voteSkipAlreadyVoted=\u00c4\u00e4nestit jo skipataksesi t\u00e4m\u00e4n biisin\! voteSkipSkipping={0} ihmist\u00e4 on \u00e4\u00e4nest\u00e4nyt ohittamista. Ohitetaan biisi {1}. voteSkipNotEnough={0} \u00e4\u00e4nesti ohitusta. V\u00e4hint\u00e4\u00e4n {1} tarvitaan. voteSkipEmbedNoVotes=Ei \u00e4\u00e4ni\u00e4 ohittaa biisi\u00e4 viel\u00e4. -voteSkipEmbedVoters={0} out of {1} have voted to skip the current track +voteSkipEmbedVoters={0} pois {1} on ehdottanut ohittaa nykyist\u00e4 laulua mathOperationResult=Tulos on mathOperationDivisionByZeroError=En voi jakaa nollalla. -mathOperationInfinity=The number is too big to be displayed\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +mathOperationInfinity=Numero on liian iso n\u00e4ytett\u00e4v\u00e4ksi\! +prefix=Etuliite +prefixGuild=T\u00e4m\u00e4n ryhm\u00e4n etuliite on {0} +prefixShowAgain=Voit n\u00e4ytt\u00e4\u00e4 etuliitteen aina, mainitsemalla minut. diff --git a/FredBoat/src/main/resources/lang/fil_PH.properties b/FredBoat/src/main/resources/lang/fil_PH.properties index a8cb884ca..2298dbde3 100644 --- a/FredBoat/src/main/resources/lang/fil_PH.properties +++ b/FredBoat/src/main/resources/lang/fil_PH.properties @@ -45,7 +45,7 @@ exportPlaylistFail=Hindi na upload ang mga tugtog sa hastebin.com listShowShuffled=Pinapakita ang halohalong tugtogan. listShowRepeatSingle=Uulitin ang kasalukuyang track. listShowRepeatAll=Uulitin ang kasalukuyang mga nakalista. -listShowHistory=Showing tracks in history. +listShowHistory=Pagpapakita ng bakas sa kasaysayan. listAddedBy=**{0}** idinagdag ni **{1}** `[{2}]` listStreamsOnlySingle=Merong **{0}** live {1} sa loob ng listahan. listStreamsOnlyMultiple=Merong mga **{0}** live {1} sa loob ng listahan. @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=, pati * *{0} * * live {1} trackSingular=subaybayan ang trackPlural=mga track npNotPlaying=Kasalukuyang hindi nag plaplay ng kahit ano. -npNotInHistory=Currently no tracks in history. +npNotInHistory=Kasalukuyang walang bakas sa kasaysayan. npDescription=Description npLoadedSoundcloud=[{0}/{1}]\n\nNakuha mula sa Soundcloud npLoadedBandcamp={0}\n\nNakuha mula sa Bandcamp @@ -74,7 +74,7 @@ npLoadedFromHTTP={0}\n\nNakuha mula sa {1} npLoadedDefault={0}\n\nNakuha mula sa {1} noneYet=Wala pa npRatingRange={0}/5 galing sa {1} boto -fwdSuccess=Forwarding **{0}** by {1}. +fwdSuccess=Pagpapasulong ng **{0}** sa {1}. restartSuccess=* *{0} * * ay na-restart na. queueEmpty=Walang nakalagay sa listahan. rewSuccess=Ni-rerewind ang * *{0} * * ng {1}. @@ -124,146 +124,146 @@ malUrl={0}**URL\: **{1}\n luaError=\ Nagkaroon ng isang error ng Lua ang \:anger\: '' ''{0} '' '' luaErrorOutputTooBig=\ Masyadong malaki ang output buffer \:anger\: Ang Discord ay nagpapahintulot lamang ng 2000 na characters kada message, mayroong {0} luaTimeout=\ Nag-time out ang function \:anger\: Ang pinahintulutuang computation time ay {0} segundo. -helpSuccess=Documentation has been sent to your direct messages\! -helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! -helpCommandsPromotion=Say {0} to learn what this bot can do\! +helpSuccess=Ang dokumentasyon ay ipinadala direkta sa inyong mensahe\! +helpDmFailed=Maaaring hindi kayang magpadala ng dokumentasyon sa inyong DMs. Pakiusap pakitignan na wala sa kanilang may kapansanan\! +helpCommandsPromotion=Sabihin {0} para malaman kung anong kayang gawin ng bot na ito\! fuzzyNoResults=Walang ganitong mga gumagamit -brainfuckCycleLimit=Program exceeded the maximum cycle count of {0} -brainfuckDataPointerOutOfBounds=Data pointer out of bounds\: {0} -brainfuckInputOOB=Input out of bounds at position\: {0} -brainfuckNoOutput=\ There was no output -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} -avatarSuccess=\ found it\n{0} -configNoArgs=Configuration for **{0}**\:``` -configSetTo=is now set to `{0}`. -configUnknownKey={0}\: Unknown key. -configMustBeBoolean={0}\: Value must be true or false. -modReason=Reason -modAuditLogMessage=Action issued by {0}\#{1} [{2}] -modFailUserHierarchy=You do not have a higher role than {0}. -modFailBotHierarchy=I need to have a higher role than {0}. -modBanFail=Failed to ban {0} -modKickBanFailUserPerms=You must have permission to kick and ban to be able to use this command. -modBanBotPerms=I need to have permission to ban members. -modKickBotPerms=I need to have permission to kick members. -kickSuccess=User {0}\#{1} [{2}] has been kicked. -kickFail=Failed to kick {0} -kickFailSelf=You can't kick yourself. -kickFailOwner=You can't kick the server owner. -kickFailMyself=I can't kick myself. -kickFailUserPerms=You must have permission to kick to be able to use this command. -softbanSuccess=User {0}\#{1} [{2}] has been softbanned. -softbanFailSelf=You can't softban yourself. -softbanFailOwner=You can't softban the server owner. -softbanFailMyself=I can't softban myself. -hardbanSuccess=User {0}\#{1} [{2}] has been banned. -hardbanFailSelf=You can't ban yourself. -hardbanFailOwner=You can't ban the server owner. -hardbanFailMyself=I can't ban myself. -getidSuccess=The id of this guild is {0}. The id of this text channel is {1}. -statsParagraph=\ This bot has been running for {0} days, {1} hours, {2} minutes and {3} seconds.\nThis bot has executed {4} commands this session. -statsRate={0}That''s a rate of {1} commands per hour -catgirlFail=Failed to extract image from {0} -catgirlFailConn=Failed to connect to {0} -hugBot=Thanks for the hugs \:blush\: -hugSuccess=Hugs {0}. -patBot=Thanks for the pats \:blush\: -patSuccess=Pats {0}. -rollSuccess={0} rolls around on the floor. -facedeskSuccess={0} facedesks. -langInvalidCode=The language code {0} doesn''t exist or is unsupported. -langSuccess=Switched to speaking {0}. -langInfo=FredBoat supports several user-contributed languages that you can select with this command. Admins on this server can select a language with `;;lang ` Here is the full list of supported languages\: -langDisclaimer=Translations may not be 100% accurate or complete. Missing translations may be contributed at . -loadSingleTrack=**{0}** has been added to the queue. -loadSingleTrackAndPlay=**{0}** will now play. -invite=Invite link for **{0}**\: -ratelimitedGeneralInfo=You are being rate limited\! Please slow down. -ratelimitedSkipCommand=You can skip more than one song by using this command\: {0} -ratelimitedGuildSlowLoadingPlaylist=This server is not allowed to add more playlists at this moment. Please don't spam long playlists. -unblacklisted=Removed {0} from the blacklist. -serverinfoTitle=Info about {0}\: -serverinfoOnlineUsers=Online Users\: -serverinfoTotalUsers=Total Users\: +brainfuckCycleLimit=Ang programa ay lumagpas sa pinakamataas na siklo ng pagbibilang {0} +brainfuckDataPointerOutOfBounds=Ang panturo ng datos ay lumabas sa mga hanggan\: {0} +brainfuckInputOOB=Mag input sa labas ng mga posisyon ng mg hangganan\: {0} +brainfuckNoOutput=\ Diyan ay walang output +weatherLocationNotFound=Hindi makita ang inyong lokasyon, Pakiusap pakitignan ang inyong input {0}. +weatherError=Maling pagkuha para sa panahon {0} +avatarSuccess=\ natagpuan ito {0} +configNoArgs=Kompigurasyon para sa **{0}**\:``` +configSetTo=ito ay nakatakda na ngayon `{0}`. +configUnknownKey={0}\: Hindi kilala na susi. +configMustBeBoolean={0}\: Ang halaga ay kailangan tama or mali. +modReason=Dahilan +modAuditLogMessage=Mula sa aksyon na inilabas ng {0}\#{1} [{2}] +modFailUserHierarchy=Wala ka ng mataas na tungkulin kasya sa {0}. +modFailBotHierarchy=Kailangan kong magkaroon ng mas mataas na tungkulin kaysa sa {0}. +modBanFail=Nabigo sa pagbabawal sa {0} +modKickBanFailUserPerms=Kailangan mong magkaroon ng pahintulot na sipain at pagbawalan upang hindi magamit ang kautosang ito. +modBanBotPerms=Kailangan kong magkaroon ng pahintulot para pagbawalan ang mga miyembro. +modKickBotPerms=Kailangan kong magkaroon ng pahintulot para sipain ang mga miyembro. +kickSuccess=Ang mga gumagamit ng {0}\#{1} [{2}] ay pinagsisipa. +kickFail=Nabigo sa pagsipa {0} +kickFailSelf=Hindi mo kayang sipain ang iyong sarili. +kickFailOwner=Hindi mo kayang sipain ang may ari ng serber. +kickFailMyself=Hindi ko kayang sipain ang aking sarili. +kickFailUserPerms=Kailangan mong magkaroon ng pahintulot na sipain at pagbawalan upang hindi magamit ang kautosang ito. +softbanSuccess=Ang gumagamit {0}\#{1} [{2}] ay pansamatalang pinagbawalan. +softbanFailSelf=Hindi mo kayang pansamantalang pagbawalan ang iyong sarili. +softbanFailOwner=Hindi mo kayang pansamantalang pagbawalan ang may ari ng serber. +softbanFailMyself=Hindi ko kayang pagbawalan ng pansamantala ang aking sarili. +hardbanSuccess=Ang mga gumagamit ng {0}\#{1} [{2}] ay pinagbawalan. +hardbanFailSelf=Hindi mo kayang pagbawalan ang iyong sarili. +hardbanFailOwner=Hindi mo kayang pagbawalan ang may ari ng serber. +hardbanFailMyself=Hindi ko kayang pagbawalan ang aking sarili. +getidSuccess=Ang id ng mga samahan ay {0}. Ang id ng tsanel ng tekstong ito ay {1}. +statsParagraph=\ Ang bot na ito ay tumatakbo para sa {0} araw, {1} oras, {2} minuto at {3} segundo. Ang bot na ito ay magsasagawa ng {4} utos sa sesyong ito. +statsRate={0} Yan ang halaga ng {1} ng utos kada oras +catgirlFail=Nabigo sa paghugot ng larawan mula sa {0} +catgirlFailConn=Nabigong kumoknekta sa {0} +hugBot=Maraming salamat sa mga yakap \:blush\: +hugSuccess=Mga yakap {0}. +patBot=Maraming salamat sa pagtapik \:blush\: +patSuccess=Mga tapik {0}. +rollSuccess={0} gumulong sa palibot ng sahig. +facedeskSuccess={0} mukhasulatan. +langInvalidCode=Ang kowd para sa lengwahe {0} ay hindi umiiral o kaya ay hindi suportado. +langSuccess=Lumipat para sa pagsasalit {0}. +langInfo=Ang FredBoat ay sinusuportahan ang mga gumagamit, nag-ambag ng wikang iyong mapipili sa komandong ito. Ang taga pangasiwa sa serber na ito ay may kakayahang pumili ng wika ng `;;lang ` Ito ang kabuoang listahan ng mga suportadong wika\: +langDisclaimer=Ang pagpapalit ay maaaring hindi 100% na tumpak o kumpleto. Ang pagpapalit na nawawala ay maaaring naiambag dito sa . +loadSingleTrack=**{0}** ay naidagdag na sa pagpipilian. +loadSingleTrackAndPlay=**{0}** ay tumutugtog ngayon. +invite=Mag-imbita ng mga link para sa **{0}**\: +ratelimitedGeneralInfo=Ang iyong halaga ay limitado lang\! Kaya pakiusap huminahon ka muna. +ratelimitedSkipCommand=Maaaring mong laktawan ng higit sa isa ang mga awitin sa pamamagitan ng pindutang ito\: {0} +ratelimitedGuildSlowLoadingPlaylist=Ang serber na ito ay pansamantalang hindi pwedeng mag dagdag ng maraming palatugtogan. Pakiusap huwag iispam ang mahabang palatugtogan. +unblacklisted=Tinanggal {0} mula sa pagkakablaklist. +serverinfoTitle=Impormasyon tungkol sa {0}\: +serverinfoOnlineUsers=Online ang mga gumagamit\: +serverinfoTotalUsers=Lahat ng mga gumagamit\: serverinfoRoles=Mga tungkulin\: serverinfoText=Text ka nya -serverinfoVoice=Voice Channels\: -serverinfoGuildID=Guild ID\: -serverinfoCreationDate=Creation Date\: -serverinfoOwner=Owner\: -serverinfoVLv=Verification Level\: -userinfoTitle=Information about {0}\: +serverinfoVoice=Tsanel ng boses\: +serverinfoGuildID=ID ng kapisanan\: +serverinfoCreationDate=Petsa ng pagkakagawa\: +serverinfoOwner=Nagmamay-ari\: +serverinfoVLv=Antas ng pagpapatunay\: +userinfoTitle=Impormasyon tungkol sa {0}\: userinfoUsername=Username\: userinfoId=ID\: -userinfoNick=Nickname\: -userinfoKnownServer=Known Servers\: -userinfoJoinDate=Join Date\: -userinfoCreationTime=Creation Date\: +userinfoNick=Palayaw\: +userinfoKnownServer=Kilalang mga serber\: +userinfoJoinDate=Petsa ng pagsali\: +userinfoCreationTime=Petsa ng pagkakagawa\: userinfoBlacklisted=Blacklisted\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. -eventUsersLeftVC=All users have left the voice channel. The player has been paused. -eventAutoResumed=User presence detected, automatically resuming the player. -commandsFun=Fun +skipDeniedTooManyTracks=Hindi mo pwedeng laktawan ang traks ng iba kung hindi ka isang DJ. Konsindera na gamitin ang Voteskip na pindutan. +eventUsersLeftVC=Nagsi-alisan ang lahat ng gumagamit sa stanel ng mga boses. Inihinto ang pagpapatugtog. +eventAutoResumed=Natukoy ang kinaroroonan ng mga gumagamit, awtomatiko ang pagpapatutog muli. +commandsFun=Masaya commandsMemes=Memes -commandsUtility=Utility -commandsModeration=Moderation -commandsMaintenance=Maintenance -commandsBotOwner=Bot owner -commandsMoreHelp=Say {0} to get more information on a specific command. -helpUnknownCommand=Unknown command. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors -helpSent=Documentation has been sent to your DMs\! -helpProperUsage=Proper usage\: -helpCommandOwnerRestricted=This command is restricted to the owner of the bot. -helpConfigCommand=Show the config of this guild or adjust settings. -helpLanguageCommand=Show available languages or set a language for this guild. -helpHardbanCommand=Ban a user and delete his messages from the last 7 days. -helpKickCommand=Kick a user from this guild. -helpSoftbanCommand=Softban a user by kicking him and deleting his messages from the last 7 days. -helpMusicCommandsHeader=FredBoat Music Commands -helpJoinCommand=Make the bot join your current voice channel. -helpLeaveCommand=Make the bot leave the current voice channel. -helpPauseCommand=Pause the player. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} -helpPlaySplitCommand=Split a YouTube video into a tracklist provided in it's description. -helpRepeatCommand=Toggle between repeat modes. -helpReshuffleCommand=Reshuffle the current queue. -helpSelectCommand=Select one of the offered tracks after a search to play. -helpShuffleCommand=Toggle shuffle mode for the current queue. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. -helpStopCommand=Stop the player and clear the playlist. Reserved for moderators with Manage Messages permission. -helpUnpauseCommand=Unpause the player. -helpVolumeCommand=Changes the volume. Values are 0-150 and 100 is the default. The volume command is deprecated on the public bot. -helpExportCommand=Export the current queue to a hastebin link, can be later used as a playlist. -helpGensokyoRadioCommand=Show the current song played on gensokyoradio.net -helpListCommand=Display a list of the current songs in the playlist. -helpHistoryCommand=Display a list of the songs in playlist history. -helpNowplayingCommand=Display the currently playing song. -helpForwardCommand=Forward the track by a given amount of time. Example\: -helpRestartCommand=Restart the currently playing track. -helpRewindCommand=Rewind the track by a given amount of time. Example\: -helpSeekCommand=Set the position of the track to the given time. Example\: -helpAvatarCommand=Display the avatar of a user. -helpBrainfuckCommand=Executes Brainfuck code. Example\: -helpWeatherCommand=Display current weather by location. -helpClearCommand=Delete all messages by this bot in the last 50 messages of this channel. -helpCommandsCommand=Show available commands. -helpHelpCommand=Receive help for this bot or help for any command. -helpInviteCommand=Post invite link for this bot. -helpMALCommand=Search MyAnimeList and display an anime or profile of a user. -helpMusicHelpCommand=Show music commands and their usage. -helpSayCommand=Make the bot echo something. -helpServerInfoCommand=Display some stats about this guild. -helpUserInfoCommand=Display information about yourself or a user known to the bot. -helpPerms=Allows whitelisting members and roles for the {0} rank. -helpPrefixCommand=Set the prefix for this guild. -helpVoteSkip=Vote to skip the current song. Needs 50% of all users in the voice chat to vote. -helpMathOperationAdd=Print the sum of num1 and num2. +commandsUtility=Kagamitan +commandsModeration=Moderasyon +commandsMaintenance=Pagpapanatili +commandsBotOwner=May-ari ng bot +commandsMoreHelp=Sabihin na {0} kumuha ng maraming impormasyon sa partikular na pindutan. +helpUnknownCommand=Di-matukoy na pindutan. +helpDocsLocation=Ang dokumento ay matatagpuan sa\: +helpBotInvite=Gusto mong bang magdagdag ng FredBoat sa iyong serber? Kung pinapangasiwaan mo ang pahintulot ng seber para sa iyong guild, Maaaring mong maimbita ang FredBoat\: +helpHangoutInvite=Kailangan ng tulong o mayroong kahit anong ideya para sa FredBoat? Marahil ay guto mong umistambay? Sumali sa kominidad ng FredBoat\! +helpNoDmCommands=Hindi ka pwedeng magpadala ng FredBoat na mga utos sa pamamagitan ng DMs. +helpCredits=Ginawa sa pamamagitan ni Fre_d at sa mga nagambag ng open source +helpSent=Ang dokumentasyon ay ipinadala sa inyong DMs\! +helpProperUsage=Wastong paggamit\: +helpCommandOwnerRestricted=Ang pindutan na ito ay takda ng may ari ng mga bot. +helpConfigCommand=Ipakita ang kumpig ng guild na ito o kaya ay ayosin ang mga setings. +helpLanguageCommand=Ipakita ang mga wikang pwede or magtakda ng mga wika sa guild na ito. +helpHardbanCommand=Pagbawalan ang gumagami na burahin ang mga mensahe sa nakalipas na pitong araw. +helpKickCommand=Patalsikin ang mga gumgamit sa guild na ito. +helpSoftbanCommand=Pansamantalang pagbabawal sa mga gumagamit na pagsipa sa kanya at pagbubura ng mga mensahe mula sa nakalipas na pitong 7 araw. +helpMusicCommandsHeader=FredBoat Direksyon ng Musika +helpJoinCommand=Gumawa ang bot para sumali sa inyong kasalukuyang tsanel ng tinig. +helpLeaveCommand=Nagawa na bot na iwanan ang kasalukuyang tsanel ng tinig. +helpPauseCommand=Ihinto ang musiko. +helpPlayCommand=Magpatugtog ng musika mula sa ibinigay na URL o kaya ay humanap sa trak. Para sa kabuong listahan ng mapagkukunan mangyaring bisitahin ang {0} +helpPlaySplitCommand=Nahati ang bidyo sa YouTube sa traklis na inilalalaan sa paglalarawan. +helpRepeatCommand=Magpaulit-ulit sa pagitan ng inulit na modes. +helpReshuffleCommand=Pag-aayos sa kasalukuyang pila. +helpSelectCommand=Pumili ng isa sa mga inaalok ng traks pagkatapos ng paghahanap para patutugin. +helpShuffleCommand=Toggle ayusin ang mode para sa kasalukuyang pila. +helpSkipCommand=Laktawan ang kasalukuyang awitin, ang n'th na awitin sa mga pagpipilian, ang lahat ng awitin mula sa n to m, o kaya ang lahat ng awitin mula sa nabanggit ng mga gumagamit. Pakiusap gamitin lamang sa kahinahunan. +helpStopCommand=Ihinto ang pagpapatugtutog at linisin ang listahan. Nakareserba para sa moderators sa pahintulot ng pangangasiwa ng mga mensahe. +helpUnpauseCommand=Alisin sa pagkakahinto ang tugtog. +helpVolumeCommand=Hinaan ang tunog. Ang halaga ay 0-150 at 100 ang pangunahin. Ang tunog ay naririnig sa publiko ng bot. +helpExportCommand=I-eksport ang kasulukuyang pagpipilian para sa hastebin link, Kalaunan ay magagamit bilang isang palatugtugan. +helpGensokyoRadioCommand=Ipakita ang kasalukuyang awiting tumutugtog sa gensokyoradio.net +helpListCommand=Ihayag ang kasalukuyang listahan ng mga kana sa palagtugtugan. +helpHistoryCommand=Ihayag ang listahan ng mga awitin sa kasaysayan ng palatugtugan. +helpNowplayingCommand=Ihayag ang kasalukuyang awiting pinapatugtog. +helpForwardCommand=Madaliin ang trak na nagbibigay ng maraming oras. Halimbawa\: +helpRestartCommand=Ulitin ang kasalukuyang trak ng tugtog. +helpRewindCommand=Madaliin ang trak na nagbibigay ng maraming oras. Halimbawa\: +helpSeekCommand=Ayosin ang posisyon ng mga trak sa ibinigay na oras. Halimbawa\: +helpAvatarCommand=Ipakita ang hitsura ng mga gumagamit. +helpBrainfuckCommand=Patayin ang kowd ng brainfuck. Halimbawa\: +helpWeatherCommand=Ihayag ang kasalukuyang lokasyon ng panahon. +helpClearCommand=Burahin ang lahat ng mensahe sa bot na ito sa nakalipas na 50 na mensahe sa tsanel na ito. +helpCommandsCommand=Ipakita ang mga pwedeng pindutan. +helpHelpCommand=Tanggapin ang tulong mula sa bot na ito o kaya ay tulongan ang anumang gawain. +helpInviteCommand=I-post ang link ng mga imbitado sa bot na ito. +helpMALCommand=Hanapin ang listahan ng aking anime at ihayag ang anime o kaya ay propayl ng mga gumagamit. +helpMusicHelpCommand=Ipakita ang pindutang ng musika at ang kanilang gamit. +helpSayCommand=Gumagawa ng bot na alingawngaw. +helpServerInfoCommand=Ihayag ang ilang estadistika tungkol sa guild na ito. +helpUserInfoCommand=Ihayag ang imporsyon tungkol sa iyong sarili o kaya ay mga gumagamit na kilala ang bot. +helpPerms=Payagan ang mga miyembro ng putinglistahan at gampanan para sa {0} ranggo. +helpPrefixCommand=Itakda ang unlapit para sa guild na ito. +helpVoteSkip=Bumoto para malaktawan ang kasalukuyang awitin. Kailangan ang 50% ng lahat ng gumagamit ng tinig sa usapan upang bumoto. +helpMathOperationAdd=I-print ang kabuuan ng num1 at num2. helpMathOperationSub=Print the difference of subtracting num2 from num1. helpMathOperationMult=Print the product of num1*num2. helpMathOperationDiv=Print the quotient of dividing num1 by num2. @@ -295,11 +295,11 @@ voteSkipAlreadyVoted=You already voted to skip this track\! voteSkipSkipping={0} have voted to skip. Skipping track {1}. voteSkipNotEnough={0} have voted to skip. At least {1} needed. voteSkipEmbedNoVotes=No votes to skip this track yet. -voteSkipEmbedVoters={0} out of {1} have voted to skip the current track -mathOperationResult=The result is -mathOperationDivisionByZeroError=I cannot divide by zero. -mathOperationInfinity=The number is too big to be displayed\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +voteSkipEmbedVoters={0} mula sa {1} ay bumuto upang laktawan ang kasalukuyang trak +mathOperationResult=Ang resulta ay +mathOperationDivisionByZeroError=Hindi ko kayang hatiin mula sa sero. +mathOperationInfinity=Ang bilang ay masyadong malaki para maipakita\! +prefix=Unlapi +prefixGuild=Ang unlapi para sa guild na ito ay {0} +prefixShowAgain=Muli maaaring mong maipakita ang unlapi anomang oras sa pamamagitan ng pagbanggit sakin. diff --git a/FredBoat/src/main/resources/lang/fr_FR.properties b/FredBoat/src/main/resources/lang/fr_FR.properties index 39287ad16..3142d4a7e 100644 --- a/FredBoat/src/main/resources/lang/fr_FR.properties +++ b/FredBoat/src/main/resources/lang/fr_FR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Vous \u00eates en taux limit\u00e9\u00a0\! S\u2019il vous ratelimitedSkipCommand=Vous pouvez passer plus d''une chanson en utilisant la commande suivante \: {0} ratelimitedGuildSlowLoadingPlaylist=Ce serveur ne peut pas charger plus de listes de lecture pour le moment. S'il vous pla\u00eet, ne spammez pas de longues listes de lecture. unblacklisted={0} a \u00e9t\u00e9 retir\u00e9 de la liste noire. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Infos \u00e0 propos de {0} \: serverinfoOnlineUsers=Utilisateurs en ligne \: serverinfoTotalUsers=Nombre total d'utilisateurs \: serverinfoRoles=R\u00f4les \: @@ -193,7 +193,7 @@ serverinfoGuildID=Identifiant de la guilde \: serverinfoCreationDate=Date de cr\u00e9ation \: serverinfoOwner=Propri\u00e9taire \: serverinfoVLv=Niveau de v\u00e9rification\u00a0\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informations \u00e0 propos de {0} \: userinfoUsername=Nom d'utilisateur \: userinfoId=Identifiant \: userinfoNick=Pseudonyme \: @@ -212,11 +212,11 @@ commandsMaintenance=Maintenance commandsBotOwner=Propri\u00e9taire du bot commandsMoreHelp=Dites {0} pour obtenir plus d\u2019informations sur une commande sp\u00e9cifique. helpUnknownCommand=Commande inconnue. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=La documentation peut \u00eatre trouv\u00e9e ici \: +helpBotInvite=Vous voulez ajouter FredBoat \u00e0 votre serveur ? Si vous avez la permission de g\u00e9rer cette guilde, vous pouvez inviter FredBoat \: +helpHangoutInvite=Vous avez besoin d'aide ou avez des id\u00e9es pour FredBoat ? Ou vous voulez juste passer le temps ? Rejoignez la communaut\u00e9 FredBoat \! +helpNoDmCommands=Vous ne pouvez pas envoyer de commandes via la messagerie priv\u00e9e. +helpCredits=Cr\u00e9\u00e9 par Fre_d et ses contributeurs en open-source helpSent=La documentation a \u00e9t\u00e9 envoy\u00e9 dans votre messagerie priv\u00e9e \! helpProperUsage=Utilisation ad\u00e9quate \: helpCommandOwnerRestricted=Cette commande est r\u00e9serv\u00e9e au propri\u00e9taire du bot. diff --git a/FredBoat/src/main/resources/lang/he_IL.properties b/FredBoat/src/main/resources/lang/he_IL.properties index 77c6dcc0b..e2b5ad103 100644 --- a/FredBoat/src/main/resources/lang/he_IL.properties +++ b/FredBoat/src/main/resources/lang/he_IL.properties @@ -11,8 +11,8 @@ joinJoining=\u05de\u05e6\u05d8\u05e8\u05e3 \u05d0\u05dc {0} joinErrorAlreadyJoining=\u05d0\u05d9\u05e8\u05e2\u05d4 \u05e9\u05d2\u05d9\u05d0\u05d4. \u05dc\u05d0 \u05d9\u05db\u05d5\u05dc\u05ea\u05d9 \u05dc\u05d4\u05e6\u05d8\u05e8\u05e3 \u05d0\u05dc {0} \u05de\u05db\u05d9\u05d5\u05d5\u05df \u05e9\u05d0\u05e0\u05d9 \u05db\u05d1\u05e8 \u05de\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05dc\u05e2\u05e8\u05d5\u05e5 \u05d6\u05d4. \u05d0\u05e0\u05d0 \u05e0\u05e1\u05d4 \u05e9\u05e0\u05d9\u05ea. pauseAlreadyPaused=\u05d4\u05e0\u05d2\u05df \u05db\u05d1\u05e8 \u05d1\u05d4\u05e9\u05d4\u05d9\u05d4. pauseSuccess=\u05d4\u05e0\u05d2\u05df \u05de\u05d5\u05e9\u05d4\u05d4 \u05db\u05e8\u05d2\u05e2. \u05d0\u05ea\u05d4 \u05d9\u05db\u05d5\u05dc \u05dc\u05d1\u05d8\u05dc \u05d0\u05ea \u05d4\u05d4\u05e9\u05e2\u05d9\u05d9\u05d4 \u05d1\u05d0\u05de\u05e6\u05e2\u05d5\u05ea `{0}unpause`. -repeatOnSingle=The player will now repeat the current track. -repeatOnAll=The player will now repeat the queue. +repeatOnSingle=\u05d4\u05e0\u05d2\u05df \u05d9\u05d7\u05d6\u05d5\u05e8 \u05db\u05e8\u05d2\u05e2 \u05e2\u05dc \u05d4\u05e9\u05d9\u05e8 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9. +repeatOnAll=\u05d4\u05e0\u05d2\u05df \u05d9\u05d7\u05d6\u05d5\u05e8 \u05db\u05e8\u05d2\u05e2 \u05e2\u05dc \u05e8\u05e9\u05d9\u05de\u05ea \u05d4\u05d4\u05e9\u05de\u05e2\u05d4. repeatOff=\u05d4\u05e0\u05d2\u05df \u05dc\u05d0 \u05d9\u05d7\u05d6\u05d5\u05e8 \u05e2\u05dc \u05e2\u05e6\u05de\u05d5. selectSuccess=\u05e9\u05d9\u05e8 **\#{0}** \u05e0\u05d1\u05d7\u05e8\: **{1}** ({2}) selectInterval=\u05d7\u05d9\u05d9\u05d1 \u05dc\u05d4\u05d9\u05d5\u05ea \u05de\u05e1\u05e4\u05e8 \u05d1\u05d9\u05df 1-{0}. @@ -20,7 +20,7 @@ selectSelectionNotGiven=\u05d0\u05ea\u05d4 \u05e7\u05d5\u05d3\u05dd \u05e6\u05e8 shuffleOn=\u05d4\u05e0\u05d2\u05df \u05e2\u05db\u05e9\u05d9\u05d5 \u05de\u05e2\u05d5\u05e8\u05d1\u05d1. shuffleOff=\u05d4\u05e0\u05d2\u05df \u05d0\u05d9\u05e0\u05d5 \u05de\u05e2\u05d5\u05e8\u05d1\u05d1. reshufflePlaylist=\u05d4\u05ea\u05d5\u05e8 \u05d4\u05ea\u05e2\u05e8\u05d1\u05d1. -reshufflePlayerNotShuffling=You must first turn on shuffle mode. +reshufflePlayerNotShuffling=\u05d0\u05ea\u05d4 \u05d7\u05d9\u05d9\u05d1 \u05dc\u05d4\u05e4\u05e2\u05d9\u05dc \u05d0\u05ea \u05e8\u05e9\u05d9\u05de\u05ea \u05d4\u05d4\u05e9\u05de\u05e2\u05d4 \u05d1\u05e1\u05d3\u05e8 \u05e8\u05e0\u05d3\u05d5\u05de\u05dc\u05d9. skipEmpty=\u05e8\u05e9\u05d9\u05de\u05ea \u05d4\u05e9\u05d9\u05e8\u05d9\u05dd \u05e8\u05d9\u05e7\u05d4\! skipOutOfBounds=\u05d0\u05d9\u05df \u05d0\u05e4\u05e9\u05e8\u05d5\u05ea \u05dc\u05d4\u05e1\u05d9\u05e8 \u05d0\u05ea \u05e9\u05d9\u05e8 \u05de\u05e1\u05e4\u05e8 {0} \u05db\u05d0\u05e9\u05e8 \u05d9\u05e9 \u05e8\u05e7 {1} \u05e9\u05d9\u05e8\u05d9\u05dd. skipNumberTooLow=\u05d4\u05de\u05e1\u05e4\u05e8 \u05d4\u05e0\u05ea\u05d5\u05df \u05d7\u05d9\u05d9\u05d1 \u05dc\u05d4\u05d9\u05d5\u05ea \u05d2\u05d3\u05d5\u05dc \u05de-0. @@ -43,7 +43,7 @@ exportEmpty=\u05d0\u05d9\u05df \u05de\u05d4 \u05dc\u05d9\u05d9\u05e6\u05d0, \u05 exportPlaylistResulted=\u05e4\u05dc\u05d9\u05d9\u05dc\u05d9\u05e1\u05d8 \u05de\u05d9\u05d5\u05e6\u05d0\: {0}\n\u05d0\u05ea\u05d4 \u05d9\u05db\u05d5\u05dc \u05dc\u05ea\u05ea \u05db\u05ea\u05d5\u05d1\u05ea \u05d0\u05ea\u05e8 \u05e2\u05dc \u05de\u05e0\u05ea \u05dc\u05d3\u05d7\u05d5\u05ea \u05d0\u05ea \u05d4\u05e4\u05dc\u05d9\u05d9\u05dc\u05d9\u05d8\u05e1 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9 \u05dc\u05d0\u05d7\u05e8 \u05db\u05da. exportPlaylistFail=\u05d4\u05e2\u05dc\u05d0\u05ea \u05d4\u05e4\u05dc\u05d9\u05d9\u05dc\u05d9\u05e1\u05d8 \u05dchastebin.com \u05e0\u05db\u05e9\u05dc\u05d4 listShowShuffled=\u05de\u05e6\u05d9\u05d2 \u05e4\u05dc\u05d9\u05d9\u05dc\u05d9\u05e1\u05d8 \u05de\u05e2\u05d5\u05e8\u05d1\u05d1.\n\n -listShowRepeatSingle=Repeating current track. +listShowRepeatSingle=\u05d7\u05d5\u05d6\u05e8 \u05e2\u05dc \u05d4\u05e9\u05d9\u05e8 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9. listShowRepeatAll=Repeating current queue. listShowHistory=Showing tracks in history. listAddedBy=**{0}** added by **{1}** `[{2}]` diff --git a/FredBoat/src/main/resources/lang/id_ID.properties b/FredBoat/src/main/resources/lang/id_ID.properties index 3e31e8757..30d077cc3 100644 --- a/FredBoat/src/main/resources/lang/id_ID.properties +++ b/FredBoat/src/main/resources/lang/id_ID.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Kamu mencapai tingkatan batas\! Harap perlambat. ratelimitedSkipCommand=Anda Dapat Melewati Lebih Dari Satu Lagu Dengan Menggunakan Perintah\: {0} ratelimitedGuildSlowLoadingPlaylist=Server ini tidak diizinkan untuk menambahkan playlist lebih untuk saat ini. Harap jangan spam playlist panjang. unblacklisted=Menghapus {0} dari blacklist. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Info tentang **{0}**\: serverinfoOnlineUsers=Pengguna Online\: serverinfoTotalUsers=Total Pengguna\: serverinfoRoles=Peran\: @@ -193,7 +193,7 @@ serverinfoGuildID=Server ID\: serverinfoCreationDate=Tanggal Pembuatan\: serverinfoOwner=Pemilik\: serverinfoVLv=Tingkat verifikasi\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informasi tentang **{0} **\: userinfoUsername=Nama Pengguna\: userinfoId=ID\: userinfoNick=Nama Panggilan\: @@ -212,11 +212,11 @@ commandsMaintenance=Perbaikan commandsBotOwner=Pemilik bot commandsMoreHelp=Katakanlah {0} untuk mendapatkan informasi lebih lanjut tentang perintah tertentu helpUnknownCommand=Perintah Tidak Ditemukan. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Dokumentasi dapat ditemukan di\: +helpBotInvite=Ingin menambahkan FredBoat ke server Anda? Jika Anda memiliki Server mengelola izin untuk guild, Anda dapat mengundang FredBoat\: +helpHangoutInvite=Memerlukan bantuan atau punya ide untuk FredBoat? Mungkin Anda hanya ingin bergaul? Ikut komunitas FredBoat\! +helpNoDmCommands=Anda tidak dapat mengirim perintah FredBoat melalui DMs. +helpCredits=Dibuat oleh Fre_d dan sumber terbuka kontributor helpSent=Dokumentasi telah dikirim ke DMS Anda\! helpProperUsage=Penggunaan yang tepat\: helpCommandOwnerRestricted=Perintah ini di ban oleh pemilik bot. diff --git a/FredBoat/src/main/resources/lang/it_IT.properties b/FredBoat/src/main/resources/lang/it_IT.properties index 73811407d..a03639529 100644 --- a/FredBoat/src/main/resources/lang/it_IT.properties +++ b/FredBoat/src/main/resources/lang/it_IT.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Sei limitato\! Per favore rallenta. ratelimitedSkipCommand=Si pu\u00f2 saltare pi\u00f9 di una canzone utilizzando questo comando\: {0} ratelimitedGuildSlowLoadingPlaylist=A questo server non \u00e8 consentito aggiungere pi\u00f9 playlist in questo momento. Per favore, non spam le liste di gioco lunghe. unblacklisted=Rimosso {0} dalla lista nera. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Info su {0}\: serverinfoOnlineUsers=Utenti online\: serverinfoTotalUsers=Utenti totali\: serverinfoRoles=Ruoli\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID della gilda\: serverinfoCreationDate=Data di creazione\: serverinfoOwner=Proprietario\: serverinfoVLv=Verifica del testo\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informazioni su {0}\: userinfoUsername=Nome utente\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,11 +212,11 @@ commandsMaintenance=Manutenzione commandsBotOwner=Proprietario di Bot commandsMoreHelp=Dire {0} per ottenere ulteriori informazioni su un comando specifico. helpUnknownCommand=Comando sconosciuto. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Si puo trovare la documentazione su\: +helpBotInvite=Vuoi aggiungere FredBoat al tuo server? se hai l'autorizzazione per aggiungere membri, puoi invitare FredBoat\: +helpHangoutInvite=Bai bisogno di aiuto o hai qualche idea per FredBoat? Forse volete solo parlare? Unisciti alla comunit\u00e0 di FredBoat\! +helpNoDmCommands=Non \u00e8 possibile inviare comandi di FredBoat tramite DMs. +helpCredits=Creato da Fre_d e collaboratori open source helpSent=La documentazione \u00e8 stata inviata ai vostri DM\! helpProperUsage=Utilizzo corretto\: helpCommandOwnerRestricted=Questo comando \u00e8 limitato al proprietario del bot. diff --git a/FredBoat/src/main/resources/lang/ja_JP.properties b/FredBoat/src/main/resources/lang/ja_JP.properties index 9b488f333..d8a9e686d 100644 --- a/FredBoat/src/main/resources/lang/ja_JP.properties +++ b/FredBoat/src/main/resources/lang/ja_JP.properties @@ -8,7 +8,7 @@ playYoutubeSearchError=YouTube\u3092\u691c\u7d22\u3059\u308b\u3068\u304d\u306b\u playSearchNoResults=`{q}`\u306e\u691c\u7d22\u7d50\u679c\u304c\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002 playSelectVideo=** ` {0} play 1-5`\u30b3\u30de\u30f3\u30c9\u3067\u66f2\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\uff1a** joinJoining={0} \u306b\u53c2\u52a0\u3057\u307e\u3057\u305f\u3002 -joinErrorAlreadyJoining=\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002Fredboat\u306f\u3059\u3067\u306b\u305d\u306e\u30c1\u30e3\u30cd\u30eb\u306b\u63a5\u7d9a\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u308b\u306e\u3067\u3001{0} \u3092\u53c2\u52a0\u3067\u304d\u306a\u304b\u3063\u305f\u3002\u3082\u3046\u4e00\u5ea6\u3084\u308a\u76f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002 +joinErrorAlreadyJoining=\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002Fredboat\u306f\u3059\u3067\u306b\u305d\u306e\u30c1\u30e3\u30cd\u30eb\u306b\u63a5\u7d9a\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u308b\u306e\u3067\u3001{0} \u306b\u306f\u53c2\u52a0\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u3082\u3046\u4e00\u5ea6\u3084\u308a\u76f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002 pauseAlreadyPaused=\u30d7\u30ec\u30fc\u30e4\u30fc\u306f\u65e2\u306b\u4e00\u6642\u505c\u6b62\u3057\u3066\u3044\u307e\u3059\u3002 pauseSuccess=\u30d7\u30ec\u30a4\u30e4\u30fc\u306f\u3053\u306e\u4e00\u6642\u505c\u6b62\u3067\u3059\u3002''{0}unpause'' \u3067\u518d\u958b\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 repeatOnSingle=\u3053\u306e\u30c8\u30e9\u30c3\u30af\u306f\u4eca\u30ea\u30d4\u30fc\u30c8\u4e2d\u3067\u3059\u3002 @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u3042\u306a\u305f\u306f\u30ec\u30fc\u30c8\u5236\u9650\u3 ratelimitedSkipCommand=\u6b21\u306e\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u7528\u3057\u3066\u8907\u6570\u306e\u66f2\u3092\u30b9\u30ad\u30c3\u30d7\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff1a{0} ratelimitedGuildSlowLoadingPlaylist=\u73fe\u5728\u3001\u3053\u306e\u30b5\u30fc\u30d0\u30fc\u3067\u306f\u3001\u3053\u308c\u4ee5\u4e0a\u30d7\u30ec\u30a4\u30ea\u30b9\u30c8\u3092\u8ffd\u52a0\u3059\u308b\u3053\u3068\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u9577\u3044\u30d7\u30ec\u30a4\u30ea\u30b9\u30c8\u3092\u30b9\u30d1\u30e0\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002 unblacklisted={0} \u3092\u30d6\u30e9\u30c3\u30af\u30ea\u30b9\u30c8\u304b\u3089\u6d88\u53bb\u3057\u307e\u3057\u305f\u3002 -serverinfoTitle=Info about {0}\: +serverinfoTitle={0} \u306b\u95a2\u3059\u308b\u60c5\u5831\: serverinfoOnlineUsers=\u30aa\u30f3\u30e9\u30a4\u30f3\u30e6\u30fc\u30b6\u30fc\: serverinfoTotalUsers=\u5408\u8a08\u30e6\u30fc\u30b6\u30fc\u6570\uff1a serverinfoRoles=\u5f79\u5272\: @@ -193,7 +193,7 @@ serverinfoGuildID=\u30ae\u30eb\u30c9ID\: serverinfoCreationDate=\u4f5c\u6210\u65e5\: serverinfoOwner=\u30aa\u30fc\u30ca\u30fc\: serverinfoVLv=\u8a8d\u8a3c\u30ec\u30d9\u30eb\: -userinfoTitle=Information about {0}\: +userinfoTitle={0} \u306b\u95a2\u3059\u308b\u60c5\u5831\: userinfoUsername=\u30e6\u30fc\u30b6\u30fc\u540d\uff1a userinfoId=ID\: userinfoNick=\u30cb\u30c3\u30af\u30cd\u30fc\u30e0\: @@ -212,11 +212,11 @@ commandsMaintenance=\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9 commandsBotOwner=bot\u306e\u30aa\u30fc\u30ca\u30fc commandsMoreHelp={0} \u3068\u767a\u8a00\u3059\u308b\u3053\u3068\u3067\u3001\u7279\u5b9a\u306e\u30b3\u30de\u30f3\u30c9\u306b\u3064\u3044\u3066\u306e\u60c5\u5831\u3092\u8a73\u3057\u304f\u8868\u793a\u3067\u304d\u307e\u3059\u3002 helpUnknownCommand=\u4e0d\u660e\u306a\u30b3\u30de\u30f3\u30c9\u3002 -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=\u4ed5\u69d8\u66f8\u306f\u3053\u3061\u3089\: +helpBotInvite=Fredboat\u3092\u3042\u306a\u305f\u306e\u30b5\u30fc\u30d0\u30fc\u306b\u8ffd\u52a0\u3057\u305f\u3044\u3067\u3059\u304b\uff1f\u3082\u3057\u3042\u306a\u305f\u304c\u30b5\u30fc\u30d0\u30fc\u306e\u7ba1\u7406\u306e\u6a29\u9650\u3092\u304a\u6301\u3061\u3067\u3057\u305f\u3089\u3001\u3053\u3061\u3089\u304b\u3089Fredboat\u3092\u62db\u5f85\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\: +helpHangoutInvite=Fredboat\u306b\u95a2\u3057\u3066\u30d8\u30eb\u30d7\u304c\u5fc5\u8981\u3067\u3059\u304b\uff1f\u305d\u308c\u3068\u3082\u30a2\u30a4\u30c7\u30a2\u304c\u3042\u308a\u307e\u3059\u304b\uff1f\u3082\u3057\u304b\u3057\u3066\u4ed6\u306e\u4eba\u3068\u96c6\u307e\u308a\u305f\u3044\u3067\u3059\u304b\uff1f\u306a\u3089\u3070\u662f\u975eFredboat\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u6765\u307e\u3057\u3087\u3046\uff01 +helpNoDmCommands=DM\u3067Fredboat\u306e\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u3046\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002 +helpCredits=Fre_d\u3068\u30aa\u30fc\u30d7\u30f3\u30bd\u30fc\u30b9\u8ca2\u732e\u8005\u306b\u3088\u3063\u3066\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u3002 helpSent=\u30d8\u30eb\u30d7\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092DM\u3067\u9001\u308a\u307e\u3057\u305f\uff01 helpProperUsage=\u9069\u5207\u306a\u4f7f\u7528\u65b9\u6cd5\: helpCommandOwnerRestricted=\u3053\u306e\u30b3\u30de\u30f3\u30c9\u306fbot\u306e\u30aa\u30fc\u30ca\u30fc\u306b\u3088\u3063\u3066\u5236\u9650\u3055\u308c\u3066\u3044\u307e\u3059\u3002 diff --git a/FredBoat/src/main/resources/lang/ko_KR.properties b/FredBoat/src/main/resources/lang/ko_KR.properties index 9409ad676..aa86db800 100644 --- a/FredBoat/src/main/resources/lang/ko_KR.properties +++ b/FredBoat/src/main/resources/lang/ko_KR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\ub2f9\uc2e0\uc740 \uc18d\ub3c4\uac00 \uc81c\ud55c\ub418\ ratelimitedSkipCommand={0} \uba85\ub839\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud558\ub098 \uc774\uc0c1\uc758 \uace1\uc744 \uac74\ub108\ub6f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4. ratelimitedGuildSlowLoadingPlaylist=\uc774 \uc11c\ubc84\ub294 \ud604\uc7ac \uc7ac\uc0dd \ubaa9\ub85d\uc744 \ub354 \uc774\uc0c1 \ucd94\uac00\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uae34 \uc7ac\uc0dd \ubaa9\ub85d\uc744 \uc7ac\uc0dd\ud558\uc9c0 \ub9c8\uc2ed\uc2dc\uc624. unblacklisted=\ube14\ub799 \ub9ac\uc2a4\ud2b8\uc5d0\uc11c {0} \uc744(\ub97c) \uc81c\uac70\ud588\uc2b5\ub2c8\ub2e4. -serverinfoTitle=Info about {0}\: +serverinfoTitle={0}\uc5d0 \ub300\ud55c \uc815\ubcf4\: serverinfoOnlineUsers=\uc628\ub77c\uc778 \uc720\uc800\ub4e4\: serverinfoTotalUsers=\ucd1d \uc720\uc800\ub4e4\: serverinfoRoles=\uc5ed\ud560\ub4e4\: @@ -193,7 +193,7 @@ serverinfoGuildID=\uae38\ub4dc \uc544\uc774\ub514\: serverinfoCreationDate=\uc0dd\uc131 \ub0a0\uc9dc\: serverinfoOwner=\uc8fc\uc778\: serverinfoVLv=\uc778\uc99d \ub808\ubca8\: -userinfoTitle=Information about {0}\: +userinfoTitle={0}\uc5d0 \ub300\ud55c \uc815\ubcf4\: userinfoUsername=\uc720\uc800\ub124\uc784\: userinfoId=\uc544\uc774\ub514\: userinfoNick=\ubcc4\uba85\: @@ -212,11 +212,11 @@ commandsMaintenance=\uc810\uac80 commandsBotOwner=\ubd07 \uc8fc\uc778 commandsMoreHelp={0} \uc744 \ub9d0\ud558\uc5ec \ud2b9\uc815 \uba85\ub839\uc5b4\uc5d0 \ub300\ud55c \ub354 \ub9ce\uc740\uac83\uc744 \uc54c\uc544\ubcf4\uc138\uc694. helpUnknownCommand=\uc54c \uc218 \uc5c6\ub294 \uba85\ub839\uc5b4\uc785\ub2c8\ub2e4. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=\ubb38\uc11c\ub97c \uc774\uacf3\uc5d0\uc11c \ucc3e\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4\: +helpBotInvite=FredBoat\ub97c \ub2f9\uc2e0\uc758 \uc11c\ubc84\uc5d0 \ucd94\uac00\ud558\uae30\ub97c \uc6d0\ud558\uc2dc\ub098\uc694? \uc11c\ubc84 \uad00\ub9ac\uc790 \uad8c\ud55c\uc774 \uc788\ub2e4\uba74, FredBoat\ub97c \ucd94\uac00\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4\: +helpHangoutInvite=FredBoat\uc5d0 \ub3c4\uc6c0\uc774 \ud544\uc694\ud558\uac70\ub098, \uc544\uc774\ub514\uc5b4\uac00 \uc788\uc73c\uc2dc\ub098\uc694? \uc544\ub2c8\uba74 \uadf8\ub0e5 \ub180\uace0 \uc2f6\ub098\uc694? FredBoat \ucee4\ubba4\ub2c8\ud2f0\uc5d0 \uac00\uc785\ud558\uc138\uc694\! +helpNoDmCommands=\uac1c\uc778 \uba54\uc138\uc9c0\ub97c \ud1b5\ud574 FredBoat\uc5d0\uac8c \uba85\ub839\uc5b4\ub97c \ubcf4\ub0bc \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +helpCredits=Fre_d\uc640 \uc624\ud508 \uc18c\uc2a4 \uae30\uc5ec\uc790\uc5d0 \uc758\ud574\uc11c \ub9cc\ub4e4\uc5b4\uc9d0 helpSent=\ubb38\uc11c \uadc0\ud558\uc758 DMs\ub97c \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4\! helpProperUsage=\uc815\ud655\ud55c \uc0ac\uc6a9\ubc95\: helpCommandOwnerRestricted=\uc774 \uba85\ub839\uc5b4\ub294 \ubd07 \uc8fc\uc778\ub9cc \uc0ac\uc6a9 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. @@ -294,12 +294,12 @@ voteSkipAdded=\ud22c\ud45c \ucd94\uac00 \ub418\uc5c8\uc2b5\ub2c8\ub2e4\! voteSkipAlreadyVoted=\ub2f9\uc2e0\uc740 \uc774\ubbf8\uc774 \ud2b8\ub799\uc744 \uac74\ub108\ub6f8 \ud558\uae30\ub85c \uacb0\uc815\! voteSkipSkipping={0} \uba85\uc774 \uc2a4\ud0b5\uc5d0 \ub3d9\uc758\ud574 {1} \ud2b8\ub799\uc744 \uc2a4\ud0b5\ud569\ub2c8\ub2e4. voteSkipNotEnough={0} \uba85\uc774 \uc2a4\ud0b5\uc5d0 \ub3d9\uc758\ud588\uc9c0\ub9cc \uc2a4\ud0b5 \ucd5c\uc18c \uc778\uc6d0 ({1} \uba85) \uc5d0 \ubbf8\uce58\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4. -voteSkipEmbedNoVotes=No votes to skip this track yet. -voteSkipEmbedVoters={0} out of {1} have voted to skip the current track +voteSkipEmbedNoVotes=\uc544\uc9c1 \uc774 \ud2b8\ub799\uc744 \uac74\ub108\ub6f8 \uc218 \uc5c6\ub294 \ub4dd\ud45c\uc218\uc785\ub2c8\ub2e4. +voteSkipEmbedVoters={1} \uc911 {0} \uc774(\uac00) \ud604\uc7ac \ud2b8\ub799\ub97c \uac74\ub108\ub6f0\uae30\ub85c \uacb0\uc815\ud588\uc2b5\ub2c8\ub2e4. mathOperationResult=\uacb0\uacfc\uac12\uc740 mathOperationDivisionByZeroError=0\uc73c\ub85c \ub098\ub20c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. mathOperationInfinity=\ud574\ub2f9 \uc22b\uc790\ub294 \ubcf4\uc5ec\uc8fc\uae30\uc5d0 \ub108\ubb34 \ud07d\ub2c8\ub2e4\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=\uc811\ub450\uc0ac +prefixGuild=\uc774 \uc11c\ubc84\uc758 \uc811\ub450\uc0ac\ub294 {0} \uc785\ub2c8\ub2e4. +prefixShowAgain=\uc800\ub97c \uc5b8\uae09\ud558\uc5ec \uc5b8\uc81c\ub4e0\uc9c0 \uc811\ub450\uc0ac\ub97c \ud45c\uc2dc\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. diff --git a/FredBoat/src/main/resources/lang/ms_MY.properties b/FredBoat/src/main/resources/lang/ms_MY.properties index 795bccc61..e8a64d93e 100644 --- a/FredBoat/src/main/resources/lang/ms_MY.properties +++ b/FredBoat/src/main/resources/lang/ms_MY.properties @@ -8,56 +8,56 @@ playYoutubeSearchError=Terdapat ralat ketika mencari di YouTube. Sebaliknya, tim playSearchNoResults=Tiada keputusan untuk `{q}` playSelectVideo=**Sila pilih lagu dengan perintah `{0}play n`\:** joinJoining=Menyertai {0} -joinErrorAlreadyJoining=An error occurred. Couldn''t join {0} because I am already trying to connect to that channel. Please try again. -pauseAlreadyPaused=The player is already paused. -pauseSuccess=The player is now paused. You can unpause it with `{0}unpause`. -repeatOnSingle=The player will now repeat the current track. -repeatOnAll=The player will now repeat the queue. -repeatOff=The player is no longer on repeat. -selectSuccess=Song **\#{0}** has been selected\: **{1}** ({2}) -selectInterval=Must be a number 1-{0}. -selectSelectionNotGiven=You must first be given a selection to choose from. -shuffleOn=The player is now shuffled. -shuffleOff=The player is no longer shuffled. -reshufflePlaylist=Queue reshuffled. -reshufflePlayerNotShuffling=You must first turn on shuffle mode. -skipEmpty=The queue is empty\! -skipOutOfBounds=Can''t remove track number {0} when there are only {1} tracks. -skipNumberTooLow=Given number must be greater than 0. -skipSuccess=Skipped track \#{0}\: **{1}** -skipRangeInvalid=Specified track range is invalid. -skipRangeSuccess=Tracks \#{0} to \#{1} have been removed. -skipTrackNotFound=Couldn't find track to skip. -stopAlreadyEmpty=The queue was already empty. -stopEmptyOne=The queue has been emptied, `1` track has been removed. -stopEmptySeveral=The queue has been emptied, `{0}` tracks have been removed. -stopAccessDenied=In order to prevent abuse, this command is only available to those who can manage messages. -unpauseQueueEmpty=The queue is empty. -unpausePlayerNotPaused=The player is not paused. -unpauseNoUsers=There are no users in the voice chat. -unpauseSuccess=The player is now unpaused. -volumeApology=Sorry\! The ;;volume command has now been deprecated on the public music bot. This is because of how it causes the bot to spend a lot more time processing audio, some tracks up to 5 times more, causing everyone to hear stutter. By disabling this feature FredBoat can play much more music without lag.\nI recommend setting the bot's volume via the dropdown menu https\://fred.moe/1vD.png -volumeSyntax=Use `;;volume <0-150>`. {0}% is the default.\nThe player is currently at **{1}%**. -volumeSuccess=Changed volume from **{0}%** to **{1}%**. -exportEmpty=Nothing to export, the queue is empty. -exportPlaylistResulted=Exported playlist\: {0}\nYou can provide this URL to play the current playlist later. -exportPlaylistFail=Failed to upload playlist to hastebin.com -listShowShuffled=Showing shuffled playlist. -listShowRepeatSingle=Repeating current track. -listShowRepeatAll=Repeating current queue. -listShowHistory=Showing tracks in history. -listAddedBy=**{0}** added by **{1}** `[{2}]` -listStreamsOnlySingle=There is **{0}** live {1} in the queue. -listStreamsOnlyMultiple=There are **{0}** live {1} in the queue. -listStreamsOrTracksSingle=There is **{0}** {1} with a remaining length of **[{2}]**{3} in the queue. -listStreamsOrTracksMultiple=There are **{0}** {1} with a remaining length of **[{2}]**{3} in the queue. +joinErrorAlreadyJoining=Satu ralat telah berlaku. Tidak dapat menyertai {0} kerana saya telah cuba untuk menyambung ke saluran itu. Sila cuba lagi. +pauseAlreadyPaused=Pemain telah dihentikan sementara. +pauseSuccess=Pemain sedang dihentikan sementara. Anda boleh mainkan semula dengan ''{0}main''. +repeatOnSingle=Pemain akan mengulang semula trek semasa. +repeatOnAll=Pemain akan mengulang semula aturan. +repeatOff=Pemain tidak akan lagi mengulang. +selectSuccess=Lagu **\#{0} ** telah dipilih\: **{1} ** ({2}) +selectInterval=Mestilah nombor 1-{0}. +selectSelectionNotGiven=Anda mesti terlebih dahulu diberi pilihan untuk memilih. +shuffleOn=Pemain sekarang akan 'shuffled'. +shuffleOff=Pemain sekarang tidak lagi 'shuffled'. +reshufflePlaylist=Aturan telah di'shuffle' semula. +reshufflePlayerNotShuffling=Anda mesti menghidupkan mod 'shuffle'. +skipEmpty=Aturan masih kosong\! +skipOutOfBounds=Tidak dapat mengalih keluar {0} nombor aturan apabila terdapat hanya {1} aturan. +skipNumberTooLow=Nombor yang diberi mestilah lebih daripada 0. +skipSuccess=Skip trek \#{0}\: **{1} ** +skipRangeInvalid=Pelbagai trek yang ditentukan tidak sah. +skipRangeSuccess=Trek \#{0} untuk \#{1} telah dibuang. +skipTrackNotFound=Tidak dapat mencari trek yang betul untuk di skip. +stopAlreadyEmpty=Aturan sudah kosong. +stopEmptyOne=Aturan yang telah dikosongkan, trek '1' telah dikeluarkan. +stopEmptySeveral=Aturan yang telah dikosongkan, trek `{0}` telah dikeluarkan. +stopAccessDenied=Untuk mengelakkan penyalahgunaan, command ini hanya disediakan untuk orang yang boleh menguruskan mesej. +unpauseQueueEmpty=Aturan masih kosong. +unpausePlayerNotPaused=Pemain tidak dihentikan. +unpauseNoUsers=Tiada pengguna yang terdapat dalam voice chat. +unpauseSuccess=Pemain sekarang tidak lagi dihentikan. +volumeApology=Maaf\! Command ;;volume kini telah tidak digalakkan atas bot muzik awam. Ini adalah kerana ia menyebabkan bot untuk menghabiskan lebih banyak masa pemprosesan audio, beberapa trek sehingga 5 kali lebih, menyebabkan semua pengguna mendengar stutter. Dengan menyahdayakan command ini, FredBoat boleh mainkan muzik lebih tanpa lag. \nSaya cadangkan menetapkan jumlah bot yang melalui menu https\://fred.moe/1vD.png +volumeSyntax=Gunakan '';;volume <0-150>''. {0}% adalah default. Para pemain sedang pada **{1}% **. +volumeSuccess=Menukar volume dari **{0}% ** ke **{1}% **. +exportEmpty=Tiada apa-apa untuk dieksport, aturan adalah kosong. +exportPlaylistResulted=Senarai yang dieksport\: {0}\nAnda boleh berikan URL ini untuk memainkan senarai main semasa nanti. +exportPlaylistFail=Gagal untuk muat naik senarai main ke hastebin.com +listShowShuffled=Menunjukkan senarai main shuffled. +listShowRepeatSingle=Mengulang semula trek semasa. +listShowRepeatAll=Mengulang semula aturan semasa. +listShowHistory=Menunjukkan history trek. +listAddedBy=**{0} ** ditambah oleh **{1} ** ''[{2}]'' +listStreamsOnlySingle=Terdapat **{0} ** yang live {1} dalam aturan. +listStreamsOnlyMultiple=Terdapat **{0} ** yang live {1} dalam aturan. +listStreamsOrTracksSingle=Terdapat **{0} ** {1} dengan masa yang tinggal selama ** [{2}] **{3} dalam aturan. +listStreamsOrTracksMultiple=Terdapat **{0} ** {1} dengan masa yang tinggal selama ** [{2}] **{3} dalam aturan. streamSingular=stream streamPlural=streams -listAsWellAsLiveStreams=, as well as **{0}** live {1} -trackSingular=track -trackPlural=tracks -npNotPlaying=Not currently playing anything. -npNotInHistory=Currently no tracks in history. +listAsWellAsLiveStreams=, serta **{0} ** {1} yang live +trackSingular=trek +trackPlural=treks +npNotPlaying=Tidak memainkan apa-apa. +npNotInHistory=Tiada dalam history trek yang terkini. npDescription=Description npLoadedSoundcloud=[{0}/{1}]\n\nLoaded from Soundcloud npLoadedBandcamp={0}\n\nLoaded from Bandcamp @@ -112,36 +112,36 @@ malEnglishTitle={0}**English\: **{1}\n malSynonyms={0}**Synonyms\: **{1}\n malEpisodes={0}**Episodes\: **{1}\n malScore={0}**Score\: **{1}\n -malType={0}**Type\: **{1}\n -malStatus={0}**Status\: **{1}\n -malStartDate={0}**Start date\: **{1}\n -malEndDate={0}**End date\: **{1} -malSynopsis={0}**Synopsis\: **"{1}"\n -malUserReveal={0}\: Search revealed a user.\n -malNoResults={0}\: No results. -malUserName={0}**Name\: **{1}\n -malUrl={0}**URL\: **{1}\n -luaError=\ A Lua error occured \:anger\:\n```{0}``` -luaErrorOutputTooBig=\ Output buffer is too large \:anger\: Discord only allows 2000 characters per message, got {0} -luaTimeout=\ Function timed out \:anger\: allowed computation time is {0} seconds. -helpSuccess=Documentation has been sent to your direct messages\! -helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! -helpCommandsPromotion=Say {0} to learn what this bot can do\! -fuzzyNoResults=No such users -brainfuckCycleLimit=Program exceeded the maximum cycle count of {0} -brainfuckDataPointerOutOfBounds=Data pointer out of bounds\: {0} -brainfuckInputOOB=Input out of bounds at position\: {0} -brainfuckNoOutput=\ There was no output -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} -avatarSuccess=\ found it\n{0} -configNoArgs=Configuration for **{0}**\:``` -configSetTo=is now set to `{0}`. -configUnknownKey={0}\: Unknown key. -configMustBeBoolean={0}\: Value must be true or false. -modReason=Reason -modAuditLogMessage=Action issued by {0}\#{1} [{2}] -modFailUserHierarchy=You do not have a higher role than {0}. +malType={0} ** jenis\: **{1}\n +malStatus={0} ** Status\: **{1}\n +malStartDate={0} ** Tarikh mula\: **{1}\n +malEndDate={0} ** Tarikh berhenti\: **{1} +malSynopsis={0} ** Sinopsis\: ** "{1}"\n +malUserReveal={0}\: Carian telah mendedahkan seorang pengguna.\n +malNoResults={0}\: Tiada keputusan. +malUserName={0} ** Nama\: **{1}\n +malUrl={0} ** URL\: **{1}\n +luaError=\ Satu error Lua berlaku \:anger\: ''''''{0} '''''' +luaErrorOutputTooBig=\ Penampan output adalah terlalu besar \:anger\: perbalahan hanya membenarkan lingkungan 2000 huruf setiap mesej, mendapat {0} +luaTimeout=\ Majlis tamat \:anger\: dibenarkan pengiraan masa ialah {0} saat. +helpSuccess=Dokumentasi telah dihantar ke mesej anda langsung\! +helpDmFailed=Tidak dapat menghantar dokumentasi untuk DMs anda. Sila pastikan bahawa anda tidak mempunyai Upaya\! +helpCommandsPromotion=Katakan {0} untuk belajar apa yang bot ini boleh lakukan\! +fuzzyNoResults=Tiada pengguna tersebut +brainfuckCycleLimit=Program melebihi kiraan kitaran maksimum {0} +brainfuckDataPointerOutOfBounds=Penuding data daripada batas-batas\: {0} +brainfuckInputOOB=Input daripada batas-batas di posisi\: {0} +brainfuckNoOutput=\ Jadilah output tidak +weatherLocationNotFound=Tidak dapat mencari lokasi, sila semak {0} input anda. +weatherError=Ralat mendapatkan keadaan cuaca di {0} +avatarSuccess=\ mendapati{0} +configNoArgs=Konfigurasi untuk **{0} **\:'''' '' +configSetTo=kini sudah bersedia untuk ''{0}''. +configUnknownKey={0}\: kekunci tidak diketahui. +configMustBeBoolean={0}\: nilai mestilah benar atau palsu. +modReason=Sebab +modAuditLogMessage=Tindakan yang dikeluarkan oleh {0}\#{1} [{2}] +modFailUserHierarchy=Anda tidak mempunyai peranan yang lebih tinggi daripada {0}. modFailBotHierarchy=I need to have a higher role than {0}. modBanFail=Failed to ban {0} modKickBanFailUserPerms=You must have permission to kick and ban to be able to use this command. diff --git a/FredBoat/src/main/resources/lang/nl_NL.properties b/FredBoat/src/main/resources/lang/nl_NL.properties index c0750636a..432b3400a 100644 --- a/FredBoat/src/main/resources/lang/nl_NL.properties +++ b/FredBoat/src/main/resources/lang/nl_NL.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Je gebruikt de opdrachten te snel\! Langzamer aan, alsjeb ratelimitedSkipCommand=Je kunt meer dan 1 nummer overslaan met deze opdracht\: {0} ratelimitedGuildSlowLoadingPlaylist=Op deze server is niet toegestaan om meer afspeellijsten toe te voegen op dit moment, gelieve geen lange afspeellijsten herhaaldelijk aan te vragen. unblacklisted={0} is verwijderd van de Zwarte lijst. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Info over **{0}**\: serverinfoOnlineUsers=Online Gebruikers\: serverinfoTotalUsers=Totaal Aantal Gebruikers\: serverinfoRoles=Rollen\: @@ -193,7 +193,7 @@ serverinfoGuildID=Gilde ID\: serverinfoCreationDate=Aanmaakdatum\: serverinfoOwner=Eigenaar\: serverinfoVLv=Verificatie Level\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informatie over {0}\: userinfoUsername=Gebruikersnaam\: userinfoId=ID\: userinfoNick=Bijnaam\: @@ -212,11 +212,11 @@ commandsMaintenance=Onderhoud commandsBotOwner=Bot eigenaar commandsMoreHelp=Zeg {0} om meer informatie te krijgen over een specifieke opdracht. helpUnknownCommand=Onbekende opdracht. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Documentatie kan worden gevonden op\: +helpBotInvite=Wilt u FredBoat aan uw server toevoegen? Als u gemachtigd bent deze Server te beheren voor uw gilde, kunt u FredBoat uitnodigen\: +helpHangoutInvite=Hulp nodig of nog idee\u00ebn voor FredBoat? Misschien wilt u gewoon hangen? Voeg u bij FredBoats gemeenschap\! +helpNoDmCommands=U kunt geen FredBoat commandos verzenden via DMs. +helpCredits=Gemaakt door Fre_d en opensource leverden helpSent=De documenten met instructies zijn naar Uw Directe Berichten verstuurd\! helpProperUsage=Correcte gebruik\: helpCommandOwnerRestricted=Deze opdracht is beperkt tot de eigenaar van de bot. @@ -229,7 +229,7 @@ helpMusicCommandsHeader=FredBoat Muziek Opdrachten helpJoinCommand=Voeg de bot aan je huidige stemkanaal toe. helpLeaveCommand=Laat de bot je huidige stemkanaal verlaten. helpPauseCommand=Pauzeer de Bot. -helpPlayCommand=Speel muziek van de gegeven URL of zoek naar een nummer. Bezoek {0} voor een volledige lijst van bronnen +helpPlayCommand=Speel muziek van de gegeven URL of zoek naar een nummer. Bezoek alsjeblieft {0} voor een volledige lijst van bronnen helpPlaySplitCommand=Verdeel een YouTube video in een nummerreeks voorzien in zijn descriptie. helpRepeatCommand=Schakel tussen herhaal modi. helpReshuffleCommand=Schuifel de huidige nummerreeks opnieuw. diff --git a/FredBoat/src/main/resources/lang/pt_BR.properties b/FredBoat/src/main/resources/lang/pt_BR.properties index c482e3c31..998d55c97 100644 --- a/FredBoat/src/main/resources/lang/pt_BR.properties +++ b/FredBoat/src/main/resources/lang/pt_BR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Voc\u00ea est\u00e1 sendo taxa limitada\! Por favor, deva ratelimitedSkipCommand=Voc\u00ea pode pular mais de uma m\u00fasica usando este comando\: {0} ratelimitedGuildSlowLoadingPlaylist=Neste servidor n\u00e3o \u00e9 permitido adicionar playlists mais neste momento. Por favor n\u00e3o spam longas listas de reprodu\u00e7\u00e3o. unblacklisted={0} removido da lista negra. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Informa\u00e7\u00e3o sobre {0}\: serverinfoOnlineUsers=Usu\u00e1rios online\: serverinfoTotalUsers=Total de usu\u00e1rios\: serverinfoRoles=Pap\u00e9is\: @@ -193,7 +193,7 @@ serverinfoGuildID=ID da Guilda\: serverinfoCreationDate=Data de cria\u00e7\u00e3o\: serverinfoOwner=Dono\: serverinfoVLv=N\u00edvel de Verifica\u00e7\u00e3o\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informa\u00e7\u00f5es sobre {0}\: userinfoUsername=Nome de Usu\u00e1rio\: userinfoId=ID\: userinfoNick=Nickname\: @@ -212,11 +212,11 @@ commandsMaintenance=Manuten\u00e7\u00e3o commandsBotOwner=Dono do Bot commandsMoreHelp=Diga {0} para obter mais informa\u00e7\u00f5es sobre um comando espec\u00edfico. helpUnknownCommand=Comando desconhecido. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Documenta\u00e7\u00e3o pode ser encontrada em\: +helpBotInvite=Deseja adicionar FredBoat ao seu servidor? Se voc\u00ea tiver a permiss\u00e3o Gerenciar Servidor na sua guilda, voc\u00ea pode convidar FredBoat\: +helpHangoutInvite=Precisar de ajuda ou tem alguma ideia para o FredBoat? Talvez voc\u00ea s\u00f3 quer bater um papo? Participe da Comunidade FredBoat\! +helpNoDmCommands=Voc\u00ea n\u00e3o pode enviar comandos do FredBoat atrav\u00e9s de DMs. +helpCredits=Criado por Fre_d e contribuidores open source helpSent=Documenta\u00e7\u00e3o foi enviada para seus DMs\! helpProperUsage=Uso correto\: helpCommandOwnerRestricted=Este comando \u00e9 restrito para o dono do bot. @@ -301,5 +301,5 @@ mathOperationDivisionByZeroError=Eu n\u00e3o posso dividir por zero. mathOperationInfinity=O n\u00famero \u00e9 muito grande para ser exibido\! prefix=Prefixo prefixGuild=O prefixo para essa guild \u00e9 {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefixShowAgain=Voc\u00ea pode mostrar o prefixo novamente a qualquer momento me mencionando. diff --git a/FredBoat/src/main/resources/lang/pt_PT.properties b/FredBoat/src/main/resources/lang/pt_PT.properties index 063a33098..c31b161ae 100644 --- a/FredBoat/src/main/resources/lang/pt_PT.properties +++ b/FredBoat/src/main/resources/lang/pt_PT.properties @@ -45,7 +45,7 @@ exportPlaylistFail=Falha ao carregar a lista para hastebin.com listShowShuffled=A exibir lista emparelhada.\n\n listShowRepeatSingle=Repetindo a faixa atual. listShowRepeatAll=Repetindo a fila atual. -listShowHistory=Showing tracks in history. +listShowHistory=A mostrar faixas anteriores. listAddedBy=**{0}** foi adicionado por **{1}** `[{2}]` listStreamsOnlySingle=H\u00e1 * *{0} * * {1} ao vivo na fila. listStreamsOnlyMultiple=Existem * *{0} * * {1} ao vivo na fila. @@ -57,7 +57,7 @@ listAsWellAsLiveStreams=, assim como **{0}** {1} ao vivo trackSingular=faixa trackPlural=faixas npNotPlaying=N\u00e3o estou tocando nada. -npNotInHistory=Currently no tracks in history. +npNotInHistory=N\u00e3o existem faixas na sua historia. npDescription=Descrip\u00e7\u00e3o npLoadedSoundcloud=[{0}/{1}] \n\nCarregado do Soundcloud npLoadedBandcamp={0} \n\nCarregado do Bandcamp @@ -79,7 +79,7 @@ restartSuccess=* *{0} * * foi reiniciado. queueEmpty=A fila est\u00e1 vazia. rewSuccess=Rebobinando de **{0}** por {1}. seekSuccess=Procurando de **{0}** a {1}. -seekDeniedLiveTrack=You can't seek a live track. +seekDeniedLiveTrack=Voee n\u00e3o pode avancar/recuar numa musica/transmiss\u00e3o ao vivo. loadPlaySplitListFail=Esse link \u00e9 de uma playlist, n\u00e3o de uma faixa. Experimente `;;play` em vez disso. loadListSuccess=Encontrando e adicionadas`{0}` m\u00fasicas da lista **{1}**. loadNoMatches=Nenhum audio p\u00f4de ser encontrado para ''{0}''. @@ -125,15 +125,15 @@ luaError=\ Ocorreu um erro Lua \:anger\: ```{0}``` luaErrorOutputTooBig=\ Buffer de s\u00e1ida \u00e9 muito largo \:anger\: a Discord s\u00f3 permite 2000 caracteres por mensagem, got {0} luaTimeout=\ Fun\u00e7\u00e3o expirou \:anger\: tempo de computa\u00e7\u00e3o permitido \u00e9 {0} segundos. helpSuccess=A documenta\u00e7\u00e3o foi enviada para suas mensagens diretas\! -helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! +helpDmFailed=N\u00e3o consegui enviar a documenta\u00e7\u00e3o para os seus DMs. Por favor verifique que n\u00e3o as tem desactivadas\! helpCommandsPromotion=Diga {0} para saber o que esse bot pode fazer\! fuzzyNoResults=Sem tais usu\u00e1rios brainfuckCycleLimit=Programa excedeu a contagem de ciclo m\u00e1ximo de {0} brainfuckDataPointerOutOfBounds=Ponteiro de datas fora dos limites\: {0} brainfuckInputOOB=Entrada fora dos limites na posi\u00e7\u00e3o\: {0} brainfuckNoOutput=\ N\u00e3o havia nenhuma sa\u00edda -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} +weatherLocationNotFound=N\u00e3o foi possivel encontrar essa localiza\u00e7\u00e3o, por favor verifique os seus argumentos {0}. +weatherError=Erro a buscar o tempo para {0} avatarSuccess=\ achei\n{0} configNoArgs=Configura\u00e7\u00e3o para **{0}**\:``` configSetTo=agora est\u00e1 definido para `{0}`. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Voc\u00ea est\u00e1 sendo taxa limitada\! Por favor, abra ratelimitedSkipCommand=Voc\u00ea podes pular mais que uma m\u00fasica usando este comando\: {0} ratelimitedGuildSlowLoadingPlaylist=Neste servidor n\u00e3o \u00e9 permitido adicionar mais playlists de momento. Por favor n\u00e3o spame longas listas de reprodu\u00e7\u00e3o. unblacklisted={0} removido da lista negra. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Informa\u00e7\u00e3o sobre {0}\: serverinfoOnlineUsers=Usu\u00e1rios online\: serverinfoTotalUsers=Total de usu\u00e1rios\: serverinfoRoles=Fun\u00e7\u00f5es\: @@ -193,17 +193,17 @@ serverinfoGuildID=ID de guilda\: serverinfoCreationDate=Data de cria\u00e7\u00e3o\: serverinfoOwner=Propriet\u00e1rio\: serverinfoVLv=N\u00edvel de verifica\u00e7\u00e3o\: -userinfoTitle=Information about {0}\: +userinfoTitle=Informa\u00e7\u00e3o sobre {0}\: userinfoUsername=Nome de usu\u00e1rio\: userinfoId=ID\: userinfoNick=Usu\u00e1rio\: userinfoKnownServer=Servidores conhecidos\: userinfoJoinDate=Data de entrada\: userinfoCreationTime=Data de cria\u00e7\u00e3o\: -userinfoBlacklisted=Blacklisted\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +userinfoBlacklisted=Bloqueado\: +skipDeniedTooManyTracks=N\u00e3o podes passar a musica de outra pessoa se n\u00e3o fores o DJ\nConsidera usar o commando Voteskip. eventUsersLeftVC=Todos os usu\u00e1rios deixaram o canal de voz. O reprodutor foi pausado. -eventAutoResumed=User presence detected, automatically resuming the player. +eventAutoResumed=Foi detectada a presen\u00e7a de um utilizador foi resumido automaticamente a musica. commandsFun=Divers\u00e3o commandsMemes=Memes commandsUtility=Utilit\u00e1rio de @@ -212,11 +212,11 @@ commandsMaintenance=Manuten\u00e7\u00e3o commandsBotOwner=Dono do bot commandsMoreHelp=Diga {0} para obter mais informa\u00e7\u00f5es sobre um comando espec\u00edfico. helpUnknownCommand=Comando desconhecido. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=A documenta\u00e7\u00e3o pode ser encontrada em\: +helpBotInvite=Queres adicionar o FredBoat ao teu server? Se tens permiss\u00f5es administrativas, tu podes convdar o FredBoat aqui\: +helpHangoutInvite=Percisas de ajuda ou tens algumas ideias para o FredBoad? Ou se calhar apenas queres conviver? Junta-te a communidade FredBoat\! +helpNoDmCommands=N\u00e3o podes enviar commandos por DMs. +helpCredits=Criado por Fre_d e contribuidores de Git Hub helpSent=A documenta\u00e7\u00e3o foi enviada para as suas mensagens privadas\! helpProperUsage=Uso correto\: helpCommandOwnerRestricted=Este comando \u00e9 restrito para o dono do bot. @@ -229,20 +229,20 @@ helpMusicCommandsHeader=Comandos de M\u00fasica do FredBoat helpJoinCommand=Fa\u00e7a o bot entrar no seu atual canal de voz. helpLeaveCommand=Fa\u00e7a o bot sair do atual canal de voz. helpPauseCommand=Pause o player. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=Toque m\u00fasica pelo o dado URL ou pesquisa pela faixa. Para uma lista cheia de fontes viste {0} helpPlaySplitCommand=Dividi um v\u00eddeo do YouTube em um tracklist fornecido na descri\u00e7\u00e3o do que \u00e9. helpRepeatCommand=Alternar entre modos de repeti\u00e7\u00e3o. helpReshuffleCommand=Reorganizar a fila atual. helpSelectCommand=Selecione uma das faixas oferecidas depois de uma busca para reproduzir. helpShuffleCommand=Alternar modo de reorganiza\u00e7\u00e3o da fila atual. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpSkipCommand=Ignore a m\u00fasica atual, a can\u00e7\u00e3o de n'th na fila ou todas as m\u00fasicas de n para m. Por favor, use com modera\u00e7\u00e3o. helpStopCommand=Pare o reprodutor e limpe a lista de reprodu\u00e7\u00e3o. Reservado para moderadores com permiss\u00e3o de gerenciar mensagens. helpUnpauseCommand=Despausar o reprodutor. helpVolumeCommand=Altera o volume. Os valores s\u00e3o 0-150 e 100 \u00e9 o padr\u00e3o. O comando de volume \u00e9 preterido no p\u00fablico bot. helpExportCommand=Exportar a fila atual para um link de hastebin, pode ser usado mais tarde como uma lista de reprodu\u00e7\u00e3o. helpGensokyoRadioCommand=Mostrar a atual m\u00fasica tocada na gensokyoradio.net helpListCommand=Exibir uma lista de m\u00fasicas atuais na lista de reprodu\u00e7\u00e3o. -helpHistoryCommand=Display a list of the songs in playlist history. +helpHistoryCommand=Mostra uma lista de musicas na historia da playlist. helpNowplayingCommand=Exiba a m\u00fasica que est\u00e1 tocando. helpForwardCommand=Avancei a faixa por um determinado per\u00edodo de tempo. Exemplo\: helpRestartCommand=Reinicie a faixa atualmente sendo reproduzida. diff --git a/FredBoat/src/main/resources/lang/sv_SE.properties b/FredBoat/src/main/resources/lang/sv_SE.properties index 52e9a68bf..ce09a9709 100644 --- a/FredBoat/src/main/resources/lang/sv_SE.properties +++ b/FredBoat/src/main/resources/lang/sv_SE.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Du skickar kommandon f\u00f6r snabbt\! Sakta ner grabben. ratelimitedSkipCommand=Du kan hoppa \u00f6ver mer \u00e4n en l\u00e5t genom att anv\u00e4nda detta kommando\: {0} ratelimitedGuildSlowLoadingPlaylist=Denna server f\u00e5r inte skapa mer spellistor f\u00f6r tillf\u00e4llet. Var sn\u00e4ll och spamma inte med l\u00e5nga spellistor. unblacklisted=Tog bort {0} fr\u00e5n svarta listan. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Info om {0}\: serverinfoOnlineUsers=Anv\u00e4ndare online\: serverinfoTotalUsers=Antal anv\u00e4ndare\: serverinfoRoles=Roller\: @@ -193,7 +193,7 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Skapades\: serverinfoOwner=\u00c4gare\: serverinfoVLv=Kontroll niv\u00e5\: -userinfoTitle=Information about {0}\: +userinfoTitle=Information om {0}\: userinfoUsername=Anv\u00e4ndarnamn\: userinfoId=ID\: userinfoNick=Smeknamn\: @@ -212,11 +212,11 @@ commandsMaintenance=Underh\u00e5ll commandsBotOwner=Bot\u00e4gare commandsMoreHelp=Skriv {0} f\u00f6r att f\u00e5 specifik information f\u00f6r ett kommando. helpUnknownCommand=Ok\u00e4nt kommando. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Dokumentation kan hittas p\u00e5\: +helpBotInvite=Vill du l\u00e4gga till FredBoat till din server? Har du hantera Server-beh\u00f6righeter f\u00f6r din guild, kan du bjuda in FredBoat\: +helpHangoutInvite=Beh\u00f6ver du hj\u00e4lp eller har n\u00e5gra id\u00e9er f\u00f6r FredBoat? Kanske vill du bara umg\u00e5s? G\u00e5 med i FredBoat community\! +helpNoDmCommands=Du kan inte skicka FredBoat kommandon via DMs. +helpCredits=Skapad av Fre_d och \u00f6ppen k\u00e4llkod bidragsgivare helpSent=Info har skickats direkt till dig\! helpProperUsage=R\u00e4tt anv\u00e4ndning\: helpCommandOwnerRestricted=Detta kommando \u00e4r endast tillg\u00e4ngligt f\u00f6r bot\u00e4garen. diff --git a/FredBoat/src/main/resources/lang/tr_TR.properties b/FredBoat/src/main/resources/lang/tr_TR.properties index 12aa1c77e..dd5ce38f3 100644 --- a/FredBoat/src/main/resources/lang/tr_TR.properties +++ b/FredBoat/src/main/resources/lang/tr_TR.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=Oran\u0131 k\u0131s\u0131tl\u0131yorsun\! L\u00fctfen yav ratelimitedSkipCommand=Bu komutu kullanarak birden fazla \u015fark\u0131 ge\u00e7ebilirsiniz\: {0} ratelimitedGuildSlowLoadingPlaylist=Bu sunucunun \u015fu anda daha fazla oynatma listesi eklemesine izin verilmez. L\u00fctfen uzun \u00e7alma listeleriyle spam g\u00f6ndermeyin. unblacklisted=Kara listeden {0} kald\u0131r\u0131ld\u0131. -serverinfoTitle=Info about {0}\: +serverinfoTitle={0} hakk\u0131nda bilgi\: serverinfoOnlineUsers=Aktif kullan\u0131c\u0131lar\: serverinfoTotalUsers=Toplam Kullan\u0131c\u0131\: serverinfoRoles=Roller\: @@ -193,7 +193,7 @@ serverinfoGuildID=Klan ID\: serverinfoCreationDate=Olu\u015fturulma Tarihi\: serverinfoOwner=Sahibi\: serverinfoVLv=Do\u011frulama Seviyesi\: -userinfoTitle=Information about {0}\: +userinfoTitle={0} hakk\u0131nda bilgi\: userinfoUsername=Kullan\u0131c\u0131 ad\u0131\: userinfoId=ID\: userinfoNick=Rumuzu\: @@ -212,11 +212,11 @@ commandsMaintenance=Bak\u0131m commandsBotOwner=Bot sahibi commandsMoreHelp=Belirli bir komutla ilgili daha fazla bilgi almak i\u00e7in {0} yaz. helpUnknownCommand=Bilinmeyen komut. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=Belgeler \u015furada bulunabilir\: +helpBotInvite=FredBoat'\u0131 sunucunuza eklemek ister misiniz? E\u011fer eklemek istedi\u011finiz sunucuda "Sunucuyu Y\u00f6net" yetkiniz varsa, FredBoat'\u0131 buradan davet edebilirsiniz\: +helpHangoutInvite=FredBoat hakk\u0131nda yard\u0131ma ihtiyac\u0131n\u0131z m\u0131 var ya da akl\u0131n\u0131za herhangi bir fikir mi geldi? Ya da sadece tak\u0131lmak m\u0131 istiyorsunuz? FredBoat toplulu\u011funa kat\u0131l\u0131n\! +helpNoDmCommands=FredBoat komutlar\u0131n\u0131 DM \u00fczerinden g\u00f6nderemezsiniz. +helpCredits=Fre_d ve a\u00e7\u0131k kaynak destek\u00e7ileri taraf\u0131ndan olu\u015fturuldu helpSent=D\u00f6k\u00fcmanlar DM ile g\u00f6nderildi\! helpProperUsage=Do\u011fru kullan\u0131m\: helpCommandOwnerRestricted=Bu komutu sadece bot sahibi kullanabilir. @@ -261,7 +261,7 @@ helpSayCommand=Botun sizin yazd\u0131\u011f\u0131n\u0131z \u015feyi yazmas\u0131 helpServerInfoCommand=Bu klan hakk\u0131nda baz\u0131 istatistikleri g\u00f6r\u00fcnt\u00fcler. helpUserInfoCommand=Kendiniz veya bot i\u00e7in bilinen bir kullan\u0131c\u0131 hakk\u0131ndaki bilgileri g\u00f6r\u00fcnt\u00fcler. helpPerms={0} s\u0131ralamas\u0131 i\u00e7in beyaz listeye eklenen \u00fcyelere ve rollere izin verir. -helpPrefixCommand=Set the prefix for this guild. +helpPrefixCommand=L\u00fctfen sunucunuz i\u00e7in bir "prefix" ayarlay\u0131n. helpVoteSkip=\u00c7alan \u015fark\u0131y\u0131 atlamak i\u00e7in oylama yap. Sohbetteki kullan\u0131c\u0131lar\u0131n en az %50'sinin oyu gereklidir. helpMathOperationAdd=num1 + num2 sonucunu yazd\u0131r. helpMathOperationSub=num1 - num2 sonucunu yazd\u0131r. @@ -300,6 +300,6 @@ mathOperationResult=Sonu\u00e7 mathOperationDivisionByZeroError=S\u0131f\u0131ra b\u00f6lemem. mathOperationInfinity=Say\u0131 g\u00f6r\u00fcnt\u00fclemek i\u00e7in \u00e7ok b\u00fcy\u00fck\! prefix=\u00d6n ek -prefixGuild=The prefix for this guild is {0} +prefixGuild=Bu sunucu i\u00e7in prefix\: {0} prefixShowAgain=Her zaman benden bahsederek (mention) \u00f6n eki ortaya \u00e7\u0131karabilirsiniz. diff --git a/FredBoat/src/main/resources/lang/vi_VN.properties b/FredBoat/src/main/resources/lang/vi_VN.properties index 8cf6f2cbc..f9390f760 100644 --- a/FredBoat/src/main/resources/lang/vi_VN.properties +++ b/FredBoat/src/main/resources/lang/vi_VN.properties @@ -45,7 +45,7 @@ exportPlaylistFail=T\u1ea3i danh s\u00e1ch l\u00ean hastebin.com kh\u00f4ng th\u listShowShuffled=Hi\u1ec3n th\u1ecb danh s\u00e1ch ph\u00e1t \u0111ang x\u00e1o tr\u1ed9n. listShowRepeatSingle=\u0110ang l\u1eb7p l\u1ea1i b\u00e0i hi\u1ec7n t\u1ea1i. listShowRepeatAll=\u0110ang l\u1eb7p l\u1ea1i h\u00e0ng ch\u1edd hi\u1ec7n t\u1ea1i. -listShowHistory=Showing tracks in history. +listShowHistory=Hi\u1ec3n th\u1ecb b\u00e0i h\u00e1t trong l\u1ecbch s\u1eed. listAddedBy=**{0}** \u0111\u00e3 \u0111\u01b0\u1ee3c th\u00eam b\u1edfi **{1}** `[{2}]` listStreamsOnlySingle=C\u00f3 **{0}** \u0111ang ch\u1edd {1} trong h\u00e0ng \u0111\u1ee3i. listStreamsOnlyMultiple=C\u00f3 **{0}** \u0111ang ch\u1edd {1} trong h\u00e0ng \u0111\u1ee3i. @@ -79,7 +79,7 @@ restartSuccess=**{0}** \u0111\u00e3 \u0111\u01b0\u1ee3c kh\u1edfi \u0111\u1ed9ng queueEmpty=H\u00e0ng \u0111\u1ee3i \u0111ang tr\u1ed1ng. rewSuccess=\u0110ang tua l\u1ea1i **{0}** b\u1edfi {1}. seekSuccess=\u0110ang t\u00ecm ki\u1ebfm t\u1eeb **{0}** \u0111\u1ebfn {1}. -seekDeniedLiveTrack=You can't seek a live track. +seekDeniedLiveTrack=B\u1ea1n kh\u00f4ng th\u1ec3 t\u00ecm ki\u1ebfm ca kh\u00fac n\u00e0y. loadPlaySplitListFail=Li\u00ean k\u1ebft \u0111\u00f3 d\u1eabn \u0111\u1ebfn m\u1ed9t danh s\u00e1ch ph\u00e1t, kh\u00f4ng ph\u1ea3i l\u00e0 m\u1ed9t b\u00e0i h\u00e1t. H\u00e3y thay th\u1ebf b\u1eb1ng `;;play`. loadListSuccess=\u0110\u00e3 t\u00ecm \u0111\u01b0\u1ee3c v\u00e0 th\u00eam ''{0} b\u00e0i h\u00e1t t\u1eeb danh s\u00e1ch ph\u00e1t **{1}**. loadNoMatches=Kh\u00f4ng c\u00f3 \u00e2m thanh \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y cho `{0}`. @@ -125,15 +125,15 @@ luaError=\ \u0110\u00e3 x\u1ea3y ra l\u1ed7i Lua \:anger\:\n```{0}``` luaErrorOutputTooBig=\ B\u1ed9 \u0111\u1ec7m \u0111\u1ea7u ra l\u00e0 qu\u00e1 l\u1edbn \:anger\: Discord ch\u1ec9 cho ph\u00e9p 2000 k\u00fd t\u1ef1 cho tin nh\u1eafn, \u0111\u00e3 ghi {0} luaTimeout=\ Ch\u1ee9c n\u0103ng \u0111\u00e3 qu\u00e1 gi\u1edd \:anger\: cho ph\u00e9p t\u00ednh to\u00e1n th\u1eddi gian l\u00e0 {0} gi\u00e2y. helpSuccess=T\u00e0i li\u1ec7u h\u01b0\u1edbng d\u1eabn \u0111\u00e3 \u0111\u01b0\u1ee3c g\u1eedi tr\u1ef1c ti\u1ebfp cho b\u1ea1n\! -helpDmFailed=Could not send documentation to your DMs. Please check that you don't have them disabled\! +helpDmFailed=C\u00f3 th\u1ec3 kh\u00f4ng g\u1eedi t\u00e0i li\u1ec7u c\u1ee7a b\u1ea1n DMs. H\u00e3y ki\u1ec3m tra r\u1eb1ng b\u1ea1n kh\u00f4ng c\u00f3 h\u1ecd v\u00f4 hi\u1ec7u h\u00f3a\! helpCommandsPromotion=Chat {0} \u0111\u1ec3 t\u00ecm hi\u1ec3u bot n\u00e0y c\u00f3 th\u1ec3 l\u00e0m \u0111\u01b0\u1ee3c g\u00ec\! fuzzyNoResults=Kh\u00f4ng c\u00f3 ng\u01b0\u1eddi d\u00f9ng n\u00e0y brainfuckCycleLimit=Ch\u01b0\u01a1ng tr\u00ecnh \u0111\u00e3 v\u01b0\u1ee3t qu\u00e1 s\u1ed1 l\u1ea7n l\u1eb7p l\u1ea1i t\u1ed1i \u0111a l\u00e0 {0} brainfuckDataPointerOutOfBounds=Con tr\u1ecf d\u1eef li\u1ec7u n\u1eb1m ngo\u00e0i gi\u1edbi h\u1ea1n\: {0} brainfuckInputOOB=Nh\u1eadp n\u1eb1m ngo\u00e0i gi\u1edbi h\u1ea1n\: {0} brainfuckNoOutput=\ Kh\u00f4ng c\u00f3 \u0111\u1ea7u ra -weatherLocationNotFound=Unable to find location, please check your input {0}. -weatherError=Error retrieving weather for {0} +weatherLocationNotFound=Kh\u00f4ng th\u1ec3 t\u00ecm th\u1ea5y \u0111\u1ecba \u0111i\u1ec3m, h\u00e3y ki\u1ec3m tra \u0111\u1ecbnh v\u1ecb c\u1ee7a b\u1ea1n {0}. +weatherError=Kh\u00f4ng th\u1ec3 hi\u1ec3n th\u1ecb th\u1eddi ti\u1ebft cho {0} avatarSuccess=\ \u0111\u00e3 t\u00ecm th\u1ea5y\n{0} configNoArgs=C\u1ea5u h\u00ecnh cho **{0}**\:``` configSetTo=hi\u1ec7n \u0111\u01b0\u1ee3c thi\u1ebft l\u1eadp th\u00e0nh `{0}`. @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=B\u1ea1n \u0111ang b\u1ecb gi\u1edbi h\u1ea1n\! H\u00e3y ratelimitedSkipCommand=B\u1ea1n c\u00f3 th\u1ec3 b\u1ecf qua nhi\u1ec1u h\u01a1n m\u1ed9t b\u00e0i h\u00e1t b\u1eb1ng c\u00e1ch d\u00f9ng l\u1ec7nh\: {0} ratelimitedGuildSlowLoadingPlaylist=M\u00e1y ch\u1ee7 n\u00e0y kh\u00f4ng \u0111\u01b0\u1ee3c cho ph\u00e9p \u0111\u1ec3 th\u00eam nhi\u1ec1u danh s\u00e1ch ph\u00e1t t\u1ea1i l\u00fac n\u00e0y. Xin \u0111\u1eebng spam danh s\u00e1ch ph\u00e1t d\u00e0i. unblacklisted=\u0110\u00e3 lo\u1ea1i b\u1ecf {0} kh\u1ecfi danh s\u00e1ch \u0111en. -serverinfoTitle=Info about {0}\: +serverinfoTitle=Th\u00f4ng tin v\u1ec1 {0}\: serverinfoOnlineUsers=Ng\u01b0\u1eddi \u0111ang online\: serverinfoTotalUsers=T\u1ed5ng s\u1ed1 ng\u01b0\u1eddi d\u00f9ng\: serverinfoRoles=Vai tro\u0300\: @@ -193,17 +193,17 @@ serverinfoGuildID=Guild ID\: serverinfoCreationDate=Ng\u00e0y t\u1ea1o\: serverinfoOwner=Ch\u1ee7 s\u1edf h\u1eefu\: serverinfoVLv=C\u1ea5p \u0111\u1ed9 x\u00e1c minh\: -userinfoTitle=Information about {0}\: +userinfoTitle=Th\u00f4ng tin v\u1ec1 {0}\: userinfoUsername=T\u00ean \u0111\u0103ng nh\u1eadp\: userinfoId=ID\: userinfoNick=Bi\u1ec7t danh\: userinfoKnownServer=M\u00e1y ch\u1ee7 \u0111\u00e3 bi\u1ebft\: userinfoJoinDate=Ng\u00e0y tham gia\: userinfoCreationTime=Ng\u00e0y t\u1ea1o\: -userinfoBlacklisted=Blacklisted\: -skipDeniedTooManyTracks=You can't skip someone else's tracks if you are not a DJ.\nConsider using the Voteskip command. +userinfoBlacklisted=Danh s\u00e1ch \u0111en\: +skipDeniedTooManyTracks=B\u1ea1n kh\u00f4ng th\u1ec3 b\u1ecf qua b\u00e0i h\u00e1t c\u1ee7a ng\u01b0\u1eddi kh\u00e1c n\u1ebfu b\u1ea1n kh\u00f4ng ph\u1ea3i l\u00e0 m\u1ed9t DJ. N\u1ebfu mu\u1ed1n chuy\u1ec3n b\u00e0i d\u00f9ng Voteskip. eventUsersLeftVC=T\u1ea5t c\u1ea3 ng\u01b0\u1eddi d\u00f9ng \u0111\u00e3 r\u1eddi kh\u1ecfi k\u00eanh tho\u1ea1i. M\u00e1y nghe nh\u1ea1c \u0111\u00e3 t\u1ea1m d\u1eebng. -eventAutoResumed=User presence detected, automatically resuming the player. +eventAutoResumed=T\u1ef1 \u0111\u1ed9ng ph\u00e1t hi\u1ec7n s\u1ef1 hi\u1ec7n di\u1ec7n c\u1ee7a ng\u01b0\u1eddi s\u1eed d\u1ee5ng, t\u1ef1 \u0111\u1ed9ng ch\u1ea1y l\u1ea1i nh\u1ea1c. commandsFun=Tr\u00f2 vui commandsMemes=Meme commandsUtility=Ti\u1ec7n \u00edch @@ -212,11 +212,11 @@ commandsMaintenance=B\u1ea3o tr\u00ec commandsBotOwner=Ch\u1ee7 s\u1edf h\u1eefu bot commandsMoreHelp=Chat {0} \u0111\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 m\u1ed9t l\u1ec7nh c\u1ee5 th\u1ec3. helpUnknownCommand=L\u1ec7nh kh\u00f4ng r\u00f5. -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=T\u00e0i li\u1ec7u h\u01b0\u1edbng d\u1eabn c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y t\u1ea1i\: +helpBotInvite=B\u1ea1n mu\u1ed1n th\u00eam FredBoat v\u00e0o m\u00e1y ch\u1ee7 c\u1ee7a b\u1ea1n? N\u1ebfu b\u1ea1n c\u00f3 quy\u1ec1n truy c\u1eadp qu\u1ea3n l\u00fd m\u00e1y ch\u1ee7 cho guild c\u1ee7a b\u1ea1n, b\u1ea1n c\u00f3 th\u1ec3 m\u1eddi FredBoat\: +helpHangoutInvite=C\u1ea7n gi\u00fap \u0111\u1ee1 ho\u1eb7c c\u00f3 b\u1ea5t k\u1ef3 \u00fd t\u01b0\u1edfng cho FredBoat? C\u00f3 l\u1ebd b\u1ea1n ch\u1ec9 mu\u1ed1n hang out? Tham gia c\u1ed9ng \u0111\u1ed3ng FredBoat\! +helpNoDmCommands=B\u1ea1n kh\u00f4ng th\u1ec3 g\u1eedi l\u1ec7nh FredBoat qua DMs. +helpCredits=T\u1ea1o b\u1edfi Fre_d v\u00e0 nh\u1eefng ng\u01b0\u1eddi \u0111\u00f3ng g\u00f3p m\u00e3 ngu\u1ed3n m\u1edf helpSent=T\u00e0i li\u1ec7u \u0111\u00e3 \u0111\u01b0\u1ee3c g\u1eedi tr\u1ef1c ti\u1ebfp cho b\u1ea1n\! helpProperUsage=C\u00e1ch d\u00f9ng ch\u00ednh x\u00e1c\: helpCommandOwnerRestricted=L\u1ec7nh n\u00e0y ch\u1ec9 \u0111\u01b0\u1ee3c gi\u1edbi h\u1ea1n cho c\u00e1c ch\u1ee7 s\u1edf h\u1eefu c\u1ee7a bot. @@ -229,20 +229,20 @@ helpMusicCommandsHeader=L\u1ec7nh FredBoat \u00c2m nh\u1ea1c helpJoinCommand=L\u00e0m cho bot tham gia k\u00eanh tho\u1ea1i hi\u1ec7n t\u1ea1i. helpLeaveCommand=L\u00e0m cho bot r\u1eddi kh\u1ecfi k\u00eanh tho\u1ea1i hi\u1ec7n t\u1ea1i. helpPauseCommand=T\u1ea1m d\u1eebng m\u00e1y nghe nh\u1ea1c. -helpPlayCommand=Play music from the given URL or search for a track. For a full list of sources please visit {0} +helpPlayCommand=Ch\u01a1i nh\u1ea1c t\u1eeb URL \u0111\u00e3 cho ho\u1eb7c t\u00ecm ki\u1ebfm m\u1ed9t b\u00e0i h\u00e1t. \u0110\u1ec3 c\u00f3 danh s\u00e1ch \u0111\u1ea7y \u0111\u1ee7 ngu\u1ed3n vui l\u00f2ng truy c\u1eadp {0} helpPlaySplitCommand=T\u00e1ch m\u1ed9t video Youtube th\u00e0nh m\u1ed9t danh s\u00e1ch b\u00e0i h\u00e1t \u0111\u01b0\u1ee3c cho \u1edf ph\u1ea7n mi\u00eau t\u1ea3. helpRepeatCommand=Chuy\u1ec3n \u0111\u1ed5i gi\u1eefa c\u00e1c ch\u1ebf \u0111\u1ed9 l\u1eb7p l\u1ea1i. helpReshuffleCommand=X\u00e1o tr\u1ed9n l\u1ea1i h\u00e0ng ch\u1edd hi\u1ec7n t\u1ea1i. helpSelectCommand=Ch\u1ecdn m\u1ed9t trong c\u00e1c b\u00e0i h\u00e1t \u0111\u01b0\u1ee3c y\u00eau c\u1ea7u sau khi t\u00ecm ki\u1ebfm \u0111\u1ec3 ch\u01a1i. helpShuffleCommand=B\u1eadt t\u1eaft ch\u1ebf \u0111\u1ed9 ng\u1eabu nhi\u00ean cho h\u00e0ng ch\u1edd hi\u1ec7n t\u1ea1i. -helpSkipCommand=Skip the current song, the n'th song in the queue, all songs from n to m, or all songs from mentioned users. Please use in moderation. +helpSkipCommand=B\u1ecf qua b\u00e0i h\u00e1t hi\u1ec7n t\u1ea1i, b\u00e0i h\u00e1t n'th trong h\u00e0ng ch\u1edd ho\u1eb7c t\u1ea5t c\u1ea3 b\u00e0i h\u00e1t t\u1eeb n t\u1edbi m. Xin vui l\u00f2ng s\u1eed d\u1ee5ng trong tr\u00ecnh qu\u1ea3n l\u00ed. helpStopCommand=D\u1eebng m\u00e1y nghe nh\u1ea1c v\u00e0 d\u1ecdn danh s\u00e1ch ph\u00e1t. D\u00e0nh ri\u00eang cho ng\u01b0\u1eddi ki\u1ec3m duy\u1ec7t v\u1edbi quy\u1ec1n qu\u1ea3n l\u00fd tin nh\u1eafn. helpUnpauseCommand=H\u1ee7y t\u1ea1m d\u1eebng m\u00e1y nghe nh\u1ea1c. helpVolumeCommand=Thay \u0111\u1ed5i \u00e2m l\u01b0\u1ee3ng. G\u00eda tr\u1ecb t\u1eeb 0-150 v\u00e0 100 l\u00e0 m\u1eb7c \u0111\u1ecbnh. L\u1ec7nh \u00e2m l\u01b0\u1ee3ng \u0111\u01b0\u1ee3c c\u00e1ch bi\u1ec7t v\u1edbi bot c\u00f4ng khai. helpExportCommand=Xu\u1ea5t ra h\u00e0ng ch\u1edd hi\u1ec7n t\u1ea1i v\u00e0o m\u1ed9t li\u00ean k\u1ebft hastebin, sau \u0111\u00f3 c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c d\u00f9ng nh\u01b0 m\u1ed9t danh s\u00e1ch ph\u00e1t. helpGensokyoRadioCommand=Hi\u1ec3n th\u1ecb b\u00e0i h\u00e1t hi\u1ec7n t\u1ea1i \u0111\u01b0\u1ee3c ch\u01a1i tr\u00ean gensokyoradio.net helpListCommand=Hi\u1ec3n th\u1ecb m\u1ed9t danh s\u00e1ch b\u00e0i h\u00e1t hi\u1ec7n t\u1ea1i trong danh s\u00e1ch ph\u00e1t. -helpHistoryCommand=Display a list of the songs in playlist history. +helpHistoryCommand=Hi\u1ec3n th\u1ecb m\u1ed9t danh s\u00e1ch c\u00e1c b\u00e0i h\u00e1t trong danh s\u00e1ch l\u1ecbch s\u1eed. helpNowplayingCommand=Hi\u1ec3n th\u1ecb b\u00e0i h\u00e1t \u0111ang ph\u00e1t. helpForwardCommand=Chuy\u1ec3n ti\u1ebfp b\u00e0i h\u00e1t b\u1eb1ng m\u1ed9t s\u1ed1 l\u01b0\u1ee3ng th\u1eddi gian nh\u1ea5t \u0111\u1ecbnh. V\u00ed d\u1ee5\: helpRestartCommand=Kh\u1edfi \u0111\u1ed9ng l\u1ea1i ca kh\u00fac hi\u1ec7n \u0111ang ph\u00e1t. @@ -250,7 +250,7 @@ helpRewindCommand=Tua l\u1ea1i b\u00e0i h\u00e1t b\u1eb1ng m\u1ed9t s\u1ed1 l\u0 helpSeekCommand=\u0110\u1eb7t v\u1ecb tr\u00ed c\u1ee7a b\u00e0i h\u00e1t tr\u00ean th\u1eddi gian nh\u1ea5t \u0111\u1ecbnh. V\u00ed d\u1ee5\: helpAvatarCommand=Hi\u1ec3n th\u1ecb \u1ea3nh \u0111\u1ea1i di\u1ec7n c\u1ee7a m\u1ed9t ng\u01b0\u1eddi d\u00f9ng. helpBrainfuckCommand=Th\u1ef1c thi m\u00e3 Hackn\u00e3o. V\u00ed d\u1ee5\: -helpWeatherCommand=Display current weather by location. +helpWeatherCommand=Hi\u1ec3n th\u1ecb hi\u1ec7n nay th\u1eddi ti\u1ebft theo \u0111\u1ecba \u0111i\u1ec3m. helpClearCommand=X\u00f3a t\u1ea5t c\u1ea3 tin nh\u0103n b\u1eb1ng bot n\u00e0y trong 50 tin nh\u1eafn \u1edf k\u00eanh n\u00e0y. helpCommandsCommand=Hi\u1ec3n th\u1ecb c\u00e1c l\u1ec7nh c\u00f3 s\u1eb5n. helpHelpCommand=Nh\u1eadn gi\u00fap \u0111\u1ee1 cho bot n\u00e0y ho\u1eb7c tr\u1ee3 gi\u00fap cho b\u1ea5t c\u1ee9 l\u1ec7nh. @@ -261,16 +261,16 @@ helpSayCommand=L\u00e0m cho bot nh\u1edb v\u1ec1 phjtieudoc. helpServerInfoCommand=Hi\u1ec3n th\u1ecb m\u1ed9t s\u1ed1 s\u1ed1 li\u1ec7u th\u1ed1ng k\u00ea v\u1ec1 guild n\u00e0y. helpUserInfoCommand=Hi\u1ec3n th\u1ecb th\u00f4ng tin v\u1ec1 ch\u00ednh m\u00ecnh ho\u1eb7c ng\u01b0\u1eddi d\u00f9ng kh\u00e1c \u0111\u1ebfn c\u00e1c bot. helpPerms=Cho ph\u00e9p c\u00e1c th\u00e0nh vi\u00ean whitelist v\u00e0 vai tr\u00f2 c\u1ee7a h\u1ea1ng {0}. -helpPrefixCommand=Set the prefix for this guild. -helpVoteSkip=Vote to skip the current song. Needs 50% of all users in the voice chat to vote. -helpMathOperationAdd=Print the sum of num1 and num2. -helpMathOperationSub=Print the difference of subtracting num2 from num1. -helpMathOperationMult=Print the product of num1*num2. -helpMathOperationDiv=Print the quotient of dividing num1 by num2. -helpMathOperationMod=Print the remainder of dividing num1 by num2. -helpMathOperationPerc=Print the percentage represented by num1 in num2. -helpMathOperationSqrt=Print the square root of num. -helpMathOperationPow=Print the result of num1^num2. +helpPrefixCommand=Thi\u1ebft l\u1eadp ti\u1ec1n t\u1ed1 cho guild n\u00e0y. +helpVoteSkip=B\u00ecnh ch\u1ecdn \u0111\u1ec3 b\u1ecf qua b\u00e0i h\u00e1t hi\u1ec7n t\u1ea1i. C\u1ea7n s\u1ef1 \u0111\u1ed3ng thu\u1eadn c\u1ee7a 50% ng\u01b0\u1eddi d\u00f9ng trong k\u00eanh \u0111\u1ec3 b\u1ecf qua b\u00e0i h\u00e1t. +helpMathOperationAdd=In t\u1ed5ng c\u1ee7a num1 v\u00e0 num2. +helpMathOperationSub=In s\u1ef1 kh\u00e1c bi\u1ec7t c\u1ee7a tr\u1eeb num2 t\u1eeb num1. +helpMathOperationMult=In c\u00e1c s\u1ea3n ph\u1ea9m c\u1ee7a num1 * num2. +helpMathOperationDiv=In th\u01b0\u01a1ng chia num1 b\u1edfi num2. +helpMathOperationMod=In th\u01b0\u01a1ng chia num1 b\u1edfi num2. +helpMathOperationPerc=In t\u1ef7 l\u1ec7 ph\u1ea7n tr\u0103m \u0111\u01b0\u1ee3c \u0111\u1ea1i di\u1ec7n b\u1edfi num1 \u1edf num2. +helpMathOperationSqrt=In b\u1eadc hai c\u1ee7a s\u1ed1 c\u00f2n t. +helpMathOperationPow=In c\u00e1c s\u1ea3n ph\u1ea9m c\u1ee7a num1 * num2. destroyDenied=B\u1ea1n c\u1ea7n ph\u1ea3i c\u00f3 quy\u1ec1n qu\u1ea3n l\u00ed tin nh\u1eafn \u0111\u1ec3 \u0111\u1eb7t l\u1ea1i m\u00e1y nghe nh\u1ea1c. destroyHelp=\u0110\u1eb7t l\u1ea1i m\u00e1y nghe nh\u1ea1c v\u00e0 d\u1ecdn danh s\u00e1ch ph\u00e1t. D\u00e0nh ri\u00eang cho ng\u01b0\u1eddi ki\u1ec3m duy\u1ec7t v\u1edbi quy\u1ec1n qu\u1ea3n l\u00fd tin nh\u1eafn. destroySucc=\u0110\u00e3 \u0111\u1eb7t l\u1ea1i m\u00e1y nghe nh\u1ea1c v\u00e0 x\u00f3a h\u00e0ng ch\u1edd. @@ -280,26 +280,26 @@ permsAdded=\u0110\u00e3 th\u00eam `{0}` t\u1edbi `{1}`. permsRemoved=\u0110\u00e3 lo\u1ea1i b\u1ecf `{0}` t\u1eeb `{1}`. permsFailSelfDemotion=B\u1ea1n kh\u00f4ng th\u1ec3 lo\u1ea1i b\u1ecf \u0111i\u1ec1u n\u00e0y v\u00ec n\u00f3 s\u1ebd khi\u1ebfn b\u1ea1n kh\u00f4ng c\u00f3 quy\u1ec1n qu\u1ea3n tr\u1ecb\! permsAlreadyAdded={0} \u0111\u00e3 \u0111\u01b0\u1ee3c th\u00eam v\u00e0o {1} -permsNotAdded={0} is not in {1} +permsNotAdded={0} kh\u00f4ng ph\u1ea3i l\u00e0 {1} fuzzyMultiple=Nhi\u1ec1u kho\u1ea3n m\u1ee5c \u0111\u00e3 \u0111\u01b0\u1ee3c t\u00ecm th\u1ea5y. B\u1ea1n c\u00f3 hi\u1ec3u b\u1ea5t k\u00ec g\u00ec kh\u00f4ng? fuzzyNothingFound=Kh\u00f4ng t\u00ecm th\u1ea5y g\u00ec cho `{0}`. cmdPermsTooLow=B\u1ea1n kh\u00f4ng c\u00f3 quy\u1ec1n \u0111\u1ec3 ch\u1ea1y l\u1ec7nh n\u00e0y\! L\u1ec7nh n\u00e0y y\u00eau c\u1ea7u `{0}`, nh\u01b0ng b\u1ea1n ch\u1ec9 c\u00f3 `{1}`. playersLimited=FredBoat hi\u1ec7n \u0111\u00e3 \u0111\u1ea1t t\u1ed1i \u0111a n\u0103ng l\u1ef1c\! Bot n\u00e0y hi\u1ec7n \u0111ang \u0111\u01b0\u1ee3c s\u1eeda \u0111\u1ec3 ph\u00e1t nh\u1ea1c \u0111\u1ebfn `{0}` b\u00e0i, n\u1ebfu kh\u00f4ng ch\u00fang t\u00f4i ph\u1ea3i ng\u1eaft k\u1ebft n\u1ed1i kh\u1ecfi Discord d\u01b0\u1edbi trang t\u1ea3i m\u1ea1ng.\nN\u1ebfu b\u1ea1n mu\u1ed1n h\u1ed7 tr\u1ee3 ch\u00fang t\u00f4i t\u0103ng th\u00eam gi\u1edbi h\u1ea1n hay b\u1ea1n mu\u1ed1n s\u1eed d\u1ee5ng bot t\u1ed1i thi\u1ec3u c\u1ee7a ch\u00fang t\u00f4i, h\u00e3y h\u1ed7 tr\u1ee3 ch\u00fang t\u00f4i qua Patreon\:\n{1}\n\nXin l\u1ed7i v\u00ec s\u1ef1 b\u1ea5t ti\u1ec7n\! B\u1ea1n c\u00f3 th\u1ec3 ph\u1ea3i th\u1eed l\u1ea1i sau. Tin nh\u1eafn n\u00e0y th\u01b0\u1eddng ch\u1ec9 xu\u1ea5t hi\u1ec7n m\u1ed9t v\u00e0i l\u1ea7n. tryLater=Vui l\u00f2ng th\u1eed l\u1ea1i sau. -skipUserSingle=Skipped {0} added by {1}. -skipUserMultiple=Skipped {0} tracks added by {1}. -skipUsersMultiple=Skipped {0} tracks added by {1} users. -skipUserNoTracks=None of the mentioned users have any tracks queued. -voteSkipAdded=Your vote has been added\! -voteSkipAlreadyVoted=You already voted to skip this track\! -voteSkipSkipping={0} have voted to skip. Skipping track {1}. -voteSkipNotEnough={0} have voted to skip. At least {1} needed. -voteSkipEmbedNoVotes=No votes to skip this track yet. -voteSkipEmbedVoters={0} out of {1} have voted to skip the current track +skipUserSingle=\u0110\u00e3 b\u1ecf qua {0} \u0111\u01b0\u1ee3c th\u00eam v\u00e0o b\u1edfi {1}. +skipUserMultiple=\u0110\u00e3 b\u1ecf qua {0} \u0111\u01b0\u1ee3c th\u00eam v\u00e0o b\u1edfi {1}. +skipUsersMultiple=\u0110\u00e3 b\u1ecf qua {0} \u0111\u01b0\u1ee3c th\u00eam v\u00e0o b\u1edfi {1}. +skipUserNoTracks=Kh\u00f4ng c\u00f3 \u0111\u1ec1 c\u1eadp \u0111\u1ebfn ng\u01b0\u1eddi d\u00f9ng c\u00f3 b\u1ea5t k\u1ef3 b\u00e0i h\u00e1t \u0111\u00e3 x\u1ebfp h\u00e0ng. +voteSkipAdded=Phi\u1ebfu b\u1ea7u c\u1ee7a b\u1ea1n \u0111\u00e3 \u0111\u01b0\u1ee3c th\u00eam\! +voteSkipAlreadyVoted=B\u1ea1n \u0111\u00e3 b\u1ecf phi\u1ebfu \u0111\u1ec3 b\u1ecf qua vi\u1ec7c theo d\u00f5i n\u00e0y\! +voteSkipSkipping={0} \u0111\u00e3 b\u1ecf phi\u1ebfu \u0111\u1ec3 b\u1ecf qua. \u0110ang b\u1ecf qua b\u00e0i h\u00e1t {1}. +voteSkipNotEnough={0} \u0111\u00e3 b\u1ecf phi\u1ebfu \u0111\u1ec3 b\u1ecf qua. C\u1ea7n \u00edt nh\u1ea5t l\u00e0 {1}. +voteSkipEmbedNoVotes=Ch\u01b0a c\u00f3 phi\u1ebfu \u0111\u1ec3 b\u1ecf qua b\u00e0i h\u00e1t n\u00e0y. +voteSkipEmbedVoters={0} tr\u00ean {1} \u0111\u00e3 b\u1ecf phi\u1ebfu \u0111\u1ec3 b\u1ecf qua vi\u1ec7c theo d\u00f5i hi\u1ec7n t\u1ea1i mathOperationResult=K\u1ebft qu\u1ea3 l\u00e0 mathOperationDivisionByZeroError=Kh\u00f4ng th\u1ec3 chia cho 0. mathOperationInfinity=S\u1ed1 qu\u00e1 l\u1edbn \u0111\u1ec3 \u0111\u01b0\u1ee3c hi\u1ec3n th\u1ecb\! -prefix=Prefix -prefixGuild=The prefix for this guild is {0} -prefixShowAgain=You can show the prefix anytime again by mentioning me. +prefix=Ti\u1ec1n t\u1ed1 +prefixGuild=Ti\u1ec1n t\u1ed1 cho guild n\u00e0y l\u00e0 {0} +prefixShowAgain=B\u1ea1n c\u00f3 th\u1ec3 hi\u1ec3n th\u1ecb c\u00e1c ti\u1ec1n t\u1ed1 b\u1ea5t c\u1ee9 l\u00fac n\u00e0o m\u1ed9t l\u1ea7n n\u1eefa b\u1eb1ng c\u00e1ch nh\u1eafc \u0111\u1ebfn t\u00f4i. diff --git a/FredBoat/src/main/resources/lang/zh_CN.properties b/FredBoat/src/main/resources/lang/zh_CN.properties index f7b77d34f..73e7c2588 100644 --- a/FredBoat/src/main/resources/lang/zh_CN.properties +++ b/FredBoat/src/main/resources/lang/zh_CN.properties @@ -19,14 +19,14 @@ selectInterval=\u6570\u5b57\u5fc5\u987b\u5728 1 \u5230 {0} \u4e4b\u95f4 selectSelectionNotGiven=\u5f53\u524d\u65e0\u641c\u7d22\u7ed3\u679c\u4f9b\u60a8\u9009\u62e9\u3002 shuffleOn=\u300c\u968f\u673a\u64ad\u653e\u300d\u6a21\u5f0f\u5df2\u6253\u5f00\u3002 shuffleOff=\u300c\u968f\u673a\u64ad\u653e\u300d\u6a21\u5f0f\u5df2\u5173\u95ed\u3002 -reshufflePlaylist=Queue reshuffled. +reshufflePlaylist=\u961f\u5217\u6539\u7ec4\u3002 reshufflePlayerNotShuffling=\u5fc5\u987b\u5148\u6253\u5f00 "\u65e0\u5e8f\u64ad\u653e" \u6a21\u5f0f\u3002 skipEmpty=\u5f53\u524d\u64ad\u653e\u5217\u8868\u4e3a\u7a7a\u3002 skipOutOfBounds=\u65e0\u6cd5\u79fb\u9664\u7b2c {0} \u9996\u6b4c\uff0c\u56e0\u4e3a\u5f53\u524d\u64ad\u653e\u5217\u8868\u53ea\u6709 {1} \u9996\u6b4c\u66f2\u3002 skipNumberTooLow=\u60a8\u8f93\u5165\u7684\u6570\u5b57\u5fc5\u987b\u5927\u4e8e 0\u3002 skipSuccess=\u5df2\u8df3\u8fc7 \#{0}\: **{1}** skipRangeInvalid=\u6307\u5b9a\u7684\u6b4c\u66f2\u8303\u56f4\u65e0\u6548\u3002 -skipRangeSuccess=Tracks \#{0} to \#{1} have been removed. +skipRangeSuccess=\u5e8f\u53f7\u4e3a {0} ~ {1} \u7684\u6b4c\u66f2\u5df2\u88ab\u79fb\u9664\u3002 skipTrackNotFound=\u5f53\u524d\u64ad\u653e\u5217\u8868\u4e3a\u7a7a\uff0c\u65e0\u6cd5\u4f7f\u7528\u8df3\u8fc7\u529f\u80fd\u3002 stopAlreadyEmpty=\u64ad\u653e\u5217\u8868\u5df2\u6e05\u7a7a\u3002 stopEmptyOne=\u64ad\u653e\u5217\u8868\u5df2\u6e05\u7a7a\uff0c`1` \u9996\u6b4c\u66f2\u5df2\u88ab\u79fb\u9664\u3002 @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u4f60\u7684\u901f\u5ea6\u6709\u9650\! \u8bf7\u6162\u4e00 ratelimitedSkipCommand=\u60a8\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u8df3\u8fc7\u591a\u4e2a\u6b4c\u66f2\: {0} ratelimitedGuildSlowLoadingPlaylist=\u6b64\u670d\u52a1\u5668\u4e0d\u5141\u8bb8\u5728\u6b64\u65f6\u6dfb\u52a0\u66f4\u591a\u64ad\u653e\u5217\u8868\u3002\u8bf7\u4e0d\u8981\u5783\u573e\u90ae\u4ef6\u957f\u64ad\u653e\u5217\u8868\u3002 unblacklisted=\u5df2\u4ece\u9ed1\u540d\u5355\u4e2d\u5220\u9664{0}\u3002 -serverinfoTitle=Info about {0}\: +serverinfoTitle=**{0}** \u7684\u76f8\u5173\u4fe1\u606f\uff1a serverinfoOnlineUsers=\u5728\u7ebf\u7528\u6237\uff1a serverinfoTotalUsers=\u7528\u6237\u603b\u6570\uff1a serverinfoRoles=\u8eab\u4efd\u7ec4\uff1a @@ -193,7 +193,7 @@ serverinfoGuildID=\u516c\u4f1a ID\uff1a serverinfoCreationDate=\u521b\u5efa\u65e5\u671f\uff1a serverinfoOwner=\u62e5\u6709\u8005\uff1a serverinfoVLv=\u9a8c\u8bc1\u7b49\u7ea7\uff1a -userinfoTitle=Information about {0}\: +userinfoTitle=**{0}** \u7684\u76f8\u5173\u4fe1\u606f\uff1a userinfoUsername=\u7528\u6237\u540d\uff1a userinfoId=ID\uff1a userinfoNick=\u6635\u79f0\uff1a @@ -212,11 +212,11 @@ commandsMaintenance=\u7cfb\u7edf\u7ef4\u62a4 commandsBotOwner=\u673a\u5668\u4eba\u4e3b\u4eba commandsMoreHelp=\u8bf4{0} \u83b7\u53d6\u6709\u5173\u7279\u5b9a\u547d\u4ee4\u7684\u66f4\u591a\u4fe1\u606f\u3002 helpUnknownCommand=\u672a\u77e5\u7684\u6307\u4ee4\u3002 -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=\u6587\u6863\u53ef\u4ee5\u5728\u4ee5\u4e0b\u65b9\u9762\u627e\u5230\: +helpBotInvite=\u8981\u5c06 FredBoat \u6dfb\u52a0\u5230\u60a8\u7684\u670d\u52a1\u5668\u5417\uff1f\u5982\u679c\u60a8\u6709\u7ba1\u7406\u516c\u4f1a\u7684\u670d\u52a1\u5668\u6743\u9650, \u60a8\u53ef\u4ee5\u9080\u8bf7 FredBoat\: +helpHangoutInvite=\u9700\u8981\u5e2e\u52a9\u6216\u6709\u4efb\u4f55\u60f3\u6cd5\u7684 FredBoat\uff1f\u4e5f\u8bb8\u4f60\u53ea\u662f\u60f3\u51fa\u53bb\u73a9\uff1f\u52a0\u5165 FredBoat \u793e\u533a\! +helpNoDmCommands=\u60a8\u4e0d\u80fd\u901a\u8fc7 DMs \u53d1\u9001 FredBoat \u547d\u4ee4\u3002 +helpCredits=\u7531 Fre_d \u548c\u5f00\u6e90\u8d21\u732e\u8005\u521b\u5efa helpSent=\u5e2e\u52a9\u6587\u6863\u5df2\u901a\u8fc7\u79c1\u804a\u53d1\u7ed9\u60a8\uff01 helpProperUsage=\u6b63\u786e\u4f7f\u7528\: helpCommandOwnerRestricted=\u6b64\u547d\u4ee4\u4ec5\u9650\u4e8e \n\u673a\u5668\u4eba\u4e3b\u4eba diff --git a/FredBoat/src/main/resources/lang/zh_TW.properties b/FredBoat/src/main/resources/lang/zh_TW.properties index 4d48ba772..cd97eeb75 100644 --- a/FredBoat/src/main/resources/lang/zh_TW.properties +++ b/FredBoat/src/main/resources/lang/zh_TW.properties @@ -183,7 +183,7 @@ ratelimitedGeneralInfo=\u60a8\u5373\u5c07\u9054\u5230\u4fe1\u606f\u4e0a\u9650\uf ratelimitedSkipCommand=\u60a8\u53ef\u4ee5\u901a\u904e\u4f7f\u7528\u6b64\u547d\u4ee4\u8df3\u904e\u8d85\u904e\u4e00\u9996\u6b4c\uff1a {0} ratelimitedGuildSlowLoadingPlaylist=\u6b64\u4f3a\u670d\u5668\u4e0d\u5141\u8a31\u5728\u6b64\u6642\u65b0\u589e\u66f4\u591a\u64ad\u653e\u6e05\u55ae\u3002\u8acb\u4e0d\u8981\u5237\u5f88\u9577\u7684\u64ad\u653e\u6e05\u55ae unblacklisted=\u5f9e\u9ed1\u540d\u55ae\u79fb\u9664 {0} -serverinfoTitle=Info about {0}\: +serverinfoTitle=\u95dc\u65bc **{0}** \u7684\u8cc7\u8a0a serverinfoOnlineUsers=\u7dda\u4e0a\u4f7f\u7528\u8005\uff1a serverinfoTotalUsers=\u4f7f\u7528\u8005\u7e3d\u6578\: serverinfoRoles=\u8eab\u4efd\uff1a @@ -193,7 +193,7 @@ serverinfoGuildID=\u516c\u6703ID\: serverinfoCreationDate=\u5efa\u7acb\u65e5\u671f\: serverinfoOwner=\u64c1\u6709\u8005\uff1a serverinfoVLv=\u9a57\u8b49\u7d1a\u5225\ufe30 -userinfoTitle=Information about {0}\: +userinfoTitle=\u95dc\u65bc **{0}** \u7684\u8cc7\u8a0a userinfoUsername=\u7528\u6236\u540d\uff1a userinfoId=ID\uff1a userinfoNick=\u66b1\u7a31\uff1a @@ -212,11 +212,11 @@ commandsMaintenance=\u7dad\u8b77 commandsBotOwner=Bot \u64c1\u6709\u8005 commandsMoreHelp=\u8aaa {0} \u4ee5\u7372\u5f97\u7279\u5b9a\u6307\u4ee4\u7684\u66f4\u591a\u8cc7\u8a0a helpUnknownCommand=\u672a\u77e5\u7684\u6307\u4ee4 -helpDocsLocation=Documentation can be found at\: -helpBotInvite=Want to add FredBoat to your server? If you have Manage Server permissions for your guild, you can invite FredBoat\: -helpHangoutInvite=Need help or have any ideas for FredBoat? Perhaps you just want to hang out? Join the FredBoat community\! -helpNoDmCommands=You cannot send FredBoat commands through DMs. -helpCredits=Created by Fre_d and open source contributors +helpDocsLocation=\u627e\u4e0d\u5230\u6587\u4ef6 +helpBotInvite=\u8981\u5c07 FredBoat \u6dfb\u52a0\u5230\u60a8\u7684\u4f3a\u670d\u5668\u55ce\uff1f\u5982\u679c\u60a8\u6709\u7ba1\u7406\u516c\u6703\u7684\u4f3a\u670d\u5668\u8a31\u53ef\u6b0a, \u60a8\u53ef\u4ee5\u9080\u8acb FredBoat\: +helpHangoutInvite=\u9700\u8981\u5e6b\u52a9\u6216\u6709\u4efb\u4f55\u60f3\u6cd5\u7684 FredBoat\uff1f\u4e5f\u8a31\u4f60\u53ea\u662f\u60f3\u51fa\u53bb\u73a9\uff1f\u52a0\u5165 FredBoat \u793e\u5340\! +helpNoDmCommands=\u60a8\u4e0d\u80fd\u901a\u904e DMs \u767c\u9001 FredBoat \u547d\u4ee4\u3002 +helpCredits=\u7531 Fre_d \u548c\u958b\u6e90\u8ca2\u737b\u8005\u5275\u5efa helpSent=\u6587\u4ef6\u5df2\u7d93\u79c1\u8a0a\u7d66\u4f60 helpProperUsage=\u6b63\u78ba\u7528\u6cd5\: helpCommandOwnerRestricted=\u6b64\u6307\u4ee4\u53ea\u9650Bot\u7684\u64c1\u6709\u8005\u4f7f\u7528 From 6175cb0bf8eebc8c42262e2fc4b7b3c6f450e734 Mon Sep 17 00:00:00 2001 From: Napster Date: Fri, 29 Dec 2017 03:02:02 +0100 Subject: [PATCH 62/62] Bump version v2.0 --- FredBoat/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FredBoat/build.gradle b/FredBoat/build.gradle index 44e733253..5039b4760 100644 --- a/FredBoat/build.gradle +++ b/FredBoat/build.gradle @@ -13,7 +13,7 @@ apply plugin: 'org.junit.platform.gradle.plugin' description = 'FredBoat Discord Music Bot' mainClassName = "fredboat.FredBoat" -version '1.1' +version '2.0' ext { moduleName = 'FredBoat' }