JuLIAnatheme/src/com/bernard/julianatheme/JuliAnathèmeManager.java

259 lines
10 KiB
Java

package com.bernard.julianatheme;
import java.awt.Color;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.reflections.Reflections;
import com.bernard.discord.api.Command;
import com.bernard.discord.api.Discord;
import com.bernard.julianatheme.JuLIAnatheme.InvalidAnathemDescriptionException;
import net.dv8tion.jda.core.EmbedBuilder;
import net.dv8tion.jda.core.MessageBuilder;
import net.dv8tion.jda.core.entities.*;
import net.dv8tion.jda.core.events.Event;
public class JuliAnathèmeManager {
Map<Class<? extends JuLIAnatheme>,Set<JuLIAnatheme>> anathemes = new HashMap<>();
static Map<String,Class<? extends JuLIAnatheme>> registeredAnathemes = new HashMap<>();
static Map<Class<? extends Event>,Set<Method>> registeredEvents = new HashMap<>();
public static final String anathemeNamePattern = "^[a-zA-Z0-9_-]*$";
static {
//Load everybody
Reflections r = new Reflections("");
for (Class<? extends JuLIAnatheme> clazz : r.getSubTypesOf(JuLIAnatheme.class)) {
try {
registerAnatheme(clazz.getField("NAME").get(null).toString(), clazz);
} catch (Exception e) {
registerAnatheme(clazz.getSimpleName(), clazz);
}
}
}
@Discord(description="Lance les évents de toutes les malédictions chagées")
public void anathemeEvent(Event e){
System.out.println("Alors l'event "+e.toString());
Set<Method> callList = registeredEvents.getOrDefault(e.getClass(), new HashSet<>()) ;
for(Method m : callList) {
Set<JuLIAnatheme> callObjects = anathemes.getOrDefault(m.getDeclaringClass(), new HashSet<>());
for(JuLIAnatheme o : callObjects) {
try {
m.invoke(o, e);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException err) {
System.err.println("Cette erreur n'est pas censée arrivée. Source : JuLI'Anathème event dispacher.");
err.printStackTrace();
}
}
}
}
@Command(admin=true,name="maudir",group="JuL'IAnathème",grp="janatheme",description="Maudit une personne. Usage 'maudir <@pseudo> <type> <extra>")
public void maudir(Message m,Guild g) {
if(m.getMentionedUsers().size() < 1) {
notifyUser("Il faut notifier l'utilisateur qu vous voulez maudir", m.getAuthor(), m.getChannel());
return;
}
String[] splitted = m.getContentRaw().split(" ");
if(splitted.length < 3) {
notifyUser("Veuillez utiliser la commande comme il faut (l'IA n'est pas encore prevue pour vous corriger). Regardez le !!help si probleme.", m.getAuthor(), m.getChannel());
return;
}
System.out.println("Splitted : "+Arrays.toString(splitted));
Member cible = g.getMember(m.getMentionedUsers().get(0));
Member source = g.getMember(m.getAuthor());
String type = splitted[2];
if(!registeredAnathemes.containsKey(type)) {
notifyUser("Je ne connais pas ce type de malédiction : "+type+", Et du coup j'ai maudit personne", m.getAuthor(), m.getChannel());
return;
}
Class<? extends JuLIAnatheme> julianathemeType = registeredAnathemes.get(type);
String extra = "";
if(splitted.length > 3)
extra = splitted[3];
JuLIAnatheme anatheme;
try {
anatheme = registeredAnathemes.get(type).getConstructor(Member.class,Member.class).newInstance(cible,source);
if(anatheme == null)
throw new NullPointerException("Le constructeur n'a pas renvoyé d'anathème (je veut pas savoir comment vous avez fait)");
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException | NullPointerException e) {
notifyUser("Je n'ai pas pu lancer la malédiction ... discutez du problème avec le dev de la malédiction (vous pouvez aussi lui montrer ça)", m.getAuthor(), m.getChannel());
EmbedBuilder builder = new EmbedBuilder();
builder.setTitle("Voila le log :");
builder.addField(e.getClass().getCanonicalName(),e.getLocalizedMessage(),false);
builder.setColor(Color.red);
m.getChannel().sendMessage(builder.build()).complete();
return;
}
try {
anatheme.initialize(extra,g);
} catch (InvalidAnathemDescriptionException e) {
MessageBuilder builder = new MessageBuilder();
builder.append("Vous ne pouvez pas créer d'anathème avec cet extra :\n");
builder.append("`"+extra+"` -> ");
builder.appendCodeBlock(e.getMessage(), null);
m.getChannel().sendMessage(builder.build()).complete();
return;
}
System.out.println("Boucle");
System.out.println(anathemes);
System.out.println(julianathemeType);
if(!anathemes.containsKey((julianathemeType)))
anathemes.put(julianathemeType, new HashSet<>());
for (JuLIAnatheme testingAnatheme : anathemes.get(julianathemeType))
if(testingAnatheme.cible.getUser().getIdLong() == cible.getUser().getIdLong()) {
notifyUser("Je n'ai pas pu lancer la malédiction ... cet utilisateur a déja été maudit, veuillez enlever puis refaire votre malédiction", m.getAuthor(), m.getChannel());
return;//TODO Utiliser ci la fonction add (surenchère de julianatheme)
}
anathemes.get(julianathemeType).add(anatheme);
System.out.println("Fin");
System.out.println(anathemes);
System.out.println(julianathemeType);
}
@Command(admin=true,name="oracle",group="JuL'IAnathème",grp="janatheme",description="Demande à l'oracle, quelles sont les maledictions planant sur une personne. Usage: 'oracle <@pseudo>")
public void oracle(Message m,Guild g) {
if(m.getMentionedUsers().size() < 1) {
notifyUser("Il faut notifier l'utilisateur qu vous voulez 'oracler'", m.getAuthor(), m.getChannel());
return;
}
Member cible = g.getMember(m.getMentionedUsers().get(0));
Set<JuLIAnatheme> anathemes = new HashSet<>();
for(Entry<Class<? extends JuLIAnatheme>,Set<JuLIAnatheme>> anathemez : this.anathemes.entrySet())
for (JuLIAnatheme testingAnatheme : anathemez.getValue())
if(testingAnatheme.cible.getUser().getIdLong() == cible.getUser().getIdLong()) {
anathemes.add(testingAnatheme);
break;
}
//Analyser les maledictions et les dump
if(anathemes.isEmpty()) {
MessageBuilder builder = new MessageBuilder();
builder.append(cible);
builder.append(" : Cette personne est pure ... pour l'instant");
m.getChannel().sendMessage(builder.build()).complete();
return;
}
EmbedBuilder dumper = new EmbedBuilder();
dumper.setTitle("Anathemes planant sur "+cible.getNickname());
dumper.setColor(Color.ORANGE);
for (JuLIAnatheme juLIAnatheme : anathemes) {
dumper.addField(juLIAnatheme.getClass().getSimpleName(), juLIAnatheme.dump(), false);
}
m.getChannel().sendMessage(dumper.build()).complete();
}
@Command(admin=true,name="exorciser",group="JuL'IAnathème",grp="janatheme",description="Excorcise une personne (lui enlève sa malediction). Usage 'exoriser <@pseudo> <type>")
public void exorciser(Message m,Guild g) {
if(m.getMentionedUsers().size() < 1) {
notifyUser("Il faut notifier l'utilisateur qu vous voulez exorciser", m.getAuthor(), m.getChannel());
return;
}
String[] splitted = m.getContentRaw().split(" ");
if(splitted.length < 3) {
notifyUser("Veuillez utiliser la commande comme il faut (l'IA n'est pas encore prevue pour vous corriger). Regardez le !!help si probleme.", m.getAuthor(), m.getChannel());
return;
}
System.out.println("Splitted : "+Arrays.toString(splitted));
Member cible = g.getMember(m.getMentionedUsers().get(0));
String type = splitted[2];
if(!registeredAnathemes.containsKey(type)) {
notifyUser("Je ne connais pas ce type de malédiction : "+type+", Et du coup j'ai rien fait", m.getAuthor(), m.getChannel());
return;
}
Class<? extends JuLIAnatheme> theClass = registeredAnathemes.get(type);
Set<JuLIAnatheme> anathemes = this.anathemes.get(theClass);
JuLIAnatheme aSupprimer = null;
for (JuLIAnatheme anatheme : anathemes)
if(anatheme.cible.getUser().getIdLong() == cible.getUser().getIdLong())
aSupprimer = anatheme;
if(aSupprimer == null) {
MessageBuilder builder = new MessageBuilder();
builder.append(cible);
builder.append(" : Cette personne est pure ... pour l'instant");
m.getChannel().sendMessage(builder.build()).complete();
return;
}
anathemes.remove(aSupprimer);
notifyUser("Ohhhh "+cible.getNickname()+" a été purifié !!! Son anathème "+type+" a disparu !",m.getAuthor(), m.getChannel());
}
public static void registerAnatheme(String name, Class<? extends JuLIAnatheme> clazz) {
System.out.println("Je vais registerer "+name);
if(clazz == null) {
System.err.println("Bon ben ... j'ajoute aucune classe ...");
return;
}
if(name == null || name.isEmpty()) {
System.err.println("Il faut mettre un nom sur le carnet de naissance SVP");
return;
}
if(!Pattern.matches(anathemeNamePattern, name)) {
System.err.println("Vous l'aimez pas votre enfant ? Donnez-lui un nom mieux que "+name+" (qui match \""+anathemeNamePattern+"\"!");
return;
}
if(!JuLIAnatheme.class.isAssignableFrom(clazz)) {
System.err.println("Cette classe "+clazz.getCanonicalName()+" n'est pas fille de JuLIAnatheme (et bien ... il faut)");
return;
}
try {
clazz.getConstructor(Member.class,Member.class);
} catch (NoSuchMethodException | SecurityException e) {
System.err.println("Cette classe "+clazz.getCanonicalName()+" n'a pas de constructeur avec deux paramètres 'Member' (cible et source) ou bien n'est pas accessible.");
return;
}
//Get events
Method[] mtds = clazz.getMethods();
for(Method m : mtds) {
if(m.getAnnotationsByType(EventReciever.class).length > 0) {
Class<?>[] pmts = m.getParameterTypes();
if(pmts.length != 1 || Event.class.isAssignableFrom(pmts[0])){
System.err.println("La methode "+m.getName()+" de la classe "+clazz.getName()+" possède l'annotation EventReciever mais ne possède pas un seul argument de type enfant de Event");
return;
}
}
}
registeredAnathemes.put(name, clazz);
}
public void sheduleDataSaving() {
Thread t = new Thread(()-> {
//TODO implement data saving in BDD (file as default)
},"JuL'IAnathèmeDataSaving");
t.start();
}
public static final void notifyUser(String problem,User user,MessageChannel channel) {
MessageBuilder builder = new MessageBuilder();
builder.append(user);
builder.append(" : ");
builder.append(problem);
user.openPrivateChannel().queue((chan) ->
{
chan.sendMessage(builder.build()).queue();
});
}
}