Added the Poll module V1
This commit is contained in:
parent
0817607697
commit
d6c272cdaf
3
SheepstarModules/PollV1/.gitignore
vendored
Normal file
3
SheepstarModules/PollV1/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Project exclude paths
|
||||
/target/
|
||||
.idea
|
2
SheepstarModules/PollV1/README.md
Normal file
2
SheepstarModules/PollV1/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# SheepstarModule-Poll
|
||||
The official sheepstar poll module
|
24
SheepstarModules/PollV1/pom.xml
Normal file
24
SheepstarModules/PollV1/pom.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>xyz.sheepstar</groupId>
|
||||
<artifactId>SheepstarModule-Poll</artifactId>
|
||||
<version>pre1.0.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>xyz.sheepstar</groupId>
|
||||
<artifactId>SheepstarCore</artifactId>
|
||||
<version>beta1.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,27 @@
|
||||
package xyz.sheepstar.poll.action;
|
||||
|
||||
import xyz.sheepstar.poll.api.controller.PollController;
|
||||
import xyz.sheepstar.poll.api.models.PollManager;
|
||||
import xyz.sheepstar.poll.core.PollCore;
|
||||
import xyz.sheepstar.util.action.RepeatedAction;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class AutomaticCloseAction extends RepeatedAction {
|
||||
|
||||
private final PollManager pollManager = (PollManager) api.getDatabase().getTableFactory().getTable(PollManager.class);
|
||||
private final PollController pollController = PollCore.getPollController();
|
||||
|
||||
@Override
|
||||
public long time() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
pollManager.getExpirablePolls().forEach((pollID, dateTime) -> {
|
||||
if (dateTime.compareTo(LocalDateTime.now()) <= 0)
|
||||
pollController.endPoll(pollID, pollManager.getPollById(pollID).getGuild());
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package xyz.sheepstar.poll.api.controller;
|
||||
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.interactions.components.ButtonStyle;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import xyz.sheepstar.poll.api.entities.Poll;
|
||||
import xyz.sheepstar.poll.api.models.PollAnswerManager;
|
||||
import xyz.sheepstar.poll.api.models.PollManager;
|
||||
import xyz.sheepstar.poll.commands.ClosePollCommand;
|
||||
import xyz.sheepstar.util.bot.builder.message.DefaultEmbedBuilder;
|
||||
import xyz.sheepstar.util.bot.builder.message.DefaultResponseBuilder;
|
||||
import xyz.sheepstar.util.bot.builder.message.MessageType;
|
||||
import xyz.sheepstar.util.bot.listener.ListenerBasics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PollController extends ListenerBasics {
|
||||
|
||||
private PollManager pollManager = (PollManager) table(PollManager.class);
|
||||
private PollAnswerManager pollAnswerManager = (PollAnswerManager) table(PollAnswerManager.class);
|
||||
|
||||
/**
|
||||
* Gets the number emoji by number
|
||||
*
|
||||
* @param number The number the emoji should display
|
||||
* @return the number as emoji
|
||||
*/
|
||||
private Emoji getEmojiByNumber(int number) {
|
||||
return Emoji.fromUnicode(number + "️⃣");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'started'-message of the poll
|
||||
*
|
||||
* @param pollID The id of the poll (used for the end button)
|
||||
* @param date The date when the poll should expire
|
||||
* @param title The title of the poll
|
||||
* @param description The description of the poll
|
||||
* @param answers All answers available in this poll
|
||||
* @param guild The guild which created the poll
|
||||
* @param closeButton Should the close button be displayed?
|
||||
* @param multipleChoices Are multiple choices allowed?
|
||||
* @return the final message
|
||||
*/
|
||||
public Message getStartedPollMessage(String pollID, Date date, String title, String description, ArrayList<String> answers, Guild guild,
|
||||
boolean closeButton, boolean multipleChoices) {
|
||||
DefaultResponseBuilder response = DefaultResponseBuilder.createSimple(guild, ClosePollCommand.class).withColor(MessageType.PRIMARY)
|
||||
.withTitle(translate("poll.poll_started", guild));
|
||||
|
||||
response.addField(":label: " + translate("poll.object.title", guild), title);
|
||||
|
||||
if (description != null)
|
||||
response.addField(":clipboard: " + translate("poll.object.description", guild), description);
|
||||
|
||||
ArrayList<String> subFields = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < answers.size(); i++)
|
||||
subFields.add(getEmojiByNumber(i + 1).getAsMention() + " - " + answers.get(i));
|
||||
|
||||
response.addField(":ballot_box: " + translate("poll.object." + (multipleChoices ? "multiple_" : "") + "choices", guild) + "", subFields);
|
||||
|
||||
if (date != null)
|
||||
response.addField(String.format("\n:alarm_clock: %s <t:%s:R>", translate("poll.ends", guild), date.getTime() / 1000));
|
||||
|
||||
if (closeButton)
|
||||
response.addButton(ButtonStyle.DANGER, "end#" + pollID, date == null ? translate("poll.end_poll", guild) : translate("poll.end_now", guild));
|
||||
|
||||
return response.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'ended'-message of the poll
|
||||
*
|
||||
* @param poll The poll you want to get the message from
|
||||
* @return The final 'ended'-message
|
||||
*/
|
||||
public Message getEndedPollMessage(Poll poll) {
|
||||
DefaultEmbedBuilder embedBuilder = new DefaultEmbedBuilder(MessageType.PRIMARY).setTitle(translate("poll.poll_ended", poll.getGuild()));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
boolean isTimeMessage = false;
|
||||
for (String line : poll.getMessage().getEmbeds().get(0).getDescription().split("\n")) {
|
||||
if (line.startsWith(":alarm_clock:")) isTimeMessage = true;
|
||||
if (!line.startsWith(":alarm_clock:")) builder.append(line).append("\n");
|
||||
}
|
||||
|
||||
embedBuilder.setDescription((!isTimeMessage ? builder + "\n" : builder.substring(0, builder.length() - 3)));
|
||||
|
||||
HashMap<String, Integer> reaction_counts = new HashMap<>();
|
||||
|
||||
poll.getMessage().getReactions().forEach(reaction -> {
|
||||
if (reaction.getReactionEmote().isEmoji())
|
||||
reaction_counts.put(reaction.getReactionEmote().getEmoji(), reaction.getCount() - 1);
|
||||
});
|
||||
|
||||
ArrayList<String> subFields = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < poll.getAnswers().size(); i++)
|
||||
subFields.add(getEmojiByNumber(i + 1).getAsMention() + " - " + reaction_counts.getOrDefault(getEmojiByNumber(i + 1).getAsMention(), 0));
|
||||
|
||||
embedBuilder.addBField(":abacus: " + translate("poll.object.results", poll.getGuild()), subFields.toArray(new String[0]));
|
||||
|
||||
return embedBuilder.toMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new poll
|
||||
*
|
||||
* @param channel The channel the poll should be created in
|
||||
* @param date The date when the poll should expire
|
||||
* @param title The title of the poll
|
||||
* @param description The description of the poll
|
||||
* @param answers All answers available in this poll
|
||||
* @param closeButton Should the close button be displayed?
|
||||
* @param multipleChoices Are multiple choices allowed?
|
||||
* @return the id of the created poll
|
||||
*/
|
||||
public String createPoll(TextChannel channel, Date date, String title, String description, ArrayList<String> answers, boolean closeButton, boolean multipleChoices) {
|
||||
String pollID = RandomStringUtils.randomAlphanumeric(10);
|
||||
|
||||
pollAnswerManager.addAnswers(pollID, answers);
|
||||
|
||||
channel.sendMessage(getStartedPollMessage(pollID, date, title, description, answers, channel.getGuild(), closeButton, multipleChoices)).queue(message -> {
|
||||
pollManager.createPoll(pollID, message, date);
|
||||
for (int i = 0; i < answers.size(); i++)
|
||||
message.addReaction(getEmojiByNumber(i + 1).getAsMention()).queue();
|
||||
});
|
||||
return pollID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the provided poll
|
||||
*
|
||||
* @param pollID The poll you want to end
|
||||
* @param guild The guild which created the poll
|
||||
* @return <code>true</code> if the poll has been ended successfully, otherwise <code>false</code>
|
||||
*/
|
||||
public boolean endPoll(String pollID, Guild guild) {
|
||||
if (!pollManager.isCreated(pollID, guild)) return false;
|
||||
|
||||
try {
|
||||
Poll poll = pollManager.getPollById(pollID);
|
||||
|
||||
poll.getMessage().editMessage(getEndedPollMessage(poll)).queue();
|
||||
|
||||
poll.getMessage().clearReactions().queue();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pollManager.deletePoll(pollID, guild);
|
||||
pollAnswerManager.deleteAnswers(pollID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package xyz.sheepstar.poll.api.entities;
|
||||
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import xyz.sheepstar.core.SheepstarCore;
|
||||
import xyz.sheepstar.poll.api.models.PollAnswerManager;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Poll {
|
||||
|
||||
private PollAnswerManager pollAnswerManager = (PollAnswerManager) SheepstarCore
|
||||
.getSheepstar().getDatabase().getTableFactory().getTable(PollAnswerManager.class);
|
||||
|
||||
private String pollID;
|
||||
private Guild guild;
|
||||
private TextChannel channel;
|
||||
private Message message;
|
||||
private LocalDateTime expiryDate;
|
||||
private ArrayList<String> answers;
|
||||
|
||||
/**
|
||||
* Basic constructor of the {@link Poll} entity
|
||||
*
|
||||
* @param pollID The id of the poll
|
||||
* @param message The poll message created by the bot
|
||||
* @param expiryDate The date when the poll should expire
|
||||
*/
|
||||
public Poll(String pollID, Message message, LocalDateTime expiryDate) {
|
||||
this.pollID = pollID;
|
||||
this.message = message;
|
||||
this.guild = message.getGuild();
|
||||
this.channel = message.getTextChannel();
|
||||
this.expiryDate = expiryDate;
|
||||
this.answers = pollAnswerManager.getAnswers(pollID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the poll id
|
||||
*
|
||||
* @return the poll id
|
||||
*/
|
||||
public String getPollID() {
|
||||
return pollID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the guild
|
||||
*
|
||||
* @return the guild
|
||||
*/
|
||||
public Guild getGuild() {
|
||||
return guild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the channel
|
||||
*
|
||||
* @return the channel
|
||||
*/
|
||||
public TextChannel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
public Message getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date when the poll should expire
|
||||
*
|
||||
* @return the expiry date
|
||||
*/
|
||||
public LocalDateTime getExpiryDate() {
|
||||
return expiryDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all answers
|
||||
*
|
||||
* @return all answers
|
||||
*/
|
||||
public ArrayList<String> getAnswers() {
|
||||
return answers;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package xyz.sheepstar.poll.api.models;
|
||||
|
||||
import xyz.sheepstar.util.sql.SheepManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PollAnswerManager extends SheepManager {
|
||||
|
||||
@Override
|
||||
protected String tableName() {
|
||||
return "poll_poll_answers";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tableFields() {
|
||||
custom("poll_id").add();
|
||||
custom("answer").add();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a single answer to the poll answers
|
||||
*
|
||||
* @param pollID The id of the poll you want to add the answer to
|
||||
* @param answer The answer you want to add
|
||||
*/
|
||||
public void addAnswer(String pollID, String answer) {
|
||||
insert().value("poll_id", pollID).value("answer", answer).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple answers to the poll answers
|
||||
*
|
||||
* @param pollID The id of the poll you want to add the answer to
|
||||
* @param answers The answers you want to add
|
||||
*/
|
||||
public void addAnswers(String pollID, ArrayList<String> answers) {
|
||||
answers.forEach(answer -> addAnswer(pollID, answer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all answers from a poll
|
||||
*
|
||||
* @param pollID The id of the poll
|
||||
*/
|
||||
public void deleteAnswers(String pollID) {
|
||||
delete().where("poll_id", pollID).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all answers from the poll
|
||||
*
|
||||
* @param pollID The id of the poll you want to get the answers from
|
||||
* @return all answers from the poll
|
||||
*/
|
||||
public ArrayList<String> getAnswers(String pollID) {
|
||||
return select().where("poll_id", pollID).getResult().getList("answer");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
package xyz.sheepstar.poll.api.models;
|
||||
|
||||
import de.gnmyt.sqltoolkit.types.SQLType;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import xyz.sheepstar.poll.api.entities.Poll;
|
||||
import xyz.sheepstar.util.sql.SheepManager;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PollManager extends SheepManager {
|
||||
|
||||
@Override
|
||||
protected String tableName() {
|
||||
return "poll_polls";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tableFields() {
|
||||
custom("poll_id").add();
|
||||
custom("guild_id").add();
|
||||
custom("channel_id").add();
|
||||
custom("message_id").add();
|
||||
custom("expiry").type(SQLType.DATETIME).allowNull(true).add();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the provided poll has been already created
|
||||
*
|
||||
* @param pollID The id of the poll you want to check
|
||||
* @param guild The guild in which the poll has been created
|
||||
* @return <code>true</code> if the provided poll has been already created, otherwise <code>false</code>
|
||||
*/
|
||||
public boolean isCreated(String pollID, Guild guild) {
|
||||
return select().where("guild_id", guild.getId()).where("poll_id", pollID).getResult().exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the provided message is a poll
|
||||
*
|
||||
* @param message The message you want to check
|
||||
* @return <code>true</code> if the message is a poll, otherwise <code>false</code>
|
||||
*/
|
||||
public boolean isPollMessage(Message message) {
|
||||
return select().where("message_id", message.getId()).getResult().exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id from the poll by a message
|
||||
*
|
||||
* @param message The message you want to get the poll id from
|
||||
* @return the id of the poll
|
||||
*/
|
||||
public String getIDByMessage(Message message) {
|
||||
return select().where("message_id", message.getId()).getResult().getString("poll_id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new poll for you
|
||||
*
|
||||
* @param pollID The id the poll should have
|
||||
* @param message The already sent message of the poll (to edit if finished)
|
||||
* @param expiry The date when the poll should expire, <code>NULL</code> if it should not close automatically
|
||||
*/
|
||||
public void createPoll(String pollID, Message message, Date expiry) {
|
||||
if (isCreated(pollID, message.getGuild())) return;
|
||||
insert()
|
||||
.value("poll_id", pollID)
|
||||
.value("guild_id", message.getGuild().getId())
|
||||
.value("channel_id", message.getChannel().getId())
|
||||
.value("message_id", message.getId())
|
||||
.value("expiry", expiry)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a poll from the table
|
||||
*
|
||||
* @param pollID The id of the poll you want to delete
|
||||
* @param guild The id of the guild the poll was created on
|
||||
*/
|
||||
public void deletePoll(String pollID, Guild guild) {
|
||||
if (!isCreated(pollID, guild)) return;
|
||||
delete().where("poll_id", pollID).where("guild_id", guild.getId()).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all polls that <b>can</b> expire
|
||||
*
|
||||
* @return all polls that can expire
|
||||
*/
|
||||
public HashMap<String, LocalDateTime> getExpirablePolls() {
|
||||
HashMap<String, LocalDateTime> expirable_polls = new HashMap<>();
|
||||
select().getResult().getList().forEach(entry -> {
|
||||
if (entry.get("expiry") != null)
|
||||
expirable_polls.put((String) entry.get("poll_id"), (LocalDateTime) entry.get("expiry"));
|
||||
});
|
||||
return expirable_polls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific poll by id
|
||||
*
|
||||
* @param pollID The id of the poll you want to get
|
||||
* @return the poll
|
||||
*/
|
||||
public Poll getPollById(String pollID) {
|
||||
return new Poll(pollID, api.getJDA().getTextChannelById(select().where("poll_id", pollID)
|
||||
.getResult().getString("channel_id")).retrieveMessageById(select().where("poll_id", pollID).getResult().getString("message_id")).complete(),
|
||||
(LocalDateTime) select().where("poll_id", pollID).getResult().getObject("expiry"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package xyz.sheepstar.poll.commands;
|
||||
|
||||
import xyz.sheepstar.poll.api.controller.PollController;
|
||||
import xyz.sheepstar.poll.core.PollCore;
|
||||
import xyz.sheepstar.util.bot.command.Arguments;
|
||||
import xyz.sheepstar.util.bot.command.GuildCommand;
|
||||
import xyz.sheepstar.util.bot.command.GuildEventController;
|
||||
import xyz.sheepstar.util.bot.command.PublicCommandException;
|
||||
import xyz.sheepstar.util.bot.command.annotations.CommandMeta;
|
||||
import xyz.sheepstar.util.bot.permission.PermissionNode;
|
||||
|
||||
@CommandMeta(aliases = "poll", subAliases = "close", description = "Closes a specific poll", permission = PermissionNode.ADMINISTRATOR)
|
||||
public class ClosePollCommand extends GuildCommand {
|
||||
|
||||
@Override
|
||||
public void usage() {
|
||||
usage("poll_id", "The id of the poll you want to close").required(true).add();
|
||||
}
|
||||
|
||||
private PollController pollController = PollCore.getPollController();
|
||||
|
||||
@Override
|
||||
public void execute(GuildEventController event, Arguments args) throws Exception {
|
||||
if (pollController.endPoll(args.getString("poll_id"), event.getGuild())) {
|
||||
event.success("poll.ended_successfully");
|
||||
} else throw new PublicCommandException("poll.not_found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buttonClick(GuildEventController event, String id) throws Exception {
|
||||
if (!id.startsWith("end#")) return;
|
||||
|
||||
pollController.endPoll(id.split("#")[1], event.getGuild());
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package xyz.sheepstar.poll.commands;
|
||||
|
||||
import net.dv8tion.jda.api.entities.ChannelType;
|
||||
import net.dv8tion.jda.api.entities.GuildChannel;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import xyz.sheepstar.poll.api.controller.PollController;
|
||||
import xyz.sheepstar.poll.core.PollCore;
|
||||
import xyz.sheepstar.util.bot.command.Arguments;
|
||||
import xyz.sheepstar.util.bot.command.GuildCommand;
|
||||
import xyz.sheepstar.util.bot.command.GuildEventController;
|
||||
import xyz.sheepstar.util.bot.command.PublicCommandException;
|
||||
import xyz.sheepstar.util.bot.command.annotations.CommandMeta;
|
||||
import xyz.sheepstar.util.bot.permission.PermissionNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
@CommandMeta(aliases = "poll", subAliases = "create", permission = PermissionNode.ADMINISTRATOR, description = "Creates a poll")
|
||||
public class CreatePollCommand extends GuildCommand {
|
||||
|
||||
private PollController pollController = PollCore.getPollController();
|
||||
|
||||
@Override
|
||||
public void usage() {
|
||||
usage("title", "The title of the poll").required(true).add();
|
||||
|
||||
usage("choice_1", "The first choice").required(true).add();
|
||||
usage("choice_2", "The second choice").required(true).add();
|
||||
|
||||
|
||||
usage("description", "The description of the poll").add();
|
||||
|
||||
usage("time", "When should the poll automatically be dissolved").add();
|
||||
|
||||
usage(OptionType.BOOLEAN, "close_button", "Should the poll show a close button? Otherwise you get the id to close the poll").add();
|
||||
|
||||
usage(OptionType.BOOLEAN, "multiple_choices", "Allows the user to click on multiple options").add();
|
||||
|
||||
usage(OptionType.CHANNEL, "channel", "The channel in which the message should be sent (for example if you have an poll channel)").add();
|
||||
|
||||
// All optional choices
|
||||
|
||||
usage("choice_3", "The third choice").add();
|
||||
usage("choice_4", "The fourth choice").add();
|
||||
usage("choice_5", "The fifth choice").add();
|
||||
usage("choice_6", "The 6th choice").add();
|
||||
usage("choice_7", "The 7th choice").add();
|
||||
usage("choice_8", "The 8th choice").add();
|
||||
usage("choice_9", "The 9th choice").add();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(GuildEventController event, Arguments args) throws Exception {
|
||||
GuildChannel channel = args.exists("channel") ? args.getChannel("channel") : event.getChannel();
|
||||
|
||||
Date date = args.exists("time") ? getTimeFromString(args.getString("time")) : null;
|
||||
|
||||
boolean closeButton = !args.exists("close_button") || args.getBoolean("close_button");
|
||||
|
||||
boolean multipleChoices = args.exists("multiple_choices") && args.getBoolean("multiple_choices");
|
||||
|
||||
if (channel.getType() != ChannelType.TEXT)
|
||||
throw new PublicCommandException("poll.error.channel.must_be_text");
|
||||
|
||||
ArrayList<String> answers = new ArrayList<>();
|
||||
|
||||
for (int i = 1; i < 10; i++)
|
||||
if (args.exists("choice_" + i)) answers.add(args.getString("choice_" + i));
|
||||
|
||||
|
||||
String pollID = pollController.createPoll((TextChannel) channel, date, args.getString("title"), args.getString("description"), answers, closeButton, multipleChoices);
|
||||
|
||||
event.success("poll.poll_created", channel.getAsMention(), pollID);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package xyz.sheepstar.poll.core;
|
||||
|
||||
import xyz.sheepstar.poll.action.AutomaticCloseAction;
|
||||
import xyz.sheepstar.poll.api.controller.PollController;
|
||||
import xyz.sheepstar.poll.api.models.PollAnswerManager;
|
||||
import xyz.sheepstar.poll.api.models.PollManager;
|
||||
import xyz.sheepstar.poll.commands.ClosePollCommand;
|
||||
import xyz.sheepstar.poll.commands.CreatePollCommand;
|
||||
import xyz.sheepstar.poll.listener.MultipleReactionListener;
|
||||
import xyz.sheepstar.util.bot.manager.ImportManager;
|
||||
import xyz.sheepstar.util.module.SheepstarModule;
|
||||
|
||||
public class PollCore extends SheepstarModule {
|
||||
|
||||
private static PollController pollController;
|
||||
|
||||
private ImportManager importManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
importManager = new ImportManager(getAPI(), "poll");
|
||||
|
||||
registerManagers();
|
||||
|
||||
pollController = new PollController();
|
||||
|
||||
registerCommands();
|
||||
registerActions();
|
||||
registerListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all managers of the module
|
||||
*/
|
||||
public void registerManagers() {
|
||||
registerTable(new PollAnswerManager());
|
||||
registerTable(new PollManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all commands of the module
|
||||
*/
|
||||
public void registerCommands() {
|
||||
importManager.registerCommand(new CreatePollCommand());
|
||||
importManager.registerCommand(new ClosePollCommand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all listeners of the module
|
||||
*/
|
||||
public void registerListeners() {
|
||||
importManager.registerListener(new MultipleReactionListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all actions of the module
|
||||
*/
|
||||
public void registerActions() {
|
||||
new AutomaticCloseAction().start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the poll controller
|
||||
*
|
||||
* @return the poll controller
|
||||
*/
|
||||
public static PollController getPollController() {
|
||||
return pollController;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package xyz.sheepstar.poll.listener;
|
||||
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
|
||||
import xyz.sheepstar.poll.api.models.PollAnswerManager;
|
||||
import xyz.sheepstar.poll.api.models.PollManager;
|
||||
import xyz.sheepstar.util.bot.listener.GuildListener;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MultipleReactionListener extends GuildListener {
|
||||
|
||||
private PollManager pollManager = (PollManager) table(PollManager.class);
|
||||
private PollAnswerManager pollAnswerManager = (PollAnswerManager) table(PollAnswerManager.class);
|
||||
|
||||
/**
|
||||
* Checks if the provided emoji is valid
|
||||
*
|
||||
* @param emoji The emoji you want to check
|
||||
* @param message The message to get the size of the answers
|
||||
* @return <code>true</code> if the emoji is valid, otherwise <code>false</code>
|
||||
*/
|
||||
public boolean isValidEmote(String emoji, Message message) {
|
||||
for (int i = 0; i < pollAnswerManager.getAnswers(pollManager.getIDByMessage(message)).size(); i++) {
|
||||
if (emoji.contains(String.valueOf(i + 1))) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuildMessageReactionAdd(GuildMessageReactionAddEvent event) {
|
||||
event.retrieveMessage().queue(message -> {
|
||||
if (event.getUser().getId().equals(jda.getSelfUser().getId())) return;
|
||||
if (!message.getAuthor().getId().equals(jda.getSelfUser().getId())) return;
|
||||
if (!pollManager.isPollMessage(message)) return;
|
||||
|
||||
// TODO: Migrate to id instead of message
|
||||
|
||||
if (!event.getReactionEmote().isEmoji()) {
|
||||
event.getReaction().removeReaction(event.getUser()).queue();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isValidEmote(event.getReactionEmote().getEmoji(), message)) {
|
||||
event.getReaction().removeReaction(event.getUser()).queue();
|
||||
return;
|
||||
}
|
||||
|
||||
String[] embedLines = message.getEmbeds().get(0).getDescription().split("\n");
|
||||
|
||||
for (String line : embedLines)
|
||||
if (line.startsWith("**:ballot_box:") && line.contains("(")) return;
|
||||
|
||||
AtomicInteger reactAmount = new AtomicInteger();
|
||||
message.getReactions().forEach(reaction -> reaction.retrieveUsers().queue(users -> users.forEach(user -> {
|
||||
if (user.getId().equals(event.getUser().getId())) reactAmount.getAndIncrement();
|
||||
|
||||
if (reactAmount.get() > 1) {
|
||||
event.getReaction().removeReaction(event.getUser()).queue();
|
||||
return;
|
||||
}
|
||||
})));
|
||||
});
|
||||
}
|
||||
}
|
3
SheepstarModules/PollV1/src/main/resources/module.yml
Normal file
3
SheepstarModules/PollV1/src/main/resources/module.yml
Normal file
@ -0,0 +1,3 @@
|
||||
main: xyz.sheepstar.poll.core.PollCore
|
||||
name: poll
|
||||
author: Mathias Wagner
|
Reference in New Issue
Block a user