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:
Teriuihi 2024-08-07 00:18:40 +02:00
parent 994cd7a85f
commit 27f1920081
14 changed files with 553 additions and 22 deletions

View File

@ -3,20 +3,17 @@ package com.alttd.buttonManager;
import com.alttd.buttonManager.buttons.autoReminder.ButtonAccepted;
import com.alttd.buttonManager.buttons.autoReminder.ButtonInProgress;
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.ButtonRemindMeConfirm;
import com.alttd.buttonManager.buttons.suggestionReview.ButtonSuggestionReviewAccept;
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.hooks.ListenerAdapter;
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.Nullable;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@ -34,6 +31,7 @@ public class ButtonManager extends ListenerAdapter {
buttons.add(new ButtonAccepted());
buttons.add(new ButtonInProgress());
buttons.add(new ButtonRejected());
buttons.add(new EventButton());
}
public void addButton(DiscordButton button) {

View File

@ -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;
}
}

View File

@ -1,5 +1,6 @@
package com.alttd.contextMenuManager;
import com.alttd.contextMenuManager.contextMenus.ContextMenuCreateEvent;
import com.alttd.contextMenuManager.contextMenus.ContextMenuForwardToKanboard;
import com.alttd.contextMenuManager.contextMenus.ContextMenuRespondSuggestion;
import com.alttd.modalManager.ModalManager;
@ -23,6 +24,7 @@ public class ContextMenuManager extends ListenerAdapter {
public ContextMenuManager(ModalManager modalManager) {
contextMenus = List.of(
new ContextMenuRespondSuggestion(modalManager),
new ContextMenuCreateEvent(modalManager),
new ContextMenuForwardToKanboard()
);
}

View File

@ -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));
}
}

View File

@ -56,7 +56,7 @@ public class ContextMenuRespondSuggestion extends DiscordContextMenu {
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);
}

View File

@ -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) {
if (instance == null)
instance = new DatabaseTables(connection);

View 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);
}
};

View File

@ -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));
}
}

View File

@ -5,8 +5,10 @@ import com.alttd.buttonManager.ButtonManager;
import com.alttd.commandManager.CommandManager;
import com.alttd.contextMenuManager.ContextMenuManager;
import com.alttd.database.queries.Poll.PollQueries;
import com.alttd.database.queries.events.QueriesEvent;
import com.alttd.modalManager.ModalManager;
import com.alttd.schedulers.AuctionScheduler;
import com.alttd.schedulers.EventTimerTask;
import com.alttd.schedulers.PollTimerTask;
import com.alttd.schedulers.ReminderScheduler;
import com.alttd.request.RequestManager;
@ -49,6 +51,8 @@ public class JDAListener extends ListenerAdapter {
jda.addEventListener(buttonManager, tagAdded, modalManager, commandManager, contextMenuManager, lockedChannel, appealRepost, selectMenuManager);
PollQueries.loadPolls(buttonManager);
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();
// RequestManager.init();
// Logger.altitudeLogs.info("Starting spring application");

View File

@ -2,16 +2,12 @@ package com.alttd.modalManager;
import com.alttd.buttonManager.ButtonManager;
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.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.List;
import java.util.Optional;
@ -25,7 +21,8 @@ public class ModalManager extends ListenerAdapter {
new ModalEvidence(),
new ModalReplySuggestion(),
new ModalRemindMe(buttonManager),
new ModalCrateItem());
new ModalCrateItem(),
new ModalCreateEvent(buttonManager));
}
@Override

View File

@ -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();
}
}

View File

@ -1,6 +1,7 @@
package com.alttd.modalManager.modals;
import com.alttd.modalManager.DiscordModal;
import com.alttd.util.UserToMessageTracker;
import com.alttd.util.Util;
import net.dv8tion.jda.api.entities.Member;
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.requests.RestAction;
import java.util.HashMap;
public class ModalReplySuggestion extends DiscordModal {
private static final HashMap<Long, Message> userToMessageMap = new HashMap<>();
public static synchronized void putMessage(long userId, Message message) {
userToMessageMap.put(userId, message);
}
private static synchronized Message pullMessage(long userId) {
return userToMessageMap.remove(userId);
}
public final static UserToMessageTracker userToMessageTracker = new UserToMessageTracker();
@Override
public String getModalId() {
@ -53,7 +44,7 @@ public class ModalReplySuggestion extends DiscordModal {
return;
}
Message message = pullMessage(member.getIdLong());
Message message = userToMessageTracker.pullMessage(member.getIdLong());
if (message == null) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to find a message for this modal"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);

View 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();
}
}

View 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);
}
}