Create event management system, added event notifier for community events
Added functionalities to create and manage events, including the creation of necessary database tables, context menus, modals, and scheduling tasks. Introduced `UserToMessageTracker` utility for tracking user messages within modals.
This commit is contained in:
parent
994cd7a85f
commit
27f1920081
|
|
@ -3,20 +3,17 @@ package com.alttd.buttonManager;
|
||||||
import com.alttd.buttonManager.buttons.autoReminder.ButtonAccepted;
|
import com.alttd.buttonManager.buttons.autoReminder.ButtonAccepted;
|
||||||
import com.alttd.buttonManager.buttons.autoReminder.ButtonInProgress;
|
import com.alttd.buttonManager.buttons.autoReminder.ButtonInProgress;
|
||||||
import com.alttd.buttonManager.buttons.autoReminder.ButtonRejected;
|
import com.alttd.buttonManager.buttons.autoReminder.ButtonRejected;
|
||||||
|
import com.alttd.buttonManager.buttons.eventButton.EventButton;
|
||||||
import com.alttd.buttonManager.buttons.remindMeConfirm.ButtonRemindMeCancel;
|
import com.alttd.buttonManager.buttons.remindMeConfirm.ButtonRemindMeCancel;
|
||||||
import com.alttd.buttonManager.buttons.remindMeConfirm.ButtonRemindMeConfirm;
|
import com.alttd.buttonManager.buttons.remindMeConfirm.ButtonRemindMeConfirm;
|
||||||
import com.alttd.buttonManager.buttons.suggestionReview.ButtonSuggestionReviewAccept;
|
import com.alttd.buttonManager.buttons.suggestionReview.ButtonSuggestionReviewAccept;
|
||||||
import com.alttd.buttonManager.buttons.suggestionReview.ButtonSuggestionReviewDeny;
|
import com.alttd.buttonManager.buttons.suggestionReview.ButtonSuggestionReviewDeny;
|
||||||
import com.alttd.util.Util;
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
|
||||||
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
import net.dv8tion.jda.api.requests.RestAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
@ -34,6 +31,7 @@ public class ButtonManager extends ListenerAdapter {
|
||||||
buttons.add(new ButtonAccepted());
|
buttons.add(new ButtonAccepted());
|
||||||
buttons.add(new ButtonInProgress());
|
buttons.add(new ButtonInProgress());
|
||||||
buttons.add(new ButtonRejected());
|
buttons.add(new ButtonRejected());
|
||||||
|
buttons.add(new EventButton());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addButton(DiscordButton button) {
|
public void addButton(DiscordButton button) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.alttd.buttonManager.buttons.eventButton;
|
||||||
|
|
||||||
|
import com.alttd.AltitudeBot;
|
||||||
|
import com.alttd.buttonManager.DiscordButton;
|
||||||
|
import com.alttd.database.queries.events.Event;
|
||||||
|
import com.alttd.util.Logger;
|
||||||
|
import com.alttd.util.Util;
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.*;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class EventButton extends DiscordButton {
|
||||||
|
|
||||||
|
public EventButton() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getButtonId() {
|
||||||
|
return "event_button";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(ButtonInteractionEvent event) {
|
||||||
|
Event eventForButton = Event.getEvent(event.getMessageIdLong());
|
||||||
|
if (eventForButton == null) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Event not found")).setEphemeral(true).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member member = event.getMember();
|
||||||
|
if (member == null) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "This button can only be used within a guild")).setEphemeral(true).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Instant.now().isAfter(eventForButton.getStartTime())) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to process you joining" + eventForButton.getTitle() + ", the event might have ended!")).setEphemeral(true).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Role> any = member.getRoles().stream().filter(role -> role.getIdLong() == eventForButton.getRoleId()).findAny();
|
||||||
|
if (any.isPresent()) {
|
||||||
|
updateJoinedEventUsersInEmbed(eventForButton);
|
||||||
|
event.replyEmbeds(Util.genericSuccessEmbed("Success", "Removed you from " + eventForButton.getTitle() + "!")).setEphemeral(true).queue();
|
||||||
|
try {
|
||||||
|
eventForButton.getRole().getGuild().removeRoleFromMember(member, eventForButton.getRole()).queue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.altitudeLogs.error(e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eventForButton.getRole().getGuild().addRoleToMember(member, eventForButton.getRole()).queue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.altitudeLogs.error(e);
|
||||||
|
}
|
||||||
|
if (updateJoinedEventUsersInEmbed(eventForButton)) {
|
||||||
|
event.replyEmbeds(Util.genericSuccessEmbed("Success", "You joined " + eventForButton.getTitle() + "!")).setEphemeral(true).queue();
|
||||||
|
} else {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Failed to add you to the event, contact an admin for help if needed")).setEphemeral(true).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Button getButton() {
|
||||||
|
return Button.primary(getButtonId(), "Join Event");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateJoinedEventUsersInEmbed(Event event) {
|
||||||
|
Optional<Message> optionalMessage = event.getMessage();
|
||||||
|
if (optionalMessage.isEmpty()) {
|
||||||
|
Logger.altitudeLogs.error("Unable to find event message");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Message message = optionalMessage.get();
|
||||||
|
List<MessageEmbed> embeds = message.getEmbeds();
|
||||||
|
if (embeds.isEmpty()) {
|
||||||
|
Logger.altitudeLogs.error("Unable to find event embed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbedBuilder builder = new EmbedBuilder(embeds.get(0));
|
||||||
|
builder.clearFields()
|
||||||
|
.addField("Event Start", "<t:" + event.getStartTime().getEpochSecond() + ":F>", true);
|
||||||
|
Guild guildById = AltitudeBot.getInstance().getJDA().getGuildById(event.getGuildId());
|
||||||
|
if (guildById != null) {
|
||||||
|
List<Member> membersWithRole = guildById.getMembersWithRoles(event.getRole());
|
||||||
|
builder.addField("Participants", String.valueOf(membersWithRole.size()), true);
|
||||||
|
}
|
||||||
|
MessageEmbed updatedEmbed = builder.build();
|
||||||
|
message.editMessageEmbeds(updatedEmbed).queue();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.alttd.contextMenuManager;
|
package com.alttd.contextMenuManager;
|
||||||
|
|
||||||
|
import com.alttd.contextMenuManager.contextMenus.ContextMenuCreateEvent;
|
||||||
import com.alttd.contextMenuManager.contextMenus.ContextMenuForwardToKanboard;
|
import com.alttd.contextMenuManager.contextMenus.ContextMenuForwardToKanboard;
|
||||||
import com.alttd.contextMenuManager.contextMenus.ContextMenuRespondSuggestion;
|
import com.alttd.contextMenuManager.contextMenus.ContextMenuRespondSuggestion;
|
||||||
import com.alttd.modalManager.ModalManager;
|
import com.alttd.modalManager.ModalManager;
|
||||||
|
|
@ -23,6 +24,7 @@ public class ContextMenuManager extends ListenerAdapter {
|
||||||
public ContextMenuManager(ModalManager modalManager) {
|
public ContextMenuManager(ModalManager modalManager) {
|
||||||
contextMenus = List.of(
|
contextMenus = List.of(
|
||||||
new ContextMenuRespondSuggestion(modalManager),
|
new ContextMenuRespondSuggestion(modalManager),
|
||||||
|
new ContextMenuCreateEvent(modalManager),
|
||||||
new ContextMenuForwardToKanboard()
|
new ContextMenuForwardToKanboard()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.alttd.contextMenuManager.contextMenus;
|
||||||
|
|
||||||
|
import com.alttd.contextMenuManager.DiscordContextMenu;
|
||||||
|
import com.alttd.modalManager.ModalManager;
|
||||||
|
import com.alttd.modalManager.modals.ModalCreateEvent;
|
||||||
|
import com.alttd.util.Util;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.Commands;
|
||||||
|
import net.dv8tion.jda.api.interactions.modals.Modal;
|
||||||
|
import net.dv8tion.jda.api.requests.RestAction;
|
||||||
|
|
||||||
|
public class ContextMenuCreateEvent extends DiscordContextMenu {
|
||||||
|
|
||||||
|
private final ModalManager modalManager;
|
||||||
|
|
||||||
|
public ContextMenuCreateEvent(ModalManager modalManager) {
|
||||||
|
this.modalManager = modalManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContextMenuId() {
|
||||||
|
return "Create Event";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(UserContextInteractionEvent event) {
|
||||||
|
event.getInteraction().replyEmbeds(Util.genericErrorEmbed("Error", "This interaction should have been a message interaction"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(MessageContextInteractionEvent event) {
|
||||||
|
if (!event.isFromGuild()) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "This has to be done in a guild"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Message message = event.getInteraction().getTarget();
|
||||||
|
|
||||||
|
if (message.getChannel().getIdLong() != 1172922338023591956L || message.getAuthor().getIdLong() != event.getUser().getIdLong()) {
|
||||||
|
event.getInteraction().replyEmbeds(Util.genericErrorEmbed("Error", "You can only use this on your own community post"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal createEvent = modalManager.getModalFor("create_event");
|
||||||
|
if (createEvent == null) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to find create event modal"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModalCreateEvent.userToMessageTracker.putMessage(event.getUser().getIdLong(), message); //TODO find a better way to do this
|
||||||
|
event.replyModal(createEvent).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandData getUserContextInteraction() {
|
||||||
|
return Commands.message(getContextMenuId())
|
||||||
|
.setGuildOnly(true)
|
||||||
|
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_SEND));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ public class ContextMenuRespondSuggestion extends DiscordContextMenu {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModalReplySuggestion.putMessage(event.getUser().getIdLong(), message); //TODO find a better way to do this
|
ModalReplySuggestion.userToMessageTracker.putMessage(event.getUser().getIdLong(), message); //TODO find a better way to do this
|
||||||
event.replyModal(replySuggestion).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
event.replyModal(replySuggestion).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,24 @@ public class DatabaseTables {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createEventsTable() {
|
||||||
|
String sql = "CREATE TABLE IF NOT EXISTS events(" +
|
||||||
|
"message_id BIGINT NOT NULL, " +
|
||||||
|
"channel_id BIGINT NOT NULL, " +
|
||||||
|
"guild_id BIGINT NOT NULL, " +
|
||||||
|
"epoch_second BIGINT NOT NULL, " +
|
||||||
|
"role_id BIGINT NOT NULL," +
|
||||||
|
"title VARCHAR(128) NOT NULL, " +
|
||||||
|
"PRIMARY KEY (message_id)" +
|
||||||
|
")";
|
||||||
|
try {
|
||||||
|
connection.prepareStatement(sql).executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Logger.altitudeLogs.error(e);
|
||||||
|
Logger.altitudeLogs.error("Unable to create auction settings table, shutting down...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void createTables(Connection connection) {
|
public static void createTables(Connection connection) {
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
instance = new DatabaseTables(connection);
|
instance = new DatabaseTables(connection);
|
||||||
|
|
|
||||||
79
src/main/java/com/alttd/database/queries/events/Event.java
Normal file
79
src/main/java/com/alttd/database/queries/events/Event.java
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
package com.alttd.database.queries.events;
|
||||||
|
|
||||||
|
import com.alttd.AltitudeBot;
|
||||||
|
import com.alttd.util.Logger;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
||||||
|
public final class Event {
|
||||||
|
|
||||||
|
private static final HashMap<Long, Event> eventMap = new HashMap<>();
|
||||||
|
@Getter
|
||||||
|
private final long messageId, guildId, channelId, roleId;
|
||||||
|
@Getter
|
||||||
|
private final Instant startTime;
|
||||||
|
@Getter
|
||||||
|
private Role role = null;
|
||||||
|
@Getter
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
|
||||||
|
public static Event getEvent(long messageId) {
|
||||||
|
return eventMap.get(messageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Message message = null;
|
||||||
|
|
||||||
|
public Event(long messageId, long guildId, long channelId, Instant startTime, long roleId, String title) {
|
||||||
|
this.messageId = messageId;
|
||||||
|
this.guildId = guildId;
|
||||||
|
this.channelId = channelId;
|
||||||
|
this.startTime = startTime;
|
||||||
|
this.roleId = roleId;
|
||||||
|
this.title = title;
|
||||||
|
|
||||||
|
eventMap.put(messageId, this);
|
||||||
|
loadMessageAndRole();
|
||||||
|
Logger.altitudeLogs.info(String.format("Loaded event with title [%s] and message id [%s]", title, messageId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Event> getNextEvent() {
|
||||||
|
return eventMap.values().stream().min(Comparator.comparing(Event::getStartTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeEvent(Event event) {
|
||||||
|
eventMap.remove(event.getMessageId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadMessageAndRole() {
|
||||||
|
Guild guild = AltitudeBot.getInstance().getJDA().getGuildById(guildId);
|
||||||
|
if (guild == null) {
|
||||||
|
Logger.altitudeLogs.error(String.format("Unable to find guild %s when creating event", guildId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TextChannel textChannel = guild.getTextChannelById(channelId);
|
||||||
|
if (textChannel == null) {
|
||||||
|
Logger.altitudeLogs.error(String.format("Unable to find text channel %s when creating event", channelId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
textChannel.retrieveMessageById(messageId).queue(message -> {
|
||||||
|
this.message = message;
|
||||||
|
Logger.altitudeLogs.debug(String.format("Loaded message for event with title [%s]", title));
|
||||||
|
});
|
||||||
|
role = guild.getRoleById(roleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Message> getMessage() {
|
||||||
|
return message == null ? Optional.empty() : Optional.of(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.alttd.database.queries.events;
|
||||||
|
|
||||||
|
import com.alttd.database.Database;
|
||||||
|
import com.alttd.util.Logger;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class QueriesEvent {
|
||||||
|
|
||||||
|
public void addEvent(Message message, Instant start, long roleId, String title) {
|
||||||
|
String sql = "INSERT INTO events VALUES(?, ?, ?, ?, ?, ?)";
|
||||||
|
|
||||||
|
try {
|
||||||
|
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
|
||||||
|
|
||||||
|
preparedStatement.setLong(1, message.getIdLong());
|
||||||
|
preparedStatement.setLong(2, message.getChannelIdLong());
|
||||||
|
preparedStatement.setLong(3, message.getGuildIdLong());
|
||||||
|
preparedStatement.setLong(4, start.getEpochSecond());
|
||||||
|
preparedStatement.setLong(5, roleId);
|
||||||
|
preparedStatement.setString(6, title);
|
||||||
|
|
||||||
|
preparedStatement.executeUpdate();
|
||||||
|
} catch (SQLException exception) {
|
||||||
|
Logger.altitudeLogs.error(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadActiveEvents() {
|
||||||
|
String sql = "SELECT * FROM events WHERE epoch_second > ?";
|
||||||
|
int counter = 0;
|
||||||
|
try {
|
||||||
|
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
|
||||||
|
|
||||||
|
preparedStatement.setLong(1, Instant.now().getEpochSecond());
|
||||||
|
|
||||||
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
new Event(
|
||||||
|
resultSet.getLong("message_id"),
|
||||||
|
resultSet.getLong("guild_id"),
|
||||||
|
resultSet.getLong("channel_id"),
|
||||||
|
Instant.ofEpochSecond(resultSet.getLong("epoch_second")),
|
||||||
|
resultSet.getLong("role_id"),
|
||||||
|
resultSet.getString("title")
|
||||||
|
);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
} catch (SQLException exception) {
|
||||||
|
Logger.altitudeLogs.error(exception);
|
||||||
|
}
|
||||||
|
Logger.altitudeLogs.info(String.format("Loaded %d events", counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,8 +5,10 @@ import com.alttd.buttonManager.ButtonManager;
|
||||||
import com.alttd.commandManager.CommandManager;
|
import com.alttd.commandManager.CommandManager;
|
||||||
import com.alttd.contextMenuManager.ContextMenuManager;
|
import com.alttd.contextMenuManager.ContextMenuManager;
|
||||||
import com.alttd.database.queries.Poll.PollQueries;
|
import com.alttd.database.queries.Poll.PollQueries;
|
||||||
|
import com.alttd.database.queries.events.QueriesEvent;
|
||||||
import com.alttd.modalManager.ModalManager;
|
import com.alttd.modalManager.ModalManager;
|
||||||
import com.alttd.schedulers.AuctionScheduler;
|
import com.alttd.schedulers.AuctionScheduler;
|
||||||
|
import com.alttd.schedulers.EventTimerTask;
|
||||||
import com.alttd.schedulers.PollTimerTask;
|
import com.alttd.schedulers.PollTimerTask;
|
||||||
import com.alttd.schedulers.ReminderScheduler;
|
import com.alttd.schedulers.ReminderScheduler;
|
||||||
import com.alttd.request.RequestManager;
|
import com.alttd.request.RequestManager;
|
||||||
|
|
@ -49,6 +51,8 @@ public class JDAListener extends ListenerAdapter {
|
||||||
jda.addEventListener(buttonManager, tagAdded, modalManager, commandManager, contextMenuManager, lockedChannel, appealRepost, selectMenuManager);
|
jda.addEventListener(buttonManager, tagAdded, modalManager, commandManager, contextMenuManager, lockedChannel, appealRepost, selectMenuManager);
|
||||||
PollQueries.loadPolls(buttonManager);
|
PollQueries.loadPolls(buttonManager);
|
||||||
new Timer().scheduleAtFixedRate(new PollTimerTask(jda, Logger.altitudeLogs), TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(5));
|
new Timer().scheduleAtFixedRate(new PollTimerTask(jda, Logger.altitudeLogs), TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(5));
|
||||||
|
new QueriesEvent().loadActiveEvents();
|
||||||
|
new Timer().scheduleAtFixedRate(new EventTimerTask(), TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1));
|
||||||
startSchedulers();
|
startSchedulers();
|
||||||
// RequestManager.init();
|
// RequestManager.init();
|
||||||
// Logger.altitudeLogs.info("Starting spring application");
|
// Logger.altitudeLogs.info("Starting spring application");
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,12 @@ package com.alttd.modalManager;
|
||||||
|
|
||||||
import com.alttd.buttonManager.ButtonManager;
|
import com.alttd.buttonManager.ButtonManager;
|
||||||
import com.alttd.modalManager.modals.*;
|
import com.alttd.modalManager.modals.*;
|
||||||
import com.alttd.util.Util;
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
|
||||||
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
import net.dv8tion.jda.api.interactions.modals.Modal;
|
import net.dv8tion.jda.api.interactions.modals.Modal;
|
||||||
import net.dv8tion.jda.api.requests.RestAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
@ -25,7 +21,8 @@ public class ModalManager extends ListenerAdapter {
|
||||||
new ModalEvidence(),
|
new ModalEvidence(),
|
||||||
new ModalReplySuggestion(),
|
new ModalReplySuggestion(),
|
||||||
new ModalRemindMe(buttonManager),
|
new ModalRemindMe(buttonManager),
|
||||||
new ModalCrateItem());
|
new ModalCrateItem(),
|
||||||
|
new ModalCreateEvent(buttonManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,150 @@
|
||||||
|
package com.alttd.modalManager.modals;
|
||||||
|
|
||||||
|
import com.alttd.buttonManager.ButtonManager;
|
||||||
|
import com.alttd.database.queries.events.Event;
|
||||||
|
import com.alttd.database.queries.events.QueriesEvent;
|
||||||
|
import com.alttd.modalManager.DiscordModal;
|
||||||
|
import com.alttd.util.UserToMessageTracker;
|
||||||
|
import com.alttd.util.Util;
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.text.TextInput;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
|
||||||
|
import net.dv8tion.jda.api.interactions.modals.Modal;
|
||||||
|
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
||||||
|
import net.dv8tion.jda.api.requests.RestAction;
|
||||||
|
import net.dv8tion.jda.api.requests.restaction.RoleAction;
|
||||||
|
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
|
||||||
|
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
|
||||||
|
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ModalCreateEvent extends DiscordModal {
|
||||||
|
|
||||||
|
public static final UserToMessageTracker userToMessageTracker = new UserToMessageTracker();
|
||||||
|
private final ButtonManager buttonManager;
|
||||||
|
|
||||||
|
public ModalCreateEvent(ButtonManager buttonManager) {
|
||||||
|
this.buttonManager = buttonManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModalId() {
|
||||||
|
return "create_event";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(ModalInteractionEvent event) {
|
||||||
|
ModalMapping titleModalMapping = event.getInteraction().getValue("title");
|
||||||
|
ModalMapping timeModalMapping = event.getInteraction().getValue("time");
|
||||||
|
if (titleModalMapping == null || timeModalMapping == null) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to find time or title in modal"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String title = titleModalMapping.getAsString();
|
||||||
|
String time = timeModalMapping.getAsString();
|
||||||
|
if (title.isEmpty() || time.isEmpty()) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Response in modal is empty"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instant eventStart;
|
||||||
|
try {
|
||||||
|
eventStart = Instant.ofEpochSecond(Long.parseLong(time));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Invalid time format, try again"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member member = event.getMember();
|
||||||
|
if (member == null) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "This modal only works from within a guild"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Message message = userToMessageTracker.pullMessage(member.getIdLong());
|
||||||
|
if (message == null) {
|
||||||
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "No message found to create an event from"))
|
||||||
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageEmbed messageEmbed = new EmbedBuilder()
|
||||||
|
.setTitle(title)
|
||||||
|
.addField("Event Start", "<t:" + time + ":F>", true)
|
||||||
|
.addField("Participants", "0", true)
|
||||||
|
.setFooter("Click the join button to be notified when the event starts")
|
||||||
|
.setColor(Color.GREEN)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Button eventButton = buttonManager.getButtonFor("event_button");
|
||||||
|
|
||||||
|
try (MessageCreateData build = new MessageCreateBuilder()
|
||||||
|
.setEmbeds(messageEmbed)
|
||||||
|
.setActionRow(eventButton)
|
||||||
|
.build()) {
|
||||||
|
|
||||||
|
Guild guild = message.getGuild();
|
||||||
|
ReplyCallbackAction replyCallbackAction = event.deferReply(true);
|
||||||
|
createRole(guild).queue(role -> {
|
||||||
|
message.reply(build).queue(newMessage -> {
|
||||||
|
new QueriesEvent().addEvent(newMessage, eventStart, role.getIdLong(), title);
|
||||||
|
new Event(newMessage.getIdLong(), newMessage.getGuildIdLong(), newMessage.getChannelIdLong(), eventStart, role.getIdLong(), title);
|
||||||
|
});
|
||||||
|
replyCallbackAction.setEmbeds(Util.genericSuccessEmbed("Success", "Your event has been created")).queue();
|
||||||
|
}, failed -> {
|
||||||
|
replyCallbackAction.setEmbeds(Util.genericErrorEmbed("Error", "Unable to create event")).queue();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RoleAction createRole(Guild guild) {
|
||||||
|
String possibleCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
|
||||||
|
Random rand = new Random();
|
||||||
|
String randomStr = rand.ints(5, 0, possibleCharacters.length())
|
||||||
|
.mapToObj(i -> possibleCharacters.charAt(i) + "")
|
||||||
|
.collect(Collectors.joining());
|
||||||
|
|
||||||
|
return guild.createRole().setName("event role " + randomStr)
|
||||||
|
.setMentionable(false)
|
||||||
|
.setHoisted(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Modal getModal() {
|
||||||
|
String currentTimestamp = String.valueOf(Instant.now().getEpochSecond());
|
||||||
|
TextInput time = TextInput.create("time", "Epoch time, see https://epochconverter.com/", TextInputStyle.SHORT)
|
||||||
|
.setPlaceholder(currentTimestamp)
|
||||||
|
.setMinLength(currentTimestamp.length())
|
||||||
|
.setMaxLength(currentTimestamp.length() + 1)
|
||||||
|
.setRequired(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
TextInput title = TextInput.create("title", "Event title", TextInputStyle.SHORT)
|
||||||
|
.setPlaceholder("The title for your event")
|
||||||
|
.setMinLength(5)
|
||||||
|
.setMaxLength(128)
|
||||||
|
.setRequired(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return Modal.create(getModalId(), "Create an event")
|
||||||
|
.addComponents(ActionRow.of(title), ActionRow.of(time))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.alttd.modalManager.modals;
|
package com.alttd.modalManager.modals;
|
||||||
|
|
||||||
import com.alttd.modalManager.DiscordModal;
|
import com.alttd.modalManager.DiscordModal;
|
||||||
|
import com.alttd.util.UserToMessageTracker;
|
||||||
import com.alttd.util.Util;
|
import com.alttd.util.Util;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
@ -11,19 +12,9 @@ import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
|
||||||
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
||||||
import net.dv8tion.jda.api.requests.RestAction;
|
import net.dv8tion.jda.api.requests.RestAction;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class ModalReplySuggestion extends DiscordModal {
|
public class ModalReplySuggestion extends DiscordModal {
|
||||||
|
|
||||||
private static final HashMap<Long, Message> userToMessageMap = new HashMap<>();
|
public final static UserToMessageTracker userToMessageTracker = new UserToMessageTracker();
|
||||||
|
|
||||||
public static synchronized void putMessage(long userId, Message message) {
|
|
||||||
userToMessageMap.put(userId, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static synchronized Message pullMessage(long userId) {
|
|
||||||
return userToMessageMap.remove(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModalId() {
|
public String getModalId() {
|
||||||
|
|
@ -53,7 +44,7 @@ public class ModalReplySuggestion extends DiscordModal {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Message message = pullMessage(member.getIdLong());
|
Message message = userToMessageTracker.pullMessage(member.getIdLong());
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to find a message for this modal"))
|
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to find a message for this modal"))
|
||||||
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
|
||||||
|
|
|
||||||
45
src/main/java/com/alttd/schedulers/EventTimerTask.java
Normal file
45
src/main/java/com/alttd/schedulers/EventTimerTask.java
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.alttd.schedulers;
|
||||||
|
|
||||||
|
import com.alttd.database.queries.events.Event;
|
||||||
|
import com.alttd.util.Logger;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class EventTimerTask extends TimerTask {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
checkShouldStartEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkShouldStartEvent(){
|
||||||
|
Optional<Event> nextEvent = Event.getNextEvent();
|
||||||
|
if (nextEvent.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Event event = nextEvent.get();
|
||||||
|
if (event.getStartTime().isAfter(Instant.now())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Event.removeEvent(event);
|
||||||
|
performEventAction(event);
|
||||||
|
event.getRole().delete().queueAfter(1, TimeUnit.HOURS);
|
||||||
|
checkShouldStartEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performEventAction(Event event) {
|
||||||
|
Optional<Message> optionalMessage = event.getMessage();
|
||||||
|
if (optionalMessage.isEmpty()) {
|
||||||
|
Logger.altitudeLogs.error("Unable to find message for event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Message message = optionalMessage.get();
|
||||||
|
|
||||||
|
message.reply(String.format("%s [%s] is starting!", event.getRole().getAsMention(), event.getTitle())).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/main/java/com/alttd/util/UserToMessageTracker.java
Normal file
19
src/main/java/com/alttd/util/UserToMessageTracker.java
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.alttd.util;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class UserToMessageTracker {
|
||||||
|
|
||||||
|
private final HashMap<Long, Message> userToMessageMap = new HashMap<>();
|
||||||
|
|
||||||
|
public synchronized void putMessage(long userId, Message message) {
|
||||||
|
userToMessageMap.put(userId, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized Message pullMessage(long userId) {
|
||||||
|
return userToMessageMap.remove(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user