diff --git a/build.gradle b/build.gradle index 7936863..0a9199b 100644 --- a/build.gradle +++ b/build.gradle @@ -28,11 +28,14 @@ application { dependencies { - implementation "net.dv8tion:JDA:5.0.1" + implementation "net.dv8tion:JDA:5.2.3" implementation 'org.jsoup:jsoup:1.15.3' implementation 'com.google.code.gson:gson:2.8.9' implementation 'org.xerial:sqlite-jdbc:3.41.2.2' implementation 'org.json:json:20231013' + implementation 'com.mysql:mysql-connector-j:9.2.0' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.0.1' + implementation "ch.qos.logback:logback-classic:1.5.6" diff --git a/src/main/java/de/ocame/ffdiscordbot/ConfigLoader.java b/src/main/java/de/ocame/ffdiscordbot/ConfigLoader.java index 2cb5a2c..52ce4b9 100644 --- a/src/main/java/de/ocame/ffdiscordbot/ConfigLoader.java +++ b/src/main/java/de/ocame/ffdiscordbot/ConfigLoader.java @@ -38,4 +38,28 @@ public class ConfigLoader { return Long.parseLong(properties.getProperty("debug.Channel")); } + public boolean getFFActive() { + return Boolean.parseBoolean(properties.getProperty("ff.active", "true")); + } + + public String getMySQLHost() { + return properties.getProperty("mysql.host", "localhost"); + } + + public String getMySQLPort() { + return properties.getProperty("mysql.port", "3306"); + } + + public String getMySQLUsername() { + return properties.getProperty("mysql.username", ""); + } + + public String getMySQLPassword() { + return properties.getProperty("mysql.password", ""); + } + + public String getMySQLDatabase() { + return properties.getProperty("mysql.database", "fuchsbot"); + } + } diff --git a/src/main/java/de/ocame/ffdiscordbot/FanFiktionReader.java b/src/main/java/de/ocame/ffdiscordbot/FanFiktionReader.java index 5383b30..27d0a3e 100644 --- a/src/main/java/de/ocame/ffdiscordbot/FanFiktionReader.java +++ b/src/main/java/de/ocame/ffdiscordbot/FanFiktionReader.java @@ -48,6 +48,11 @@ public class FanFiktionReader { try { LoggerUtil.log("info", "Reader", "Beginn Check Alerts"); + ConfigLoader configLoader = new ConfigLoader(); + if(!configLoader.getFFActive()) { + LoggerUtil.log("info", "Reader", "Check ist aus"); + return; + } Document alertPage = fetchHTMLWithAuthentication(URL + "/?a=i"); if (alertPage == null) { LoggerUtil.log("info", "Reader", "Keine Seite gefunden"); @@ -156,7 +161,7 @@ public class FanFiktionReader { public void checkNewChapter(String url, long chapterDate, boolean force) { try { - LoggerUtil.log("info", "Reader", "Check neue Kapitel"); + LoggerUtil.log("info", "Reader", "Check neue Kapitel " + url); Document storyPage = fetchHTMLWithAuthentication(url); if (storyPage == null) return; @@ -182,7 +187,7 @@ public class FanFiktionReader { // Die gefundene Nummernfolge ausgeben ffid = matcher.group(1); } else { - // todo: fehler behandlung + LoggerUtil.log("error", "Reader", "Fehler beim finden der Chapter Nr"); } if (!SQLiteStorage.checkChapter(ffid, Long.parseLong(chapterNumer)) || force) { @@ -199,6 +204,7 @@ public class FanFiktionReader { } } } catch (IOException | InterruptedException e) { + LoggerUtil.log("error", "Reader", "Fehler beim Kapitel Auslesen " + e.getMessage()); e.printStackTrace(); } } @@ -209,6 +215,7 @@ public class FanFiktionReader { * @param storyPage */ public void readandSaveStory(Document storyPage) { + LoggerUtil.log("info", "Reader", "Beginn Story Infos lesen"); Elements infoBox = storyPage.select(".story-left"); String storyName = infoBox.first().getElementsByTag("h4").text(); String storyAutor = infoBox.select("a.no-wrap").first().text(); @@ -302,7 +309,7 @@ public class FanFiktionReader { if (nameBox.isEmpty()) { time += 2 * 60 * 60; // Zeit um 2h erhöhen new InfoNotifier(jda).setMessagetext("Login Fehlgeschlagen").sendOutput(); - LoggerUtil.log("info", "Reader", "Login Fehlgeschlagen"); + LoggerUtil.log("error", "Reader", "Login Fehlgeschlagen"); } Elements aBox = logintPage.select("input[name='a']"); @@ -326,7 +333,7 @@ public class FanFiktionReader { if (!nameBox.isEmpty()) { time += 2 * 60 * 60; // Zeit um 2h erhöhen new InfoNotifier(jda).setMessagetext("Login Fehlgeschlagen").sendOutput(); - LoggerUtil.log("info", "Reader", "Login Fehlgeschlagen"); + LoggerUtil.log("error", "Reader", "Login Fehlgeschlagen"); } } catch (IOException | InterruptedException e) { @@ -370,7 +377,7 @@ public class FanFiktionReader { try { Document sendToFav = fetcher.fetchHtml(URL + "/?a=q&a1=v&t=addstory&lbi=popup-addtofav-body&ar=1&action=i", postData); if(sendToFav.getElementsByClass("successbox").isEmpty()) { - LoggerUtil.log("info", "Reader", "Story konnte nicht hinzugefügt werden"); + LoggerUtil.log("error", "Reader", "Story konnte nicht hinzugefügt werden"); new InfoNotifier(jda).setMessagetext("Story " + ffid + "konnte nicht hinzugefügt werden. \n" + sendToFav.toString()).sendOutput(); } } diff --git a/src/main/java/de/ocame/ffdiscordbot/Main.java b/src/main/java/de/ocame/ffdiscordbot/Main.java index 5c66d32..325596c 100644 --- a/src/main/java/de/ocame/ffdiscordbot/Main.java +++ b/src/main/java/de/ocame/ffdiscordbot/Main.java @@ -1,5 +1,6 @@ package de.ocame.ffdiscordbot; +import de.ocame.ffdiscordbot.achievements.ChatReader; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.OnlineStatus; @@ -25,6 +26,7 @@ public class Main { .setActivity(Activity.playing("mit der Marine fangen")) .setStatus(OnlineStatus.ONLINE) .setAutoReconnect(true) + .addEventListeners(new ChatReader()) .build();/**/ try { @@ -54,7 +56,7 @@ public class Main { delay[0] = ffr.getTime(); - LoggerUtil.log("info", "Main", "neue Zeit: " + Long.toString(delay[0])); + LoggerUtil.log("info", "Main", "neue Zeit: " + (Long.toString(Math.round(delay[0] / 60 * 10)/10) )); // Plane die Aufgabe erneut mit dem neuen Intervall scheduledFuture.get().cancel(false); diff --git a/src/main/java/de/ocame/ffdiscordbot/achievements/AchievementManager.java b/src/main/java/de/ocame/ffdiscordbot/achievements/AchievementManager.java new file mode 100644 index 0000000..0be4d87 --- /dev/null +++ b/src/main/java/de/ocame/ffdiscordbot/achievements/AchievementManager.java @@ -0,0 +1,168 @@ +package de.ocame.ffdiscordbot.achievements; + +import net.dv8tion.jda.api.entities.Message; + +import java.io.IOException; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.List; + +public class AchievementManager { + + /* + X Nachrichten Erstellt + X Emojis benutzt + Bestimmte Emojis benutzt / Emojis Kombination z.b. Crewmitglied + X Gifs benuzt + Selbstverliebt - eigene Nachricht Reaction + X Antworten + X Threads erstellt + Brüllaffe - in Capsschreiben + Korrektur - Nachricht bearbeiten + Zeit abhänige Nachrichten z.b. Früher Vogel zwichen 5 - 8 Uhr + + */ + + private DataAchievement user; + + public void AnalyseMessage(String userId, String message, OffsetDateTime timestamp) { + user = MySQLStorage.loadAchievementByUserId(userId); + AnalyseMessageBody(message); + MySQLStorage.saveAchievement(user); + } + + public void AnalyseMessage(Message message) { + user = MySQLStorage.loadAchievementByUserId(message.getAuthor().getId()); + + AnalyseMessageBody(message.getContentRaw().trim()); + + if (!message.getStickers().isEmpty()) { // Stickers gefunden + user.increseStickerCount(); + } + MySQLStorage.saveAchievement(user); + + } + + private void AnalyseMessageBody(String message) { + try { + if (!message.isEmpty()) { + // Nachrichtern Zähler + user.increseMessageCount(); + + // Wurden Emoji Benutzt? + Pattern pattern = Pattern.compile("<:[a-zA-Z0-9_]+:"); + Matcher matcher = pattern.matcher(message); + while (matcher.find()) { + user.increseEmojiCount(); + } + + // Crew Emojis Erkennen + pattern = Pattern.compile("<:BJEMOTE([^:]+):"); + matcher = pattern.matcher(message); + + ObjectMapper objectMapper = new ObjectMapper(); + List userCrews = new ArrayList<>(); + try { + userCrews = objectMapper.readValue(user.getCrewEmoji(), new TypeReference>() {}); + } catch (IOException e) { + userCrews = new ArrayList<>(); + } + + + while (matcher.find()) { + String emoteName = matcher.group(1); // Alles nach BJEMOTE extrahieren + + // Prüfen ob es ein Crew Emote ist + String crewName = CheckCrewEmojis(emoteName); + if (!crewName.isEmpty()) { + user.increseCrewEmojiCount(); + if (!userCrews.contains(crewName)) + userCrews.add(crewName); + } + + // Prüfen ob es ein Herz Emote ist + if(emoteName.startsWith("Herz")) { + // Fehlt noch + } + } + user.setCrewEmoji(objectMapper.writeValueAsString(userCrews)); + } + + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + private String CheckCrewEmojis(String emoji) { + switch (emoji) { + case "AAAmauryDetektiv": + case "AAAmauryEkel": + return "Amaury"; + + case "AAAnnaugenrollen": + case "AAAnnpfeifen": + return "Ann"; + + case "AAErikaNachdenken": + case "AAErikaSalutieren": + return "Erika"; + + + case "AAFersynthDOWN": + case "AAFersynthWeinen": + return "Fersynth"; + + + case "AAFin": + return "Fin"; + + case "AAHaileBlush": + case "AAHaileSauer": + return "Haile"; + + case "AAHarlowSchelmisch": + case "AAHarlowSleepy": + return "Harlow"; + + case "AAHokulaniAufgeregt": + case "AAHokulaniSchmolli": + return "Hokulani"; + + case "AAJacquesHerz": + case "AAJacquesLecker": + return "Jacques"; + + case "AAKeakaPssst": + case "AAKeakagerhrt": + return "Keaka"; + + case "AALunaBlushHappy": + case "AALunaVerstecken": + return "Luna"; + + case "AANoahSchock": + case "AANoahSkeptisch": + return "Noah"; + + case "AARasmusFlirty": + case "AARasmusLachen": + return "Rasmus"; + + case "AASeymourVerwirrt": + return "Seymour"; + + case "AASilverFacepalm": + case "AASilverGenervt": + return "Silver"; + } + return ""; + } +} diff --git a/src/main/java/de/ocame/ffdiscordbot/achievements/ChatReader.java b/src/main/java/de/ocame/ffdiscordbot/achievements/ChatReader.java new file mode 100644 index 0000000..8a26534 --- /dev/null +++ b/src/main/java/de/ocame/ffdiscordbot/achievements/ChatReader.java @@ -0,0 +1,199 @@ +package de.ocame.ffdiscordbot.achievements; + +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageReaction; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.events.message.MessageUpdateEvent; +import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.requests.RestAction; + +import java.io.FileWriter; +import java.io.IOException; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.CompletableFuture; + + +public class ChatReader extends ListenerAdapter { + + RestAction latestUpdate = null; + private Set ChannelWhitelist; + + public ChatReader() { + ChannelWhitelist = new HashSet<>(); + ChannelWhitelist.add("1203755455638409297"); // Testserver tetx + ChannelWhitelist.add("1082725289387376721"); // Kombüse + ChannelWhitelist.add("836378236974792756"); // Plauderecke + new MySQLStorage(); + } + + @Override + public void onMessageReceived(MessageReceivedEvent event) { + if(event.getAuthor().isBot()) + return; + if(!ChannelWhitelist.contains(event.getChannel().getId()) || !event.getMessage().getType().equals("DEFAULT")) { + return; + } + String content = event.getMessage().getContentRaw(); + + new AchievementManager().AnalyseMessage(event.getMessage()); + + if (content.equals("Save Conversation")) { + handleSaveConversation(event); + } + } + + @Override + public void onMessageUpdate(MessageUpdateEvent event) { + if(event.getAuthor().isBot()) + return; + if(!ChannelWhitelist.contains(event.getChannel().getId())) { + return; + } + System.out.println(event.getMessage().getContentDisplay()); + + } + + @Override + public void onMessageReactionAdd(MessageReactionAddEvent event) { + if(event.getUser().isBot()) + return; + if(!ChannelWhitelist.contains(event.getChannel().getId())) { + return; + } + System.out.println(event.getReaction().toString()); + } + + // ========================================================================================= + + private void handleSaveConversation(MessageReceivedEvent event) { + String fileName = event.getChannel().getName() + ".txt"; + String filePath = "./" + fileName; + + int MAX_DESIRED = 10000; + List messages = new ArrayList<>(); + + // Fortschrittsnachricht senden + Message progressMessage; + try { + progressMessage = event.getChannel() + .sendMessage(getProgressInfo(filePath, 0)) + .complete(); + } catch (Exception e) { + event.getChannel().sendMessage("Failed to save messages: " + e.getMessage()).queue(); + e.printStackTrace(); + return; + } + + event.getChannel().getIterableHistory() + .forEachAsync(message -> { + messages.add(message); + System.out.println(message.getType().toString()); + handleProgressUpdate(progressMessage, filePath, messages.size()); + return messages.size() < MAX_DESIRED; + }) + .thenRun(() -> { + // Verarbeiten der gesammelten Nachrichten + saveMessagesToFile(event, filePath, messages, progressMessage); + }) + .exceptionally(error -> { + event.getChannel().sendMessage("Failed to fetch messages: " + error.getMessage()).queue(); + error.printStackTrace(); + return null; + }); + } + + private void handleProgressUpdate(Message progressMessage, String filePath, int totalMessages) { + RestAction action = progressMessage.editMessage(getProgressInfo(filePath, totalMessages)); + latestUpdate = action; + + action.setCheck(() -> { + // Only send out the latest progress update. + return action == latestUpdate; + }); + //Submit is similar to .queue(...), but gives easier access to a "finally" like method. + action.submit().whenComplete((_ignored, _ignored2) -> { + // Clear the latest update if we just sent it. + if (latestUpdate == action) { + latestUpdate = null; + } + }); + } + + + private String getProgressInfo(String filePath, int totalMessages) { + String message = ""; + message += "Processing conversation to file:\n"; + message += "`" + filePath + "`\n\n"; + message += "Total messages retrieved thus far: " + totalMessages; + + return message; + } + + + private void saveMessagesToFile(MessageReceivedEvent event, String filePath, List messages, Message progressMessage) { + try (FileWriter fileWriter = new FileWriter(filePath)) { + Collections.reverse(messages); + for (Message message : messages) { + writeMessageToFile(fileWriter, message); + } + event.getChannel().sendMessage("Conversation was successfully saved").queue(); + } catch (IOException e) { + event.getChannel().sendMessage("Failed to save messages: " + e.getMessage()).queue(); + e.printStackTrace(); + } finally { + if (progressMessage != null) { + progressMessage.delete().queue(); + } + } + } + + private void writeMessageToFile(FileWriter fileWriter, Message message) { + try { + fileWriter.write("Time: " + message.getTimeCreated().toString() + "\n"); + fileWriter.write("Author: " + message.getAuthor().getId() + "\n"); + fileWriter.write("Message ID: " + message.getId() + "\n"); + fileWriter.write("Content: " + message.getContentRaw() + "\n"); + + if (!message.getReactions().isEmpty()) { + List> reactionFutures = new ArrayList<>(); + + for (MessageReaction reaction : message.getReactions()) { + String emojiName = reaction.getEmoji().getName(); + + // Erstelle eine Future für jede Reaktion + CompletableFuture reactionFuture = new CompletableFuture<>(); + reaction.retrieveUsers().queue(users -> { + StringBuilder reactionUsers = new StringBuilder(); + for (User user : users) { + if (reactionUsers.length() > 0) reactionUsers.append("|"); + reactionUsers.append(user.getId()); + } + reactionFuture.complete("Reaction: " + emojiName + ": " + reactionUsers + "\n"); + }, reactionFuture::completeExceptionally); + + reactionFutures.add(reactionFuture); + } + + // Auf alle Futures warten und die Ergebnisse schreiben + CompletableFuture.allOf(reactionFutures.toArray(new CompletableFuture[0])) + .thenAccept(v -> { + for (CompletableFuture future : reactionFutures) { + try { + fileWriter.write(future.join()); // Schreibe die Ergebnisse + } catch (IOException e) { + e.printStackTrace(); + } + } + }).join(); // Warten, bis alle Futures abgeschlossen sind + } + + fileWriter.write("\n\n"); + } catch (IOException e) { + throw new RuntimeException("Error writing message to file: " + e.getMessage(), e); + } + } + +} diff --git a/src/main/java/de/ocame/ffdiscordbot/achievements/DataAchievement.java b/src/main/java/de/ocame/ffdiscordbot/achievements/DataAchievement.java new file mode 100644 index 0000000..0fc9994 --- /dev/null +++ b/src/main/java/de/ocame/ffdiscordbot/achievements/DataAchievement.java @@ -0,0 +1,234 @@ +package de.ocame.ffdiscordbot.achievements; +import java.sql.Timestamp; + +public class DataAchievement { + private String userId; + private String username; + private Timestamp createDate; + + private int messageCount; + private int reactionCount; + private int gifCount; + private int replayCount; + private int stickerCount; + private int editCount; + private int foxEmojiCount; + private int crewEmojiCount; + private int emojiCount; + + private String crewEmoji; + private boolean crewEmojiFlag; + private boolean isNarcissistic; + private boolean isLoud; + private boolean isEarlyBird; + private boolean isNightOwl; + + // Konstruktor + public DataAchievement() {} + + public DataAchievement(String userId, String username, Timestamp createDate, + int messageCount, int reactionCount, int gifCount, int replayCount, + int stickerCount, int editCount, int foxEmojiCount, int crewEmojiCount, int emojiCount, + String crewEmoji, boolean crewEmojiFlag, boolean isNarcissistic, + boolean isLoud, boolean isEarlyBird, boolean isNightOwl) { + this.userId = userId; + this.username = username; + this.createDate = createDate; + this.messageCount = messageCount; + this.reactionCount = reactionCount; + this.gifCount = gifCount; + this.replayCount = replayCount; + this.stickerCount = stickerCount; + this.editCount = editCount; + this.foxEmojiCount = foxEmojiCount; + this.crewEmojiCount = crewEmojiCount; + this.emojiCount = emojiCount; + this.crewEmoji = crewEmoji; + this.crewEmojiFlag = crewEmojiFlag; + this.isNarcissistic = isNarcissistic; + this.isLoud = isLoud; + this.isEarlyBird = isEarlyBird; + this.isNightOwl = isNightOwl; + } + + // Getter & Setter + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public int getMessageCount() { + return messageCount; + } + + public void setMessageCount(int messageCount) { + this.messageCount = messageCount; + } + + public int getReactionCount() { + return reactionCount; + } + + public void setReactionCount(int reactionCount) { + this.reactionCount = reactionCount; + } + + public int getGifCount() { + return gifCount; + } + + public void setGifCount(int gifCount) { + this.gifCount = gifCount; + } + + public int getReplayCount() { + return replayCount; + } + + public void setReplayCount(int replayCount) { + this.replayCount = replayCount; + } + + public int getStickerCount() { + return stickerCount; + } + + public void setStickerCount(int stickerCount) { + this.stickerCount = stickerCount; + } + + public int getEditCount() { + return editCount; + } + + public void setEditCount(int editCount) { + this.editCount = editCount; + } + + public int getFoxEmojiCount() { + return foxEmojiCount; + } + + public void setFoxEmojiCount(int foxEmojiCount) { + this.foxEmojiCount = foxEmojiCount; + } + + public int getCrewEmojiCount() { + return crewEmojiCount; + } + + public void setCrewEmojiCount(int crewEmojiCount) { + this.crewEmojiCount = crewEmojiCount; + } + + public String getCrewEmoji() { + return crewEmoji; + } + + public void setCrewEmoji(String crewEmoji) { + this.crewEmoji = crewEmoji; + } + + public boolean isCrewEmojiFlag() { + return crewEmojiFlag; + } + + public void setCrewEmojiFlag(boolean crewEmojiFlag) { + this.crewEmojiFlag = crewEmojiFlag; + } + + public boolean isNarcissistic() { + return isNarcissistic; + } + + public void setNarcissistic(boolean narcissistic) { + isNarcissistic = narcissistic; + } + + public boolean isLoud() { + return isLoud; + } + + public void setLoud(boolean loud) { + isLoud = loud; + } + + public boolean isEarlyBird() { + return isEarlyBird; + } + + public void setEarlyBird(boolean earlyBird) { + isEarlyBird = earlyBird; + } + + public boolean isNightOwl() { + return isNightOwl; + } + + public void setNightOwl(boolean nightOwl) { + isNightOwl = nightOwl; + } + + public int getEmojiCount() { + return emojiCount; + } + + public void setEmojiCount(int emojiCount) { + this.emojiCount = emojiCount; + } + + public void increseMessageCount() { + messageCount++; + } + + public void increseReactionCount() { + reactionCount++; + } + public void increseGifCount() { + gifCount++; + } + + public void increseReplayCount() { + replayCount++; + } + + public void increseStickerCount() { + stickerCount++; + } + + public void increseEditCount() { + editCount++; + } + + public void increseFoxEmojiCount() { + foxEmojiCount++; + } + + public void increseCrewEmojiCount() { + crewEmojiCount++; + } + + public void increseEmojiCount() { + emojiCount++; + } + +} diff --git a/src/main/java/de/ocame/ffdiscordbot/achievements/MySQLStorage.java b/src/main/java/de/ocame/ffdiscordbot/achievements/MySQLStorage.java new file mode 100644 index 0000000..1f77983 --- /dev/null +++ b/src/main/java/de/ocame/ffdiscordbot/achievements/MySQLStorage.java @@ -0,0 +1,198 @@ +package de.ocame.ffdiscordbot.achievements; + +import de.ocame.ffdiscordbot.ConfigLoader; +import de.ocame.ffdiscordbot.LoggerUtil; + +import java.sql.*; + +public class MySQLStorage { + + // Konstruktor, um ConfigLoader zu initialisieren + public MySQLStorage() { + this.checkAndCreateAchievementTable(); + } + + // Methode, die eine MySQL-Verbindung herstellt + public static Connection getConnection() { + Connection connection = null; + ConfigLoader configLoader = new ConfigLoader(); + + try { + // Konfigurationswerte abrufen + String host = configLoader.getMySQLHost(); + String port = configLoader.getMySQLPort(); // Beispiel: "3306" + String database = configLoader.getMySQLDatabase(); + String username = configLoader.getMySQLUsername(); + String password = configLoader.getMySQLPassword(); + + // Verbindung erstellen + String url = "jdbc:mysql://" + host + ":" + port + "/" + database + "?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"; + connection = DriverManager.getConnection(url, username, password); + System.out.println("Erfolgreich mit der Datenbank verbunden!"); + LoggerUtil.log("info", "MySQL", "Erfolgreich mit der Datenbank verbunden!"); + + } catch (SQLException e) { + LoggerUtil.log("error", "MySQL", "Fehler beim Herstellen der Verbindung zur MySQL-Datenbank: " + e.getMessage()); + e.printStackTrace(); + } + + return connection; + } + + public void checkAndCreateAchievementTable() { + try (Connection connection = getConnection(); Statement statement = connection.createStatement()) { + // Prüfen, ob die Tabelle bereits existiert + String checkTableQuery = "SHOW TABLES LIKE 'Achievement'"; + try (ResultSet resultSet = statement.executeQuery(checkTableQuery)) { + if (resultSet.next()) { + //System.out.println("Tabelle 'Achievement' existiert bereits."); + return; + } + } + + // Tabelle erstellen, falls sie nicht existiert + String createTableQuery = """ + CREATE TABLE Achievement ( + userId VARCHAR(255) NOT NULL, + username VARCHAR(255), + createDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + + messageCount INT DEFAULT 0, + reactionCount INT DEFAULT 0, + gifCount INT DEFAULT 0, + replayCount INT DEFAULT 0, + stickerCount INT DEFAULT 0, + editCount INT DEFAULT 0, + foxEmojiCount INT DEFAULT 0, + crewEmojiCount INT DEFAULT 0, + emojiCount INT DEFAULT 0, + + crewEmoji VARCHAR(255) NOT NULL DEFAULT "", + crewEmojiFlag TINYINT(1) DEFAULT 0, + isNarcissistic TINYINT(1) DEFAULT 0, + isLoud TINYINT(1) DEFAULT 0, + isEarlyBird TINYINT(1) DEFAULT 0, + isNightOwl TINYINT(1) DEFAULT 0, + + PRIMARY KEY (userId) + ) + """; + statement.executeUpdate(createTableQuery); + LoggerUtil.log("info", "MySQL", "Tabelle 'Achievement' wurde erfolgreich erstellt."); + } catch (SQLException e) { + LoggerUtil.log("error", "MySQL", "Fehler beim Erstellen der Tabelle 'Achievement':" + e.getMessage()); + e.printStackTrace(); + } + } + + + public static void saveAchievement(DataAchievement achievement) { + + String sql = """ + INSERT INTO Achievement (userId, username, messageCount, reactionCount, gifCount, replayCount, + stickerCount, editCount, foxEmojiCount, crewEmojiCount, emojiCount, crewEmoji, crewEmojiFlag, + isNarcissistic, isLoud, isEarlyBird, isNightOwl) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE + username = VALUES(username), + messageCount = VALUES(messageCount), + reactionCount = VALUES(reactionCount), + gifCount = VALUES(gifCount), + replayCount = VALUES(replayCount), + stickerCount = VALUES(stickerCount), + editCount = VALUES(editCount), + foxEmojiCount = VALUES(foxEmojiCount), + crewEmojiCount = VALUES(crewEmojiCount), + emojiCount = VALUES(emojiCount), + crewEmoji = VALUES(crewEmoji), + crewEmojiFlag = VALUES(crewEmojiFlag), + isNarcissistic = VALUES(isNarcissistic), + isLoud = VALUES(isLoud), + isEarlyBird = VALUES(isEarlyBird), + isNightOwl = VALUES(isNightOwl) + """; + try (Connection connection = getConnection(); PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, achievement.getUserId()); + stmt.setString(2, achievement.getUsername()); + stmt.setInt(3, achievement.getMessageCount()); + stmt.setInt(4, achievement.getReactionCount()); + stmt.setInt(5, achievement.getGifCount()); + stmt.setInt(6, achievement.getReplayCount()); + stmt.setInt(7, achievement.getStickerCount()); + stmt.setInt(8, achievement.getEditCount()); + stmt.setInt(9, achievement.getFoxEmojiCount()); + stmt.setInt(10, achievement.getCrewEmojiCount()); + stmt.setInt(11, achievement.getEmojiCount()); + stmt.setString(12, achievement.getCrewEmoji()); + stmt.setBoolean(13, achievement.isCrewEmojiFlag()); + stmt.setBoolean(14, achievement.isNarcissistic()); + stmt.setBoolean(15, achievement.isLoud()); + stmt.setBoolean(16, achievement.isEarlyBird()); + stmt.setBoolean(17, achievement.isNightOwl()); + + stmt.executeUpdate(); + + } catch (SQLException e) { + LoggerUtil.log("error", "MySQL", "Fehler beim Erstellen der Tabelle 'Achievement':" + e.getMessage()); + e.printStackTrace(); + } + } + + public static void addUsers(String userId) { + + String sql = """ + INSERT INTO Achievement (userId) + VALUES (?) + ON DUPLICATE KEY UPDATE + username = VALUES(username); + """; + try (Connection connection = getConnection(); PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, userId); + stmt.executeUpdate(); + + } catch (SQLException e) { + LoggerUtil.log("error", "MySQL", "Fehler beim Erstellen des Users Tabelle 'Achievement':" + e.getMessage()); + e.printStackTrace(); + } + } + + public static DataAchievement loadAchievementByUserId(String userId) { + String sql = "SELECT * FROM Achievement WHERE userId = ?"; + try (Connection connection = getConnection(); PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, userId); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + return new DataAchievement( + rs.getString("userId"), + rs.getString("username"), + rs.getTimestamp("createDate"), + rs.getInt("messageCount"), + rs.getInt("reactionCount"), + rs.getInt("gifCount"), + rs.getInt("replayCount"), + rs.getInt("stickerCount"), + rs.getInt("editCount"), + rs.getInt("foxEmojiCount"), + rs.getInt("crewEmojiCount"), + rs.getInt("emojiCount"), + rs.getString("crewEmoji"), + rs.getBoolean("crewEmojiFlag"), + rs.getBoolean("isNarcissistic"), + rs.getBoolean("isLoud"), + rs.getBoolean("isEarlyBird"), + rs.getBoolean("isNightOwl") + ); + } + else { + addUsers(userId); + return loadAchievementByUserId(userId); + } + } + } catch (SQLException e) { + LoggerUtil.log("error", "MySQL", "Fehler beim Erstellen der Tabelle 'Achievement':" + e.getMessage()); + e.printStackTrace(); + } + return new DataAchievement(); // Falls kein Datensatz gefunden wurde + } + +} diff --git a/src/main/java/de/ocame/ffdiscordbot/output/BaseNotifier.java b/src/main/java/de/ocame/ffdiscordbot/output/BaseNotifier.java index 94b516e..2ed30c9 100644 --- a/src/main/java/de/ocame/ffdiscordbot/output/BaseNotifier.java +++ b/src/main/java/de/ocame/ffdiscordbot/output/BaseNotifier.java @@ -1,6 +1,7 @@ package de.ocame.ffdiscordbot.output; import de.ocame.ffdiscordbot.DataStory; +import de.ocame.ffdiscordbot.LoggerUtil; import de.ocame.ffdiscordbot.OutputContentElement; import de.ocame.ffdiscordbot.SQLiteStorage; import net.dv8tion.jda.api.EmbedBuilder; @@ -38,7 +39,12 @@ public abstract class BaseNotifier > { } public void sendOutput() { + LoggerUtil.log("info", "BaseNotifier", "neues Output"); EmbedBuilder outputBox = createEmbed(); + if(outputBox == null) { + LoggerUtil.log("info", "BaseNotifier", "keine Output Daten gefunden"); + return; + } Long[] channelIds = SQLiteStorage.getChannelIds(); if(targetChannel != null) { Objects.requireNonNull(jda.getTextChannelById(targetChannel)) @@ -57,7 +63,7 @@ public abstract class BaseNotifier > { Objects.requireNonNull(jda.getTextChannelById(channelId)).sendMessageEmbeds(outputBox.build()).queue(); } catch (NullPointerException e) { - // + LoggerUtil.log("error", "BaseNotifier", "keine Rechte zu senden in " + channelId); } } } @@ -76,6 +82,10 @@ public abstract class BaseNotifier > { protected EmbedBuilder createEmbed() { EmbedBuilder outputBox = new EmbedBuilder(); OutputContentElement outputContentElement = getOCE(); + if(outputContentElement == null) { + LoggerUtil.log("info", "BaseNotifier", "keine Story Verbindung gefunden"); + return null; + } // Titel und Link von der spezifischen Implementierung holen outputBox.setTitle(getEmbedTitle(), getLink()) diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 8cc54a9..a614181 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - %d{HH:mm:ss.SSS} %boldCyan(%-34.-34thread) %red(%10.10X{jda.shard}) %boldGreen(%-15.-15logger{0}) %highlight(%-6level) %msg%n + %d{dd.MM.YY HH:mm:ss.SSS} %boldCyan(%-34.-34thread) %red(%10.10X{jda.shard}) %boldGreen(%-15.-15logger{0}) %highlight(%-6level) %msg%n