From 045d5186aa09e186f988f2e7cae45e14682cb76a Mon Sep 17 00:00:00 2001 From: Mysaa Date: Sun, 23 May 2021 02:27:16 +0200 Subject: [PATCH] =?UTF-8?q?=C3=89criture=20du=20fichier=20de=20code=20d'?= =?UTF-8?q?=C3=89couteurDEvents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 81 ++++++++ settings.gradle | 18 ++ .../com/bernard/juliabot/EcouteurDEvents.java | 196 ++++++++++++++++-- 3 files changed, 281 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index e69de29..19f621e 100644 --- a/build.gradle +++ b/build.gradle @@ -0,0 +1,81 @@ +/* + * This build file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Java Library project to get you started. + * For more details take a look at the Java Libraries chapter in the Gradle + * user guide available at https://docs.gradle.org/4.3/userguide/java_library_plugin.html + */ + +// Apply the java-library plugin to add support for Java Library +apply plugin: 'java-library' +apply plugin: 'eclipse' + +// In this section you declare where to find the dependencies of your project +repositories { + // Use jcenter for resolving your dependencies. + // You can declare any Maven/Ivy/file repository here. + jcenter() +} + +sourceSets { + main { + java { + srcDir '/src/main/java' + + exclude 'com/bernard/juliabot/internalddon/**' + } + } +} + +task apiJar(type: Jar) { + archiveName = "JuliabotAPI.jar" + group 'build' + description "Fait un jar avec juste l'api" + from(sourceSets.main.output) { + include "com/bernard/juliabot/api/**" + } +} + +task internalddonJar(type: Jar) { + archiveName = "JuliabotInternaddon_beta.jar" + group 'build' + description "Fait un jar avec juste l'addon interne" + from(sourceSets.main.output) { + include "com/bernard/juliabot/internaddon/**" + } +} + +task execute(type:JavaExec) { + group 'execution' + description "Compile et execute le fichier jar" + main = 'com.bernard.juliabot.Julia' + classpath = sourceSets.main.runtimeClasspath +} + +task copyDependencies(type: Copy) { + group 'build' + from configurations.compile + into 'dependencies' +} + +dependencies { + // This dependency is exported to consumers, that is to say found on their compile classpath. + api 'org.apache.commons:commons-math3:3.6.1' + + // This dependency is used internally, and not exposed to consumers on their own compile classpath. + implementation 'com.google.guava:guava:23.0' + + // Use JUnit test framework + testImplementation 'junit:junit:4.12' + + compile 'org.slf4j:slf4j-nop:1.7.25' + + compile 'net.dv8tion:JDA:3.8.1_439' + + compile 'com.thedeanda:lorem:2.1' + + // https://mvnrepository.com/artifact/mysql/mysql-connector-java + compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.15' + +} + diff --git a/settings.gradle b/settings.gradle index e69de29..8b51b63 100644 --- a/settings.gradle +++ b/settings.gradle @@ -0,0 +1,18 @@ +/* + * This settings file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * In a single project build this file can be empty or even removed. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user guide at https://docs.gradle.org/4.3/userguide/multi_project_builds.html + */ + +/* +// To declare projects as part of a multi-project build use the 'include' method +include 'shared' +include 'api' +include 'services:webservice' +*/ + +rootProject.name = 'Juliabot' diff --git a/src/main/java/com/bernard/juliabot/EcouteurDEvents.java b/src/main/java/com/bernard/juliabot/EcouteurDEvents.java index e3298d8..4d4f5db 100644 --- a/src/main/java/com/bernard/juliabot/EcouteurDEvents.java +++ b/src/main/java/com/bernard/juliabot/EcouteurDEvents.java @@ -1,13 +1,27 @@ package com.bernard.juliabot; +import java.io.*; +import java.nio.charset.StandardCharsets; import java.sql.*; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.stream.Collectors; + +import com.mysql.cj.exceptions.ExceptionInterceptor; +import com.mysql.cj.exceptions.ExceptionInterceptorChain; +import com.mysql.cj.jdbc.Blob; import net.dv8tion.jda.client.events.call.GenericCallEvent; import net.dv8tion.jda.client.events.group.GenericGroupEvent; import net.dv8tion.jda.client.events.message.group.GenericGroupMessageEvent; import net.dv8tion.jda.client.events.relationship.GenericRelationshipEvent; -import net.dv8tion.jda.core.events.Event; +import net.dv8tion.jda.core.entities.*; +import net.dv8tion.jda.core.events.*; import net.dv8tion.jda.core.events.channel.category.GenericCategoryEvent; +import net.dv8tion.jda.core.events.channel.category.update.*; import net.dv8tion.jda.core.events.channel.priv.PrivateChannelCreateEvent; import net.dv8tion.jda.core.events.channel.priv.PrivateChannelDeleteEvent; import net.dv8tion.jda.core.events.channel.text.GenericTextChannelEvent; @@ -26,14 +40,28 @@ import net.dv8tion.jda.core.hooks.EventListener; public class EcouteurDEvents implements EventListener{ + Queue storeQueue = new ConcurrentLinkedQueue<>(); + + Thread looper; + public EcouteurDEvents() { - // TODO Auto-generated constructor stub + ResultSet results; + try { + Statement geidS = Julia.theJulia.eventDatabase.createStatement(); + results = geidS.executeQuery("SELECT MAX(GEID) FROM events"); + Long geid = results.getLong(1); + looper = new Thread(new DbLooper(geid),"dbLooper-"+System.nanoTime()); + + looper.start(); + } catch (SQLException e) { + System.err.println("IMPOSSIBLE de récuperer le MAX_GEID : L'Écouteur d'écents ne démarera pas"); + e.printStackTrace(); + } } @Override public void onEvent(Event event) { - Thread dbRunner = new Thread(new DbRunner(event),"dbRunner-"+System.nanoTime()); - dbRunner.start(); + storeQueue.add(new PendingEventStore(event,Date.from(Instant.now()))); Julia.theJulia.laboratoires.get(getLabo(event)).trigger(event); } @@ -85,23 +113,116 @@ public class EcouteurDEvents implements EventListener{ return Julia.theJulia.laboratoriesIdentifieurs.getOrDefault(id, '#'); } - public class DbRunner implements Runnable{ + public class DbLooper implements Runnable{ - Event event; + boolean stop = false; - public DbRunner(Event event) { - this.event = event; + public long indexGEID; + + public DbLooper(long higherGEID) { + indexGEID = higherGEID+1; } @Override public void run() { + + while(!stop) { + + if(storeQueue.isEmpty()) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + System.err.println("Impossible de faire dormir le thread ... On va donc continuer de looper sans pause"); + e.printStackTrace(); + } + }else { + PendingEventStore pes = storeQueue.poll(); + storeEvent(pes.e, pes.eTime); + } + + + } + } + + public void storeEvent(Event event,Date date) { PreparedStatement s; Connection db = Julia.theJulia.eventDatabase; try { - switch(event.getClass().getName()) { - case "net.dv8tion.jda.core.events.message.react.MessageReactionAddEvent": + long geid = indexGEID++; + //TODO store event GEID + + PreparedStatement geidS = db.prepareStatement("INSERT INTO events VALUES (?,?,?,?)"); + geidS.setLong(1, geid); + geidS.setDate(2, new java.sql.Date(date.getTime())); + geidS.setLong(3, event.getResponseNumber()); + geidS.setString(4, event.getClass().getName()); + geidS.executeUpdate(); + + String tName = l1(event.getClass().getSimpleName()); + switch(event.getClass().getSimpleName()) { + + /////////// GenericCategoryEvent /////////// + case "CategoryUpdatePermissionsEvent": + addPermissionHolders(geid,((CategoryUpdatePermissionsEvent)event).getChangedPermissionHolders(),); + case "CategoryCreateEvent": + case "CategoryDeleteEvent": + GenericCategoryEvent e1 = (GenericCategoryEvent) event; + s = db.prepareStatement("INSERT INTO "+tName+" VALUES (?,?,?)"); + s.setLong(2, e1.getGuild().getIdLong()); + s.setLong(3, e1.getIdLong()); + break; + case "CategoryUpdateNameEvent": + CategoryUpdateNameEvent e2 = (CategoryUpdateNameEvent) event; + s = db.prepareStatement("INSERT INTO "+tName+" VALUES (?,?,?,?,?)"); + s.setLong(2, e2.getGuild().getIdLong()); + s.setLong(3, e2.getIdLong()); + s.setString(4, e2.getOldName()); + s.setString(5, e2.getNewName()); + break; + case "CategoryUpdatePositionEvent": + CategoryUpdatePositionEvent e3 = (CategoryUpdatePositionEvent) event; + s = db.prepareStatement("INSERT INTO "+tName+" VALUES (?,?,?,?,?)"); + s.setLong(2, e3.getGuild().getIdLong()); + s.setLong(3, e3.getIdLong()); + s.setInt(4, e3.getOldPosition()); + s.setInt(5, e3.getNewPosition()); + break; + + ////////// Events ////////// + case "DisconnectEvent": + DisconnectEvent e4 = (DisconnectEvent)event; + s = db.prepareStatement("INSERT INTO disconnectEvent VALUES (?,?,?,?,?,?,?)"); + s.setBlob(2, new Blob(e4.getClientCloseFrame().getPayload(),null)); + s.setString(3, e4.getCloseCode().name()); + s.setDate(4, new java.sql.Date(e4.getDisconnectTime().toEpochSecond())); + s.setBlob(5, new Blob(e4.getServiceCloseFrame().getPayload(),null)); + s.setBoolean(6, e4.isClosedByServer()); + s.setString(7, String.join("\n", e4.getCloudflareRays())); + + case "ExceptionEvent": + ExceptionEvent e5 = (ExceptionEvent)event; + s = db.prepareStatement("INSERT INTO exceptionEvent VALUES (?,?,?,?,?,?,?)"); + s.setString(2, e5.getCause().getClass().getName()); + s.setString(3, e5.getCause().getMessage()); + StringWriter sw = new StringWriter(); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (PrintStream ps = new PrintStream(baos, true, "UTF-8")) { + e5.getCause().printStackTrace(ps); + } + String data = new String(baos.toByteArray(), StandardCharsets.UTF_8); + s.setDate(4, new java.sql.Date(e4.getDisconnectTime().toEpochSecond())); + s.setBlob(5, new Blob(e4.getServiceCloseFrame().getPayload(),null)); + s.setBoolean(6, e4.isClosedByServer()); + s.setString(7, String.join("\n", e4.getCloudflareRays())); + + + + + + case "MessageReactionAddEvent": MessageReactionAddEvent e = (MessageReactionAddEvent) event; s = db.prepareStatement("INSERT INTO messageReactionAdd VALUES (?,?,?,?,?,?,?,?,?,?)"); + s.setLong(4, e.getMessageIdLong()); s.setLong(5, e.getChannel().getIdLong()); s.setLong(6, e.getGuild().getIdLong()); @@ -110,12 +231,13 @@ public class EcouteurDEvents implements EventListener{ s.setString(9, e.getReactionEmote().getName()); s.setLong(10, e.getReactionEmote().getIdLong()); break; + + + + default: throw new IllegalStateException("Cette méthode n'est pas a jour avec le JDA ... je gère pas "+event.getClass().getName()); } - //(int ID,Datetime post-date,long responceNumber) - s.setNull(1, Types.INTEGER); - s.setDate(2, new Date(System.currentTimeMillis())); - s.setLong(3, event.getResponseNumber()); + s.setLong(1, geid);//Le GEID s.executeUpdate(); } catch (SQLException e1) { System.err.println("Mysql pas content ......"); @@ -123,6 +245,52 @@ public class EcouteurDEvents implements EventListener{ } } + + + public void stop() { + stop = true; + } + + } + + + ////////////////////DB UTILS//////////////////// + public static void addPermissionHolders(long geid,List holders, Connection db) throws SQLException { + for(IPermissionHolder holder : holders) { + PreparedStatement s = db.prepareStatement("INSERT INTO permissionUpdateHolders VALUES (NULL,?,?,?,?)"); + s.setLong(1, geid); + s.setString(2, (holder.getClass().equals(Member.class))?"MEMBER":"ROLE"); + s.setLong(3, (holder.getClass().equals(Member.class))?((Member)holder).getUser().getIdLong():((Role)holder).getIdLong()); + s.setString(4, holder.getPermissions().stream().map(perm->perm.name()).collect(Collectors.joining(","))); + s.executeUpdate(); + } + } + + + + public static class PendingEventStore { + Event e; + Date eTime; + + public PendingEventStore(Event e, Date date) { + this.e = e; + this.eTime = date; + } + + public Event getE() { + return e; + } + + public Date geteTime() { + return eTime; + } + + } + + public static String l1(String in) { + char c[] = in.toCharArray(); + c[0] += 32; + return new String(c); } }