From fb5e9494ff67e9d9ce4263386e7e0005be94fd9b Mon Sep 17 00:00:00 2001 From: Alyx Batte Date: Tue, 9 Dec 2025 19:13:31 -0500 Subject: [PATCH] feat: wip fml --- .github/workflows/gradle.yml | 28 --- build.gradle | 16 +- src/main/java/dev/salmonllama/fsbot/Main.java | 27 +-- .../developer/CreateGalleryCommand.java | 1 - .../fsbot/commands/general/HelpCommand.java | 1 - .../fsbot/commands/staff/EditMetaCommand.java | 1 - .../commands/staff/RemoveOutfitCommand.java | 1 - .../commands/staff/RestoreOutfitCommand.java | 1 - .../fsbot/commands/staff/RetagCommand.java | 1 - .../commands/staff/WelcomeMessageCommand.java | 109 ----------- .../salmonllama/fsbot/config/BotConfig.java | 96 ---------- .../salmonllama/fsbot/config/EnvManager.java | 16 ++ .../fsbot/config/SecretManager.java | 33 ---- .../fsbot/database/DatabaseProvider.java | 1 - .../dev/salmonllama/fsbot/database/FSDB.java | 1 - .../fsbot/endpoints/ApiConnection.java | 143 ++++++++++++++ .../fashionscape/FashionscapeApi.java | 29 +++ .../fashionscape/controllers/GalleryApi.java | 44 +++++ .../GuildConfigApi.java | 3 +- .../fashionscape/controllers/ImageApi.java | 4 + .../fashionscape/models/Gallery.java | 24 +++ .../fashionscape/models/GuildConfig.java | 175 ++++++++++++++++++ .../endpoints/fashionscape/models/Image.java | 4 + .../endpoints/imgur/ImgurAPIConnection.java | 7 +- .../fsbot/guthix/CommandContext.java | 100 +++++----- .../dev/salmonllama/fsbot/guthix/Guthix.java | 47 ++--- .../fsbot/guthix/PermissionManager.java | 18 +- .../salmonllama/fsbot/guthix/Registry.java | 2 - .../interactions/ServerConfigInteraction.java | 134 ++++++++++++++ .../reporting/ReportModuleInteraction.java | 33 ++++ .../internal/guildcfg/GuildConfigHelper.java | 97 ++++++++++ .../fsbot/listeners/AchievementListener.java | 1 - .../fsbot/listeners/ImageListener.java | 42 +---- .../fsbot/listeners/NewMemberListener.java | 1 - .../fsbot/listeners/ReportListener.java | 1 - .../fsbot/listeners/ThumbsListener.java | 1 - .../fsbot/services/MemberRoleService.java | 2 - .../fsbot/utilities/DiscordUtilities.java | 1 - 38 files changed, 778 insertions(+), 468 deletions(-) delete mode 100644 .github/workflows/gradle.yml delete mode 100644 src/main/java/dev/salmonllama/fsbot/commands/staff/WelcomeMessageCommand.java delete mode 100644 src/main/java/dev/salmonllama/fsbot/config/BotConfig.java create mode 100644 src/main/java/dev/salmonllama/fsbot/config/EnvManager.java delete mode 100644 src/main/java/dev/salmonllama/fsbot/config/SecretManager.java create mode 100644 src/main/java/dev/salmonllama/fsbot/endpoints/ApiConnection.java create mode 100644 src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/FashionscapeApi.java create mode 100644 src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/GalleryApi.java rename src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/{guildconfig => controllers}/GuildConfigApi.java (93%) create mode 100644 src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/ImageApi.java create mode 100644 src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Gallery.java create mode 100644 src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/GuildConfig.java create mode 100644 src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Image.java create mode 100644 src/main/java/dev/salmonllama/fsbot/interactions/ServerConfigInteraction.java create mode 100644 src/main/java/dev/salmonllama/fsbot/interactions/reporting/ReportModuleInteraction.java create mode 100644 src/main/java/dev/salmonllama/fsbot/internal/guildcfg/GuildConfigHelper.java diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml deleted file mode 100644 index d36ccfb..0000000 --- a/.github/workflows/gradle.yml +++ /dev/null @@ -1,28 +0,0 @@ -# This workflow will build a Java project with Gradle -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle - -name: Java CI with Gradle - -on: - push: - branches: - - '**' - pull_request: - branches: - - '**' - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.16 - uses: actions/setup-java@v1 - with: - java-version: 1.16 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew build diff --git a/build.gradle b/build.gradle index e60cdf3..331d90c 100644 --- a/build.gradle +++ b/build.gradle @@ -26,24 +26,18 @@ repositories { } dependencies { - implementation("net.dv8tion:JDA:5.0.1") + implementation("net.dv8tion:JDA:6.0.0") implementation 'org.xerial:sqlite-jdbc:3.41.2.2' - implementation 'com.github.Kaaz:ConfigurationBuilder:0.4' - implementation 'org.javacord:javacord:3.8.0' implementation 'com.vdurmont:emoji-java:5.1.1' - implementation 'com.squareup.okhttp3:okhttp:4.9.1' - implementation 'ch.qos.logback:logback-classic:1.2.5' - implementation 'com.google.code.gson:gson:2.8.8' + implementation 'com.squareup.okhttp3:okhttp:4.9.2' + implementation 'ch.qos.logback:logback-classic:1.5.13' + implementation 'com.google.code.gson:gson:2.8.9' implementation 'org.springframework.boot:spring-boot-starter-actuator:2.5.4' implementation 'org.springframework.boot:spring-boot-starter-web:2.5.4' testImplementation 'org.springframework.boot:spring-boot-starter-test:2.5.4' - implementation platform('com.google.cloud:libraries-bom:23.0.0') - implementation 'com.google.cloud:google-cloud-secretmanager' - - - testImplementation group: 'junit', name: 'junit', version: '4.12' + testImplementation group: 'junit', name: 'junit', version: '4.13.1' } mainClassName = 'dev.salmonllama.fsbot.Main' diff --git a/src/main/java/dev/salmonllama/fsbot/Main.java b/src/main/java/dev/salmonllama/fsbot/Main.java index 65ccd59..34670d4 100644 --- a/src/main/java/dev/salmonllama/fsbot/Main.java +++ b/src/main/java/dev/salmonllama/fsbot/Main.java @@ -4,18 +4,14 @@ package dev.salmonllama.fsbot; -import dev.salmonllama.fsbot.config.BotConfig; -// import dev.salmonllama.fsbot.config.SecretManager; -import dev.salmonllama.fsbot.database.FSDB; +import dev.salmonllama.fsbot.config.EnvManager; import dev.salmonllama.fsbot.guthix.Guthix; +import dev.salmonllama.fsbot.interactions.ServerConfigInteraction; import dev.salmonllama.fsbot.listeners.*; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.requests.GatewayIntent; -import org.javacord.api.DiscordApiBuilder; -import dev.salmonllama.fsbot.utilities.Constants; -import org.javacord.api.entity.intent.Intent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; @@ -30,26 +26,15 @@ public class Main { private final static Logger logger = LoggerFactory.getLogger(Main.class); public static void main(String[] args) { - BotConfig.initConfig(Constants.BOT_FOLDER, false); - - FSDB.init(); - - String token; - if (System.getenv("ENVIRONMENT") != null) - { - token = BotConfig.BOT_TOKEN_PROD; - // token = SecretManager.DISCORD_TOKEN_PROD.getPlainText(); - } - else - { - token = BotConfig.BOT_TOKEN_DEV; - // token = SecretManager.DISCORD_TOKEN.getPlainText(); - } + String token = EnvManager.BOT_TOKEN; JDA jda = JDABuilder.createLight(token, EnumSet.noneOf(GatewayIntent.class)) .addEventListeners(new ImageListener()) + .addEventListeners(new ServerConfigInteraction()) .build(); + jda.upsertCommand(ServerConfigInteraction.ServerConfigCommand()).queue(); + new DiscordApiBuilder().addIntents(Intent.MESSAGE_CONTENT).setToken(token).login().thenAccept(api -> { @SuppressWarnings("unused") diff --git a/src/main/java/dev/salmonllama/fsbot/commands/developer/CreateGalleryCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/developer/CreateGalleryCommand.java index 21c8883..49ef60f 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/developer/CreateGalleryCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/developer/CreateGalleryCommand.java @@ -5,7 +5,6 @@ package dev.salmonllama.fsbot.commands.developer; import com.vdurmont.emoji.EmojiParser; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.controllers.GalleryController; import dev.salmonllama.fsbot.database.models.GalleryChannel; import dev.salmonllama.fsbot.guthix.*; diff --git a/src/main/java/dev/salmonllama/fsbot/commands/general/HelpCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/general/HelpCommand.java index ebac328..f8a1bc3 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/general/HelpCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/general/HelpCommand.java @@ -4,7 +4,6 @@ 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; diff --git a/src/main/java/dev/salmonllama/fsbot/commands/staff/EditMetaCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/staff/EditMetaCommand.java index 87902f3..36cf801 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/staff/EditMetaCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/staff/EditMetaCommand.java @@ -5,7 +5,6 @@ package dev.salmonllama.fsbot.commands.staff; import com.vdurmont.emoji.EmojiParser; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.controllers.OutfitController; import dev.salmonllama.fsbot.guthix.*; import org.apache.logging.log4j.util.Strings; diff --git a/src/main/java/dev/salmonllama/fsbot/commands/staff/RemoveOutfitCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/staff/RemoveOutfitCommand.java index 21d1eb4..6dbfed1 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/staff/RemoveOutfitCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/staff/RemoveOutfitCommand.java @@ -5,7 +5,6 @@ package dev.salmonllama.fsbot.commands.staff; import com.vdurmont.emoji.EmojiParser; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.controllers.OutfitController; import dev.salmonllama.fsbot.guthix.*; import org.javacord.api.entity.channel.TextChannel; diff --git a/src/main/java/dev/salmonllama/fsbot/commands/staff/RestoreOutfitCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/staff/RestoreOutfitCommand.java index 69d25cf..2ef4f3b 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/staff/RestoreOutfitCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/staff/RestoreOutfitCommand.java @@ -5,7 +5,6 @@ package dev.salmonllama.fsbot.commands.staff; import com.vdurmont.emoji.EmojiParser; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.controllers.OutfitController; import dev.salmonllama.fsbot.guthix.*; import org.javacord.api.entity.channel.TextChannel; diff --git a/src/main/java/dev/salmonllama/fsbot/commands/staff/RetagCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/staff/RetagCommand.java index 04984c9..0f18d6e 100644 --- a/src/main/java/dev/salmonllama/fsbot/commands/staff/RetagCommand.java +++ b/src/main/java/dev/salmonllama/fsbot/commands/staff/RetagCommand.java @@ -5,7 +5,6 @@ package dev.salmonllama.fsbot.commands.staff; import com.vdurmont.emoji.EmojiParser; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.controllers.OutfitController; import dev.salmonllama.fsbot.database.models.Outfit; import dev.salmonllama.fsbot.guthix.*; diff --git a/src/main/java/dev/salmonllama/fsbot/commands/staff/WelcomeMessageCommand.java b/src/main/java/dev/salmonllama/fsbot/commands/staff/WelcomeMessageCommand.java deleted file mode 100644 index 0e0ff66..0000000 --- a/src/main/java/dev/salmonllama/fsbot/commands/staff/WelcomeMessageCommand.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2021 Aleksei Gryczewski - */ - -package dev.salmonllama.fsbot.commands.staff; - -import dev.salmonllama.fsbot.config.BotConfig; -import dev.salmonllama.fsbot.database.controllers.ServerConfigController; -import dev.salmonllama.fsbot.database.models.ServerConfig; -import dev.salmonllama.fsbot.guthix.*; -import org.javacord.api.entity.message.embed.EmbedBuilder; -import org.javacord.api.util.logging.ExceptionLogger; - -import java.util.Arrays; -import java.util.List; - -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 newMessage]"; } - @Override public CommandCategory category() { return CommandCategory.STAFF; } - @Override public CommandPermission permission() { return new CommandPermission(PermissionType.STATIC, "staff"); } - @Override public List aliases() { return Arrays.asList("welcomemessage", "wmsg"); } - - @Override - public void onCommand(CommandContext ctx) { - if (ctx.isPrivateMessage()) { - ctx.reply("This command can only be used within a server"); - return; - } - - if (ctx.getArgs().length < 1) { - ctx.reply("You need to supply arguments for this command"); - return; - } - - String[] args = ctx.getArgs(); - switch (args[0]) { - case "get": - get(ctx); - break; - case "set": // TODO: check for args here - String newMsg = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); - set(ctx, newMsg); - break; - default: - ctx.reply("You used this command incorrectly."); - } - } - - private void get(CommandContext ctx) { - ctx.getServer().ifPresent( // If server is present (not private message) get the server config - server -> ServerConfigController.get(server.getIdAsString()).thenAcceptAsync( - possibleConf -> possibleConf.ifPresentOrElse( // Check for current server config - conf -> ctx.reply(getMsg(conf)), // Fetch and send the current welcome message - () -> ctx.reply(notFound()) // No welcome message exists, sorrynotsorry - ) - )); - } - - private EmbedBuilder getMsg(ServerConfig config) { - return new EmbedBuilder() - .setTitle("Current Welcome Message") - .setDescription(config.getWelcomeMessage()); - } - - private EmbedBuilder notFound() { - return new EmbedBuilder() - .setTitle("Does not exist!") - .setDescription("No welcome message was found! use `~wmsg set` to set one!"); - } - - private void set(CommandContext ctx, String newMsg) { - ctx.getServer().ifPresent( // If server is present (private msg check) get the server's config - server -> ServerConfigController.get(server.getIdAsString()).thenAcceptAsync( // Check for a current server config - possibleConf -> possibleConf.ifPresentOrElse( - conf -> ctx.reply(updateMsg(conf, newMsg)), // Config exists, update with new welcome message - () -> ctx.reply(setNewMsg(server.getIdAsString(), newMsg))))); // Config does not exist, init and add new welcome message - } - - private EmbedBuilder updateMsg(ServerConfig conf, String newMsg) { - // Updates a welcome message from an already existing server config - ServerConfig config = new ServerConfig.ServerConfigBuilder().from(conf) - .setWelcomeMessage(newMsg) - .build(); - - ServerConfigController.update(config).exceptionally(ExceptionLogger.get()); // TODO: Write a discord Throwable consumer like this - - return new EmbedBuilder() - .setTitle("Welcome Message Set") - .addField("New Welcome Message:", config.getWelcomeMessage()); - } - - private EmbedBuilder setNewMsg(String serverId, String newMsg) { - // Creates a new server config and adds a welcome message - ServerConfig config = new ServerConfig.ServerConfigBuilder() - .setId(serverId) - .setPrefix(BotConfig.DEFAULT_PREFIX) - .setWelcomeMessage(newMsg) - .build(); - - ServerConfigController.insert(config); - - return new EmbedBuilder() - .setTitle("Welcome Message Set!") - .setDescription("server conf has been created") - .addField("New Welcome Message:", newMsg); - } -} diff --git a/src/main/java/dev/salmonllama/fsbot/config/BotConfig.java b/src/main/java/dev/salmonllama/fsbot/config/BotConfig.java deleted file mode 100644 index 4339701..0000000 --- a/src/main/java/dev/salmonllama/fsbot/config/BotConfig.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2021 Aleksei Gryczewski - */ - -// Shoutout to Kaaz (again) for a kickass config service: https://github.com/Kaaz/ConfigurationBuilder -package dev.salmonllama.fsbot.config; - -import com.kaaz.configuration.ConfigurationBuilder; -import com.kaaz.configuration.ConfigurationOption; -import dev.salmonllama.fsbot.utilities.Constants; - -import java.nio.file.Path; -import java.nio.file.Paths; - -public class BotConfig { - @ConfigurationOption - public static String DB_ADDR = "SQLite connection address here"; - - @ConfigurationOption - public static String DB_NAME = "SQLite database name here"; - - @ConfigurationOption - public static String DEFAULT_PREFIX = "default prefix here"; - - @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 WELCOME_CHANNEL = "welcome channel here"; - - @ConfigurationOption - public static String JOIN_LOG = "join log channel"; - - @ConfigurationOption - public static String REPORT_LOG = "report_log_channel"; - - @ConfigurationOption - public static String OUTFIT_LOG = "outfit log channel"; - - @ConfigurationOption - public static String CONTEST_LOG = "zammy log here"; - - @ConfigurationOption - public static String ACTIVITY_LOG = "bot_log_channel"; - - @ConfigurationOption - public static String HYDRIX_ROLE = "hydrix role id here"; - - @ConfigurationOption - public static String MEMBER_ROLE = "member role id here"; - - @ConfigurationOption - public static String DEFAULT_REACTION = ":heartpulse:"; - - @ConfigurationOption - public static String HOME_SERVER = "Home server here"; - - @ConfigurationOption - public static String BOT_TOKEN_DEV = "bot token here"; - - @ConfigurationOption - public static String BOT_TOKEN_PROD = "production token here"; - - @ConfigurationOption - public static String IMGUR_BEARER = "Bearer token here"; - - @ConfigurationOption - public static String IMGUR_CLIENT = "client ID here"; - - public static void initConfig(Path filePath, boolean cleanfile) { - try { - new ConfigurationBuilder(BotConfig.class, Paths.get(filePath.toString(), Constants.CONFIG_NAME) .toFile()).build(cleanfile); - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - } -} diff --git a/src/main/java/dev/salmonllama/fsbot/config/EnvManager.java b/src/main/java/dev/salmonllama/fsbot/config/EnvManager.java new file mode 100644 index 0000000..f65d45e --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/config/EnvManager.java @@ -0,0 +1,16 @@ +package dev.salmonllama.fsbot.config; + +public class EnvManager { + // Bot configuration + public static String BOT_TOKEN = System.getenv("BOT_TOKEN"); + public static String BOT_OWNER = System.getenv("BOT_OWNER"); + public static String DEFAULT_COMMAND_PREFIX = System.getenv("DEFAULT_COMMAND_PREFIX"); + public static String DEFAULT_IMAGE_REACTION = System.getenv(":heartpulse:"); + + // Internal API configurations + public static String API_URI = System.getenv("API_URI"); + + // External API configurations + public static String IMGUR_CLIENT_ID = System.getenv("IMGUR_CLIENT_ID"); + public static String IMGUR_BEARER_TOKEN = System.getenv("IMGUR_BEARER_TOKEN"); +} diff --git a/src/main/java/dev/salmonllama/fsbot/config/SecretManager.java b/src/main/java/dev/salmonllama/fsbot/config/SecretManager.java deleted file mode 100644 index 8bf8fb2..0000000 --- a/src/main/java/dev/salmonllama/fsbot/config/SecretManager.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2021 Aleksei Gryczewski - */ - -package dev.salmonllama.fsbot.config; - -import java.io.IOException; - -import com.google.cloud.secretmanager.v1.SecretManagerServiceClient; - -public enum SecretManager { - DISCORD_TOKEN ("projects/fashionscapers-212707/secrets/fs_discord_token/versions/latest"), - DISCORD_TOKEN_PROD ("projects/fashionscapers-212707/secrets/fs_discord_token_prod/versions/latest"), - IMGUR_ID ("projects/fashionscapers-212707/secrets/fs_imgur_client_id/versions/latest"), - IMGUR_BEARER ("projects/fashionscapers-212707/secrets/fs_imgur_bearer_token/versions/latest") - ; - - private final String resourceId; - - SecretManager(String resourceId) { - this.resourceId = resourceId; - } - - public String getPlainText() { - try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) { - return client.accessSecretVersion(this.resourceId).getPayload().getData().toStringUtf8(); - } catch (IOException e) { - e.printStackTrace(); // TODO: Add plain text error message to log to console - System.exit(1); // Secrets are integral to full operation, crash if not retrieved properly. - return null; - } - } -} diff --git a/src/main/java/dev/salmonllama/fsbot/database/DatabaseProvider.java b/src/main/java/dev/salmonllama/fsbot/database/DatabaseProvider.java index e084f61..5ad2bb7 100644 --- a/src/main/java/dev/salmonllama/fsbot/database/DatabaseProvider.java +++ b/src/main/java/dev/salmonllama/fsbot/database/DatabaseProvider.java @@ -6,7 +6,6 @@ package dev.salmonllama.fsbot.database; import dev.salmonllama.fsbot.exceptions.UnknownParameterException; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.utilities.Constants; import org.slf4j.Logger; diff --git a/src/main/java/dev/salmonllama/fsbot/database/FSDB.java b/src/main/java/dev/salmonllama/fsbot/database/FSDB.java index 376e324..4bbf644 100644 --- a/src/main/java/dev/salmonllama/fsbot/database/FSDB.java +++ b/src/main/java/dev/salmonllama/fsbot/database/FSDB.java @@ -5,7 +5,6 @@ // Heavily inspired by Kaaz's Emily database connection: https://github.com/Kaaz/DiscordBot/tree/master/src/main/java/emily/db package dev.salmonllama.fsbot.database; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.models.*; import java.sql.SQLException; diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/ApiConnection.java b/src/main/java/dev/salmonllama/fsbot/endpoints/ApiConnection.java new file mode 100644 index 0000000..0a6ea5a --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/ApiConnection.java @@ -0,0 +1,143 @@ +package dev.salmonllama.fsbot.endpoints; + +import com.google.gson.Gson; +import io.micrometer.core.lang.Nullable; +import okhttp3.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +public class ApiConnection { + private final HttpUrl REQUEST_URI; + private final HashMap HEADERS; + + private final Logger logger = LoggerFactory.getLogger(ApiConnection.class); + + public ApiConnection(String uri, @Nullable HashMap headers) { + this.REQUEST_URI = Objects.requireNonNull(HttpUrl.parse(uri)); + this.HEADERS = headers; + } + + public ApiConnection(String uri) { + this(uri, null); + } + + public CompletableFuture get(@Nullable HashMap parameters) { + HttpUrl.Builder urlBuilder = REQUEST_URI.newBuilder(); + if (parameters != null) { + parameters.forEach(urlBuilder::addQueryParameter); + } + + Request.Builder request = new Request.Builder() + .get() + .url(urlBuilder.build()); + + return call(request); + } + + public CompletableFuture get() { + return get(null); + } + + public CompletableFuture post(@Nullable HashMap parameters, RequestBody body) { + HttpUrl.Builder urlBuilder = REQUEST_URI.newBuilder(); + if (parameters != null) { + parameters.forEach(urlBuilder::addQueryParameter); + } + + Request.Builder request = new Request.Builder() + .post(body) + .url(urlBuilder.build()); + + return call (request); + } + + public CompletableFuture post(RequestBody body) { + return post(null, body); + } + + public CompletableFuture put(@Nullable HashMap parameters, RequestBody body) { + HttpUrl.Builder urlBuilder = REQUEST_URI.newBuilder(); + if (parameters != null) { + parameters.forEach(urlBuilder::addQueryParameter); + } + + Request.Builder request = new Request.Builder() + .put(body) + .url(urlBuilder.build()); + + return call(request); + } + + public CompletableFuture put(RequestBody body) { + return put(null, body); + } + + public CompletableFuture delete(@Nullable HashMap parameters, @Nullable RequestBody body) { + HttpUrl.Builder urlBuilder = REQUEST_URI.newBuilder(); + if (parameters != null) { + parameters.forEach(urlBuilder::addQueryParameter); + } + + Request.Builder request = new Request.Builder() + .url(urlBuilder.build()); + + if (body != null) { + request.delete(body); + } else { + request.delete(); + } + + return call(request); + } + + public CompletableFuture delete(RequestBody body) { + return delete(null, body); + } + + public CompletableFuture delete(HashMap parameters) { + return delete(parameters, null); + } + + public CompletableFuture delete() { + return delete(null, null); + } + + private CompletableFuture call(Request.Builder request) { + if (HEADERS != null) { + HEADERS.forEach(request::addHeader); + } + + OkHttpClient client = new OkHttpClient().newBuilder().build(); + + return CompletableFuture.supplyAsync(() -> { + try (var response = client.newCall(request.build()).execute()) { + return response; + } catch (IOException e) { + throw new CompletionException(e); + } + }); + } + + public static T unmarshall(ResponseBody body, Class classOfT) throws IOException { + Gson gson = new Gson(); + return gson.fromJson(body.string(), classOfT); + } + + public static T unmarshall(ResponseBody body, Type typeOfT) throws IOException { + Gson gson = new Gson(); + return gson.fromJson(body.string(), typeOfT); + } + + public static RequestBody marshall(Object obj) { + Gson gson = new Gson(); + return RequestBody.create(gson.toJson(obj), MediaType.parse("application/json")); + + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/FashionscapeApi.java b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/FashionscapeApi.java new file mode 100644 index 0000000..c487882 --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/FashionscapeApi.java @@ -0,0 +1,29 @@ +package dev.salmonllama.fsbot.endpoints.fashionscape; + +import dev.salmonllama.fsbot.endpoints.fashionscape.controllers.GalleryApi; +import dev.salmonllama.fsbot.endpoints.fashionscape.controllers.GuildConfigApi; +import dev.salmonllama.fsbot.endpoints.fashionscape.controllers.ImageApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FashionscapeApi { + + public FashionscapeApi() { + } + + @Bean + public static GuildConfigApi guildConfig() { + return new GuildConfigApi(); + } + + @Bean + public static ImageApi image() { + return new ImageApi(); + } + + @Bean + public static GalleryApi gallery() { + return new GalleryApi(); + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/GalleryApi.java b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/GalleryApi.java new file mode 100644 index 0000000..bfd2199 --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/GalleryApi.java @@ -0,0 +1,44 @@ +package dev.salmonllama.fsbot.endpoints.fashionscape.controllers; + +import com.google.gson.reflect.TypeToken; +import dev.salmonllama.fsbot.config.EnvManager; +import dev.salmonllama.fsbot.endpoints.ApiConnection; +import dev.salmonllama.fsbot.endpoints.fashionscape.models.Gallery; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +public class GalleryApi { + + private final String GALLERY_URI = EnvManager.API_URI + "/gallery"; + + private final ApiConnection conn; + + public GalleryApi() { + this.conn = new ApiConnection(GALLERY_URI); + } + + public CompletableFuture> getAll(String guildId) { + HashMap params = new HashMap<>(); + params.put("guildid", guildId); + + return conn.get(params).thenApplyAsync(response -> { + if (response.body() == null) { + throw new CompletionException(new RuntimeException("No Response")); + } + + try { + return ApiConnection.unmarshall(response.body(), new TypeToken>(){}.getType()); + } catch (IOException e) { + throw new CompletionException(e); + } + }); + } + + public void create(Gallery.Create gallery) { + + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/guildconfig/GuildConfigApi.java b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/GuildConfigApi.java similarity index 93% rename from src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/guildconfig/GuildConfigApi.java rename to src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/GuildConfigApi.java index c1c7f07..bb2be56 100644 --- a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/guildconfig/GuildConfigApi.java +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/GuildConfigApi.java @@ -1,7 +1,8 @@ -package dev.salmonllama.fsbot.endpoints.fashionscape.guildconfig; +package dev.salmonllama.fsbot.endpoints.fashionscape.controllers; import dev.salmonllama.fsbot.config.EnvManager; import dev.salmonllama.fsbot.endpoints.ApiConnection; +import dev.salmonllama.fsbot.endpoints.fashionscape.models.GuildConfig; import okhttp3.RequestBody; import java.io.IOException; diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/ImageApi.java b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/ImageApi.java new file mode 100644 index 0000000..a9a1b62 --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/controllers/ImageApi.java @@ -0,0 +1,4 @@ +package dev.salmonllama.fsbot.endpoints.fashionscape.controllers; + +public class ImageApi { +} diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Gallery.java b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Gallery.java new file mode 100644 index 0000000..c06228e --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Gallery.java @@ -0,0 +1,24 @@ +package dev.salmonllama.fsbot.endpoints.fashionscape.models; + +public class Gallery { + private String objectId; + private String guildId; + private String channelid; + private String tag; + private String reaction; + + public Gallery() { + + } + + public static class Create { + private String guildId; + private String channelId; + private String tag; + private String reaction; + + public Create() { + + } + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/GuildConfig.java b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/GuildConfig.java new file mode 100644 index 0000000..7fd4d87 --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/GuildConfig.java @@ -0,0 +1,175 @@ +package dev.salmonllama.fsbot.endpoints.fashionscape.models; + +import com.google.gson.annotations.SerializedName; + +import java.util.Map; +import java.util.Set; + +public class GuildConfig { + + public GuildConfig() { + + } + + //* General settings */ + @SerializedName("object_id") + private String objectId; + @SerializedName("guild_id") + private String guildId; + @SerializedName("prefix") + private String prefix; + + //* Reporting Module */ + @SerializedName("report_enabled") + private boolean isReportingEnabled; + @SerializedName("report_persistent") + private boolean isReportLogPersistent; + @SerializedName("report_channel") + private String reportingStaffChannel; + + //* Welcome Messaging Module */ + @SerializedName("welcome_enabled") + private boolean isWelcomeEnabled; + @SerializedName("welcome_channel") + private String welcomeChannel; + @SerializedName("welcome_message") + private String welcomeMessage; + + //* Social Reactions Module */ + @SerializedName("social_enabled") + private boolean isSocialReactEnabled; + @SerializedName("social_channels") + private Set socialReactChannels; + + //* Celebrations Module */ + @SerializedName("celebration_enabled") + private boolean isCelebrationEnabled; + @SerializedName("celebration_data") + private Map celebrationData; //* */ + + //* Gallery Module */ + @SerializedName("gallery_enabled") + private boolean isGalleryEnabled; + @SerializedName("gallery_channels") + private Set galleryChannels; //* Gallery data will be stored in a diff table */ + + public String getObjectId() { + return objectId; + } + + public void setObjectId(String objectId) { + this.objectId = objectId; + } + + public String getGuildId() { + return guildId; + } + + public void setGuildId(String guildId) { + this.guildId = guildId; + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public boolean isReportingEnabled() { + return isReportingEnabled; + } + + public void setReportingEnabled(boolean reportingEnabled) { + isReportingEnabled = reportingEnabled; + } + + public boolean isReportLogPersistent() { + return isReportLogPersistent; + } + + public void setReportLogPersistent(boolean reportLogPersistent) { + isReportLogPersistent = reportLogPersistent; + } + + public String getReportingStaffChannel() { + return reportingStaffChannel; + } + + public void setReportingStaffChannel(String reportingStaffChannel) { + this.reportingStaffChannel = reportingStaffChannel; + } + + public boolean isWelcomeEnabled() { + return isWelcomeEnabled; + } + + public void setWelcomeEnabled(boolean welcomeEnabled) { + isWelcomeEnabled = welcomeEnabled; + } + + public String getWelcomeChannel() { + return welcomeChannel; + } + + public void setWelcomeChannel(String welcomeChannel) { + this.welcomeChannel = welcomeChannel; + } + + public String getWelcomeMessage() { + return welcomeMessage; + } + + public void setWelcomeMessage(String welcomeMessage) { + this.welcomeMessage = welcomeMessage; + } + + public boolean isSocialReactEnabled() { + return isSocialReactEnabled; + } + + public void setSocialReactEnabled(boolean socialReactEnabled) { + isSocialReactEnabled = socialReactEnabled; + } + + public Set getSocialReactChannels() { + return socialReactChannels; + } + + public void setSocialReactChannels(Set socialReactChannels) { + this.socialReactChannels = socialReactChannels; + } + + public boolean isCelebrationEnabled() { + return isCelebrationEnabled; + } + + public void setCelebrationEnabled(boolean celebrationEnabled) { + isCelebrationEnabled = celebrationEnabled; + } + + public Map getCelebrationData() { + return celebrationData; + } + + public void setCelebrationData(Map celebrationData) { + this.celebrationData = celebrationData; + } + + public boolean isGalleryEnabled() { + return isGalleryEnabled; + } + + public void setGalleryEnabled(boolean galleryEnabled) { + isGalleryEnabled = galleryEnabled; + } + + public Set getGalleryChannels() { + return galleryChannels; + } + + public void setGalleryChannels(Set galleryChannels) { + this.galleryChannels = galleryChannels; + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Image.java b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Image.java new file mode 100644 index 0000000..b1bb917 --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/fashionscape/models/Image.java @@ -0,0 +1,4 @@ +package dev.salmonllama.fsbot.endpoints.fashionscape.models; + +public class Image { +} diff --git a/src/main/java/dev/salmonllama/fsbot/endpoints/imgur/ImgurAPIConnection.java b/src/main/java/dev/salmonllama/fsbot/endpoints/imgur/ImgurAPIConnection.java index a311969..18d0c89 100644 --- a/src/main/java/dev/salmonllama/fsbot/endpoints/imgur/ImgurAPIConnection.java +++ b/src/main/java/dev/salmonllama/fsbot/endpoints/imgur/ImgurAPIConnection.java @@ -5,11 +5,10 @@ package dev.salmonllama.fsbot.endpoints.imgur; //import dev.salmonllama.fsbot.config.SecretManager; +import dev.salmonllama.fsbot.config.EnvManager; import okhttp3.*; import org.json.JSONObject; -import dev.salmonllama.fsbot.config.BotConfig; - import java.io.IOException; import java.util.concurrent.CompletableFuture; @@ -24,8 +23,8 @@ public class ImgurAPIConnection { private final Request.Builder requestBuilder; public ImgurAPIConnection() { - CLIENT_ID = BotConfig.IMGUR_CLIENT; - BEARER_TOKEN = BotConfig.IMGUR_BEARER; + CLIENT_ID = EnvManager.IMGUR_CLIENT_ID; + BEARER_TOKEN = EnvManager.IMGUR_BEARER_TOKEN; // CLIENT_ID = SecretManager.IMGUR_ID.getPlainText(); // BEARER_TOKEN = SecretManager.IMGUR_BEARER.getPlainText(); diff --git a/src/main/java/dev/salmonllama/fsbot/guthix/CommandContext.java b/src/main/java/dev/salmonllama/fsbot/guthix/CommandContext.java index cf7f712..b74ffae 100644 --- a/src/main/java/dev/salmonllama/fsbot/guthix/CommandContext.java +++ b/src/main/java/dev/salmonllama/fsbot/guthix/CommandContext.java @@ -4,62 +4,61 @@ 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 org.javacord.api.event.message.MessageCreateEvent; +import dev.salmonllama.fsbot.config.EnvManager; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import java.util.Collection; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import java.util.function.Predicate; public class CommandContext { - private MessageCreateEvent event; - private DiscordApi api; - private Message message; - private MessageAuthor author; - private TextChannel channel; - private Optional server; - private Command usedCommand; - private String usedAlias; - private String[] args; + private final MessageReceivedEvent event; + private final JDA jda; + private final Message message; + private final User author; + private final Channel channel; + private final Guild guild; + private final Command usedCommand; + private final String usedAlias; + private final String[] args; private CommandContext(CommandContextBuilder builder) { this.event = builder.event; - this.api = builder.api; + this.jda = builder.jda; this.message = builder.message; this.author = builder.author; this.channel = builder.channel; - this.server = builder.server; + this.guild = builder.guild; this.usedCommand = builder.usedCommand; this.usedAlias = builder.usedAlias; this.args = builder.args; } - public DiscordApi getApi() { - return api; + public JDA getJDA() { + return jda; } public Message getMessage() { return message; } - public MessageAuthor getAuthor() { + public User getAuthor() { return author; } - public TextChannel getChannel() { + public Channel getChannel() { return channel; } - public Optional getServer() { - return server; + public Guild getGuild() { + return guild; } public Command getUsedCommand() { @@ -75,32 +74,19 @@ public class CommandContext { } public User getUser() { - if (author.asUser().isPresent()) { - return author.asUser().get(); - } else { - // Log something to discord, I dunno - } - return null; - } - - public Optional> getUserRoles() { - User user = getUser(); - if (getServer().isPresent()) { - return Optional.of(user.getRoles(getServer().get())); - } - return Optional.empty(); + return author; } public boolean isUserOwner() { - return getUser().getIdAsString().equals(BotConfig.BOT_OWNER); + return author.getId().equals(EnvManager.BOT_OWNER); } public boolean isPrivateMessage() { - return event.isPrivateMessage(); + return !event.isFromGuild(); } public CompletableFuture reply(String msg) { - return channel.sendMessage(msg); + return guild.getTextChannelById(channel.getId()).se } public CompletableFuture reply(EmbedBuilder embed) { @@ -116,28 +102,28 @@ public class CommandContext { } public static class CommandContextBuilder { - private MessageCreateEvent event; - private DiscordApi api; - private Message message; - private MessageAuthor author; - private TextChannel channel; - private Optional server; - private Command usedCommand; - private String usedAlias; - private String[] args; + private final MessageReceivedEvent event; + private final JDA jda; + private final Message message; + private final User author; + private final Channel channel; + private final Guild guild; + private final Command usedCommand; + private final String usedAlias; + private final String[] args; public CommandContextBuilder( - MessageCreateEvent event, + MessageReceivedEvent event, Command usedCommand, String usedAlias, String[] args ) { this.event = event; - this.api = event.getApi(); + this.jda = event.getJDA(); this.message = event.getMessage(); - this.author = event.getMessageAuthor(); + this.author = event.getAuthor(); this.channel = event.getChannel(); - this.server = event.getServer(); + this.guild = event.getGuild(); this.usedCommand = usedCommand; this.usedAlias = usedAlias; this.args = args; diff --git a/src/main/java/dev/salmonllama/fsbot/guthix/Guthix.java b/src/main/java/dev/salmonllama/fsbot/guthix/Guthix.java index 2195439..5e61099 100644 --- a/src/main/java/dev/salmonllama/fsbot/guthix/Guthix.java +++ b/src/main/java/dev/salmonllama/fsbot/guthix/Guthix.java @@ -11,10 +11,10 @@ import dev.salmonllama.fsbot.commands.rs3search.*; import dev.salmonllama.fsbot.commands.staff.OutfitInfoCommand; import dev.salmonllama.fsbot.commands.staff.*; import dev.salmonllama.fsbot.database.controllers.UserBlacklistController; -import org.javacord.api.DiscordApi; -import org.javacord.api.entity.message.MessageAuthor; -import org.javacord.api.event.message.MessageCreateEvent; -import org.javacord.api.listener.message.MessageCreateListener; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,18 +24,18 @@ import java.util.HashMap; /* * Guthix is Fashionscape Bot's command repository and dispatcher */ -public class Guthix implements MessageCreateListener { +public class Guthix extends ListenerAdapter { private final static Logger logger = LoggerFactory.getLogger(Guthix.class); @SuppressWarnings("unused") - private final DiscordApi api; + private final JDA jda; private final Registry registry; private final PermissionManager manager; - public Guthix(DiscordApi api) { - this.api = api; - api.addMessageCreateListener(this); + public Guthix(JDA jda) { + this.jda = jda; + jda.addEventListener(this); manager = new PermissionManager(); registry = new Registry(); @@ -76,31 +76,6 @@ public class Guthix implements MessageCreateListener { addCommand(new StatsCommand()); addCommand(new PrivacyCommand()); - // Osrs Search Commands - addCommand(new OsrsSearchCommand()); - addCommand(new OsrsHeadCommand()); - addCommand(new OsrsBodyCommand()); - addCommand(new OsrsHandCommand()); - addCommand(new OsrsLegsCommand()); - addCommand(new OsrsFeetCommand()); - addCommand(new OsrsCapeCommand()); - addCommand(new OsrsNeckCommand()); - addCommand(new OsrsShieldCommand()); - addCommand(new OsrsWeaponCommand()); - - // Rs3 Search Commands - addCommand(new Rs3SearchCommand()); - addCommand(new Rs3HeadCommand()); - addCommand(new Rs3BodyCommand()); - addCommand(new Rs3NeckCommand()); - addCommand(new Rs3HandCommand()); - addCommand(new Rs3FeetCommand()); - addCommand(new Rs3LegsCommand()); - addCommand(new Rs3BackCommand()); - addCommand(new Rs3MainhandCommand()); - addCommand(new Rs3OffhandCommand()); - addCommand(new Rs3TwohandedCommand()); - logger.info("Command initialization complete!"); } @@ -117,8 +92,8 @@ public class Guthix implements MessageCreateListener { } @Override - public void onMessageCreate(MessageCreateEvent event) { - MessageAuthor author = event.getMessageAuthor(); + public void onMessageReceived(MessageReceivedEvent event) { + User author = event.getAuthor(); if (manager.sourceIsValid(author)) { diff --git a/src/main/java/dev/salmonllama/fsbot/guthix/PermissionManager.java b/src/main/java/dev/salmonllama/fsbot/guthix/PermissionManager.java index e020383..cb1f054 100644 --- a/src/main/java/dev/salmonllama/fsbot/guthix/PermissionManager.java +++ b/src/main/java/dev/salmonllama/fsbot/guthix/PermissionManager.java @@ -6,10 +6,9 @@ package dev.salmonllama.fsbot.guthix; import java.util.concurrent.atomic.AtomicBoolean; -import org.javacord.api.entity.message.MessageAuthor; - import dev.salmonllama.fsbot.database.controllers.StaticPermissionController; import dev.salmonllama.fsbot.database.models.StaticPermission; +import net.dv8tion.jda.api.entities.User; public class PermissionManager { @@ -23,9 +22,6 @@ public class PermissionManager { switch (permType) { case NONE: return true; - case ROLE: - // If the author has the role, yes. Doesn't work in DM - return roleHandler(permValue, ctx); case STATIC: return staticHandler(permValue, ctx); case PERMISSION: @@ -38,14 +34,6 @@ public class PermissionManager { } } - private boolean roleHandler(String roleId, CommandContext ctx) { - if (ctx.getUserRoles().isEmpty()) { - ctx.reply("This command can only be used in a server"); - return false; - } - return ctx.getUserRoles().get().stream().anyMatch(role -> role.getIdAsString().equals(roleId)); - } - private boolean ownerHandler(CommandContext ctx) { return ctx.isUserOwner(); } @@ -71,7 +59,7 @@ public class PermissionManager { return ret.get(); } - boolean sourceIsValid(MessageAuthor author) { - return !author.isBotUser() && !author.isWebhook(); + boolean sourceIsValid(User author) { + return !author.isBot() && !author.isSystem(); } } diff --git a/src/main/java/dev/salmonllama/fsbot/guthix/Registry.java b/src/main/java/dev/salmonllama/fsbot/guthix/Registry.java index 9d699e2..e78cc46 100644 --- a/src/main/java/dev/salmonllama/fsbot/guthix/Registry.java +++ b/src/main/java/dev/salmonllama/fsbot/guthix/Registry.java @@ -4,8 +4,6 @@ package dev.salmonllama.fsbot.guthix; -import dev.salmonllama.fsbot.config.BotConfig; - import java.util.*; import java.util.function.Predicate; diff --git a/src/main/java/dev/salmonllama/fsbot/interactions/ServerConfigInteraction.java b/src/main/java/dev/salmonllama/fsbot/interactions/ServerConfigInteraction.java new file mode 100644 index 0000000..0633b5b --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/interactions/ServerConfigInteraction.java @@ -0,0 +1,134 @@ +package dev.salmonllama.fsbot.interactions; + +import dev.salmonllama.fsbot.endpoints.fashionscape.controllers.GuildConfigApi; +import dev.salmonllama.fsbot.internal.guildcfg.GuildConfigHelper; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.Commands; +import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Objects; + +public class ServerConfigInteraction extends ListenerAdapter { + + @Autowired + private GuildConfigHelper guildConfigHelper; + + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (!event.isFromGuild()) { + event.reply("This command can only be used inside a server").queue(); + return; + } + + if (event.getSubcommandGroup() != null) { //* There is a subcommand group */ + if (event.getSubcommandGroup().equalsIgnoreCase("reports") && event.getSubcommandName() != null) { //* Process individual subcommands for Reporting Module + switch (event.getSubcommandName().toLowerCase()) { + case "enable": + guildConfigHelper.enableReports( + Objects.requireNonNull(event.getGuild()).getId(), + Objects.requireNonNull(event.getOption("channel", OptionMapping::getAsChannel)).getId(), + event.getOption("persist", OptionMapping::getAsBoolean) != null && event.getOption("persist", OptionMapping::getAsBoolean) + ); + + break; + case "disable": + guildConfigHelper.disableReports( + Objects.requireNonNull(event.getGuild()).getId() + ); + + break; + } + } + } else { //* No subcommand group, process default (display full config) */ + event.deferReply().queue(); + guildConfigHelper.getGuildConfig(Objects.requireNonNull(event.getGuild()).getId()).thenAcceptAsync(cfg -> { + event.reply(cfg.toString()).queue(); + }); + } + } + + private static SubcommandData welcomeModuleSubCommand() { + return new SubcommandData("Welcome Messages", "Manage the welcome message module") + .addOption(OptionType.BOOLEAN, "Enabled", "Is the module enabled for this server?", true) + .addOption(OptionType.CHANNEL, "Channel", "Which channel should welcome messages be sent to?", true) + .addOption(OptionType.STRING, "Message", "What should the welcome message say?", true) + ; + } + + + public static SlashCommandData ServerConfigCommand() { + return Commands.slash("config", "View the server's configuration") + .addSubcommandGroups( + new SocialReactModule(), + new ReportModule() + ) + .setDefaultPermissions(DefaultMemberPermissions.enabledFor( + Permission.MANAGE_SERVER, + Permission.MODERATE_MEMBERS + )) + ; + } + + private static class SocialReactModule extends SubcommandGroupData { + + private SocialReactModule() { + super("Social", "Options related to Social Reacts"); + this.addSubcommands( + enableSocialChannels(), + disableSocialChannels(), + addSocialChannel(), + removeSocialChannel() + ); + } + + private SubcommandData enableSocialChannels() { + return new SubcommandData("Enable", "Enable the social react module"); + } + + private SubcommandData disableSocialChannels() { + return new SubcommandData("Disable", "Disable the social react module"); + } + + private SubcommandData addSocialChannel() { + return new SubcommandData("Add", "Add a channel as a social channel") + .addOption(OptionType.CHANNEL, "Channel", "The channel that should have social reactions", true) + ; + } + + private SubcommandData removeSocialChannel() { + return new SubcommandData("Remove", "Remove a channel from the social react channel list") + .addOption(OptionType.CHANNEL, "Channel", "The channel that should no longer have social reactions", true) + ; + // TODO: pre-populate this list with channels that are currently enabled. + } + } + + private static class ReportModule extends SubcommandGroupData { + private ReportModule() { + super("Reports", "Options related to reporting module (modmail)"); + this.addSubcommands( + enableReporting(), + disableReporting() + ); + } + + private SubcommandData enableReporting() { + return new SubcommandData("Enable", "Enable the reporting module") + .addOption(OptionType.CHANNEL, "Channel", "Where should reports be sent? This should be a moderator-only channel", true) + .addOption(OptionType.BOOLEAN, "Persist", "Should reporting logs be stored externally? (Default false)", false) + ; + } + + private SubcommandData disableReporting() { + return new SubcommandData("Disable", "Disable the reporting module"); + } + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/interactions/reporting/ReportModuleInteraction.java b/src/main/java/dev/salmonllama/fsbot/interactions/reporting/ReportModuleInteraction.java new file mode 100644 index 0000000..363faad --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/interactions/reporting/ReportModuleInteraction.java @@ -0,0 +1,33 @@ +package dev.salmonllama.fsbot.interactions.reporting; + +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.Commands; +import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; + +public class ReportModuleInteraction extends ListenerAdapter { + + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + if (event.getName().equals("reportmodule")) { + boolean enabled = event.getOption("enabled", OptionMapping::getAsBoolean); + Channel reportChannel = event.getOption("mod_channel", OptionMapping::getAsChannel); + boolean loggingEnabled = event.getOption("enable_logging", OptionMapping::getAsBoolean); + + // Gather the data and send it to the api service + } + } + + public static SlashCommandData ReportModuleCommand() { + return Commands.slash("reportmodule", "Manage the server's modmail reporting settings") + .addOption(OptionType.BOOLEAN, "enabled", "Whether the module should be enabled or disabled", true) + .addOption(OptionType.CHANNEL, "mod_channel", "The channel to send modmail reports to", true) + .addOption(OptionType.BOOLEAN, "enable_logging", "Whether modmail reports should be preserved in an external log", true) + .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MANAGE_SERVER, Permission.MODERATE_MEMBERS)); + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/internal/guildcfg/GuildConfigHelper.java b/src/main/java/dev/salmonllama/fsbot/internal/guildcfg/GuildConfigHelper.java new file mode 100644 index 0000000..3761145 --- /dev/null +++ b/src/main/java/dev/salmonllama/fsbot/internal/guildcfg/GuildConfigHelper.java @@ -0,0 +1,97 @@ +package dev.salmonllama.fsbot.internal.guildcfg; + +import dev.salmonllama.fsbot.endpoints.fashionscape.controllers.GuildConfigApi; +import dev.salmonllama.fsbot.endpoints.fashionscape.models.GuildConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.yaml.snakeyaml.util.ArrayUtils; + +import java.util.Arrays; +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +@Configuration +public class GuildConfigHelper { + + @Autowired + private GuildConfigApi guildConfigApi; + + public GuildConfigHelper() { + + } + + @Bean + public GuildConfigHelper getGuildConfigHelperBean() { + return new GuildConfigHelper(); + } + + public CompletableFuture getGuildConfig(String guildId) { + return guildConfigApi.get(guildId); + } + + public CompletableFuture setPrefix(String guildId, String prefix) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setPrefix(prefix); + + guildConfigApi.update(cfg); + }); + } + + public CompletableFuture enableReports(String guildId, String channelId, boolean shouldPersist) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setReportingEnabled(true); + cfg.setReportingStaffChannel(channelId); + cfg.setReportLogPersistent(shouldPersist); + + guildConfigApi.update(cfg); + }); + } + + public CompletableFuture disableReports(String guildId) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setReportingEnabled(false); + + guildConfigApi.update(cfg); + }); + } + + public CompletableFuture enableWelcomes(String guildId, String channelId, String msg) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setWelcomeEnabled(true); + cfg.setWelcomeChannel(channelId); + cfg.setWelcomeMessage(msg); + + guildConfigApi.update(cfg); + }); + } + + public CompletableFuture disableWelcomes(String guildId) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setWelcomeEnabled(false); + + guildConfigApi.update(cfg); + }); + } + + public CompletableFuture enableSocial(String guildId, String ...channelIds) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setSocialReactEnabled(true); + cfg.setSocialReactChannels(Set.of(channelIds)); + + guildConfigApi.update(cfg); + }); + } + + public CompletableFuture disableSocial(String guildId) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setSocialReactEnabled(false); + }); + } + + public CompletableFuture addSocialChannels(String guildId, String ...channelIds) { + return getGuildConfig(guildId).thenAcceptAsync(cfg -> { + cfg.setSocialReactChannels(Set.of(cfg.getSocialReactChannels(), channelIds)); + }) + } +} diff --git a/src/main/java/dev/salmonllama/fsbot/listeners/AchievementListener.java b/src/main/java/dev/salmonllama/fsbot/listeners/AchievementListener.java index cc9054d..afbfcbd 100644 --- a/src/main/java/dev/salmonllama/fsbot/listeners/AchievementListener.java +++ b/src/main/java/dev/salmonllama/fsbot/listeners/AchievementListener.java @@ -5,7 +5,6 @@ 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; diff --git a/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java b/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java index 3555395..23b294a 100644 --- a/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java +++ b/src/main/java/dev/salmonllama/fsbot/listeners/ImageListener.java @@ -4,7 +4,6 @@ package dev.salmonllama.fsbot.listeners; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.controllers.GalleryController; import dev.salmonllama.fsbot.database.controllers.OutfitController; import dev.salmonllama.fsbot.database.controllers.UserBlacklistController; @@ -116,45 +115,8 @@ public class ImageListener extends ListenerAdapter { Outfit outfit = outfitBuilder.build(); OutfitController.insert(outfit).thenAcceptAsync((Void) -> { - // Log the outfit -// // TODO: START ZAMMY LOG -// if (outfit.getTag().equals("necro-contest")) -// { -// event.getJDA().getTextChannelById(BotConfig.CONTEST_LOG).ifPresentOrElse(chnl -> -// { -// EmbedBuilder response = new EmbedBuilder() -// .setTitle("Outfit Added") -// .setAuthor(event.getMessageAuthor()) -// .setThumbnail(outfit.getLink()) -// .setFooter(String.format("%s | %s", outfit.getTag(), outfit.getId())) -// .setUrl(outfit.getLink()) -// .setColor(Color.GREEN) -// .addField("Uploaded:", outfit.getCreated().toString()) -// .addField("Discord Name:", outfit.getDiscordName()); -// -// if (!outfit.getMeta().equals("")) { -// response.addField("Meta:", outfit.getMeta()); -// } -// -// chnl.sendMessage(response); -// logger.info(String.format("Outfit from %s successfully added to the running event.", event.getMessageAuthor().getDiscriminatedName())); -// -// // Add the reaction to the original message -// GalleryController.getEmoji(channel.getIdAsString()).thenAcceptAsync( -// emoji -> event.getMessage().addReaction(EmojiParser.parseToUnicode(emoji)) -// ).exceptionally(ExceptionLogger.get()); -// }, () -> -// { -// // Fallback error message to me -// event.getApi().getUserById(BotConfig.BOT_OWNER).thenAcceptAsync( -// user -> user.sendMessage("Could not find CONTEST_LOG") -// ); -// }); -// } -// // TODO: END ZAMMY LOG - - var logChannel = event.getJDA().getTextChannelById(BotConfig.OUTFIT_LOG); + var logChannel = event.getJDA().getTextChannelById(BotConfig.OUTFIT_LOG); // TODO: Gallery channel configured log channel if (logChannel != null) { EmbedBuilder response = new EmbedBuilder() .setTitle("Outfit Added") @@ -175,7 +137,7 @@ public class ImageListener extends ListenerAdapter { // Add the emoji reaction to the message GalleryController.getEmoji(eventChannel.getId()).thenAcceptAsync( - emoji -> event.getMessage().addReaction(Emoji.fromUnicode(emoji)) + emoji -> event.getMessage().addReaction(Emoji.fromUnicode(emoji)).queue() ); } else { // TODO: Fallback error logging in owner DMs diff --git a/src/main/java/dev/salmonllama/fsbot/listeners/NewMemberListener.java b/src/main/java/dev/salmonllama/fsbot/listeners/NewMemberListener.java index f41f600..4277600 100644 --- a/src/main/java/dev/salmonllama/fsbot/listeners/NewMemberListener.java +++ b/src/main/java/dev/salmonllama/fsbot/listeners/NewMemberListener.java @@ -4,7 +4,6 @@ package dev.salmonllama.fsbot.listeners; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.database.controllers.ServerConfigController; import dev.salmonllama.fsbot.services.MemberRoleService; import org.javacord.api.event.server.member.ServerMemberJoinEvent; diff --git a/src/main/java/dev/salmonllama/fsbot/listeners/ReportListener.java b/src/main/java/dev/salmonllama/fsbot/listeners/ReportListener.java index f275a4d..7f0c94f 100644 --- a/src/main/java/dev/salmonllama/fsbot/listeners/ReportListener.java +++ b/src/main/java/dev/salmonllama/fsbot/listeners/ReportListener.java @@ -12,7 +12,6 @@ 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.*; diff --git a/src/main/java/dev/salmonllama/fsbot/listeners/ThumbsListener.java b/src/main/java/dev/salmonllama/fsbot/listeners/ThumbsListener.java index 5a659af..bb3e83c 100644 --- a/src/main/java/dev/salmonllama/fsbot/listeners/ThumbsListener.java +++ b/src/main/java/dev/salmonllama/fsbot/listeners/ThumbsListener.java @@ -5,7 +5,6 @@ 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; diff --git a/src/main/java/dev/salmonllama/fsbot/services/MemberRoleService.java b/src/main/java/dev/salmonllama/fsbot/services/MemberRoleService.java index d8c226b..79eef8f 100644 --- a/src/main/java/dev/salmonllama/fsbot/services/MemberRoleService.java +++ b/src/main/java/dev/salmonllama/fsbot/services/MemberRoleService.java @@ -4,8 +4,6 @@ package dev.salmonllama.fsbot.services; -import dev.salmonllama.fsbot.config.BotConfig; - import org.javacord.api.event.server.member.ServerMemberJoinEvent; public class MemberRoleService implements Runnable { diff --git a/src/main/java/dev/salmonllama/fsbot/utilities/DiscordUtilities.java b/src/main/java/dev/salmonllama/fsbot/utilities/DiscordUtilities.java index 28fe27e..374b197 100644 --- a/src/main/java/dev/salmonllama/fsbot/utilities/DiscordUtilities.java +++ b/src/main/java/dev/salmonllama/fsbot/utilities/DiscordUtilities.java @@ -4,7 +4,6 @@ package dev.salmonllama.fsbot.utilities; -import dev.salmonllama.fsbot.config.BotConfig; import dev.salmonllama.fsbot.guthix.CommandContext; import org.javacord.api.entity.message.embed.EmbedBuilder;