Petites modifications des fichiers
This commit is contained in:
parent
045d5186aa
commit
42ad4335b2
File diff suppressed because it is too large
Load Diff
@ -1,113 +1,136 @@
|
|||||||
package com.bernard.juliabot;
|
package com.bernard.juliabot;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
import java.lang.reflect.*;
|
||||||
import java.lang.reflect.Constructor;
|
import java.sql.*;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.util.*;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.bernard.juliabot.JuliaAddon.JarWithMultipleAddonsException;
|
import com.bernard.juliabot.JuliaAddon.JarWithMultipleAddonsException;
|
||||||
import com.bernard.juliabot.JuliaAddon.JuliaClassLoader;
|
import com.bernard.juliabot.JuliaAddon.JuliaClassLoader;
|
||||||
import com.bernard.juliabot.api.Command;
|
import com.bernard.juliabot.api.*;
|
||||||
import com.bernard.juliabot.api.CommandCall;
|
import com.thedeanda.lorem.LoremIpsum;
|
||||||
import com.bernard.juliabot.api.Discord;
|
|
||||||
|
|
||||||
import net.dv8tion.jda.core.AccountType;
|
import net.dv8tion.jda.core.*;
|
||||||
import net.dv8tion.jda.core.JDA;
|
|
||||||
import net.dv8tion.jda.core.JDABuilder;
|
|
||||||
import net.dv8tion.jda.core.events.Event;
|
import net.dv8tion.jda.core.events.Event;
|
||||||
|
|
||||||
public class Julia {
|
public class Julia {
|
||||||
|
|
||||||
public static final String juliaddonsFolder = "/home/julia/juliaddons/";
|
public static final String juliaddonsFolder = "/home/julia/juliaddons/";
|
||||||
|
|
||||||
|
public static final String sysinPipe = "/home/julia/entree";
|
||||||
|
|
||||||
private static final String token = "";
|
private static final String token = "";
|
||||||
|
|
||||||
static Julia theJulia;
|
static Julia theJulia;
|
||||||
|
|
||||||
JDA jda;
|
public JDA jda;
|
||||||
|
|
||||||
Map<String,JuliaAddon> avalivableAddons;//pkg+version->addon
|
Map<String,JuliaAddon> avalivableAddons;//pkg+version->addon
|
||||||
Map<Long,Character> laboratoriesIdentifieurs;//Store channels IDs ...
|
Map<Long,Character> laboratoriesIdentifieurs;//Store channels IDs ...
|
||||||
|
|
||||||
Map<Character,Laboratory> laboratoires;
|
public Map<Character,Laboratory> laboratoires;
|
||||||
|
|
||||||
Map<String,Long> fileTrack;//<File name in juliaddonFolder, lastModified>
|
Map<String,Long> fileTrack;//<File name in juliaddonFolder, lastModified>
|
||||||
|
|
||||||
|
public EcouteurDEvents lecouteur;
|
||||||
|
ReadLoop sysinator;
|
||||||
|
|
||||||
Connection eventDatabase;
|
Connection eventDatabase;
|
||||||
Connection juliaDatabase;
|
Connection juliaDatabase;
|
||||||
|
|
||||||
|
|
||||||
public Julia() {
|
public Julia() {
|
||||||
|
|
||||||
avalivableAddons = new HashMap<>();
|
avalivableAddons = new HashMap<>();
|
||||||
laboratoriesIdentifieurs = new HashMap<>();
|
laboratoriesIdentifieurs = new HashMap<>();
|
||||||
laboratoires = new HashMap<>();
|
laboratoires = new HashMap<>();
|
||||||
|
|
||||||
fileTrack = new HashMap<>();
|
fileTrack = new HashMap<>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void startup() {
|
||||||
//Set up mysql cnnections (events & data)
|
//Set up mysql cnnections (events & data)
|
||||||
Properties connectionProps = new Properties();
|
Properties connectionProps = new Properties();
|
||||||
connectionProps.put("user", "julia");
|
connectionProps.put("user", "julia");
|
||||||
connectionProps.put("password", "juliabestbotever");
|
connectionProps.put("password", "juliabestbotever");
|
||||||
connectionProps.put("serverTimezone", "UTC");
|
connectionProps.put("serverTimezone", "UTC");
|
||||||
connectionProps.put("verifyServerCertificate", "false");
|
connectionProps.put("verifyServerCertificate", "false");
|
||||||
connectionProps.put("useSSL", "true");
|
connectionProps.put("useSSL", "true");
|
||||||
connectionProps.put("requireSSL", "true");
|
connectionProps.put("requireSSL", "true");
|
||||||
try {
|
try {
|
||||||
eventDatabase = DriverManager.getConnection("jdbc:mysql://localhost:3306/juliaEvents", connectionProps);
|
Class.forName("com.mysql.jdbc.Driver");
|
||||||
juliaDatabase = DriverManager.getConnection("jdbc:mysql://localhost:3306/julia", connectionProps);
|
eventDatabase = DriverManager.getConnection("jdbc:mysql://192.168.1.41:3306/juliaEvents", connectionProps);
|
||||||
} catch (SQLException e) {
|
juliaDatabase = DriverManager.getConnection("jdbc:mysql://192.168.1.41:3306/julia", connectionProps);
|
||||||
|
} catch (SQLException | ClassNotFoundException e) {
|
||||||
System.err.println("Impossible de se connecter a la BDD, ca ne sers a rien de lancer JuL'IA du coup ... Bonne nuit");
|
System.err.println("Impossible de se connecter a la BDD, ca ne sers a rien de lancer JuL'IA du coup ... Bonne nuit");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//XXX sSet up JDA and Bot
|
System.out.println("La BDD est charg<72><67>e" + eventDatabase+","+juliaDatabase);
|
||||||
|
|
||||||
try {
|
|
||||||
jda = new JDABuilder(AccountType.BOT).setToken(token).buildBlocking();
|
// D<EFBFBD><EFBFBD>marrage de JDA et du Bot
|
||||||
|
try {
|
||||||
|
lecouteur = new EcouteurDEvents(this);
|
||||||
|
jda = new JDABuilder(AccountType.BOT).setToken(token).addEventListener(lecouteur).build();
|
||||||
|
jda.awaitReady();
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
System.err.println("Impossible de démarrer JuL'IA");
|
System.err.println("Impossible de d<EFBFBD><EFBFBD>marrer JuL'IA");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jda.getGuildById(222947179017404416L).getTextChannelById(460935684669046784L).sendMessage(LoremIpsum.getInstance().getWords(10, 15)).complete();
|
||||||
|
|
||||||
//Launch update to see every addon in juliaddon/
|
//Launch update to see every addon in juliaddon/
|
||||||
update();//Va remplir la map avalivableAddons
|
update();//Va remplir la map avalivableAddons
|
||||||
|
|
||||||
|
|
||||||
//Load addons in # and in $ (récupere ce qu'il faut dans la BDD)
|
|
||||||
|
//D<EFBFBD><EFBFBD>marrage du sysin
|
||||||
|
sysinator = new ReadLoop();
|
||||||
|
Thread sysinThread = new Thread(sysinator, "sysin-reader");
|
||||||
|
sysinThread.start();
|
||||||
|
|
||||||
|
System.out.println("Sont disponibles :"+avalivableAddons);
|
||||||
|
//Loader l'internalddon (hard-coded)
|
||||||
|
//laboratoires.get('#').loadAddon("com.bernard.juliabot.internaddon", "beta", false);//Pas besoin d'update, il viens d'etre fait
|
||||||
|
|
||||||
|
//Load addons in # and in $ (r<EFBFBD><EFBFBD>cupere ce qu'il faut dans la BDD)
|
||||||
|
Set<String> toLoad = new HashSet<>();
|
||||||
try {
|
try {
|
||||||
Statement statement = juliaDatabase.createStatement();
|
Statement statement = juliaDatabase.createStatement();
|
||||||
ResultSet result = statement.executeQuery("SELECT * FROM loadedJuliaddons");
|
ResultSet result = statement.executeQuery("SELECT * FROM loadedJuliaddons");
|
||||||
do {
|
while(result.next()) {
|
||||||
char laboratory = result.getString("laboratory").charAt(0);
|
char laboratory = result.getString("laboratory").charAt(0);
|
||||||
String pkg = result.getString("pkg");
|
String pkg = result.getString("pkg");
|
||||||
String version = result.getString("version");
|
String version = result.getString("version");
|
||||||
if(!laboratoires.containsKey(laboratory))
|
toLoad.add(laboratory+pkg+":"+version);
|
||||||
laboratoires.put(laboratory, new Laboratory(laboratory));
|
}
|
||||||
Laboratory labo = laboratoires.get(laboratory);
|
|
||||||
labo.loadAddon(pkg, version, false);//Pas besoin d'update, il viens d'etre fait
|
|
||||||
}while(result.next());
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println("Impossible de charger les plugins, vous aurez tout a faire a la main !");
|
System.err.println("Impossible de charger les plugins, vous aurez tout a faire a la main !");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
System.out.println("Les addons <20><> charger : "+toLoad);
|
||||||
|
try {
|
||||||
|
juliaDatabase.createStatement().executeUpdate("DELETE FROM loadedJuliaddons");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("Je n'ai pas pu vider la table ... atention aux doublons !");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String l : toLoad) {
|
||||||
|
if(!laboratoires.containsKey(l.charAt(0)))
|
||||||
|
laboratoires.put(l.charAt(0), new Laboratory(l.charAt(0)));
|
||||||
|
Laboratory labo = laboratoires.get(l.charAt(0));
|
||||||
|
labo.loadAddon(l.substring(1, l.lastIndexOf(":")), l.substring(l.lastIndexOf(":")+1), false);//Pas besoin d'update, il viens d'etre fait
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +138,8 @@ public class Julia {
|
|||||||
Map<String,JuliaAddon> avalivableAddons = new HashMap<>();
|
Map<String,JuliaAddon> avalivableAddons = new HashMap<>();
|
||||||
File juliaddonFolder = new File(juliaddonsFolder);
|
File juliaddonFolder = new File(juliaddonsFolder);
|
||||||
for(File f : juliaddonFolder.listFiles((parent,name)->name.toLowerCase().endsWith(".jar"))){
|
for(File f : juliaddonFolder.listFiles((parent,name)->name.toLowerCase().endsWith(".jar"))){
|
||||||
if(fileTrack.get(f.getName()) == f.lastModified())
|
if(fileTrack.containsKey(f.getName()) && fileTrack.get(f.getName()) == f.lastModified())
|
||||||
continue;//Le fichier n'a pas bougé, pas besoin de le relire
|
continue;//Le fichier n'a pas boug<EFBFBD><EFBFBD>, pas besoin de le relire
|
||||||
fileTrack.put(f.getName(), f.lastModified());
|
fileTrack.put(f.getName(), f.lastModified());
|
||||||
try {
|
try {
|
||||||
JarFile jar = new JarFile(f);
|
JarFile jar = new JarFile(f);
|
||||||
@ -124,7 +147,7 @@ public class Julia {
|
|||||||
JuliaAddon addon = new JuliaAddon(jar);
|
JuliaAddon addon = new JuliaAddon(jar);
|
||||||
String id = addon.pkg+":"+addon.version;
|
String id = addon.pkg+":"+addon.version;
|
||||||
if(avalivableAddons.containsKey(id))
|
if(avalivableAddons.containsKey(id))
|
||||||
System.err.println("L'addon "+id+" a déjà été chargé dans les fichiers "+avalivableAddons.get(id).jarFile.getName()+" et "+jar.getName()+", je garde que le deuxième !");
|
System.err.println("L'addon "+id+" a d<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD> <20><>t<EFBFBD><74> charg<72><67> dans les fichiers "+avalivableAddons.get(id).jarFile.getName()+" et "+jar.getName()+", je garde que le deuxi<EFBFBD><EFBFBD>me !");
|
||||||
avalivableAddons.put(id, addon);
|
avalivableAddons.put(id, addon);
|
||||||
}catch(JarWithMultipleAddonsException e) {
|
}catch(JarWithMultipleAddonsException e) {
|
||||||
Set<Set<JarEntry>> addonsEntries = e.getAddonsEntries();
|
Set<Set<JarEntry>> addonsEntries = e.getAddonsEntries();
|
||||||
@ -133,15 +156,17 @@ public class Julia {
|
|||||||
JuliaAddon addon = new JuliaAddon(jar, entry);
|
JuliaAddon addon = new JuliaAddon(jar, entry);
|
||||||
String id = addon.pkg+":"+addon.version;
|
String id = addon.pkg+":"+addon.version;
|
||||||
if(avalivableAddons.containsKey(id))
|
if(avalivableAddons.containsKey(id))
|
||||||
System.err.println("L'addon "+id+" a déjà été chargé dans les fichiers "+avalivableAddons.get(id).jarFile.getName()+" et "+jar.getName()+", je garde que le deuxième !");
|
System.err.println("L'addon "+id+" a d<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD> <20><>t<EFBFBD><74> charg<72><67> dans les fichiers "+avalivableAddons.get(id).jarFile.getName()+" et "+jar.getName()+", je garde que le deuxi<EFBFBD><EFBFBD>me !");
|
||||||
avalivableAddons.put(id, addon);
|
avalivableAddons.put(id, addon);
|
||||||
} catch (JarWithMultipleAddonsException e1) {
|
} catch (JarWithMultipleAddonsException e1) {
|
||||||
System.err.println("THIS SHOULD NOT HAPPEN");
|
System.err.println("THIS SHOULD NOT HAPPEN");
|
||||||
System.err.println("TOUT EST CASSÉ ALERTE ROUGE !");
|
System.err.println("TOUT EST CASS<EFBFBD><EFBFBD> ALERTE ROUGE !");
|
||||||
System.err.println("C'est problematique, j'eteint tout, c'est mieux");
|
System.err.println("C'est problematique, j'<EFBFBD><EFBFBD>teint tout, c'est mieux");
|
||||||
System.exit(31415926);
|
System.exit(31415926);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}catch(IllegalStateException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
System.err.println("Impossible de lire le fichier jar "+f.getName());
|
System.err.println("Impossible de lire le fichier jar "+f.getName());
|
||||||
@ -151,18 +176,49 @@ public class Julia {
|
|||||||
this.avalivableAddons = avalivableAddons;
|
this.avalivableAddons = avalivableAddons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ReadLoop implements Runnable{
|
||||||
|
|
||||||
|
boolean running = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
running = true;
|
||||||
|
try {
|
||||||
|
Scanner sc = new Scanner(new File(sysinPipe));
|
||||||
|
while(running) {
|
||||||
|
String request = sc.nextLine();
|
||||||
|
|
||||||
|
System.out.println("Je suis cens<6E><73> avoir lu la commande "+request);
|
||||||
|
//TODO r<EFBFBD><EFBFBD>agir ...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sc.close();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.err.println("Erreur de lecture du sysin, je deviens sourd");
|
||||||
|
e.printStackTrace();
|
||||||
|
running=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Laboratory{
|
public class Laboratory{
|
||||||
char laboratory;
|
char laboratory;
|
||||||
Map<String,JuliaAddon> loadedAddons;//<pkg,JuliaAddon>
|
Map<String,JuliaAddon> loadedAddons;//<pkg,JuliaAddon> : les addons charg<EFBFBD><EFBFBD>s dans ce laboratoire
|
||||||
Map<String,Method> loadedCommands;
|
Map<String,CommandeSurchargee> loadedCommands;//<commandName,Calling method> : les commandes charg<EFBFBD><EFBFBD>es
|
||||||
Map<Class<?>,Object> callerObjects;
|
Map<Class<?>,Object> callerObjects; // <Classe, objet de cette classe> : Les objets instanci<EFBFBD><EFBFBD>s dans ce laboratoire
|
||||||
Map<String,String> aliases;
|
Map<String,String> aliases;// <alias, vrainom>
|
||||||
Map<Class<? extends Event>,Set<Method>> loadedEvents;
|
Map<Class<? extends Event>,Set<Method>> loadedEvents;// Les m<EFBFBD><EFBFBD>thodes <EFBFBD><EFBFBD> appeler quand un event de cette classe est lanc<EFBFBD><EFBFBD>
|
||||||
Map<String,JuliaClassLoader> clazzTrack;//<className,JuliaClassLoader which loaded ths class in this laboratory>
|
Map<String,JuliaClassLoader> clazzTrack;//<className,JuliaClassLoader which loaded ths class in this laboratory>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Laboratory(char laboratory) {
|
public Laboratory(char laboratory) {
|
||||||
this.laboratory = laboratory;
|
this.laboratory = laboratory;
|
||||||
loadedAddons = new HashMap<>();
|
loadedAddons = new HashMap<>();
|
||||||
@ -170,6 +226,7 @@ public class Julia {
|
|||||||
aliases = new HashMap<>();
|
aliases = new HashMap<>();
|
||||||
loadedEvents = new HashMap<>();
|
loadedEvents = new HashMap<>();
|
||||||
clazzTrack = new HashMap<>();
|
clazzTrack = new HashMap<>();
|
||||||
|
callerObjects = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JuliaClassLoader findClassLoader(String className) {
|
public JuliaClassLoader findClassLoader(String className) {
|
||||||
@ -180,6 +237,7 @@ public class Julia {
|
|||||||
unloadAddon(pkg);
|
unloadAddon(pkg);
|
||||||
loadAddon(pkg, version);
|
loadAddon(pkg, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadAddon(String pkg,String version) {
|
public void loadAddon(String pkg,String version) {
|
||||||
this.loadAddon(pkg, version, true);
|
this.loadAddon(pkg, version, true);
|
||||||
}
|
}
|
||||||
@ -187,9 +245,9 @@ public class Julia {
|
|||||||
public synchronized void loadAddon(String pkg,String version,boolean update) {
|
public synchronized void loadAddon(String pkg,String version,boolean update) {
|
||||||
if(update)Julia.this.update();
|
if(update)Julia.this.update();
|
||||||
if(loadedAddons.containsKey(pkg))
|
if(loadedAddons.containsKey(pkg))
|
||||||
throw new IllegalStateException("Impossible de charger le juliaddon "+pkg+" dans le laboratoire "+laboratory+", il est déjà chargé");
|
throw new IllegalStateException("Impossible de charger le juliaddon "+pkg+" dans le laboratoire "+laboratory+", il est d<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD> charg<72><67>");
|
||||||
try {
|
try {
|
||||||
PreparedStatement s = juliaDatabase.prepareStatement("INSERT INTO juliaddons (laboratory,pkg,version) VALUES (?,?,?)");
|
PreparedStatement s = juliaDatabase.prepareStatement("INSERT INTO loadedJuliaddons (ID,laboratory,pkg,version) VALUES (NULL,?,?,?)");
|
||||||
s.setString(1, Character.toString(laboratory));
|
s.setString(1, Character.toString(laboratory));
|
||||||
s.setString(2, pkg);
|
s.setString(2, pkg);
|
||||||
s.setString(3, version);
|
s.setString(3, version);
|
||||||
@ -210,13 +268,13 @@ public class Julia {
|
|||||||
|
|
||||||
public synchronized void unloadAddon(String pkg) {
|
public synchronized void unloadAddon(String pkg) {
|
||||||
if(!loadedAddons.containsKey(pkg))
|
if(!loadedAddons.containsKey(pkg))
|
||||||
return;//SI l'addon n'est pas chargé, on a rien besoin de faire
|
return;//SI l'addon n'est pas charg<EFBFBD><EFBFBD>, on a rien besoin de faire
|
||||||
try {
|
try {
|
||||||
PreparedStatement s = juliaDatabase.prepareStatement("DELETE FROM juliaddons WHERE laboratory=? AND pkg=?");
|
PreparedStatement s = juliaDatabase.prepareStatement("DELETE FROM juliaddons WHERE laboratory=? AND pkg=?");
|
||||||
s.setString(1, Character.toString(laboratory));
|
s.setString(1, Character.toString(laboratory));
|
||||||
s.setString(2, pkg);
|
s.setString(2, pkg);
|
||||||
if(s.executeUpdate() != 1) {
|
if(s.executeUpdate() != 1) {
|
||||||
System.err.println("Ce juliaddon n'était pas chargé dans la BDD ... très bizzare");
|
System.err.println("Ce juliaddon n'<EFBFBD><EFBFBD>tait pas charg<72><67> dans la BDD ... tr<74><72>s bizzare");
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println("Je ne peux pas notifier la BDD que je unload le plugin, je l'unload mais vous risquez d'avoir des problemes ...");
|
System.err.println("Je ne peux pas notifier la BDD que je unload le plugin, je l'unload mais vous risquez d'avoir des problemes ...");
|
||||||
@ -229,34 +287,46 @@ public class Julia {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void registerCommand(Method m,Command c) {
|
public synchronized void registerCommand(Method m,Command c) {
|
||||||
if(loadedCommands.containsKey(c.name()))
|
if(!loadedCommands.containsKey(c.name()))
|
||||||
throw new IllegalStateException("Une commade "+c.name()+" a déjà été enregistrée !");
|
loadedCommands.put(c.name(), new CommandeSurchargee(c));
|
||||||
|
|
||||||
//Verify that commands asks for good argument
|
//Verify that commands asks for good argument
|
||||||
Class<?>[] parameters = m.getParameterTypes();
|
if(!Arrays.stream(m.getParameterTypes()).map(CCommande.class::isAssignableFrom).reduce(Boolean::logicalAnd).get())
|
||||||
if(parameters.length > 1)
|
throw new IllegalArgumentException("Les param<61><6D>tres d'une commande doivent tous impl<70><6C>menter CCommande");
|
||||||
throw new IllegalArgumentException("La méthode d'une commande ne peux prendre au maximum qu'un argument (de type CommandCall), la méthode fautive étant "+m.toGenericString());
|
|
||||||
if(parameters.length == 1 && parameters[0] == CommandCall.class)
|
try {
|
||||||
throw new IllegalArgumentException("La méthode d'une commande, si elle possede un argument, ce dernier doit tre de type CommandCall, la méthode fautive étant "+m.toGenericString());
|
m.setAccessible(true);
|
||||||
|
}catch(SecurityException e) {
|
||||||
|
throw new IllegalArgumentException("Impossible de me donner le droit d'<27><>xecuter "+m.toGenericString());
|
||||||
|
}
|
||||||
|
|
||||||
// Argument OK
|
// Argument OK
|
||||||
//Register aliases
|
//Register aliases
|
||||||
for(String alias:c.aliases()) {
|
// print un message d'erreur si un alias a d<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD> <EFBFBD><EFBFBD>t<EFBFBD><EFBFBD> enregistr<EFBFBD><EFBFBD> pour une autre commande
|
||||||
if(aliases.containsKey(alias))
|
Arrays.stream(c.aliases())
|
||||||
System.err.println("Faut remplacer l'alias "+alias+", plus de deux addons l'utilisent");
|
.filter(aliases::containsKey).filter(alias -> !aliases.get(alias).equals(c.name()))
|
||||||
aliases.put(alias, c.name());
|
.forEach(alias -> System.err.println("Faut remplacer l'alias "+alias+", plus de deux addons l'utilisent"));
|
||||||
}
|
Arrays.stream(c.aliases())
|
||||||
//Création de l'objet si ca n'a pas été fait
|
.filter(a -> !aliases.containsKey(a)).forEach(alias -> aliases.put(alias, c.name()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Cr<EFBFBD><EFBFBD>ation de l'objet si ca n'a pas <EFBFBD><EFBFBD>t<EFBFBD><EFBFBD> fait
|
||||||
checkObject(m.getDeclaringClass());
|
checkObject(m.getDeclaringClass());
|
||||||
loadedCommands.put(c.name(), m);
|
|
||||||
|
//Enregistre la nouvelle surcharge
|
||||||
|
loadedCommands.get(c.name()).surcharger(Arrays.stream(m.getParameterTypes()).collect(Collectors.toSet()), m);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")//It is, in reallity checked
|
@SuppressWarnings("unchecked")//It is, in reallity checked
|
||||||
public synchronized void registerEvent(Method m, Discord d) {
|
public synchronized void registerEvent(Method m, Discord d) {
|
||||||
Class<?>[] parameters = m.getParameterTypes();
|
Class<?>[] parameters = m.getParameterTypes();
|
||||||
if(parameters.length != 1)
|
if(parameters.length != 1)
|
||||||
throw new IllegalArgumentException("Les catcheurs d'events ne doivent avoir qu'un seul paramètre, extends Event, la méthde fautive étant "+m.toGenericString());
|
throw new IllegalArgumentException("Les catcheurs d'events ne doivent avoir qu'un seul param<EFBFBD><EFBFBD>tre, extends Event, la m<><6D>thde fautive <20><>tant "+m.toGenericString());
|
||||||
if(Event.class.isAssignableFrom(parameters[0]))
|
if(!Event.class.isAssignableFrom(parameters[0]))
|
||||||
throw new IllegalArgumentException("Les catcheur d'events ne doivent avoir qu'un paramètre, qui doit extends Event, la méthode fautive étant "+m.toGenericString());
|
throw new IllegalArgumentException("Les catcheur d'events ne doivent avoir qu'un param<EFBFBD><EFBFBD>tre, qui doit extends Event, la m<><6D>thode fautive <20><>tant "+m.toGenericString());
|
||||||
//La méthode est vérifiée
|
//La m<EFBFBD><EFBFBD>thode est v<EFBFBD><EFBFBD>rifi<EFBFBD><EFBFBD>e
|
||||||
if(!loadedEvents.containsKey(parameters[0]))
|
if(!loadedEvents.containsKey(parameters[0]))
|
||||||
loadedEvents.put((Class<? extends Event>) parameters[0], new HashSet<>());
|
loadedEvents.put((Class<? extends Event>) parameters[0], new HashSet<>());
|
||||||
checkObject(m.getDeclaringClass());
|
checkObject(m.getDeclaringClass());
|
||||||
@ -265,7 +335,7 @@ public class Julia {
|
|||||||
|
|
||||||
public synchronized void unregisterCommand(Method m,Command c) {
|
public synchronized void unregisterCommand(Method m,Command c) {
|
||||||
if(loadedCommands.containsKey(c.name()))
|
if(loadedCommands.containsKey(c.name()))
|
||||||
throw new IllegalStateException("Une commade "+c.name()+" a déjà été enregistrée !");
|
throw new IllegalStateException("Une commade "+c.name()+" a d<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD> <20><>t<EFBFBD><74> enregistr<74><72>e !");
|
||||||
//Unregister aliases
|
//Unregister aliases
|
||||||
for(String alias:c.aliases())
|
for(String alias:c.aliases())
|
||||||
aliases.remove(alias, c.name());//Evite de supprimer les alias d'autres commandes qui auraient overwrite
|
aliases.remove(alias, c.name());//Evite de supprimer les alias d'autres commandes qui auraient overwrite
|
||||||
@ -273,10 +343,10 @@ public class Julia {
|
|||||||
loadedCommands.remove(c.name());
|
loadedCommands.remove(c.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")//Pour un truc qui n'ets pas censé arriver, donc bon ...
|
@SuppressWarnings("unchecked")//Pour un truc qui n'ets pas cens<EFBFBD><EFBFBD> arriver, donc bon ...
|
||||||
public synchronized void unregisterEvent(Method m, Discord d) {
|
public synchronized void unregisterEvent(Method m, Discord d) {
|
||||||
Class<?>[] parameters = m.getParameterTypes();
|
Class<?>[] parameters = m.getParameterTypes();
|
||||||
if(!loadedEvents.containsKey(parameters[0]))//N'est pas censé arriver, si l'event a été load, cette HashSet devrai exister
|
if(!loadedEvents.containsKey(parameters[0]))//N'est pas cens<EFBFBD><EFBFBD> arriver, si l'event a <EFBFBD><EFBFBD>t<EFBFBD><EFBFBD> load, cette HashSet devrai exister
|
||||||
loadedEvents.put((Class<? extends Event>) parameters[0], new HashSet<>());
|
loadedEvents.put((Class<? extends Event>) parameters[0], new HashSet<>());
|
||||||
loadedEvents.get(parameters[0]).remove(m);
|
loadedEvents.get(parameters[0]).remove(m);
|
||||||
}
|
}
|
||||||
@ -294,6 +364,14 @@ public class Julia {
|
|||||||
case "java.lang.Character":
|
case "java.lang.Character":
|
||||||
params[i] = this.laboratory;
|
params[i] = this.laboratory;
|
||||||
break;
|
break;
|
||||||
|
case "java.sql.Connection":
|
||||||
|
params[i] = Julia.this.juliaDatabase;
|
||||||
|
break;
|
||||||
|
case "net.dv8tion.jda.core.JDA":
|
||||||
|
params[i] = Julia.this.jda;
|
||||||
|
break;
|
||||||
|
//TODO completer les param<EFBFBD><EFBFBD>tres
|
||||||
|
|
||||||
default:
|
default:
|
||||||
continue constLoop;
|
continue constLoop;
|
||||||
}
|
}
|
||||||
@ -303,21 +381,112 @@ public class Julia {
|
|||||||
//Tant pis, constructeur suivant
|
//Tant pis, constructeur suivant
|
||||||
continue constLoop;
|
continue constLoop;
|
||||||
}
|
}
|
||||||
if(o != null)break;//Sortir de la boucle, on a notre juli objet
|
if(o != null)break;//Sortir de la boucle, on a notre joli objet
|
||||||
}
|
}
|
||||||
if(o == null) {
|
if(o == null) {
|
||||||
System.err.println("Je ne peux pas créer l'objet, faudait mettre un costructeur valide (en mon sens :P)");
|
System.err.println("Je ne peux pas cr<EFBFBD><EFBFBD>er l'objet, faudait mettre un costructeur valide (en mon sens :P)");
|
||||||
System.err.println("Je fais tout planter du coup, votrez addon sera pas chargé !");
|
System.err.println("Je fais tout planter du coup, votrez addon sera pas charg<EFBFBD><EFBFBD> !");
|
||||||
throw new IllegalStateException("Pas de constructeur valable");
|
throw new IllegalStateException("Pas de constructeur valable");
|
||||||
}
|
}
|
||||||
|
callerObjects.put(clazz, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void trigger(Event event) {
|
public void trigger(Event event) {
|
||||||
// TODO Auto-generated method stub
|
Class<? extends Event> eventClass = event.getClass();
|
||||||
|
Set<Method> toCall = loadedEvents.get(eventClass);
|
||||||
|
for(Method m : toCall) {
|
||||||
|
Object callable = callerObjects.get(m.getDeclaringClass());
|
||||||
|
try {
|
||||||
|
m.invoke(callable, event);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
System.err.println("C'est pas joli joli, je suis cens<6E><73> lancer une m<><6D>thode <20><> laquelle je n'ai pas acc<63><63>s : "+m.toGenericString());
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.err.println("La m<><6D>thode n'est pas cens<6E><73>e recevoir de tels erreurs, je devrai avoir ch<63><68>ck<63><6B> la m<><6D>thode, mais elle ne veut pas de mes arguments ... : "+m.toGenericString());
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
System.err.println("La m<><6D>thode <20><> lanc<6E><63> cette exception ... je la relance derri<72><69>re du coup : "+m.toGenericString());
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandCalled executeCommand(String name, CCommande content) {
|
||||||
|
|
||||||
|
String cname = name;
|
||||||
|
|
||||||
|
if(aliases.containsKey(name))
|
||||||
|
cname = aliases.get(name);
|
||||||
|
if(!loadedCommands.containsKey(cname))
|
||||||
|
throw new IllegalArgumentException("Je ne connais ni la commande, ni l'alias "+cname);
|
||||||
|
|
||||||
|
|
||||||
|
CommandeSurchargee scommande = loadedCommands.get(cname);
|
||||||
|
Method m = scommande.getExecutor(content);
|
||||||
|
if(m==null)
|
||||||
|
throw new IllegalArgumentException("La commande "+cname+" alias "+name+" n'est pas pr<70><72>vue pour s'<27><>xecuter avec un "+content.getClass().getCanonicalName());
|
||||||
|
final Object[] parameters = new Object[m.getParameterCount()];
|
||||||
|
Arrays.fill(parameters, content);
|
||||||
|
final Object caller = callerObjects.get(m.getDeclaringClass());
|
||||||
|
|
||||||
|
final CommandCalled called = new CommandCalled(m, content, name, cname, caller);
|
||||||
|
|
||||||
|
|
||||||
|
Thread t = new Thread(() -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
m.invoke(caller, parameters);
|
||||||
|
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
System.err.println("Probl<EFBFBD><EFBFBD>me d'acc<63><63>s <20><> la m<><6D>thode "+m.toGenericString()+" ... c'est emb<6D><62>tant");
|
||||||
|
e.printStackTrace();
|
||||||
|
called.setExitValue(e.getCause());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.err.println("<EFBFBD><EFBFBD>trange, je pensais avoir check les arguments");
|
||||||
|
e.printStackTrace();
|
||||||
|
called.setExitValue(e.getCause());
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
//Lui a plant<EFBFBD><EFBFBD>
|
||||||
|
called.setExitValue(e.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
|
called.ended();
|
||||||
|
|
||||||
|
}, "commande-"+cname+".aka."+name+"-"+System.nanoTime());
|
||||||
|
|
||||||
|
called.setThread(t);
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
|
||||||
|
return called;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<String, JuliaAddon> getLoadedAddons() {
|
||||||
|
return loadedAddons;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, CommandeSurchargee> getLoadedCommands() {
|
||||||
|
return loadedCommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getAliases() {
|
||||||
|
return aliases;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Class<? extends Event>, Set<Method>> getLoadedEvents() {
|
||||||
|
return loadedEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getL() {
|
||||||
|
return laboratory;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,6 +496,7 @@ public class Julia {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
theJulia = new Julia();
|
theJulia = new Julia();
|
||||||
|
theJulia.startup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Julia theJulia() {
|
public static Julia theJulia() {
|
||||||
|
|||||||
@ -22,8 +22,8 @@ import com.bernard.juliabot.api.JuLIAddon;
|
|||||||
|
|
||||||
public class JuliaAddon {
|
public class JuliaAddon {
|
||||||
|
|
||||||
private static final Pattern pkgFromClassName = Pattern.compile("^(\\w(\\.\\w){2,})\\.\\w(\\$\\w)*$");
|
private static final Pattern pkgFromClassName = Pattern.compile("^(\\w+(\\.\\w+){2,})\\.\\w+(\\$\\w+)*$");
|
||||||
private static final Pattern jarNameParser = Pattern.compile("^([^_])_([^_])(_(.*))?.jar$");
|
private static final Pattern jarNameParser = Pattern.compile("^([^_]+)_([^_]+)(_(.+))?.jar$");
|
||||||
|
|
||||||
|
|
||||||
String pkg;
|
String pkg;
|
||||||
@ -51,27 +51,30 @@ public class JuliaAddon {
|
|||||||
|
|
||||||
//Parsing du nom du fichier
|
//Parsing du nom du fichier
|
||||||
Matcher jarMatcher = jarNameParser.matcher(jar.getName());
|
Matcher jarMatcher = jarNameParser.matcher(jar.getName());
|
||||||
jarMatcher.matches();
|
if(!jarMatcher.matches())
|
||||||
|
throw new IllegalStateException("Le fichier n'a pas un nom valide, je ne peux pas récupérer la version du juliaddon : "+jar.getName().split("/")[jar.getName().split("/").length-1]);
|
||||||
//String jarAddonName = jarMatcher.group(1);
|
//String jarAddonName = jarMatcher.group(1);
|
||||||
String jarVersion = jarMatcher.group(2);
|
String jarVersion = jarMatcher.group(2);
|
||||||
//String jarExtra = jarMatcher.group(3);
|
//String jarExtra = jarMatcher.group(3);
|
||||||
version = jarVersion;
|
version = jarVersion;
|
||||||
|
|
||||||
//Sets addon,pkg,version(si redefini) et addonClass
|
//Sets addon,pkg,version(si redefini) et addonClass
|
||||||
unassignedClassLoader = new JuliaClassLoader(jar, entriesToRead);
|
unassignedClassLoader = new JuliaClassLoader(jar, entriesToRead,new DummyLaboratory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public synchronized JuliaClassLoader newClassLoader(Laboratory laboratory) {
|
public synchronized JuliaClassLoader newClassLoader(Laboratory laboratory) {
|
||||||
if(unassignedClassLoader==null)
|
if(unassignedClassLoader==null)
|
||||||
try {
|
try {
|
||||||
JuliaClassLoader cl = new JuliaClassLoader(jarFile, loaderEntries);
|
JuliaClassLoader cl = new JuliaClassLoader(jarFile, loaderEntries,laboratory);
|
||||||
cl.laboratory = laboratory;
|
|
||||||
classLoaders.put(laboratory.laboratory, cl);
|
classLoaders.put(laboratory.laboratory, cl);
|
||||||
return cl;
|
return cl;
|
||||||
} catch (JarWithMultipleAddonsException e) {
|
} catch (JarWithMultipleAddonsException e) {
|
||||||
System.err.println("Cette erreur n'est pas censée arriver, alerte rouge");
|
System.err.println("Cette erreur n'est pas censée arriver, alerte rouge");
|
||||||
System.exit(685533990);
|
System.exit(685533990);
|
||||||
}
|
}
|
||||||
|
|
||||||
JuliaClassLoader cl = unassignedClassLoader;
|
JuliaClassLoader cl = unassignedClassLoader;
|
||||||
unassignedClassLoader = null;
|
unassignedClassLoader = null;
|
||||||
cl.laboratory = laboratory;
|
cl.laboratory = laboratory;
|
||||||
@ -79,10 +82,18 @@ public class JuliaAddon {
|
|||||||
return cl;
|
return cl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return addon.name();
|
return addon.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class JuliaClassLoader extends ClassLoader {
|
public class JuliaClassLoader extends ClassLoader {
|
||||||
|
|
||||||
Map<String,Class<?>> loadedClasses;
|
Map<String,Class<?>> loadedClasses;
|
||||||
@ -91,9 +102,10 @@ public class JuliaAddon {
|
|||||||
HashSet<Method> registeredCommands;
|
HashSet<Method> registeredCommands;
|
||||||
HashSet<Method> registeredEvents;
|
HashSet<Method> registeredEvents;
|
||||||
|
|
||||||
public JuliaClassLoader(JarFile jar,Set<JarEntry> entriesToRead) throws JarWithMultipleAddonsException {
|
public JuliaClassLoader(JarFile jar,Set<JarEntry> entriesToRead,Laboratory labo) throws JarWithMultipleAddonsException {
|
||||||
super();
|
super();
|
||||||
|
loadedClasses = new HashMap<>();
|
||||||
|
this.laboratory = labo;
|
||||||
Set<Class<?>> readClasses = new HashSet<>();
|
Set<Class<?>> readClasses = new HashSet<>();
|
||||||
Map<String,JarEntry> juliaddons = new HashMap<>();
|
Map<String,JarEntry> juliaddons = new HashMap<>();
|
||||||
for(JarEntry entry : entriesToRead) {
|
for(JarEntry entry : entriesToRead) {
|
||||||
@ -182,7 +194,6 @@ public class JuliaAddon {
|
|||||||
|
|
||||||
//Initialisation du JuliaClassloader
|
//Initialisation du JuliaClassloader
|
||||||
//Les parametres addon, pkg,version et addonCLass ont déjà été initialisés lors de l'itération des fichiers du jar
|
//Les parametres addon, pkg,version et addonCLass ont déjà été initialisés lors de l'itération des fichiers du jar
|
||||||
loadedClasses = new HashMap<>();
|
|
||||||
for(Class<?> clazz : readClasses)
|
for(Class<?> clazz : readClasses)
|
||||||
loadedClasses.put(clazz.getName(), clazz);
|
loadedClasses.put(clazz.getName(), clazz);
|
||||||
|
|
||||||
@ -193,7 +204,7 @@ public class JuliaAddon {
|
|||||||
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||||
if(loadedClasses.containsKey(name))
|
if(loadedClasses.containsKey(name))
|
||||||
return loadedClasses.get(name);
|
return loadedClasses.get(name);
|
||||||
|
//System.out.println("I was asked to load "+name);
|
||||||
JuliaClassLoader cl = laboratory.findClassLoader(name);
|
JuliaClassLoader cl = laboratory.findClassLoader(name);
|
||||||
if(cl != null)
|
if(cl != null)
|
||||||
try {
|
try {
|
||||||
@ -271,4 +282,12 @@ public class JuliaAddon {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class DummyLaboratory extends Julia.Laboratory{
|
||||||
|
|
||||||
|
public DummyLaboratory() {
|
||||||
|
Julia.theJulia().super(Character.MIN_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ public @interface Command {
|
|||||||
public String name();
|
public String name();
|
||||||
public String[] aliases() default {};
|
public String[] aliases() default {};
|
||||||
public String description();
|
public String description();
|
||||||
|
public String synopsis() default "";
|
||||||
public boolean admin();//TODO a remplacer par les permissions
|
public boolean admin();//TODO a remplacer par les permissions
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user