forked from Fascinated/Bat
Compare commits
36 Commits
f07e30d843
...
80e7afedea
Author | SHA1 | Date | |
---|---|---|---|
80e7afedea | |||
285a0ca00a | |||
bd9ac1e138 | |||
3878d3029b | |||
831bc934b4 | |||
938005f6d9 | |||
5959b814a7 | |||
5f75302f3a | |||
a7a7bc784b | |||
2b4980fb10 | |||
655662c6f8 | |||
642185f8c5 | |||
c2e447f416 | |||
271a1cf88d | |||
11e7ca4aa6 | |||
f6834db9cb | |||
90aaf5422f | |||
e4183b4882 | |||
f62a022ed5 | |||
50b8b4b2c1 | |||
920755eae0 | |||
2255b02a60 | |||
f30697d1a6 | |||
83250d2c08 | |||
d7916ad24a | |||
295d673d06 | |||
da06a01097 | |||
6202aa6691 | |||
82a87c79b2 | |||
e795d542b9 | |||
162d7af46b | |||
821190a144 | |||
cb35182c6a | |||
ac499898e3 | |||
35596b720b | |||
048d2856f9 |
@ -18,7 +18,6 @@ public enum Category {
|
|||||||
SERVER(Emoji.fromFormatted("U+1F5A5"), "Server", false),
|
SERVER(Emoji.fromFormatted("U+1F5A5"), "Server", false),
|
||||||
UTILITY(Emoji.fromFormatted("U+1F6E0"), "Utility", false),
|
UTILITY(Emoji.fromFormatted("U+1F6E0"), "Utility", false),
|
||||||
MUSIC(Emoji.fromFormatted("U+1F3B5"), "Music", false),
|
MUSIC(Emoji.fromFormatted("U+1F3B5"), "Music", false),
|
||||||
MOVIES_TV(Emoji.fromFormatted("U+1F37F"), "Movies & TV", false),
|
|
||||||
SNIPE(Emoji.fromFormatted("U+1F4A3"), "Snipe", false),
|
SNIPE(Emoji.fromFormatted("U+1F4A3"), "Snipe", false),
|
||||||
LOGS(Emoji.fromFormatted("U+1F4D1"), "Logs", false),
|
LOGS(Emoji.fromFormatted("U+1F4D1"), "Logs", false),
|
||||||
BEAT_SABER(Emoji.fromFormatted("U+1FA84"), "Beat Saber", false),
|
BEAT_SABER(Emoji.fromFormatted("U+1FA84"), "Beat Saber", false),
|
||||||
|
@ -31,6 +31,7 @@ public class WebRequest {
|
|||||||
* @return the response
|
* @return the response
|
||||||
*/
|
*/
|
||||||
public static <T> T getAsEntity(String url, Class<T> clazz) throws RateLimitException {
|
public static <T> T getAsEntity(String url, Class<T> clazz) throws RateLimitException {
|
||||||
|
try {
|
||||||
ResponseEntity<T> responseEntity = CLIENT.get()
|
ResponseEntity<T> responseEntity = CLIENT.get()
|
||||||
.uri(url)
|
.uri(url)
|
||||||
.retrieve()
|
.retrieve()
|
||||||
@ -45,6 +46,11 @@ public class WebRequest {
|
|||||||
throw new RateLimitException("Rate limit reached");
|
throw new RateLimitException("Rate limit reached");
|
||||||
}
|
}
|
||||||
return responseEntity.getBody();
|
return responseEntity.getBody();
|
||||||
|
} catch (RateLimitException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
package cc.fascinated.bat.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
|
||||||
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
|
||||||
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
|
||||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class MongoConfig {
|
|
||||||
@Bean
|
|
||||||
public MappingMongoConverter mongoConverter(MongoDatabaseFactory mongoFactory, MongoMappingContext mongoMappingContext) {
|
|
||||||
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoFactory);
|
|
||||||
MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
|
|
||||||
mongoConverter.setMapKeyDotReplacement("-DOT");
|
|
||||||
return mongoConverter;
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,6 +19,7 @@ import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleAddEvent;
|
|||||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent;
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent;
|
||||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
|
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
|
||||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent;
|
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent;
|
||||||
|
import net.dv8tion.jda.api.events.guild.voice.GenericGuildVoiceEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
|
||||||
@ -232,6 +233,15 @@ public interface EventListener {
|
|||||||
default void onUserUpdateAvatar(@NonNull BatUser user, String oldAvatarUrl, String newAvatarUrl, @NonNull UserUpdateAvatarEvent event) {
|
default void onUserUpdateAvatar(@NonNull BatUser user, String oldAvatarUrl, String newAvatarUrl, @NonNull UserUpdateAvatarEvent event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a user joins or leaves a voice channel
|
||||||
|
*
|
||||||
|
* @param guild the guild that the user joined or left the voice channel in
|
||||||
|
* @param user the user that joined or left the voice channel
|
||||||
|
*/
|
||||||
|
default void onGuildVoiceUpdate(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GenericGuildVoiceEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when Spring is shutting down
|
* Called when Spring is shutting down
|
||||||
*/
|
*/
|
||||||
|
@ -49,7 +49,11 @@ public class AutoRoleListener implements EventListener {
|
|||||||
event.getGuild().addRoleToMember(event.getMember(), role).queue();
|
event.getGuild().addRoleToMember(event.getMember(), role).queue();
|
||||||
}
|
}
|
||||||
toRemove.forEach(profile::removeRole);
|
toRemove.forEach(profile::removeRole);
|
||||||
log.info("Gave user \"{}\" {} auto roles{}", user.getId(), profile.getRoles().size(), toRemove.isEmpty() ? ""
|
log.info("Gave user \"{}\" {} auto roles in guild \"{}\"{}",
|
||||||
: " and removed %s invalid roles".formatted(toRemove.size()));
|
user.getId(),
|
||||||
|
profile.getRoles().size(),
|
||||||
|
guild.getName(),
|
||||||
|
toRemove.isEmpty() ? "" : " and removed %s invalid roles from the profile".formatted(toRemove.size())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package cc.fascinated.bat.features.base;
|
|||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
||||||
import cc.fascinated.bat.features.Feature;
|
import cc.fascinated.bat.features.Feature;
|
||||||
import cc.fascinated.bat.features.base.commands.botadmin.premium.PremiumAdminCommand;
|
import cc.fascinated.bat.features.base.commands.botadmin.premium.PremiumAdminCommand;
|
||||||
|
import cc.fascinated.bat.features.base.commands.fun.EightBallCommand;
|
||||||
import cc.fascinated.bat.features.base.commands.fun.image.ImageCommand;
|
import cc.fascinated.bat.features.base.commands.fun.image.ImageCommand;
|
||||||
import cc.fascinated.bat.features.base.commands.general.*;
|
import cc.fascinated.bat.features.base.commands.general.*;
|
||||||
import cc.fascinated.bat.features.base.commands.general.avatar.AvatarCommand;
|
import cc.fascinated.bat.features.base.commands.general.avatar.AvatarCommand;
|
||||||
@ -39,5 +40,6 @@ public class BaseFeature extends Feature {
|
|||||||
super.registerCommand(commandService, context.getBean(AvatarCommand.class));
|
super.registerCommand(commandService, context.getBean(AvatarCommand.class));
|
||||||
super.registerCommand(commandService, context.getBean(ImageCommand.class));
|
super.registerCommand(commandService, context.getBean(ImageCommand.class));
|
||||||
super.registerCommand(commandService, context.getBean(FeatureCommand.class));
|
super.registerCommand(commandService, context.getBean(FeatureCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(EightBallCommand.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package cc.fascinated.bat.features.base.commands.fun;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "8ball", description = "Ask the magic 8ball a question")
|
||||||
|
public class EightBallCommand extends BatCommand {
|
||||||
|
private final String[] responses = new String[]{
|
||||||
|
"It is certain",
|
||||||
|
"It is decidedly so",
|
||||||
|
"Without a doubt",
|
||||||
|
"Yes, definitely",
|
||||||
|
"You may rely on it",
|
||||||
|
"As I see it, yes",
|
||||||
|
"Most likely",
|
||||||
|
"Outlook good",
|
||||||
|
"Yes",
|
||||||
|
"Signs point to yes",
|
||||||
|
"Reply hazy, try again",
|
||||||
|
"Ask again later",
|
||||||
|
"Better not tell you now",
|
||||||
|
"Cannot predict now",
|
||||||
|
"Concentrate and ask again",
|
||||||
|
"Don't count on it",
|
||||||
|
"My reply is no",
|
||||||
|
"My sources say no",
|
||||||
|
"Outlook not so good",
|
||||||
|
"Very doubtful"
|
||||||
|
};
|
||||||
|
|
||||||
|
public EightBallCommand() {
|
||||||
|
super.addOption(OptionType.STRING, "question", "The question you want to ask the 8ball", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
OptionMapping questionOption = event.getOption("question");
|
||||||
|
if (questionOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String question = questionOption.getAsString();
|
||||||
|
String response = responses[(int) (Math.random() * responses.length)];
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("You asked: `%s`\n\n:8ball: The magic 8ball says: `%s`".formatted(question, response))
|
||||||
|
.build())
|
||||||
|
.queue();
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,7 @@ public class VoteCommand extends BatCommand {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("Vote Links");
|
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("Vote Links");
|
||||||
description.appendLine("Vote for the bot on the following websites to support us!", true);
|
description.appendLine("Vote for the bot on the following websites to support us!", false);
|
||||||
for (String link : VOTE_LINKS) {
|
for (String link : VOTE_LINKS) {
|
||||||
description.appendLine(link, true);
|
description.appendLine(link, true);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,9 @@ public enum LogType {
|
|||||||
* Channel Events
|
* Channel Events
|
||||||
*/
|
*/
|
||||||
CHANNEL_CREATE(LogCategory.CHANNEL, "Channel Create"),
|
CHANNEL_CREATE(LogCategory.CHANNEL, "Channel Create"),
|
||||||
CHANNEL_DELETE(LogCategory.CHANNEL, "Channel Delete");
|
CHANNEL_DELETE(LogCategory.CHANNEL, "Channel Delete"),
|
||||||
|
VOICE_CHANNEL_JOIN(LogCategory.CHANNEL, "Voice Channel Join"),
|
||||||
|
VOICE_CHANNEL_LEAVE(LogCategory.CHANNEL, "Voice Channel Leave");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The category of the log type
|
* The category of the log type
|
||||||
|
@ -7,20 +7,33 @@ import cc.fascinated.bat.event.EventListener;
|
|||||||
import cc.fascinated.bat.features.logging.LogFeature;
|
import cc.fascinated.bat.features.logging.LogFeature;
|
||||||
import cc.fascinated.bat.features.logging.LogType;
|
import cc.fascinated.bat.features.logging.LogType;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.unions.AudioChannelUnion;
|
||||||
import net.dv8tion.jda.api.entities.channel.unions.ChannelUnion;
|
import net.dv8tion.jda.api.entities.channel.unions.ChannelUnion;
|
||||||
import net.dv8tion.jda.api.events.channel.ChannelCreateEvent;
|
import net.dv8tion.jda.api.events.channel.ChannelCreateEvent;
|
||||||
import net.dv8tion.jda.api.events.channel.ChannelDeleteEvent;
|
import net.dv8tion.jda.api.events.channel.ChannelDeleteEvent;
|
||||||
|
import net.dv8tion.jda.api.events.guild.voice.GenericGuildVoiceEvent;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@Log4j2
|
||||||
public class ChannelListener implements EventListener {
|
public class ChannelListener implements EventListener {
|
||||||
|
/**
|
||||||
|
* A map of users and the last voice channel they were in
|
||||||
|
*/
|
||||||
|
private final Map<BatUser, VoiceChannel> lastVoiceChannel = new HashMap<>();
|
||||||
private final LogFeature logFeature;
|
private final LogFeature logFeature;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -30,6 +43,7 @@ public class ChannelListener implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelCreate(@NonNull BatGuild guild, @NonNull ChannelCreateEvent event) {
|
public void onChannelCreate(@NonNull BatGuild guild, @NonNull ChannelCreateEvent event) {
|
||||||
|
log.info("Channel \"{}\" was created in guild \"{}\"", event.getChannel().getName(), guild.getName());
|
||||||
logFeature.sendLog(guild, LogType.CHANNEL_CREATE, EmbedUtils.successEmbed()
|
logFeature.sendLog(guild, LogType.CHANNEL_CREATE, EmbedUtils.successEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("%s Channel Created".formatted(EnumUtils.getEnumName(event.getChannel().getType())))
|
.setDescription(new EmbedDescriptionBuilder("%s Channel Created".formatted(EnumUtils.getEnumName(event.getChannel().getType())))
|
||||||
.appendLine("Channel: %s".formatted(event.getChannel().getAsMention()), true)
|
.appendLine("Channel: %s".formatted(event.getChannel().getAsMention()), true)
|
||||||
@ -40,6 +54,7 @@ public class ChannelListener implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelDelete(@NonNull BatGuild guild, @NonNull ChannelDeleteEvent event) {
|
public void onChannelDelete(@NonNull BatGuild guild, @NonNull ChannelDeleteEvent event) {
|
||||||
|
log.info("Channel \"{}\" was deleted in guild \"{}\"", event.getChannel().getName(), guild.getName());
|
||||||
ChannelUnion channel = event.getChannel();
|
ChannelUnion channel = event.getChannel();
|
||||||
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("%s Channel Deleted".formatted(EnumUtils.getEnumName(channel.getType())))
|
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("%s Channel Deleted".formatted(EnumUtils.getEnumName(channel.getType())))
|
||||||
.appendLine("Name: #%s".formatted(channel.getName()), true);
|
.appendLine("Name: #%s".formatted(channel.getName()), true);
|
||||||
@ -49,4 +64,31 @@ public class ChannelListener implements EventListener {
|
|||||||
}
|
}
|
||||||
logFeature.sendLog(guild, LogType.CHANNEL_DELETE, EmbedUtils.errorEmbed().setDescription(description.build()).build());
|
logFeature.sendLog(guild, LogType.CHANNEL_DELETE, EmbedUtils.errorEmbed().setDescription(description.build()).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGuildVoiceUpdate(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GenericGuildVoiceEvent event) {
|
||||||
|
AudioChannelUnion channel = event.getVoiceState().getChannel();
|
||||||
|
if (channel != null) {
|
||||||
|
VoiceChannel voiceChannel = channel.asVoiceChannel();
|
||||||
|
lastVoiceChannel.put(user, voiceChannel);
|
||||||
|
}
|
||||||
|
VoiceChannel voiceChannel = lastVoiceChannel.get(user);
|
||||||
|
if (voiceChannel == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean joined = voiceChannel.getMembers().contains(event.getMember());
|
||||||
|
if (!joined) {
|
||||||
|
lastVoiceChannel.remove(user);
|
||||||
|
}
|
||||||
|
log.info("User \"{}\" {} voice channel \"{}\" in guild \"{}\"", user.getId(), joined ? "joined" : "left", voiceChannel.getName(), guild.getName());
|
||||||
|
String description = new EmbedDescriptionBuilder("User %s Voice Channel".formatted(joined ? "Joined" : "Left"))
|
||||||
|
.appendLine("User: %s".formatted(user.getDiscordUser().getAsMention()), true)
|
||||||
|
.appendLine("Channel: %s".formatted(voiceChannel.getAsMention()), true)
|
||||||
|
.build();
|
||||||
|
if (joined) {
|
||||||
|
logFeature.sendLog(guild, LogType.VOICE_CHANNEL_JOIN, EmbedUtils.successEmbed().setDescription(description).build());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logFeature.sendLog(guild, LogType.VOICE_CHANNEL_LEAVE, EmbedUtils.errorEmbed().setDescription(description).build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEv
|
|||||||
import net.dv8tion.jda.api.events.user.update.UserUpdateAvatarEvent;
|
import net.dv8tion.jda.api.events.user.update.UserUpdateAvatarEvent;
|
||||||
import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent;
|
import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent;
|
||||||
import net.dv8tion.jda.api.events.user.update.UserUpdateNameEvent;
|
import net.dv8tion.jda.api.events.user.update.UserUpdateNameEvent;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -35,6 +37,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class MemberListener implements EventListener {
|
public class MemberListener implements EventListener {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MemberListener.class);
|
||||||
private final LogFeature logFeature;
|
private final LogFeature logFeature;
|
||||||
private final GuildService guildService;
|
private final GuildService guildService;
|
||||||
|
|
||||||
@ -47,12 +50,13 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onGuildMemberJoin(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberJoinEvent event) {
|
public void onGuildMemberJoin(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberJoinEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" joined the guild \"{}\"", user.getName(), guild.getDiscordGuild().getName());
|
||||||
|
|
||||||
logFeature.sendLog(guild, LogType.MEMBER_JOIN, EmbedUtils.successEmbed()
|
logFeature.sendLog(guild, LogType.MEMBER_JOIN, EmbedUtils.successEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Joined")
|
.setDescription(new EmbedDescriptionBuilder("Member Joined")
|
||||||
.appendLine("Member: %s".formatted(user.getDiscordUser().getAsMention()), true)
|
.appendLine("Member: %s".formatted(user.getDiscordUser().getAsMention()), true)
|
||||||
.appendLine("Username: %s".formatted(user.getDiscordUser().getName()), true)
|
.appendLine("Username: %s".formatted(user.getDiscordUser().getName()), true)
|
||||||
.appendLine("Account Age: <t:%s:R>".formatted(user.getDiscordUser().getTimeCreated().toEpochSecond()), true)
|
.appendLine("Joined Discord: <t:%s:R>".formatted(user.getDiscordUser().getTimeCreated().toEpochSecond()), true)
|
||||||
.build())
|
.build())
|
||||||
.setThumbnail(user.getDiscordUser().getEffectiveAvatarUrl())
|
.setThumbnail(user.getDiscordUser().getEffectiveAvatarUrl())
|
||||||
.build());
|
.build());
|
||||||
@ -60,12 +64,13 @@ public class MemberListener implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGuildMemberLeave(@NonNull BatGuild guild, BatUser user, @NonNull GuildMemberRemoveEvent event) {
|
public void onGuildMemberLeave(@NonNull BatGuild guild, BatUser user, @NonNull GuildMemberRemoveEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user == null || user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" left the guild \"{}\"", user.getName(), guild.getDiscordGuild().getName());
|
||||||
|
|
||||||
logFeature.sendLog(guild, LogType.MEMBER_LEAVE, EmbedUtils.errorEmbed()
|
logFeature.sendLog(guild, LogType.MEMBER_LEAVE, EmbedUtils.errorEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Left")
|
.setDescription(new EmbedDescriptionBuilder("Member Left")
|
||||||
.appendLine("Member: %s".formatted(user.getDiscordUser().getAsMention()), true)
|
.appendLine("Member: <@%s>".formatted(user.getId()), true)
|
||||||
.appendLine("Username: %s".formatted(user.getDiscordUser().getName()), true)
|
.appendLine("Username: %s".formatted(user.getName()), true)
|
||||||
.build())
|
.build())
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
@ -73,6 +78,7 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onGuildMemberUpdateNickname(@NonNull BatGuild guild, @NonNull BatUser user, String oldName, String newName, @NonNull GuildMemberUpdateNicknameEvent event) {
|
public void onGuildMemberUpdateNickname(@NonNull BatGuild guild, @NonNull BatUser user, String oldName, String newName, @NonNull GuildMemberUpdateNicknameEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" changed their nickname from \"{}\" to \"{}\" in the guild \"{}\"", user.getName(), oldName, newName, guild.getDiscordGuild().getName());
|
||||||
|
|
||||||
logFeature.sendLog(guild, LogType.MEMBER_NICKNAME_UPDATE, EmbedUtils.genericEmbed()
|
logFeature.sendLog(guild, LogType.MEMBER_NICKNAME_UPDATE, EmbedUtils.genericEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Nickname Updated")
|
.setDescription(new EmbedDescriptionBuilder("Member Nickname Updated")
|
||||||
@ -86,9 +92,12 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onUserUpdateGlobalName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateGlobalNameEvent event) {
|
public void onUserUpdateGlobalName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateGlobalNameEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" changed their global name from \"{}\" to \"{}\"", user.getName(), oldName, newName);
|
||||||
|
|
||||||
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
||||||
BatGuild batGuild = guildService.getGuild(guild.getId());
|
BatGuild batGuild = guildService.getGuild(guild.getId());
|
||||||
if (batGuild == null) continue;
|
if (batGuild == null) continue;
|
||||||
|
if (!guild.isMember(user.getDiscordUser())) continue; // User is not in the guild
|
||||||
|
|
||||||
logFeature.sendLog(batGuild, LogType.MEMBER_GLOBAL_NAME_UPDATE, EmbedUtils.genericEmbed()
|
logFeature.sendLog(batGuild, LogType.MEMBER_GLOBAL_NAME_UPDATE, EmbedUtils.genericEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Name Updated")
|
.setDescription(new EmbedDescriptionBuilder("Member Name Updated")
|
||||||
@ -103,9 +112,12 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onUserUpdateName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateNameEvent event) {
|
public void onUserUpdateName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateNameEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" changed their username from \"{}\" to \"{}\"", user.getName(), oldName, newName);
|
||||||
|
|
||||||
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
||||||
BatGuild batGuild = guildService.getGuild(guild.getId());
|
BatGuild batGuild = guildService.getGuild(guild.getId());
|
||||||
if (batGuild == null) continue;
|
if (batGuild == null) continue;
|
||||||
|
if (!guild.isMember(user.getDiscordUser())) continue; // User is not in the guild
|
||||||
|
|
||||||
logFeature.sendLog(batGuild, LogType.MEMBER_USERNAME_UPDATE, EmbedUtils.genericEmbed()
|
logFeature.sendLog(batGuild, LogType.MEMBER_USERNAME_UPDATE, EmbedUtils.genericEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Username Updated")
|
.setDescription(new EmbedDescriptionBuilder("Member Username Updated")
|
||||||
@ -120,14 +132,17 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onUserUpdateAvatar(@NonNull BatUser user, String oldAvatarUrl, String newAvatarUrl, @NonNull UserUpdateAvatarEvent event) {
|
public void onUserUpdateAvatar(@NonNull BatUser user, String oldAvatarUrl, String newAvatarUrl, @NonNull UserUpdateAvatarEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" changed their avatar to \"{}\"", user.getName(), newAvatarUrl);
|
||||||
|
|
||||||
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
||||||
BatGuild batGuild = guildService.getGuild(guild.getId());
|
BatGuild batGuild = guildService.getGuild(guild.getId());
|
||||||
if (batGuild == null) continue;
|
if (batGuild == null) continue;
|
||||||
|
if (!guild.isMember(user.getDiscordUser())) continue; // User is not in the guild
|
||||||
|
|
||||||
logFeature.sendLog(batGuild, LogType.MEMBER_USERNAME_UPDATE, EmbedUtils.genericEmbed()
|
logFeature.sendLog(batGuild, LogType.MEMBER_USERNAME_UPDATE, EmbedUtils.genericEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Avatar Updated")
|
.setDescription(new EmbedDescriptionBuilder("Member Avatar Updated")
|
||||||
.appendLine("Member: %s".formatted(user.getDiscordUser().getAsMention()), true)
|
.appendLine("Member: %s".formatted(user.getDiscordUser().getAsMention()), true)
|
||||||
.appendLine("Old Avatar: [avatar](%s)".formatted(oldAvatarUrl), true)
|
.appendLine("Old Avatar: %s".formatted(oldAvatarUrl == null ? "None" : "[avatar](%s)".formatted(oldAvatarUrl)), true)
|
||||||
.appendLine("New Avatar: [avatar](%s)".formatted(newAvatarUrl), true)
|
.appendLine("New Avatar: [avatar](%s)".formatted(newAvatarUrl), true)
|
||||||
.build())
|
.build())
|
||||||
.build());
|
.build());
|
||||||
@ -137,6 +152,7 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onGuildMemberRoleAdd(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull List<Role> rolesAdded, @NonNull GuildMemberRoleAddEvent event) {
|
public void onGuildMemberRoleAdd(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull List<Role> rolesAdded, @NonNull GuildMemberRoleAddEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" was given {} roles in the guild \"{}\"", user.getName(), rolesAdded.size(), guild.getDiscordGuild().getName());
|
||||||
|
|
||||||
StringBuilder roles = new StringBuilder();
|
StringBuilder roles = new StringBuilder();
|
||||||
for (Role role : rolesAdded) {
|
for (Role role : rolesAdded) {
|
||||||
@ -155,6 +171,7 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onGuildMemberRoleRemove(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull List<Role> rolesAdded, @NonNull GuildMemberRoleRemoveEvent event) {
|
public void onGuildMemberRoleRemove(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull List<Role> rolesAdded, @NonNull GuildMemberRoleRemoveEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" had {} roles removed in the guild \"{}\"", user.getName(), rolesAdded.size(), guild.getDiscordGuild().getName());
|
||||||
|
|
||||||
StringBuilder roles = new StringBuilder();
|
StringBuilder roles = new StringBuilder();
|
||||||
for (Role role : rolesAdded) {
|
for (Role role : rolesAdded) {
|
||||||
@ -173,6 +190,7 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onGuildMemberBan(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildBanEvent event) {
|
public void onGuildMemberBan(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildBanEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" was banned from the guild \"{}\"", user.getName(), guild.getDiscordGuild().getName());
|
||||||
|
|
||||||
logFeature.sendLog(guild, LogType.MEMBER_BAN, EmbedUtils.errorEmbed()
|
logFeature.sendLog(guild, LogType.MEMBER_BAN, EmbedUtils.errorEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Banned")
|
.setDescription(new EmbedDescriptionBuilder("Member Banned")
|
||||||
@ -184,6 +202,7 @@ public class MemberListener implements EventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onGuildMemberUnban(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildUnbanEvent event) {
|
public void onGuildMemberUnban(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildUnbanEvent event) {
|
||||||
if (user.getDiscordUser().isBot()) return;
|
if (user.getDiscordUser().isBot()) return;
|
||||||
|
log.info("User \"{}\" was unbanned from the guild \"{}\"", user.getName(), guild.getDiscordGuild().getName());
|
||||||
|
|
||||||
logFeature.sendLog(guild, LogType.MEMBER_UNBAN, EmbedUtils.successEmbed()
|
logFeature.sendLog(guild, LogType.MEMBER_UNBAN, EmbedUtils.successEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Member Unbanned")
|
.setDescription(new EmbedDescriptionBuilder("Member Unbanned")
|
||||||
@ -196,6 +215,7 @@ public class MemberListener implements EventListener {
|
|||||||
public void onGuildMemberTimeout(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberUpdateTimeOutEvent event) {
|
public void onGuildMemberTimeout(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberUpdateTimeOutEvent event) {
|
||||||
OffsetDateTime timeoutEnd = event.getNewTimeOutEnd();
|
OffsetDateTime timeoutEnd = event.getNewTimeOutEnd();
|
||||||
if (user.getDiscordUser().isBot() || timeoutEnd == null) return;
|
if (user.getDiscordUser().isBot() || timeoutEnd == null) return;
|
||||||
|
log.info("User \"{}\" was timed out until \"{}\"", user.getName(), timeoutEnd);
|
||||||
|
|
||||||
long seconds = timeoutEnd.toInstant().getEpochSecond();
|
long seconds = timeoutEnd.toInstant().getEpochSecond();
|
||||||
logFeature.sendLog(guild, LogType.MEMBER_TIMEOUT, EmbedUtils.errorEmbed()
|
logFeature.sendLog(guild, LogType.MEMBER_TIMEOUT, EmbedUtils.errorEmbed()
|
||||||
|
@ -9,6 +9,7 @@ import cc.fascinated.bat.model.BatGuild;
|
|||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.model.DiscordMessage;
|
import cc.fascinated.bat.model.DiscordMessage;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
|
import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
|
||||||
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
|
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -19,6 +20,7 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@Log4j2
|
||||||
public class MessageListener implements EventListener {
|
public class MessageListener implements EventListener {
|
||||||
private final LogFeature logFeature;
|
private final LogFeature logFeature;
|
||||||
|
|
||||||
@ -29,7 +31,8 @@ public class MessageListener implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGuildMessageDelete(@NonNull BatGuild guild, BatUser user, DiscordMessage message, @NonNull MessageDeleteEvent event) {
|
public void onGuildMessageDelete(@NonNull BatGuild guild, BatUser user, DiscordMessage message, @NonNull MessageDeleteEvent event) {
|
||||||
if (user.getDiscordUser().isBot() || message.getAuthor().isBot()) return;
|
if (user == null || user.getDiscordUser().isBot() || message.getAuthor().isBot()) return;
|
||||||
|
log.info("User \"{}\" deleted a message in guild \"{}\"", user.getDiscordUser().getGlobalName(), guild.getName());
|
||||||
|
|
||||||
logFeature.sendLog(guild, LogType.MESSAGE_DELETE, EmbedUtils.errorEmbed()
|
logFeature.sendLog(guild, LogType.MESSAGE_DELETE, EmbedUtils.errorEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Message Deleted")
|
.setDescription(new EmbedDescriptionBuilder("Message Deleted")
|
||||||
@ -44,6 +47,7 @@ public class MessageListener implements EventListener {
|
|||||||
public void onGuildMessageEdit(@NonNull BatGuild guild, @NonNull BatUser user, DiscordMessage oldMessage,
|
public void onGuildMessageEdit(@NonNull BatGuild guild, @NonNull BatUser user, DiscordMessage oldMessage,
|
||||||
@NonNull DiscordMessage newMessage, @NonNull MessageUpdateEvent event) {
|
@NonNull DiscordMessage newMessage, @NonNull MessageUpdateEvent event) {
|
||||||
if (user.getDiscordUser().isBot() || newMessage.getAuthor().isBot() || oldMessage == null) return;
|
if (user.getDiscordUser().isBot() || newMessage.getAuthor().isBot() || oldMessage == null) return;
|
||||||
|
log.info("User \"{}\" edited a message in guild \"{}\"", user.getDiscordUser().getGlobalName(), guild.getName());
|
||||||
|
|
||||||
logFeature.sendLog(guild, LogType.MESSAGE_EDIT, EmbedUtils.genericEmbed()
|
logFeature.sendLog(guild, LogType.MESSAGE_EDIT, EmbedUtils.genericEmbed()
|
||||||
.setDescription(new EmbedDescriptionBuilder("Message Edited")
|
.setDescription(new EmbedDescriptionBuilder("Message Edited")
|
||||||
|
@ -30,7 +30,7 @@ public class MessageSnipeFeature extends Feature implements EventListener {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public MessageSnipeFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
public MessageSnipeFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
super("Message Snipe", false, Category.SNIPE);
|
super("Message Snipe", false, Category.MESSAGES);
|
||||||
|
|
||||||
super.registerCommand(commandService, context.getBean(MessageSnipeCommand.class));
|
super.registerCommand(commandService, context.getBean(MessageSnipeCommand.class));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package cc.fascinated.bat.features.moderation;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.Category;
|
||||||
|
import cc.fascinated.bat.features.Feature;
|
||||||
|
import cc.fascinated.bat.features.moderation.command.PurgeCommand;
|
||||||
|
import cc.fascinated.bat.service.CommandService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ModerationFeature extends Feature {
|
||||||
|
@Autowired
|
||||||
|
public ModerationFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
|
super("Moderation", true,Category.MODERATION);
|
||||||
|
|
||||||
|
super.registerCommand(commandService, context.getBean(PurgeCommand.class));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package cc.fascinated.bat.features.moderation.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "purge", description = "Purge messages from a channel", requiredPermissions = Permission.MESSAGE_MANAGE)
|
||||||
|
public class PurgeCommand extends BatCommand {
|
||||||
|
private final long MESSAGE_DELETE_DELAY = TimeUnit.SECONDS.toMillis(10);
|
||||||
|
|
||||||
|
public PurgeCommand() {
|
||||||
|
super.addOption(OptionType.INTEGER, "amount", "The amount of messages to remove", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
OptionMapping amountOption = event.getOption("amount");
|
||||||
|
if (amountOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int amount = amountOption.getAsInt();
|
||||||
|
if (amount < 2 || amount > 100) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You can only purge between 2 and 100 messages")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Purging `%s` messages...".formatted(amount))
|
||||||
|
.build()).queue(then -> {
|
||||||
|
TextChannel textChannel = (TextChannel) channel;
|
||||||
|
textChannel.getHistory().retrievePast(amount + 1).queue(messages -> {
|
||||||
|
// Filter out the command message
|
||||||
|
then.retrieveOriginal().queue(original -> {
|
||||||
|
if (original == null) return;
|
||||||
|
List<Message> toRemove = messages.stream().filter(message -> !original.getId().equals(message.getId())).toList();
|
||||||
|
textChannel.deleteMessages(toRemove).queue(done -> then.editOriginalEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Successfully purged `%s` messages\n\n*This message will be removed <t:%s:R>*".formatted(
|
||||||
|
amount,
|
||||||
|
(System.currentTimeMillis() + MESSAGE_DELETE_DELAY) / 1000
|
||||||
|
))
|
||||||
|
.build()).queue(message -> message.delete().queueAfter(MESSAGE_DELETE_DELAY, TimeUnit.MILLISECONDS)));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package cc.fascinated.bat.features.reminder;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor @Getter
|
||||||
|
public class Reminder {
|
||||||
|
/**
|
||||||
|
* What we should remind the user of
|
||||||
|
*/
|
||||||
|
private final String reminder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel ID to send the reminder to
|
||||||
|
*/
|
||||||
|
private final String channelId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date the reminder should end
|
||||||
|
*/
|
||||||
|
private final Date endDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the reminder is expired
|
||||||
|
*
|
||||||
|
* @return If the reminder is expired
|
||||||
|
*/
|
||||||
|
public boolean isExpired() {
|
||||||
|
return System.currentTimeMillis() >= endDate.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the channel to send the reminder to
|
||||||
|
*
|
||||||
|
* @return The channel
|
||||||
|
*/
|
||||||
|
public TextChannel getChannel() {
|
||||||
|
return DiscordService.JDA.getTextChannelById(channelId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package cc.fascinated.bat.features.reminder;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.Category;
|
||||||
|
import cc.fascinated.bat.features.Feature;
|
||||||
|
import cc.fascinated.bat.features.reminder.command.ReminderCommand;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.service.CommandService;
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.DependsOn;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Log4j2(topic = "Reminder Feature")
|
||||||
|
@DependsOn("discordService")
|
||||||
|
public class ReminderFeature extends Feature {
|
||||||
|
public static final int MAX_REMINDERS = 5; // 5 reminders
|
||||||
|
public static final long MAX_REMINDER_LENGTH = TimeUnit.DAYS.toMillis(30); // 1 month
|
||||||
|
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ReminderFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService, @NonNull GuildService guildService) {
|
||||||
|
super("Reminder", true, Category.GENERAL);
|
||||||
|
this.guildService = guildService;
|
||||||
|
|
||||||
|
super.registerCommand(commandService, context.getBean(ReminderCommand.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "*/30 * * * * *")
|
||||||
|
public void checkReminders() {
|
||||||
|
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
||||||
|
BatGuild batGuild = guildService.getGuild(guild.getId());
|
||||||
|
if (batGuild == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReminderProfile reminderProfile = batGuild.getProfile(ReminderProfile.class);
|
||||||
|
if (reminderProfile == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<User, List<Reminder>> entry : reminderProfile.getReminders().entrySet()) {
|
||||||
|
User user = entry.getKey();
|
||||||
|
List<Reminder> toRemove = new ArrayList<>();
|
||||||
|
List<Reminder> reminders = entry.getValue();
|
||||||
|
for (Reminder reminder : reminders) {
|
||||||
|
if (!reminder.isExpired()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
toRemove.add(reminder);
|
||||||
|
TextChannel channel = reminder.getChannel();
|
||||||
|
if (channel != null) {
|
||||||
|
channel.sendMessage("Hey %s! ⏰ It's time for your reminder: `%s`".formatted(
|
||||||
|
user.getAsMention(),
|
||||||
|
reminder.getReminder()
|
||||||
|
)).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toRemove.forEach(reminder -> reminderProfile.removeReminder(user, reminder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
package cc.fascinated.bat.features.reminder;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.Serializable;
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class ReminderProfile extends Serializable {
|
||||||
|
/**
|
||||||
|
* The reminders in the guild
|
||||||
|
*/
|
||||||
|
private final Map<User, List<Reminder>> reminders = new HashMap<>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the amount of reminders a user has
|
||||||
|
*
|
||||||
|
* @param user The user to get the reminders for
|
||||||
|
* @return The amount of reminders the user has
|
||||||
|
*/
|
||||||
|
public int getReminderCount(User user) {
|
||||||
|
List<Reminder> reminderList = reminders.get(user);
|
||||||
|
return reminderList == null ? 0 : reminderList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove all reminders for a user
|
||||||
|
*
|
||||||
|
* @param user The user to remove the reminders for
|
||||||
|
*/
|
||||||
|
public void removeReminders(User user) {
|
||||||
|
reminders.remove(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if a user has reminders
|
||||||
|
*
|
||||||
|
* @param user The user to check for
|
||||||
|
* @return If the user has reminders
|
||||||
|
*/
|
||||||
|
public boolean hasReminders(User user) {
|
||||||
|
return reminders.containsKey(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the reminders for a user
|
||||||
|
*
|
||||||
|
* @param user The user to get the reminders for
|
||||||
|
* @return The reminders for the user
|
||||||
|
*/
|
||||||
|
public List<Reminder> getReminders(User user) {
|
||||||
|
return reminders.get(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a reminder for a user
|
||||||
|
*
|
||||||
|
* @param user The user to add the reminder for
|
||||||
|
* @param reminder The reminder to add
|
||||||
|
*/
|
||||||
|
public Reminder addReminder(User user, TextChannel channel, String reason, Date endDate) {
|
||||||
|
List<Reminder> reminderList = reminders.get(user);
|
||||||
|
if (reminderList == null) {
|
||||||
|
reminderList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
Reminder reminder = new Reminder(reason, channel.getId(), endDate);
|
||||||
|
reminderList.add(reminder);
|
||||||
|
reminders.put(user, reminderList);
|
||||||
|
return reminder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove a reminder for a user
|
||||||
|
*
|
||||||
|
* @param user The user to remove the reminder for
|
||||||
|
* @param reminder The reminder to remove
|
||||||
|
*/
|
||||||
|
public void removeReminder(User user, Reminder reminder) {
|
||||||
|
List<Reminder> reminderList = reminders.get(user);
|
||||||
|
if (reminderList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reminderList.remove(reminder);
|
||||||
|
reminders.put(user, reminderList);
|
||||||
|
|
||||||
|
if (reminderList.isEmpty()) {
|
||||||
|
reminders.remove(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Document document, Gson gson) {
|
||||||
|
for (String key : document.keySet()) {
|
||||||
|
User user = DiscordService.JDA.getUserById(key);
|
||||||
|
if (user == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
List<Reminder> reminderList = new ArrayList<>();
|
||||||
|
for (Document reminderDocument : document.getList(key, Document.class)) {
|
||||||
|
reminderList.add(new Reminder(
|
||||||
|
reminderDocument.getString("reminder"),
|
||||||
|
reminderDocument.getString("channelId"),
|
||||||
|
reminderDocument.getDate("endDate")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
reminders.put(user, reminderList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Document serialize(Gson gson) {
|
||||||
|
Document document = new Document();
|
||||||
|
for (Map.Entry<User, List<Reminder>> entry : reminders.entrySet()) {
|
||||||
|
List<Document> reminderDocuments = new ArrayList<>();
|
||||||
|
List<Reminder> value = entry.getValue();
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Reminder reminder : value) {
|
||||||
|
Document reminderDocument = new Document();
|
||||||
|
reminderDocument.append("reminder", reminder.getReminder());
|
||||||
|
reminderDocument.append("channelId", reminder.getChannelId());
|
||||||
|
reminderDocument.append("endDate", reminder.getEndDate());
|
||||||
|
reminderDocuments.add(reminderDocument);
|
||||||
|
}
|
||||||
|
document.append(entry.getKey().getId(), reminderDocuments);
|
||||||
|
}
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
reminders.clear();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package cc.fascinated.bat.features.reminder.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.reminder.ReminderProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("reminder:clear.sub")
|
||||||
|
@CommandInfo(name = "clear", description = "Clear all your active reminders.")
|
||||||
|
public class ClearSubCommand extends BatSubCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
ReminderProfile profile = guild.getReminderProfile();
|
||||||
|
if (!profile.hasReminders(user.getDiscordUser())) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You do not have any active reminders.")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int reminderCount = profile.getReminderCount(user.getDiscordUser());
|
||||||
|
profile.removeReminders(user.getDiscordUser());
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Successfully cleared %s reminders.".formatted(reminderCount))
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package cc.fascinated.bat.features.reminder.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.reminder.Reminder;
|
||||||
|
import cc.fascinated.bat.features.reminder.ReminderProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("reminder:list.sub")
|
||||||
|
@CommandInfo(name = "list", description = "View your active reminders.")
|
||||||
|
public class ListSubCommand extends BatSubCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
ReminderProfile profile = guild.getReminderProfile();
|
||||||
|
if (!profile.hasReminders(user.getDiscordUser())) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You do not have any active reminders.")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("Active Reminders");
|
||||||
|
for (Reminder reminder : profile.getReminders(user.getDiscordUser())) {
|
||||||
|
description.appendLine("%s - <t:%s:R> %s".formatted(
|
||||||
|
reminder.getReminder(),
|
||||||
|
reminder.getEndDate().toInstant().getEpochSecond(),
|
||||||
|
reminder.getChannel().getAsMention()
|
||||||
|
), true);
|
||||||
|
}
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription(description.build())
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package cc.fascinated.bat.features.reminder.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "reminder", description = "Set or view reminders.")
|
||||||
|
public class ReminderCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public ReminderCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommand(context.getBean(SetSubCommand.class));
|
||||||
|
super.addSubCommand(context.getBean(ListSubCommand.class));
|
||||||
|
super.addSubCommand(context.getBean(ClearSubCommand.class));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package cc.fascinated.bat.features.reminder.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.TimeUtils;
|
||||||
|
import cc.fascinated.bat.features.reminder.Reminder;
|
||||||
|
import cc.fascinated.bat.features.reminder.ReminderFeature;
|
||||||
|
import cc.fascinated.bat.features.reminder.ReminderProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("reminder:set.sub")
|
||||||
|
@CommandInfo(name = "set", description = "Set a reminder.")
|
||||||
|
public class SetSubCommand extends BatSubCommand {
|
||||||
|
public SetSubCommand() {
|
||||||
|
super.addOption(OptionType.STRING, "reminder", "The reminder to set.", true);
|
||||||
|
super.addOption(OptionType.STRING, "time", "After how long should the reminder be sent. (eg: 5m)", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
ReminderProfile profile = guild.getReminderProfile();
|
||||||
|
if (profile.getReminderCount(user.getDiscordUser()) >= ReminderFeature.MAX_REMINDERS) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You have reached the maximum amount of reminders.")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionMapping reminderOption = event.getOption("reminder");
|
||||||
|
if (reminderOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OptionMapping timeOption = event.getOption("time");
|
||||||
|
if (timeOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String reminderText = reminderOption.getAsString();
|
||||||
|
long time = TimeUtils.fromString(timeOption.getAsString());
|
||||||
|
if (time == 0) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("Invalid time format.")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (time < TimeUnit.MINUTES.toMillis(1)) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The time must be at least 1 minute.")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (time > ReminderFeature.MAX_REMINDER_LENGTH) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The time must be at most %s.".formatted(TimeUtils.format(ReminderFeature.MAX_REMINDER_LENGTH)))
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Reminder reminder = profile.addReminder(user.getDiscordUser(), event.getChannel().asTextChannel(), reminderText, new Date(System.currentTimeMillis() + time));
|
||||||
|
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Reminder for `%s` set, you will be reminded <t:%s:R>".formatted(reminderText,
|
||||||
|
reminder.getEndDate().toInstant().getEpochSecond()))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +41,9 @@ public class CurrentSubCommand extends BatSubCommand implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
event.replyEmbeds(SpotifyFeature.currentSong(spotifyService, user).build()).addComponents(createActions()).queue();
|
event.replyEmbeds(SpotifyFeature.currentSong(spotifyService, user).build()).addComponents(createActions()).queue(message -> {
|
||||||
|
message.editOriginalComponents(new ArrayList<>()).queueAfter(5, TimeUnit.MINUTES); // Remove the buttons after 5 minutes
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @SneakyThrows
|
@Override @SneakyThrows
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class WelcomerEmbed {
|
||||||
|
/**
|
||||||
|
* The title of the embed
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description of the embed
|
||||||
|
*/
|
||||||
|
@NonNull private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the embed
|
||||||
|
*/
|
||||||
|
@NonNull private String color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we ping the user before sending the message?
|
||||||
|
*/
|
||||||
|
private boolean pingBeforeSend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the embed and replaces the placeholders
|
||||||
|
*
|
||||||
|
* @return The built embed
|
||||||
|
*/
|
||||||
|
public EmbedBuilder buildEmbed(Object... replacements) {
|
||||||
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
if (title != null) {
|
||||||
|
embedBuilder.setTitle(WelcomerPlaceholders.replaceAllPlaceholders(title, replacements));
|
||||||
|
}
|
||||||
|
embedBuilder.setDescription(WelcomerPlaceholders.replaceAllPlaceholders(description, replacements));
|
||||||
|
embedBuilder.setColor(Integer.parseInt(color, 16));
|
||||||
|
return embedBuilder;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.Category;
|
||||||
|
import cc.fascinated.bat.features.Feature;
|
||||||
|
import cc.fascinated.bat.features.welcomer.command.WelcomerCommand;
|
||||||
|
import cc.fascinated.bat.service.CommandService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class WelcomerFeature extends Feature {
|
||||||
|
@Autowired
|
||||||
|
public WelcomerFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
|
super("Welcomer", true,Category.SERVER);
|
||||||
|
|
||||||
|
super.registerCommand(commandService, context.getBean(WelcomerCommand.class));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.event.EventListener;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class WelcomerListener implements EventListener {
|
||||||
|
private final WelcomerFeature welcomerFeature;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public WelcomerListener(WelcomerFeature welcomerFeature) {
|
||||||
|
this.welcomerFeature = welcomerFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGuildMemberJoin(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberJoinEvent event) {
|
||||||
|
if (guild.getFeatureProfile().isFeatureDisabled(welcomerFeature)) { // Check if the feature is disabled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WelcomerProfile profile = guild.getWelcomerProfile();
|
||||||
|
profile.sendWelcomeMessage(guild, user);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class WelcomerMessage {
|
||||||
|
/**
|
||||||
|
* The message to send
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the message and replaces the placeholders
|
||||||
|
*
|
||||||
|
* @return The built message
|
||||||
|
*/
|
||||||
|
public String buildMessage(Object... replacements) {
|
||||||
|
return WelcomerPlaceholders.replaceAllPlaceholders(message, replacements);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum WelcomerPlaceholders {
|
||||||
|
USER_MENTION("{user_mention}", BatUser.class) {
|
||||||
|
@Override
|
||||||
|
public String replacePlaceholder(Object object) {
|
||||||
|
return ((BatUser) object).getDiscordUser().getAsMention();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
USER_NAME("{user_name}", BatUser.class) {
|
||||||
|
@Override
|
||||||
|
public String replacePlaceholder(Object object) {
|
||||||
|
return ((BatUser) object).getName();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GUILD_NAME("{guild_name}", BatGuild.class) {
|
||||||
|
@Override
|
||||||
|
public String replacePlaceholder(Object object) {
|
||||||
|
return ((BatGuild) object).getName();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
JOIN_DATE("{join_date}", null) {
|
||||||
|
@Override
|
||||||
|
public String replacePlaceholder(Object object) {
|
||||||
|
return "<t:%s>".formatted(new Date().toInstant().getEpochSecond());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The placeholder string that will get replaced
|
||||||
|
*/
|
||||||
|
private final String placeholder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that the placeholder is associated with
|
||||||
|
*/
|
||||||
|
private final Class<?> clazz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the placeholder with the string based on the overridden method
|
||||||
|
*
|
||||||
|
* @param object The object to replace the placeholder with
|
||||||
|
* @return The string with the placeholder replaced
|
||||||
|
*/
|
||||||
|
public String replacePlaceholder(Object object) {
|
||||||
|
if (clazz != null && !clazz.isInstance(object)) {
|
||||||
|
throw new IllegalArgumentException("Object is not an instance of " + clazz.getName());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces all placeholders in a message with the objects provided
|
||||||
|
*
|
||||||
|
* @param message The message to replace the placeholders in
|
||||||
|
* @param objects The objects to replace the placeholders with
|
||||||
|
* @return The message with the placeholders replaced
|
||||||
|
*/
|
||||||
|
public static String replaceAllPlaceholders(String message, Object... objects) {
|
||||||
|
for (WelcomerPlaceholders placeholder : values()) {
|
||||||
|
for (Object object : objects) {
|
||||||
|
if (placeholder.getClazz() != null && !placeholder.getClazz().isInstance(object)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
message = message.replace(placeholder.getPlaceholder(), placeholder.replacePlaceholder(object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.Serializable;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Getter @Setter
|
||||||
|
public class WelcomerProfile extends Serializable {
|
||||||
|
/**
|
||||||
|
* The welcomer message, null if we're using an embed
|
||||||
|
*/
|
||||||
|
private WelcomerMessage welcomerMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The welcomer embed, null if we're using a message
|
||||||
|
*/
|
||||||
|
private WelcomerEmbed welcomerEmbed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel to send the welcomer messages to
|
||||||
|
*/
|
||||||
|
private TextChannel channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the welcomer message
|
||||||
|
*
|
||||||
|
* @return The welcomer message, false if we're using an embed
|
||||||
|
*/
|
||||||
|
public boolean isEmbed() {
|
||||||
|
return welcomerEmbed != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the welcomer message
|
||||||
|
*
|
||||||
|
* @return The welcomer message, false if we're using an embed
|
||||||
|
*/
|
||||||
|
public boolean isMessage() {
|
||||||
|
return welcomerMessage != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the welcomer message
|
||||||
|
* <p>
|
||||||
|
* This will disable the embed if it's enabled
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void setMessage(String message) {
|
||||||
|
welcomerMessage = new WelcomerMessage(message);
|
||||||
|
welcomerEmbed = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the welcomer embed
|
||||||
|
* <p>
|
||||||
|
* This will disable the message if it's enabled
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
|
public void setEmbed(String title, String description, String color, boolean pingBeforeSend) {
|
||||||
|
welcomerEmbed = new WelcomerEmbed(title, description, color, pingBeforeSend);
|
||||||
|
welcomerMessage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the welcome message to the user
|
||||||
|
*
|
||||||
|
* @param guild The guild to send the message in
|
||||||
|
* @param user The user to send the message to
|
||||||
|
*/
|
||||||
|
public void sendWelcomeMessage(BatGuild guild, BatUser user) {
|
||||||
|
if (this.channel == null || (!this.isMessage() && !this.isEmbed())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (welcomerEmbed != null) {
|
||||||
|
if (welcomerEmbed.isPingBeforeSend()) { // Ping the user before sending the message
|
||||||
|
this.channel.sendMessage(user.getDiscordUser().getAsMention()).queue();
|
||||||
|
}
|
||||||
|
this.channel.sendMessageEmbeds(welcomerEmbed.buildEmbed(guild, user).build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (welcomerMessage != null) {
|
||||||
|
this.channel.sendMessage(welcomerMessage.buildMessage(guild, user)).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Document document, Gson gson) {
|
||||||
|
Document welcomerMessageDocument = document.get("welcomerMessage", Document.class);
|
||||||
|
if (welcomerMessageDocument != null) {
|
||||||
|
welcomerMessage = new WelcomerMessage(
|
||||||
|
welcomerMessageDocument.getString("message")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Document welcomerEmbedDocument = document.get("welcomerEmbed", Document.class);
|
||||||
|
if (welcomerEmbedDocument != null) {
|
||||||
|
welcomerEmbed = new WelcomerEmbed(
|
||||||
|
welcomerEmbedDocument.getString("title"),
|
||||||
|
welcomerEmbedDocument.getString("description"),
|
||||||
|
welcomerEmbedDocument.getString("color"),
|
||||||
|
welcomerEmbedDocument.getBoolean("pingBeforeSend")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
String channelId = document.getString("channelId");
|
||||||
|
if (channelId != null) {
|
||||||
|
TextChannel textChannel = DiscordService.JDA.getTextChannelById(channelId);
|
||||||
|
if (textChannel != null) {
|
||||||
|
channel = textChannel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Document serialize(Gson gson) {
|
||||||
|
Document document = new Document();
|
||||||
|
if (welcomerMessage != null) {
|
||||||
|
document.put("welcomerMessage", new Document("message", welcomerMessage.getMessage()));
|
||||||
|
}
|
||||||
|
if (welcomerEmbed != null) {
|
||||||
|
document.put("welcomerEmbed", new Document()
|
||||||
|
.append("title", welcomerEmbed.getTitle())
|
||||||
|
.append("description", welcomerEmbed.getDescription())
|
||||||
|
.append("color", welcomerEmbed.getColor())
|
||||||
|
.append("pingBeforeSend", welcomerEmbed.isPingBeforeSend())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (channel != null) {
|
||||||
|
document.put("channelId", channel.getId());
|
||||||
|
}
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
welcomerMessage = null;
|
||||||
|
welcomerEmbed = null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("welcomer:channel.sub")
|
||||||
|
@CommandInfo(name = "channel", description = "Set the welcomer channel")
|
||||||
|
public class ChannelSubCommand extends BatSubCommand {
|
||||||
|
public ChannelSubCommand() {
|
||||||
|
super.addOption(OptionType.CHANNEL, "channel", "The channel to send the welcomer messages to", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
WelcomerProfile profile = guild.getWelcomerProfile();
|
||||||
|
OptionMapping channelOption = event.getOption("channel");
|
||||||
|
if (channelOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TextChannel textChannel = channelOption.getAsChannel().asTextChannel();
|
||||||
|
profile.setChannel(textChannel);
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("The welcomer channel has been set to %s".formatted(textChannel.getAsMention()))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerPlaceholders;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("welcomer:current.sub")
|
||||||
|
@CommandInfo(name = "current", description = "View the current welcomer configuration")
|
||||||
|
public class CurrentSubCommand extends BatSubCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
WelcomerProfile profile = guild.getWelcomerProfile();
|
||||||
|
if (!profile.isEmbed() && !profile.isMessage()) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The welcomer is not configured.\n\n" + getPlaceholders(guild, user))
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile.isEmbed()) {
|
||||||
|
event.replyEmbeds(profile.getWelcomerEmbed().buildEmbed(guild, user)
|
||||||
|
.appendDescription("\n\n" + getPlaceholders(guild, user))
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (profile.isMessage()) {
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription("**Preview:** %s\n*note: the real message won't be an embed*\n\n%s".formatted(
|
||||||
|
profile.getWelcomerMessage().buildMessage(guild, user),
|
||||||
|
getPlaceholders(guild, user)
|
||||||
|
))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the placeholders that the user can use
|
||||||
|
*
|
||||||
|
* @param replacements What to replace the placeholders using
|
||||||
|
* @return The placeholders
|
||||||
|
*/
|
||||||
|
public String getPlaceholders(Object... replacements) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("**Available Placeholders:**\n");
|
||||||
|
for (WelcomerPlaceholders placeholder : WelcomerPlaceholders.values()) {
|
||||||
|
String placeholderString = placeholder.getPlaceholder();
|
||||||
|
builder.append("`").append(placeholderString).append("` - ")
|
||||||
|
.append(WelcomerPlaceholders.replaceAllPlaceholders(placeholderString, replacements)).append("\n");
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.Emojis;
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("welcomer:embed.sub")
|
||||||
|
@CommandInfo(name = "embed", description = "Set the welcomer embed (this will remove the welcomer plain message if set)")
|
||||||
|
public class EmbedSubCommand extends BatSubCommand {
|
||||||
|
public EmbedSubCommand() {
|
||||||
|
super.addOption(OptionType.BOOLEAN, "ping-before-send", "Should we ping the user before sending the message?", true);
|
||||||
|
super.addOption(OptionType.STRING, "description", "The description of the embed", true);
|
||||||
|
super.addOption(OptionType.STRING, "color", "The color of the embed", true);
|
||||||
|
super.addOption(OptionType.STRING, "title", "The title of the embed (only set if you want a title)", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
WelcomerProfile profile = guild.getWelcomerProfile();
|
||||||
|
OptionMapping titleOption = event.getOption("title");
|
||||||
|
OptionMapping descriptionOption = event.getOption("description");
|
||||||
|
OptionMapping colorOption = event.getOption("color");
|
||||||
|
OptionMapping pingBeforeSendOption = event.getOption("ping-before-send");
|
||||||
|
if (descriptionOption == null || colorOption == null || pingBeforeSendOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String title = titleOption == null ? null : titleOption.getAsString();
|
||||||
|
String description = descriptionOption.getAsString();
|
||||||
|
String color = colorOption.getAsString();
|
||||||
|
boolean pingBeforeSend = pingBeforeSendOption.getAsBoolean();
|
||||||
|
|
||||||
|
// Remove # if the user added it
|
||||||
|
color = color.replace("#", "");
|
||||||
|
|
||||||
|
// Validate the input
|
||||||
|
if (color.length() != 6 || Color.decode("#" + color).getRGB() == -1){
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The color must be a valid hex color code\n" +
|
||||||
|
"You can use this website to get a hex color code: https://htmlcolorcodes.com")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (title != null && title.length() > 128) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The title must be less than 128 characters")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (description.length() > 512) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The description must be less than 512 characters")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isMessageEnabled = profile.isMessage();
|
||||||
|
profile.setEmbed(title, description, color, pingBeforeSend);
|
||||||
|
EmbedDescriptionBuilder successDescription = new EmbedDescriptionBuilder("Welcomer Embed")
|
||||||
|
.appendLine("%s Successfully set the welcomer embed!".formatted(Emojis.CHECK_MARK_EMOJI), false);
|
||||||
|
if (isMessageEnabled) {
|
||||||
|
successDescription.appendLine("*This has removed the plain message welcomer*", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
successDescription.emptyLine();
|
||||||
|
successDescription.appendLine("**Configuration:**", false);
|
||||||
|
if (title != null) {
|
||||||
|
successDescription.appendLine("Title: `%s`".formatted(title), true);
|
||||||
|
}
|
||||||
|
successDescription.appendLine("Description: `%s`".formatted(description), true);
|
||||||
|
successDescription.appendLine("Color: `#%s`".formatted(color), true);
|
||||||
|
successDescription.appendLine("Ping Before Send: %s".formatted(pingBeforeSend ? Emojis.CHECK_MARK_EMOJI.getFormatted() + " *(Preview won't ping you)*" : Emojis.CROSS_MARK_EMOJI), true);
|
||||||
|
successDescription.emptyLine();
|
||||||
|
successDescription.appendLine("**Preview Below:**", false);
|
||||||
|
event.replyEmbeds(
|
||||||
|
EmbedUtils.successEmbed()
|
||||||
|
.setDescription(successDescription.build())
|
||||||
|
.build(),
|
||||||
|
profile.getWelcomerEmbed().buildEmbed(guild, user).build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.Emojis;
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedDescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerPlaceholders;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("welcomer:message.sub")
|
||||||
|
@CommandInfo(name = "message", description = "Set the welcomer message (this will remove the welcomer embed if set)")
|
||||||
|
public class MessageSubCommand extends BatSubCommand {
|
||||||
|
public MessageSubCommand() {
|
||||||
|
super.addOption(OptionType.STRING, "message", "The message to send", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
WelcomerProfile profile = guild.getWelcomerProfile();
|
||||||
|
OptionMapping messageOption = event.getOption("message");
|
||||||
|
if (messageOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String message = messageOption.getAsString();
|
||||||
|
boolean isEmbedEnabled = profile.isEmbed();
|
||||||
|
profile.setMessage(message);
|
||||||
|
|
||||||
|
EmbedDescriptionBuilder description = new EmbedDescriptionBuilder("Welcomer Message")
|
||||||
|
.appendLine("%s Set the message to `%s`".formatted(Emojis.CHECK_MARK_EMOJI, message), false);
|
||||||
|
if (isEmbedEnabled) {
|
||||||
|
description.appendLine("*This has removed the embed welcomer*", false);
|
||||||
|
}
|
||||||
|
description.emptyLine();
|
||||||
|
description.appendLine("**Preview:** %s".formatted(WelcomerPlaceholders.replaceAllPlaceholders(message, guild, user)), false);
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription(description.build())
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
|
||||||
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("welcomer:reset.sub")
|
||||||
|
@CommandInfo(name = "reset", description = "Clear the welcomer configuration")
|
||||||
|
public class ResetSubCommand extends BatSubCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
||||||
|
WelcomerProfile profile = guild.getWelcomerProfile();
|
||||||
|
if (!profile.isEmbed() && !profile.isMessage()) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The welcomer is not configured")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.reset();
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("The welcomer configuration has been reset")
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package cc.fascinated.bat.features.welcomer.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "welcomer", description = "Configure the welcomer on your server", requiredPermissions = Permission.MANAGE_SERVER)
|
||||||
|
public class WelcomerCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public WelcomerCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommand(context.getBean(MessageSubCommand.class));
|
||||||
|
super.addSubCommand(context.getBean(EmbedSubCommand.class));
|
||||||
|
super.addSubCommand(context.getBean(CurrentSubCommand.class));
|
||||||
|
super.addSubCommand(context.getBean(ChannelSubCommand.class));
|
||||||
|
super.addSubCommand(context.getBean(ResetSubCommand.class));
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,8 @@ import cc.fascinated.bat.features.base.profile.FeatureProfile;
|
|||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
||||||
import cc.fascinated.bat.features.logging.LogProfile;
|
import cc.fascinated.bat.features.logging.LogProfile;
|
||||||
import cc.fascinated.bat.features.namehistory.profile.guild.NameHistoryProfile;
|
import cc.fascinated.bat.features.namehistory.profile.guild.NameHistoryProfile;
|
||||||
|
import cc.fascinated.bat.features.reminder.ReminderProfile;
|
||||||
|
import cc.fascinated.bat.features.welcomer.WelcomerProfile;
|
||||||
import cc.fascinated.bat.premium.PremiumProfile;
|
import cc.fascinated.bat.premium.PremiumProfile;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
import cc.fascinated.bat.service.MongoService;
|
import cc.fascinated.bat.service.MongoService;
|
||||||
@ -18,7 +20,6 @@ import net.dv8tion.jda.api.entities.Guild;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -29,7 +30,6 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Document(collection = "guilds")
|
|
||||||
public class BatGuild extends ProfileHolder {
|
public class BatGuild extends ProfileHolder {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BatGuild.class);
|
private static final Logger log = LoggerFactory.getLogger(BatGuild.class);
|
||||||
/**
|
/**
|
||||||
@ -49,11 +49,21 @@ public class BatGuild extends ProfileHolder {
|
|||||||
*/
|
*/
|
||||||
private Date createdAt;
|
private Date createdAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The guild as the JDA Guild
|
||||||
|
*/
|
||||||
|
private Guild guild;
|
||||||
|
|
||||||
public BatGuild(@NonNull String id, @NonNull org.bson.Document document) {
|
public BatGuild(@NonNull String id, @NonNull org.bson.Document document) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.document = document;
|
this.document = document;
|
||||||
boolean newAccount = this.document.isEmpty();
|
boolean newAccount = this.document.isEmpty();
|
||||||
this.createdAt = newAccount ? new Date() : document.getDate("createdAt");
|
this.createdAt = newAccount ? new Date() : document.getDate("createdAt");
|
||||||
|
|
||||||
|
Guild guild = DiscordService.JDA.getGuildById(id);
|
||||||
|
if (guild != null) {
|
||||||
|
this.guild = guild;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,7 +81,10 @@ public class BatGuild extends ProfileHolder {
|
|||||||
* @return the guild
|
* @return the guild
|
||||||
*/
|
*/
|
||||||
public Guild getDiscordGuild() {
|
public Guild getDiscordGuild() {
|
||||||
return DiscordService.JDA.getGuildById(id);
|
if (guild == null) {
|
||||||
|
guild = DiscordService.JDA.getGuildById(id);
|
||||||
|
}
|
||||||
|
return guild;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,6 +132,24 @@ public class BatGuild extends ProfileHolder {
|
|||||||
return getProfile(LogProfile.class);
|
return getProfile(LogProfile.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the reminder profile
|
||||||
|
*
|
||||||
|
* @return the reminder profile
|
||||||
|
*/
|
||||||
|
public ReminderProfile getReminderProfile() {
|
||||||
|
return getProfile(ReminderProfile.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the welcomer profile
|
||||||
|
*
|
||||||
|
* @return the welcomer profile
|
||||||
|
*/
|
||||||
|
public WelcomerProfile getWelcomerProfile() {
|
||||||
|
return getProfile(WelcomerProfile.class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the user
|
* Saves the user
|
||||||
*/
|
*/
|
||||||
|
@ -13,10 +13,7 @@ import lombok.NonNull;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -28,9 +25,7 @@ import java.util.Map;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Document(collection = "users")
|
|
||||||
public class BatUser extends ProfileHolder {
|
public class BatUser extends ProfileHolder {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BatUser.class);
|
|
||||||
/**
|
/**
|
||||||
* The document that belongs to this user
|
* The document that belongs to this user
|
||||||
*/
|
*/
|
||||||
@ -53,6 +48,11 @@ public class BatUser extends ProfileHolder {
|
|||||||
*/
|
*/
|
||||||
private Date createdAt;
|
private Date createdAt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The discord user associated with this user
|
||||||
|
*/
|
||||||
|
private User user;
|
||||||
|
|
||||||
public BatUser(@NonNull String id, @NonNull org.bson.Document document) {
|
public BatUser(@NonNull String id, @NonNull org.bson.Document document) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.document = document;
|
this.document = document;
|
||||||
@ -61,6 +61,7 @@ public class BatUser extends ProfileHolder {
|
|||||||
|
|
||||||
User user = DiscordService.JDA.getUserById(id);
|
User user = DiscordService.JDA.getUserById(id);
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
|
this.user = user;
|
||||||
this.globalName = user.getGlobalName();
|
this.globalName = user.getGlobalName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +79,10 @@ public class BatUser extends ProfileHolder {
|
|||||||
* @return the guild
|
* @return the guild
|
||||||
*/
|
*/
|
||||||
public User getDiscordUser() {
|
public User getDiscordUser() {
|
||||||
return DiscordService.JDA.getUserById(id);
|
if (user == null) {
|
||||||
|
user = DiscordService.JDA.getUserById(id);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,6 +138,7 @@ public class CommandService extends ListenerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
|
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
|
||||||
|
long before = System.currentTimeMillis();
|
||||||
Guild discordGuild = event.getGuild();
|
Guild discordGuild = event.getGuild();
|
||||||
if (event.getUser().isBot()) {
|
if (event.getUser().isBot()) {
|
||||||
return;
|
return;
|
||||||
@ -230,9 +231,10 @@ public class CommandService extends ListenerAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Executing command \"{}\" for user \"{}\"", commandName, user.getDiscordUser().getName());
|
|
||||||
executor.execute(guild, user, ranInsideGuild ? event.getChannel().asTextChannel() : event.getChannel().asPrivateChannel(),
|
executor.execute(guild, user, ranInsideGuild ? event.getChannel().asTextChannel() : event.getChannel().asPrivateChannel(),
|
||||||
event.getMember(), event.getInteraction());
|
event.getMember(), event.getInteraction());
|
||||||
|
log.info("Executed command \"{}\" for user \"{}\" (took: {}ms)", commandName, user.getDiscordUser().getName(),
|
||||||
|
System.currentTimeMillis() - before);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("An error occurred while executing command \"{}\"", commandName, ex);
|
log.error("An error occurred while executing command \"{}\"", commandName, ex);
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
@ -16,6 +16,7 @@ import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleAddEvent;
|
|||||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent;
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent;
|
||||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
|
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
|
||||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent;
|
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent;
|
||||||
|
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
|
||||||
@ -290,4 +291,17 @@ public class EventService extends ListenerAdapter {
|
|||||||
listener.onUserUpdateAvatar(user, event.getOldAvatarUrl(), event.getNewAvatarUrl(), event);
|
listener.onUserUpdateAvatar(user, event.getOldAvatarUrl(), event.getNewAvatarUrl(), event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGuildVoiceUpdate(@NotNull GuildVoiceUpdateEvent event) {
|
||||||
|
if (event.getEntity().getUser().isBot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BatGuild guild = guildService.getGuild(event.getEntity().getGuild().getId());
|
||||||
|
BatUser user = userService.getUser(event.getEntity().getUser().getId());
|
||||||
|
|
||||||
|
for (EventListener listener : LISTENERS) {
|
||||||
|
listener.onGuildVoiceUpdate(guild, user, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class MongoService {
|
public class MongoService {
|
||||||
public static MongoService INSTANCE;
|
public static MongoService INSTANCE;
|
||||||
private final MongoTemplate mongo;
|
private final MongoTemplate mongoTemplate;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public MongoService(MongoTemplate mongo) {
|
public MongoService(MongoTemplate mongo) {
|
||||||
INSTANCE = this;
|
INSTANCE = this;
|
||||||
this.mongo = mongo;
|
this.mongoTemplate = mongo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +26,7 @@ public class MongoService {
|
|||||||
* @return The guilds collection
|
* @return The guilds collection
|
||||||
*/
|
*/
|
||||||
public MongoCollection<Document> getGuildsCollection() {
|
public MongoCollection<Document> getGuildsCollection() {
|
||||||
return mongo.getCollection("guilds");
|
return mongoTemplate.getCollection("guilds");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,6 +35,6 @@ public class MongoService {
|
|||||||
* @return The users collection
|
* @return The users collection
|
||||||
*/
|
*/
|
||||||
public MongoCollection<Document> getUsersCollection() {
|
public MongoCollection<Document> getUsersCollection() {
|
||||||
return mongo.getCollection("users");
|
return mongoTemplate.getCollection("users");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import com.mongodb.client.model.Filters;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||||
import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent;
|
import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
@ -57,23 +58,28 @@ public class UserService implements EventListener {
|
|||||||
if (users.containsKey(id)) {
|
if (users.containsKey(id)) {
|
||||||
return users.get(id);
|
return users.get(id);
|
||||||
}
|
}
|
||||||
if (DiscordService.JDA.getUserById(id) == null) {
|
User user = DiscordService.JDA.getUserById(id);
|
||||||
log.warn("Attempted to get user with ID \"{}\" but it does not exist", id);
|
if (user == null) {
|
||||||
|
log.warn("Attempted to get user with ID \"{}\" but they do not exist", id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (user.isBot()) {
|
||||||
|
log.warn("Attempted to get user with ID \"{}\" but they are a bot", id);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// User is not cached
|
// User is not cached
|
||||||
Document document = MongoService.INSTANCE.getUsersCollection().find(Filters.eq("_id", id)).first();
|
Document document = MongoService.INSTANCE.getUsersCollection().find(Filters.eq("_id", id)).first();
|
||||||
if (document != null) {
|
if (document != null) {
|
||||||
BatUser user = new BatUser(id, document);
|
BatUser batUser = new BatUser(id, document);
|
||||||
users.put(id, user);
|
users.put(id, batUser);
|
||||||
log.info("Loaded user \"{}\" in {}ms", user.getName(),System.currentTimeMillis() - before);
|
log.info("Loaded user \"{}\" in {}ms", batUser.getName(),System.currentTimeMillis() - before);
|
||||||
return user;
|
return batUser;
|
||||||
}
|
}
|
||||||
// New user
|
// New user
|
||||||
BatUser user = new BatUser(id, new Document());
|
BatUser batUser = new BatUser(id, new Document());
|
||||||
users.put(id, user);
|
users.put(id, batUser);
|
||||||
log.info("Created user \"{}\" - \"{}\"", user.getName(), user.getId());
|
log.info("Created user \"{}\" - \"{}\"", user.getName(), user.getId());
|
||||||
return user;
|
return batUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -92,7 +98,6 @@ public class UserService implements EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUserUpdateGlobalName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateGlobalNameEvent event) {
|
public void onUserUpdateGlobalName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateGlobalNameEvent event) {
|
||||||
log.info("User \"{}\" changed their name from \"{}\" to \"{}\"", user.getName(), oldName, newName);
|
|
||||||
user.setGlobalName(newName);
|
user.setGlobalName(newName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ tmdb:
|
|||||||
# API Read Access Token
|
# API Read Access Token
|
||||||
api-key: "api-read-access-token"
|
api-key: "api-read-access-token"
|
||||||
|
|
||||||
|
|
||||||
# Spring Configuration
|
# Spring Configuration
|
||||||
spring:
|
spring:
|
||||||
data:
|
data:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user