Init
This commit is contained in:
45
build.gradle
Normal file
45
build.gradle
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
plugins {
|
||||||
|
id 'application'
|
||||||
|
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||||
|
}
|
||||||
|
|
||||||
|
application.mainClass = "de.ocame.ffdiscordbot.Main"
|
||||||
|
group 'de.ocame'
|
||||||
|
version '1.1-SNAPSHOT'
|
||||||
|
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sourceCompatibility = '17'
|
||||||
|
targetCompatibility = '17'
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
application {
|
||||||
|
mainModule = 'de.ocame.ffdiscordbot'
|
||||||
|
mainClass = 'de.ocame.ffdiscordbot.Main'
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "net.dv8tion:JDA:5.0.1"
|
||||||
|
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 "ch.qos.logback:logback-classic:1.5.6"
|
||||||
|
// compile "org.json:json:20141113"
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
32
src/main/java/de/ocame/ffdiscordbot/ConfigLoader.java
Normal file
32
src/main/java/de/ocame/ffdiscordbot/ConfigLoader.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class ConfigLoader {
|
||||||
|
|
||||||
|
private final Properties properties;
|
||||||
|
|
||||||
|
public ConfigLoader() {
|
||||||
|
properties = new Properties();
|
||||||
|
try (FileInputStream input = new FileInputStream("ffBot.conf")) {
|
||||||
|
properties.load(input);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Konfigurationsdatei konnte nicht geladen werden: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return properties.getProperty("api.token");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return properties.getProperty("ff.username");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return properties.getProperty("ff.password");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
242
src/main/java/de/ocame/ffdiscordbot/DiscordOutput.java
Normal file
242
src/main/java/de/ocame/ffdiscordbot/DiscordOutput.java
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class DiscordOutput {
|
||||||
|
|
||||||
|
private final List<StoryOutputText> chapterText;
|
||||||
|
public DiscordOutput() {
|
||||||
|
|
||||||
|
chapterText = new ArrayList<>();
|
||||||
|
chapterText.add(new StoryOutputText(
|
||||||
|
"Oh, wie mein Herz singt! **%autor%** hat ein neues Kapitel unserer Geschichte \"**%storyName%**\" geschrieben, " +
|
||||||
|
"und es heißt \"**%chapterName%**\". \n\nIch spüre die Aufregung in der Luft, als ob jeder Flügelschlag mich höher trägt. " +
|
||||||
|
"Die Welt leuchtet in neuen Farben, und jeder Sonnenstrahl erzählt von Abenteuern, die uns erwarten. Dieses Kapitel " +
|
||||||
|
"verspricht so viel – ich kann es kaum erwarten, in die Worte zu tauchen und die Geschichten, die sie verbergen, " +
|
||||||
|
"zu entdecken!"
|
||||||
|
, "https://media.discordapp.net/stickers/1219043798101786624.webp?size=160"));
|
||||||
|
chapterText.add(new StoryOutputText(
|
||||||
|
"Aye, Text in Sicht, ihr Seeratten! **%autor%** hat ein neues Kapitel in der Geschichte \"**%storyName%**\" aufgetan, und " +
|
||||||
|
"es trägt den Namen \"**%chapterName%**\". Macht die Fässer klar, holt die besten Getränke, und besetzt die Bildschirme! \n" +
|
||||||
|
"Keiner rührt sich, bis wir jedes Wort gelesen haben, verstanden? Und hört gut hin: Wer es wagt, auch nur ein Wort " +
|
||||||
|
"zu spoilern, wird schneller gekielholt, als er \"Piratenkodex\" sagen kann! Jetzt aber volle Fahrt voraus – das " +
|
||||||
|
"Abenteuer ruft!", "https://cdn.discordapp.com/attachments/542202034330271759/1272999183673987133/image.png?ex=66bd0460&is=66bbb2e0&hm=708f10708d0616ed212d0c288cfde503fb27785ddd68c1ba30bb4d3f7698acee&"));
|
||||||
|
chapterText.add(new StoryOutputText(
|
||||||
|
"Mesdames et Messieurs, heute habe ich die Ehre, Ihnen ein exquisites Gericht zu präsentieren: " +
|
||||||
|
"das \"**%chapterName%**\" à la \"**%storyName%**\", nach der feinen Art unseres geschätzten Chef-Autors \"**%autor%**\". \n" +
|
||||||
|
"Es ist ein Meisterwerk der literarischen Küche, perfekt gewürzt mit Spannung und serviert mit einer Prise Abenteuer. " +
|
||||||
|
"Lassen Sie sich von den Aromen dieser neuen Geschichte verführen und genießen Sie jeden Bissen – bon appétit!",
|
||||||
|
"https://cdn.discordapp.com/attachments/542202034330271759/1272999507587629188/image.png?ex=66bd04ad&is=66bbb32d&hm=d4d7325f233c27a75305ee9622c9f87b03e1aa507acb534c2fd6c3de62d435d1&",
|
||||||
|
new Color(255, 0, 229)));
|
||||||
|
|
||||||
|
chapterText.add(new StoryOutputText(
|
||||||
|
"........................\n " +
|
||||||
|
"........................\n " +
|
||||||
|
"........................\n " +
|
||||||
|
"........................\n " +
|
||||||
|
"Na los, Grünschnabel, hör auf zu trödeln und lies endlich das neue Kapitel \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" " +
|
||||||
|
"vom \"**%autor%**\" vor! Meine Zeit ist nicht unendlich, und ich hab keine Lust, hier ewig zu warten. Also mach schon, bevor ich " +
|
||||||
|
"noch selbst anfangen muss, die Seiten zu ertasten!"
|
||||||
|
));
|
||||||
|
chapterText.add(new StoryOutputText(
|
||||||
|
"Das neue Kapitel \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" vom \"**%autor%**\" ist erschienen, und ich werde es als Erster lesen. " +
|
||||||
|
"Während die Piraten noch ihren Rum genießen, verschaffe ich mir den Wissensvorsprung. Mit jedem Satz, den ich lese, " +
|
||||||
|
"wird meine Strategie schärfer, und bald werde ich ihnen einen Schritt voraus sein. Ein kluger Kopf gewinnt schließlich immer " +
|
||||||
|
"das Spiel.",
|
||||||
|
"https://cdn.discordapp.com/attachments/542202034330271759/1273002039923965952/image.png?ex=66bd0709&is=66bbb589&hm=77130cbe420a9e941e58e68010c12cc2e53c54c288b8563fd6a1a856ffebd0df&"
|
||||||
|
));
|
||||||
|
|
||||||
|
chapterText.add(new StoryOutputText(
|
||||||
|
"hcilrütan ebah hci sad etseuen Letipak nohcs neseleg \n\n" +
|
||||||
|
"Erika Rückwerts die Worte auszuprechen ist kein Reptiloidisch!\n\n" +
|
||||||
|
"Menschen! Natürlich habe ich das neueste Kapitel schon gelesen. Kein Zweifel, es ist genauso grandios, " +
|
||||||
|
"wie ich es erwartet habe. Jede Wendung, jeder Dialog – einfach meisterhaft. Und falls du es wissen willst: Es handelt sich " +
|
||||||
|
"um \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" vom Autor \"**%autor%**\". Wenn du wirklich etwas Gutes lesen willst, dann ist das genau das " +
|
||||||
|
"Richtige für dich. Aber hey, das hab ich ja gleich gewusst.",
|
||||||
|
"https://cdn.discordapp.com/attachments/542202034330271759/1273005878974349313/image.png?ex=66bd0a9c&is=66bbb91c&hm=8e7701f259b7bd84ea3b91b5c8fb63c4b8807dd297a05fc9289aead8c1978fac&",
|
||||||
|
new Color(40, 145, 6)
|
||||||
|
));
|
||||||
|
chapterText.add(new StoryOutputText(
|
||||||
|
"Ah, wie wunderbar! Endlich halte ich das neue Kapitel \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" " +
|
||||||
|
"vom \"**%autor%**\" in den Händen. Ein wahres Vergnügen für den Geist! Und bitte, meine Lieben, lasst den Kronleuchter in Ruhe. " +
|
||||||
|
"Er spendet gerade das perfekte Licht zum Lesen – eine solch erhabene Lektüre verdient schließlich die besten Bedingungen."
|
||||||
|
));
|
||||||
|
chapterText.add(new StoryOutputText("Ich habe die Zukunft gesehen, und glaub mir, das neue Kapitel von \"**%chapterName%**\" aus der Geschichte " +
|
||||||
|
"\"**%storyName%**\" vom \"**%autor%**\" ist etwas ganz Besonderes. Es ist, als ob die Worte selbst eine Melodie singen, die so sanft und " +
|
||||||
|
"doch so kraftvoll ist, dass sie dich mitreißt, egal wohin sie dich führt. Jedes Wort, jede Zeile – sie fließen wie ein ruhiger " +
|
||||||
|
"Fluss, der dich in eine Welt entführt, die so fesselnd und lebendig ist, dass du alles um dich herum vergisst.\n" +
|
||||||
|
"\n" +
|
||||||
|
"Es ist wie der erste Schluck eines perfekt gebrühten Tees, dieser Moment, in dem sich die Wärme in deinem Körper ausbreitet " +
|
||||||
|
"und du spürst, wie jeder Tropfen dich beruhigt und gleichzeitig belebt. Ach, Tee... Was für ein wunderbares Getränk, nicht wahr? " +
|
||||||
|
"So viel Sorgfalt und Liebe steckt in jeder Tasse, genau wie in diesen Worten, die ich gerade gelesen habe. Die Teeblätter, " +
|
||||||
|
"die mit so viel Bedacht und Geduld gepflückt werden, erinnern mich an die frischen Pflanzen im Frühling, wenn alles grünt und blüht. " +
|
||||||
|
"Sie sind voller Leben, voller Möglichkeiten, genau wie die Geschichten, die uns erzählen, wohin unser Weg führen könnte.\n" +
|
||||||
|
"\n" +
|
||||||
|
"Wie wunderschön es doch ist, in solchen einfachen Freuden Trost zu finden – sei es in einem guten Buch, einer heißen Tasse Tee oder dem " +
|
||||||
|
"Anblick von Pflanzen, die in ihrer vollen Pracht stehen. Manchmal sind es gerade diese kleinen, stillen Momente, die das Leben wirklich " +
|
||||||
|
"lebenswert machen."));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void newChapter(JDA jda, DataChapter chapter, DataStory story) {
|
||||||
|
newChapter(jda, chapter, story, null, null);
|
||||||
|
}
|
||||||
|
public void newChapter(JDA jda, DataChapter chapter, DataStory story, Integer version, Long tagetChannel) {
|
||||||
|
try {
|
||||||
|
String message;
|
||||||
|
EmbedBuilder outputBox = new EmbedBuilder();
|
||||||
|
|
||||||
|
outputBox.setTitle("Neues Kapitel:", chapter.link());
|
||||||
|
|
||||||
|
List<StoryOutputText> chapterTexte;
|
||||||
|
if(version != null) {
|
||||||
|
chapterTexte = SQLiteStorage.getChapterTexte(version);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chapterTexte = SQLiteStorage.getChapterTexte(story);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StoryOutputText versionText = null;
|
||||||
|
if(chapterTexte.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
|
||||||
|
versionText = chapterTexte.get(random.nextInt(chapterTexte.size()));
|
||||||
|
|
||||||
|
message = versionText.getMessage();
|
||||||
|
|
||||||
|
message = message.replace("%chapterName%", "**" + chapter.name() + "**")
|
||||||
|
.replace("%storyName%", "**" + story.name() + "**")
|
||||||
|
.replace("%autor%", "**" + story.author() + "**");
|
||||||
|
|
||||||
|
|
||||||
|
outputBox.setDescription(message);
|
||||||
|
|
||||||
|
outputBox.setColor(versionText.getColor());
|
||||||
|
|
||||||
|
Instant instant = Instant.ofEpochSecond(chapter.date());
|
||||||
|
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Berlin"));
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy HH:mm 'Uhr'");
|
||||||
|
|
||||||
|
|
||||||
|
outputBox.setFooter("Veröffentlicht am " + dateTime.format(formatter));
|
||||||
|
if(versionText.getImage() != null && !Objects.equals(versionText.getImage(), ""))
|
||||||
|
outputBox.setThumbnail(versionText.getImage());
|
||||||
|
|
||||||
|
Long[] channelIds = SQLiteStorage.getChannelIds();
|
||||||
|
if(tagetChannel != null) {
|
||||||
|
Objects.requireNonNull(jda.getTextChannelById(tagetChannel))
|
||||||
|
.sendMessage("Hier ist ein Text vor dem Embed <@&423156046115242005> :")
|
||||||
|
.setEmbeds(outputBox.build())
|
||||||
|
.queue();
|
||||||
|
}
|
||||||
|
else if(Objects.requireNonNull(channelIds).length == 0) {
|
||||||
|
Objects.requireNonNull(jda.getTextChannelById(542202034330271759L)).sendMessageEmbeds(outputBox.build()).queue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (Long channelId : channelIds ) {
|
||||||
|
try {
|
||||||
|
if (Objects.requireNonNull(jda.getTextChannelById(channelId)).canTalk())
|
||||||
|
Objects.requireNonNull(jda.getTextChannelById(channelId)).sendMessageEmbeds(outputBox.build()).queue();
|
||||||
|
}
|
||||||
|
catch (NullPointerException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
//jda.getTextChannelById(channelId).sendMessage("Nope").queue();
|
||||||
|
System.out.println("problem: " + e.getMessage());
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
System.out.println("problem: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void newStory(JDA jda, DataStory story) {
|
||||||
|
newStory(jda, story, null);
|
||||||
|
}
|
||||||
|
public void newStory(JDA jda, DataStory story, Integer version) {
|
||||||
|
try {
|
||||||
|
String message;
|
||||||
|
EmbedBuilder outputBox = new EmbedBuilder();
|
||||||
|
|
||||||
|
|
||||||
|
outputBox.setTitle("Neue Gesichte:", story.link());
|
||||||
|
|
||||||
|
List<StoryOutputText> storyTexte = SQLiteStorage.getStoryTexte();
|
||||||
|
StoryOutputText versionText = null;
|
||||||
|
if(storyTexte.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(version != null) {
|
||||||
|
versionText = storyTexte.get(version);
|
||||||
|
}
|
||||||
|
if(version == null || versionText == null) {
|
||||||
|
Random random = new Random();
|
||||||
|
versionText = storyTexte.get(random.nextInt(storyTexte.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
message = versionText.getMessage();
|
||||||
|
|
||||||
|
message = message.replace("%storyName%", "**" + story.name() + "**")
|
||||||
|
.replace("%autor%", "**" + story.author() + "**");
|
||||||
|
|
||||||
|
|
||||||
|
outputBox.setDescription(message);
|
||||||
|
|
||||||
|
outputBox.setColor(versionText.getColor());
|
||||||
|
|
||||||
|
Instant instant = Instant.ofEpochSecond(story.date());
|
||||||
|
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Berlin"));
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy HH:mm 'Uhr'");
|
||||||
|
|
||||||
|
|
||||||
|
outputBox.setFooter("Veröffentlicht am " + dateTime.format(formatter));
|
||||||
|
if(versionText.getImage() != null && !Objects.equals(versionText.getImage(), ""))
|
||||||
|
outputBox.setThumbnail(versionText.getImage());
|
||||||
|
|
||||||
|
Long[] channelIds = SQLiteStorage.getChannelIds();
|
||||||
|
if(channelIds.length == 0) {
|
||||||
|
jda.getTextChannelById(542202034330271759L).sendMessageEmbeds(outputBox.build()).queue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (Long channelId : channelIds ) {
|
||||||
|
try {
|
||||||
|
if (jda.getTextChannelById(channelId).canTalk())
|
||||||
|
jda.getTextChannelById(channelId).sendMessageEmbeds(outputBox.build())
|
||||||
|
.queue();
|
||||||
|
}
|
||||||
|
catch (NullPointerException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
//jda.getTextChannelById(channelId).sendMessage("Nope").queue();
|
||||||
|
}
|
||||||
|
catch (NullPointerException e ) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
System.out.println("problem: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
361
src/main/java/de/ocame/ffdiscordbot/FanFiktionReader.java
Normal file
361
src/main/java/de/ocame/ffdiscordbot/FanFiktionReader.java
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class FanFiktionReader {
|
||||||
|
|
||||||
|
private final HtmlFetcher fetcher;
|
||||||
|
|
||||||
|
private final DiscordOutput dco;
|
||||||
|
|
||||||
|
private final JDA jda;
|
||||||
|
|
||||||
|
private long time = 30*60;
|
||||||
|
|
||||||
|
|
||||||
|
public FanFiktionReader(JDA jda) {
|
||||||
|
|
||||||
|
fetcher = new HtmlFetcher();
|
||||||
|
SQLiteStorage.createTable();
|
||||||
|
dco = new DiscordOutput();
|
||||||
|
this.jda = jda;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liest neue Ereignse von der Alert Seite aus
|
||||||
|
*/
|
||||||
|
public void checkAlerts() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String alertURL = "https://www.fanfiktion.de/?a=i";
|
||||||
|
|
||||||
|
Document alertPage = fetcher.fetchURL(alertURL);
|
||||||
|
|
||||||
|
// Login Check
|
||||||
|
Elements title = alertPage.getElementsByTag("title");
|
||||||
|
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
|
||||||
|
login();
|
||||||
|
alertPage = fetcher.fetchURL(alertURL);
|
||||||
|
title = alertPage.getElementsByTag("title");
|
||||||
|
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
|
||||||
|
// Fehler
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Story Check
|
||||||
|
Element authorBox = alertPage.getElementById("ffcbox-alerts_author-box");
|
||||||
|
if(authorBox != null) {
|
||||||
|
Elements rows = authorBox.select("table tbody tr");
|
||||||
|
for (Element row : rows) {
|
||||||
|
checkNewStoryFromAlert(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kapitel Check
|
||||||
|
Element StoryBox = alertPage.getElementById("ffcbox-alerts_story-box");
|
||||||
|
if(StoryBox != null) {
|
||||||
|
Elements rows = StoryBox.select("table tbody tr");
|
||||||
|
|
||||||
|
for (Element row : rows) {
|
||||||
|
Elements cols = row.select("td");
|
||||||
|
if (cols.size() >= 2) {
|
||||||
|
Element link = cols.get(1).selectFirst("a");
|
||||||
|
String linkHref = (link != null) ? link.attr("href") : "No link";
|
||||||
|
String chaptertime = cols.get(6).text();
|
||||||
|
long chapterUnixtime = DateToTimestamp(chaptertime);
|
||||||
|
|
||||||
|
Element delLink = cols.last().selectFirst("a");
|
||||||
|
String delLinkHref = (delLink != null) ? delLink.attr("href") : "No link";
|
||||||
|
|
||||||
|
checkNewChapter("https://www.fanfiktion.de" + linkHref, chapterUnixtime);
|
||||||
|
|
||||||
|
// Ausführung des Links, um Inhalt aus Alert zu entfernen
|
||||||
|
try {
|
||||||
|
if(!delLinkHref.equals("No link"))
|
||||||
|
fetcher.fetchURL("https://www.fanfiktion.de" + delLinkHref);
|
||||||
|
}
|
||||||
|
catch (IOException | InterruptedException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (IOException | InterruptedException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Random random = new Random();
|
||||||
|
this.time = random.nextLong(24*60,34*60);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liest neue Storys von der Alarm Seite aus
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
*/
|
||||||
|
public void checkNewStoryFromAlert(Element row) {
|
||||||
|
Elements cols = row.select("td");
|
||||||
|
if (cols.size() >= 2) { // Ensure there are at least two columns
|
||||||
|
/*name, link, ffid, date, autor*/
|
||||||
|
String storyName = cols.get(1).text();
|
||||||
|
String storyAutor = cols.get(3).text();
|
||||||
|
String storytime = cols.get(4).text();
|
||||||
|
long storyUnixtime = DateToTimestamp(storytime);
|
||||||
|
|
||||||
|
Element link = cols.get(1).selectFirst("a");
|
||||||
|
String linkHref = (link != null) ? link.attr("href") : "No link";
|
||||||
|
String[] hrefElements = linkHref.split("/s/",2);
|
||||||
|
String storyId = hrefElements[1];
|
||||||
|
if(!SQLiteStorage.checkStory(storyId)) {
|
||||||
|
/* todo: neue Story gefunden Ausgabe */
|
||||||
|
DataStory newStory = new DataStory(storyName, "https://www.fanfiktion.de/s/" + storyId, storyId,storyUnixtime,storyAutor, 0);
|
||||||
|
SQLiteStorage.insertStorys(newStory);
|
||||||
|
dco.newStory(jda, newStory);
|
||||||
|
|
||||||
|
}
|
||||||
|
Element delLink = cols.last().selectFirst("a");
|
||||||
|
String delLinkHref = (delLink != null) ? delLink.attr("href") : "No link";
|
||||||
|
|
||||||
|
// Ausführung des Links, um Inhalt aus Alert zu entfernen
|
||||||
|
try {
|
||||||
|
if(!delLinkHref.equals("No link"))
|
||||||
|
fetcher.fetchURL("https://www.fanfiktion.de" + delLinkHref);
|
||||||
|
}
|
||||||
|
catch (IOException | InterruptedException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prüft neues Kapitel Anhand der Seite, das Datum wird nur aus bequemlichkeit mit übergeben, da das schneller auslesbar war
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param chapterDate
|
||||||
|
*/
|
||||||
|
public void checkNewChapter(String url, long chapterDate) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Login Check
|
||||||
|
Document storyPage = fetcher.fetchURL(url);
|
||||||
|
Elements title = storyPage.getElementsByTag("title");
|
||||||
|
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
|
||||||
|
login();
|
||||||
|
storyPage = fetcher.fetchURL(url);
|
||||||
|
title = storyPage.getElementsByTag("title");
|
||||||
|
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
|
||||||
|
// Fehler
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auswahl Select für Kapitel Auswahl
|
||||||
|
Element chapterSelect = storyPage.getElementById("kA");
|
||||||
|
if(chapterSelect != null) {
|
||||||
|
Elements options = storyPage.select("option");
|
||||||
|
String chapterName = options.last().text();
|
||||||
|
String chapterNumer = options.last().attr("value");
|
||||||
|
String onChange = chapterSelect.attributes().get("onchange")
|
||||||
|
.replace("location.href = '" , "")
|
||||||
|
.replace("' + this.value + '" , chapterNumer)
|
||||||
|
.replace("'" , "");
|
||||||
|
|
||||||
|
// Regulärer Ausdruck für die ffid nach /s/
|
||||||
|
String regex = "/s/([a-zA-Z0-9]+)/";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(onChange);
|
||||||
|
String ffid = "";
|
||||||
|
if (matcher.find()) {
|
||||||
|
// Die gefundene Nummernfolge ausgeben
|
||||||
|
ffid = matcher.group(1);
|
||||||
|
} else {
|
||||||
|
// todo: fehler behandlung
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SQLiteStorage.checkChapter(ffid, Long.parseLong(chapterNumer))) {
|
||||||
|
/* todo: neue Chapter gefunden Ausgabe */
|
||||||
|
if(!SQLiteStorage.checkStory(ffid)) {
|
||||||
|
readandSaveStory(storyPage);
|
||||||
|
}
|
||||||
|
DataStory ds = SQLiteStorage.getStory(ffid);
|
||||||
|
DataChapter newChapter = new DataChapter(chapterName, "https://www.fanfiktion.de" + onChange, ffid, chapterDate, Long.parseLong(chapterNumer));
|
||||||
|
SQLiteStorage.insertChapter(newChapter);
|
||||||
|
//clearChapter();
|
||||||
|
dco.newChapter(jda, newChapter, ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException | InterruptedException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List alle Infos aus einer Story Seite aus, um das relevante zu speichern
|
||||||
|
* @param storyPage
|
||||||
|
*/
|
||||||
|
public void readandSaveStory(Document storyPage) {
|
||||||
|
Elements infoBox = storyPage.select(".story-left");
|
||||||
|
String storyName = infoBox.first().getElementsByTag("h4").text();
|
||||||
|
String storyAutor = infoBox.select("a.no-wrap").first().text();
|
||||||
|
String storytime = infoBox.select(".flexicon-container.small-font.block div").first().text();
|
||||||
|
long storyUnixtime = DateToTimestamp(storytime + " | 00:00 Uhr");
|
||||||
|
|
||||||
|
String storyLink = storyPage.select("#ffcbox-story .topics a").last().attr("href");
|
||||||
|
|
||||||
|
String regex = "/s/([a-zA-Z0-9]+)/";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(storyLink);
|
||||||
|
String ffid = "";
|
||||||
|
if (matcher.find()) {
|
||||||
|
// Die gefundene Nummernfolge ausgeben
|
||||||
|
ffid = matcher.group(1);
|
||||||
|
} else {
|
||||||
|
// todo: fehler behandlung
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!SQLiteStorage.checkStory(ffid)) {
|
||||||
|
DataStory newStory = new DataStory(storyName, "https://www.fanfiktion.de/s/" + ffid, ffid, storyUnixtime, storyAutor, 0);
|
||||||
|
SQLiteStorage.insertStorys(newStory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void outputCheapterTester(int chapterId, String chapterTextTitle, String storyTitle, String autor, Long tagetChannel) {
|
||||||
|
DataStory ds = new DataStory(storyTitle, "https://www.fanfiktion.de", "", LocalDateTime.now().toEpochSecond(ZoneOffset.UTC), autor, 0);
|
||||||
|
DataChapter dc = new DataChapter(chapterTextTitle, "https://www.fanfiktion.de", "", LocalDateTime.now().toEpochSecond(ZoneOffset.UTC), 1);
|
||||||
|
|
||||||
|
dco.newChapter(jda, dc, ds, chapterId, tagetChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wandelt String Zeit in Unix Timestamp um
|
||||||
|
*
|
||||||
|
* @param dateString
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long DateToTimestamp(String dateString) {
|
||||||
|
|
||||||
|
//dateString = "02.08.2024 | 21:21 Uhr";
|
||||||
|
|
||||||
|
// Definiere das Datumsformat
|
||||||
|
//DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy | HH:mm 'Uhr'").withResolverStyle(ResolverStyle.STRICT);
|
||||||
|
//DateTimeFormatter formatteralternativ = DateTimeFormatter.ofPattern("dd.MM.yyyy'");
|
||||||
|
|
||||||
|
String[] patterns = {"dd.MM.yyyy | HH:mm 'Uhr'" , "dd.MM.yyyy'", "dd.MM.yyyy HH:mm'"};
|
||||||
|
LocalDateTime dateTime = parseDateTimeWithMultiplePatterns(dateString, patterns);
|
||||||
|
if(dateTime == null || dateTime.toEpochSecond(ZoneOffset.UTC) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return dateTime.toEpochSecond(ZoneOffset.UTC);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalDateTime parseDateTimeWithMultiplePatterns(String dateString, String[] patterns) {
|
||||||
|
for (String pattern : patterns) {
|
||||||
|
try {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||||
|
return LocalDateTime.parse(dateString.trim(), formatter);
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
// Continue with the next pattern if parsing fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null; // If none of the patterns work, return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Führt den Login aus
|
||||||
|
*/
|
||||||
|
public void login() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
ConfigLoader configLoader = new ConfigLoader();
|
||||||
|
|
||||||
|
String loginURL = "https://www.fanfiktion.de/?a=l";
|
||||||
|
Document logintPage = fetcher.fetchURL(loginURL);
|
||||||
|
|
||||||
|
Elements nameBox = logintPage.select ("input[name='nickname']");
|
||||||
|
Elements pwBox = logintPage.select ("input[name='passwd']");
|
||||||
|
|
||||||
|
if(nameBox.isEmpty()) {
|
||||||
|
// todo: Fehler wenn Login nicht geht
|
||||||
|
}
|
||||||
|
|
||||||
|
Elements aBox = logintPage.select ("input[name='a']");
|
||||||
|
Elements uBox = logintPage.select ("input[name='u']");
|
||||||
|
|
||||||
|
String uValue = fetcher.getCookieValue("https://www.fanfiktion.de/", "u");
|
||||||
|
uValue = java.net.URLDecoder.decode(uValue, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
String ffNickname = configLoader.getUsername();
|
||||||
|
String ffPw = configLoader.getPassword();
|
||||||
|
String postData = "a=l" // + java.net.URLEncoder.encode(aBox.attr("value"), StandardCharsets.UTF_8)
|
||||||
|
+ "&u=" + java.net.URLEncoder.encode(uValue, StandardCharsets.UTF_8)
|
||||||
|
+ "&nickname=" + java.net.URLEncoder.encode(ffNickname, StandardCharsets.UTF_8)
|
||||||
|
+ "&passwd=" + java.net.URLEncoder.encode(ffPw, StandardCharsets.UTF_8)
|
||||||
|
+ "&savelogindata=" + java.net.URLEncoder.encode("1", StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Document loginRequest = fetcher.fetchURL("https://www.fanfiktion.de/", postData);
|
||||||
|
nameBox = loginRequest.select ("input[name='nickname']");
|
||||||
|
|
||||||
|
if(!nameBox.isEmpty()) {
|
||||||
|
// todo: Fehler wenn Login nicht geht
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (IOException | InterruptedException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearChapter(String url) {
|
||||||
|
try {
|
||||||
|
Document storyPage = fetcher.fetchURL(url);
|
||||||
|
Elements title = storyPage.getElementsByTag("title");
|
||||||
|
if (title.first().text().contains("keine Berechtigung!")) {
|
||||||
|
login();
|
||||||
|
storyPage = fetcher.fetchURL(url);
|
||||||
|
title = storyPage.getElementsByTag("title");
|
||||||
|
if (title.first().text().contains("keine Berechtigung!")) {
|
||||||
|
// Fehler
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException | InterruptedException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
157
src/main/java/de/ocame/ffdiscordbot/HtmlFetcher.java
Normal file
157
src/main/java/de/ocame/ffdiscordbot/HtmlFetcher.java
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.net.HttpCookie;
|
||||||
|
import java.net.CookieManager;
|
||||||
|
import java.net.CookiePolicy;
|
||||||
|
import java.net.CookieStore;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
|
||||||
|
import java.net.http.HttpRequest.BodyPublishers;
|
||||||
|
|
||||||
|
|
||||||
|
public class HtmlFetcher {
|
||||||
|
|
||||||
|
private final HttpClient client;
|
||||||
|
private final CookieManager cookieManager;
|
||||||
|
private static final String COOKIE_FILE = "cookies.json";
|
||||||
|
|
||||||
|
public HtmlFetcher() {
|
||||||
|
cookieManager = new CookieManager();
|
||||||
|
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
|
||||||
|
client = HttpClient.newBuilder()
|
||||||
|
.cookieHandler(cookieManager)
|
||||||
|
.followRedirects(HttpClient.Redirect.ALWAYS)
|
||||||
|
.connectTimeout(Duration.ofSeconds(10)) // Verbindungs-Timeout
|
||||||
|
.build();
|
||||||
|
|
||||||
|
loadCookies();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Document fetchURL(String url) throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
return fetchURL(url, "");
|
||||||
|
}
|
||||||
|
public Document fetchURL(String url, String postData) throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(url))
|
||||||
|
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0")
|
||||||
|
.header("Accept", "text/html")
|
||||||
|
.header("Accept-Language", "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7")
|
||||||
|
.timeout(Duration.ofSeconds(10));// Lese-Timeout
|
||||||
|
|
||||||
|
if (postData == null || postData.isEmpty()) {
|
||||||
|
requestBuilder.GET();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Wenn postData nicht leer ist, füge die POST-Daten hinzu
|
||||||
|
requestBuilder
|
||||||
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
.POST(BodyPublishers.ofString(postData));
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpRequest request = requestBuilder.build();
|
||||||
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
||||||
|
// Print cookies if any
|
||||||
|
CookieStore cookieStore = cookieManager.getCookieStore();
|
||||||
|
List<HttpCookie> cookies = cookieStore.getCookies();
|
||||||
|
/*for (HttpCookie cookie : cookies) {
|
||||||
|
System.out.println("Cookie: " + cookie);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Save cookies
|
||||||
|
saveCookies();
|
||||||
|
|
||||||
|
return Jsoup.parse(response.body());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveCookies() {
|
||||||
|
CookieStore cookieStore = cookieManager.getCookieStore();
|
||||||
|
List<HttpCookie> cookies = cookieStore.getCookies();
|
||||||
|
List<SerializableCookie> serializableCookies = new ArrayList<>();
|
||||||
|
for (HttpCookie cookie : cookies) {
|
||||||
|
serializableCookies.add(new SerializableCookie(cookie));
|
||||||
|
}
|
||||||
|
|
||||||
|
try (FileWriter writer = new FileWriter(COOKIE_FILE)) {
|
||||||
|
new Gson().toJson(serializableCookies, writer);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadCookies() {
|
||||||
|
try (FileReader reader = new FileReader(COOKIE_FILE)) {
|
||||||
|
List<SerializableCookie> serializableCookies = new Gson().fromJson(reader, new TypeToken<List<SerializableCookie>>(){}.getType());
|
||||||
|
if (serializableCookies != null) {
|
||||||
|
for (SerializableCookie serializableCookie : serializableCookies) {
|
||||||
|
cookieManager.getCookieStore().add(new URI(serializableCookie.uri), serializableCookie.toHttpCookie());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SerializableCookie {
|
||||||
|
private String uri;
|
||||||
|
private String name;
|
||||||
|
private String value;
|
||||||
|
private String path;
|
||||||
|
private String domain;
|
||||||
|
private long maxAge;
|
||||||
|
private boolean secure;
|
||||||
|
private boolean httpOnly;
|
||||||
|
|
||||||
|
SerializableCookie(HttpCookie cookie) {
|
||||||
|
this.uri = cookie.getDomain();
|
||||||
|
this.name = cookie.getName();
|
||||||
|
this.value = cookie.getValue();
|
||||||
|
this.path = cookie.getPath();
|
||||||
|
this.domain = cookie.getDomain();
|
||||||
|
this.maxAge = cookie.getMaxAge();
|
||||||
|
this.secure = cookie.getSecure();
|
||||||
|
this.httpOnly = cookie.isHttpOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpCookie toHttpCookie() {
|
||||||
|
HttpCookie cookie = new HttpCookie(name, value);
|
||||||
|
cookie.setPath(path);
|
||||||
|
cookie.setDomain(domain);
|
||||||
|
cookie.setMaxAge(maxAge);
|
||||||
|
cookie.setSecure(secure);
|
||||||
|
cookie.setHttpOnly(httpOnly);
|
||||||
|
return cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CookieManager getCookieManager() {
|
||||||
|
return cookieManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCookieValue(String uri, String cookieName) {
|
||||||
|
CookieStore cookieStore = cookieManager.getCookieStore();
|
||||||
|
List<HttpCookie> cookies = cookieStore.get(URI.create(uri));
|
||||||
|
for (HttpCookie cookie : cookies) {
|
||||||
|
if (cookie.getName().equals(cookieName)) {
|
||||||
|
return cookie.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null; // Cookie wurde nicht gefunden
|
||||||
|
}
|
||||||
|
}
|
||||||
71
src/main/java/de/ocame/ffdiscordbot/Main.java
Normal file
71
src/main/java/de/ocame/ffdiscordbot/Main.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import net.dv8tion.jda.api.JDABuilder;
|
||||||
|
import net.dv8tion.jda.api.OnlineStatus;
|
||||||
|
import net.dv8tion.jda.api.entities.Activity;
|
||||||
|
import net.dv8tion.jda.api.requests.GatewayIntent;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
ConfigLoader configLoader = new ConfigLoader();
|
||||||
|
|
||||||
|
// Insert your bot's token here
|
||||||
|
//String token = "MTI3NzcxNTQ1NTI1MDkyMzU4MA.GUuRyh.07mjVRcI7MhLHo-Wdnytvxlb3Pts-hfRaNMaPA";
|
||||||
|
// iro
|
||||||
|
String token = configLoader.getToken();
|
||||||
|
/**/
|
||||||
|
JDA jda = JDABuilder.createDefault(token)
|
||||||
|
.enableIntents(GatewayIntent.MESSAGE_CONTENT)
|
||||||
|
.setActivity(Activity.playing("mit der Marine fangen"))
|
||||||
|
.setStatus(OnlineStatus.ONLINE)
|
||||||
|
.setAutoReconnect(true)
|
||||||
|
.build();/**/
|
||||||
|
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(10);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
FanFiktionReader ffr = new FanFiktionReader(jda);
|
||||||
|
|
||||||
|
// Start des Socket-Servers in einem separaten Thread
|
||||||
|
Thread socketThread = new Thread(new SocketServerRunnable(jda, ffr));
|
||||||
|
socketThread.start();
|
||||||
|
|
||||||
|
|
||||||
|
//ffr.checkAlerts();
|
||||||
|
|
||||||
|
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||||
|
final long[] delay = {30 * 60};
|
||||||
|
|
||||||
|
AtomicReference<ScheduledFuture<?>> scheduledFuture = new AtomicReference<>();
|
||||||
|
Runnable task = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//ffr.checkAlerts();
|
||||||
|
// Berechne das neue Intervall basierend auf ffr.getTime()
|
||||||
|
delay[0] = ffr.getTime();
|
||||||
|
|
||||||
|
// Plane die Aufgabe erneut mit dem neuen Intervall
|
||||||
|
scheduledFuture.get().cancel(false);
|
||||||
|
scheduledFuture.set(scheduler.schedule(this, delay[0], TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Plane die erste Ausführung der Aufgabe
|
||||||
|
scheduledFuture.set(scheduler.schedule(task, delay[0], TimeUnit.SECONDS));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
457
src/main/java/de/ocame/ffdiscordbot/SQLiteStorage.java
Normal file
457
src/main/java/de/ocame/ffdiscordbot/SQLiteStorage.java
Normal file
@ -0,0 +1,457 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SQLiteStorage {
|
||||||
|
|
||||||
|
private static final String DB_URL = "jdbc:sqlite:data.db";
|
||||||
|
private static final int MAX_RETRIES = 5;
|
||||||
|
private static final int RETRY_WAIT_TIME_MS = 1000;
|
||||||
|
|
||||||
|
public static void createTable() {
|
||||||
|
String sql = """
|
||||||
|
CREATE TABLE IF NOT EXISTS Storys (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
link TEXT NOT NULL,
|
||||||
|
ffid TEXT NOT NULL,
|
||||||
|
date INTEGER NOT NULL,
|
||||||
|
tagId INTEGER NULL,
|
||||||
|
autor TEXT NOT NULL
|
||||||
|
);""";
|
||||||
|
|
||||||
|
String sqlChapter = """
|
||||||
|
CREATE TABLE IF NOT EXISTS Chapter (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
storyId TEXT NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
link TEXT NOT NULL,
|
||||||
|
date INTEGER NOT NULL,
|
||||||
|
number INTEGER NOT NULL
|
||||||
|
);""";
|
||||||
|
|
||||||
|
String sqlChapterText = """
|
||||||
|
CREATE TABLE IF NOT EXISTS ChapterText (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
chapterText TEXT NOT NULL,
|
||||||
|
color TEXT NOT NULL,
|
||||||
|
imageUrl TEXT NOT NULL,
|
||||||
|
active BOOLEAN NOT NULL DEFAULT 1
|
||||||
|
);""";
|
||||||
|
|
||||||
|
String sqlStoryText = """
|
||||||
|
CREATE TABLE IF NOT EXISTS StoryText (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
storyText TEXT NOT NULL,
|
||||||
|
color TEXT NOT NULL,
|
||||||
|
imageUrl TEXT NOT NULL,
|
||||||
|
active BOOLEAN NOT NULL DEFAULT 1
|
||||||
|
);""";
|
||||||
|
|
||||||
|
String sqlTags = """
|
||||||
|
CREATE TABLE IF NOT EXISTS Tags (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL UNIQUE
|
||||||
|
);
|
||||||
|
""";
|
||||||
|
|
||||||
|
String chapterTag = """
|
||||||
|
CREATE TABLE IF NOT EXISTS ChapterText_Tags (
|
||||||
|
chapterText_id INTEGER,
|
||||||
|
tag_id INTEGER,
|
||||||
|
PRIMARY KEY (chapterText_id, tag_id),
|
||||||
|
FOREIGN KEY (chapterText_id) REFERENCES ChapterText(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (tag_id) REFERENCES Tags(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
""";
|
||||||
|
|
||||||
|
String options = """
|
||||||
|
CREATE TABLE IF NOT EXISTS Options (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL UNIQUE,
|
||||||
|
value TEXT
|
||||||
|
);
|
||||||
|
""";
|
||||||
|
|
||||||
|
String createIndexSQL = "CREATE INDEX IF NOT EXISTS idx_ffid ON Storys(ffid)";
|
||||||
|
String createIndexSQLChapter = "CREATE INDEX IF NOT EXISTS idx_ffid ON Chapter(ffid)";
|
||||||
|
String createIndexSQLChapter2 = "CREATE INDEX IF NOT EXISTS idx_storyId ON Chapter(storyId)";
|
||||||
|
String createIndexSQLChapterText = "CREATE INDEX IF NOT EXISTS idx_chapterText_active ON ChapterText (active);\n";
|
||||||
|
String createIndexSQLStoryText = "CREATE INDEX IF NOT EXISTS idx_storyText_active ON StoryText (active);\n";
|
||||||
|
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL);
|
||||||
|
Statement stmt = conn.createStatement()) {
|
||||||
|
stmt.execute(sql);
|
||||||
|
stmt.execute(createIndexSQL);
|
||||||
|
|
||||||
|
stmt.execute(sqlChapter);
|
||||||
|
stmt.execute(sqlChapterText);
|
||||||
|
stmt.execute(sqlStoryText);
|
||||||
|
stmt.execute(sqlTags);
|
||||||
|
stmt.execute(chapterTag);
|
||||||
|
stmt.execute(options);
|
||||||
|
|
||||||
|
stmt.execute(createIndexSQLChapter);
|
||||||
|
stmt.execute(createIndexSQLChapter2);
|
||||||
|
stmt.execute(createIndexSQLChapterText);
|
||||||
|
stmt.execute(createIndexSQLStoryText);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void insertStorys(DataStory record) {
|
||||||
|
String sql = "INSERT INTO Storys(name, link, ffid, date, autor) VALUES(?, ?, ?, ?, ?)";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
executeUpdateWithRetry(conn, sql,
|
||||||
|
record.name(),
|
||||||
|
record.link(),
|
||||||
|
record.ffid(),
|
||||||
|
record.date(),
|
||||||
|
record.author());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean checkStory(String ffid) {
|
||||||
|
|
||||||
|
String sql = "SELECT COUNT(*) FROM Storys WHERE ffid = ?";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql, ffid);
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
int count = rs.getInt(1);
|
||||||
|
return count > 0; // Gibt true zurück, wenn die ID existiert, sonst false
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean checkChapter(String ffid, long number) {
|
||||||
|
String sql = "SELECT COUNT(*) AS anzahl FROM Chapter WHERE storyId = ? AND number = ?";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql, ffid, number);
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
int count = rs.getInt(1);
|
||||||
|
return count > 0; // Gibt true zurück, wenn die ID existiert, sonst false
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataStory getStory(String ffid) {
|
||||||
|
String sql = "SELECT name, link, ffid, date, autor, tagId FROM Storys WHERE ffid = ?";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql, ffid);
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
return new DataStory(
|
||||||
|
rs.getString("name"),
|
||||||
|
rs.getString("link"),
|
||||||
|
ffid,
|
||||||
|
rs.getLong("date"),
|
||||||
|
rs.getString("autor"),
|
||||||
|
rs.getInt("tagId")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static DataChapter getChapter(String ffid, long number) {
|
||||||
|
String sql = "SELECT storyId, name, link, date, number FROM Chapter WHERE storyId = ? AND number = ?";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql, ffid, number);
|
||||||
|
|
||||||
|
if (rs != null && rs.next()) {
|
||||||
|
return new DataChapter(
|
||||||
|
rs.getString("name"),
|
||||||
|
rs.getString("link"),
|
||||||
|
ffid,
|
||||||
|
rs.getLong("date"),
|
||||||
|
number
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void insertChapter(DataChapter record) {
|
||||||
|
String sql = "INSERT INTO Chapter(name, link, storyId, date, number) VALUES(?, ?, ?, ?, ?)";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
executeUpdateWithRetry(conn, sql,
|
||||||
|
record.name(),
|
||||||
|
record.link(),
|
||||||
|
record.storyId(),
|
||||||
|
record.date(),
|
||||||
|
record.number());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
createTable();
|
||||||
|
|
||||||
|
/* DataStory record1 = new DataStory("Text 1", "https://link1.com", "Text 2");
|
||||||
|
DataStory record2 = new DataStory("Text 3", "https://link2.com", "Text 4");
|
||||||
|
|
||||||
|
// Insert data into SQLite
|
||||||
|
insertData(record1);
|
||||||
|
insertData(record2);
|
||||||
|
|
||||||
|
// Load data from SQLite
|
||||||
|
List<DataStory> loadedData = loadData();
|
||||||
|
for (DataStory record : loadedData) {
|
||||||
|
System.out.println(record);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int executeUpdateWithRetry(Connection conn, String sql, Object... params) throws SQLException {
|
||||||
|
int attempt = 0;
|
||||||
|
boolean success = false;
|
||||||
|
while (attempt < MAX_RETRIES && !success) {
|
||||||
|
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||||
|
setParameters(pstmt, params);
|
||||||
|
int rowsAffected = pstmt.executeUpdate();
|
||||||
|
success = true;
|
||||||
|
return rowsAffected;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
handleSQLException(e, ++attempt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new SQLException("Operation nach " + MAX_RETRIES + " Versuchen fehlgeschlagen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ResultSet executeQueryWithRetry(Connection conn, String sql, Object... params) throws SQLException {
|
||||||
|
int attempt = 0;
|
||||||
|
boolean success = false;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
while (attempt < MAX_RETRIES && !success) {
|
||||||
|
try {
|
||||||
|
PreparedStatement pstmt = conn.prepareStatement(sql);
|
||||||
|
setParameters(pstmt, params);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
handleSQLException(e, ++attempt);
|
||||||
|
if (rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
System.out.println("Failed to close ResultSet: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
throw new SQLException("Operation nach " + MAX_RETRIES + " Versuchen fehlgeschlagen.");
|
||||||
|
}
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
throw new SQLException("Operation nach " + MAX_RETRIES + " Versuchen fehlgeschlagen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setParameters(PreparedStatement pstmt, Object... params) throws SQLException {
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
pstmt.setObject(i + 1, params[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleSQLException(SQLException e, int attempt) throws SQLException {
|
||||||
|
if (e.getMessage().contains("database is locked")) {
|
||||||
|
System.out.println("Datenbank gesperrt, versuche erneut... (Versuch " + attempt + " von " + MAX_RETRIES + ")");
|
||||||
|
try {
|
||||||
|
Thread.sleep(RETRY_WAIT_TIME_MS);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new SQLException("Der Thread wurde unterbrochen.", ie);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw e; // Andere SQL-Fehler weiterwerfen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long[] getChannelIds() {
|
||||||
|
String sql = "SELECT name, value FROM \"Options\" WHERE name = \"channels\"";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql);
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
String channelOption = rs.getString("value");
|
||||||
|
if (!channelOption.isEmpty()) {
|
||||||
|
|
||||||
|
JSONArray jsonArray = new JSONArray(channelOption);
|
||||||
|
List<Long> longList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
try {
|
||||||
|
// Versuche, den Wert in ein Long zu konvertieren
|
||||||
|
long value = jsonArray.getLong(i);
|
||||||
|
longList.add(value); // Füge den Wert der Liste hinzu, wenn es ein gültiger Long ist
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Wenn der Wert kein gültiges Long ist, wird er übersprungen
|
||||||
|
//System.out.println("Überspringe ungültigen Wert: " + jsonArray.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return longList.toArray(new Long[0]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<StoryOutputText> getChapterTexte(DataStory ds) {
|
||||||
|
String sql = """
|
||||||
|
SELECT\s
|
||||||
|
CT.id,
|
||||||
|
CT.chapterText,
|
||||||
|
CT.color,
|
||||||
|
CT.imageUrl
|
||||||
|
FROM\s
|
||||||
|
ChapterText CT
|
||||||
|
LEFT JOIN\s
|
||||||
|
ChapterText_Tags CTT\s
|
||||||
|
ON\s
|
||||||
|
CT.id = CTT.chapterText_id
|
||||||
|
LEFT JOIN\s
|
||||||
|
Tags T\s
|
||||||
|
ON\s
|
||||||
|
T.id = CTT.tag_id
|
||||||
|
WHERE
|
||||||
|
T.id = ? AND CT.active = TRUE
|
||||||
|
GROUP BY\s
|
||||||
|
CT.id;""";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql, ds.tagId());
|
||||||
|
|
||||||
|
List<StoryOutputText> outputList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
outputList.add(new StoryOutputText(
|
||||||
|
rs.getString("chapterText"),
|
||||||
|
rs.getString("imageUrl"),
|
||||||
|
Color.decode(rs.getString("color")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return outputList;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<StoryOutputText> getChapterTexte(int ctId) {
|
||||||
|
String sql = """
|
||||||
|
SELECT\s
|
||||||
|
CT.id,
|
||||||
|
CT.chapterText,
|
||||||
|
CT.color,
|
||||||
|
CT.imageUrl
|
||||||
|
FROM\s
|
||||||
|
ChapterText CT
|
||||||
|
WHERE
|
||||||
|
CT.id = ?
|
||||||
|
GROUP BY\s
|
||||||
|
CT.id;""";
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql, ctId);
|
||||||
|
|
||||||
|
List<StoryOutputText> outputList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
outputList.add(new StoryOutputText(
|
||||||
|
rs.getString("chapterText"),
|
||||||
|
rs.getString("imageUrl"),
|
||||||
|
Color.decode(rs.getString("color")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return outputList;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<StoryOutputText> getStoryTexte() {
|
||||||
|
String sql = """
|
||||||
|
SELECT\s
|
||||||
|
CT.id,
|
||||||
|
CT.storyText,
|
||||||
|
CT.color,
|
||||||
|
CT.imageUrl
|
||||||
|
FROM\s
|
||||||
|
StoryText CT
|
||||||
|
WHERE
|
||||||
|
CT.active = TRUE;""";
|
||||||
|
|
||||||
|
|
||||||
|
try (Connection conn = DriverManager.getConnection(DB_URL)) {
|
||||||
|
ResultSet rs = executeQueryWithRetry(conn, sql);
|
||||||
|
|
||||||
|
List<StoryOutputText> outputList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
outputList.add(new StoryOutputText(
|
||||||
|
rs.getString("storyText"),
|
||||||
|
rs.getString("imageUrl"),
|
||||||
|
Color.decode(rs.getString("color")))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return outputList;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
record DataStory(String name, String link, String ffid, long date, String author, Integer tagId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
record DataChapter(String name, String link, String storyId, long date, long number) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
104
src/main/java/de/ocame/ffdiscordbot/SocketServerRunnable.java
Normal file
104
src/main/java/de/ocame/ffdiscordbot/SocketServerRunnable.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
|
||||||
|
class SocketServerRunnable implements Runnable {
|
||||||
|
|
||||||
|
private final JDA jda;
|
||||||
|
|
||||||
|
private final FanFiktionReader ffr;
|
||||||
|
|
||||||
|
public SocketServerRunnable(JDA jda, FanFiktionReader ffr) {
|
||||||
|
|
||||||
|
this.jda = jda;
|
||||||
|
this.ffr = ffr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int port = 12345;
|
||||||
|
try (ServerSocket serverSocket = new ServerSocket(port)) {
|
||||||
|
System.out.println("Socket-Server läuft auf Port " + port);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try (Socket clientSocket = serverSocket.accept();
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
|
||||||
|
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {
|
||||||
|
|
||||||
|
String jsonMessageFromClient = in.readLine();
|
||||||
|
System.out.println("Nachricht vom Client erhalten: " + jsonMessageFromClient);
|
||||||
|
JSONObject jsonData = new JSONObject(jsonMessageFromClient);
|
||||||
|
String action = jsonData.getString("action");
|
||||||
|
|
||||||
|
JSONObject jsonResponse= new JSONObject();
|
||||||
|
Long channelId = null;
|
||||||
|
|
||||||
|
if(action.equals("channelCheck")) {
|
||||||
|
Object channelIdObj = jsonData.get("channelId");
|
||||||
|
if(channelIdObj.equals("")) {
|
||||||
|
jsonResponse.put("status", "fail");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channelIdObj instanceof Number) {
|
||||||
|
channelId = ((Number) channelIdObj).longValue();
|
||||||
|
} else if (channelIdObj instanceof String) {
|
||||||
|
String channelIdStr = (String) channelIdObj;
|
||||||
|
channelId = Long.parseLong(channelIdStr);
|
||||||
|
} else {
|
||||||
|
jsonResponse.put("status", "fail");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String response = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
TextChannel textchannel = jda.getTextChannelById(channelId);
|
||||||
|
if (textchannel.canTalk()) {
|
||||||
|
jsonResponse.put("status", "success")
|
||||||
|
.put("name", textchannel.getName())
|
||||||
|
.put("serverName", textchannel.getGuild().getName());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jsonResponse.put("status", "fail");
|
||||||
|
}
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
jsonResponse.put("status", "error");
|
||||||
|
}
|
||||||
|
|
||||||
|
out.println(jsonResponse);
|
||||||
|
}
|
||||||
|
else if(action.equals("check")) {
|
||||||
|
ffr.checkAlerts();
|
||||||
|
jsonResponse.put("status", "success");
|
||||||
|
out.println(jsonResponse);
|
||||||
|
}
|
||||||
|
else if(action.equals("chapterTest")) {
|
||||||
|
String storyName = jsonData.getString("storyName");
|
||||||
|
String chapterName = jsonData.getString("chapterName");
|
||||||
|
String author = jsonData.getString("author");
|
||||||
|
Integer id = jsonData.getInt("id");
|
||||||
|
Long target = jsonData.getLong("target");
|
||||||
|
|
||||||
|
|
||||||
|
ffr.outputCheapterTester(id, chapterName, storyName, author, target);
|
||||||
|
jsonResponse.put("status", "success");
|
||||||
|
out.println(jsonResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException | NullPointerException e) {
|
||||||
|
System.out.println("Fehler bei der Kommunikation mit dem Client: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Server konnte nicht gestartet werden: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/main/java/de/ocame/ffdiscordbot/StoryOutputText.java
Normal file
39
src/main/java/de/ocame/ffdiscordbot/StoryOutputText.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package de.ocame.ffdiscordbot;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class StoryOutputText {
|
||||||
|
|
||||||
|
private final String message;
|
||||||
|
private final String image;
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
public StoryOutputText(String message) {
|
||||||
|
this.message = message;
|
||||||
|
this.image = null;
|
||||||
|
this.color = new Color(36, 153, 245);
|
||||||
|
}
|
||||||
|
public StoryOutputText(String message, String image) {
|
||||||
|
this.message = message;
|
||||||
|
this.image = image;
|
||||||
|
this.color = new Color(36, 153, 245);
|
||||||
|
}
|
||||||
|
public StoryOutputText(String message, String image, Color color) {
|
||||||
|
this.message = message;
|
||||||
|
this.image = image;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user