From af9b13b05055f18ecd5f1bd0826ef9654fec5d32 Mon Sep 17 00:00:00 2001 From: Louis Vallat Date: Mon, 16 Nov 2020 21:30:07 +0100 Subject: [PATCH] [WIP] Implementing a socket system for governing the bot from another instance, to turn on maintenance mode for example. Signed-off-by: Louis Vallat --- build.gradle | 3 +- .../java/xyz/vallat/louis/MoviesQuoteBot.java | 26 ++++++- .../xyz/vallat/louis/codes/ExitCodes.java | 4 +- .../vallat/louis/discord/DiscordManager.java | 12 +++- .../louis/env/EnvironmentVariables.java | 1 + .../java/xyz/vallat/louis/sockets/Client.java | 4 ++ .../java/xyz/vallat/louis/sockets/Server.java | 70 +++++++++++++++++++ .../vallat/louis/sockets/SocketsCommand.java | 17 +++++ 8 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 src/main/java/xyz/vallat/louis/sockets/Client.java create mode 100644 src/main/java/xyz/vallat/louis/sockets/Server.java create mode 100644 src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java diff --git a/build.gradle b/build.gradle index 2fcde53..9bde080 100644 --- a/build.gradle +++ b/build.gradle @@ -11,8 +11,9 @@ ext { javaMainClass = 'xyz.vallat.louis.MoviesQuoteBot' } + application { - mainClassName = javaMainClass + getMainClass().set(javaMainClass) } jar { diff --git a/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java b/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java index 014ce6d..ba862b8 100644 --- a/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java +++ b/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java @@ -1,5 +1,6 @@ package xyz.vallat.louis; +import org.apache.commons.cli.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xyz.vallat.louis.database.DBManager; @@ -11,13 +12,22 @@ public class MoviesQuoteBot { public static final String PREFIX = "!"; public static final String NAME = "Movies Quote Bot"; public static final String DESCRIPTION = "I may know quotes from movies."; - public static final String VERSION = "0.3.7-SNAPSHOT"; + public static final String VERSION = "0.3.8-SNAPSHOT"; private static final Logger logger = LoggerFactory.getLogger(MoviesQuoteBot.class.getCanonicalName()); + private static final Options options = new Options(); - public static void main(String[] args) { + static { + options.addOption(Option.builder().longOpt("reimport").build()); + } + + public static void main(String[] args) throws ParseException { + CommandLine cmd = new DefaultParser().parse(options, args); DBManager.testConnection(); DBManager.initDatabase(); OpenSubtitles.login(); + + if (cmd.hasOption("reimport")) reimportAllSubtitleLines(); + DiscordManager.login(); Runtime.getRuntime().addShutdownHook(new Thread(() -> { @@ -28,4 +38,16 @@ public class MoviesQuoteBot { DiscordManager.onDisconnect(); } + + public static void switchToMaintenanceMode() { + + } + + public static void switchToNormalOperations() { + + } + + private static void reimportAllSubtitleLines() { + DiscordManager.setOnMaintenanceMode(); + } } diff --git a/src/main/java/xyz/vallat/louis/codes/ExitCodes.java b/src/main/java/xyz/vallat/louis/codes/ExitCodes.java index 13626a8..6b364af 100644 --- a/src/main/java/xyz/vallat/louis/codes/ExitCodes.java +++ b/src/main/java/xyz/vallat/louis/codes/ExitCodes.java @@ -4,7 +4,9 @@ public enum ExitCodes { CANNOT_CONNECT_TO_DB(1), CANNOT_INITIALIZE_DB(2), CANNOT_INITIALIZE_LANGUAGES(3), - CANNOT_GET_PROPERTY(4); + CANNOT_GET_PROPERTY(4), + CANNOT_START_SOCKET_SERVER(5), + URGENT_EXIT_REQUIRED(6); private final int value; diff --git a/src/main/java/xyz/vallat/louis/discord/DiscordManager.java b/src/main/java/xyz/vallat/louis/discord/DiscordManager.java index 7f5b80f..6401923 100644 --- a/src/main/java/xyz/vallat/louis/discord/DiscordManager.java +++ b/src/main/java/xyz/vallat/louis/discord/DiscordManager.java @@ -46,7 +46,7 @@ public final class DiscordManager { private static void registerDiscordCommands() { for (Command command : commands) discordClient.getEventDispatcher().on(MessageCreateEvent.class) - .filter(event -> event.getMessage().getAuthor().map(user -> !user.isBot()).orElse(false)) + .filter(event -> !isInMaintenanceMode && event.getMessage().getAuthor().map(user -> !user.isBot()).orElse(false)) .filter(event -> event.getMessage().getContent().split(" ")[0].equals(command.getName())) .flatMap(event -> command.execute(event).then()) .subscribe(); @@ -61,7 +61,7 @@ public final class DiscordManager { } ).block(); assert discordClient != null; - discordClient.updatePresence(Presence.online(Activity.watching("more films"))).subscribe(); + setOnline(); discordClient.getEventDispatcher().on(ReadyEvent.class) .subscribe(event -> { User self = event.getSelf(); @@ -78,4 +78,12 @@ public final class DiscordManager { return discordClient.getGuilds().count(); } + public static void setOnline() { + if (discordClient != null) discordClient.updatePresence(Presence.online(Activity.watching("more films"))).subscribe(); + } + + public static void setOnMaintenanceMode() { + if (discordClient != null) discordClient.updatePresence(Presence.idle(Activity.playing("maintenance mode."))).subscribe(); + isInMaintenanceMode = true; + } } diff --git a/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java b/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java index 18165ef..0307aff 100644 --- a/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java +++ b/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java @@ -10,6 +10,7 @@ public enum EnvironmentVariables { OS_USERNAME("OPEN_SUBTITLES_USERNAME"), OS_PASSWORD("OPEN_SUBTITLES_PASSWORD"), OS_USER_AGENT("OPEN_SUBTITLES_USER_AGENT"), + SOCKET_PORT("SOCKET_PORT"), OMDB_API_KEY("OMDB_API_KEY"); private final String value; diff --git a/src/main/java/xyz/vallat/louis/sockets/Client.java b/src/main/java/xyz/vallat/louis/sockets/Client.java new file mode 100644 index 0000000..ce6da78 --- /dev/null +++ b/src/main/java/xyz/vallat/louis/sockets/Client.java @@ -0,0 +1,4 @@ +package xyz.vallat.louis.sockets; + +public class Client { +} diff --git a/src/main/java/xyz/vallat/louis/sockets/Server.java b/src/main/java/xyz/vallat/louis/sockets/Server.java new file mode 100644 index 0000000..2396cd2 --- /dev/null +++ b/src/main/java/xyz/vallat/louis/sockets/Server.java @@ -0,0 +1,70 @@ +package xyz.vallat.louis.sockets; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import xyz.vallat.louis.MoviesQuoteBot; +import xyz.vallat.louis.codes.ExitCodes; +import xyz.vallat.louis.env.EnvironmentVariables; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.ServerSocket; +import java.net.Socket; + +public class Server { + + public static final String KILL_SWITCH_FILE = "system_locked"; + private static final Logger logger = LoggerFactory.getLogger(Server.class.getCanonicalName()); + private static final int PORT; + + static { + int port = 8888; + try { + port = Integer.parseInt(EnvironmentVariables.SOCKET_PORT.getValue()); + } catch (NumberFormatException ignored) { + logger.warn("Port is not a valid numeric value. Using default one instead: '{}'.", port); + } + PORT = port; + } + + private Server() { + } + + public static void start() { + new Thread(() -> { + boolean everythingIsOkay = true; + while (everythingIsOkay) { + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + logger.info("Waiting for connections on port '{}'...", PORT); + Socket socket = serverSocket.accept(); + logger.info("Connected!"); + BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + String message = reader.readLine(); + logger.debug("Received message '{}'.", message); + if (message.equals(SocketsCommand.KILL_SWITCH_URGENT.getName())) everythingIsOkay = false; + else if (message.equals(SocketsCommand.MAINTENANCE_MODE_ON.getName())) + MoviesQuoteBot.switchToMaintenanceMode(); + else if (message.equals(SocketsCommand.MAINTENANCE_MODE_OFF.getName())) + MoviesQuoteBot.switchToNormalOperations(); + else logger.warn("Be careful, I received a message that I don't understand: '{}'.", message); + } catch (IOException e) { + everythingIsOkay = false; + logger.error("Cannot start socket server.", e); + logger.error("Exiting."); + System.exit(ExitCodes.CANNOT_START_SOCKET_SERVER.getValue()); + } + } + logger.error("Everything was not okay. Urgent exit required."); + try { + if (!new File(KILL_SWITCH_FILE).createNewFile()) + throw new IOException("File already existed apparently."); + } catch (IOException e) { + logger.error("Couldn't even create kill switch file... Exiting anyway.", e); + } + System.exit(ExitCodes.URGENT_EXIT_REQUIRED.getValue()); + }); + } + +} diff --git a/src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java b/src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java new file mode 100644 index 0000000..d10e382 --- /dev/null +++ b/src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java @@ -0,0 +1,17 @@ +package xyz.vallat.louis.sockets; + +public enum SocketsCommand { + MAINTENANCE_MODE_ON("maintenance_engaged"), + MAINTENANCE_MODE_OFF("maintenance_disengaged"), + KILL_SWITCH_URGENT("big_red_button_pressed"); + + private final String name; + + SocketsCommand(String name) { + this.name = name; + } + + public String getName() { + return name; + } +}