Open source release

This commit is contained in:
Aleksei 2020-02-13 23:01:27 -05:00
commit 434ebc4703
60 changed files with 3501 additions and 0 deletions

32
.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
.gradle
build/
bin/
# Ignore any sqlite databases created
*.db
# Stupid IntelliJ stuff
.idea
*.iml
out/
# Stupid VSCode stuff
.vscode
# Stupid Eclipse project files
.classpath
.project
.settings
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Ignore commandler files
cmdframework.db
config.properties
# Ignore the bot config
bot.config

33
build.gradle Normal file
View File

@ -0,0 +1,33 @@
/*
* Developed by Alek Gryczewski on 10/18/18 1:39 PM
* Last modified 9/25/18 7:33 PM
* Copyright (c) 2018. All rights reserved.
*/
plugins {
id 'application'
}
group 'studio.spiderling'
version '1.1.11'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven {
url 'https://jitpack.io'
}
}
dependencies {
implementation 'com.github.Kaaz:ConfigurationBuilder:0.4'
implementation group: 'org.javacord', name: 'javacord', version:'3.0.5'
implementation group: 'com.rethinkdb', name: 'rethinkdb-driver', version: '2.3.3'
implementation 'com.vdurmont:emoji-java:4.0.0'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
mainClassName = 'dev.salmonllama.fsbot.Main'

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,12 @@
#
# Developed by Alek Gryczewski on 10/18/18 1:39 PM
# Last modified 8/10/18 4:16 AM
# Copyright (c) 2018. All rights reserved.
#
#Fri Aug 10 04:16:52 EDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip

172
gradlew vendored Normal file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored Normal file
View File

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

BIN
profilePic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
profilePicDEV.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

8
settings.gradle Normal file
View File

@ -0,0 +1,8 @@
/*
* Developed by Alek Gryczewski on 10/18/18 1:39 PM
* Last modified 8/27/18 6:45 PM
* Copyright (c) 2018. All rights reserved.
*/
rootProject.name = 'fsbot'

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.net.Connection;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Guthix;
import dev.salmonllama.fsbot.listeners.*;
import org.javacord.api.DiscordApiBuilder;
import dev.salmonllama.fsbot.utilities.Constants;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
// TODO: auto-switching status messages.
// TODO: Add an official Logger --> logging to Discord, not console
public class Main {
public static void main(String[] args) {
String configLocation = Constants.BOT_FOLDER.concat(Constants.CONFIG_NAME);
BotConfig.initConfig(configLocation);
// Initialise the database with values from the bot's config file
RethinkDB r = RethinkDB.r;
Connection conn = r.connection().hostname(BotConfig.DB_HOST).port(BotConfig.DB_PORT).connect();
new DiscordApiBuilder().setToken(BotConfig.TOKEN).login().thenAccept(api -> {
DatabaseUtilities db = new DatabaseUtilities(r, conn, api);
db.tableSetup();
Guthix guthix = new Guthix(api, db);
// Register listeners
api.addMessageCreateListener(new ImageListener(r, conn));
api.addServerMemberJoinListener(new NewMemberListener(api));
api.addServerJoinListener(new ServerJoined(api, db));
api.addMessageCreateListener(new ThumbsListener());
api.addMessageCreateListener(new AchievementListener());
api.addMessageCreateListener(new ReportListener());
System.out.println(String.format("Bot invite: %s", api.createBotInvite()));
System.out.println(String.format("Logged in as %s", api.getYourself().getDiscriminatedName()));
});
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.developer;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.net.Connection;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.server.Server;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class CreateGalleryCommand extends Command { // TODO: This command needs help.
@Override public String name() { return "Create Gallery"; }
@Override public String description() { return "Creates a channel gallery, tracking any posted images"; }
@Override public String usage() { return "creategallery <String tag>"; }
@Override public String category() { return "Developer"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.OWNER); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("creategallery", "addgallery", "addgall")); }
static final RethinkDB R = RethinkDB.r;
static final Connection CONN = R.connection().hostname("localhost").port(28015).connect();
@Override
public void onCommand(CommandContext ctx) {
Server server = ctx.getServer();
TextChannel channel = ctx.getChannel();
String[] args = ctx.getArgs();
String targetChannelId = channel.getIdAsString();
String targetChannelName = channel.asServerChannel().get().getName(); // TODO: un-band-aid this.
String targetServerName = server.getName();
String targetServerId = server.getIdAsString();
if (!server.getIdAsString().equals(BotConfig.HOME_SERVER)) {
channel.sendMessage("Fashion galleries can only be created in the Fashionscape server");
return;
}
if (args.length < 1) {
channel.sendMessage("No Arguments provided");
return;
}
else if (args.length > 1) {
channel.sendMessage("Too many arguments provided.");
return;
}
String tag = args[0];
if (R.db("fsbot").table("channels").getField("cId").contains(targetChannelId).run(CONN)) {
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.RED)
.addField("ERROR", "This channel is already gathering images");
channel.sendMessage(embed);
}
else {
R.db("fsbot").table("channels").insert(
R.hashMap("sName", targetServerName)
.with("sId", targetServerId)
.with("cName", targetChannelName)
.with("cId", targetChannelId)
.with("tag", tag)
).run(CONN);
R.db("fsbot").tableCreate(tag).run(CONN);
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.GREEN)
.addField("Success", "Channel added to storage with the following values:")
.addField("Channel Name:", targetChannelName)
.addField("Channel Id:", targetChannelId)
.addField("Tag:", tag)
.addField("End:", String.format("Table \"%s\" created for images in this channel", tag));
channel.sendMessage(embed);
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.developer;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class EvalCommand extends Command {
@Override public String name() { return "Eval"; }
@Override public String description() { return "Evaluates the given parameters"; }
@Override public String usage() { return "eval <statement>"; }
@Override public String category() { return "Developer"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.OWNER); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("eval", "ev")); }
private final DatabaseUtilities db;
public EvalCommand(DatabaseUtilities db) {
this.db = db;
}
@Override
public void onCommand(CommandContext ctx) {
String statement = String.join(" ", ctx.getArgs());
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.put("db", db);
try {
Object result = engine.eval(statement);
ctx.reply(result.toString());
}
catch (Exception e) {
ctx.reply(e.getMessage());
}
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.developer;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.TextChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class InviteCommand extends Command {
@Override public String name() { return "Invite"; }
@Override public String description() { return "Spits out a bot invite"; }
@Override public String usage() { return "invite"; }
@Override public String category() { return "Developer"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.OWNER); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("invite", "inv")); }
@Override
public void onCommand(CommandContext ctx) {
TextChannel channel = ctx.getChannel();
DiscordApi api = ctx.getApi();
channel.sendMessage(String.format("<%s>", api.createBotInvite()));
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.developer;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class TestCommand extends Command {
@Override public String name() { return "Test"; }
@Override public String description() { return "A test command"; }
@Override public String usage() { return "test"; }
@Override public String category() { return "Developer"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.OWNER); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("test", "t")); }
@Override
public void onCommand(CommandContext ctx) {
ctx.getChannel().sendMessage("Test Command has been invoked");
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.general;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import dev.salmonllama.fsbot.utilities.ColorRole;
import dev.salmonllama.fsbot.utilities.database.RoleColourUtility;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.permission.Role;
import org.javacord.api.entity.server.Server;
import dev.salmonllama.fsbot.utilities.warnings.Warning;
import org.javacord.api.entity.user.User;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ColorCommand extends Command {
@Override public String name() { return "Color"; }
@Override public String description() { return "Assigns the provided cosmetic role"; }
@Override public String usage() { return "color <colorName>"; }
@Override public String category() { return "General"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.NONE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("color", "colour")); }
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
DiscordApi api = ctx.getApi();
Server server = ctx.getServer();
User user = ctx.getUser();
TextChannel channel = ctx.getChannel();
// Live server
if (!server.getIdAsString().equals(BotConfig.HOME_SERVER)) { return; }
if (!user.getRoles(server).contains(server.getRoleById(BotConfig.HYDRIX_ROLE).orElseThrow(AssertionError::new))) {
channel.sendMessage(new Warning("You need the Hydrix role to use this").sendWarning());
return;
}
if (args.length != 1) {
channel.sendMessage(new Warning("Not enough arguments provided").sendWarning());
return;
}
// args[0] is the subcommand, either list, or a colour
if (args[0].equals("list")) {
System.out.println(RoleColourUtility.getAllRoleInfo());
return;
}
String roleId = RoleColourUtility.getColour(args[0]);
Role role;
if (!api.getRoleById(roleId).isPresent()) {
channel.sendMessage(new Warning("That role doesn't exist, mate!").sendWarning());
return;
}
else {
role = api.getRoleById(roleId).get();
}
// Actual command logic now
// Remove all the colour roles from the user, except the target one
List<ColorRole> allRoles = RoleColourUtility.getAllRoles();
allRoles.forEach(r -> {
if (r.id.equals(roleId)) {
server.removeRoleFromUser(user, server.getRoleById(r.id).orElseThrow(AssertionError::new));
}
});
// If user already has the role, remove it
if (user.getRoles(server).contains(role)) {
user.removeRole(role);
channel.sendMessage(new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Role Removed")
.addInlineField("Role:", role.getName())
);
}
else {
user.addRole(role);
channel.sendMessage(new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Role Added")
.addInlineField("Role:", role.getName())
);
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.general;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.server.Server;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.utilities.ColorRole;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class ColorsCommand extends Command {
@Override public String name() { return "Colors"; }
@Override public String description() { return "Lists available cosmetic roles"; }
@Override public String usage() { return "colors"; }
@Override public String category() { return "General"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.NONE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("colors", "colours")); }
@Override
public void onCommand(CommandContext ctx) {
Server server = ctx.getServer();
TextChannel channel = ctx.getChannel();
if (!server.getIdAsString().equals(BotConfig.HOME_SERVER)) {
return;
}
channel.sendMessage(ColorRole.rolesListEmbed());
}
}

View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.general;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.*;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class HelpCommand extends Command {
@Override public String name() { return "Help"; }
@Override public String description() { return "Shows all commands, or a specific command's information"; }
@Override public String usage() { return "help [String command]"; }
@Override public String category() { return "General"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.NONE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("help", "h")); }
private final Guthix guthix;
public HelpCommand(Guthix guthix) {
this.guthix = guthix;
}
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
TextChannel channel = ctx.getChannel();
String prefix = BotConfig.DEFAULT_PREFIX;
if (args.length == 0) {
channel.sendMessage(buildCategoryHelp(prefix));
}
if (args.length == 1) {
if (isCategory(args[0])) {
channel.sendMessage(buildTargetCategory(prefix, args[0]));
}
else if (isCommand(args[0])) {
channel.sendMessage(buildCommandHelp(channel, prefix, args[0]));
}
else {
channel.sendMessage("No match found");
}
}
}
private EmbedBuilder buildCategoryHelp(String prefix) {
StringBuilder builder = new StringBuilder();
builder.append("```yml");
List<String> categories = new ArrayList<>();
for (Command cmd : guthix.listCommands()) {
String category = cmd.category();
if (!categories.contains(category)) {
categories.add(category);
builder.append("\n -").append(category);
}
}
builder.append("```");
return new EmbedBuilder()
.setTitle("Command Categories")
.setColor(Color.GREEN)
.addField("Prefix", String.format("```%s```", prefix))
.addField("Categories", builder.toString())
.setFooter(String.format("Use `%shelp <category> to see commands in the category", prefix));
}
private EmbedBuilder buildTargetCategory(String prefix, String category) {
StringBuilder builder = new StringBuilder().append("```yml");
for (Command cmd : guthix.listCommands()) {
String cat = cmd.category().toLowerCase();
if (cat.equals(category.toLowerCase())) {
builder.append("\n- ").append(cmd.name());
}
}
builder.append("```");
return new EmbedBuilder()
.setTitle(String.format("%s Commands", category))
.setColor(Color.GREEN)
.addField("Prefix", String.format("```%s```", prefix))
.addField("Commands:", builder.toString())
.setFooter(String.format("Use `%shelp <command> to see command info", prefix));
}
private EmbedBuilder buildCommandHelp(TextChannel channel, String prefix, String command) {
String targetedCommand = null;
Collection<String> targetedAliases = null;
String targetedDescription = null;
String targetedUsage = null;
CommandPermission targetedPermissions = null; // TODO: Make a toString() method for this eh?
for (Command cmd : guthix.listCommands()) {
for (String alias : cmd.aliases()) {
if (alias.equals(command)) {
targetedCommand = cmd.name();
targetedAliases = cmd.aliases();
targetedDescription = cmd.description();
targetedUsage = cmd.usage();
targetedPermissions = cmd.permission();
}
}
}
if (targetedCommand == null) {
return new EmbedBuilder()
.setColor(Color.RED)
.addField("ERROR:", "That command does not exist");
}
StringBuilder builder = new StringBuilder();
builder.append("```yml\n");
if (targetedAliases.size() != 0) {
builder.append(String.format("- Aliases: %s\n", String.join(", ", targetedAliases)));
}
if (!targetedDescription.equals("none")) {
builder.append(String.format("- Description: %s\n", targetedDescription));
}
if (!targetedUsage.equals("")) {
builder.append(String.format("- Usage: %s\n", targetedUsage));
}
builder.append(String.format("- Permissions: %s\n", targetedPermissions));
builder.append("```");
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle(String.format("%s%s", prefix, targetedCommand))
.setDescription(builder.toString());
}
public boolean isCommand(String input) {
for (Command cmd : guthix.listCommands()) {
Collection<String> aliases = cmd.aliases();
for (String alias : aliases) {
if (alias.toLowerCase().equals(input.toLowerCase())) {
return true;
}
}
}
return false;
}
public boolean isCategory(String input) {
for (Command cmd : guthix.listCommands()) {
String category = cmd.category();
if (category.toLowerCase().equals(input.toLowerCase())) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.general;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.Message;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class OutfitCommand extends Command {
@Override public String name() { return "Outfit"; }
@Override public String description() { return "Generates a random image with the given tag. Use ~tags to see valid tags."; }
@Override public String usage() { return "outfit <String tag>"; }
@Override public String category() { return "General"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.NONE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("outfit", "o")); }
private final DatabaseUtilities db;
public OutfitCommand(DatabaseUtilities db) {
this.db = db;
}
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
TextChannel channel = ctx.getChannel();
Message message = ctx.getMessage();
// Find the first arg for tag/submitter/naught, find the next arg for number to send
int MAX_OUTFITS = 5;
if (args.length == 0) {
channel.sendMessage(db.randomOutfit().generateEmbed());
}
else if (message.getMentionedUsers().size() > 0) {
// Outfit needs to be from submitter
String userId = message.getMentionedUsers().get(0).getIdAsString();
if (args.length == 2) {
// Send a number of outfits
int iterator = ((Integer.parseInt(args[1]) > MAX_OUTFITS) ? MAX_OUTFITS : Integer.parseInt(args[1]));
for (int i = 0; i < iterator; i++) {
channel.sendMessage(db.getOutfitBySubmitter(userId).generateEmbed());
}
}
else {
channel.sendMessage(db.getOutfitBySubmitter(userId).generateEmbed());
}
}
else if (db.getTags().contains(args[0].toLowerCase())) {
// Outfit needs to be tagged
String tag = args[0];
if (args.length == 2) {
// Send a number of outfits
int iterator = ((Integer.parseInt(args[1]) > MAX_OUTFITS) ? MAX_OUTFITS : Integer.parseInt(args[1]));
for (int i = 0; i < iterator; i++) {
channel.sendMessage(db.randomTaggedOutfit(tag).generateEmbed());
}
}
else {
channel.sendMessage(db.randomTaggedOutfit(tag).generateEmbed());
}
}
else if (args.length == 1 && args[0].matches("\\d")) {
int iterator = ((Integer.parseInt(args[0]) > MAX_OUTFITS) ? MAX_OUTFITS : Integer.parseInt(args[0]));
for (int i = 0; i < iterator; i++) {
channel.sendMessage(db.randomOutfit().generateEmbed());
}
}
else {
channel.sendMessage("Something went wrong");
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.general;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import java.util.*;
public class PingCommand extends Command {
@Override public String name() { return "Ping"; }
@Override public String description() { return "Pings the bot, checks for a heartbeat"; }
@Override public String usage() { return "ping"; }
@Override public String category() { return "General"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.NONE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Collections.singletonList("ping")); }
@Override
public void onCommand(CommandContext ctx) {
final long start = System.currentTimeMillis();
ctx.getChannel().sendMessage("I'm alive").thenAccept(msg -> {
final long end = System.currentTimeMillis();
msg.edit(String.format("I'm alive! (%sms)", (end - start)));
});
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.general;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.channel.ServerTextChannel;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import org.javacord.api.entity.channel.TextChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
public class SpecificOutfitCommand extends Command {
@Override public String name() { return "Specific Outfit"; }
@Override public String description() { return "Generates an outfit of a specific tag"; }
@Override public String usage() { return "<String tag> [int number]"; }
@Override public String category() { return "General"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.NONE); }
@Override public Collection<String> aliases() { return new ArrayList<>(db.getTags()); }
private final DatabaseUtilities db;
public SpecificOutfitCommand(DatabaseUtilities db) {
this.db = db;
}
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
String tag = ctx.getUsedAlias();
TextChannel channel = ctx.getChannel();
if (args.length == 1) {
// Send the specific number of outfits with a max of 5
int outfitNumber = Integer.parseInt(args[0]);
if (outfitNumber > 5) { outfitNumber = 5; }
for (int i = 0; i < outfitNumber; i++) {
channel.sendMessage(db.randomTaggedOutfit(tag).generateEmbed());
}
}
else if (args.length > 1) {
channel.sendMessage("You did that wrong, mate");
}
else {
channel.sendMessage(db.randomTaggedOutfit(tag).generateEmbed());
}
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import dev.salmonllama.fsbot.utilities.database.RoleColourUtility;
import dev.salmonllama.fsbot.utilities.warnings.Warning;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.permission.Role;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class AddColorCommand extends Command {
@Override public String name() { return "Add Color"; }
@Override public String description() { return "adds the provided role to the toggleable cosmetic roles."; }
@Override public String usage() { return "addcolor <colorName> <roleId>"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("addcolor", "addcolour", "addclr")); }
@Override
public void onCommand(CommandContext ctx) {
String[] args = (String[]) ctx.getArgs();
TextChannel channel = ctx.getChannel();
DiscordApi api = ctx.getApi();
if (args.length != 2) {
channel.sendMessage(new Warning("Insufficient arguments").sendWarning());
return;
}
String colour = args[0];
String id = args[1];
Role role = api.getRoleById(args[1]).orElse(null);
if (role == null) {
channel.sendMessage(new Warning("Supplied roleId isn't a roleId").sendWarning());
return;
}
RoleColourUtility.addColourRole(colour, id);
channel.sendMessage(new EmbedBuilder()
.setTitle(role.getName())
.setColor(role.getColor().orElse(Color.GREEN))
.addField("Role id:", role.getIdAsString())
.addField("Colour to be stored as:", args[0])
);
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class EchoCommand extends Command {
@Override public String name() { return "Echo"; }
@Override public String description() { return "Echos your message. Typical bash"; }
@Override public String usage() { return "echo <message>"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Collections.singletonList("echo")); }
@Override
public void onCommand(CommandContext ctx) {
String echoMessage = String.join(" ", ctx.getArgs());
ctx.getMessage().delete();
ctx.reply(echoMessage);
}
}

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.net.Connection;
import com.rethinkdb.net.Cursor;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class GetOutfitCommand extends Command { // TODO: This command also needs HELP
@Override public String name() { return "Get Outift"; }
@Override public String description() { return "Shows the outfit, given an ID"; }
@Override public String usage() { return "getoutfit <String id>"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("getoutfit", "get")); }
static final RethinkDB r = RethinkDB.r;
static final Connection conn = r.connection().hostname("localhost").port(28015).connect();
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
TextChannel channel = ctx.getChannel();
if (args.length != 1) {
channel.sendMessage("you did that wrong mate");
return;
}
String id = args[0];
// Check if the given id exists in the table
try {
r.db("fsbot").table("outfits").filter(row -> row.getField("id").eq(id)).run(conn);
}
catch (Exception e) {
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.RED)
.addField("ERROR:", "That id does not exist in that table")
.addField("Output:", e.toString())
.setFooter("Contact Salmonllama#5727 if you see this");
channel.sendMessage(embed);
return;
}
// Get the entry for the given table/tag and id, build the embed, and send it.
try {
String embedLink = null;
String embedSubmitter = null;
Cursor linkCursor = r.db("fsbot")
.table("outfits")
.filter(row -> row.getField("id").eq(id))
.getField("link")
.run(conn);
Cursor submitterCursor = r.db("fsbot")
.table("outfits")
.filter(row -> row.getField("id").eq(id))
.getField("submitter")
.run(conn);
List links = linkCursor.toList();
for (Object link : links) {
embedLink = link.toString();
}
List submitters = submitterCursor.toList();
for (Object submitter : submitters) {
embedSubmitter = submitter.toString();
}
// Send a diff message if any of the things are null
if (embedLink == null) {
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.RED)
.addField("ERROR: ", "The entry you tried to access doesn't exist.");
channel.sendMessage(embed);
return;
}
// Send the final Embed with the outfit image as a link, the submitter, and the id of the image.
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.GREEN)
.setAuthor(embedSubmitter)
.setImage(embedLink)
.setFooter(id);
channel.sendMessage(embed);
}
catch (Exception e) {
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.RED)
.addField("ERROR:", "Something went wrong...")
.addField("Output:", e.toString())
.setFooter("Contact Crablet#9999 and show him this error.");
channel.sendMessage(embed);
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.server.Server;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class GetServersCommand extends Command {
@Override public String name() { return "Get Servers"; }
@Override public String description() { return "Lists all the servers the bot is in"; }
@Override public String usage() { return "getservers"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("getservers", "servers")); }
@Override
public void onCommand(CommandContext ctx) {
DiscordApi api = ctx.getApi();
StringBuilder builder = new StringBuilder();
builder.append("```md");
for (Server server : api.getServers()) {
String serverId = server.getIdAsString();
String serverName = server.getName();
builder.append(String.format("\n- %s: %s", serverName, serverId));
}
builder.append("\n```");
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Servers")
.setDescription(builder.toString())
.setFooter(String.format("%s is in %d servers", api.getYourself().getName(), api.getServers().size()));
ctx.getChannel().sendMessage(embed).join();
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.DiscordApi;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import dev.salmonllama.fsbot.utilities.exceptions.DiscordError;
import dev.salmonllama.fsbot.utilities.exceptions.OutfitNotFoundException;
import org.javacord.api.entity.channel.TextChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class OutfitInfoCommand extends Command {
@Override public String name() { return "Outfit Info"; }
@Override public String description() { return "Shows all related info about the outfit"; }
@Override public String usage() { return "outfitinfo <String id>"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("outfitinfo", "oinfo")); }
private final DatabaseUtilities db;
public OutfitInfoCommand(DatabaseUtilities db) {
this.db = db;
}
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
DiscordApi api = ctx.getApi();
TextChannel channel = ctx.getChannel();
if (args.length != 1) {
channel.sendMessage(String.format("you did that wrong. bother %s to make these more specific.", api.getOwner().join().getDiscriminatedName()));
return;
}
try {
channel.sendMessage(db.getOutfitFromId(args[0]).generateInfo());
}
catch (OutfitNotFoundException e) {
channel.sendMessage(new DiscordError(e.getMessage()).get());
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import com.vdurmont.emoji.EmojiParser;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.user.User;
import dev.salmonllama.fsbot.listeners.ReactionDeleteConfirmationListener;
import dev.salmonllama.fsbot.utilities.Outfit;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import dev.salmonllama.fsbot.utilities.exceptions.DiscordError;
import dev.salmonllama.fsbot.utilities.exceptions.OutfitNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class RemoveOutfitCommand extends Command {
@Override public String name() { return "Remove Outfit"; }
@Override public String description() { return "Removes an outfit from the database given an id"; }
@Override public String usage() { return "remove <String id>"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("removeoutfit", "remove")); }
private final DatabaseUtilities db;
public RemoveOutfitCommand(DatabaseUtilities db) {
this.db = db;
}
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
TextChannel channel = ctx.getChannel();
User author = ctx.getUser();
if (args.length != 1) {
channel.sendMessage("You did that wrong, mate");
return;
}
// get the outfit, confirm deletion through reaction.
try {
Outfit outfit = db.getOutfitFromId(args[0]);
channel.sendMessage(outfit.generateInfo().setTitle("Confirm Outfit Deletion")).thenAccept(message -> {
message.addReaction(EmojiParser.parseToUnicode(":white_check_mark:"));
message.addReaction(EmojiParser.parseToUnicode(":octagonal_sign:"));
message.addReactionAddListener(new ReactionDeleteConfirmationListener(author, message, outfit, db));
});
}
catch (OutfitNotFoundException e) {
channel.sendMessage(new DiscordError(e.getMessage()).get());
}
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import com.vdurmont.emoji.EmojiParser;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.user.User;
import dev.salmonllama.fsbot.listeners.ReactionRetagConfirmationListener;
import dev.salmonllama.fsbot.utilities.Outfit;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import dev.salmonllama.fsbot.utilities.exceptions.DiscordError;
import dev.salmonllama.fsbot.utilities.exceptions.OutfitNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class RetagCommand extends Command {
@Override public String name() { return "Retag"; }
@Override public String description() { return "Changes the tag of the given outfit"; }
@Override public String usage() { return "retag <String id> <String newtag>"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Collections.singletonList("retag")); }
private final DatabaseUtilities db;
public RetagCommand(DatabaseUtilities db) {
this.db = db;
}
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
TextChannel channel = ctx.getChannel();
User author = ctx.getUser();
if (args.length != 2) {
channel.sendMessage("You did that wrong mate. check the help command.");
return;
}
try {
Outfit outfit = this.db.getOutfitFromId(args[0]);
channel.sendMessage(outfit.generateInfo().setTitle(String.format("Update tag to %s?", args[1]))).thenAcceptAsync(message -> {
message.addReaction(EmojiParser.parseToUnicode(":white_check_mark:"));
message.addReaction(EmojiParser.parseToUnicode(":octagonal_sign:"));
message.addReactionAddListener(new ReactionRetagConfirmationListener(author, message, outfit, db, outfit.getTag(), args[1]));
});
}
catch (OutfitNotFoundException e) {
channel.sendMessage(new DiscordError(e.getMessage()).get());
}
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import com.vdurmont.emoji.EmojiParser;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class SetStatusCommand extends Command {
@Override public String name() { return "Set Status"; }
@Override public String description() { return "Updates the bot's current status"; }
@Override public String usage() { return "updatestatus <String status>"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("setstatus", "status")); }
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
// argument checking
if (args.length == 0) {
EmbedBuilder embed = new EmbedBuilder()
.setColor(Color.YELLOW)
.addField("WARNING", "Not enough arguments supplied");
ctx.getChannel().sendMessage(embed);
return;
}
String status = String.join(" ", args);
ctx.getApi().updateActivity(status);
ctx.getMessage().addReaction(EmojiParser.parseToUnicode(":white_check_mark:"));
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.commands.staff;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.guthix.Command;
import dev.salmonllama.fsbot.guthix.CommandContext;
import dev.salmonllama.fsbot.guthix.CommandPermission;
import dev.salmonllama.fsbot.guthix.PermissionType;
import dev.salmonllama.fsbot.utilities.database.ServerConfUtility;
import dev.salmonllama.fsbot.utilities.warnings.Warning;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.server.Server;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class WelcomeMessageCommand extends Command {
@Override public String name() { return "Welcome Message"; }
@Override public String description() { return "View or update the server welcome message. Options: get|set|getchannel|setchannel."; }
@Override public String usage() { return "welcomemessage <String opt> [String newMessage]"; }
@Override public String category() { return "Staff"; }
@Override public CommandPermission permission() { return new CommandPermission(PermissionType.ROLE, BotConfig.STAFF_ROLE); }
@Override public Collection<String> aliases() { return new ArrayList<>(Arrays.asList("welcomemessage", "wmsg")); }
@Override
public void onCommand(CommandContext ctx) {
String[] args = ctx.getArgs();
TextChannel channel = ctx.getChannel();
Server server = ctx.getServer();
if (!server.getIdAsString().equals(BotConfig.HOME_SERVER)) {
return;
}
if (args.length == 0) channel.sendMessage(new Warning("Not enough arguments provided").sendWarning());
switch (args[0]) {
case ("get"):
channel.sendMessage(fetchWelcomeMsg(server));
break;
case ("set"):
StringBuilder sb = new StringBuilder();
for (int i = 1; i < args.length; i++) {
sb.append(String.format("%s ", args[i]));
}
channel.sendMessage(updateWelcomeMsg(sb.toString(), server));
break;
case ("getchannel"):
channel.sendMessage(fetchWelcomeChannel(server));
break;
case ("setchannel"):
if (args.length < 2) channel.sendMessage(new Warning("Not enough arguments provided").sendWarning());
channel.sendMessage(updateWelcomeChannel(args[1], server));
break;
}
}
private EmbedBuilder fetchWelcomeMsg(Server server) {
ServerConfUtility conf = new ServerConfUtility(server.getIdAsString());
String msg = conf.getWelcomeMsg();
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Current welcome message:")
.setDescription(msg);
}
private EmbedBuilder updateWelcomeMsg(String msg, Server server) {
ServerConfUtility conf = new ServerConfUtility(server.getIdAsString());
conf.setWelcomeMsg(msg);
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Welcome message updated")
.addField("New welcome message:", msg);
}
private EmbedBuilder fetchWelcomeChannel(Server server) {
ServerConfUtility conf = new ServerConfUtility(server.getIdAsString());
String welcomeChannel = conf.getWelcomeChannel();
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Current welcome channel:")
.setDescription(welcomeChannel);
}
private EmbedBuilder updateWelcomeChannel(String id, Server server) {
ServerConfUtility conf = new ServerConfUtility(server.getIdAsString());
conf.setWelcomeChannel(id);
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Welcome channel updated:")
.addField("New welcome channel:", id);
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.config;
import com.kaaz.configuration.ConfigurationBuilder;
import com.kaaz.configuration.ConfigurationOption;
import java.io.File;
public class BotConfig {
@ConfigurationOption
public static String TOKEN = "token-goes-here";
@ConfigurationOption
public static String DB_HOST = "localhost";
@ConfigurationOption
public static int DB_PORT = 28015;
@ConfigurationOption
public static String DEFAULT_PREFIX = "~";
@ConfigurationOption
public static String BOT_OWNER = "owner's id here";
@ConfigurationOption
public static String STAFF_ROLE = "staff role id here";
@ConfigurationOption
public static String REPORT_CHANNEL = "report channel";
@ConfigurationOption
public static String ACHIEVEMENT_CHANNEL = "achievement channel here";
@ConfigurationOption
public static String ANNOUNCEMENT_CHANNEL = "announcement channel here";
@ConfigurationOption
public static String NEWS_CHANNEL = "news channel here";
@ConfigurationOption
public static String VOTE_CHANNEL = "vote channel here";
@ConfigurationOption
public static String REPORT_LOG = "report_log_channel";
@ConfigurationOption
public static String OUTFIT_LOG = "outfit log channel";
@ConfigurationOption
public static String BOT_LOG = "bot_log_channel";
@ConfigurationOption
public static String HYDRIX_ROLE = "hydrix role id here";
@ConfigurationOption
public static String IMGUR_ID = "imgur_id_here";
@ConfigurationOption
public static String IMGUR_BEARER = "imgur bearer here";
@ConfigurationOption
public static String HOME_SERVER = "340511685024546816";
public static void initConfig(String filePath) {
try {
new ConfigurationBuilder(BotConfig.class, new File(filePath)).build(false);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
import java.util.Collection;
public abstract class Command {
public abstract String name();
public abstract String description();
public abstract String usage();
public abstract String category();
public abstract CommandPermission permission();
public abstract Collection<String> aliases();
public abstract void onCommand(CommandContext ctx);
public void invoke(final CommandContext ctx) {
Thread thread = new Thread(() -> onCommand(ctx));
thread.start();
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.MessageAuthor;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.permission.Role;
import org.javacord.api.entity.server.Server;
import org.javacord.api.entity.user.User;
import dev.salmonllama.fsbot.config.BotConfig;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
public class CommandContext {
private DiscordApi api;
private Message message;
private MessageAuthor author;
private TextChannel channel;
private Server server;
private Command usedCommand;
private String usedAlias;
private String[] args;
CommandContext(DiscordApi api, Message message, MessageAuthor author, TextChannel channel, Server server, String alias, Command cmd, String[] args) {
this.api = api;
this.message = message;
this.author = author;
this.channel = channel;
this.server = server;
this.usedCommand = cmd;
this.usedAlias = alias;
this.args = args;
}
public DiscordApi getApi() {
return api;
}
public Message getMessage() {
return message;
}
public MessageAuthor getAuthor() {
return author;
}
public TextChannel getChannel() {
return channel;
}
public Server getServer() {
return server;
}
public Command getUsedCommand() {
return usedCommand;
}
public String getUsedAlias() {
return usedAlias;
}
public String[] getArgs() {
return args;
}
public User getUser() {
if (author.asUser().isPresent()) {
return author.asUser().get();
} else {
// Log something to discord, I dunno
}
return null;
}
public Collection<Role> getUserRoles() {
User user = getUser();
return user.getRoles(getServer());
}
public boolean isUserOwner() {
return getUser().getIdAsString().equals(BotConfig.BOT_OWNER);
}
public CompletableFuture<Message> reply(String msg) {
return channel.sendMessage(msg);
}
public CompletableFuture<Message> reply(EmbedBuilder embed) {
return channel.sendMessage(embed);
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
public class CommandPermission {
private PermissionType type;
private String value;
public CommandPermission(PermissionType type) {
this.type = type;
}
public CommandPermission(PermissionType type, String value) {
this.type = type;
this.value = value;
}
public PermissionType getType() {
return type;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.MessageAuthor;
import org.javacord.api.entity.server.Server;
import java.util.Collection;
public class ContextBuilder {
private DiscordApi api;
private Message message;
private MessageAuthor author;
private TextChannel channel;
private Server server;
private Command usedCommand;
private String usedAlias;
private String[] args;
public ContextBuilder() {
}
public ContextBuilder setUsedCommand(Command commandUsed) {
this.usedCommand = commandUsed;
return this;
}
public ContextBuilder setUsedAlias(String alias) {
this.usedAlias = alias;
return this;
}
public ContextBuilder setArgs(String[] args) {
this.args = args;
return this;
}
ContextBuilder setMessage(Message message) {
this.message = message;
return this;
}
ContextBuilder setAuthor(MessageAuthor author) {
this.author = author;
return this;
}
ContextBuilder setChannel(TextChannel channel) {
this.channel = channel;
return this;
}
ContextBuilder setServer(Server server) {
this.server = server;
return this;
}
ContextBuilder setApi(DiscordApi api) {
this.api = api;
return this;
}
CommandContext build() {
return new CommandContext(api, message, author, channel, server, usedAlias, usedCommand, args);
}
}

View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
import dev.salmonllama.fsbot.commands.general.HelpCommand;
import dev.salmonllama.fsbot.commands.general.SpecificOutfitCommand;
import dev.salmonllama.fsbot.commands.staff.OutfitInfoCommand;
import dev.salmonllama.fsbot.commands.general.OutfitCommand;
import dev.salmonllama.fsbot.commands.staff.*;
import dev.salmonllama.fsbot.commands.developer.InviteCommand;
import dev.salmonllama.fsbot.commands.developer.CreateGalleryCommand;
import dev.salmonllama.fsbot.commands.general.ColorsCommand;
import dev.salmonllama.fsbot.commands.general.ColorCommand;
import dev.salmonllama.fsbot.commands.general.PingCommand;
import dev.salmonllama.fsbot.commands.developer.EvalCommand;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.MessageAuthor;
import org.javacord.api.entity.server.Server;
import org.javacord.api.event.message.MessageCreateEvent;
import org.javacord.api.listener.message.MessageCreateListener;
import dev.salmonllama.fsbot.commands.developer.TestCommand;
import java.util.Collection;
import java.util.HashMap;
/*
* Guthix is Fashionscape Bot's command repository and dispatcher
*/
public class Guthix implements MessageCreateListener {
private DiscordApi api;
private DatabaseUtilities db;
private Registry registry;
private PermissionManager manager;
public Guthix(DiscordApi api, DatabaseUtilities db) {
this.api = api;
api.addMessageCreateListener(this);
this.db = db;
manager = new PermissionManager(api);
registry = new Registry();
initCommands();
}
public void initCommands() {
// Developer Commands
addCommand(new TestCommand());
addCommand(new EvalCommand(db));
addCommand(new CreateGalleryCommand());
addCommand(new InviteCommand());
// Staff Commands
addCommand(new EchoCommand());
addCommand(new GetServersCommand());
addCommand(new AddColorCommand());
addCommand(new GetOutfitCommand());
addCommand(new RetagCommand(db));
addCommand(new RemoveOutfitCommand(db));
addCommand(new OutfitInfoCommand(db));
addCommand(new SetStatusCommand());
addCommand(new WelcomeMessageCommand());
// General Commands
addCommand(new PingCommand());
addCommand(new ColorCommand());
addCommand(new ColorsCommand());
addCommand(new OutfitCommand(db));
addCommand(new SpecificOutfitCommand(db));
addCommand(new HelpCommand(this));
}
public void addCommand(Command cmd) {
registry.addCommand(cmd);
// return cmd;
}
public Collection<Command> listCommands() {
return registry.listCommands();
}
public HashMap<String, Command> mapCommands() {
return registry.mapCommands();
}
@Override
public void onMessageCreate(MessageCreateEvent event) {
MessageAuthor author = event.getMessageAuthor();
if (manager.sourceIsValid(author)) {
} else {
return;
}
String content = event.getMessageContent().toLowerCase();
if (registry.startsWithPrefix(content)) {
} else {
return;
}
String cmdString = registry.commandString(content);
if (registry.isCommandAlias(cmdString)) {
} else {
return;
}
Message msg = event.getMessage();
TextChannel channel = event.getChannel();
Server server = event.getServer().orElse(null);
String[] cmdArgs = registry.getCmdArgs(content);
Command cmd = registry.findCommand(cmdString).orElse(null); // TODO: default command here
CommandContext ctx = new ContextBuilder().setApi(api)
.setServer(server)
.setAuthor(author)
.setChannel(channel)
.setMessage(msg)
.setArgs(cmdArgs)
.setUsedAlias(cmdString)
.setUsedCommand(cmd)
.build();
if (manager.hasPermission(cmd.permission(), ctx)) {
} else {
return;
}
cmd.invoke(ctx);
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.message.MessageAuthor;
public class PermissionManager {
private DiscordApi api;
public PermissionManager(DiscordApi api) {
this.api = api;
}
public boolean hasPermission(CommandPermission reqPerm, CommandContext ctx) {
PermissionType permtype = reqPerm.getType();
switch (permtype) {
case NONE:
return true;
case ROLE:
// If the author has the role, yes. Doesn't work in DM
return roleHandler(reqPerm.getValue(), ctx);
case OWNER:
// If the author is the owner, yes.
return ownerHandler(ctx);
}
return false;
}
private boolean roleHandler(String roleId, CommandContext ctx) {
return ctx.getUserRoles().stream().anyMatch(role -> role.getIdAsString().equals(roleId));
}
private boolean ownerHandler(CommandContext ctx) {
return ctx.isUserOwner();
}
boolean sourceIsValid(MessageAuthor author) {
return !author.isBotUser() && !author.isWebhook();
}
}

View File

@ -0,0 +1,12 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
public enum PermissionType {
ROLE, // User has a specific role inside the server
OWNER, // User is the bot owner
NONE // No requirement
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.guthix;
import dev.salmonllama.fsbot.config.BotConfig;
import java.util.*;
import java.util.function.Predicate;
class Registry {
private Collection<Command> commands;
private HashMap<String, Command> commandsMap;
Registry() {
commands = new ArrayList<>();
commandsMap = new HashMap<>();
}
Predicate<String> valueMatch(String input) { // TODO: Move to a helper class
return str -> str.equals(input);
}
Command addCommand(Command cmd) {
commands.add(cmd);
commandsMap.put(cmd.name(), cmd);
return cmd;
}
Collection<Command> listCommands() {
return commands;
}
HashMap<String, Command> mapCommands() {
return commandsMap;
}
boolean startsWithPrefix(String input) {
return input.startsWith(BotConfig.DEFAULT_PREFIX);
}
Collection<String> getCommandAliases() {
Collection<String> aliases = new ArrayList<>();
commands.forEach(cmd -> {
aliases.addAll(cmd.aliases());
});
return aliases;
}
Optional<Command> findCommand(String alias) {
for (Command cmd: commands) {
if (cmd.aliases().contains(alias)) {
return Optional.of(cmd);
}
}
return Optional.empty();
}
boolean isCommandAlias(String input) {
return getCommandAliases().stream().anyMatch(valueMatch(input));
}
String removePrefix(String input) {
int startPoint = BotConfig.DEFAULT_PREFIX.length();
return input.substring(startPoint);
}
List<String> splitArgs(String input) {
if (input.contains(" ")) {
input = removePrefix(input);
String[] splits = input.split(" ");
return new ArrayList<>(Arrays.asList(splits));
} else {
input = removePrefix(input);
return new ArrayList<>(Collections.singletonList(input));
}
}
String[] getCmdArgs(String input) {
List<String> splits = splitArgs(input);
splits.remove(0);
return splits.toArray(new String[0]);
}
String commandString(String input) {
// Cleans the string of the prefix and any args, returning only the command
return splitArgs(input).get(0);
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import com.vdurmont.emoji.EmojiParser;
import dev.salmonllama.fsbot.config.BotConfig;
import org.javacord.api.entity.message.MessageAttachment;
import org.javacord.api.event.message.MessageCreateEvent;
import org.javacord.api.listener.message.MessageCreateListener;
public class AchievementListener implements MessageCreateListener {
public void onMessageCreate(MessageCreateEvent event) {
if (!event.getChannel().getIdAsString().equals(BotConfig.ACHIEVEMENT_CHANNEL)) {
return;
}
if (event.getMessage().getAttachments().stream().noneMatch(MessageAttachment::isImage)) {
return;
}
event.getMessage().addReaction(EmojiParser.parseToUnicode(":tada:"));
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.net.Connection;
import com.rethinkdb.net.Cursor;
import com.vdurmont.emoji.EmojiParser;
import okhttp3.*;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.MessageAttachment;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.event.message.MessageCreateEvent;
import org.javacord.api.listener.message.MessageCreateListener;
import org.json.JSONObject;
import dev.salmonllama.fsbot.config.BotConfig;
import java.awt.*;
import java.util.List;
public class ImageListener implements MessageCreateListener {
final RethinkDB r;
final Connection conn;
public ImageListener(RethinkDB r, Connection conn) {
this.r = r;
this.conn = conn;
}
@Override
public void onMessageCreate(MessageCreateEvent event) {
event.getMessage().getUserAuthor().ifPresent(author -> {
if (author.isBot()) {
return;
}
});
Message message = event.getMessage();
String channel = event.getChannel().getIdAsString();
String submitter = event.getMessage().getAuthor().getIdAsString();
if (message.getAttachments().stream().noneMatch(MessageAttachment::isImage)) {
return;
}
// If the message contains an image, check if the channel is being listened to for image storage
String dbTable = null;
if(r.db("fsbot").table("channels").g("cId").contains(channel).run(conn)) {
Cursor cursor = r.db("fsbot")
.table("channels")
.filter(row -> row.getField("cId").eq(channel))
.getField("tag")
.run(conn);
List tags = cursor.toList();
for (Object tag : tags) {
dbTable = tag.toString();
}
}
else {
return;
}
List<MessageAttachment> attachments = message.getAttachments();
for (MessageAttachment attachment : attachments) {
String discordLink = attachment.getUrl().toString();
String imgurLink = null;
// Upload the image to imgur
try {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(
mediaType,
String.format("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n%s\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", discordLink));
Request request = new Request.Builder()
.url("https://api.imgur.com/3/image")
.method("POST", body)
.header("Authorization", BotConfig.IMGUR_ID)
.header("Authorization", BotConfig.IMGUR_BEARER)
.build();
Response response = client.newCall(request).execute();
if (response.body() == null) {
event.getChannel().sendMessage("Something went wrong!");
return;
}
String jsonData = response.body().string();
imgurLink = new JSONObject(jsonData).getJSONObject("data").getString("link");
if (imgurLink == null) {
event.getChannel().sendMessage("Something went wrong!");
return;
}
}
catch (Exception e) {
e.printStackTrace();
}
r.db("fsbot").table("outfits").insert(
r.hashMap("link", imgurLink)
.with("submitter", submitter)
.with("tag", dbTable)
).run(conn);
final String finalLink = imgurLink;
Cursor imgId = r.db("fsbot")
.table("outfits")
.filter(row -> row.getField("link").eq(finalLink))
.getField("id")
.run(conn);
String embedId = null;
List imgIds = imgId.toList();
for (Object id : imgIds) {
embedId = id.toString();
}
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Added an entry of tag " + dbTable)
.setColor(Color.GREEN)
.setThumbnail(imgurLink)
.setAuthor("Placeholder")
.setFooter(embedId);
event.getApi().getUserById(submitter).thenAccept(user -> embed.setAuthor(user.getDiscriminatedName()));
event.getApi().getChannelById(BotConfig.OUTFIT_LOG).ifPresent(chnl -> {
chnl.asTextChannel().ifPresent(txtchnl -> {
txtchnl.sendMessage(embed).join();
});
});
message.addReaction(EmojiParser.parseToUnicode(":heartpulse:"));
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import dev.salmonllama.fsbot.utilities.database.ServerConfUtility;
import org.javacord.api.DiscordApi;
import org.javacord.api.event.server.member.ServerMemberJoinEvent;
import org.javacord.api.listener.server.member.ServerMemberJoinListener;
public class NewMemberListener implements ServerMemberJoinListener {
private DiscordApi api;
public NewMemberListener(DiscordApi api) {
this.api = api;
}
public void onServerMemberJoin(ServerMemberJoinEvent event) {
if (!event.getServer().getIdAsString().equals("340511685024546816")) return;
ServerConfUtility conf = new ServerConfUtility(event.getServer().getIdAsString());
String welcomeMsg = conf.getWelcomeMsg();
String welcomeChannel = conf.getWelcomeChannel();
String logMessage = String.format(welcomeMsg, event.getUser().getMentionTag());
api.getChannelById(welcomeChannel).ifPresent(chnl -> {
chnl.asServerTextChannel().ifPresent(channel -> {
channel.sendMessage(logMessage);
});
});
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import com.vdurmont.emoji.EmojiParser;
import dev.salmonllama.fsbot.config.BotConfig;
import org.javacord.api.entity.channel.Channel;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.user.User;
import org.javacord.api.event.message.reaction.ReactionAddEvent;
import org.javacord.api.listener.message.reaction.ReactionAddListener;
import dev.salmonllama.fsbot.utilities.Outfit;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import dev.salmonllama.fsbot.utilities.exceptions.DiscordError;
import dev.salmonllama.fsbot.utilities.exceptions.OutfitNotFoundException;
import java.awt.*;
public class ReactionDeleteConfirmationListener implements ReactionAddListener {
private final User author;
private final Message message;
private final Outfit outfit;
private final DatabaseUtilities db;
public ReactionDeleteConfirmationListener(User author, Message message, Outfit outfit, DatabaseUtilities db) {
this.author = author;
this.message = message;
this.outfit = outfit;
this.db = db;
}
public void onReactionAdd(ReactionAddEvent event) {
if (!event.getUser().getIdAsString().equals(author.getIdAsString())) {
return;
}
if (event.getEmoji().equalsEmoji(EmojiParser.parseToUnicode(":white_check_mark:"))) {
// Delete the message and send confirmation
String completed = "";
try {
completed = db.removeFromDatabase(outfit.getId());
}
catch(OutfitNotFoundException e) {
event.getChannel().sendMessage(new DiscordError(e.getMessage()).get().addField("Info:", "This message was sent by a reaction listener. **YOU SHOULD NOT BE SEEING THIS!**"));
}
if (Integer.parseInt(completed) > 0) {
// Successful deletion
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Success!")
.setColor(Color.GREEN)
.setDescription("Outfit deleted successfully");
message.removeAllReactions();
message.edit(embed);
event.getApi().getChannelById(BotConfig.OUTFIT_LOG).map(Channel::asServerTextChannel).orElseThrow(AssertionError::new).map(channel ->
channel.sendMessage(outfit.generateInfo().setTitle(String.format("Outfit Deleted by %s", event.getUser().getDiscriminatedName())).setColor(Color.RED))
);
}
else {
// Deletion failure
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Error!")
.setColor(Color.RED)
.setDescription("An error occurred and the outfit was not deleted. Did you use the correct ID?")
.setFooter(String.format("Bother %s about making these stupid things more useful.", event.getApi().getOwner().thenAccept(User::getDiscriminatedName)));
message.removeAllReactions();
message.edit(embed);
}
}
else if (event.getEmoji().equalsEmoji(EmojiParser.parseToUnicode(":octagonal_sign:"))) {
// Cancel deletion and do nothing
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Oops!")
.setColor(Color.GREEN)
.setDescription("Deletion cancelled. No changes were made.");
message.removeAllReactions();
message.edit(embed);
}
event.getApi().removeListener(this);
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import com.vdurmont.emoji.EmojiParser;
import dev.salmonllama.fsbot.config.BotConfig;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.entity.user.User;
import org.javacord.api.event.message.reaction.ReactionAddEvent;
import org.javacord.api.listener.message.reaction.ReactionAddListener;
import dev.salmonllama.fsbot.utilities.Outfit;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import dev.salmonllama.fsbot.utilities.exceptions.DiscordError;
import dev.salmonllama.fsbot.utilities.exceptions.OutfitNotFoundException;
import java.awt.*;
public class ReactionRetagConfirmationListener implements ReactionAddListener {
private User author;
private final Message message;
private final Outfit outfit;
private final DatabaseUtilities db;
private final String oldTag;
private final String newTag;
public ReactionRetagConfirmationListener(User author, Message message, Outfit outfit, DatabaseUtilities db, String oldTag, String newTag) {
this.author = author;
this.message = message;
this.outfit = outfit;
this.db = db;
this.oldTag = oldTag;
this.newTag = newTag;
}
public void onReactionAdd(ReactionAddEvent event) {
if (!event.getUser().getIdAsString().equals(this.author.getIdAsString())) {
return;
}
if (event.getEmoji().equalsEmoji(EmojiParser.parseToUnicode(":white_check_mark:"))) {
// retag the image, send a confirmation, or an error if it failed for whatever reason.
String result = "";
try {
result = db.changeOutfitTag(outfit.getId(), this.newTag);
}
catch (OutfitNotFoundException e) {
message.delete();
event.getChannel().sendMessage(new DiscordError(e.getMessage()).get().addField("Info", "This message was generated by a listener thread. YOU SHOULD NOT BE SEEING THIS ERROR!"));
}
message.removeAllReactions();
if (Integer.parseInt(result) > 0) {
// success, send confirmation
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Success")
.setColor(Color.GREEN)
.setDescription("Outfit retagged successfully")
.setFooter("Check the log for more information");
message.edit(embed);
// log message with new tag and old tag
event.getApi().getChannelById(BotConfig.OUTFIT_LOG).ifPresent(channel -> {
channel.asServerTextChannel().ifPresent(chnl -> {
chnl.sendMessage(outfit.tagChangeEmbed(this.author.getDiscriminatedName(), this.oldTag, this.newTag));
});
});
}
else {
// failure, something went wrong
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Error!")
.setColor(Color.RED)
.setFooter("Big oopsie");
event.getApi().getOwner().thenAcceptAsync(user -> {
embed.setDescription(String.format("Something has gone horribly wrong, contact %s", user.getDiscriminatedName()));
});
message.edit(embed);
}
}
else if (event.getEmoji().equalsEmoji(EmojiParser.parseToUnicode(":octagonal_sign:"))) {
// Cancel the image retagging.
message.removeAllReactions();
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Operation cancelled!")
.setDescription("No changes made.")
.setColor(Color.GREEN)
.setFooter("boop");
message.edit(embed);
}
event.getApi().removeListener(this);
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.TextChannel;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.message.MessageAuthor;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.event.message.MessageCreateEvent;
import org.javacord.api.listener.message.MessageCreateListener;
import dev.salmonllama.fsbot.config.BotConfig;
import dev.salmonllama.fsbot.utilities.MessageUtilities;
import java.awt.*;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
public class ReportListener implements MessageCreateListener {
public void onMessageCreate(MessageCreateEvent event) {
DiscordApi api = event.getApi();
TextChannel channel = event.getChannel();
if (!channel.getIdAsString().equals(BotConfig.REPORT_CHANNEL)) {
return;
}
Message message = event.getMessage();
MessageAuthor author = message.getAuthor();
if (author.isBotUser()) {
return;
}
String content = message.getContent();
message.delete().join();
EmbedBuilder embed = new EmbedBuilder()
.setTitle("User Report")
.setDescription(content)
.setColor(Color.GREEN)
.setFooter("From: " + author.getDiscriminatedName());
Optional<TextChannel> logChannel = api.getTextChannelById(BotConfig.REPORT_LOG);
if (logChannel.isPresent()) {
logChannel.get().sendMessage(embed);
}
else {
channel.sendMessage("Could not find proper log channel, please contact a staff member.")
.thenAccept(MessageUtilities.deleteAfter(30, TimeUnit.SECONDS));
}
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import dev.salmonllama.fsbot.utilities.database.DatabaseUtilities;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import org.javacord.api.event.server.ServerJoinEvent;
import org.javacord.api.listener.server.ServerJoinListener;
import java.awt.*;
public class ServerJoined implements ServerJoinListener {
private DiscordApi api;
private DatabaseUtilities db;
public ServerJoined(DiscordApi api, DatabaseUtilities db) {
this.api = api;
this.db = db;
}
public void onServerJoin(ServerJoinEvent event) {
db.newServerProcess(event.getServer());
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Server joined")
.setColor(Color.GREEN)
.addInlineField("Server name:", event.getServer().getName())
.addInlineField("Server Id:", event.getServer().getIdAsString());
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.listeners;
import com.vdurmont.emoji.EmojiParser;
import dev.salmonllama.fsbot.config.BotConfig;
import org.javacord.api.event.message.MessageCreateEvent;
import org.javacord.api.listener.message.MessageCreateListener;
public class ThumbsListener implements MessageCreateListener {
public void onMessageCreate(MessageCreateEvent event) {
if (event.getChannel().getIdAsString().equals(BotConfig.ANNOUNCEMENT_CHANNEL)) {
// Announcements
event.getMessage().addReaction(EmojiParser.parseToUnicode(":thumbsup:"));
event.getMessage().addReaction(EmojiParser.parseToUnicode(":thumbsdown:"));
}
else if (event.getChannel().getIdAsString().equals(BotConfig.NEWS_CHANNEL)) {
// Newsfeed
event.getMessage().addReaction(EmojiParser.parseToUnicode(":thumbsup:"));
event.getMessage().addReaction(EmojiParser.parseToUnicode(":thumbsdown:"));
}
else if (event.getChannel().getIdAsString().equals(BotConfig.VOTE_CHANNEL)) {
// Votes
event.getMessage().addReaction(EmojiParser.parseToUnicode(":thumbsup:"));
event.getMessage().addReaction(EmojiParser.parseToUnicode(":thumbsdown:"));
}
}
}

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities;
public class Checks {
public static boolean checkTag() {
return true;
}
public static boolean checkId() {
return true;
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import dev.salmonllama.fsbot.utilities.database.RoleColourUtility;
import java.util.List;
import java.awt.Color;
public class ColorRole {
public String id;
public String name;
public ColorRole(String id, String name) {
this.id = id;
this.name = name;
}
public static EmbedBuilder rolesListEmbed() {
List<ColorRole> roles = RoleColourUtility.getAllRoles();
EmbedBuilder embed = new EmbedBuilder()
.setTitle("Available ColorRoles")
.setColor(Color.GREEN)
.setFooter("Showing " + roles.size() + " roles");
StringBuilder builder = new StringBuilder();
roles.forEach(role -> {
builder.append(role.name).append("\n");
});
embed.addField("Roles:", builder.toString());
return embed;
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities;
public class Constants {
public static final String BOT_FOLDER = System.getenv("HOME").concat("/.fsbot/");
public static final String CONFIG_NAME = "bot.config";
public static final String DB_NAME = "fsbot";
public static final String OUTFIT_TABLE = "outfits";
public static final String SCONF_TABLE = "server_conf";
}

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities;
import org.javacord.api.entity.message.Message;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
public class MessageUtilities {
public static Consumer<Message> deleteAfter(long delay, TimeUnit timeUnit) {
return msg -> msg.getApi().getThreadPool().getScheduler().schedule((Runnable) msg::delete, delay, timeUnit);
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import java.awt.*;
public class Outfit {
private String id;
private String tag;
private String submitter;
private String link;
private DiscordApi api;
public Outfit(String id, String tag, String submitter, String link) {
this.id = id;
this.tag = tag;
this.submitter = submitter;
this.link = link;
}
public void setId(String id) { this.id = id; }
public String getId() { return this.id; }
public String getTag() { return this.tag; }
// public void setTag(String tag) { this.tag = tag; }
// public String getTag() { return this.tag; }
// public void setSubmitter(String submitter) { this.submitter = submitter; }
// public String getSubmitter() { return this.submitter; }
// public void setLink(String link) { this.link = link; }
// public String getLink() { return this.link; }
public EmbedBuilder generateEmbed() {
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle(submitter + " | " + tag)
.setImage(this.link)
.setFooter(this.id);
}
public EmbedBuilder generateInfo() {
return new EmbedBuilder()
.setColor(Color.GREEN)
.setTitle("Outfit Information")
.setThumbnail(this.link)
.addField("Submitter:", this.submitter, true)
.addField("Tag:", this.tag, true)
.addField("Id:", this.id)
.addField("Link:", this.link);
}
public EmbedBuilder tagChangeEmbed(String changer, String oldTag, String newTag) {
return new EmbedBuilder()
.setColor(Color.YELLOW)
.setTitle(String.format("Tag changed by %s", changer))
.setThumbnail(this.link)
.addField("Old Tag:", oldTag)
.addField("New Tag:", newTag)
.setFooter(this.id);
}
}

View File

@ -0,0 +1,246 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.database;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.gen.ast.Table;
import com.rethinkdb.net.Connection;
import com.rethinkdb.net.Cursor;
import org.javacord.api.DiscordApi;
import dev.salmonllama.fsbot.utilities.Outfit;
import org.javacord.api.entity.server.Server;
import dev.salmonllama.fsbot.utilities.exceptions.OutfitNotFoundException;
import java.util.*;
public class DatabaseUtilities {
private final RethinkDB r;
private final Connection conn;
private final DiscordApi api;
public DatabaseUtilities(RethinkDB r, Connection conn, DiscordApi api) {
this.r = r;
this.conn = conn;
this.api = api;
}
private Table getTable(String table) {
if (this.r.db("fsbot").tableList().contains(table).run(this.conn)) {
return this.r.db("fsbot").table(table);
}
else {
return null;
}
}
private boolean validateId(String id) {
return r.db("fsbot").table("outfits").getField("id").contains(id).run(this.conn);
}
public boolean tagExists(String tag) {
return r.db("fsbot").table("outfits").getField("tag").distinct().contains(tag).run(this.conn);
}
public int countTags() {
return this.r.db("fsbot").table("outfits").getField("tag").distinct().count().run(this.conn);
}
public ArrayList<String> getTags() {
return r.db("fsbot").table("outfits").getField("tag").distinct().run(this.conn);
}
public Outfit getOutfitFromId(String id) throws OutfitNotFoundException {
if (!this.validateId(id)) throw new OutfitNotFoundException();
HashMap sample = this.r.db("fsbot").table("outfits")
.get(id)
.run(this.conn);
String tag = sample.get("tag").toString();
String link = sample.get("link").toString();
String submitterId = sample.get("submitter").toString();
String submitterName = api.getUserById(submitterId).join().getDiscriminatedName();
return new Outfit(id, tag, submitterName, link);
}
public String removeFromDatabase(String id) throws OutfitNotFoundException {
if (!this.validateId(id)) throw new OutfitNotFoundException();
// Remove outfit return deletion status. 0 = failed, >= 1 = success
HashMap deletion = r.db("fsbot").table("outfits").get(id).delete().run(conn);
return deletion.get("deleted").toString();
}
public Outfit randomOutfit() {
HashMap sample = this.r.db("fsbot").table("outfits")
.sample(1).nth(0)
.run(this.conn);
String id = sample.get("id").toString();
String tag = sample.get("tag").toString();
String link = sample.get("link").toString();
String submitterId = sample.get("submitter").toString();
String submitterName = api.getUserById(submitterId).join().getDiscriminatedName();
return new Outfit(id, tag, submitterName, link);
}
public Outfit randomTaggedOutfit(String targetTag) {
HashMap sample = r.db("fsbot").table("outfits")
.filter(row -> row.getField("tag").eq(targetTag))
.sample(1).nth(0)
.run(conn);
String id = String.valueOf(sample.get("id"));
String tag = String.valueOf(sample.get("tag"));
String link = String.valueOf(sample.get("link"));
String submitterId = String.valueOf(sample.get("submitter"));
String submitterName = api.getUserById(submitterId).join().getDiscriminatedName(); // Try a thenAccept with a thenApply
return new Outfit(id, tag, submitterName, link);
}
public String changeOutfitTag(String outfitId, String newTag) throws OutfitNotFoundException {
if (!this.validateId(outfitId)) throw new OutfitNotFoundException();
HashMap replacement = this.r.db("fsbot").table("outfits").get(outfitId).update(r.hashMap("tag", newTag)).run(this.conn);
return replacement.get("replaced").toString();
}
public Outfit getOutfitBySubmitter(String userId) {
HashMap sample = r.db("fsbot").table("outfits")
.filter(row -> row.getField("submitter").eq(userId))
.sample(1).nth(0)
.run(conn);
String id = String.valueOf(sample.get("id"));
String tag = String.valueOf(sample.get("tag"));
String link = String.valueOf(sample.get("link"));
String submitterId = String.valueOf(sample.get("submitter"));
String submitterName = api.getUserById(submitterId).join().getDiscriminatedName();
return new Outfit(id, tag, submitterName, link);
}
public long getSubmitterCount(String submitter) {
return r.db("fsbot").table("outfits")
.filter(
row -> row.getField("submitter").eq(submitter)
)
.count()
.run(conn);
}
public List<String> getSubmitterIds(String submitter) {
List<String> ids = new ArrayList<>();
Cursor<String> cursor = r.db("fsbot").table("outfits")
.filter(
row -> row.getField("submitter").eq(submitter)
)
.getField("id")
.run(conn);
cursor.forEach(ids::add);
return ids;
}
public void updateSubmitter(String submitter, String newSubmitter) {
// Add feature to return update-error?
r.db("fsbot").table("outfits")
.filter(r.hashMap("submitter", submitter))
.update(r.hashMap("submitter", newSubmitter))
.run(conn);
}
public void newServerProcess(Server server) {
if (this.r.db("fsbot").table("serverConf").contains(server.getIdAsString()).run(this.conn)) {
return;
}
String serverName = server.getName();
String serverId = server.getIdAsString();
String logChannel = "null";
String giveawayChannel = "null";
String welcomeChannel = "null";
String defaultWelcome = "welcome to the server";
this.r.db("fsbot").table("serverConf").insert(
this.r.hashMap("id", serverId)
.with("name", serverName)
.with("logChannel", logChannel)
.with("giveawayChannel", giveawayChannel)
.with("welcomeMsg", defaultWelcome)
.with("welcomeChannel", welcomeChannel)
.with("prefix", "~")
).run(this.conn);
}
public void tableSetup() { // TODO: Fix this -- invert conditionals, just create the tables. -> if *not* exist then create
// Check for database existence, if not, create
if (r.dbList().contains("fsbot").run(conn)) {
// System.out.println("database 'fsbot' already exists.");
}
else {
r.dbCreate("fsbot").run(conn);
System.out.println("database fsbot did not exist, and has been created");
}
// Check for channels table existence, if not, create
if (r.db("fsbot").tableList().contains("channels").run(conn)) {
// System.out.println("table channels already exists");
}
else {
r.db("fsbot").tableCreate("channels").run(conn);
System.out.println("table channels did not exist, and has been created.");
}
// Check for serverconf table existence, if not, create
if (r.db("fsbot").tableList().contains("serverConf").run(conn)) {
// System.out.println("table serverConf already exists");
}
else {
r.db("fsbot").tableCreate("serverConf").run(conn);
System.out.println("table serverConf did not exist, and has been created");
}
// Check for permissions table existene, if not, create
if (r.db("fsbot").tableList().contains("permissions").run(conn)) {
// System.out.println("table permissions already exists");
}
else {
r.db("fsbot").tableCreate("permissions").run(conn);
System.out.println("table permissions did not exist and has been created");
}
// Check for outfits table existence, if not, create
if (r.db("fsbot").tableList().contains("outfits").run(conn)) {
// System.out.println("table outfits already exists");
}
else {
r.db("fsbot").tableCreate("outfits").run(conn);
System.out.println("table outfits did not exist and has been created");
}
// Check for colourRoles table existence, if not, create
if (r.db("fsbot").tableList().contains("colourRoles").run(conn)) {
// System.out.println("table colourRoles already exists");
}
else {
r.db("fsbot").tableCreate("colourRoles").run(conn);
System.out.println("table colourRoles did not exist and has been created");
}
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.database;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.net.Connection;
import com.rethinkdb.net.Cursor;
import dev.salmonllama.fsbot.utilities.ColorRole;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class RoleColourUtility {
private static RethinkDB r = RethinkDB.r;
private static Connection conn = r.connection().hostname("localhost").port(28015).connect();
public static void addColourRole(String colourName, String roleId) {
r.db("fsbot").table("colourRoles").insert(
r.hashMap("id", roleId)
.with("name", colourName)).run(conn);
}
public static void deleteColourRole() {
}
public static String getColour(String colourName) {
String roleId = null;
Cursor cursor = r.db("fsbot").table("colourRoles")
.filter(row -> row.getField("name").eq(colourName))
.getField("id")
.run(conn);
List roleIds = cursor.toList();
for (Object id : roleIds) {
roleId = id.toString();
}
return roleId;
}
public static List<ColorRole> getAllRoles() {
List<ColorRole> allRoles = new ArrayList<>();
Cursor cursor = r.db("fsbot").table("colourRoles")
.run(conn);
while (cursor.hasNext()) {
HashMap role = (HashMap) cursor.next();
String id = String.valueOf(role.get("id"));
String name = String.valueOf(role.get("name"));
allRoles.add(new ColorRole(id, name));
}
return allRoles;
}
public static String getAllRoleInfo() {
return r.db("fsbot").table("colourRoles").run(conn);
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.database;
import com.rethinkdb.RethinkDB;
import com.rethinkdb.net.Connection;
import com.rethinkdb.net.Cursor;
import java.util.List;
public class ServerConfUtility {
private static final RethinkDB r = RethinkDB.r;
private static final Connection conn = r.connection().hostname("localhost").port(28015).connect();
private static String serverId;
public ServerConfUtility(String sId) {
serverId = sId;
}
// TODO: Turn server into method args, not class field.
public String getWelcomeMsg() {
String welcomeMsg = null;
Cursor welcomes = r.db("fsbot").table("serverConf")
.filter(row -> row.getField("id").eq(serverId))
.getField("welcomeMsg")
.run(conn);
List welcomeMsgs = welcomes.toList();
for (Object msg : welcomeMsgs) {
welcomeMsg = msg.toString();
}
return welcomeMsg;
}
public void setWelcomeMsg(String msg) {
r.db("fsbot").table("serverConf")
.get(serverId)
.update(r.hashMap("welcomeMsg", msg))
.run(conn);
}
public String getWelcomeChannel() {
String welcomeChannel = null;
Cursor channels = r.db("fsbot").table("serverConf")
.filter(row -> row.getField("id").eq(serverId))
.getField("welcomeChannel")
.run(conn);
List welcomeChannels = channels.toList();
for (Object chnl : welcomeChannels) {
welcomeChannel = chnl.toString();
}
return welcomeChannel;
}
public void setWelcomeChannel(String id) {
r.db("fsbot").table("serverConf")
.get(serverId)
.update(r.hashMap("welcomeChannel", id))
.run(conn);
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.exceptions;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import java.awt.*;
public class DiscordError {
String title = "Error!";
String message;
String footer = "Contact Salmonllama#5727 if you think this is wrong";
public DiscordError(String message) {
this.message = message;
}
public EmbedBuilder get() {
return new EmbedBuilder().setTitle(this.title).setDescription(this.message).setColor(Color.RED).setFooter(this.footer);
}
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.exceptions;
import java.awt.*;
public class DiscordException {
private Color color;
private String message;
private String footer;
private String title;
DiscordException(String title, String message, String footer, Color color) {
this.title = title;
this.message = message;
this.footer = footer;
this.color = color;
}
}

View File

@ -0,0 +1,9 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.exceptions;
public class DiscordWarning {
}

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.exceptions;
public class OutfitNotFoundException extends Exception {
@Override
public String getMessage() {
return "An outfit with that ID was not found";
}
}

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.exceptions;
public class TagNotFoundException extends Exception {
@Override
public String getMessage() {
return "That tag was not found, check your spelling and try again.";
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2020. Aleksei Gryczewski
* All rights reserved.
*/
package dev.salmonllama.fsbot.utilities.warnings;
import org.javacord.api.entity.message.embed.EmbedBuilder;
import java.awt.*;
public class Warning {
private static Color embedColor = Color.YELLOW;
private static String embedFooter = "Bother Crablet#9999 to add usages to these things";
private String embedWarning;
public Warning(String warnMessage) {
this.embedWarning = warnMessage;
}
public EmbedBuilder sendWarning() {
EmbedBuilder warning = new EmbedBuilder()
.setColor(Color.YELLOW)
.setFooter(embedFooter)
.addField("WARNING", embedWarning);
return warning;
}
}