commit 39edd9bee6b09856ae927e555345ba8f2fc75f42 Author: Mysaa Date: Mon May 24 14:57:50 2021 +0200 Premier commit - Inclusion dans le projet git diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e108870 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.classpath +.project +.settings +bin/ diff --git a/src/com/bernard/juliapoll/CommandCommander.java b/src/com/bernard/juliapoll/CommandCommander.java new file mode 100644 index 0000000..ae58e5d --- /dev/null +++ b/src/com/bernard/juliapoll/CommandCommander.java @@ -0,0 +1,262 @@ +package com.bernard.juliapoll; + +import static com.bernard.juliapoll.PollManager.pollID; + +import java.awt.Color; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +import com.bernard.discord.api.Command; + +import net.dv8tion.jda.core.EmbedBuilder; +import net.dv8tion.jda.core.MessageBuilder; +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.IMentionable; +import net.dv8tion.jda.core.entities.Message; +import net.dv8tion.jda.core.entities.TextChannel; + +public class CommandCommander { + + @Command(name="poll",description="Gère les scrutins",admin=false,group="JuLIAPoll",grp="poll") + public void poll(Guild g, TextChannel chan, Message m){ + String[] args = m.getContentRaw().split(" "); + if(args.length < 2) { + commandReturn(m.getAuthor(), "Cette commande prends au moins un argument : l'action a effectuer (voir !!poll help)", chan); + return; + } + switch(args[0]) { + case "create": + case "new": + case "nouveau": + case "créer": + case "add": + case "ajouter": + //!!poll ajouter pollName addable durée votesParPersonne votants(GroupID) couleur(hexa) + String pollName; + boolean addable = false; + int durée = 3600*24; + Integer votesParPersonne = 1; + Long votants = -1L; + Color color = Color.getHSBColor((float)Math.random(), 1.0f, 1.0f); + switch(args.length) { + default: + commandReturn(m.getAuthor(), "Il y a trop d'arguments dans cette commande, je ne prends que les premiers", chan); + case 8: + try { + color = Color.decode(args[7]); + }catch(NumberFormatException e) { + commandReturn(m.getAuthor(), "J'ai pas compris cette couleur : "+args[7]+" ``` "+e.getLocalizedMessage() + "```", chan); + return; + } + + case 7: + try { + votants = Long.parseLong(args[6]); + }catch(NumberFormatException e) { + commandReturn(m.getAuthor(), "J'ai pas compris cet ID de groupe ... : "+args[6]+" ``` "+e.getLocalizedMessage() + "```", chan); + return; + } + if(g.getRoleById(votants) == null) + commandReturn(m.getAuthor(), "L'ID de groupe "+args[6]+" ne correspond a aucun groupe .... je l'enregistre mais sans conviction", chan); + + case 6: + try { + votesParPersonne = Integer.parseInt(args[5]); + }catch(NumberFormatException e) { + commandReturn(m.getAuthor(), "J'ai pas compris ce nombre de votes ... : "+args[5]+" ``` "+e.getLocalizedMessage() + "```", chan); + return; + } + + case 5: + if(!Pattern.matches("[0-9]+(s|m|h|j)?",args[4])) { + commandReturn(m.getAuthor(), "J'ai pas compris cette durée de scrutin ... : "+args[4]+" \n\t (pour info, la regex à match c'est \"[0-9]+(s|m|h|j)?\"", chan); + return; + } + char suffix = args[4].charAt(args[4].length()-1); + String data = args[4]; + if(Character.isDigit(suffix)) + suffix='s'; + else + data = data.substring(0, data.length()-2); + durée = Integer.parseInt(data); + switch(suffix) { + case 'j': durée *= 24; + case 'h': durée *= 60; + case 'm': durée *= 60; + } + + case 4: + addable = Pattern.compile("^(true|false|ok|oui|ja|da|okiedokie|d'accord|agree|ouais|vrai|richtig|right|gut)$", Pattern.CASE_INSENSITIVE).matcher(args[3]).find(); + case 3: + pollName = args[2]; + if(!Pattern.matches("^[a-zA-Z0-9-_~.]+$", pollName)) { + commandReturn(m.getAuthor(), "ERREUR: nom de scrutin illégal ... : "+args[4]+" \n\t (pour info, la regex à match c'est \"^[a-zA-Z0-9-_~.]+$\"", chan); + return; + } + break; + case 2: + commandReturn(m.getAuthor(), "Cette commande prends au moins UN argument obligatoire (le nom du poll créé)", chan); + return; + } + + Date finalDate = Date.from(new Date().toInstant().plus(durée, ChronoUnit.SECONDS)); + + JuliaPoll poll = new JuliaPoll(pollName, addable, votesParPersonne, new HashMap<>(), votants, m.getChannel(), finalDate, m.getAuthor().getIdLong(), color, g); + + PollManager.registerPoll(g, poll); + + commandReturn(m.getAuthor(), "Poll créé, amusez vous bien !", chan); + + break; + + case "option": + case "options": + case "propositions": + case "choix": + case "choices": + + if(args.length < 3) { + commandReturn(m.getAuthor(), "Cette commande '"+args[1]+"' prends au moins un argument : le nom du poll a modifier (voir !!poll help)", chan); + return; + } + if(PollManager.checkPoll(pollID(g, args[2]))) { + commandReturn(m.getAuthor(), "Je ne connais pas le poll "+args[2], chan); + return; + } + + + //Parsing + Map addedOptions = new HashMap<>(); + Set removedOptions = new HashSet<>(); + char state = '}'; + String emote = "", text = ""; + for(int i = 3;i options; // Emoji -> Option + long votants; + MessageChannel channel; + Date finalTime; + long creator; + Color color; + Map> results = new HashMap<>(); + Map votes = new HashMap<>(); + + + public JuliaPoll(String nom, boolean addable, int voix, Map options, long votants, + MessageChannel channel, Date finalTime, long creator, Color color,Guild guild) { + this.nom = nom; + this.addable = addable; + this.voix = voix; + this.options = options; + this.votants = votants; + this.channel = channel; + this.finalTime = finalTime; + this.creator = creator; + this.color = color; + this.guild = guild; + } + + + + public MessageEmbed toMessage() { + EmbedBuilder builder = new EmbedBuilder(); + + builder.setTitle(this.nom); + + builder.setColor(this.color); + + for(Map.Entry e : options.entrySet()) { + builder.addField(e.getKey() + " : " + e.getValue(), null, true); + } + + builder.setAuthor("Poll de "+guild.getMemberById(creator).getEffectiveName()+" proposé par votre BOT préféré",null,null); + + return builder.build(); + } + + public MessageEmbed toResultMessage() { + EmbedBuilder builder = new EmbedBuilder(); + + builder.setTitle(this.nom); + + builder.setColor(this.color); + + for(Map.Entry e : options.entrySet()) { + builder.addField(e.getKey() + " : " + results.get(e.getKey()).size() + " voix", null, true); + } + + builder.setAuthor("Poll de "+guild.getMemberById(creator).getEffectiveName()+" proposé par votre BOT préféré",null,null); + + return builder.build(); + } + + + + public String getNom() { + return nom; + } + public void setNom(String nom) { + this.nom = nom; + } + public boolean isAddable() { + return addable; + } + public void setAddable(boolean addable) { + this.addable = addable; + } + public int getVoix() { + return voix; + } + public void setVoix(int voix) { + this.voix = voix; + } + public Map getOptions() { + return options; + } + public long getVotants() { + return votants; + } + public void setVotants(long votants) { + this.votants = votants; + } + public MessageChannel getChannel() { + return this.channel; + } + public void setChannel(MessageChannel channel) { + this.channel = channel; + } + public Date getFinalTime() { + return finalTime; + } + public void setFinalTime(Date finalTime) { + this.finalTime = finalTime; + } + public long getCreator() { + return creator; + } + + + + public void setCreator(long creator) { + this.creator = creator; + } + + + + public Color getColor() { + return color; + } + + + + public void setColor(Color color) { + this.color = color; + } + + + + public Map> getResults() { + return results; + } + + public Map getVotes() { + return votes; + } + + + @Override + public String toString() { + return "JuliaPoll [nom=" + nom + ", addable=" + addable + ", voix=" + voix + ", options=" + options + + ", votants=" + votants + ", channel=" + channel + ", finalTime=" + finalTime + ", creator=" + creator + + ", color=" + color + "]"; + } + +} diff --git a/src/com/bernard/juliapoll/PollManager.java b/src/com/bernard/juliapoll/PollManager.java new file mode 100644 index 0000000..a355ba6 --- /dev/null +++ b/src/com/bernard/juliapoll/PollManager.java @@ -0,0 +1,135 @@ +package com.bernard.juliapoll; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.Message; +import net.dv8tion.jda.core.entities.MessageChannel; +import net.dv8tion.jda.core.entities.MessageEmbed; +import net.dv8tion.jda.core.entities.User; + +public class PollManager { + + static Map polls; + static Map messages; + static Map messagesResult; + + public static boolean checkPoll(int ID) { + return polls.containsKey(ID); + } + + public static Integer pollID(Guild g, String name) { + return (g.getId() + name).hashCode(); + } + + public static void registerPoll(Guild g, JuliaPoll j) { + int ID = pollID(g, j.getNom()); + polls.put(ID, j); + postPollMessage(j.getChannel(), ID); + } + + public static void endPoll(Guild g, Integer ID) { + JuliaPoll j = polls.get(ID); + if(!messagesResult.containsValue(ID)) + printResults(g, ID, j.getChannel()); + updatePoll(g, ID); + + + polls.remove(ID); + //Dé référence les messages de vote et de résultat + messages.values().removeIf(id -> ID==id); + messagesResult.values().removeIf(id -> ID==id); + } + + public static void printResults(Guild g, Integer ID, MessageChannel messageChannel) { + MessageEmbed message = polls.get(ID).toResultMessage(); + Message sent = messageChannel.sendMessage(message).complete(); + messagesResult.put(sent, ID); + } + + public static void addOption(Integer ID, String emoji, String option) { + polls.get(ID).getOptions().put(emoji, option); + } + + public static void manageOptions(Integer ID, Map addedOptions, Set removedOptions) { + JuliaPoll poll = polls.get(ID); + poll.getOptions().putAll(addedOptions); + for(String emote : removedOptions) { + poll.getOptions().remove(emote); + } + } + + public static void postPollMessage(MessageChannel messageChannel,Integer ID) { + MessageEmbed message = polls.get(ID).toMessage(); + Message sent = messageChannel.sendMessage(message).complete(); + messages.put(sent, ID); + } + + public static void updatePoll(Guild g,Integer ID) { + //edit tous les messages de poll + List toUpdate = getKeysFromValue(messages, ID); + List toResultUpdate = getKeysFromValue(messagesResult, ID); + MessageEmbed pollMessage = polls.get(ID).toMessage(); + MessageEmbed pollResultMessage = polls.get(ID).toResultMessage(); + + for(Message m : toUpdate) + m.editMessage(pollMessage).queue(); + for(Message m : toResultUpdate) + m.editMessage(pollResultMessage).queue(); + } + + public static int vote(User u,String vote, Integer ID) { + JuliaPoll j = polls.get(ID); + if(!j.getVotes().containsKey(u)) + j.getVotes().put(u, 0); + if(j.getVotes().get(u) >= j.getVoix()) + return -1;//A déjà trop voté + if(!j.getResults().containsKey(vote)) + j.getResults().put(vote, new HashSet<>()); + if(!j.getResults().get(vote).add(u)) + return -2;//Avait déjà voté + j.getVotes().replace(u,j.getVotes().get(u)+1); + return 42;//Tout c'est bien passé + } + + public static int unvote(User u,String vote, Integer ID) { + JuliaPoll j = polls.get(ID); + if(!j.getResults().containsKey(vote)) + j.getResults().put(vote, new HashSet<>()); + if(!j.getResults().get(vote).remove(u)) + return -2;//N'avais pas voté + j.getVotes().replace(u,j.getVotes().get(u)-1);//Pas possible de ne pas etre set + return 42;//Tout c'est bien passé + } + + + + + + + + + static List getKeysFromValue(Map mapOfWords, V value) + { + List listOfKeys = new ArrayList<>(); + + // Iterate over each entry of map using entrySet + for (Map.Entry entry : mapOfWords.entrySet()) + { + // Check if value matches with given value + if (entry.getValue().equals(value)) + { + // Store the key from entry to the list + listOfKeys.add(entry.getKey()); + } + } + + // Return the list of keys whose value matches with given value. + return listOfKeys; + } + +}