From 1eef2a727ef903cc2cfcd23c62909fd50571bea5 Mon Sep 17 00:00:00 2001 From: southernscreamer32 Date: Thu, 14 Mar 2024 01:08:48 -0700 Subject: [PATCH] Manually merged changes from JMusicBot, also updated dependencies --- README.md | 4 +- pom.xml | 14 +++- src/main/java/a9lim/raiko/Raiko.java | 70 ++++++++++--------- .../java/a9lim/raiko/audio/AudioHandler.java | 4 +- .../a9lim/raiko/commands/MusicCommand.java | 1 + .../a9lim/raiko/settings/SettingsManager.java | 17 ++++- .../java/a9lim/raiko/utils/FormatUtil.java | 23 ++++++ 7 files changed, 91 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 9a85d9e8c..03aec3c8a 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ Discord music + chatbot forked from [jagrosh's JMusicBot](https://github.com/jag 1. [Install Java 21](https://www.oracle.com/java/technologies/downloads/#java21) 2. Download the .jar file in the [latest release](https://github.com/a9lim/Raiko/releases) 3. Get a [Discord bot token](https://github.com/jagrosh/MusicBot/wiki/Getting-a-Bot-Token) and your [Discord user ID](https://github.com/jagrosh/MusicBot/wiki/Finding-Your-User-ID). -4. If you have an [OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-api-key), Youtube account, or NicoNico account, get them ready as well. +4. If you have an [OpenAI API key](https://help.openai.com/en/articles/4936850-where-do-i-find-my-api-key) or Youtube account get them ready as well. 5. Save a copy of [this file](https://github.com/a9lim/Raiko/blob/main/src/main/resources/reference.conf) as 'config.txt' in the same folder as the .jar file, and edit it to add your tokens/accounts 6. Run the .jar file with `java -jar /path/to/raiko.jar` ## Main Changes * Migrated to Java 21 -* Reworked to use [JDA 5.0.0](https://github.com/discord-jda/JDA), [LavaPlayer 2.1.0](https://github.com/lavalink-devs/lavaplayer), and several other updated libraries +* Reworked to use [JDA 5.0.0](https://github.com/discord-jda/JDA), [LavaPlayer 2.1.1](https://github.com/lavalink-devs/lavaplayer), and several other updated libraries * [JDA-Utilities](https://github.com/JDA-Applications/JDA-Utilities) forked and directly incorporated into project * ChatGPT-powered chatbot integrated * Added support for NicoNico diff --git a/pom.xml b/pom.xml index 1ce22688f..35f1e9ce1 100644 --- a/pom.xml +++ b/pom.xml @@ -20,18 +20,28 @@ always + + m2.duncte123.dev + m2-duncte123 + https://m2.duncte123.dev/releases + net.dv8tion JDA - 5.0.0-beta.20 + 5.0.0-beta.21 dev.arbjerg lavaplayer - 2.1.0 + 2.1.1 + + + com.dunctebot + sourcemanagers + 1.9.0 org.json diff --git a/src/main/java/a9lim/raiko/Raiko.java b/src/main/java/a9lim/raiko/Raiko.java index be06fe586..d39c04369 100644 --- a/src/main/java/a9lim/raiko/Raiko.java +++ b/src/main/java/a9lim/raiko/Raiko.java @@ -18,6 +18,7 @@ package a9lim.raiko; +import a9lim.jdautilities.command.CommandClient; import a9lim.jdautilities.command.CommandClientBuilder; import a9lim.jdautilities.commons.waiter.EventWaiter; import a9lim.raiko.chat.ChatBot; @@ -48,7 +49,7 @@ public class Raiko { public final static Logger LOG = LoggerFactory.getLogger(Raiko.class); public final static Permission[] RECOMMENDED_PERMS = {Permission.VIEW_CHANNEL, Permission.MESSAGE_SEND, Permission.MESSAGE_HISTORY, Permission.MESSAGE_ADD_REACTION, Permission.MESSAGE_EMBED_LINKS, Permission.MESSAGE_ATTACH_FILES, Permission.MESSAGE_MANAGE, Permission.MESSAGE_EXT_EMOJI, - Permission.MANAGE_CHANNEL, Permission.VOICE_CONNECT, Permission.VOICE_SPEAK, Permission.NICKNAME_CHANGE}; + Permission.VOICE_CONNECT, Permission.VOICE_SPEAK, Permission.NICKNAME_CHANGE}; public final static GatewayIntent[] INTENTS = {GatewayIntent.DIRECT_MESSAGES, GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MESSAGE_REACTIONS, GatewayIntent.GUILD_VOICE_STATES, GatewayIntent.MESSAGE_CONTENT, GatewayIntent.GUILD_EMOJIS_AND_STICKERS}; @@ -75,10 +76,41 @@ private static void startBot() { EventWaiter waiter = new EventWaiter(); SettingsManager settings = new SettingsManager(); Bot bot = new Bot(waiter, config, settings); + CommandClient client = createCommandClient(config, settings, bot); + if (!prompt.isNoGUI()) { + try { + GUI gui = new GUI(bot); + bot.setGUI(gui); + gui.init(); + } catch (Exception e) { + LOG.error("Could not start GUI. If you are " + + "running on a server or in a location where you cannot display a " + + "window, please run in nogui mode using the -Dnogui=true flag."); + } + } + + // attempt to log in and start + try { + bot.setJDA(JDABuilder.create(config.getToken(), Arrays.asList(INTENTS)) + .enableCache(CacheFlag.MEMBER_OVERRIDES, CacheFlag.VOICE_STATE) + .disableCache(CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS, CacheFlag.EMOJI, CacheFlag.ONLINE_STATUS, CacheFlag.SCHEDULED_EVENTS) + .addEventListeners(client, waiter, new Listener(bot)) + .setBulkDeleteSplittingEnabled(true).build()); + } catch (IllegalArgumentException ex) { + prompt.alert(Prompt.Level.ERROR, "Raiko", "Some aspect of the configuration is " + + "invalid: " + ex + "\nConfig Location: " + config.getConfigLocation()); + System.exit(1); + } catch (ErrorResponseException ex) { + prompt.alert(Prompt.Level.ERROR, "Raiko", ex + "\nInvalid reponse returned when " + + "attempting to connect, please make sure you're connected to the internet"); + System.exit(1); + } + } + private static CommandClient createCommandClient(BotConfig config, SettingsManager settings, Bot bot){ AboutCmd aboutCmd = new AboutCmd(Color.BLUE.brighter(), - "raiko gaming", - new String[]{"high-quality (touhou) music playback", "DoubleDealingQueue™ Technology", "(somewhat) easy to host yourself"}, + "Touhou-themed Music Bot", + new String[]{"High-quality (Touhou) music playback", "DoubleDealingQueue™ Technology (Literally just a deque)", "(Somewhat) Easy to host yourself"}, RECOMMENDED_PERMS); aboutCmd.setIsAuthor(false); aboutCmd.setReplacementCharacter("\uD83C\uDFB6"); // 🎶 @@ -130,7 +162,7 @@ private static void startBot() { new SetstatusCmd(), new ShutdownCmd()); - if(config.getCgpttoken() != null) { + if (config.getCgpttoken() != null) { ChatCommand.setChatBot(new ChatBot(config)); cb.addCommands( new ChatCmd(), @@ -143,34 +175,6 @@ private static void startBot() { cb.setStatus(config.getStatus()); cb.setActivity(config.getGame()); - - if (!prompt.isNoGUI()) { - try { - GUI gui = new GUI(bot); - bot.setGUI(gui); - gui.init(); - } catch (Exception e) { - LOG.error("Could not start GUI. If you are " - + "running on a server or in a location where you cannot display a " - + "window, please run in nogui mode using the -Dnogui=true flag."); - } - } - - // attempt to log in and start - try { - bot.setJDA( JDABuilder.create(config.getToken(), Arrays.asList(INTENTS)) - .enableCache(CacheFlag.MEMBER_OVERRIDES, CacheFlag.VOICE_STATE) - .disableCache(CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS, CacheFlag.EMOJI, CacheFlag.ONLINE_STATUS, CacheFlag.SCHEDULED_EVENTS) - .addEventListeners(cb.build(), waiter, new Listener(bot)) - .setBulkDeleteSplittingEnabled(true).build() ); - } catch (IllegalArgumentException ex) { - prompt.alert(Prompt.Level.ERROR, "Raiko", "Some aspect of the configuration is " - + "invalid: " + ex + "\nConfig Location: " + config.getConfigLocation()); - System.exit(1); - } catch (ErrorResponseException ex) { - prompt.alert(Prompt.Level.ERROR, "Raiko", ex + "\nInvalid reponse returned when " - + "attempting to connect, please make sure you're connected to the internet"); - System.exit(1); - } + return cb.build(); } } diff --git a/src/main/java/a9lim/raiko/audio/AudioHandler.java b/src/main/java/a9lim/raiko/audio/AudioHandler.java index 113a8a908..379ba789b 100644 --- a/src/main/java/a9lim/raiko/audio/AudioHandler.java +++ b/src/main/java/a9lim/raiko/audio/AudioHandler.java @@ -173,9 +173,9 @@ public MessageCreateData getNowPlaying(JDA jda) { if (rm.getOwner() != 0L) { User u = guild.getJDA().getUserById(rm.user.id); if (u == null) - eb.setAuthor(rm.user.username + "#" + rm.user.discrim, null, rm.user.avatar); + eb.setAuthor(FormatUtil.formatUsername(rm.user), null, rm.user.avatar); else - eb.setAuthor(u.getName() + "#" + u.getDiscriminator(), null, u.getEffectiveAvatarUrl()); + eb.setAuthor(FormatUtil.formatUsername(u), null, u.getEffectiveAvatarUrl()); } try { diff --git a/src/main/java/a9lim/raiko/commands/MusicCommand.java b/src/main/java/a9lim/raiko/commands/MusicCommand.java index bfebc1a06..1c4772bee 100644 --- a/src/main/java/a9lim/raiko/commands/MusicCommand.java +++ b/src/main/java/a9lim/raiko/commands/MusicCommand.java @@ -72,6 +72,7 @@ protected void execute(CommandEvent event) { if (!event.getGuild().getSelfMember().getVoiceState().inAudioChannel()) { try { event.getGuild().getAudioManager().openAudioConnection(userState.getChannel()); + event.getGuild().getAudioManager().setSelfDeafened(true); } catch (PermissionException ex) { event.replyError(" I am unable to connect to " + userState.getChannel().getAsMention() + "!"); return; diff --git a/src/main/java/a9lim/raiko/settings/SettingsManager.java b/src/main/java/a9lim/raiko/settings/SettingsManager.java index d97906969..b0752440c 100644 --- a/src/main/java/a9lim/raiko/settings/SettingsManager.java +++ b/src/main/java/a9lim/raiko/settings/SettingsManager.java @@ -27,15 +27,17 @@ import java.io.IOException; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.util.HashMap; public class SettingsManager implements GuildSettingsManager { + private final static String SETTINGS_FILE = "serversettings.json"; private final HashMap settings; public SettingsManager() { settings = new HashMap<>(); try { - JSONObject loadedSettings = new JSONObject(new String(Files.readAllBytes(OtherUtil.getPath("serversettings.json")))); + JSONObject loadedSettings = new JSONObject(new String(Files.readAllBytes(OtherUtil.getPath(SETTINGS_FILE)))); loadedSettings.keySet().forEach((id) -> { JSONObject o = loadedSettings.getJSONObject(id); @@ -52,9 +54,18 @@ public SettingsManager() { o.has("repeat_mode") ? o.getEnum(RepeatMode.class, "repeat_mode") : RepeatMode.OFF, o.has("prefix") ? o.getString("prefix") : null)); }); + } catch (NoSuchFileException e) { + // create an empty json file + try { + LoggerFactory.getLogger("Settings").info("serversettings.json will be created in " + OtherUtil.getPath("serversettings.json").toAbsolutePath()); + Files.write(OtherUtil.getPath("serversettings.json"), new JSONObject().toString(4).getBytes()); + } catch(IOException ex) { + LoggerFactory.getLogger("Settings").warn("Failed to create new settings file: "+ex); + } } catch (IOException | JSONException e) { - LoggerFactory.getLogger("Settings").warn("Failed to load server settings (this is normal if no settings have been set yet): " + e); + LoggerFactory.getLogger("Settings").warn("Failed to load server settings: "+e); } + LoggerFactory.getLogger("Settings").info("serversettings.json loaded from " + OtherUtil.getPath("serversettings.json").toAbsolutePath()); } /** @@ -95,7 +106,7 @@ protected void writeSettings() { obj.put(Long.toString(key), o); }); try { - Files.write(OtherUtil.getPath("serversettings.json"), obj.toString(4).getBytes()); + Files.write(OtherUtil.getPath(SETTINGS_FILE), obj.toString(4).getBytes()); } catch (IOException ex) { LoggerFactory.getLogger("Settings").warn("Failed to write to file: " + ex); } diff --git a/src/main/java/a9lim/raiko/utils/FormatUtil.java b/src/main/java/a9lim/raiko/utils/FormatUtil.java index 47b3d7dff..2f3dcec62 100644 --- a/src/main/java/a9lim/raiko/utils/FormatUtil.java +++ b/src/main/java/a9lim/raiko/utils/FormatUtil.java @@ -18,7 +18,10 @@ package a9lim.raiko.utils; +import a9lim.raiko.audio.RequestMetadata.UserInfo; + import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; @@ -37,6 +40,26 @@ public static String formatTime(long duration) { return (hours > 0 ? hours + ":" : "") + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds); } + public static String formatUsername(String username, String discrim) + { + if(discrim == null || discrim.equals("0000")) + { + return username; + } + else + { + return username + "#" + discrim; + } + } + + public static String formatUsername(UserInfo userinfo) { + return formatUsername(userinfo.username, userinfo.discrim); + } + + public static String formatUsername(User user) { + return formatUsername(user.getName(), user.getDiscriminator()); + } + public static String progressBar(double percent) { StringBuilder str = new StringBuilder(); for (int i = 0; i < 12; i++)