Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f47a596
Added RemindMe Command
Deliasama Jan 3, 2024
33c0463
Added RemindMe Command
Deliasama Jan 4, 2024
142628a
Merge branch 'SlimeCloud:master' into master
Deliasama Jan 4, 2024
fac4ca4
Reformat code and fix delete problem
MineKing9534 Jan 4, 2024
1ff660d
Add List and Delete Function
Deliasama Jan 4, 2024
63a1b77
Add support for null snowflakes
MineKing9534 Jan 4, 2024
a8a8d9d
Use Role instead of RoleId
Deliasama Jan 4, 2024
7a38eac
Merge branch 'master' into reminder
MineKing9534 Jan 7, 2024
732a501
Update to new JavaUtils version
MineKing9534 Jan 7, 2024
b4e6674
Edit Message and bug fixing
Deliasama Jan 10, 2024
98729dc
Merge remote-tracking branch 'origin/master'
Deliasama Jan 10, 2024
61921bf
Merge branch 'SlimeCloud:master' into master
Deliasama Jan 10, 2024
25c07a6
Reformat code
Deliasama Jan 10, 2024
8c0df56
Merge branch 'SlimeCloud:master' into master
Deliasama Jan 16, 2024
d05aacd
Merge branch 'SlimeCloud:master' into master
Deliasama Jan 21, 2024
4788e45
Save when the timer was set
Deliasama Jan 25, 2024
74ca2ae
Reformat code
MineKing9534 Jan 27, 2024
1d8318d
Fix reminder delete command
MineKing9534 Jan 27, 2024
8e0386c
Improve reminder creation
MineKing9534 Jan 27, 2024
064a819
Remove unused field
MineKing9534 Jan 27, 2024
f3fd7ff
Update DiscordUtils
MineKing9534 Jan 27, 2024
4904f24
USe DiscordUtils list feature
MineKing9534 Jan 27, 2024
8ee34c8
Merge branch 'master' into master
MineKing9534 Feb 12, 2024
b8eb339
typo
MatitoDev Feb 18, 2024
aa9797c
better ux
MatitoDev Feb 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/main/java/de/slimecloud/slimeball/config/GuildConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -69,6 +70,10 @@ public static GuildConfig readFromFile(@NotNull SlimeBot bot, long guild) {
@ConfigField(name = "Team", command = "team", description = "Die Team-Rolle", type = ConfigFieldType.ROLE)
private Long teamRole;

@Setter
@ConfigField(name = "TeamChannel", command = "teamChannel", description = "Der Team-Channel", type = ConfigFieldType.MESSAGE_CHANNEL)
private Long teamChannel;

@Getter
@ConfigField(name = "Beitritts Rollen", command = "autorole", description = "Rollen, die Mitgliedern beim Beitreten gegeben werden", type = ConfigFieldType.ROLE)
private final List<Long> joinRoles = new ArrayList<>();
Expand Down Expand Up @@ -199,6 +204,11 @@ public Optional<Role> getTeamRole() {
return Optional.ofNullable(teamRole).map(bot.getJda()::getRoleById);
}

@NotNull
public Optional<MessageChannel> getTeamChannel() {
return Optional.ofNullable(teamChannel).map(channel -> getGuild().getChannelById(MessageChannel.class, channel));
}

@NotNull
public Optional<GuildMessageChannel> getGreetingsChannel() {
return Optional.ofNullable(greetingsChannel).map(id -> bot.getJda().getChannelById(GuildMessageChannel.class, id));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package de.slimecloud.slimeball.features.reminder;

import de.mineking.discordutils.commands.ApplicationCommand;
import de.mineking.discordutils.commands.ApplicationCommandMethod;
import de.mineking.discordutils.commands.Command;
import de.mineking.discordutils.commands.Setup;
import de.mineking.discordutils.commands.context.ICommandContext;
import de.mineking.discordutils.commands.option.Option;
import de.mineking.discordutils.list.ListManager;
import de.slimecloud.slimeball.main.CommandPermission;
import de.slimecloud.slimeball.main.Main;
import de.slimecloud.slimeball.main.SlimeBot;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.utils.TimeFormat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.List;

@ApplicationCommand(name = "remind", description = "Setzt einen Reminder")
public class RemindCommand {
@Setup
public static void setup(@NotNull SlimeBot bot, @NotNull ListManager<ICommandContext> manager, @NotNull Command<ICommandContext> command) {
command.addSubcommand(manager.createCommand(s -> bot.getReminder()).withDescription("Zeigt alle deine Reminder an"));
}

public static void createReminder(@NotNull SlimeBot bot, @NotNull SlashCommandInteractionEvent event,
@Nullable Role role,
@NotNull String time,
@NotNull String message
) throws DateTimeParseException {
if (message.length() > 1024) event.reply("Deine Nachricht darf maximal nur 1024 Zeichen lang sein!").setEphemeral(true).queue();
Instant timestamp = convertTime(time);

if (timestamp.isBefore(Instant.now())) event.reply("Deine angegebene Zeit ist schon vergangen!").setEphemeral(true).queue();

try {
bot.getReminder().createReminder(event.getMember(), role, timestamp, Instant.now(), message);
event.reply("Reminder wurde gesetzt! Löst aus " + TimeFormat.RELATIVE.format(timestamp)).setEphemeral(true).queue();
} catch (DateTimeParseException e) {
event.reply("Falsches Zeitformat! Versuche etwas wie \"14:45\" oder \"09:04 04.05.2024\"").setEphemeral(true).queue();
}
}

public static Instant convertTime(String time) throws DateTimeParseException {
LocalDateTime now = LocalDateTime.now(Main.timezone);

return LocalDateTime.parse(time, new DateTimeFormatterBuilder().appendPattern("HH:mm[ dd.MM.yyyy]")
.parseDefaulting(ChronoField.DAY_OF_MONTH, now.getDayOfMonth())
.parseDefaulting(ChronoField.MONTH_OF_YEAR, now.getMonthValue())
.parseDefaulting(ChronoField.YEAR, now.getYear())
.toFormatter()
).toInstant(Main.timezone);
}

@ApplicationCommand(name = "me", description = "Setze einen Reminder")
public static class MeCommand {
@ApplicationCommandMethod
public void performCommand(@NotNull SlimeBot bot, @NotNull SlashCommandInteractionEvent event,
@Option(description = "Die Zeit an welcher du erinnert werden möchtest, beispielsweise 13:30") String time,
@Option(description = "Die Sache an die du erinnert werden möchtest") String message
) {
createReminder(bot, event, null, time, message);
}
}

@ApplicationCommand(name = "role", description = "Setze einen Reminder")
public static class RoleCommand {
public final CommandPermission permission = CommandPermission.TEAM;

@ApplicationCommandMethod
public void performCommand(@NotNull SlimeBot bot, @NotNull SlashCommandInteractionEvent event,
@Option(description = "Rolle die erwähnt werden soll") Role role,
@Option(description = "Die Zeit an welcher du erinnern möchtest, beispielsweise 13:30") String time,
@Option(description = "Die Sache an die du erinnern möchtest") String message
) {
createReminder(bot, event, role, time, message);
}
}

@ApplicationCommand(name = "delete", description = "Lösche einen aktiven Reminder")
public static class DeleteCommand {
@ApplicationCommandMethod
public void performCommand(@NotNull SlimeBot bot, @NotNull SlashCommandInteractionEvent event,
@Option(description = "Nummer des Reminders") int number
) {
List<Reminder> reminders = bot.getReminder().getByMember(event.getMember());
if (reminders.isEmpty()) {
event.reply("Du hast keine aktiven Reminder auf diesem Server!").setEphemeral(true).queue();
return;
}

if (number < 1 || number > reminders.size()) {
event.reply("Diesen Reminder gibt es nicht oder ist bereits ausgelaufen!").setEphemeral(true).queue();
return;
}

reminders.get(number - 1).delete();
bot.getRemindManager().scheduleNextReminder();

event.reply("Reminder gelöscht!").setEphemeral(true).queue();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package de.slimecloud.slimeball.features.reminder;

import de.slimecloud.slimeball.main.SlimeBot;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.ScheduledFuture;

public class RemindManager {
private final ReminderTable table;
private ScheduledFuture<?> scheduledFuture = null;

public RemindManager(@NotNull SlimeBot bot) {
this.table = bot.getReminder();
}

public void scheduleNextReminder() {
if (scheduledFuture != null) scheduledFuture.cancel(true);
table.getNext().flatMap(Reminder::schedule).ifPresent(f -> scheduledFuture = f);
}
}
111 changes: 111 additions & 0 deletions src/main/java/de/slimecloud/slimeball/features/reminder/Reminder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package de.slimecloud.slimeball.features.reminder;

import de.mineking.discordutils.list.ListContext;
import de.mineking.discordutils.list.ListEntry;
import de.mineking.javautils.database.Column;
import de.mineking.javautils.database.DataClass;
import de.mineking.javautils.database.Table;
import de.slimecloud.slimeball.main.SlimeBot;
import de.slimecloud.slimeball.main.SlimeEmoji;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.UserSnowflake;
import net.dv8tion.jda.api.utils.TimeFormat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

@Getter
@AllArgsConstructor
public class Reminder implements DataClass<Reminder>, Comparable<Reminder>, Runnable, ListEntry {
private final SlimeBot bot;

@Column(autoincrement = true, key = true)
private final int id;

@Column
private final Guild guild;
@Column
private final UserSnowflake user;

@Column
@Nullable
private final Role role;

@Column
private final Instant time;
@Column
private final Instant timeSet;

@Column
private final String message;

public Reminder(@NotNull SlimeBot bot) {
this(bot, 0, null, null, null, null, null, null);
}

@NotNull
@Override
public Table<Reminder> getTable() {
return bot.getReminder();
}

@Override
public int compareTo(@NotNull Reminder o) {
return this.getTime().compareTo(o.getTime());
}

@Override
public void run() {
if (role == null) {
// Send Private Reminder
EmbedBuilder embedBuilder = new EmbedBuilder()
.setAuthor(guild.getName(), null, guild.getIconUrl())
.setTitle(SlimeEmoji.EXCLAMATION.toString(guild) + " Reminder!")
.setColor(bot.getColor(guild))
.setDescription(message + " \n \n" + "(Reminder vor " + TimeFormat.RELATIVE.format(timeSet) + ")");

bot.getJda().openPrivateChannelById(user.getIdLong())
.flatMap(channel -> channel.sendMessageEmbeds(embedBuilder.build()))
.queue();
} else {
// Send Role Reminder
guild.retrieveMember(user).queue(member -> {
EmbedBuilder embedBuilder = new EmbedBuilder()
.setAuthor(member.getEffectiveName(), null, member.getEffectiveAvatarUrl())
.setTitle(SlimeEmoji.EXCLAMATION.toString(guild) + " Reminder!")
.setColor(bot.getColor(guild))
.setDescription(message + " \n \n" + "(Reminder vor " + TimeFormat.RELATIVE.format(timeSet) + ")");

bot.loadGuild(guild.getIdLong()).getTeamChannel().ifPresent(channel -> {
channel.sendMessage(role.getAsMention()).setEmbeds(embedBuilder.build()).queue();
});
});
}

delete();
bot.getRemindManager().scheduleNextReminder();
}

public Optional<ScheduledFuture<?>> schedule() {
long delay = time.toEpochMilli() - System.currentTimeMillis();
if (delay <= 0) {
run();
return Optional.empty();
}
return Optional.of(bot.getExecutor().schedule(this, delay / 1000, TimeUnit.SECONDS));
}

@NotNull
@Override
public String build(int index, @NotNull ListContext<? extends ListEntry> context) {
return (index + 1) + ". " + TimeFormat.RELATIVE.format(time) + ": " + message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package de.slimecloud.slimeball.features.reminder;

import de.mineking.discordutils.list.ListContext;
import de.mineking.discordutils.list.Listable;
import de.mineking.discordutils.ui.MessageMenu;
import de.mineking.discordutils.ui.state.DataState;
import de.mineking.javautils.database.Order;
import de.mineking.javautils.database.Table;
import de.mineking.javautils.database.Where;
import de.slimecloud.slimeball.main.SlimeBot;
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.Role;
import org.jetbrains.annotations.NotNull;

import java.time.Instant;
import java.util.List;
import java.util.Optional;

public interface ReminderTable extends Table<Reminder>, Listable<Reminder> {
@NotNull
default Optional<Reminder> getNext() {
return selectAll(Order.ascendingBy("time").limit(1)).stream().findFirst();
}

default Reminder createReminder(@NotNull Member member, Role role, @NotNull Instant time, @NotNull Instant timeSet, @NotNull String message) {
SlimeBot bot = getManager().getData("bot");

Reminder result = insert(new Reminder(bot, 0, member.getGuild(), member, role, time, timeSet, message));
bot.getRemindManager().scheduleNextReminder();
return result;
}

@NotNull
default List<Reminder> getByMember(@NotNull Member member) {
return selectMany(Where.allOf(
Where.equals("user", member.getUser()),
Where.equals("guild", member.getGuild()),
Where.equals("role", null)
), Order.ascendingBy("time"));
}

@NotNull
default List<Reminder> getByGuild(@NotNull Guild guild) {
return selectMany(Where.equals("guild", guild));
}

/*
* Listable implementation
*/

@NotNull
@Override
default EmbedBuilder createEmbed(@NotNull DataState<MessageMenu> state, @NotNull ListContext<Reminder> context) {
EmbedBuilder builder = new EmbedBuilder()
.setTitle("Reminder auf **" + state.getEvent().getGuild().getName() + "**")
.setColor(getManager().<SlimeBot>getData("bot").getColor(state.getEvent().getGuild()));

if (context.entries().isEmpty()) builder.setDescription("*Du hast keine aktiven Reminder auf diesem Server*");
else builder.setFooter("Insgesamt " + context.entries().size() + " Reminder");

return builder;
}

@Override
default void finalizeEmbed(@NotNull EmbedBuilder builder, @NotNull DataState<MessageMenu> state, @NotNull ListContext<Reminder> context) {
if(context.entries().isEmpty()) return;
builder.appendDescription("\n\nLösche einen Reminder mit " + context.manager().getManager().getCommandManager().getCommand(RemindCommand.DeleteCommand.class).getAsMention());
}

@NotNull
@Override
default List<Reminder> getEntries(@NotNull DataState<MessageMenu> state, @NotNull ListContext<Reminder> context) {
return getByMember(context.event().getMember());
}
}
4 changes: 2 additions & 2 deletions src/main/java/de/slimecloud/slimeball/main/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

@Slf4j
public class Main {
public final static Random random = new Random();

public final static ZoneOffset timezone = ZoneOffset.ofHours(1);

public final static Random random = new Random();

public final static Gson json = new Gson();
public final static Gson formattedJson = new GsonBuilder()
.setPrettyPrinting()
Expand Down
Loading