diff --git a/.gitignore b/.gitignore
index 0dd928cb9..08ded24d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -119,7 +119,7 @@ nbproject/private/
run.bat
target/
.nb-gradle/
-/dependency-reduced-pom.xml
+*/dependency-reduced-pom.xml
*credentials.json
*credentials.yaml
*tokens.json
@@ -132,3 +132,4 @@ target/
/music_persistence/
/bootloader.json
gc-*.log
+*dbconf.yaml
\ No newline at end of file
diff --git a/FredBoat-Bootloader/pom.xml b/FredBoat-Bootloader/pom.xml
index 35b464d0f..a5844d026 100644
--- a/FredBoat-Bootloader/pom.xml
+++ b/FredBoat-Bootloader/pom.xml
@@ -24,17 +24,33 @@
~
-->
-
+
+
+ fredboat
+ FredBoat-Root
+ 1.0
+
+
4.0.0
- com.frederikam
FredBoat-Bootloader
1.0
jar
+
- UTF-8
- 1.8
- 1.8
+ fredboat.bootloader.Bootloader
+
+
+
+
+ fredboat
+ Shared
+ 1.0
+
+
+
@@ -51,7 +67,7 @@
- com.frederikam.fredboat.bootloader.Bootloader
+ fredboat.bootloader.Bootloader
@@ -61,12 +77,4 @@
-
-
- org.json
- json
- 20160810
- jar
-
-
-
\ No newline at end of file
+
diff --git a/FredBoat-Bootloader/src/main/java/com/frederikam/fredboat/bootloader/ExitCodes.java b/FredBoat-Bootloader/src/main/java/com/frederikam/fredboat/bootloader/ExitCodes.java
deleted file mode 100644
index 9c6a2d5a9..000000000
--- a/FredBoat-Bootloader/src/main/java/com/frederikam/fredboat/bootloader/ExitCodes.java
+++ /dev/null
@@ -1,34 +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 com.frederikam.fredboat.bootloader;
-
-public class ExitCodes {
-
- public static final int EXIT_CODE_NORMAL = 0;
- public static final int EXIT_CODE_UPDATE = 20;
- public static final int EXIT_CODE_RESTART = 21;
-
-}
diff --git a/FredBoat-Bootloader/src/main/java/com/frederikam/fredboat/bootloader/Bootloader.java b/FredBoat-Bootloader/src/main/java/fredboat/bootloader/Bootloader.java
similarity index 93%
rename from FredBoat-Bootloader/src/main/java/com/frederikam/fredboat/bootloader/Bootloader.java
rename to FredBoat-Bootloader/src/main/java/fredboat/bootloader/Bootloader.java
index d894a5af8..9aa926ff7 100644
--- a/FredBoat-Bootloader/src/main/java/com/frederikam/fredboat/bootloader/Bootloader.java
+++ b/FredBoat-Bootloader/src/main/java/fredboat/bootloader/Bootloader.java
@@ -1,4 +1,5 @@
/*
+ *
* MIT License
*
* Copyright (c) 2017 Frederik Ar. Mikkelsen
@@ -20,10 +21,13 @@
* 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 com.frederikam.fredboat.bootloader;
+package fredboat.bootloader;
+
+import fredboat.shared.constant.ExitCodes;
+import org.json.JSONArray;
+import org.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
@@ -31,8 +35,6 @@
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Scanner;
-import org.json.JSONArray;
-import org.json.JSONObject;
public class Bootloader {
@@ -40,7 +42,7 @@ public class Bootloader {
private static String jarName;
private static int recentBoots = 0;
private static long lastBoot = 0L;
-
+
public static void main(String[] args) throws IOException, InterruptedException {
OUTER:
while (true) {
@@ -48,14 +50,14 @@ public static void main(String[] args) throws IOException, InterruptedException
Scanner scanner = new Scanner(is);
JSONObject json = new JSONObject(scanner.useDelimiter("\\A").next());
scanner.close();
-
+
command = json.getJSONArray("command");
jarName = json.getString("jarName");
Process process = boot();
process.waitFor();
System.out.println("[BOOTLOADER] Bot exited with code " + process.exitValue());
-
+
switch (process.exitValue()) {
case ExitCodes.EXIT_CODE_UPDATE:
System.out.println("[BOOTLOADER] Now updating...");
@@ -65,7 +67,7 @@ public static void main(String[] args) throws IOException, InterruptedException
case ExitCodes.EXIT_CODE_NORMAL:
System.out.println("[BOOTLOADER] Now shutting down...");
break OUTER;
- //SIGINT received or clean exit
+ //SIGINT received or clean exit
default:
System.out.println("[BOOTLOADER] Now restarting..");
break;
@@ -75,18 +77,18 @@ public static void main(String[] args) throws IOException, InterruptedException
private static Process boot() throws IOException {
//Check that we are not booting too quick (we could be stuck in a login loop)
- if(System.currentTimeMillis() - lastBoot > 3000 * 1000){
+ if (System.currentTimeMillis() - lastBoot > 3000 * 1000) {
recentBoots = 0;
}
-
+
recentBoots++;
lastBoot = System.currentTimeMillis();
-
- if(recentBoots >= 4){
+
+ if (recentBoots >= 4) {
System.out.println("[BOOTLOADER] Failed to restart 3 times, probably due to login errors. Exiting...");
System.exit(-1);
}
-
+
//ProcessBuilder pb = new ProcessBuilder(System.getProperty("java.home") + "/bin/java -jar "+new File("FredBoat-1.0.jar").getAbsolutePath())
ProcessBuilder pb = new ProcessBuilder()
.inheritIO();
@@ -94,9 +96,9 @@ private static Process boot() throws IOException {
command.forEach((Object str) -> {
list.add((String) str);
});
-
+
pb.command(list);
-
+
Process process = pb.start();
return process;
}
diff --git a/FredBoat/.gitignore b/FredBoat/.gitignore
index d35ced37e..e6c65aad7 100644
--- a/FredBoat/.gitignore
+++ b/FredBoat/.gitignore
@@ -1,6 +1,5 @@
/logs/
/bootloader.json
-/dependency-reduced-pom.xml
/music_persistence/
/credentials_test.json
/credentials.json.old
diff --git a/FredBoat/config.yaml b/FredBoat/config.yaml
index 1aee473e9..c0187fe41 100644
--- a/FredBoat/config.yaml
+++ b/FredBoat/config.yaml
@@ -1,7 +1,7 @@
---
-patron: false
-development: true # Set this to true for self hosting
-prefix: '<<' # Default prefix used by the bot
-restServerEnabled: true # Change this if you are running multiple FredBoat bots on the same machine
-admins: [] # add comma separated userIds and roleIds that should have access to admin commands
-useAutoBlacklist: true # set to true to automatically blacklist users who frequently hit the rate limits
+patron: false # Set this to true for self hosting the music bot
+development: true # Set this to true for self hosting the full bot (including non music commands)
+prefix: '<<' # Default prefix used by the bot
+restServerEnabled: true # Set this to false if you are running multiple FredBoat bots on the same machine
+admins: [] # add comma separated userIds and roleIds that should have access to bot admin commands
+useAutoBlacklist: true # set to true to automatically blacklist users who frequently hit the rate limits
diff --git a/FredBoat/feature_flags.properties b/FredBoat/feature_flags.properties
index d69235a9a..5aa8bb4b5 100644
--- a/FredBoat/feature_flags.properties
+++ b/FredBoat/feature_flags.properties
@@ -31,3 +31,5 @@
# example to turn a feature on (uncomment it):
#RATE_LIMITER=false
#CHATBOT=false
+#DATA_METHODS=false
+PERMISSIONS=false
diff --git a/FredBoat/pom.xml b/FredBoat/pom.xml
index 396dcd9c1..87de39de7 100644
--- a/FredBoat/pom.xml
+++ b/FredBoat/pom.xml
@@ -24,201 +24,196 @@
~
-->
-
+
+
+ fredboat
+ FredBoat-Root
+ 1.0
+
+
4.0.0
- fredboat
FredBoat
1.0
jar
+
- UTF-8
- 1.8
- 1.8
fredboat.FredBoat
+
- com.github.DV8FromTheWorld
+
+ fredboat
+ Shared
+ 1.0
+
+
+
+ net.dv8tion
JDA
- 1a13578
+ 3.1.1_217
+
+ net.sf.trove4j
+ trove4j
+ 3.0.3
+
+
+
org.apache.commons
commons-collections4
4.1
compile
+
com.sedmelluq
lavaplayer
1.2.39
+
com.sedmelluq
jda-nas
1.0.5
+
frederikam
JCA
1.0
+
commons-io
commons-io
2.5
- org.springframework.boot
- spring-boot-starter-web
- 1.5.3.RELEASE
-
-
- org.slf4j
- slf4j-api
- 1.7.25
+
+ org.apache.commons
+ commons-lang3
+ 3.6
+
ch.qos.logback
logback-classic
1.2.3
- org.apache.commons
- commons-lang3
- 3.5
+
+ org.slf4j
+ slf4j-api
+ 1.7.25
+
com.sparkjava
spark-core
- 2.5.5
+ 2.6.0
+
org.yaml
snakeyaml
1.18
-
+
net.sourceforge.htmlunit
htmlunit
- 2.26
+ 2.27
-
+
org.eclipse.jetty.websocket
websocket-client
-
+
it.unimi.dsi
fastutil
8.1.0
-
+
org.hibernate
hibernate-core
5.2.10.Final
+
org.hibernate
hibernate-ehcache
5.2.10.Final
+
org.hibernate
hibernate-hikaricp
5.2.10.Final
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 1.5.4.RELEASE
+
+
+
org.springframework
spring-orm
- 4.3.8.RELEASE
+ 4.3.9.RELEASE
+
org.postgresql
postgresql
42.1.1
- org.junit.jupiter
- junit-jupiter-api
- 5.0.0-M4
- test
-
-
-
-
+
org.xerial
sqlite-jdbc
- 3.16.1
+ 3.19.3
-
+
com.github.gwenn
sqlite-dialect
24970986d0
-
-
+
com.jcraft
jsch
0.1.54
-
-
+
org.togglz
togglz-core
2.4.1.Final
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.0.0-M4
+ test
+
-
-
- jcenter
- jcenter-bintray
- http://jcenter.bintray.com
-
-
-
- false
-
- bintray-frederikam-JCA
- bintray
- http://dl.bintray.com/frederikam/JCA
-
-
- sedmelluq
- sedmelluq
- http://maven.sedmelluq.com/
-
-
- jitpack.io
- https://jitpack.io
-
-
+
-
-
- maven-clean-plugin
- 3.0.0
-
-
- auto-clean
- initialize
-
- clean
-
-
-
-
maven-surefire-plugin
@@ -301,7 +296,7 @@
org.springframework.boot
spring-boot-maven-plugin
- 1.5.3.RELEASE
+ 1.5.4.RELEASE
diff --git a/FredBoat/src/main/java/fredboat/Config.java b/FredBoat/src/main/java/fredboat/Config.java
index d1573394d..35f7e28e6 100644
--- a/FredBoat/src/main/java/fredboat/Config.java
+++ b/FredBoat/src/main/java/fredboat/Config.java
@@ -26,8 +26,8 @@
package fredboat;
import com.mashape.unirest.http.exceptions.UnirestException;
+import fredboat.shared.constant.DistributionEnum;
import fredboat.util.DiscordUtil;
-import fredboat.util.constant.DistributionEnum;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/FredBoat/src/main/java/fredboat/FredBoat.java b/FredBoat/src/main/java/fredboat/FredBoat.java
index 928d00953..879acc572 100644
--- a/FredBoat/src/main/java/fredboat/FredBoat.java
+++ b/FredBoat/src/main/java/fredboat/FredBoat.java
@@ -45,16 +45,15 @@
import fredboat.event.EventListenerSelf;
import fredboat.event.ShardWatchdogListener;
import fredboat.feature.I18n;
-import fredboat.util.constant.DistributionEnum;
+import fredboat.shared.constant.DistributionEnum;
+import fredboat.util.JDAUtil;
import fredboat.util.log.SimpleLogToSLF4JAdapter;
import frederikam.jca.JCA;
import frederikam.jca.JCABuilder;
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDAInfo;
import net.dv8tion.jda.core.entities.Guild;
-import net.dv8tion.jda.core.entities.ISnowflake;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.VoiceChannel;
import net.dv8tion.jda.core.events.ReadyEvent;
@@ -66,6 +65,7 @@
import org.slf4j.LoggerFactory;
import javax.security.auth.login.LoginException;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
@@ -326,7 +326,12 @@ public void onInit(ReadyEvent readyEvent) {
int ready = numShardsReady.get();
if (ready == Config.CONFIG.getNumShards()) {
log.info("All " + ready + " shards are ready.");
- MusicPersistenceHandler.reloadPlaylists();
+
+ if (Config.CONFIG.getNumShards() <= 10) {
+ MusicPersistenceHandler.reloadPlaylists();
+ } else {
+ log.warn("Skipped music persistence loading! We are using more than 10 shards, so probably not a good idea to run that.");
+ }
}
//Rejoin old channels if revived
@@ -395,20 +400,11 @@ public static List getShards() {
}
public static List getAllGuilds() {
- ArrayList list = new ArrayList<>();
-
- for (FredBoat fb : shards) {
- list.addAll(fb.getJda().getGuilds());
- }
-
- return list;
+ return JDAUtil.getAllGuilds(shards);
}
public static int countAllGuilds() {
- return Collections.unmodifiableCollection(shards)
- .stream()
- .mapToInt(shard -> shard.getJda().getGuilds().size())
- .sum();
+ return JDAUtil.countAllGuilds(shards);
}
//this probably takes horribly long and should be solved in a different way
@@ -425,28 +421,19 @@ public static int countAllGuilds() {
// return map;
// }
- private static int biggestUserCount = -1;
+ private static AtomicInteger biggestUserCount = new AtomicInteger(-1);
//IMPORTANT: do not use this for actually counting, it will not be accurate; it is meant to be used to initialize
// sets or maps that are about to hold all those user values
public static int getExpectedUserCount() {
- if (biggestUserCount <= 0) { //initialize
+ if (biggestUserCount.get() <= 0) { //initialize
countAllUniqueUsers();
}
- return biggestUserCount;
+ return biggestUserCount.get();
}
public static long countAllUniqueUsers() {
- int expected = biggestUserCount > 0 ? biggestUserCount : LongOpenHashSet.DEFAULT_INITIAL_SIZE;
- LongOpenHashSet uniqueUsers = new LongOpenHashSet(expected + 100000); //add 100k for good measure
- Collections.unmodifiableCollection(shards).forEach(
- shard -> shard.getJda().getUsers().parallelStream().mapToLong(ISnowflake::getIdLong).forEach(uniqueUsers::add)
- );
- //never shrink the user count (might happen due to not connected shards)
- if (uniqueUsers.size() > biggestUserCount) {
- biggestUserCount = uniqueUsers.size();
- }
- return uniqueUsers.size();
+ return JDAUtil.countAllUniqueUsers(shards, biggestUserCount);
}
public static TextChannel getTextChannelById(String id) {
@@ -507,6 +494,14 @@ public ShardInfo getShardInfo() {
}
}
+ public long getGuildCount() {
+ return JDAUtil.countAllGuilds(Collections.singletonList(this));
+ }
+
+ public long getUserCount() {
+ return JDAUtil.countAllUniqueUsers(Collections.singletonList(this), biggestUserCount);
+ }
+
public abstract void revive();
public ShardWatchdogListener getShardWatchdogListener() {
diff --git a/FredBoat/src/main/java/fredboat/FredBoatBot.java b/FredBoat/src/main/java/fredboat/FredBoatBot.java
index 10ee9f546..0332218da 100644
--- a/FredBoat/src/main/java/fredboat/FredBoatBot.java
+++ b/FredBoat/src/main/java/fredboat/FredBoatBot.java
@@ -32,6 +32,7 @@
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;
+import net.dv8tion.jda.core.entities.VoiceChannel;
import net.dv8tion.jda.core.exceptions.RateLimitedException;
import net.dv8tion.jda.core.hooks.EventListener;
import org.slf4j.Logger;
@@ -109,7 +110,8 @@ public void revive() {
PlayerRegistry.getPlayingPlayers().stream()
.filter(guildPlayer -> guildPlayer.getJda().getShardInfo().getShardId() == shardId)
.forEach(guildPlayer -> {
- if (guildPlayer.getChannel() != null) channelsToRejoin.add(guildPlayer.getChannel().getId());
+ VoiceChannel channel = guildPlayer.getChannel();
+ if (channel != null) channelsToRejoin.add(channel.getId());
});
} catch (Exception ex) {
log.error("Caught exception while reviving shard " + this, ex);
diff --git a/FredBoat/src/main/java/fredboat/agent/ShardWatchdogAgent.java b/FredBoat/src/main/java/fredboat/agent/ShardWatchdogAgent.java
index 73488d6af..f24a57470 100644
--- a/FredBoat/src/main/java/fredboat/agent/ShardWatchdogAgent.java
+++ b/FredBoat/src/main/java/fredboat/agent/ShardWatchdogAgent.java
@@ -28,7 +28,7 @@
import fredboat.Config;
import fredboat.FredBoat;
import fredboat.event.ShardWatchdogListener;
-import fredboat.util.constant.DistributionEnum;
+import fredboat.shared.constant.DistributionEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/FredBoat/src/main/java/fredboat/api/API.java b/FredBoat/src/main/java/fredboat/api/API.java
index dafce27b1..d6bf8ccfc 100644
--- a/FredBoat/src/main/java/fredboat/api/API.java
+++ b/FredBoat/src/main/java/fredboat/api/API.java
@@ -74,8 +74,8 @@ public static void start() {
for (FredBoat fb : shards) {
JSONObject fbStats = new JSONObject();
fbStats.put("id", fb.getShardInfo().getShardId())
- .put("guilds", fb.getJda().getGuilds().size())
- .put("users", fb.getJda().getUsers().size())
+ .put("guilds", fb.getGuildCount())
+ .put("users", fb.getUserCount())
.put("status", fb.getJda().getStatus());
a.put(fbStats);
diff --git a/FredBoat/src/main/java/fredboat/audio/AbstractPlayer.java b/FredBoat/src/main/java/fredboat/audio/AbstractPlayer.java
index bee652e9f..285cdb2d6 100644
--- a/FredBoat/src/main/java/fredboat/audio/AbstractPlayer.java
+++ b/FredBoat/src/main/java/fredboat/audio/AbstractPlayer.java
@@ -32,7 +32,6 @@
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter;
import com.sedmelluq.discord.lavaplayer.source.bandcamp.BandcampAudioSourceManager;
import com.sedmelluq.discord.lavaplayer.source.beam.BeamAudioSourceManager;
-import com.sedmelluq.discord.lavaplayer.source.http.HttpAudioSourceManager;
import com.sedmelluq.discord.lavaplayer.source.soundcloud.SoundCloudAudioSourceManager;
import com.sedmelluq.discord.lavaplayer.source.twitch.TwitchStreamAudioSourceManager;
import com.sedmelluq.discord.lavaplayer.source.vimeo.VimeoAudioSourceManager;
@@ -49,7 +48,7 @@
import fredboat.audio.queue.TrackEndMarkerHandler;
import fredboat.audio.source.PlaylistImportSourceManager;
import fredboat.audio.source.SpotifyPlaylistSourceManager;
-import fredboat.util.constant.DistributionEnum;
+import fredboat.shared.constant.DistributionEnum;
import net.dv8tion.jda.core.audio.AudioSendHandler;
import org.slf4j.LoggerFactory;
@@ -94,7 +93,7 @@ private static void initAudioPlayerManager() {
playerManager.useRemoteNodes(Config.CONFIG.getLavaplayerNodes());
}
- playerManager.setItemLoaderThreadPoolSize(100);
+ playerManager.setItemLoaderThreadPoolSize(500);
}
}
@@ -111,7 +110,8 @@ public static AudioPlayerManager registerSourceManagers(AudioPlayerManager mng)
}
//add new source managers above the HttpAudio one, because it will either eat your request or throw an exception
//so you will never reach a source manager below it
- mng.registerSourceManager(new HttpAudioSourceManager());
+ // commented out to prevent leaking our ip
+// mng.registerSourceManager(new HttpAudioSourceManager());
return mng;
}
diff --git a/FredBoat/src/main/java/fredboat/audio/GuildPlayer.java b/FredBoat/src/main/java/fredboat/audio/GuildPlayer.java
index 66cbcca64..795a53afd 100644
--- a/FredBoat/src/main/java/fredboat/audio/GuildPlayer.java
+++ b/FredBoat/src/main/java/fredboat/audio/GuildPlayer.java
@@ -191,8 +191,13 @@ public List getLiveTracks() {
return l;
}
+ //may return null
public VoiceChannel getChannel() {
- return getUserCurrentVoiceChannel(getGuild().getSelfMember());
+ Guild guild = getGuild();
+ if (guild != null)
+ return getUserCurrentVoiceChannel(guild.getSelfMember());
+ else
+ return null;
}
/**
diff --git a/FredBoat/src/main/java/fredboat/audio/MusicPersistenceHandler.java b/FredBoat/src/main/java/fredboat/audio/MusicPersistenceHandler.java
index 99607d2ed..da0720919 100644
--- a/FredBoat/src/main/java/fredboat/audio/MusicPersistenceHandler.java
+++ b/FredBoat/src/main/java/fredboat/audio/MusicPersistenceHandler.java
@@ -34,8 +34,8 @@
import fredboat.audio.queue.RepeatMode;
import fredboat.audio.queue.SplitAudioTrackContext;
import fredboat.feature.I18n;
-import fredboat.util.constant.DistributionEnum;
-import fredboat.util.constant.ExitCodes;
+import fredboat.shared.constant.DistributionEnum;
+import fredboat.shared.constant.ExitCodes;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.VoiceChannel;
diff --git a/FredBoat/src/main/java/fredboat/command/admin/BotRestartCommand.java b/FredBoat/src/main/java/fredboat/command/admin/BotRestartCommand.java
index f1ec73197..3c379604d 100644
--- a/FredBoat/src/main/java/fredboat/command/admin/BotRestartCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/admin/BotRestartCommand.java
@@ -30,7 +30,7 @@
import fredboat.commandmeta.abs.ICommand;
import fredboat.commandmeta.abs.ICommandRestricted;
import fredboat.perms.PermissionLevel;
-import fredboat.util.constant.ExitCodes;
+import fredboat.shared.constant.ExitCodes;
import fredboat.util.TextUtils;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
diff --git a/FredBoat/src/main/java/fredboat/command/admin/ExitCommand.java b/FredBoat/src/main/java/fredboat/command/admin/ExitCommand.java
index e85300a73..22d0393b0 100644
--- a/FredBoat/src/main/java/fredboat/command/admin/ExitCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/admin/ExitCommand.java
@@ -30,7 +30,7 @@
import fredboat.commandmeta.abs.ICommand;
import fredboat.commandmeta.abs.ICommandRestricted;
import fredboat.perms.PermissionLevel;
-import fredboat.util.constant.ExitCodes;
+import fredboat.shared.constant.ExitCodes;
import fredboat.util.TextUtils;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
diff --git a/FredBoat/src/main/java/fredboat/command/admin/UpdateCommand.java b/FredBoat/src/main/java/fredboat/command/admin/UpdateCommand.java
index 3b0899373..db251f512 100644
--- a/FredBoat/src/main/java/fredboat/command/admin/UpdateCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/admin/UpdateCommand.java
@@ -30,7 +30,7 @@
import fredboat.commandmeta.abs.ICommand;
import fredboat.commandmeta.abs.ICommandRestricted;
import fredboat.perms.PermissionLevel;
-import fredboat.util.constant.ExitCodes;
+import fredboat.shared.constant.ExitCodes;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Message;
diff --git a/FredBoat/src/main/java/fredboat/command/maintenance/GitInfoCommand.java b/FredBoat/src/main/java/fredboat/command/maintenance/GitInfoCommand.java
index c8895df8d..c81be30f2 100644
--- a/FredBoat/src/main/java/fredboat/command/maintenance/GitInfoCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/maintenance/GitInfoCommand.java
@@ -68,7 +68,7 @@ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message m
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy @ hh:mm:ss z");
EmbedBuilder embedBuilder = new EmbedBuilder();
- embedBuilder.setTitle("Build & git info", url);
+ embedBuilder.setTitle("Build & git info");
embedBuilder.addField("Commit info", gitRepoState.describe + "\n\n" + gitRepoState.commitMessageFull, false);
embedBuilder.addField("Commit timestamp", gitRepoState.commitTime, false);
embedBuilder.addField("Commit on Github", url, false);
diff --git a/FredBoat/src/main/java/fredboat/command/maintenance/PingCommand.java b/FredBoat/src/main/java/fredboat/command/maintenance/PingCommand.java
new file mode 100644
index 000000000..0e653cb43
--- /dev/null
+++ b/FredBoat/src/main/java/fredboat/command/maintenance/PingCommand.java
@@ -0,0 +1,33 @@
+package fredboat.command.maintenance;
+
+import fredboat.commandmeta.abs.Command;
+import fredboat.commandmeta.abs.IMaintenanceCommand;
+import net.dv8tion.jda.core.JDA;
+import net.dv8tion.jda.core.entities.*;
+
+/**
+ * Created by epcs on 6/30/2017.
+ * Good enough of an indicator of the ping to Discord.
+ */
+
+public class PingCommand extends Command implements IMaintenanceCommand {
+ @Override
+ public String help(Guild guild) {
+ return "{0}{1}\n#Returns the ping to Discord."; //TODO: i18n
+ }
+
+ @Override
+ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message message, String[] args) {
+
+ JDA jda = guild.getJDA();
+ long ping = jda.getPing();
+
+ channel.sendMessage(ping + "ms").queue();
+ }
+}
+
+//hello
+//this is a comment
+//I want pats
+//multiple pats
+//pats never seen before
diff --git a/FredBoat/src/main/java/fredboat/command/maintenance/ShardsCommand.java b/FredBoat/src/main/java/fredboat/command/maintenance/ShardsCommand.java
index 0aa003f15..984b6779d 100644
--- a/FredBoat/src/main/java/fredboat/command/maintenance/ShardsCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/maintenance/ShardsCommand.java
@@ -29,10 +29,10 @@
import fredboat.FredBoat;
import fredboat.commandmeta.abs.Command;
import fredboat.commandmeta.abs.IMaintenanceCommand;
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.MessageBuilder;
import net.dv8tion.jda.core.entities.*;
+import net.dv8tion.jda.core.entities.impl.JDAImpl;
import java.util.ArrayList;
import java.util.List;
@@ -57,11 +57,12 @@ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message m
List shards = new ArrayList<>(FredBoat.getShards());
int borkenShards = 0;
int healthyGuilds = 0;
- LongOpenHashSet healthyUsers = new LongOpenHashSet(FredBoat.getExpectedUserCount());
+ int healthyUsers = 0;
for (FredBoat fb : shards) {
if (fb.getJda().getStatus() == JDA.Status.CONNECTED && !full) {
- healthyGuilds += fb.getJda().getGuilds().size();
- fb.getJda().getUsers().parallelStream().mapToLong(ISnowflake::getIdLong).forEach(healthyUsers::add);
+ healthyGuilds += fb.getGuildCount();
+ // casting to get the underlying map, this is safe because we only need the .size()
+ healthyUsers += ((JDAImpl) fb.getJda()).getUserMap().size();
} else {
if (borkenShards % SHARDS_PER_MESSAGE == 0) {
mb = new MessageBuilder()
@@ -74,9 +75,9 @@ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message m
.append(" ")
.append(fb.getJda().getStatus())
.append(" -- Guilds: ")
- .append(String.format("%04d", fb.getJda().getGuilds().size()))
+ .append(String.format("%04d", fb.getGuildCount()))
.append(" -- Users: ")
- .append(fb.getJda().getUsers().size())
+ .append(fb.getUserCount())
.append("\n");
borkenShards++;
}
@@ -86,7 +87,7 @@ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message m
if (!full) {
channel.sendMessage("```diff\n+ "
+ (shards.size() - borkenShards) + "/" + Config.CONFIG.getNumShards() + " shards are " + JDA.Status.CONNECTED
- + " -- Guilds: " + healthyGuilds + " -- Users: " + healthyUsers.size() + "\n```").queue();
+ + " -- Guilds: " + healthyGuilds + " -- Users: " + healthyUsers + "\n```").queue();
}
//detailed shards
diff --git a/FredBoat/src/main/java/fredboat/command/moderation/HardbanCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/HardbanCommand.java
index 4b4c14cc8..5e1e9e846 100644
--- a/FredBoat/src/main/java/fredboat/command/moderation/HardbanCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/moderation/HardbanCommand.java
@@ -37,10 +37,12 @@
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.requests.RestAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
+import java.util.function.Consumer;
/**
* Created by napster on 19.04.17.
@@ -62,18 +64,35 @@ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message m
return;
}
+ //was there a target provided?
Member target = ArgumentUtil.checkSingleFuzzyMemberSearchResult(channel, args[1]);
-
if (target == null) return;
+ //are we allowed to do that?
if (!checkHardBanAuthorization(channel, invoker, target)) return;
- target.getGuild().getController().ban(target, 7).queue(
- aVoid -> {
- TextUtils.replyWithName(channel, invoker, MessageFormat.format(I18n.get(guild).getString("hardbanSuccess"), target.getUser().getName(), target.getUser().getDiscriminator(), target.getUser().getId()));
- },
- throwable -> log.error(MessageFormat.format(I18n.get(guild).getString("modBanFail"), target.getUser()))
- );
+ //putting together a reason
+ String plainReason = DiscordUtil.getReasonForModAction(args, guild);
+ String auditLogReason = DiscordUtil.formatReasonForAuditLog(plainReason, guild, invoker);
+
+ //putting together the action
+ RestAction modAction = guild.getController().ban(target, 7, auditLogReason);
+
+ //on success
+ String successOutput = MessageFormat.format(I18n.get(guild).getString("hardbanSuccess"),
+ target.getUser().getName(), target.getUser().getDiscriminator(), target.getUser().getId())
+ + "\n" + plainReason;
+ Consumer onSuccess = aVoid -> TextUtils.replyWithName(channel, invoker, successOutput);
+
+ //on fail
+ String failOutput = MessageFormat.format(I18n.get(guild).getString("modBanFail"), target.getUser());
+ Consumer onFail = t -> {
+ log.error("Failed to ban user {} in guild {}", target.getUser().getIdLong(), guild.getIdLong(), t);
+ TextUtils.replyWithName(channel, invoker, failOutput);
+ };
+
+ //issue the mod action
+ modAction.queue(onSuccess, onFail);
}
private boolean checkHardBanAuthorization(TextChannel channel, Member mod, Member target) {
@@ -118,7 +137,7 @@ private boolean checkHardBanAuthorization(TextChannel channel, Member mod, Membe
@Override
public String help(Guild guild) {
- String usage = "{0}{1} \n#";
+ String usage = "{0}{1} \n#";
return usage + I18n.get(guild).getString("helpHardbanCommand");
}
}
diff --git a/FredBoat/src/main/java/fredboat/command/moderation/KickCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/KickCommand.java
index 1a9366307..71a3c0e3c 100644
--- a/FredBoat/src/main/java/fredboat/command/moderation/KickCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/moderation/KickCommand.java
@@ -37,10 +37,12 @@
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.requests.RestAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
+import java.util.function.Consumer;
/**
* Created by napster on 19.04.17.
@@ -62,18 +64,35 @@ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message m
return;
}
+ //was there a target provided?
Member target = ArgumentUtil.checkSingleFuzzyMemberSearchResult(channel, args[1]);
-
if (target == null) return;
+ //are we allowed to do that?
if (!checkKickAuthorization(channel, invoker, target)) return;
- target.getGuild().getController().kick(target).queue(
- aVoid -> {
- TextUtils.replyWithName(channel, invoker, MessageFormat.format(I18n.get(guild).getString("kickSuccess"), target.getUser().getName(), target.getUser().getDiscriminator(), target.getUser().getId()));
- },
- throwable -> log.error(MessageFormat.format(I18n.get(guild).getString("kickFail"), target.getUser()))
- );
+ //putting together a reason
+ String plainReason = DiscordUtil.getReasonForModAction(args, guild);
+ String auditLogReason = DiscordUtil.formatReasonForAuditLog(plainReason, guild, invoker);
+
+ //putting together the action
+ RestAction modAction = guild.getController().kick(target, auditLogReason);
+
+ //on success
+ String successOutput = MessageFormat.format(I18n.get(guild).getString("kickSuccess"),
+ target.getUser().getName(), target.getUser().getDiscriminator(), target.getUser().getId())
+ + "\n" + plainReason;
+ Consumer onSuccess = aVoid -> TextUtils.replyWithName(channel, invoker, successOutput);
+
+ //on fail
+ String failOutput = MessageFormat.format(I18n.get(guild).getString("kickFail"), target.getUser());
+ Consumer onFail = t -> {
+ log.error("Failed to kick user {} in guild {}", target.getUser().getIdLong(), guild.getIdLong(), t);
+ TextUtils.replyWithName(channel, invoker, failOutput);
+ };
+
+ //issue the mod action
+ modAction.queue(onSuccess, onFail);
}
private boolean checkKickAuthorization(TextChannel channel, Member mod, Member target) {
@@ -117,7 +136,7 @@ private boolean checkKickAuthorization(TextChannel channel, Member mod, Member t
@Override
public String help(Guild guild) {
- String usage = "{0}{1} \n#";
+ String usage = "{0}{1} \n#";
return usage + I18n.get(guild).getString("helpKickCommand");
}
}
diff --git a/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java
index 84119fd0f..8ab907eec 100644
--- a/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/moderation/PermissionsCommand.java
@@ -32,11 +32,12 @@
import fredboat.db.EntityWriter;
import fredboat.db.entity.GuildPermissions;
import fredboat.feature.I18n;
+import fredboat.feature.togglz.FeatureFlags;
import fredboat.perms.PermissionLevel;
import fredboat.perms.PermsUtil;
+import fredboat.shared.constant.BotConstants;
import fredboat.util.ArgumentUtil;
import fredboat.util.TextUtils;
-import fredboat.util.constant.BotConstants;
import net.dv8tion.jda.core.EmbedBuilder;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild;
@@ -66,6 +67,11 @@ public PermissionsCommand(PermissionLevel permissionLevel) {
@Override
public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message message, String[] args) {
+ if (!FeatureFlags.PERMISSIONS.isActive()) {
+ channel.sendMessage("Permissions are currently disabled.").queue();
+ return;
+ }
+
if (args.length < 2) {
HelpCommand.sendFormattedCommandHelp(message);
return;
diff --git a/FredBoat/src/main/java/fredboat/command/moderation/SoftbanCommand.java b/FredBoat/src/main/java/fredboat/command/moderation/SoftbanCommand.java
index 52d2ddb75..5aae530ce 100644
--- a/FredBoat/src/main/java/fredboat/command/moderation/SoftbanCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/moderation/SoftbanCommand.java
@@ -38,10 +38,12 @@
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.TextChannel;
+import net.dv8tion.jda.core.requests.RestAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
+import java.util.function.Consumer;
public class SoftbanCommand extends Command implements IModerationCommand {
@@ -50,25 +52,44 @@ public class SoftbanCommand extends Command implements IModerationCommand {
@Override
public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message message, String[] args) {
//Ensure we have a search term
- if(args.length == 1){
+ if (args.length == 1) {
String command = args[0].substring(Config.CONFIG.getPrefix().length());
HelpCommand.sendFormattedCommandHelp(guild, channel, invoker, command);
return;
}
+ //was there a target provided?
Member target = ArgumentUtil.checkSingleFuzzyMemberSearchResult(channel, args[1]);
-
if (target == null) return;
+ //are we allowed to do that?
if (!checkAuthorization(channel, invoker, target)) return;
- target.getGuild().getController().ban(target, 7).queue(
- aVoid -> {
- target.getGuild().getController().unban(target.getUser()).queue();
- TextUtils.replyWithName(channel, invoker, MessageFormat.format(I18n.get(guild).getString("softbanSuccess"), target.getUser().getName(), target.getUser().getDiscriminator(), target.getUser().getId()));
- },
- throwable -> log.error(MessageFormat.format(I18n.get(guild).getString("modBanFail"), target.getUser()))
- );
+ //putting together a reason
+ String plainReason = DiscordUtil.getReasonForModAction(args, guild);
+ String auditLogReason = DiscordUtil.formatReasonForAuditLog(plainReason, guild, invoker);
+
+ //putting together the action
+ RestAction modAction = guild.getController().ban(target, 7, auditLogReason);
+
+ //on success
+ String successOutput = MessageFormat.format(I18n.get(guild).getString("softbanSuccess"),
+ target.getUser().getName(), target.getUser().getDiscriminator(), target.getUser().getId())
+ + "\n" + plainReason;
+ Consumer onSuccess = aVoid -> {
+ guild.getController().unban(target.getUser()).queue();
+ TextUtils.replyWithName(channel, invoker, successOutput);
+ };
+
+ //on fail
+ String failOutput = MessageFormat.format(I18n.get(guild).getString("modBanFail"), target.getUser());
+ Consumer onFail = t -> {
+ log.error("Failed to ban user {} in guild {}", target.getUser().getIdLong(), guild.getIdLong(), t);
+ TextUtils.replyWithName(channel, invoker, failOutput);
+ };
+
+ //issue the mod action
+ modAction.queue(onSuccess, onFail);
}
private boolean checkAuthorization(TextChannel channel, Member mod, Member target) {
@@ -112,7 +133,7 @@ private boolean checkAuthorization(TextChannel channel, Member mod, Member targe
@Override
public String help(Guild guild) {
- String usage = "{0}{1} \n#";
+ String usage = "{0}{1} \n#";
return usage + I18n.get(guild).getString("helpSoftbanCommand");
}
}
diff --git a/FredBoat/src/main/java/fredboat/command/music/control/SkipCommand.java b/FredBoat/src/main/java/fredboat/command/music/control/SkipCommand.java
index 36881f561..f78cf1355 100644
--- a/FredBoat/src/main/java/fredboat/command/music/control/SkipCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/music/control/SkipCommand.java
@@ -42,10 +42,15 @@
import net.dv8tion.jda.core.entities.TextChannel;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.logging.impl.SLF4JLog;
+import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -53,20 +58,41 @@ public class SkipCommand extends Command implements IMusicCommand, ICommandRestr
private static final String TRACK_RANGE_REGEX = "^(0?\\d+)-(0?\\d+)$";
private static final Pattern trackRangePattern = Pattern.compile(TRACK_RANGE_REGEX);
+ /**
+ * Represents the relationship between a guild's id and skip cooldown.
+ */
+ private static Map guildIdToLastSkip = new HashMap();
+
+ /**
+ * The default cooldown for calling the {@link #onInvoke} method in milliseconds.
+ */
+ private static final int SKIP_COOLDOWN = 500;
+
@Override
public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message message, String[] args) {
GuildPlayer player = PlayerRegistry.get(guild);
player.setCurrentTC(channel);
+
if (player.isQueueEmpty()) {
channel.sendMessage(I18n.get(guild).getString("skipEmpty")).queue();
return;
}
- if(args.length == 1){
+ if (!guildIdToLastSkip.containsKey(guild.getId())) {
+ guildIdToLastSkip.put(guild.getId(), System.currentTimeMillis());
+ }
+
+ if (isOnCooldown(guild)) {
+ return;
+ }
+
+ guildIdToLastSkip.put(guild.getId(), System.currentTimeMillis());
+
+ if (args.length == 1) {
skipNext(guild, channel, invoker, args);
} else if (args.length == 2 && StringUtils.isNumeric(args[1])) {
skipGivenIndex(player, channel, invoker, args);
- } else if (args.length == 2 && trackRangePattern.matcher(args[1]).matches()){
+ } else if (args.length == 2 && trackRangePattern.matcher(args[1]).matches()) {
skipInRange(player, channel, invoker, args);
} else {
String command = args[0].substring(Config.CONFIG.getPrefix().length());
@@ -74,18 +100,29 @@ public void onInvoke(Guild guild, TextChannel channel, Member invoker, Message m
}
}
+ /**
+ * Specifies whether the skip command is on cooldown.
+ * @param guild The guild where the skip command was called.
+ * @return {@code true} if the elapsed time since the skip command is less than or equal to
+ * {@link #SKIP_COOLDOWN}; otherwise, {@code false}.
+ */
+ private boolean isOnCooldown(Guild guild) {
+ long currentTIme = System.currentTimeMillis();
+ return currentTIme - guildIdToLastSkip.get(guild.getId()) <= SKIP_COOLDOWN;
+ }
+
private void skipGivenIndex(GuildPlayer player, TextChannel channel, Member invoker, String[] args) {
int givenIndex = Integer.parseInt(args[1]);
- if(givenIndex == 1){
+ if (givenIndex == 1) {
skipNext(channel.getGuild(), channel, invoker, args);
return;
}
- if(player.getRemainingTracks().size() < givenIndex){
+ if (player.getRemainingTracks().size() < givenIndex) {
channel.sendMessage(MessageFormat.format(I18n.get(channel.getGuild()).getString("skipOutOfBounds"), givenIndex, player.getRemainingTracks().size())).queue();
return;
- } else if (givenIndex < 1){
+ } else if (givenIndex < 1) {
channel.sendMessage(I18n.get(channel.getGuild()).getString("skipNumberTooLow")).queue();
return;
}
@@ -94,7 +131,7 @@ private void skipGivenIndex(GuildPlayer player, TextChannel channel, Member invo
player.skipTracksForMemberPerms(channel, invoker, atc);
Pair result = player.skipTracksForMemberPerms(channel, invoker, atc);
- if(result.getLeft()) {
+ if (result.getLeft()) {
channel.sendMessage(MessageFormat.format(I18n.get(channel.getGuild()).getString("skipSuccess"), givenIndex, atc.getEffectiveTitle())).queue();
}
}
@@ -103,7 +140,8 @@ private void skipInRange(GuildPlayer player, TextChannel channel, Member invoker
Matcher trackMatch = trackRangePattern.matcher(args[1]);
if (!trackMatch.find()) return;
- int startTrackIndex, endTrackIndex;
+ int startTrackIndex;
+ int endTrackIndex;
String tmp = "";
try {
tmp = trackMatch.group(1);
@@ -135,21 +173,21 @@ private void skipInRange(GuildPlayer player, TextChannel channel, Member invoker
Pair pair = player.skipTracksForMemberPerms(channel, invoker, tracks);
- if(pair.getLeft()) {
+ if (pair.getLeft()) {
channel.sendMessage(MessageFormat.format(I18n.get(channel.getGuild()).getString("skipRangeSuccess"),
TextUtils.forceNDigits(startTrackIndex, 2),
TextUtils.forceNDigits(endTrackIndex, 2))).queue();
}
}
- private void skipNext(Guild guild, TextChannel channel, Member invoker, String[] args){
+ private void skipNext(Guild guild, TextChannel channel, Member invoker, String[] args) {
GuildPlayer player = PlayerRegistry.get(guild);
AudioTrackContext atc = player.getPlayingTrack();
- if(atc == null) {
+ if (atc == null) {
channel.sendMessage(I18n.get(guild).getString("skipTrackNotFound")).queue();
} else {
Pair result = player.skipTracksForMemberPerms(channel, invoker, atc);
- if(result.getLeft()) {
+ if (result.getLeft()) {
channel.sendMessage(MessageFormat.format(I18n.get(guild).getString("skipSuccess"), 1, atc.getEffectiveTitle())).queue();
}
}
diff --git a/FredBoat/src/main/java/fredboat/command/music/info/NowplayingCommand.java b/FredBoat/src/main/java/fredboat/command/music/info/NowplayingCommand.java
index abfaa80f3..d84210c53 100644
--- a/FredBoat/src/main/java/fredboat/command/music/info/NowplayingCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/music/info/NowplayingCommand.java
@@ -41,7 +41,7 @@
import fredboat.commandmeta.abs.Command;
import fredboat.commandmeta.abs.IMusicCommand;
import fredboat.feature.I18n;
-import fredboat.util.constant.BotConstants;
+import fredboat.shared.constant.BotConstants;
import fredboat.util.TextUtils;
import fredboat.util.rest.YoutubeAPI;
import fredboat.util.rest.YoutubeVideo;
diff --git a/FredBoat/src/main/java/fredboat/command/util/ServerInfoCommand.java b/FredBoat/src/main/java/fredboat/command/util/ServerInfoCommand.java
index e32a66aef..fd61c7f49 100644
--- a/FredBoat/src/main/java/fredboat/command/util/ServerInfoCommand.java
+++ b/FredBoat/src/main/java/fredboat/command/util/ServerInfoCommand.java
@@ -28,7 +28,7 @@
import fredboat.commandmeta.abs.Command;
import fredboat.commandmeta.abs.IUtilCommand;
import fredboat.feature.I18n;
-import fredboat.util.constant.BotConstants;
+import fredboat.shared.constant.BotConstants;
import net.dv8tion.jda.core.EmbedBuilder;
import net.dv8tion.jda.core.OnlineStatus;
import net.dv8tion.jda.core.entities.Guild;
diff --git a/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java b/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java
index 27d27a20c..7eb738f91 100644
--- a/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java
+++ b/FredBoat/src/main/java/fredboat/commandmeta/CommandManager.java
@@ -34,10 +34,10 @@
import fredboat.feature.I18n;
import fredboat.perms.PermissionLevel;
import fredboat.perms.PermsUtil;
+import fredboat.shared.constant.BotConstants;
+import fredboat.shared.constant.DistributionEnum;
import fredboat.util.DiscordUtil;
import fredboat.util.TextUtils;
-import fredboat.util.constant.BotConstants;
-import fredboat.util.constant.DistributionEnum;
import fredboat.util.rest.RestActionScheduler;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild;
diff --git a/FredBoat/src/main/java/fredboat/commandmeta/abs/Command.java b/FredBoat/src/main/java/fredboat/commandmeta/abs/Command.java
index 79547e481..2fbcd59b5 100644
--- a/FredBoat/src/main/java/fredboat/commandmeta/abs/Command.java
+++ b/FredBoat/src/main/java/fredboat/commandmeta/abs/Command.java
@@ -34,11 +34,11 @@
import java.util.ArrayList;
public abstract class Command implements ICommand {
-
+
public static String name = "Undefined";
- public static ArrayList aliasses = new ArrayList<>();
-
- public void onInvoke(JDA jda, Guild guild, TextChannel channel, Member invoker, Message message, ArrayList args){
+ public static ArrayList aliases = new ArrayList<>();
+
+ public void onInvoke(JDA jda, Guild guild, TextChannel channel, Member invoker, Message message, ArrayList args) {
String[] newA = new String[args.size()];
int i = 0;
for (String str : args) {
@@ -47,25 +47,25 @@ public void onInvoke(JDA jda, Guild guild, TextChannel channel, Member invoker,
}
onInvoke(guild, channel, invoker, message, newA);//Old system is default
}
-
+
public static CommandInfo getCommandInfo(){
- return new CommandInfo(name, "Undefined", "Undefined", aliasses);
+ return new CommandInfo(name, "Undefined", "Undefined", aliases);
}
-
+
public static class CommandInfo {
-
+
public String name;
public String desc;
public String usage;
- public ArrayList aliasses;
+ public ArrayList aliases;
- public CommandInfo(String name, String desc, String usage, ArrayList aliasses) {
+ public CommandInfo(String name, String desc, String usage, ArrayList aliases) {
this.name = name;
this.desc = desc;
this.usage = usage;
- this.aliasses = aliasses;
+ this.aliases = aliases;
}
-
+
}
-
+
}
diff --git a/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java b/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java
index 422f785f9..c8010d075 100644
--- a/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java
+++ b/FredBoat/src/main/java/fredboat/commandmeta/init/MainCommandInitializer.java
@@ -38,41 +38,47 @@ public class MainCommandInitializer {
public static void initCommands() {
CommandRegistry.registerCommand("help", new HelpCommand(), "info");
-
- CommandRegistry.registerCommand("unblacklist", new UnblacklistCommand(), "unlimit");
CommandRegistry.registerCommand("commands", new CommandsCommand(), "comms", "cmds");
+ CommandRegistry.registerCommand("invite", new InviteCommand());
+
+ /* Bot Maintenance */
+ CommandRegistry.registerCommand("unblacklist", new UnblacklistCommand(), "unlimit");
CommandRegistry.registerCommand("version", new VersionCommand());
- CommandRegistry.registerCommand("say", new SayCommand());
CommandRegistry.registerCommand("uptime", new StatsCommand(), "stats");
- CommandRegistry.registerCommand("serverinfo", new fredboat.command.util.ServerInfoCommand(), "guildinfo");
- CommandRegistry.registerCommand("invite", new InviteCommand());
- CommandRegistry.registerCommand("userinfo", new fredboat.command.util.UserInfoCommand(), "memberinfo");
+ CommandRegistry.registerCommand("update", new UpdateCommand());
+ CommandRegistry.registerCommand("compile", new CompileCommand());
+ CommandRegistry.registerCommand("mvntest", new MavenTestCommand());
+ CommandRegistry.registerCommand("botrestart", new BotRestartCommand());
+ CommandRegistry.registerCommand("eval", new EvalCommand());
+ CommandRegistry.registerCommand("shards", new ShardsCommand());
+ CommandRegistry.registerCommand("revive", new ReviveCommand());
+ CommandRegistry.registerCommand("test", new TestCommand());
CommandRegistry.registerCommand("gitinfo", new GitInfoCommand(), "git");
CommandRegistry.registerCommand("exit", new ExitCommand());
- CommandRegistry.registerCommand("avatar", new AvatarCommand(), "ava");
- CommandRegistry.registerCommand("test", new TestCommand());
- CommandRegistry.registerCommand("brainfuck", new BrainfuckCommand());
+
+ /* Moderation */
+ CommandRegistry.registerCommand("hardban", new HardbanCommand());
+ CommandRegistry.registerCommand("kick", new KickCommand());
+ CommandRegistry.registerCommand("softban", new SoftbanCommand());
+ CommandRegistry.registerCommand("clear", new ClearCommand());
+
+ /* Util */
+ CommandRegistry.registerCommand("serverinfo", new fredboat.command.util.ServerInfoCommand(), "guildinfo");
+ CommandRegistry.registerCommand("userinfo", new fredboat.command.util.UserInfoCommand(), "memberinfo");
+ CommandRegistry.registerCommand("ping", new PingCommand());
+ CommandRegistry.registerCommand("fuzzy", new FuzzyUserSearchCommand());
+
+ /* Fun Commands */
CommandRegistry.registerCommand("joke", new JokeCommand(), "jk");
//TODO LeetCommand is borken. Don't throw unnecessary error reports until it's fixed or removed.
// CommandRegistry.registerCommand("leet", new LeetCommand(), "1337", "l33t", "1ee7");
CommandRegistry.registerCommand("riot", new RiotCommand());
- CommandRegistry.registerCommand("update", new UpdateCommand());
- CommandRegistry.registerCommand("compile", new CompileCommand());
- CommandRegistry.registerCommand("mvntest", new MavenTestCommand());
- CommandRegistry.registerCommand("botrestart", new BotRestartCommand());
CommandRegistry.registerCommand("dance", new DanceCommand());
- CommandRegistry.registerCommand("eval", new EvalCommand());
- CommandRegistry.registerCommand("clear", new ClearCommand());
CommandRegistry.registerCommand("talk", new TalkCommand());
- CommandRegistry.registerCommand("mal", new MALCommand());
CommandRegistry.registerCommand("akinator", new AkinatorCommand());
- CommandRegistry.registerCommand("fuzzy", new FuzzyUserSearchCommand());
- CommandRegistry.registerCommand("hardban", new HardbanCommand());
- CommandRegistry.registerCommand("kick", new KickCommand());
- CommandRegistry.registerCommand("softban", new SoftbanCommand());
CommandRegistry.registerCommand("catgirl", new CatgirlCommand(), "neko", "catgrill");
- CommandRegistry.registerCommand("shards", new ShardsCommand());
- CommandRegistry.registerCommand("revive", new ReviveCommand());
+ CommandRegistry.registerCommand("avatar", new AvatarCommand(), "ava");
+ CommandRegistry.registerCommand("say", new SayCommand());
/* Other Anime Discord, Sergi memes or any other memes */
// saved in this album https://imgur.com/a/wYvDu
@@ -101,13 +107,20 @@ public static void initCommands() {
CommandRegistry.registerCommand("faceofdisapproval", new TextCommand("ಠ_ಠ"), "fod", "disapproving");
CommandRegistry.registerCommand("sendenergy", new TextCommand("༼ つ ◕_◕ ༽つ"));
CommandRegistry.registerCommand("peeking", new TextCommand("┬┴┬┴┤ ͜ʖ ͡°) ├┬┴┬┴"), "peekinglenny", "peek");
- CommandRegistry.registerCommand("dealwithit", new TextCommand("(•\\_•) ( •\\_•)>⌐■-■ (⌐■_■)"), "dwi"); //NOTE: This may break, depending on how the backlashes are handled.
+ CommandRegistry.registerCommand("dealwithit", new TextCommand("(•\\_•) ( •\\_•)>⌐■-■ (⌐■_■)"), "dwi");
CommandRegistry.registerCommand("channelingenergy", new TextCommand("(ノ◕ヮ◕)ノ*:・゚✧ ✧゚・: *ヽ(◕ヮ◕ヽ)"));
CommandRegistry.registerCommand("butterfly", new TextCommand("Ƹ̵̡Ӝ̵̨̄Ʒ"));
- CommandRegistry.registerCommand("angrytableflip", new TextCommand("(ノಠ益ಠ)ノ彡┻━┻"), "tableflipbutangry");
+ CommandRegistry.registerCommand("angrytableflip", new TextCommand("(ノಠ益ಠ)ノ彡┻━┻"), "tableflipbutangry", "atp");
CommandRegistry.registerCommand("cooldog", new DogCommand(), "dog", "dogmeme");
- CommandRegistry.registerCommand("lood", new TextCommand("T-that's l-lewd, baka!!!"), "lewd");
+ CommandRegistry.registerCommand("lood", new TextCommand("T-that's l-lewd, baka!!!"), "lewd", "l00d");
CommandRegistry.registerCommand("useless", new TextCommand("This command is useless."));
+ CommandRegistry.registerCommand("swtf", new TextCommand("¯\\\\(°_o)/¯"), "shrugwtf");
+ CommandRegistry.registerCommand("hurray", new TextCommand("ヽ(^o^)ノ"), "yay", "woot");
+
+ /* Misc - All commands under this line fall in this category */
+
+ CommandRegistry.registerCommand("mal", new MALCommand());
+ CommandRegistry.registerCommand("brainfuck", new BrainfuckCommand());
CommandRegistry.registerCommand("github", new TextCommand("https://github.com/Frederikam"));
CommandRegistry.registerCommand("repo", new TextCommand("https://github.com/Frederikam/FredBoat"));
diff --git a/FredBoat/src/main/java/fredboat/commandmeta/init/MusicCommandInitializer.java b/FredBoat/src/main/java/fredboat/commandmeta/init/MusicCommandInitializer.java
index f5e9ea413..5a27e84ff 100644
--- a/FredBoat/src/main/java/fredboat/commandmeta/init/MusicCommandInitializer.java
+++ b/FredBoat/src/main/java/fredboat/commandmeta/init/MusicCommandInitializer.java
@@ -43,9 +43,10 @@
import fredboat.command.util.CommandsCommand;
import fredboat.command.util.HelpCommand;
import fredboat.command.util.MusicHelpCommand;
+import fredboat.command.util.UserInfoCommand;
import fredboat.commandmeta.CommandRegistry;
import fredboat.perms.PermissionLevel;
-import fredboat.util.constant.DistributionEnum;
+import fredboat.shared.constant.DistributionEnum;
import fredboat.util.rest.SearchUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,52 +57,63 @@ public class MusicCommandInitializer {
public static void initCommands() {
CommandRegistry.registerCommand("help", new HelpCommand(), "info");
-
- CommandRegistry.registerCommand("mgitinfo", new GitInfoCommand(), "mgit");
- CommandRegistry.registerCommand("munblacklist", new UnblacklistCommand(), "munlimit");
- CommandRegistry.registerCommand("mexit", new ExitCommand());
- CommandRegistry.registerCommand("mbotrestart", new BotRestartCommand());
- CommandRegistry.registerCommand("mstats", new StatsCommand());
+ CommandRegistry.registerCommand("music", new MusicHelpCommand(), "musichelp");
+ CommandRegistry.registerCommand("commands", new CommandsCommand(), "comms", "cmds");
+
+ /* Control */
CommandRegistry.registerCommand("play", new PlayCommand(SearchUtil.SearchProvider.YOUTUBE), "yt", "youtube");
CommandRegistry.registerCommand("sc", new PlayCommand(SearchUtil.SearchProvider.SOUNDCLOUD), "soundcloud");
- CommandRegistry.registerCommand("meval", new EvalCommand());
CommandRegistry.registerCommand("skip", new SkipCommand(), "sk");
CommandRegistry.registerCommand("join", new JoinCommand(), "summon", "jn");
- CommandRegistry.registerCommand("nowplaying", new NowplayingCommand(), "np");
CommandRegistry.registerCommand("leave", new LeaveCommand(), "lv");
- CommandRegistry.registerCommand("list", new ListCommand(), "queue", "q");
- CommandRegistry.registerCommand("mupdate", new UpdateCommand());
- CommandRegistry.registerCommand("mcompile", new CompileCommand());
- CommandRegistry.registerCommand("mmvntest", new MavenTestCommand());
CommandRegistry.registerCommand("select", new SelectCommand(), "sel");
CommandRegistry.registerCommand("stop", new StopCommand(), "st");
CommandRegistry.registerCommand("pause", new PauseCommand(), "pa", "ps");
- CommandRegistry.registerCommand("unpause", new UnpauseCommand(), "unp", "resume");
- CommandRegistry.registerCommand("getid", new GetIdCommand());
CommandRegistry.registerCommand("shuffle", new ShuffleCommand(), "sh");
CommandRegistry.registerCommand("reshuffle", new ReshuffleCommand(), "resh");
CommandRegistry.registerCommand("repeat", new RepeatCommand(), "rep");
CommandRegistry.registerCommand("volume", new VolumeCommand(), "vol");
- CommandRegistry.registerCommand("restart", new RestartCommand());
+ CommandRegistry.registerCommand("unpause", new UnpauseCommand(), "unp", "resume");
+ CommandRegistry.registerCommand("split", new PlaySplitCommand());
+ CommandRegistry.registerCommand("destroy", new DestroyCommand());
+
+ /* Info */
+ CommandRegistry.registerCommand("nowplaying", new NowplayingCommand(), "np");
+ CommandRegistry.registerCommand("list", new ListCommand(), "queue", "q");
CommandRegistry.registerCommand("export", new ExportCommand(), "ex");
+ CommandRegistry.registerCommand("gr", new GensokyoRadioCommand(), "gensokyo", "gensokyoradio");
+ CommandRegistry.registerCommand("muserinfo", new UserInfoCommand());
+
+ /* Seeking */
+ CommandRegistry.registerCommand("seek", new SeekCommand());
+ CommandRegistry.registerCommand("forward", new ForwardCommand(), "fwd");
+ CommandRegistry.registerCommand("rewind", new RewindCommand(), "rew");
+ CommandRegistry.registerCommand("restart", new RestartCommand());
+
+ /* Bot Maintenance Commands */
+ CommandRegistry.registerCommand("mgitinfo", new GitInfoCommand(), "mgit");
+ CommandRegistry.registerCommand("munblacklist", new UnblacklistCommand(), "munlimit");
+ CommandRegistry.registerCommand("mexit", new ExitCommand());
+ CommandRegistry.registerCommand("mbotrestart", new BotRestartCommand());
+ CommandRegistry.registerCommand("mstats", new StatsCommand());
+ CommandRegistry.registerCommand("meval", new EvalCommand());
+ CommandRegistry.registerCommand("mupdate", new UpdateCommand());
+ CommandRegistry.registerCommand("mcompile", new CompileCommand());
+ CommandRegistry.registerCommand("mmvntest", new MavenTestCommand());
+ CommandRegistry.registerCommand("getid", new GetIdCommand());
CommandRegistry.registerCommand("playerdebug", new PlayerDebugCommand());
- CommandRegistry.registerCommand("music", new MusicHelpCommand(), "musichelp");
- CommandRegistry.registerCommand("commands", new CommandsCommand(), "comms", "cmds");
CommandRegistry.registerCommand("nodes", new NodesCommand());
- CommandRegistry.registerCommand("gr", new GensokyoRadioCommand(), "gensokyo", "gensokyoradio");
CommandRegistry.registerCommand("mshards", new ShardsCommand());
- CommandRegistry.registerCommand("split", new PlaySplitCommand());
- CommandRegistry.registerCommand("config", new ConfigCommand(), "cfg");
- CommandRegistry.registerCommand("lang", new LanguageCommand(), "language");
CommandRegistry.registerCommand("mrevive", new ReviveCommand());
CommandRegistry.registerCommand("adebug", new AudioDebugCommand());
CommandRegistry.registerCommand("announce", new AnnounceCommand());
- CommandRegistry.registerCommand("destroy", new DestroyCommand());
-
- CommandRegistry.registerCommand("seek", new SeekCommand());
- CommandRegistry.registerCommand("forward", new ForwardCommand(), "fwd");
- CommandRegistry.registerCommand("rewind", new RewindCommand(), "rew");
-
+ CommandRegistry.registerCommand("mping", new PingCommand());
+
+ /* Bot configuration */
+ CommandRegistry.registerCommand("config", new ConfigCommand(), "cfg");
+ CommandRegistry.registerCommand("lang", new LanguageCommand(), "language");
+
+ /* Perms */
CommandRegistry.registerCommand("admin", new PermissionsCommand(PermissionLevel.ADMIN));
CommandRegistry.registerCommand("dj", new PermissionsCommand(PermissionLevel.DJ));
CommandRegistry.registerCommand("user", new PermissionsCommand(PermissionLevel.USER));
diff --git a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java
index 5a3b743f7..1c2434f4b 100644
--- a/FredBoat/src/main/java/fredboat/db/DatabaseManager.java
+++ b/FredBoat/src/main/java/fredboat/db/DatabaseManager.java
@@ -92,6 +92,8 @@ public synchronized void startup() {
properties.put("hibernate.connection.provider_class", "org.hibernate.hikaricp.internal.HikariCPConnectionProvider");
properties.put("hibernate.connection.url", jdbcUrl);
if (dialect != null && !"".equals(dialect)) properties.put("hibernate.dialect", dialect);
+ 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
@@ -296,4 +298,4 @@ public void log(int level, String message) {
}
}
-}
\ No newline at end of file
+}
diff --git a/FredBoat/src/main/java/fredboat/db/entity/GuildPermissions.java b/FredBoat/src/main/java/fredboat/db/entity/GuildPermissions.java
index eeb219731..0d08ad9ab 100644
--- a/FredBoat/src/main/java/fredboat/db/entity/GuildPermissions.java
+++ b/FredBoat/src/main/java/fredboat/db/entity/GuildPermissions.java
@@ -26,6 +26,8 @@
package fredboat.db.entity;
import fredboat.perms.PermissionLevel;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -37,6 +39,7 @@
@Entity
@Table(name = "guild_permissions")
+@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region="guild_permissions")
public class GuildPermissions implements IEntity {
// Guild ID
diff --git a/FredBoat/src/main/java/fredboat/feature/togglz/FeatureFlags.java b/FredBoat/src/main/java/fredboat/feature/togglz/FeatureFlags.java
index bec3b42a5..2da93d348 100644
--- a/FredBoat/src/main/java/fredboat/feature/togglz/FeatureFlags.java
+++ b/FredBoat/src/main/java/fredboat/feature/togglz/FeatureFlags.java
@@ -44,7 +44,16 @@ public enum FeatureFlags implements Feature {
//using the chatbot class
@Label("Chatbot")
@EnabledByDefault
- CHATBOT;
+ CHATBOT,
+
+ @Label("Permissions")
+ @EnabledByDefault
+ PERMISSIONS,
+
+ //using data methods that don't collect everything to new data structures
+ @Label("Streaming data methods")
+ @EnabledByDefault
+ DATA_METHODS;
public boolean isActive() {
return FeatureConfig.getTheFeatureManager().isActive(this);
diff --git a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java
index 276aca72b..e88db44de 100644
--- a/FredBoat/src/main/java/fredboat/perms/PermsUtil.java
+++ b/FredBoat/src/main/java/fredboat/perms/PermsUtil.java
@@ -28,6 +28,7 @@
import fredboat.Config;
import fredboat.db.EntityReader;
import fredboat.db.entity.GuildPermissions;
+import fredboat.feature.togglz.FeatureFlags;
import fredboat.util.DiscordUtil;
import fredboat.util.TextUtils;
import net.dv8tion.jda.core.Permission;
@@ -51,6 +52,10 @@ public static PermissionLevel getPerms(Member member) {
return PermissionLevel.ADMIN;
}
+ if (!FeatureFlags.PERMISSIONS.isActive()) {
+ return PermissionUtil.checkPermission(member, Permission.MESSAGE_MANAGE) ? PermissionLevel.DJ : PermissionLevel.USER;
+ }
+
GuildPermissions gp = EntityReader.getGuildPermissions(member.getGuild());
if (checkList(gp.getAdminList(), member)) return PermissionLevel.ADMIN;
diff --git a/FredBoat/src/main/java/fredboat/util/DiscordUtil.java b/FredBoat/src/main/java/fredboat/util/DiscordUtil.java
index ed5f100cd..03d07ae90 100644
--- a/FredBoat/src/main/java/fredboat/util/DiscordUtil.java
+++ b/FredBoat/src/main/java/fredboat/util/DiscordUtil.java
@@ -28,24 +28,19 @@
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import fredboat.Config;
-import fredboat.util.constant.BotConstants;
+import fredboat.feature.I18n;
+import fredboat.shared.constant.BotConstants;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.OnlineStatus;
-import net.dv8tion.jda.core.entities.Guild;
-import net.dv8tion.jda.core.entities.Member;
-import net.dv8tion.jda.core.entities.Message;
-import net.dv8tion.jda.core.entities.Role;
-import net.dv8tion.jda.core.entities.User;
+import net.dv8tion.jda.core.entities.*;
import net.dv8tion.jda.core.exceptions.RateLimitedException;
-import net.dv8tion.jda.core.requests.Request;
-import net.dv8tion.jda.core.requests.Requester;
-import net.dv8tion.jda.core.requests.Response;
-import net.dv8tion.jda.core.requests.RestAction;
-import net.dv8tion.jda.core.requests.Route;
+import net.dv8tion.jda.core.requests.*;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.text.MessageFormat;
+import java.util.Arrays;
import java.util.List;
public class DiscordUtil {
@@ -185,4 +180,21 @@ public static JSONObject getApplicationInfo(String token) throws UnirestExceptio
.getObject();
}
+ // ########## Moderation related helper functions
+ public static String getReasonForModAction(String[] commandArgs, Guild guild) {
+ String r = null;
+ if (commandArgs.length > 2) {
+ r = String.join(" ", Arrays.copyOfRange(commandArgs, 2, commandArgs.length));
+ }
+
+ return I18n.get(guild).getString("modReason") + ": " + (r != null ? r : "No reason provided.");
+ }
+
+ public static String formatReasonForAuditLog(String plainReason, Guild guild, Member invoker) {
+ String i18nAuditLogMessage = MessageFormat.format(I18n.get(guild).getString("modAuditLogMessage"),
+ invoker.getEffectiveName(), invoker.getUser().getDiscriminator(), invoker.getUser().getId()) + ", ";
+ int auditLogMaxLength = 512 - i18nAuditLogMessage.length(); //512 is a hard limit by discord
+ return i18nAuditLogMessage + (plainReason.length() > auditLogMaxLength ?
+ plainReason.substring(0, auditLogMaxLength) : plainReason);
+ }
}
diff --git a/FredBoat/src/main/java/fredboat/util/JDAUtil.java b/FredBoat/src/main/java/fredboat/util/JDAUtil.java
new file mode 100644
index 000000000..d9de40905
--- /dev/null
+++ b/FredBoat/src/main/java/fredboat/util/JDAUtil.java
@@ -0,0 +1,146 @@
+/*
+ * 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.util;
+
+import fredboat.FredBoat;
+import fredboat.feature.togglz.FeatureFlags;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import net.dv8tion.jda.core.entities.Guild;
+import net.dv8tion.jda.core.entities.ISnowflake;
+import net.dv8tion.jda.core.entities.impl.JDAImpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * JDA methods/hacks that had merit to put in its own class.
+ *
+ * @author Shredder121
+ */
+public class JDAUtil {
+
+
+ public static int countAllGuilds(List shards) {
+ if (FeatureFlags.DATA_METHODS.isActive()) {
+ return New.countAllGuilds(shards);
+ } else {
+ return Old.countAllGuilds(shards);
+ }
+ }
+
+ public static long countAllUniqueUsers(List shards, AtomicInteger biggestUserCount) {
+ if (FeatureFlags.DATA_METHODS.isActive()) {
+ return New.countAllUniqueUsers(shards, biggestUserCount);
+ } else {
+ return Old.countAllUniqueUsers(shards, biggestUserCount);
+ }
+ }
+ public static List getAllGuilds(List shards) {
+ if (FeatureFlags.DATA_METHODS.isActive()) {
+ return New.getAllGuilds(shards);
+ } else {
+ return Old.getAllGuilds(shards);
+ }
+ }
+
+
+
+ private static class New {
+
+ public static int countAllGuilds(List shards) {
+ return shards.stream()
+ // don't do this at home, we only use it for the size()
+ .mapToInt(shard -> ((JDAImpl) shard.getJda()).getGuildMap().size())
+ .sum();
+ }
+
+ public static long countAllUniqueUsers(List shards, AtomicInteger biggestUserCount) {
+ int expected = biggestUserCount.get() > 0 ? biggestUserCount.get() : LongOpenHashSet.DEFAULT_INITIAL_SIZE;
+ LongOpenHashSet uniqueUsers = new LongOpenHashSet(expected + 100000); //add 100k for good measure
+ Collections.unmodifiableCollection(shards).forEach(
+ // IMPLEMENTATION NOTE: READ
+ // careful, touching the map is in not all cases safe
+ // In this case, it just so happens to be safe, because the map is synchronized
+ // this means however, that for the (small) duration, the map cannot be used by other threads (if there are any)
+ shard -> ((JDAImpl) shard.getJda()).getUserMap().forEachValue(user -> {
+ uniqueUsers.add(user.getIdLong());
+ return true;
+ })
+ );
+ //never shrink the user count (might happen due to not connected shards)
+ biggestUserCount.accumulateAndGet(uniqueUsers.size(), Math::max);
+ return uniqueUsers.size();
+ }
+
+ public static List getAllGuilds(List shards) {
+ ArrayList list = new ArrayList<>();
+
+ for (FredBoat fb : shards) {
+ // addAll() does actually need to use .toArray() but 1 copy is better than 2
+ list.addAll(((JDAImpl)fb.getJda()).getGuildMap().valueCollection());
+ }
+
+ return list;
+ }
+
+ private New() {
+ }
+ }
+ private static final class Old {
+
+ public static int countAllGuilds(List shards) {
+ return Collections.unmodifiableCollection(shards)
+ .stream()
+ .mapToInt(shard -> shard.getJda().getGuilds().size())
+ .sum();
+ }
+
+ public static long countAllUniqueUsers(List shards, AtomicInteger biggestUserCount) {
+ int expected = biggestUserCount.get() > 0 ? biggestUserCount.get() : LongOpenHashSet.DEFAULT_INITIAL_SIZE;
+ LongOpenHashSet uniqueUsers = new LongOpenHashSet(expected + 100000); //add 100k for good measure
+ Collections.unmodifiableCollection(shards).forEach(
+ shard -> shard.getJda().getUsers().parallelStream().mapToLong(ISnowflake::getIdLong).forEach(uniqueUsers::add)
+ );
+ //never shrink the user count (might happen due to not connected shards)
+ biggestUserCount.accumulateAndGet(uniqueUsers.size(), Math::max);
+ return uniqueUsers.size();
+ }
+
+ public static List getAllGuilds(List shards) {
+ ArrayList list = new ArrayList<>();
+
+ for (FredBoat fb : shards) {
+ list.addAll(fb.getJda().getGuilds());
+ }
+
+ return list;
+ }
+
+ private Old() {
+ }
+ }
+}
diff --git a/FredBoat/src/main/resources/lang b/FredBoat/src/main/resources/lang
index 1c64b5684..7816988fb 160000
--- a/FredBoat/src/main/resources/lang
+++ b/FredBoat/src/main/resources/lang
@@ -1 +1 @@
-Subproject commit 1c64b5684d0372d47afec346d3e80d7598d0af40
+Subproject commit 7816988fbd744ed42fb2bd284f6427268d566dbe
diff --git a/FredBoat/src/test/java/fredboat/ProvideJDASingleton.java b/FredBoat/src/test/java/fredboat/ProvideJDASingleton.java
index 9eeec6638..99010a501 100644
--- a/FredBoat/src/test/java/fredboat/ProvideJDASingleton.java
+++ b/FredBoat/src/test/java/fredboat/ProvideJDASingleton.java
@@ -1,6 +1,6 @@
package fredboat;
-import fredboat.util.constant.BotConstants;
+import fredboat.shared.constant.BotConstants;
import fredboat.util.TextUtils;
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.EmbedBuilder;
diff --git a/README.md b/README.md
index 80263af8e..0975a5403 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ 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://frederikam.github.io/FredBoat/
+Help can be found at https://docs.fredboat.com/
For installation instructions, go to http://docs.fredboat.com/selfhosting
diff --git a/Shared/pom.xml b/Shared/pom.xml
new file mode 100644
index 000000000..911d791d9
--- /dev/null
+++ b/Shared/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+ fredboat
+ FredBoat-Root
+ 1.0
+
+
+ 4.0.0
+ Shared
+ 1.0
+
+
+
+ org.json
+ json
+ 20170516
+
+
+
\ No newline at end of file
diff --git a/FredBoat/src/main/java/fredboat/util/constant/BotConstants.java b/Shared/src/main/java/fredboat/shared/constant/BotConstants.java
similarity index 97%
rename from FredBoat/src/main/java/fredboat/util/constant/BotConstants.java
rename to Shared/src/main/java/fredboat/shared/constant/BotConstants.java
index 8a1e1bc18..54a8ae3bd 100644
--- a/FredBoat/src/main/java/fredboat/util/constant/BotConstants.java
+++ b/Shared/src/main/java/fredboat/shared/constant/BotConstants.java
@@ -23,7 +23,7 @@
*
*/
-package fredboat.util.constant;
+package fredboat.shared.constant;
import java.awt.*;
diff --git a/FredBoat/src/main/java/fredboat/util/constant/DistributionEnum.java b/Shared/src/main/java/fredboat/shared/constant/DistributionEnum.java
similarity index 97%
rename from FredBoat/src/main/java/fredboat/util/constant/DistributionEnum.java
rename to Shared/src/main/java/fredboat/shared/constant/DistributionEnum.java
index acbc684d0..f2b803186 100644
--- a/FredBoat/src/main/java/fredboat/util/constant/DistributionEnum.java
+++ b/Shared/src/main/java/fredboat/shared/constant/DistributionEnum.java
@@ -23,7 +23,7 @@
*
*/
-package fredboat.util.constant;
+package fredboat.shared.constant;
public enum DistributionEnum {
MAIN("production", false),
diff --git a/FredBoat/src/main/java/fredboat/util/constant/ExitCodes.java b/Shared/src/main/java/fredboat/shared/constant/ExitCodes.java
similarity index 97%
rename from FredBoat/src/main/java/fredboat/util/constant/ExitCodes.java
rename to Shared/src/main/java/fredboat/shared/constant/ExitCodes.java
index 4a7dffb59..100833eee 100644
--- a/FredBoat/src/main/java/fredboat/util/constant/ExitCodes.java
+++ b/Shared/src/main/java/fredboat/shared/constant/ExitCodes.java
@@ -23,7 +23,7 @@
*
*/
-package fredboat.util.constant;
+package fredboat.shared.constant;
public class ExitCodes {
diff --git a/pom.xml b/pom.xml
index 455496d6e..7b56b6393 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,15 +24,68 @@
~
-->
-
+
4.0.0
fredboat
- 1.0
FredBoat-Root
+ 1.0
pom
FredBoat
FredBoat-Bootloader
+ Shared
-
\ No newline at end of file
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ jcenter
+ jcenter-bintray
+ http://jcenter.bintray.com
+
+
+
+ false
+
+ bintray-frederikam-JCA
+ bintray
+ http://dl.bintray.com/frederikam/JCA
+
+
+ sedmelluq
+ sedmelluq
+ http://maven.sedmelluq.com/
+
+
+ jitpack.io
+ https://jitpack.io
+
+
+
+
+
+
+
+ maven-clean-plugin
+ 3.0.0
+
+
+ auto-clean
+ initialize
+
+ clean
+
+
+
+
+
+
+