forked from Fascinated/Bat
Compare commits
No commits in common. "87bf0b9f67f5c99c35af5581ca5ff6da36330b2c" and "eb8408eb8f21f1f414d7e071102431eb7af56cfa" have entirely different histories.
87bf0b9f67
...
eb8408eb8f
23
pom.xml
23
pom.xml
@ -85,29 +85,6 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>io.sentry</groupId>
|
|
||||||
<artifactId>sentry-spring-boot-starter-jakarta</artifactId>
|
|
||||||
<version>7.10.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.mongock</groupId>
|
|
||||||
<artifactId>mongock-bom</artifactId>
|
|
||||||
<version>5.2.4</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.mongock</groupId>
|
|
||||||
<artifactId>mongock-springboot-v3</artifactId>
|
|
||||||
<version>5.2.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.mongock</groupId>
|
|
||||||
<artifactId>mongodb-springdata-v4-driver</artifactId>
|
|
||||||
<version>5.2.4</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Libraries -->
|
<!-- Libraries -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
||||||
"extends": [
|
|
||||||
"local>Fascinated/renovate-config"
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,12 +1,7 @@
|
|||||||
package cc.fascinated.bat;
|
package cc.fascinated.bat;
|
||||||
|
|
||||||
import cc.fascinated.bat.config.Config;
|
|
||||||
import cc.fascinated.bat.event.EventListener;
|
|
||||||
import cc.fascinated.bat.service.EventService;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import io.mongock.runner.springboot.EnableMongock;
|
|
||||||
import jakarta.annotation.PreDestroy;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
@ -20,8 +15,7 @@ import java.nio.file.StandardCopyOption;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
@SpringBootApplication(scanBasePackages = "cc.fascinated.bat")
|
@SpringBootApplication
|
||||||
@EnableMongock
|
|
||||||
@Log4j2(topic = "Bat")
|
@Log4j2(topic = "Bat")
|
||||||
public class BatApplication {
|
public class BatApplication {
|
||||||
public static Gson GSON = new GsonBuilder().create();
|
public static Gson GSON = new GsonBuilder().create();
|
||||||
@ -41,15 +35,5 @@ public class BatApplication {
|
|||||||
|
|
||||||
// Start the app
|
// Start the app
|
||||||
SpringApplication.run(BatApplication.class, args);
|
SpringApplication.run(BatApplication.class, args);
|
||||||
|
|
||||||
log.info("APP IS RUNNING IN %s MODE!!!!!!!!!".formatted(Config.isProduction() ? "PRODUCTION" : "DEVELOPMENT"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PreDestroy
|
|
||||||
public void onShutdown() {
|
|
||||||
log.info("Shutting down...");
|
|
||||||
for (EventListener listener : EventService.LISTENERS) {
|
|
||||||
listener.onSpringShutdown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,10 +8,4 @@ public class Consts {
|
|||||||
public static final String SUPPORT_INVITE_URL = "https://discord.gg/invite/yjj2U3ctEG";
|
public static final String SUPPORT_INVITE_URL = "https://discord.gg/invite/yjj2U3ctEG";
|
||||||
public static String BOT_OWNER = "474221560031608833";
|
public static String BOT_OWNER = "474221560031608833";
|
||||||
public static String ADMIN_GUILD = "1203163422498361404";
|
public static String ADMIN_GUILD = "1203163422498361404";
|
||||||
|
|
||||||
static {
|
|
||||||
if (System.getenv("ADMIN_GUILD") != null) {
|
|
||||||
ADMIN_GUILD = System.getenv("ADMIN_GUILD");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
package cc.fascinated.bat;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
|
||||||
import net.dv8tion.jda.api.JDA;
|
|
||||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Log4j2
|
|
||||||
public class Emojis {
|
|
||||||
public static final Emoji SPOTIFY_EMOJI;
|
|
||||||
public static final Emoji CHECK_MARK_EMOJI;
|
|
||||||
public static final Emoji CROSS_MARK_EMOJI;
|
|
||||||
public static final Emoji SAD_FACE_EMOJI;
|
|
||||||
public static final Emoji PAUSE_EMOJI;
|
|
||||||
public static final Emoji PLAY_EMOJI;
|
|
||||||
public static final Emoji SKIP_EMOJI;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Presence Status Emojis
|
|
||||||
*/
|
|
||||||
public static final Emoji ONLINE_EMOJI;
|
|
||||||
public static final Emoji IDLE_EMOJI;
|
|
||||||
public static final Emoji DND_EMOJI;
|
|
||||||
public static final Emoji OFFLINE_EMOJI;
|
|
||||||
|
|
||||||
static {
|
|
||||||
log.info("Loading emojis...");
|
|
||||||
JDA jda = DiscordService.JDA;
|
|
||||||
SPOTIFY_EMOJI = jda.getEmojiById("1256629771975266479");
|
|
||||||
CHECK_MARK_EMOJI = jda.getEmojiById("1256633734065557676");
|
|
||||||
CROSS_MARK_EMOJI = jda.getEmojiById("1256634487429922897");
|
|
||||||
SAD_FACE_EMOJI = jda.getEmojiById("1256636078258131055");
|
|
||||||
ONLINE_EMOJI = jda.getEmojiById("1256662465668710430");
|
|
||||||
IDLE_EMOJI = jda.getEmojiById("1256662632203685991");
|
|
||||||
DND_EMOJI = jda.getEmojiById("1256662572933845032");
|
|
||||||
OFFLINE_EMOJI = jda.getEmojiById("1256662679402053662");
|
|
||||||
PAUSE_EMOJI = Emoji.fromUnicode("⏸");
|
|
||||||
PLAY_EMOJI = Emoji.fromUnicode("▶");
|
|
||||||
SKIP_EMOJI = Emoji.fromUnicode("⏭");
|
|
||||||
log.info("Loaded emojis!");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
package cc.fascinated.bat.command;
|
package cc.fascinated.bat.command;
|
||||||
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -39,11 +38,6 @@ public abstract class BatCommand implements BatCommandExecutor {
|
|||||||
*/
|
*/
|
||||||
private Category category;
|
private Category category;
|
||||||
|
|
||||||
/**
|
|
||||||
* The feature that the command belongs to
|
|
||||||
*/
|
|
||||||
private Feature feature;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the command can only be used by the bot owner
|
* Whether the command can only be used by the bot owner
|
||||||
*/
|
*/
|
||||||
|
@ -12,20 +12,20 @@ import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|||||||
*/
|
*/
|
||||||
public interface BatCommandExecutor {
|
public interface BatCommandExecutor {
|
||||||
/**
|
/**
|
||||||
* Executes the command using a slash command event.
|
* Executes the command using a slash command interaction.
|
||||||
*
|
*
|
||||||
* @param guild the bat guild the command was executed in (null if the command was executed in a DM)
|
* @param guild the bat guild the command was executed in (null if the command was executed in a DM)
|
||||||
* @param user the bat user that executed the command
|
* @param user the bat user that executed the command
|
||||||
* @param channel the channel the command was executed in
|
* @param channel the channel the command was executed in
|
||||||
* @param member the member that executed the command
|
* @param member the member that executed the command
|
||||||
* @param event the slash command event
|
* @param interaction the slash command interaction
|
||||||
*/
|
*/
|
||||||
default void execute(
|
default void execute(
|
||||||
BatGuild guild,
|
BatGuild guild,
|
||||||
@NonNull BatUser user,
|
@NonNull BatUser user,
|
||||||
@NonNull MessageChannel channel,
|
@NonNull MessageChannel channel,
|
||||||
Member member,
|
Member member,
|
||||||
@NonNull SlashCommandInteraction event
|
@NonNull SlashCommandInteraction interaction
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general;
|
package cc.fascinated.bat.command.impl;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.NumberFormatter;
|
|
||||||
import cc.fascinated.bat.common.TimeUtils;
|
import cc.fascinated.bat.common.TimeUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
@ -38,19 +37,19 @@ public class BotStatsCommand 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 interaction) {
|
||||||
JDA jda = DiscordService.JDA;
|
JDA jda = DiscordService.JDA;
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed().setDescription(
|
interaction.replyEmbeds(EmbedUtils.genericEmbed().setDescription(
|
||||||
"**Bot Statistics**\n" +
|
"**Bot Statistics**\n" +
|
||||||
"➜ Guilds: **%s**\n".formatted(NumberFormatter.format(jda.getGuilds().size())) +
|
"➜ Guilds: **%s**\n".formatted(jda.getGuilds().size()) +
|
||||||
"➜ Users: **%s**\n".formatted(NumberFormatter.format(jda.getUsers().size())) +
|
"➜ Users: **%s**\n".formatted(jda.getUsers().size()) +
|
||||||
"➜ Gateway Ping: **%sms**\n".formatted(jda.getGatewayPing()) +
|
"➜ Gateway Ping: **%sms**\n".formatted(jda.getGatewayPing()) +
|
||||||
"\n" +
|
"\n" +
|
||||||
"**Bat Statistics**\n" +
|
"**Bat Statistics**\n" +
|
||||||
"➜ Uptime: **%s**\n".formatted(TimeUtils.format(bean.getUptime())) +
|
"➜ Uptime: **%s**\n".formatted(TimeUtils.format(bean.getUptime())) +
|
||||||
"➜ Cached Guilds: **%s**\n".formatted(NumberFormatter.format(guildService.getGuilds().size())) +
|
"➜ Cached Guilds: **%s**\n".formatted(guildService.getGuilds().size()) +
|
||||||
"➜ Cached Users: **%s**".formatted(NumberFormatter.format(userService.getUsers().size()))
|
"➜ Cached Users: **%s**".formatted(userService.getUsers().size())
|
||||||
).build()).queue();
|
).build()).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general;
|
package cc.fascinated.bat.command.impl;
|
||||||
|
|
||||||
import cc.fascinated.bat.Consts;
|
import cc.fascinated.bat.Consts;
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
@ -45,8 +45,8 @@ public class HelpCommand extends BatCommand 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 interaction) {
|
||||||
event.replyEmbeds(createHomeEmbed()).addComponents(createHomeActions()).queue();
|
interaction.replyEmbeds(createHomeEmbed()).addComponents(createHomeActions()).queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general;
|
package cc.fascinated.bat.command.impl;
|
||||||
|
|
||||||
import cc.fascinated.bat.Consts;
|
import cc.fascinated.bat.Consts;
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
@ -19,8 +19,8 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "invite", description = "Invite the bot to your server!", guildOnly = false)
|
@CommandInfo(name = "invite", description = "Invite the bot to your server!", guildOnly = false)
|
||||||
public class InviteCommand extends BatCommand {
|
public class InviteCommand 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 interaction) {
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("You can invite the bot to your server by clicking [here](%s)".formatted(Consts.INVITE_URL))
|
.setDescription("You can invite the bot to your server by clicking [here](%s)".formatted(Consts.INVITE_URL))
|
||||||
.build())
|
.build())
|
||||||
.setEphemeral(true)
|
.setEphemeral(true)
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general;
|
package cc.fascinated.bat.command.impl;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -18,9 +18,9 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "ping", description = "Gets the ping of the bot", guildOnly = false)
|
@CommandInfo(name = "ping", description = "Gets the ping of the bot", guildOnly = false)
|
||||||
public class PingCommand extends BatCommand {
|
public class PingCommand 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 interaction) {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
event.reply("Pinging...").queue(response -> {
|
interaction.reply("Pinging...").queue(response -> {
|
||||||
response.editOriginal("Gateway response time: `%sms`\nAPI response time `%sms`".formatted(
|
response.editOriginal("Gateway response time: `%sms`\nAPI response time `%sms`".formatted(
|
||||||
DiscordService.JDA.getGatewayPing(),
|
DiscordService.JDA.getGatewayPing(),
|
||||||
System.currentTimeMillis() - time
|
System.currentTimeMillis() - time
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general.avatar;
|
package cc.fascinated.bat.command.impl.avatar;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general.avatar;
|
package cc.fascinated.bat.command.impl.avatar;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -19,18 +19,18 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "guild", description = "View the avatar of the guild")
|
@CommandInfo(name = "guild", description = "View the avatar of the guild")
|
||||||
public class GuildSubCommand extends BatSubCommand {
|
public class GuildSubCommand extends BatSubCommand {
|
||||||
@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 interaction) {
|
||||||
ImageProxy icon = guild.getDiscordGuild().getIcon();
|
ImageProxy icon = guild.getDiscordGuild().getIcon();
|
||||||
|
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("**%s** does not have an avatar!".formatted(guild.getName()))
|
.setDescription("**%s** does not have an avatar!".formatted(guild.getName()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Avatar".formatted(guild.getName()), null, guild.getDiscordGuild().getIconUrl())
|
.setAuthor("%s's Avatar".formatted(guild.getName()), null, guild.getDiscordGuild().getIconUrl())
|
||||||
.setImage(icon.getUrl(4096))
|
.setImage(icon.getUrl(4096))
|
||||||
.build()
|
.build()
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general.avatar;
|
package cc.fascinated.bat.command.impl.avatar;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -25,10 +25,10 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
OptionMapping userOption = event.getOption("user");
|
OptionMapping userOption = interaction.getOption("user");
|
||||||
if (userOption == null) {
|
if (userOption == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("You must provide a user to view the avatar of!")
|
.setDescription("You must provide a user to view the avatar of!")
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -36,7 +36,7 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
User target = userOption.getAsUser();
|
User target = userOption.getAsUser();
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Avatar".formatted(target.getName()), null, target.getEffectiveAvatarUrl())
|
.setAuthor("%s's Avatar".formatted(target.getName()), null, target.getEffectiveAvatarUrl())
|
||||||
.setImage(target.getEffectiveAvatarUrl())
|
.setImage(target.getEffectiveAvatarUrl())
|
||||||
.build()
|
.build()
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general.banner;
|
package cc.fascinated.bat.command.impl.banner;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general.banner;
|
package cc.fascinated.bat.command.impl.banner;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -19,17 +19,17 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "guild", description = "View the banner of the guild")
|
@CommandInfo(name = "guild", description = "View the banner of the guild")
|
||||||
public class GuildSubCommand extends BatSubCommand {
|
public class GuildSubCommand extends BatSubCommand {
|
||||||
@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 interaction) {
|
||||||
ImageProxy banner = guild.getDiscordGuild().getBanner();
|
ImageProxy banner = guild.getDiscordGuild().getBanner();
|
||||||
if (banner == null) {
|
if (banner == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("**%s** does not have a banner!".formatted(guild.getName()))
|
.setDescription("**%s** does not have a banner!".formatted(guild.getName()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Banner".formatted(guild.getName()))
|
.setAuthor("%s's Banner".formatted(guild.getName()))
|
||||||
.setImage(banner.getUrl(512))
|
.setImage(banner.getUrl(512))
|
||||||
.build()
|
.build()
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general.banner;
|
package cc.fascinated.bat.command.impl.banner;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -26,10 +26,10 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
OptionMapping userOption = event.getOption("user");
|
OptionMapping userOption = interaction.getOption("user");
|
||||||
if (userOption == null) {
|
if (userOption == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("You must provide a user to view the banner of!")
|
.setDescription("You must provide a user to view the banner of!")
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -39,14 +39,14 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
User target = userOption.getAsUser();
|
User target = userOption.getAsUser();
|
||||||
ImageProxy banner = target.retrieveProfile().complete().getBanner();
|
ImageProxy banner = target.retrieveProfile().complete().getBanner();
|
||||||
if (banner == null) {
|
if (banner == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("**%s** does not have a banner!".formatted(target.getName()))
|
.setDescription("**%s** does not have a banner!".formatted(target.getName()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Banner".formatted(target.getName()))
|
.setAuthor("%s's Banner".formatted(target.getName()))
|
||||||
.setImage(banner.getUrl(512))
|
.setImage(banner.getUrl(512))
|
||||||
.build()
|
.build()
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.botadmin.premium;
|
package cc.fascinated.bat.command.impl.botadmin.premium;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
@ -1,10 +1,9 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.botadmin.premium;
|
package cc.fascinated.bat.command.impl.botadmin.premium;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.premium.PremiumProfile;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
@ -30,25 +29,26 @@ public class RemoveSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
OptionMapping guildOption = event.getOption("guild");
|
OptionMapping guildOption = interaction.getOption("guild");
|
||||||
if (guildOption == null) {
|
if (guildOption == null) {
|
||||||
event.reply("Please provide a guild id").queue();
|
interaction.reply("Please provide a guild id").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String guildId = guildOption.getAsString();
|
String guildId = guildOption.getAsString();
|
||||||
BatGuild targetGuild = guildService.getGuild(guildId);
|
BatGuild batGuild = guildService.getGuild(guildId);
|
||||||
if (targetGuild == null) {
|
if (batGuild == null) {
|
||||||
event.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
interaction.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PremiumProfile premium = targetGuild.getPremiumProfile();
|
BatGuild.Premium premium = batGuild.getPremium();
|
||||||
if (!premium.hasPremium()) {
|
if (!premium.hasPremium()) {
|
||||||
event.reply("The guild does not have premium").queue();
|
interaction.reply("The guild does not have premium").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
premium.removePremium();
|
premium.removePremium();
|
||||||
event.reply("The guild **%s** has had its premium removed".formatted(targetGuild.getName())).queue();
|
guildService.saveGuild(batGuild);
|
||||||
|
interaction.reply("The guild **%s** has had its premium removed".formatted(guild.getName())).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,9 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.botadmin.premium;
|
package cc.fascinated.bat.command.impl.botadmin.premium;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.premium.PremiumProfile;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
@ -24,42 +23,43 @@ public class SetSubCommand extends BatSubCommand {
|
|||||||
private final GuildService guildService;
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SetSubCommand(@NonNull GuildService guildService) {
|
public SetSubCommand(GuildService guildService) {
|
||||||
this.guildService = guildService;
|
this.guildService = guildService;
|
||||||
super.addOption(OptionType.STRING, "guild", "The guild id to set as premium", true);
|
super.addOption(OptionType.STRING, "guild", "The guild id to set as premium", true);
|
||||||
super.addOption(OptionType.BOOLEAN, "infinite", "Whether the premium length should be infinite", true);
|
super.addOption(OptionType.BOOLEAN, "infinite", "Whether the premium length should be infinite", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
OptionMapping guildOption = event.getOption("guild");
|
OptionMapping guildOption = interaction.getOption("guild");
|
||||||
if (guildOption == null) {
|
if (guildOption == null) {
|
||||||
event.reply("Please provide a guild id").queue();
|
interaction.reply("Please provide a guild id").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String guildId = guildOption.getAsString();
|
String guildId = guildOption.getAsString();
|
||||||
OptionMapping infiniteOption = event.getOption("infinite");
|
OptionMapping infiniteOption = interaction.getOption("infinite");
|
||||||
if (infiniteOption == null) {
|
if (infiniteOption == null) {
|
||||||
event.reply("Please provide whether the premium length should be infinite").queue();
|
interaction.reply("Please provide whether the premium length should be infinite").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean infinite = infiniteOption.getAsBoolean();
|
boolean infinite = infiniteOption.getAsBoolean();
|
||||||
BatGuild targetGuild = guildService.getGuild(guildId);
|
BatGuild batGuild = guildService.getGuild(guildId);
|
||||||
if (targetGuild == null) {
|
if (batGuild == null) {
|
||||||
event.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
interaction.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PremiumProfile premium = targetGuild.getPremiumProfile();
|
BatGuild.Premium premium = batGuild.getPremium();
|
||||||
if (!infinite) {
|
if (!infinite) {
|
||||||
premium.addTime();
|
premium.addTime();
|
||||||
} else {
|
} else {
|
||||||
premium.addInfiniteTime();
|
premium.addInfiniteTime();
|
||||||
}
|
}
|
||||||
|
guildService.saveGuild(batGuild);
|
||||||
if (!infinite) {
|
if (!infinite) {
|
||||||
event.reply("The guild **%s** has been set as premium until <t:%s>".formatted(targetGuild.getName(), premium.getExpiresAt().toInstant().toEpochMilli() / 1000)).queue();
|
interaction.reply("The guild **%s** has been set as premium until <t:%s>".formatted(guild.getName(), premium.getExpiresAt().toInstant().toEpochMilli() / 1000)).queue();
|
||||||
} else {
|
} else {
|
||||||
event.reply("The guild **%s** has been set as premium indefinitely".formatted(targetGuild.getName())).queue();
|
interaction.reply("The guild **%s** has been set as premium indefinitely".formatted(guild.getName())).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.fun.image;
|
package cc.fascinated.bat.command.impl.fun.image;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -20,14 +20,14 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "cat", description = "Get a random cat image")
|
@CommandInfo(name = "cat", description = "Get a random cat image")
|
||||||
public class CatSubCommand extends BatSubCommand {
|
public class CatSubCommand extends BatSubCommand {
|
||||||
@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 interaction) {
|
||||||
CatImageToken[] responseEntity = WebRequest.getAsEntity("https://api.thecatapi.com/v1/images/search", CatImageToken[].class);
|
CatImageToken[] responseEntity = WebRequest.getAsEntity("https://api.thecatapi.com/v1/images/search", CatImageToken[].class);
|
||||||
if (responseEntity == null || responseEntity.length == 0) {
|
if (responseEntity == null || responseEntity.length == 0) {
|
||||||
event.reply("Failed to get a cat image!").queue();
|
interaction.reply("Failed to get a cat image!").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("Here's a random cat image!")
|
.setAuthor("Here's a random cat image!")
|
||||||
.setImage(responseEntity[0].getUrl())
|
.setImage(responseEntity[0].getUrl())
|
||||||
.build()).queue();
|
.build()).queue();
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.fun.image;
|
package cc.fascinated.bat.command.impl.fun.image;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -20,14 +20,14 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "dog", description = "Get a random dog image")
|
@CommandInfo(name = "dog", description = "Get a random dog image")
|
||||||
public class DogSubCommand extends BatSubCommand {
|
public class DogSubCommand extends BatSubCommand {
|
||||||
@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 interaction) {
|
||||||
RandomImage responseEntity = WebRequest.getAsEntity("https://dog.ceo/api/breeds/image/random", RandomImage.class);
|
RandomImage responseEntity = WebRequest.getAsEntity("https://dog.ceo/api/breeds/image/random", RandomImage.class);
|
||||||
if (responseEntity == null) {
|
if (responseEntity == null) {
|
||||||
event.reply("Failed to get a dog image!").queue();
|
interaction.reply("Failed to get a dog image!").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("Here's a random dog image!")
|
.setAuthor("Here's a random dog image!")
|
||||||
.setImage(responseEntity.getMessage())
|
.setImage(responseEntity.getMessage())
|
||||||
.build()).queue();
|
.build()).queue();
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.fun.image;
|
package cc.fascinated.bat.command.impl.fun.image;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -20,14 +20,14 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "fox", description = "Get a random fox image")
|
@CommandInfo(name = "fox", description = "Get a random fox image")
|
||||||
public class FoxSubCommand extends BatSubCommand {
|
public class FoxSubCommand extends BatSubCommand {
|
||||||
@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 interaction) {
|
||||||
RandomFoxToken responseEntity = WebRequest.getAsEntity("https://randomfox.ca/floof/", RandomFoxToken.class);
|
RandomFoxToken responseEntity = WebRequest.getAsEntity("https://randomfox.ca/floof/", RandomFoxToken.class);
|
||||||
if (responseEntity == null) {
|
if (responseEntity == null) {
|
||||||
event.reply("Failed to get a fox image!").queue();
|
interaction.reply("Failed to get a fox image!").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("Here's a random fox image!")
|
.setAuthor("Here's a random fox image!")
|
||||||
.setImage(responseEntity.getImage())
|
.setImage(responseEntity.getImage())
|
||||||
.build()).queue();
|
.build()).queue();
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.fun.image;
|
package cc.fascinated.bat.command.impl.fun.image;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
||||||
@ -19,6 +19,5 @@ public class ImageCommand extends BatCommand {
|
|||||||
super.addSubCommand(context.getBean(CatSubCommand.class));
|
super.addSubCommand(context.getBean(CatSubCommand.class));
|
||||||
super.addSubCommand(context.getBean(DogSubCommand.class));
|
super.addSubCommand(context.getBean(DogSubCommand.class));
|
||||||
super.addSubCommand(context.getBean(FoxSubCommand.class));
|
super.addSubCommand(context.getBean(FoxSubCommand.class));
|
||||||
super.addSubCommand(context.getBean(DuckSubCommand.class));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package cc.fascinated.bat.command.impl.server;
|
||||||
|
|
||||||
|
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.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
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 Nick (okNick)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "membercount", description = "View the member count of the server!")
|
||||||
|
public class MemberCountCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
||||||
|
EmbedBuilder embed = EmbedUtils.genericEmbed().setAuthor("Member Count");
|
||||||
|
Guild discordGuild = guild.getDiscordGuild();
|
||||||
|
embed.setDescription("**%s** has a total of %s members.".formatted(discordGuild.getName(), discordGuild.getMembers().size()));
|
||||||
|
interaction.replyEmbeds(embed.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server;
|
package cc.fascinated.bat.command.impl.server;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.premium.PremiumProfile;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
@ -21,8 +20,8 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "premium", description = "View the premium information for the guild", requiredPermissions = Permission.ADMINISTRATOR)
|
@CommandInfo(name = "premium", description = "View the premium information for the guild", requiredPermissions = Permission.ADMINISTRATOR)
|
||||||
public class PremiumCommand extends BatCommand {
|
public class PremiumCommand 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 interaction) {
|
||||||
PremiumProfile premium = guild.getPremiumProfile();
|
BatGuild.Premium premium = guild.getPremium();
|
||||||
EmbedBuilder embed = EmbedUtils.genericEmbed().setAuthor("Premium Information");
|
EmbedBuilder embed = EmbedUtils.genericEmbed().setAuthor("Premium Information");
|
||||||
if (premium.hasPremium()) {
|
if (premium.hasPremium()) {
|
||||||
embed.addField("Premium", premium.hasPremium() ? "Yes" : "No", true);
|
embed.addField("Premium", premium.hasPremium() ? "Yes" : "No", true);
|
||||||
@ -32,6 +31,6 @@ public class PremiumCommand extends BatCommand {
|
|||||||
} else {
|
} else {
|
||||||
embed.setDescription("The guild does not have premium");
|
embed.setDescription("The guild does not have premium");
|
||||||
}
|
}
|
||||||
event.replyEmbeds(embed.build()).queue();
|
interaction.replyEmbeds(embed.build()).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.channel;
|
package cc.fascinated.bat.command.impl.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.channel;
|
package cc.fascinated.bat.command.impl.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -26,10 +26,10 @@ public class RemoveTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
Channel target = event.getOption("channel") == null ? channel : event.getOption("channel").getAsChannel();
|
Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel();
|
||||||
if (!(target instanceof TextChannel textChannel)) {
|
if (!(target instanceof TextChannel textChannel)) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -37,7 +37,7 @@ public class RemoveTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (textChannel.getTopic() == null) {
|
if (textChannel.getTopic() == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -45,7 +45,7 @@ public class RemoveTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textChannel.getManager().setTopic(null).queue();
|
textChannel.getManager().setTopic(null).queue();
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully removed the topic of <#%s>".formatted(textChannel.getId()))
|
.setDescription("Successfully removed the topic of <#%s>".formatted(textChannel.getId()))
|
||||||
.build()
|
.build()
|
||||||
).queue();
|
).queue();
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.channel;
|
package cc.fascinated.bat.command.impl.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -27,19 +27,19 @@ public class SetTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
Channel target = event.getOption("channel") == null ? channel : event.getOption("channel").getAsChannel();
|
Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel();
|
||||||
if (!(target instanceof TextChannel textChannel)) {
|
if (!(target instanceof TextChannel textChannel)) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String topic = event.getOption("topic").getAsString();
|
String topic = interaction.getOption("topic").getAsString();
|
||||||
if (topic.length() > 1024) {
|
if (topic.length() > 1024) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The topic must be 1024 characters or less!")
|
.setDescription("The topic must be 1024 characters or less!")
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -47,7 +47,7 @@ public class SetTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textChannel.getManager().setTopic(topic).queue();
|
textChannel.getManager().setTopic(topic).queue();
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully set the topic of <#%s> to: \"%s\"".formatted(textChannel.getId(), topic))
|
.setDescription("Successfully set the topic of <#%s> to: \"%s\"".formatted(textChannel.getId(), topic))
|
||||||
.build()
|
.build()
|
||||||
).queue();
|
).queue();
|
@ -1,4 +1,4 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.channel;
|
package cc.fascinated.bat.command.impl.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
@ -25,10 +25,10 @@ public class ViewTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
Channel target = event.getOption("channel") == null ? channel : event.getOption("channel").getAsChannel();
|
Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel();
|
||||||
if (!(target instanceof TextChannel textChannel)) {
|
if (!(target instanceof TextChannel textChannel)) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -37,14 +37,14 @@ public class ViewTopicSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
String topic = textChannel.getTopic();
|
String topic = textChannel.getTopic();
|
||||||
if (topic == null) {
|
if (topic == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("The topic of <#%s> is: \"%s\"".formatted(textChannel.getId(), topic))
|
.setDescription("The topic of <#%s> is: \"%s\"".formatted(textChannel.getId(), topic))
|
||||||
.build()
|
.build()
|
||||||
).queue();
|
).queue();
|
@ -1,83 +0,0 @@
|
|||||||
package cc.fascinated.bat.common;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
public class NumberFormatter {
|
|
||||||
/**
|
|
||||||
* The suffixes for the numbers
|
|
||||||
*/
|
|
||||||
private static final String[] SUFFIXES = new String[] { "K", "M", "B", "T", "Q", "QT", "S", "SP", "O", "N", "D", "UD", "DD", "TD" };
|
|
||||||
private static final DecimalFormat FORMAT = new DecimalFormat("###.##");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format the provided double
|
|
||||||
*
|
|
||||||
* @param input the value to format
|
|
||||||
* @return the formatted double, in the format of xx.xx[suffix]
|
|
||||||
*/
|
|
||||||
public static String format(double input) {
|
|
||||||
if (Double.isNaN(input)) {
|
|
||||||
return "ERROR";
|
|
||||||
}
|
|
||||||
if (Double.isInfinite(input) || input == Double.MAX_VALUE) {
|
|
||||||
return "∞";
|
|
||||||
}
|
|
||||||
if (1000 > input) {
|
|
||||||
return FORMAT.format(input);
|
|
||||||
}
|
|
||||||
double power = (int) Math.log10(input);
|
|
||||||
int index = (int) Math.floor(power / 3) - 1;
|
|
||||||
double factor = input / Math.pow(10, 3 + index * 3);
|
|
||||||
if (index >= SUFFIXES.length) {
|
|
||||||
return "ERROR";
|
|
||||||
}
|
|
||||||
return FORMAT.format(factor) + SUFFIXES[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format the provided double with commas
|
|
||||||
*
|
|
||||||
* @param input the value to format
|
|
||||||
* @return the formatted double, in the format of xx,xxx,xxx
|
|
||||||
*/
|
|
||||||
public static String formatCommas(double input) {
|
|
||||||
return String.format("%,.0f", input);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turns a provided string into a double, for example 1M -> 1000000.00
|
|
||||||
* Accepts decimal and negative values and is not case-sensitive
|
|
||||||
*
|
|
||||||
* @param input the string to convert
|
|
||||||
* @return the value the string represents
|
|
||||||
*/
|
|
||||||
public static double fromString(String input) {
|
|
||||||
if ((input = input.trim()).isEmpty()) {
|
|
||||||
return -1D;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
double value = Double.parseDouble(input); // parse pure numbers
|
|
||||||
if (Double.isNaN(value) || Double.isInfinite(value)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
input = input.toUpperCase(Locale.UK);
|
|
||||||
for (int i = SUFFIXES.length - 1; i > 0; i--) {
|
|
||||||
String suffix = SUFFIXES[i];
|
|
||||||
if (!input.endsWith(suffix)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String amount = input.substring(0, input.length() - suffix.length());
|
|
||||||
if (!amount.isEmpty()) {
|
|
||||||
return Double.parseDouble(amount) * Math.pow(10, 3 + i * 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
27
src/main/java/cc/fascinated/bat/common/NumberUtils.java
Normal file
27
src/main/java/cc/fascinated/bat/common/NumberUtils.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@UtilityClass
|
||||||
|
public class NumberUtils {
|
||||||
|
/**
|
||||||
|
* Formats a number with commas.
|
||||||
|
* <p>
|
||||||
|
* Example: 1000 -> 1,000 | Example: 1000.5 -> 1,000.5
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param number the number to format
|
||||||
|
* @return the formatted number
|
||||||
|
*/
|
||||||
|
public static String formatNumberCommas(double number) {
|
||||||
|
NumberFormat format = NumberFormat.getNumberInstance();
|
||||||
|
format.setGroupingUsed(true);
|
||||||
|
format.setMaximumFractionDigits(2);
|
||||||
|
return format.format(number);
|
||||||
|
}
|
||||||
|
}
|
26
src/main/java/cc/fascinated/bat/common/Profile.java
Normal file
26
src/main/java/cc/fascinated/bat/common/Profile.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public abstract class Profile {
|
||||||
|
/**
|
||||||
|
* The key of the profile.
|
||||||
|
*/
|
||||||
|
private String profileKey;
|
||||||
|
|
||||||
|
public Profile() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the profile
|
||||||
|
*/
|
||||||
|
public abstract void reset();
|
||||||
|
}
|
@ -1,9 +1,6 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
import cc.fascinated.bat.BatApplication;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -12,11 +9,11 @@ import java.util.Map;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public abstract class ProfileHolder {
|
public class ProfileHolder {
|
||||||
/**
|
/**
|
||||||
* The profiles for the holder
|
* The profiles for the holder
|
||||||
*/
|
*/
|
||||||
private final Map<String, Serializable> profiles = new HashMap<>();
|
private Map<String, Profile> profiles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a profile for the holder
|
* Gets a profile for the holder
|
||||||
@ -25,25 +22,19 @@ public abstract class ProfileHolder {
|
|||||||
* @param <T> The type of the profile
|
* @param <T> The type of the profile
|
||||||
* @return The profile
|
* @return The profile
|
||||||
*/
|
*/
|
||||||
public abstract <T extends Serializable> T getProfile(Class<T> clazz);
|
public <T extends Profile> T getProfile(Class<T> clazz) {
|
||||||
|
if (profiles == null) {
|
||||||
|
profiles = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
Profile profile = profiles.values().stream().filter(p -> p.getClass().equals(clazz)).findFirst().orElse(null);
|
||||||
* Gets the profiles for the holder
|
|
||||||
* using the provided document
|
|
||||||
*
|
|
||||||
* @return the profiles
|
|
||||||
*/
|
|
||||||
@SneakyThrows
|
|
||||||
protected <T extends Serializable> T getProfileFromDocument(Class<T> clazz, Document document) {
|
|
||||||
Serializable profile = getProfiles().get(clazz.getSimpleName());
|
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
T newProfile = clazz.cast(clazz.getDeclaredConstructors()[0].newInstance());
|
try {
|
||||||
org.bson.Document profiles = document.get("profiles", new org.bson.Document());
|
profile = clazz.newInstance();
|
||||||
org.bson.Document profileDocument = profiles.isEmpty() ? new org.bson.Document() : profiles.get(clazz.getSimpleName(), new org.bson.Document());
|
profiles.put(profile.getProfileKey(), profile);
|
||||||
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
newProfile.load(profileDocument, BatApplication.GSON);
|
e.printStackTrace();
|
||||||
getProfiles().put(clazz.getSimpleName(), newProfile);
|
}
|
||||||
return newProfile;
|
|
||||||
}
|
}
|
||||||
return clazz.cast(profile);
|
return clazz.cast(profile);
|
||||||
}
|
}
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
package cc.fascinated.bat.common;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@NoArgsConstructor
|
|
||||||
public abstract class Serializable {
|
|
||||||
/**
|
|
||||||
* Load data from the provided document into this profile
|
|
||||||
*
|
|
||||||
* @param document the document to load data from
|
|
||||||
* @param gson the GSON instance to use
|
|
||||||
*/
|
|
||||||
public abstract void load(Document document, Gson gson);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialize this profile into a Bson document
|
|
||||||
*
|
|
||||||
* @param gson the GSON instance to use
|
|
||||||
* @return the serialized document
|
|
||||||
*/
|
|
||||||
public abstract Document serialize(Gson gson);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the profile to its default state
|
|
||||||
*/
|
|
||||||
public abstract void reset();
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package cc.fascinated.bat.common;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.SpotifyService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
|
||||||
import se.michaelthelin.spotify.model_objects.miscellaneous.CurrentlyPlaying;
|
|
||||||
import se.michaelthelin.spotify.model_objects.specification.Track;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Log4j2
|
|
||||||
public class SpotifyUtils {
|
|
||||||
/**
|
|
||||||
* Gets the URL of the track that is currently playing.
|
|
||||||
*
|
|
||||||
* @param currentlyPlaying The currently playing object.
|
|
||||||
* @return The URL of the track that is currently playing.
|
|
||||||
*/
|
|
||||||
public static String getTrackUrl(CurrentlyPlaying currentlyPlaying) {
|
|
||||||
return "https://open.spotify.com/track/" + currentlyPlaying.getItem().getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the formatted time of the currently playing track
|
|
||||||
*
|
|
||||||
* @param currentlyPlaying the currently playing track
|
|
||||||
* @return the formatted time
|
|
||||||
*/
|
|
||||||
public static String getFormattedTime(@NonNull CurrentlyPlaying currentlyPlaying) {
|
|
||||||
Track track = (Track) currentlyPlaying.getItem();
|
|
||||||
int currentMinutes = currentlyPlaying.getProgress_ms() / 1000 / 60;
|
|
||||||
int currentSeconds = currentlyPlaying.getProgress_ms() / 1000 % 60;
|
|
||||||
int totalMinutes = track.getDurationMs() / 1000 / 60;
|
|
||||||
int totalSeconds = track.getDurationMs() / 1000 % 60;
|
|
||||||
|
|
||||||
return "`%02d:%02d`/`%02d:%02d`".formatted(currentMinutes, currentSeconds, totalMinutes, totalSeconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the next track that is playing
|
|
||||||
*
|
|
||||||
* @param user The user to get the track for
|
|
||||||
* @param oldName The name of the old track
|
|
||||||
* @return The new track
|
|
||||||
*/
|
|
||||||
public static CurrentlyPlaying getNewTrack(@NonNull SpotifyService spotifyService, @NonNull BatUser user, @NonNull String oldName) {
|
|
||||||
int checks = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(150);
|
|
||||||
while (checks < 10) {
|
|
||||||
CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user);
|
|
||||||
Track track = (Track) currentlyPlaying.getItem();
|
|
||||||
if (track.getName().equals(oldName)) {
|
|
||||||
Thread.sleep(250);
|
|
||||||
checks++;
|
|
||||||
} else {
|
|
||||||
log.info("Found new track \"{}\" in {} check{}", track.getName(), checks, checks == 1 ? "" : "s");
|
|
||||||
return currentlyPlaying;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package cc.fascinated.bat.config;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
public class Config {
|
|
||||||
/**
|
|
||||||
* Is the app running in a production environment?
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
private static final boolean production;
|
|
||||||
|
|
||||||
static {
|
|
||||||
// Are we running on production?
|
|
||||||
String appEnv = System.getenv("APP_ENV");
|
|
||||||
production = appEnv != null && (appEnv.equals("production"));
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,7 +27,7 @@ public class SpotifyController {
|
|||||||
* @return the response entity
|
* @return the response entity
|
||||||
*/
|
*/
|
||||||
@GetMapping(value = "/callback")
|
@GetMapping(value = "/callback")
|
||||||
public ResponseEntity<String> authorizationCallback(@RequestParam(required = false) String code) {
|
public ResponseEntity<String> authorizationCallback(@RequestParam String code) {
|
||||||
return ResponseEntity.ok(spotifyService.authorize(code));
|
return ResponseEntity.ok(spotifyService.authorize(code));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,10 @@ import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberScoreToken;
|
|||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
|
||||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
|
|
||||||
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;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
@ -83,31 +81,4 @@ public interface EventListener {
|
|||||||
*/
|
*/
|
||||||
default void onModalInteraction(BatGuild guild, @NonNull BatUser user, @NonNull ModalInteractionEvent event) {
|
default void onModalInteraction(BatGuild guild, @NonNull BatUser user, @NonNull ModalInteractionEvent event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a user updates their global name
|
|
||||||
*
|
|
||||||
* @param user the user that updated their global name
|
|
||||||
* @param oldName the old global name
|
|
||||||
* @param newName the new global name
|
|
||||||
*/
|
|
||||||
default void onUserUpdateGlobalName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateGlobalNameEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a user updates their nickname in a guild
|
|
||||||
*
|
|
||||||
* @param guild the guild that the user updated their nickname in
|
|
||||||
* @param user the user that updated their nickname
|
|
||||||
* @param oldName the old nickname
|
|
||||||
* @param newName the new nickname
|
|
||||||
*/
|
|
||||||
default void onGuildMemberUpdateNickname(@NonNull BatGuild guild, @NonNull BatUser user, String oldName, String newName, @NonNull GuildMemberUpdateNicknameEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when Spring is shutting down
|
|
||||||
*/
|
|
||||||
default void onSpringShutdown() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
package cc.fascinated.bat.exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
public class BatException extends Exception {
|
|
||||||
public BatException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,6 +5,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
|||||||
|
|
||||||
@ResponseStatus(HttpStatus.TOO_MANY_REQUESTS)
|
@ResponseStatus(HttpStatus.TOO_MANY_REQUESTS)
|
||||||
public class RateLimitException extends RuntimeException {
|
public class RateLimitException extends RuntimeException {
|
||||||
|
|
||||||
public RateLimitException(String message) {
|
public RateLimitException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
package cc.fascinated.bat.exception.spotify;
|
|
||||||
|
|
||||||
import lombok.experimental.StandardException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@StandardException
|
|
||||||
public class SpotifyTokenRefreshException extends RuntimeException {
|
|
||||||
public SpotifyTokenRefreshException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,11 +20,6 @@ public abstract class Feature {
|
|||||||
*/
|
*/
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
/**
|
|
||||||
* The description of the feature
|
|
||||||
*/
|
|
||||||
public final boolean canBeDisabled;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The category of the feature
|
* The category of the feature
|
||||||
*/
|
*/
|
||||||
@ -37,11 +32,7 @@ public abstract class Feature {
|
|||||||
* @param command The command to register
|
* @param command The command to register
|
||||||
*/
|
*/
|
||||||
public void registerCommand(@NonNull CommandService commandService, @NonNull BatCommand command) {
|
public void registerCommand(@NonNull CommandService commandService, @NonNull BatCommand command) {
|
||||||
// If the command using the default category then set the category to the feature's category
|
command.setCategory(category);
|
||||||
if (command.getCategory() == Category.GENERAL) {
|
|
||||||
command.setCategory(this.category);
|
|
||||||
}
|
|
||||||
command.setFeature(this);
|
|
||||||
commandService.registerCommand(command);
|
commandService.registerCommand(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class AfkFeature extends Feature {
|
public class AfkFeature extends Feature {
|
||||||
public AfkFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
public AfkFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
super("AFK", true, Category.GENERAL);
|
super("AFK", Category.GENERAL);
|
||||||
|
|
||||||
registerCommand(commandService, context.getBean(AfkCommand.class));
|
registerCommand(commandService, context.getBean(AfkCommand.class));
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,10 @@ import cc.fascinated.bat.event.EventListener;
|
|||||||
import cc.fascinated.bat.features.afk.profile.AfkProfile;
|
import cc.fascinated.bat.features.afk.profile.AfkProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,6 +15,13 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class AfkReturnListener implements EventListener {
|
public class AfkReturnListener implements EventListener {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AfkReturnListener(@NonNull GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGuildMessageReceive(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull MessageReceivedEvent event) {
|
public void onGuildMessageReceive(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull MessageReceivedEvent event) {
|
||||||
AfkProfile profile = guild.getProfile(AfkProfile.class);
|
AfkProfile profile = guild.getProfile(AfkProfile.class);
|
||||||
@ -20,6 +29,7 @@ public class AfkReturnListener implements EventListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
profile.removeAfkUser(guild, user.getId());
|
profile.removeAfkUser(guild, user.getId());
|
||||||
|
guildService.saveGuild(guild);
|
||||||
event.getMessage().reply("Welcome back, %s! You are no longer AFK.".formatted(user.getDiscordUser().getAsMention())).queue();
|
event.getMessage().reply("Welcome back, %s! You are no longer AFK.".formatted(user.getDiscordUser().getAsMention())).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,14 @@ import cc.fascinated.bat.common.MemberUtils;
|
|||||||
import cc.fascinated.bat.features.afk.profile.AfkProfile;
|
import cc.fascinated.bat.features.afk.profile.AfkProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,21 +22,26 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "afk", description = "Sets your AFK status")
|
@CommandInfo(name = "afk", description = "Sets your AFK status")
|
||||||
public class AfkCommand extends BatCommand {
|
public class AfkCommand extends BatCommand {
|
||||||
public AfkCommand() {
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AfkCommand(@NonNull GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
super.addOption(OptionType.STRING, "reason", "The reason for being AFK", false);
|
super.addOption(OptionType.STRING, "reason", "The reason for being AFK", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
AfkProfile profile = guild.getProfile(AfkProfile.class);
|
AfkProfile profile = guild.getProfile(AfkProfile.class);
|
||||||
String reason = null;
|
String reason = null;
|
||||||
OptionMapping reasonOption = event.getOption("reason");
|
OptionMapping reasonOption = interaction.getOption("reason");
|
||||||
if (reasonOption != null) {
|
if (reasonOption != null) {
|
||||||
reason = reasonOption.getAsString();
|
reason = reasonOption.getAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.addAfkUser(guild, member.getId(), reason);
|
profile.addAfkUser(guild, member.getId(), reason);
|
||||||
event.reply("You are now AFK: %s%s".formatted(
|
guildService.saveGuild(guild);
|
||||||
|
interaction.reply("You are now AFK: %s%s".formatted(
|
||||||
profile.getAfkReason(member.getId()),
|
profile.getAfkReason(member.getId()),
|
||||||
MemberUtils.hasPermissionToEdit(guild, user) ? "" :
|
MemberUtils.hasPermissionToEdit(guild, user) ? "" :
|
||||||
"\n\n*I do not have enough permissions to edit your user, and therefore cannot update your nickname*"
|
"\n\n*I do not have enough permissions to edit your user, and therefore cannot update your nickname*"
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
package cc.fascinated.bat.features.afk.profile;
|
package cc.fascinated.bat.features.afk.profile;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
import cc.fascinated.bat.common.Profile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import org.bson.Document;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -16,8 +13,7 @@ import java.util.Map;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@NoArgsConstructor
|
public class AfkProfile extends Profile {
|
||||||
public class AfkProfile extends Serializable {
|
|
||||||
private static final String DEFAULT_REASON = "Away";
|
private static final String DEFAULT_REASON = "Away";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,21 +98,4 @@ public class AfkProfile extends Serializable {
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
afkUsers = new HashMap<>();
|
afkUsers = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
afkUsers = new HashMap<>();
|
|
||||||
for (String key : document.keySet()) {
|
|
||||||
afkUsers.put(key, document.getString(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
for (String key : afkUsers.keySet()) {
|
|
||||||
document.put(key, afkUsers.get(key));
|
|
||||||
}
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class AutoRoleFeature extends Feature {
|
public class AutoRoleFeature extends Feature {
|
||||||
@Autowired
|
@Autowired
|
||||||
public AutoRoleFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
public AutoRoleFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
super("Auto Role",true, Category.SERVER);
|
super("AutoRole", Category.SERVER);
|
||||||
|
|
||||||
registerCommand(commandService, context.getBean(AutoRoleCommand.class));
|
registerCommand(commandService, context.getBean(AutoRoleCommand.class));
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,10 @@ import cc.fascinated.bat.event.EventListener;
|
|||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -21,20 +19,8 @@ import java.util.List;
|
|||||||
@Component
|
@Component
|
||||||
@Log4j2
|
@Log4j2
|
||||||
public class AutoRoleListener implements EventListener {
|
public class AutoRoleListener implements EventListener {
|
||||||
private final FeatureService featureService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public AutoRoleListener(@NonNull FeatureService featureService) {
|
|
||||||
this.featureService = featureService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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) {
|
||||||
AutoRoleFeature autoRoleFeature = featureService.getFeature(AutoRoleFeature.class);
|
|
||||||
if (!guild.getFeatureProfile().isFeatureEnabled(autoRoleFeature)) { // Check if the feature is enabled
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
if (profile.getRoles().isEmpty()) {
|
if (profile.getRoles().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -7,6 +7,7 @@ import cc.fascinated.bat.common.RoleUtils;
|
|||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
@ -23,27 +24,30 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("autoroles:add.sub")
|
@Component("autoroles:add.sub")
|
||||||
@CommandInfo(name = "add", description = "Adds a role to the auto roles list")
|
@CommandInfo(name = "add", description = "Adds a role to the auto roles list")
|
||||||
public class AddSubCommand extends BatSubCommand {
|
public class AddSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public AddSubCommand() {
|
public AddSubCommand(@NonNull GuildService guildService) {
|
||||||
super.addOption(OptionType.ROLE, "role", "The role to add", true);
|
super.addOption(OptionType.ROLE, "role", "The role to add", true);
|
||||||
|
this.guildService = guildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
// Check if the guild has reached the maximum auto roles count
|
// Check if the guild has reached the maximum auto roles count
|
||||||
int maxRoleSlots = AutoRoleProfile.getMaxRoleSlots(guild);
|
int maxRoleSlots = AutoRoleProfile.getMaxRoleSlots(guild);
|
||||||
if (profile.getRoleSlotsInUse() >= maxRoleSlots) {
|
if (profile.getRoleSlotsInUse() >= maxRoleSlots) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The guild can only have a maximum of %d auto roles"
|
.setDescription("The guild can only have a maximum of %d auto roles"
|
||||||
.formatted(maxRoleSlots))
|
.formatted(maxRoleSlots))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionMapping option = event.getOption("role");
|
OptionMapping option = interaction.getOption("role");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Please provide a role to add")
|
.setDescription("Please provide a role to add")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -52,7 +56,7 @@ public class AddSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
// Check if the role is already in the auto roles list
|
// Check if the role is already in the auto roles list
|
||||||
if (profile.hasRole(role.getId())) {
|
if (profile.hasRole(role.getId())) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The role %s is already in the auto roles list".formatted(role.getAsMention()))
|
.setDescription("The role %s is already in the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -60,7 +64,7 @@ public class AddSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
// Check if the bot has permission to give the role
|
// Check if the bot has permission to give the role
|
||||||
if (!RoleUtils.hasPermissionToGiveRole(guild, guild.getDiscordGuild().getSelfMember(), role)) {
|
if (!RoleUtils.hasPermissionToGiveRole(guild, guild.getDiscordGuild().getSelfMember(), role)) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("I do not have permission to give the role %s".formatted(role.getAsMention()))
|
.setDescription("I do not have permission to give the role %s".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -68,7 +72,7 @@ public class AddSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
// Check if the role is higher than the user adding the role
|
// Check if the role is higher than the user adding the role
|
||||||
if (!RoleUtils.hasPermissionToGiveRole(guild, member, role)) {
|
if (!RoleUtils.hasPermissionToGiveRole(guild, member, role)) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("You cannot add a role that is higher than you")
|
.setDescription("You cannot add a role that is higher than you")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -76,7 +80,8 @@ public class AddSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
// Add the role to the auto roles list
|
// Add the role to the auto roles list
|
||||||
profile.addRole(role.getId());
|
profile.addRole(role.getId());
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("You have added %s to the auto roles list".formatted(role.getAsMention()))
|
.setDescription("You have added %s to the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,12 @@ import cc.fascinated.bat.common.EmbedUtils;
|
|||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,12 +20,20 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("autoroles:clear.sub")
|
@Component("autoroles:clear.sub")
|
||||||
@CommandInfo(name = "clear", description = "Clears all auto roles")
|
@CommandInfo(name = "clear", description = "Clears all auto roles")
|
||||||
public class ClearSubCommand extends BatSubCommand {
|
public class ClearSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ClearSubCommand(GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
|
|
||||||
profile.reset();
|
profile.reset();
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully cleared all auto roles")
|
.setDescription("Successfully cleared all auto roles")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "list", description = "Lists all auto roles")
|
@CommandInfo(name = "list", description = "Lists all auto roles")
|
||||||
public class ListSubCommand extends BatSubCommand {
|
public class ListSubCommand extends BatSubCommand {
|
||||||
@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 interaction) {
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
if (profile.getRoles().isEmpty()) {
|
if (profile.getRoles().isEmpty()) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("There are no auto roles set")
|
.setDescription("There are no auto roles set")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -41,6 +41,6 @@ public class ListSubCommand extends BatSubCommand {
|
|||||||
EmbedBuilder embed = EmbedUtils.genericEmbed();
|
EmbedBuilder embed = EmbedUtils.genericEmbed();
|
||||||
embed.setAuthor("Auto Role List");
|
embed.setAuthor("Auto Role List");
|
||||||
embed.setDescription(roles.toString());
|
embed.setDescription(roles.toString());
|
||||||
event.replyEmbeds(embed.build()).queue();
|
interaction.replyEmbeds(embed.build()).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import cc.fascinated.bat.common.EmbedUtils;
|
|||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
@ -22,17 +23,20 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("autoroles:remove.sub")
|
@Component("autoroles:remove.sub")
|
||||||
@CommandInfo(name = "remove", description = "Removes a role from the auto roles list")
|
@CommandInfo(name = "remove", description = "Removes a role from the auto roles list")
|
||||||
public class RemoveSubCommand extends BatSubCommand {
|
public class RemoveSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public RemoveSubCommand() {
|
public RemoveSubCommand(GuildService guildService) {
|
||||||
super.addOption(OptionType.ROLE, "role", "The role to remove", true);
|
super.addOption(OptionType.ROLE, "role", "The role to remove", true);
|
||||||
|
this.guildService = guildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
OptionMapping option = event.getOption("role");
|
OptionMapping option = interaction.getOption("role");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Please provide a role to remove")
|
.setDescription("Please provide a role to remove")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -40,14 +44,15 @@ public class RemoveSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
Role role = option.getAsRole();
|
Role role = option.getAsRole();
|
||||||
if (!profile.hasRole(role.getId())) {
|
if (!profile.hasRole(role.getId())) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The role %s is not in the auto roles list".formatted(role.getAsMention()))
|
.setDescription("The role %s is not in the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.removeRole(role.getId());
|
profile.removeRole(role.getId());
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully removed the role %s from the auto roles list".formatted(role.getAsMention()))
|
.setDescription("Successfully removed the role %s from the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
package cc.fascinated.bat.features.autorole.profile;
|
package cc.fascinated.bat.features.autorole.profile;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
import cc.fascinated.bat.common.Profile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,8 +15,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
@NoArgsConstructor
|
public class AutoRoleProfile extends Profile {
|
||||||
public class AutoRoleProfile extends Serializable {
|
|
||||||
private static final int DEFAULT_MAX_ROLES = 10;
|
private static final int DEFAULT_MAX_ROLES = 10;
|
||||||
private static final int PREMIUM_MAX_ROLES = 25;
|
private static final int PREMIUM_MAX_ROLES = 25;
|
||||||
|
|
||||||
@ -28,6 +24,10 @@ public class AutoRoleProfile extends Serializable {
|
|||||||
*/
|
*/
|
||||||
private List<String> roleIds;
|
private List<String> roleIds;
|
||||||
|
|
||||||
|
public AutoRoleProfile() {
|
||||||
|
super("auto-role");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum amount of roles that can be set in the guild
|
* Gets the maximum amount of roles that can be set in the guild
|
||||||
*
|
*
|
||||||
@ -35,7 +35,7 @@ public class AutoRoleProfile extends Serializable {
|
|||||||
* @return the amount of role slots
|
* @return the amount of role slots
|
||||||
*/
|
*/
|
||||||
public static int getMaxRoleSlots(BatGuild guild) {
|
public static int getMaxRoleSlots(BatGuild guild) {
|
||||||
if (guild.getPremiumProfile().hasPremium()) {
|
if (guild.getPremium().hasPremium()) {
|
||||||
return PREMIUM_MAX_ROLES;
|
return PREMIUM_MAX_ROLES;
|
||||||
}
|
}
|
||||||
return DEFAULT_MAX_ROLES;
|
return DEFAULT_MAX_ROLES;
|
||||||
@ -110,16 +110,4 @@ public class AutoRoleProfile extends Serializable {
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
roleIds.clear();
|
roleIds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
roleIds = document.getList("roleIds", String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
document.put("roleIds", roleIds);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.Category;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
|
||||||
import cc.fascinated.bat.features.base.commands.botadmin.premium.PremiumAdminCommand;
|
|
||||||
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.avatar.AvatarCommand;
|
|
||||||
import cc.fascinated.bat.features.base.commands.general.banner.BannerCommand;
|
|
||||||
import cc.fascinated.bat.features.base.commands.server.MemberCountCommand;
|
|
||||||
import cc.fascinated.bat.features.base.commands.server.PremiumCommand;
|
|
||||||
import cc.fascinated.bat.features.base.commands.server.channel.ChannelCommand;
|
|
||||||
import cc.fascinated.bat.features.base.commands.server.feature.FeatureCommand;
|
|
||||||
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 BaseFeature extends Feature {
|
|
||||||
@Autowired
|
|
||||||
public BaseFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
|
||||||
super("Base", false, Category.GENERAL);
|
|
||||||
|
|
||||||
super.registerCommand(commandService, context.getBean(PremiumCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(PremiumAdminCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(MemberCountCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(ChannelCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(VoteCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(PingCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(InviteCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(HelpCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(BotStatsCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(BannerCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(AvatarCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(ImageCommand.class));
|
|
||||||
super.registerCommand(commandService, context.getBean(FeatureCommand.class));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.fun.image;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.common.WebRequest;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.model.token.randomd.RandomDuck;
|
|
||||||
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
|
|
||||||
@CommandInfo(name = "duck", description = "Get a random duck image")
|
|
||||||
public class DuckSubCommand extends BatSubCommand {
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
RandomDuck responseEntity = WebRequest.getAsEntity("https://random-d.uk/api/v2/random", RandomDuck.class);
|
|
||||||
if (responseEntity == null) {
|
|
||||||
event.reply("Failed to get a duck image!").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
.setAuthor("Here's a random duck image!")
|
|
||||||
.setImage(responseEntity.getUrl())
|
|
||||||
.build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.general;
|
|
||||||
|
|
||||||
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.SlashCommandInteraction;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "vote", description = "Vote for the bot", guildOnly = false)
|
|
||||||
public class VoteCommand extends BatCommand {
|
|
||||||
private static final String[] VOTE_LINKS = new String[]{
|
|
||||||
"https://top.gg/bot/1254161119975833652/vote"
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("You can vote for the bot by clicking the following links:\n\n");
|
|
||||||
for (String link : VOTE_LINKS) {
|
|
||||||
builder.append("%s\n".formatted(link));
|
|
||||||
}
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
.setDescription(builder.toString())
|
|
||||||
.build()
|
|
||||||
).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.Emojis;
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.common.NumberFormatter;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
|
||||||
import net.dv8tion.jda.api.OnlineStatus;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Nick (okNick)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "membercount", description = "View the member count of the server!")
|
|
||||||
public class MemberCountCommand extends BatCommand {
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
Guild discordGuild = guild.getDiscordGuild();
|
|
||||||
int totalMembers = 0, totalUsers = 0, totalBots = 0;
|
|
||||||
Map<OnlineStatus, Integer> memberCounts = new HashMap<>();
|
|
||||||
for (Member guildMember : discordGuild.getMembers()) {
|
|
||||||
OnlineStatus status = guildMember.getOnlineStatus();
|
|
||||||
memberCounts.put(status, memberCounts.getOrDefault(status, 0) + 1);
|
|
||||||
|
|
||||||
if (guildMember.getUser().isBot()) {
|
|
||||||
totalBots++;
|
|
||||||
} else {
|
|
||||||
totalUsers++;
|
|
||||||
}
|
|
||||||
totalMembers++;
|
|
||||||
}
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
.setDescription("""
|
|
||||||
**Member Count**
|
|
||||||
Total Members: `%s`
|
|
||||||
Total Users: `%s`
|
|
||||||
Total Bots: `%s`
|
|
||||||
\s
|
|
||||||
**Member Presence**
|
|
||||||
%s Online: `%s`
|
|
||||||
%s Idle: `%s`
|
|
||||||
%s Do Not Disturb: `%s`
|
|
||||||
%s Offline: `%s`""".formatted(
|
|
||||||
NumberFormatter.format(totalMembers),
|
|
||||||
NumberFormatter.format(totalUsers),
|
|
||||||
NumberFormatter.format(totalBots),
|
|
||||||
Emojis.ONLINE_EMOJI,
|
|
||||||
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.ONLINE, 0)),
|
|
||||||
Emojis.IDLE_EMOJI,
|
|
||||||
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.IDLE, 0)),
|
|
||||||
Emojis.DND_EMOJI,
|
|
||||||
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.DO_NOT_DISTURB, 0)),
|
|
||||||
Emojis.OFFLINE_EMOJI,
|
|
||||||
NumberFormatter.format(memberCounts.getOrDefault(OnlineStatus.OFFLINE, 0))))
|
|
||||||
.build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.feature;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
|
||||||
import cc.fascinated.bat.features.base.profile.FeatureProfile;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
|
||||||
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.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component("feature:disable.sub")
|
|
||||||
@CommandInfo(name = "disable", description = "Disables a feature")
|
|
||||||
public class DisableSubCommand extends BatSubCommand {
|
|
||||||
@Autowired
|
|
||||||
public DisableSubCommand() {
|
|
||||||
super.addOption(OptionType.STRING, "feature", "The feature to disable", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
FeatureProfile featureProfile = guild.getFeatureProfile();
|
|
||||||
OptionMapping featureOption = event.getOption("feature");
|
|
||||||
if (featureOption == null) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("You must provide a feature to enabled")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String featureName = featureOption.getAsString();
|
|
||||||
if (!FeatureService.INSTANCE.isFeature(featureName)) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("That feature does not exist")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Feature feature = FeatureService.INSTANCE.getFeature(featureName);
|
|
||||||
if (featureProfile.isFeatureDisabled(feature)) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("The feature `%s` is already disabled".formatted(feature.getName()))
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
featureProfile.disableFeature(feature);
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("Successfully disabled the `%s` feature".formatted(feature.getName()))
|
|
||||||
.build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.feature;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
|
||||||
import cc.fascinated.bat.features.base.profile.FeatureProfile;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
|
||||||
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.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component("feature:enable.sub")
|
|
||||||
@CommandInfo(name = "enable", description = "Enables a feature")
|
|
||||||
public class EnableSubCommand extends BatSubCommand {
|
|
||||||
@Autowired
|
|
||||||
public EnableSubCommand() {
|
|
||||||
super.addOption(OptionType.STRING, "feature", "The feature to enable", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
FeatureProfile featureProfile = guild.getFeatureProfile();
|
|
||||||
OptionMapping featureOption = event.getOption("feature");
|
|
||||||
if (featureOption == null) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("You must provide a feature to enabled")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String featureName = featureOption.getAsString();
|
|
||||||
if (!FeatureService.INSTANCE.isFeature(featureName)) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("That feature does not exist")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Feature feature = FeatureService.INSTANCE.getFeature(featureName);
|
|
||||||
if (featureProfile.isFeatureEnabled(feature)) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("The feature `%s` is already enabled".formatted(feature.getName()))
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
featureProfile.enableFeature(feature);
|
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("Successfully enabled the `%s` feature".formatted(feature.getName()))
|
|
||||||
.build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.feature;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
|
||||||
import cc.fascinated.bat.command.Category;
|
|
||||||
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 = "feature", description = "Configure features in your guild", requiredPermissions = Permission.ADMINISTRATOR, category = Category.SERVER)
|
|
||||||
public class FeatureCommand extends BatCommand {
|
|
||||||
@Autowired
|
|
||||||
public FeatureCommand(@NonNull ApplicationContext context) {
|
|
||||||
super.addSubCommand(context.getBean(EnableSubCommand.class));
|
|
||||||
super.addSubCommand(context.getBean(DisableSubCommand.class));
|
|
||||||
super.addSubCommand(context.getBean(ListSubCommand.class));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.commands.server.feature;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
|
||||||
import cc.fascinated.bat.features.base.profile.FeatureProfile;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
|
||||||
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("feature:list.sub")
|
|
||||||
@CommandInfo(name = "list", description = "Lists the features and their states")
|
|
||||||
public class ListSubCommand extends BatSubCommand {
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
StringBuilder featureStates = new StringBuilder();
|
|
||||||
for (Feature feature : FeatureService.INSTANCE.getFeaturesSorted()) {
|
|
||||||
FeatureProfile featureProfile = guild.getFeatureProfile();
|
|
||||||
featureStates.append("%s `%s`\n".formatted(
|
|
||||||
featureProfile.getFeatureState(feature).getEmoji(),
|
|
||||||
feature.getName()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
.setTitle("Feature List")
|
|
||||||
.setDescription(featureStates.toString())
|
|
||||||
.build()
|
|
||||||
).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,120 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.base.profile;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class FeatureProfile extends Serializable {
|
|
||||||
private static final FeatureState DEFAULT_STATE = FeatureState.ENABLED;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The feature states
|
|
||||||
*/
|
|
||||||
private Map<String, FeatureState> featureStates;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the feature states
|
|
||||||
*
|
|
||||||
* @return the feature states
|
|
||||||
*/
|
|
||||||
public FeatureState getFeatureState(Feature feature) {
|
|
||||||
if (feature == null) {
|
|
||||||
return DEFAULT_STATE;
|
|
||||||
}
|
|
||||||
String featureName = feature.getName().toUpperCase();
|
|
||||||
if (!this.featureStates.containsKey(featureName)) {
|
|
||||||
this.featureStates.put(featureName, DEFAULT_STATE);
|
|
||||||
}
|
|
||||||
return this.featureStates.get(featureName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets whether the feature is enabled
|
|
||||||
*
|
|
||||||
* @return the feature state
|
|
||||||
*/
|
|
||||||
public boolean isFeatureEnabled(Feature feature) {
|
|
||||||
return this.getFeatureState(feature) == FeatureState.ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets whether the feature is disabled
|
|
||||||
*
|
|
||||||
* @return the feature state
|
|
||||||
*/
|
|
||||||
public boolean isFeatureDisabled(Feature feature) {
|
|
||||||
return this.getFeatureState(feature) == FeatureState.DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables the feature
|
|
||||||
*
|
|
||||||
* @param feature the feature to enable
|
|
||||||
*/
|
|
||||||
public void enableFeature(Feature feature) {
|
|
||||||
this.setFeatureState(feature, FeatureState.ENABLED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disables the feature
|
|
||||||
*
|
|
||||||
* @param feature the feature to disable
|
|
||||||
*/
|
|
||||||
public void disableFeature(Feature feature) {
|
|
||||||
this.setFeatureState(feature, FeatureState.DISABLED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the feature state
|
|
||||||
*
|
|
||||||
* @param feature the feature to set the state for
|
|
||||||
* @param state the state to set
|
|
||||||
*/
|
|
||||||
public void setFeatureState(Feature feature, FeatureState state) {
|
|
||||||
this.featureStates.put(feature.getName().toUpperCase(), state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
this.featureStates = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.featureStates = new HashMap<>();
|
|
||||||
for (String key : document.keySet()) {
|
|
||||||
this.featureStates.put(key, FeatureState.valueOf(document.getString(key)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
for (String key : this.featureStates.keySet()) {
|
|
||||||
document.put(key, this.featureStates.get(key).name());
|
|
||||||
}
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@AllArgsConstructor @Getter
|
|
||||||
public enum FeatureState {
|
|
||||||
ENABLED(":white_check_mark:"),
|
|
||||||
DISABLED(":x:");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The emoji for the feature state
|
|
||||||
*/
|
|
||||||
private final String emoji;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +1,13 @@
|
|||||||
package cc.fascinated.bat.features.birthday;
|
package cc.fascinated.bat.features.birthday;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
||||||
import cc.fascinated.bat.event.EventListener;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
import cc.fascinated.bat.features.Feature;
|
||||||
import cc.fascinated.bat.features.birthday.command.BirthdayCommand;
|
import cc.fascinated.bat.features.birthday.command.BirthdayCommand;
|
||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.service.CommandService;
|
import cc.fascinated.bat.service.CommandService;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -19,11 +16,11 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BirthdayFeature extends Feature implements EventListener {
|
public class BirthdayFeature extends Feature {
|
||||||
private final GuildService guildService;
|
private final GuildService guildService;
|
||||||
|
|
||||||
public BirthdayFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService, @NonNull GuildService guildService) {
|
public BirthdayFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService, @NonNull GuildService guildService) {
|
||||||
super("Birthday", true, Category.UTILITY);
|
super("Birthday", Category.UTILITY);
|
||||||
this.guildService = guildService;
|
this.guildService = guildService;
|
||||||
|
|
||||||
registerCommand(commandService, context.getBean(BirthdayCommand.class));
|
registerCommand(commandService, context.getBean(BirthdayCommand.class));
|
||||||
@ -32,15 +29,11 @@ public class BirthdayFeature extends Feature implements EventListener {
|
|||||||
/**
|
/**
|
||||||
* Check birthdays every day at midnight
|
* Check birthdays every day at midnight
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "0 1 0 * * *")
|
@Scheduled(cron = "0 0 0 * * *")
|
||||||
private void checkBirthdays() {
|
private void checkBirthdays() {
|
||||||
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
for (BatGuild guild : guildService.getAllGuilds()) {
|
||||||
BatGuild batGuild = guildService.getGuild(guild.getId());
|
BirthdayProfile profile = guild.getProfile(BirthdayProfile.class);
|
||||||
if (batGuild == null) {
|
profile.checkBirthdays(guild);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BirthdayProfile profile = batGuild.getBirthdayProfile();
|
|
||||||
profile.checkBirthdays(batGuild);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.birthday;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class UserBirthday extends Serializable {
|
|
||||||
/**
|
|
||||||
* The user's birthday
|
|
||||||
*/
|
|
||||||
private Date birthday;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the birthday should be hidden
|
|
||||||
*/
|
|
||||||
private boolean hidden;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the age of the user
|
|
||||||
*
|
|
||||||
* @return the age of the user
|
|
||||||
*/
|
|
||||||
public int calculateAge() {
|
|
||||||
Calendar birthdayCalendar = Calendar.getInstance();
|
|
||||||
birthdayCalendar.setTime(this.getBirthday());
|
|
||||||
Calendar today = Calendar.getInstance();
|
|
||||||
int age = today.get(Calendar.YEAR) - birthdayCalendar.get(Calendar.YEAR);
|
|
||||||
|
|
||||||
// Check if the birthday hasn't occurred yet this year
|
|
||||||
if (today.get(Calendar.DAY_OF_YEAR) < birthdayCalendar.get(Calendar.DAY_OF_YEAR)) {
|
|
||||||
age--;
|
|
||||||
}
|
|
||||||
return age;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.birthday = document.getDate("birthday");
|
|
||||||
this.hidden = document.getBoolean("hidden", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
document.put("birthday", this.birthday);
|
|
||||||
document.put("hidden", this.hidden);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,7 +19,5 @@ public class BirthdayCommand extends BatCommand {
|
|||||||
super.addSubCommand(context.getBean(RemoveSubCommand.class));
|
super.addSubCommand(context.getBean(RemoveSubCommand.class));
|
||||||
super.addSubCommand(context.getBean(ChannelSubCommand.class));
|
super.addSubCommand(context.getBean(ChannelSubCommand.class));
|
||||||
super.addSubCommand(context.getBean(MessageSubCommand.class));
|
super.addSubCommand(context.getBean(MessageSubCommand.class));
|
||||||
super.addSubCommand(context.getBean(ViewSubCommand.class));
|
|
||||||
super.addSubCommand(context.getBean(PrivateSubCommand.class));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import cc.fascinated.bat.common.TextChannelUtils;
|
|||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
@ -25,23 +26,26 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("birthday:channel.sub")
|
@Component("birthday:channel.sub")
|
||||||
@CommandInfo(name = "channel", description = "Sets the birthday notification channel", requiredPermissions = Permission.MANAGE_SERVER)
|
@CommandInfo(name = "channel", description = "Sets the birthday notification channel", requiredPermissions = Permission.MANAGE_SERVER)
|
||||||
public class ChannelSubCommand extends BatSubCommand {
|
public class ChannelSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ChannelSubCommand() {
|
public ChannelSubCommand(GuildService guildService) {
|
||||||
super.addOption(OptionType.CHANNEL, "channel", "The channel birthdays will be sent in", false);
|
super.addOption(OptionType.CHANNEL, "channel", "The channel birthdays will be sent in", false);
|
||||||
|
this.guildService = guildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
BirthdayProfile profile = guild.getBirthdayProfile();
|
BirthdayProfile profile = guild.getProfile(BirthdayProfile.class);
|
||||||
OptionMapping option = event.getOption("channel");
|
OptionMapping option = interaction.getOption("channel");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("There is no channel set for birthday notifications. Please provide a channel to set the birthday channel to")
|
.setDescription("There is no channel set for birthday notifications. Please provide a channel to set the birthday channel to")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("The current birthday channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
.setDescription("The current birthday channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -49,14 +53,16 @@ public class ChannelSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
GuildChannelUnion targetChannel = option.getAsChannel();
|
GuildChannelUnion targetChannel = option.getAsChannel();
|
||||||
if (targetChannel.getType() != ChannelType.TEXT) {
|
if (targetChannel.getType() != ChannelType.TEXT) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Invalid channel type, please provide a text channel")
|
.setDescription("Invalid channel type, please provide a text channel")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.setChannelId(targetChannel.getId());
|
profile.setChannelId(targetChannel.getId());
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully set the birthday channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
.setDescription("Successfully set the birthday channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import cc.fascinated.bat.common.EmbedUtils;
|
|||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
@ -16,6 +17,10 @@ import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|||||||
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.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
@ -23,17 +28,22 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("birthday:message.sub")
|
@Component("birthday:message.sub")
|
||||||
@CommandInfo(name = "message", description = "Changes the message that is sent when it is a user's birthday", requiredPermissions = Permission.MANAGE_SERVER)
|
@CommandInfo(name = "message", description = "Changes the message that is sent when it is a user's birthday", requiredPermissions = Permission.MANAGE_SERVER)
|
||||||
public class MessageSubCommand extends BatSubCommand {
|
public class MessageSubCommand extends BatSubCommand {
|
||||||
|
private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("dd/MM/yyyy");
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public MessageSubCommand() {
|
public MessageSubCommand(GuildService guildService) {
|
||||||
super.addOption(OptionType.STRING, "message", "The message that is sent. (Placeholders: {user}, {age})", true);
|
super.addOption(OptionType.STRING, "message", "The message that is sent. (Placeholders: {user}, {age})", true);
|
||||||
|
this.guildService = guildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
BirthdayProfile profile = guild.getBirthdayProfile();
|
BirthdayProfile profile = guild.getProfile(BirthdayProfile.class);
|
||||||
OptionMapping messageOption = event.getOption("message");
|
|
||||||
|
OptionMapping messageOption = interaction.getOption("message");
|
||||||
if (messageOption == null) {
|
if (messageOption == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("You must provide a message")
|
.setDescription("You must provide a message")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -41,21 +51,37 @@ public class MessageSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
String message = messageOption.getAsString();
|
String message = messageOption.getAsString();
|
||||||
if (message.length() > 2000) {
|
if (message.length() > 2000) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The message must be less than 2000 characters")
|
.setDescription("The message must be less than 2000 characters")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!message.contains("{user}") || !message.contains("{age}")) {
|
if (!message.contains("{user}") || !message.contains("{age}")) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The message must contain the placeholders {user} and {age}")
|
.setDescription("The message must contain the placeholders {user} and {age}")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.setMessage(message);
|
profile.setMessage(message);
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("You have updated the birthday message!\n\n**Message:** %s".formatted(profile.getBirthdayMessage(user.getDiscordUser())))
|
.setDescription("You have updated the birthday message!\n\n**Message:** %s".formatted(profile.getBirthdayMessage(user.getDiscordUser())))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a birthday from the string
|
||||||
|
*
|
||||||
|
* @param birthday the date to parse
|
||||||
|
* @return the birthday
|
||||||
|
*/
|
||||||
|
private Date parseBirthday(String birthday) {
|
||||||
|
try {
|
||||||
|
return FORMATTER.parse(birthday);
|
||||||
|
} catch (ParseException ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.birthday.command;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.features.birthday.UserBirthday;
|
|
||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
|
||||||
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.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component("birthday:private.sub")
|
|
||||||
@CommandInfo(name = "private", description = "Changes whether your birthday is private or not")
|
|
||||||
public class PrivateSubCommand extends BatSubCommand {
|
|
||||||
@Autowired
|
|
||||||
public PrivateSubCommand() {
|
|
||||||
super.addOption(OptionType.BOOLEAN, "enabled", "Whether your birthday is private or not", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
BirthdayProfile profile = guild.getBirthdayProfile();
|
|
||||||
OptionMapping enabledOption = event.getOption("enabled");
|
|
||||||
if (enabledOption == null) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("You must provide whether your birthday is private or not")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean enabled = enabledOption.getAsBoolean();
|
|
||||||
UserBirthday birthday = profile.getBirthday(user.getId());
|
|
||||||
if (birthday == null) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("You have not set your birthday yet")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
birthday.setHidden(enabled);
|
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("Your birthday privacy settings have been updated\n\n**Private:** " + (enabled ? "Yes" : "No"))
|
|
||||||
.build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,10 +6,12 @@ import cc.fascinated.bat.common.EmbedUtils;
|
|||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
@ -19,12 +21,21 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("birthday:remove.sub")
|
@Component("birthday:remove.sub")
|
||||||
@CommandInfo(name = "remove", description = "Remove your birthday from this guild")
|
@CommandInfo(name = "remove", description = "Remove your birthday from this guild")
|
||||||
public class RemoveSubCommand extends BatSubCommand {
|
public class RemoveSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RemoveSubCommand(GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
BirthdayProfile profile = guild.getBirthdayProfile();
|
BirthdayProfile profile = guild.getProfile(BirthdayProfile.class);
|
||||||
|
|
||||||
profile.removeBirthday(user.getId());
|
profile.removeBirthday(user.getId());
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Your birthday has been removed from this guild")
|
.setDescription("Your birthday has been removed from this guild")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@ package cc.fascinated.bat.features.birthday.command;
|
|||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.features.birthday.UserBirthday;
|
|
||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
@ -28,25 +28,28 @@ import java.util.Date;
|
|||||||
@CommandInfo(name = "set", description = "Add your birthday to this guild")
|
@CommandInfo(name = "set", description = "Add your birthday to this guild")
|
||||||
public class SetSubCommand extends BatSubCommand {
|
public class SetSubCommand extends BatSubCommand {
|
||||||
private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("dd/MM/yyyy");
|
private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("dd/MM/yyyy");
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SetSubCommand() {
|
public SetSubCommand(GuildService guildService) {
|
||||||
super.addOption(OptionType.STRING, "birthday", "Your birthday (format: DAY/MONTH/YEAR - 01/05/2004)", true);
|
super.addOption(OptionType.STRING, "birthday", "Your birthday (format: DAY/MONTH/YEAR - 01/05/2004)", true);
|
||||||
|
this.guildService = guildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
BirthdayProfile profile = guild.getBirthdayProfile();
|
BirthdayProfile profile = guild.getProfile(BirthdayProfile.class);
|
||||||
|
|
||||||
if (!profile.hasChannelSetup()) {
|
if (!profile.hasChannelSetup()) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Birthdays have not been enabled in this guild. Please ask an administrator to enable them.")
|
.setDescription("Birthdays have not been enabled in this guild. Please ask an administrator to enable them.")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionMapping birthdayOption = event.getOption("birthday");
|
OptionMapping birthdayOption = interaction.getOption("birthday");
|
||||||
if (birthdayOption == null) {
|
if (birthdayOption == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("You must provide a birthday")
|
.setDescription("You must provide a birthday")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -54,20 +57,16 @@ public class SetSubCommand extends BatSubCommand {
|
|||||||
String birthdayString = birthdayOption.getAsString();
|
String birthdayString = birthdayOption.getAsString();
|
||||||
Date birthday = parseBirthday(birthdayString);
|
Date birthday = parseBirthday(birthdayString);
|
||||||
if (birthday == null) {
|
if (birthday == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("""
|
.setDescription("Invalid birthday format. Please use the format: DAY/MONTH/YEAR - 01/05/2004")
|
||||||
Invalid birthday format. Please use the following format:
|
|
||||||
DAY/MONTH/YEAR - 01/05/2004
|
|
||||||
""")
|
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserBirthday userBirthday = new UserBirthday();
|
profile.addBirthday(member.getId(), birthday);
|
||||||
userBirthday.setBirthday(birthday);
|
guildService.saveGuild(guild);
|
||||||
userBirthday.setHidden(false);
|
|
||||||
profile.addBirthday(member.getId(), userBirthday);
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("You have updated your birthday!")
|
.setDescription("You have updated your birthday!")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
@ -80,16 +79,9 @@ public class SetSubCommand extends BatSubCommand {
|
|||||||
*/
|
*/
|
||||||
private Date parseBirthday(String birthday) {
|
private Date parseBirthday(String birthday) {
|
||||||
try {
|
try {
|
||||||
Date date = FORMATTER.parse(birthday);
|
return FORMATTER.parse(birthday);
|
||||||
if (date.after(new Date())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (date.toInstant().toEpochMilli() < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return date;
|
|
||||||
} catch (ParseException ignored) {
|
} catch (ParseException ignored) {
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.birthday.command;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.features.birthday.UserBirthday;
|
|
||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.UserService;
|
|
||||||
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.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component("birthday:view.sub")
|
|
||||||
@CommandInfo(name = "view", description = "Add your birthday to this guild")
|
|
||||||
public class ViewSubCommand extends BatSubCommand {
|
|
||||||
private final UserService userService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ViewSubCommand(@NonNull UserService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
super.addOption(OptionType.USER, "user", "The user to view the birthday of", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
BirthdayProfile profile = guild.getBirthdayProfile();
|
|
||||||
if (!profile.hasChannelSetup()) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("Birthdays have not been enabled in this guild. Please ask an administrator to enable them.")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionMapping birthdayOption = event.getOption("user");
|
|
||||||
BatUser target = birthdayOption == null ? user : userService.getUser(birthdayOption.getAsUser().getId());
|
|
||||||
if (target == null) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("You must provide a valid user")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UserBirthday birthday = profile.getBirthday(target.getId());
|
|
||||||
if (birthday == null) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("%s does not have a birthday set".formatted(target.getDiscordUser().getAsMention()))
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (birthday.isHidden() && !user.getId().equals(target.getId())) {
|
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("%s has their birthday set to private".formatted(target.getDiscordUser().getAsMention()))
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("%s was born on <t:%s:D> they are `%s` years old!".formatted(
|
|
||||||
target.getDiscordUser().getAsMention(), birthday.getBirthday().toInstant().toEpochMilli()/1000,
|
|
||||||
birthday.calculateAge()
|
|
||||||
))
|
|
||||||
.build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +1,28 @@
|
|||||||
package cc.fascinated.bat.features.birthday.profile;
|
package cc.fascinated.bat.features.birthday.profile;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
import cc.fascinated.bat.common.Profile;
|
||||||
import cc.fascinated.bat.features.birthday.UserBirthday;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.*;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
public class BirthdayProfile extends Profile {
|
||||||
public class BirthdayProfile extends Serializable {
|
|
||||||
private static final String DEFAULT_MESSAGE = "Happy Birthday {user} :tada: :birthday: You are now {age} years old!";
|
private static final String DEFAULT_MESSAGE = "Happy Birthday {user} :tada: :birthday: You are now {age} years old!";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of birthdays that are being tracked
|
* The list of birthdays that are being tracked
|
||||||
*/
|
*/
|
||||||
private Map<String, UserBirthday> birthdays;
|
private Map<String, Date> birthdays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The channel ID of the birthday feed
|
* The channel ID of the birthday feed
|
||||||
@ -42,13 +34,17 @@ public class BirthdayProfile extends Serializable {
|
|||||||
*/
|
*/
|
||||||
private String message = DEFAULT_MESSAGE;
|
private String message = DEFAULT_MESSAGE;
|
||||||
|
|
||||||
|
public BirthdayProfile() {
|
||||||
|
super("birthday");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a birthday to be tracked
|
* Adds a birthday to be tracked
|
||||||
*
|
*
|
||||||
* @param userId the id of the user to track
|
* @param userId the id of the user to track
|
||||||
* @param birthday the birthday of the user
|
* @param birthday the birthday of the user
|
||||||
*/
|
*/
|
||||||
public void addBirthday(String userId, UserBirthday birthday) {
|
public void addBirthday(String userId, Date birthday) {
|
||||||
if (birthdays == null) {
|
if (birthdays == null) {
|
||||||
birthdays = new HashMap<>();
|
birthdays = new HashMap<>();
|
||||||
}
|
}
|
||||||
@ -73,7 +69,7 @@ public class BirthdayProfile extends Serializable {
|
|||||||
* @param userId the id of the user
|
* @param userId the id of the user
|
||||||
* @return the birthday of the user
|
* @return the birthday of the user
|
||||||
*/
|
*/
|
||||||
public UserBirthday getBirthday(String userId) {
|
public Date getBirthday(String userId) {
|
||||||
if (birthdays == null) {
|
if (birthdays == null) {
|
||||||
birthdays = new HashMap<>();
|
birthdays = new HashMap<>();
|
||||||
}
|
}
|
||||||
@ -89,6 +85,33 @@ public class BirthdayProfile extends Serializable {
|
|||||||
return channelId != null;
|
return channelId != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the age of a user
|
||||||
|
*
|
||||||
|
* @param userId the id of the user
|
||||||
|
* @return the age of the user
|
||||||
|
*/
|
||||||
|
public int calculateAge(String userId) {
|
||||||
|
Date birthday = getBirthday(userId);
|
||||||
|
if (birthday == null) {
|
||||||
|
return 0; // or throw an exception
|
||||||
|
}
|
||||||
|
|
||||||
|
Calendar birthdayCalendar = Calendar.getInstance();
|
||||||
|
birthdayCalendar.setTime(birthday);
|
||||||
|
|
||||||
|
Calendar today = Calendar.getInstance();
|
||||||
|
|
||||||
|
int age = today.get(Calendar.YEAR) - birthdayCalendar.get(Calendar.YEAR);
|
||||||
|
|
||||||
|
// Check if the birthday hasn't occurred yet this year
|
||||||
|
if (today.get(Calendar.DAY_OF_YEAR) < birthdayCalendar.get(Calendar.DAY_OF_YEAR)) {
|
||||||
|
age--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the profiles configuration
|
* Validates the profiles configuration
|
||||||
*
|
*
|
||||||
@ -99,10 +122,33 @@ public class BirthdayProfile extends Serializable {
|
|||||||
if (birthdays == null) {
|
if (birthdays == null) {
|
||||||
birthdays = new HashMap<>();
|
birthdays = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> toRemove = new ArrayList<>();
|
||||||
|
Guild discordGuild = guild.getDiscordGuild();
|
||||||
|
for (Map.Entry<String, Date> entry : birthdays.entrySet()) {
|
||||||
|
String userId = entry.getKey();
|
||||||
|
Date birthday = entry.getValue();
|
||||||
|
|
||||||
|
if (userId == null || birthday == null) { // this should never happen
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user is still in the guild, if not remove them
|
||||||
|
Member member = discordGuild.getMemberById(userId);
|
||||||
|
if (member == null) {
|
||||||
|
toRemove.add(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String userId : toRemove) {
|
||||||
|
birthdays.remove(userId);
|
||||||
|
}
|
||||||
|
|
||||||
if (channelId == null) {
|
if (channelId == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (guild.getDiscordGuild().getTextChannelById(channelId) == null) {
|
|
||||||
|
if (discordGuild.getTextChannelById(channelId) == null) {
|
||||||
channelId = null;
|
channelId = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -124,10 +170,13 @@ public class BirthdayProfile extends Serializable {
|
|||||||
int todayDay = today.get(Calendar.DAY_OF_MONTH);
|
int todayDay = today.get(Calendar.DAY_OF_MONTH);
|
||||||
int todayMonth = today.get(Calendar.MONTH); // Note: January is 0
|
int todayMonth = today.get(Calendar.MONTH); // Note: January is 0
|
||||||
|
|
||||||
for (Map.Entry<String, UserBirthday> entry : birthdays.entrySet()) {
|
Iterator<Map.Entry<String, Date>> iterator = birthdays.entrySet().iterator();
|
||||||
Date birthday = entry.getValue().getBirthday();
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<String, Date> entry = iterator.next();
|
||||||
|
Date birthday = entry.getValue();
|
||||||
|
|
||||||
if (birthday == null) {
|
if (birthday == null) {
|
||||||
|
iterator.remove();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +223,7 @@ public class BirthdayProfile extends Serializable {
|
|||||||
public String getBirthdayMessage(User user) {
|
public String getBirthdayMessage(User user) {
|
||||||
return message
|
return message
|
||||||
.replace("{user}", user.getAsMention())
|
.replace("{user}", user.getAsMention())
|
||||||
.replace("{age}", String.valueOf(birthdays.get(user.getId()).calculateAge()));
|
.replace("{age}", String.valueOf(calculateAge(user.getId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -182,27 +231,4 @@ public class BirthdayProfile extends Serializable {
|
|||||||
birthdays.clear();
|
birthdays.clear();
|
||||||
channelId = null;
|
channelId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
birthdays = new HashMap<>();
|
|
||||||
for (String key : document.keySet()) {
|
|
||||||
UserBirthday userBirthday = new UserBirthday();
|
|
||||||
userBirthday.load((Document) document.get(key), gson);
|
|
||||||
birthdays.put(key, userBirthday);
|
|
||||||
}
|
|
||||||
channelId = document.getString("channelId");
|
|
||||||
message = (String) document.getOrDefault("message", DEFAULT_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
for (String key : birthdays.keySet()) {
|
|
||||||
document.put(key, birthdays.get(key).serialize(gson));
|
|
||||||
}
|
|
||||||
document.put("channelId", channelId);
|
|
||||||
document.put("message", message);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.Category;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
|
||||||
import cc.fascinated.bat.features.namehistory.command.NameHistoryCommand;
|
|
||||||
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 NameHistoryFeature extends Feature {
|
|
||||||
public static final int NAME_HISTORY_SIZE = 25;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public NameHistoryFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
|
||||||
super("Name History", true,Category.UTILITY);
|
|
||||||
|
|
||||||
super.registerCommand(commandService, context.getBean(NameHistoryCommand.class));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.event.EventListener;
|
|
||||||
import cc.fascinated.bat.features.namehistory.profile.user.NameHistoryProfile;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
|
|
||||||
import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class NameHistoryListener implements EventListener {
|
|
||||||
private final GuildService guildService;
|
|
||||||
private final FeatureService featureService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public NameHistoryListener(@NonNull GuildService guildService, @NonNull FeatureService featureService) {
|
|
||||||
this.guildService = guildService;
|
|
||||||
this.featureService = featureService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUserUpdateGlobalName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateGlobalNameEvent event) {
|
|
||||||
NameHistoryProfile profile = user.getNameHistoryProfile();
|
|
||||||
profile.addName(newName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGuildMemberUpdateNickname(@NonNull BatGuild guild, @NonNull BatUser user, String oldName, String newName,
|
|
||||||
@NonNull GuildMemberUpdateNicknameEvent event) {
|
|
||||||
NameHistoryFeature nameHistoryFeature = featureService.getFeature(NameHistoryFeature.class);
|
|
||||||
if (!guild.getFeatureProfile().isFeatureEnabled(nameHistoryFeature)) { // Check if the feature is enabled
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cc.fascinated.bat.features.namehistory.profile.guild.NameHistoryProfile profile = guild.getNameHistoryProfile();
|
|
||||||
profile.addName(user, newName);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Getter @Setter
|
|
||||||
public class TrackedName extends Serializable {
|
|
||||||
/**
|
|
||||||
* The new name of the user
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The date the name was changed
|
|
||||||
*/
|
|
||||||
private Date changedDate;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.name = document.getString("name");
|
|
||||||
this.changedDate = document.getDate("changedDate");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
document.put("name", this.name);
|
|
||||||
document.put("changedDate", this.changedDate);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory.command;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.features.namehistory.TrackedName;
|
|
||||||
import cc.fascinated.bat.features.namehistory.profile.guild.NameHistoryProfile;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.UserService;
|
|
||||||
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.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component("namehistory:guild.sub")
|
|
||||||
@CommandInfo(name = "guild", description = "View the guild nickname history of a user")
|
|
||||||
public class GuildSubCommand extends BatSubCommand {
|
|
||||||
private final UserService userService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public GuildSubCommand(@NonNull UserService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
super.addOption(OptionType.USER, "user", "The user to view the name history of", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
OptionMapping userOption = event.getOption("user");
|
|
||||||
BatUser target = userOption == null ? user : userService.getUser(userOption.getAsUser().getId());
|
|
||||||
if (target == null) {
|
|
||||||
channel.sendMessage("User not found").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NameHistoryProfile profile = guild.getNameHistoryProfile();
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
if (profile.getNameHistory(target).isEmpty()) {
|
|
||||||
builder.append("%s has no name history".formatted(target.getDiscordUser().getAsMention()));
|
|
||||||
} else {
|
|
||||||
for (TrackedName trackedName : profile.getNameHistorySorted(target)) {
|
|
||||||
builder.append("%s - <t:%s>\n".formatted(
|
|
||||||
trackedName.getName() == null ? "Removed Nickname" : "`%s`".formatted(trackedName.getName()),
|
|
||||||
trackedName.getChangedDate().toInstant().toEpochMilli()/1000
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
.setAuthor("%s's Nickname History in %s".formatted(target.getName(), guild.getName()))
|
|
||||||
.setDescription(builder.toString())
|
|
||||||
.build()
|
|
||||||
).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory.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 = "namehistory", description = "View the name history of a user")
|
|
||||||
public class NameHistoryCommand extends BatCommand {
|
|
||||||
@Autowired
|
|
||||||
public NameHistoryCommand(@NonNull ApplicationContext context) {
|
|
||||||
super.addSubCommand(context.getBean(UserSubCommand.class));
|
|
||||||
super.addSubCommand(context.getBean(GuildSubCommand.class));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory.command;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.features.namehistory.TrackedName;
|
|
||||||
import cc.fascinated.bat.features.namehistory.profile.user.NameHistoryProfile;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.UserService;
|
|
||||||
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.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component("namehistory:user.sub")
|
|
||||||
@CommandInfo(name = "user", description = "View the global name history of a user", guildOnly = false)
|
|
||||||
public class UserSubCommand extends BatSubCommand {
|
|
||||||
private final UserService userService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public UserSubCommand(@NonNull UserService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
super.addOption(OptionType.USER, "user", "The user to view the name history of", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
OptionMapping userOption = event.getOption("user");
|
|
||||||
BatUser target = userOption == null ? user : userService.getUser(userOption.getAsUser().getId());
|
|
||||||
if (target == null) {
|
|
||||||
channel.sendMessage("User not found").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NameHistoryProfile profile = target.getNameHistoryProfile();
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
if (profile.getNameHistory().isEmpty()) {
|
|
||||||
builder.append("%s has no name history".formatted(target.getDiscordUser().getAsMention()));
|
|
||||||
} else {
|
|
||||||
for (TrackedName trackedName : profile.getNameHistorySorted()) {
|
|
||||||
builder.append("`%s` - <t:%s>\n".formatted(trackedName.getName(), trackedName.getChangedDate().toInstant().toEpochMilli()/1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
.setAuthor("%s's Global Name History".formatted(target.getName()))
|
|
||||||
.setDescription(builder.toString())
|
|
||||||
.build()
|
|
||||||
).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory.profile.guild;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
|
||||||
import cc.fascinated.bat.features.namehistory.NameHistoryFeature;
|
|
||||||
import cc.fascinated.bat.features.namehistory.TrackedName;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class NameHistoryProfile extends Serializable {
|
|
||||||
/**
|
|
||||||
* The name history of the user
|
|
||||||
*/
|
|
||||||
private Map<String, List<TrackedName>> nameHistory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name history of the user
|
|
||||||
*
|
|
||||||
* @param user the user to get the name history of
|
|
||||||
* @return the name history of the user
|
|
||||||
*/
|
|
||||||
public List<TrackedName> getNameHistory(BatUser user) {
|
|
||||||
if (this.nameHistory == null) {
|
|
||||||
this.nameHistory = new HashMap<>();
|
|
||||||
}
|
|
||||||
if (!this.nameHistory.containsKey(user.getId())) {
|
|
||||||
this.nameHistory.put(user.getId(), new LinkedList<>());
|
|
||||||
}
|
|
||||||
return this.nameHistory.get(user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name history of the user sorted
|
|
||||||
*
|
|
||||||
* @param user the user to get the name history of
|
|
||||||
* @return the name history of the user sorted
|
|
||||||
*/
|
|
||||||
public List<TrackedName> getNameHistorySorted(BatUser user) {
|
|
||||||
return getNameHistory(user).stream().sorted((o1, o2) -> o2.getChangedDate().compareTo(o1.getChangedDate())).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a name to the name history
|
|
||||||
*
|
|
||||||
* @param user the user to add the name to
|
|
||||||
* @param name the name to add
|
|
||||||
*/
|
|
||||||
public void addName(BatUser user, String name) {
|
|
||||||
TrackedName trackedName = new TrackedName();
|
|
||||||
trackedName.setName(name);
|
|
||||||
trackedName.setChangedDate(new Date());
|
|
||||||
getNameHistory(user).add(trackedName);
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans up the name history
|
|
||||||
* <p>
|
|
||||||
* This will remove any names that are not within
|
|
||||||
* the size limit of the name history
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
private void cleanup() {
|
|
||||||
for (String userId : this.nameHistory.keySet()) {
|
|
||||||
List<TrackedName> trackedNames = this.nameHistory.get(userId);
|
|
||||||
if (trackedNames.size() > NameHistoryFeature.NAME_HISTORY_SIZE) {
|
|
||||||
trackedNames.sort((o1, o2) -> o2.getChangedDate().compareTo(o1.getChangedDate()));
|
|
||||||
trackedNames.subList(NameHistoryFeature.NAME_HISTORY_SIZE, trackedNames.size()).clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
this.nameHistory = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.nameHistory = new HashMap<>();
|
|
||||||
for (String key : document.keySet()) {
|
|
||||||
List<TrackedName> trackedNames = new LinkedList<>();
|
|
||||||
for (Document trackedNameDocument : (List<Document>) document.get(key)) {
|
|
||||||
TrackedName trackedName = new TrackedName();
|
|
||||||
trackedName.load(trackedNameDocument, gson);
|
|
||||||
trackedNames.add(trackedName);
|
|
||||||
}
|
|
||||||
this.nameHistory.put(key, trackedNames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
for (String key : this.nameHistory.keySet()) {
|
|
||||||
List<Document> trackedNames = new LinkedList<>();
|
|
||||||
for (TrackedName trackedName : this.nameHistory.get(key)) {
|
|
||||||
trackedNames.add(trackedName.serialize(gson));
|
|
||||||
}
|
|
||||||
document.put(key, trackedNames);
|
|
||||||
}
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.namehistory.profile.user;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
|
||||||
import cc.fascinated.bat.features.namehistory.NameHistoryFeature;
|
|
||||||
import cc.fascinated.bat.features.namehistory.TrackedName;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class NameHistoryProfile extends Serializable {
|
|
||||||
/**
|
|
||||||
* The name history of the user
|
|
||||||
*/
|
|
||||||
private List<TrackedName> nameHistory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name history of the user
|
|
||||||
*
|
|
||||||
* @return the name history of the user
|
|
||||||
*/
|
|
||||||
public List<TrackedName> getNameHistory() {
|
|
||||||
if (this.nameHistory == null) {
|
|
||||||
this.nameHistory = new LinkedList<>();
|
|
||||||
}
|
|
||||||
return nameHistory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name history of the user sorted
|
|
||||||
*
|
|
||||||
* @return the name history of the user sorted
|
|
||||||
*/
|
|
||||||
public List<TrackedName> getNameHistorySorted() {
|
|
||||||
return getNameHistory().stream().sorted((o1, o2) -> o2.getChangedDate().compareTo(o1.getChangedDate())).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a name to the name history
|
|
||||||
*
|
|
||||||
* @param name the name to add
|
|
||||||
*/
|
|
||||||
public void addName(String name) {
|
|
||||||
if (this.nameHistory == null) {
|
|
||||||
this.nameHistory = new LinkedList<>();
|
|
||||||
}
|
|
||||||
TrackedName trackedName = new TrackedName();
|
|
||||||
trackedName.setName(name);
|
|
||||||
trackedName.setChangedDate(new Date());
|
|
||||||
this.nameHistory.add(trackedName);
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans up the name history
|
|
||||||
* <p>
|
|
||||||
* This will remove any names that are not within
|
|
||||||
* the size limit of the name history
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
private void cleanup() {
|
|
||||||
if (this.nameHistory.size() > NameHistoryFeature.NAME_HISTORY_SIZE) {
|
|
||||||
List<TrackedName> trackedNames = new ArrayList<>(this.nameHistory);
|
|
||||||
trackedNames.sort((o1, o2) -> o2.getChangedDate().compareTo(o1.getChangedDate()));
|
|
||||||
this.nameHistory = trackedNames.subList(0, NameHistoryFeature.NAME_HISTORY_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
this.nameHistory = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.nameHistory = new LinkedList<>();
|
|
||||||
for (Document trackedNameDocument : document.getList("nameHistory", Document.class, new ArrayList<>())) {
|
|
||||||
TrackedName trackedName = new TrackedName();
|
|
||||||
trackedName.load(trackedNameDocument, gson);
|
|
||||||
|
|
||||||
this.nameHistory.add(trackedName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
List<Document> trackedNames = new ArrayList<>();
|
|
||||||
for (TrackedName trackedName : this.nameHistory) {
|
|
||||||
Document trackedNameDocument = new Document();
|
|
||||||
trackedNameDocument.put("name", trackedName.getName());
|
|
||||||
trackedNameDocument.put("changedDate", trackedName.getChangedDate());
|
|
||||||
trackedNames.add(trackedNameDocument);
|
|
||||||
}
|
|
||||||
document.put("nameHistory", trackedNames);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +1,14 @@
|
|||||||
package cc.fascinated.bat.features.scoresaber;
|
package cc.fascinated.bat.features.scoresaber;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.NumberFormatter;
|
import cc.fascinated.bat.common.NumberUtils;
|
||||||
import cc.fascinated.bat.event.EventListener;
|
import cc.fascinated.bat.event.EventListener;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.NumberOneScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.GuildNumberOneScoreFeedProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberLeaderboardToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberLeaderboardToken;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberPlayerScoreToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberPlayerScoreToken;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberScoreToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberScoreToken;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
@ -25,12 +23,10 @@ import org.springframework.stereotype.Component;
|
|||||||
@Log4j2
|
@Log4j2
|
||||||
public class NumberOneScoreFeedListener implements EventListener {
|
public class NumberOneScoreFeedListener implements EventListener {
|
||||||
private final GuildService guildService;
|
private final GuildService guildService;
|
||||||
private final FeatureService featureService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public NumberOneScoreFeedListener(@NonNull GuildService guildService, @NonNull FeatureService featureService) {
|
public NumberOneScoreFeedListener(GuildService guildService) {
|
||||||
this.guildService = guildService;
|
this.guildService = guildService;
|
||||||
this.featureService = featureService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -45,7 +41,7 @@ public class NumberOneScoreFeedListener implements EventListener {
|
|||||||
log.info("A new #1 score has been set by {} on {} ({})!",
|
log.info("A new #1 score has been set by {} on {} ({})!",
|
||||||
player.getName(),
|
player.getName(),
|
||||||
leaderboard.getSongName(),
|
leaderboard.getSongName(),
|
||||||
"%s⭐".formatted(NumberFormatter.formatCommas(leaderboard.getStars()))
|
"%s⭐".formatted(NumberUtils.formatNumberCommas(leaderboard.getStars()))
|
||||||
);
|
);
|
||||||
|
|
||||||
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
||||||
@ -53,20 +49,16 @@ public class NumberOneScoreFeedListener implements EventListener {
|
|||||||
if (batGuild == null) {
|
if (batGuild == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ScoreSaberFeature scoreSaberFeature = featureService.getFeature(ScoreSaberFeature.class);
|
GuildNumberOneScoreFeedProfile profile = batGuild.getProfile(GuildNumberOneScoreFeedProfile.class);
|
||||||
if (!batGuild.getFeatureProfile().isFeatureEnabled(scoreSaberFeature)) { // Check if the feature is enabled
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NumberOneScoreFeedProfile profile = batGuild.getProfile(NumberOneScoreFeedProfile.class);
|
|
||||||
if (profile == null || profile.getChannelId() == null) {
|
if (profile == null || profile.getChannelId() == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextChannel channel = profile.getTextChannel();
|
TextChannel channel = profile.getAsTextChannel();
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
log.error("Scoresaber user feed channel is null for guild {}, removing the stored channel.", guild.getId());
|
log.error("Scoresaber user feed channel is null for guild {}, removing the stored channel.", guild.getId());
|
||||||
profile.setChannelId(null);
|
profile.setChannelId(null);
|
||||||
|
guildService.saveGuild(batGuild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
channel.sendMessageEmbeds(ScoreSaberFeature.buildScoreEmbed(score)).queue();
|
channel.sendMessageEmbeds(ScoreSaberFeature.buildScoreEmbed(score)).queue();
|
||||||
|
@ -3,7 +3,7 @@ package cc.fascinated.bat.features.scoresaber;
|
|||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
||||||
import cc.fascinated.bat.common.DateUtils;
|
import cc.fascinated.bat.common.DateUtils;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.NumberFormatter;
|
import cc.fascinated.bat.common.NumberUtils;
|
||||||
import cc.fascinated.bat.common.ScoreSaberUtils;
|
import cc.fascinated.bat.common.ScoreSaberUtils;
|
||||||
import cc.fascinated.bat.features.Feature;
|
import cc.fascinated.bat.features.Feature;
|
||||||
import cc.fascinated.bat.features.scoresaber.command.numberone.NumberOneFeedCommand;
|
import cc.fascinated.bat.features.scoresaber.command.numberone.NumberOneFeedCommand;
|
||||||
@ -26,7 +26,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class ScoreSaberFeature extends Feature {
|
public class ScoreSaberFeature extends Feature {
|
||||||
@Autowired
|
@Autowired
|
||||||
public ScoreSaberFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
public ScoreSaberFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
super("ScoreSaber", true, Category.BEAT_SABER);
|
super("ScoreSaber", Category.BEAT_SABER);
|
||||||
|
|
||||||
registerCommand(commandService, context.getBean(ScoreSaberCommand.class));
|
registerCommand(commandService, context.getBean(ScoreSaberCommand.class));
|
||||||
registerCommand(commandService, context.getBean(UserFeedCommand.class));
|
registerCommand(commandService, context.getBean(UserFeedCommand.class));
|
||||||
@ -55,10 +55,10 @@ public class ScoreSaberFeature extends Feature {
|
|||||||
);
|
);
|
||||||
|
|
||||||
String accuracy = leaderboardToken.getMaxScore() == 0 ? "N/A" :
|
String accuracy = leaderboardToken.getMaxScore() == 0 ? "N/A" :
|
||||||
String.format("%s%%", NumberFormatter.formatCommas(((double) scoreToken.getBaseScore() / leaderboardToken.getMaxScore()) * 100));
|
String.format("%s%%", NumberUtils.formatNumberCommas(((double) scoreToken.getBaseScore() / leaderboardToken.getMaxScore()) * 100));
|
||||||
|
|
||||||
String rawPp = scoreToken.getPp() == 0 ? "Unranked" : NumberFormatter.formatCommas(scoreToken.getPp());
|
String rawPp = scoreToken.getPp() == 0 ? "Unranked" : NumberUtils.formatNumberCommas(scoreToken.getPp());
|
||||||
String rank = String.format("#%s", NumberFormatter.formatCommas(scoreToken.getRank()));
|
String rank = String.format("#%s", NumberUtils.formatNumberCommas(scoreToken.getRank()));
|
||||||
String misses = String.format("%s", scoreToken.getMissedNotes());
|
String misses = String.format("%s", scoreToken.getMissedNotes());
|
||||||
String badCuts = String.format("%s", scoreToken.getBadCuts());
|
String badCuts = String.format("%s", scoreToken.getBadCuts());
|
||||||
String maxCombo = String.format("%s %s",
|
String maxCombo = String.format("%s %s",
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package cc.fascinated.bat.features.scoresaber;
|
package cc.fascinated.bat.features.scoresaber;
|
||||||
|
|
||||||
import cc.fascinated.bat.event.EventListener;
|
import cc.fascinated.bat.event.EventListener;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.UserScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.GuildUserScoreFeedProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberLeaderboardToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberLeaderboardToken;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberPlayerScoreToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberPlayerScoreToken;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberScoreToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberScoreToken;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
import cc.fascinated.bat.service.FeatureService;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
@ -24,12 +22,10 @@ import org.springframework.stereotype.Component;
|
|||||||
@Log4j2
|
@Log4j2
|
||||||
public class UserScoreFeedListener implements EventListener {
|
public class UserScoreFeedListener implements EventListener {
|
||||||
private final GuildService guildService;
|
private final GuildService guildService;
|
||||||
private final FeatureService featureService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public UserScoreFeedListener(@NonNull GuildService guildService, @NonNull FeatureService featureService) {
|
public UserScoreFeedListener(GuildService guildService) {
|
||||||
this.guildService = guildService;
|
this.guildService = guildService;
|
||||||
this.featureService = featureService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -40,19 +36,16 @@ public class UserScoreFeedListener implements EventListener {
|
|||||||
if (batGuild == null) {
|
if (batGuild == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ScoreSaberFeature scoreSaberFeature = featureService.getFeature(ScoreSaberFeature.class);
|
GuildUserScoreFeedProfile profile = batGuild.getProfile(GuildUserScoreFeedProfile.class);
|
||||||
if (!batGuild.getFeatureProfile().isFeatureEnabled(scoreSaberFeature)) { // Check if the feature is enabled
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UserScoreFeedProfile profile = batGuild.getProfile(UserScoreFeedProfile.class);
|
|
||||||
if (profile == null || profile.getChannelId() == null || !profile.getTrackedUsers().contains(player.getId())) {
|
if (profile == null || profile.getChannelId() == null || !profile.getTrackedUsers().contains(player.getId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextChannel channel = profile.getTextChannel();
|
TextChannel channel = profile.getAsTextChannel();
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
log.error("Scoresaber user feed channel is null for guild {}, removing the stored channel.", guild.getId());
|
log.error("Scoresaber user feed channel is null for guild {}, removing the stored channel.", guild.getId());
|
||||||
profile.setChannelId(null);
|
profile.setChannelId(null);
|
||||||
|
guildService.saveGuild(batGuild);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
channel.sendMessageEmbeds(ScoreSaberFeature.buildScoreEmbed(score)).queue();
|
channel.sendMessageEmbeds(ScoreSaberFeature.buildScoreEmbed(score)).queue();
|
||||||
|
@ -4,9 +4,10 @@ import cc.fascinated.bat.command.BatSubCommand;
|
|||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.TextChannelUtils;
|
import cc.fascinated.bat.common.TextChannelUtils;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.NumberOneScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.GuildNumberOneScoreFeedProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
||||||
@ -24,23 +25,26 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("scoresaber-number-one-feed:channel.sub")
|
@Component("scoresaber-number-one-feed:channel.sub")
|
||||||
@CommandInfo(name = "channel", description = "Sets the feed channel")
|
@CommandInfo(name = "channel", description = "Sets the feed channel")
|
||||||
public class ChannelSubCommand extends BatSubCommand {
|
public class ChannelSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ChannelSubCommand() {
|
public ChannelSubCommand(GuildService guildService) {
|
||||||
super.addOption(OptionType.CHANNEL, "channel", "The channel scores are sent in", false);
|
super.addOption(OptionType.CHANNEL, "channel", "The channel scores are sent in", false);
|
||||||
|
this.guildService = guildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
NumberOneScoreFeedProfile profile = guild.getProfile(NumberOneScoreFeedProfile.class);
|
GuildNumberOneScoreFeedProfile profile = guild.getProfile(GuildNumberOneScoreFeedProfile.class);
|
||||||
OptionMapping option = event.getOption("channel");
|
OptionMapping option = interaction.getOption("channel");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("There is no channel set for the feed notifications.")
|
.setDescription("There is no channel set for the feed notifications.")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("The current feed channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
.setDescription("The current feed channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -48,14 +52,16 @@ public class ChannelSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
GuildChannelUnion targetChannel = option.getAsChannel();
|
GuildChannelUnion targetChannel = option.getAsChannel();
|
||||||
if (targetChannel.getType() != ChannelType.TEXT) {
|
if (targetChannel.getType() != ChannelType.TEXT) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Invalid channel type, please provide a text channel")
|
.setDescription("Invalid channel type, please provide a text channel")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.setChannelId(targetChannel.getId());
|
profile.setChannelId(targetChannel.getId());
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully set the feed channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
.setDescription("Successfully set the feed channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,15 @@ package cc.fascinated.bat.features.scoresaber.command.numberone;
|
|||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.NumberOneScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.GuildNumberOneScoreFeedProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,12 +20,20 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("scoresaber-number-one-feed:reset.sub")
|
@Component("scoresaber-number-one-feed:reset.sub")
|
||||||
@CommandInfo(name = "reset", description = "Resets the settings")
|
@CommandInfo(name = "reset", description = "Resets the settings")
|
||||||
public class ResetSubCommand extends BatSubCommand {
|
public class ResetSubCommand extends BatSubCommand {
|
||||||
@Override
|
private final GuildService guildService;
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
NumberOneScoreFeedProfile profile = guild.getProfile(NumberOneScoreFeedProfile.class);
|
|
||||||
profile.reset();
|
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
@Autowired
|
||||||
|
public ResetSubCommand(GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
||||||
|
GuildNumberOneScoreFeedProfile profile = guild.getProfile(GuildNumberOneScoreFeedProfile.class);
|
||||||
|
profile.reset();
|
||||||
|
guildService.saveGuild(guild);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully reset the settings.")
|
.setDescription("Successfully reset the settings.")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@ package cc.fascinated.bat.features.scoresaber.command.scoresaber;
|
|||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.features.scoresaber.profile.UserScoreSaberProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberAccountToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberAccountToken;
|
||||||
import cc.fascinated.bat.service.ScoreSaberService;
|
import cc.fascinated.bat.service.ScoreSaberService;
|
||||||
|
import cc.fascinated.bat.service.UserService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
@ -23,18 +25,20 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "link", description = "Links your ScoreSaber profile")
|
@CommandInfo(name = "link", description = "Links your ScoreSaber profile")
|
||||||
public class LinkSubCommand extends BatSubCommand {
|
public class LinkSubCommand extends BatSubCommand {
|
||||||
private final ScoreSaberService scoreSaberService;
|
private final ScoreSaberService scoreSaberService;
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LinkSubCommand(@NonNull ScoreSaberService scoreSaberService) {
|
public LinkSubCommand(@NonNull ScoreSaberService scoreSaberService, @NonNull UserService userService) {
|
||||||
super.addOption(OptionType.STRING, "link", "Link your ScoreSaber profile", true);
|
super.addOption(OptionType.STRING, "link", "Link your ScoreSaber profile", true);
|
||||||
this.scoreSaberService = scoreSaberService;
|
this.scoreSaberService = scoreSaberService;
|
||||||
|
this.userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
OptionMapping option = event.getOption("link");
|
OptionMapping option = interaction.getOption("link");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Please provide a ScoreSaber profile link")
|
.setDescription("Please provide a ScoreSaber profile link")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -42,7 +46,7 @@ public class LinkSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
String link = option.getAsString();
|
String link = option.getAsString();
|
||||||
if (!link.contains("scoresaber.com/u/")) {
|
if (!link.contains("scoresaber.com/u/")) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Invalid ScoreSaber profile link")
|
.setDescription("Invalid ScoreSaber profile link")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -55,14 +59,15 @@ public class LinkSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
ScoreSaberAccountToken account = scoreSaberService.getAccount(id);
|
ScoreSaberAccountToken account = scoreSaberService.getAccount(id);
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Invalid ScoreSaber profile link")
|
.setDescription("Invalid ScoreSaber profile link")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.getScoreSaberProfile().setAccountId(id);
|
user.getProfile(UserScoreSaberProfile.class).setSteamId(id);
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
userService.saveUser(user);
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully linked your [ScoreSaber](%s) profile".formatted("https://scoresaber.com/u/%s".formatted(id)))
|
.setDescription("Successfully linked your [ScoreSaber](%s) profile".formatted("https://scoresaber.com/u/%s".formatted(id)))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class MeSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
ScoreSaberCommand.sendProfileEmbed(true, user, scoreSaberService, event);
|
ScoreSaberCommand.sendProfileEmbed(true, user, scoreSaberService, interaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,15 @@ package cc.fascinated.bat.features.scoresaber.command.scoresaber;
|
|||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.user.ScoreSaberProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.UserScoreSaberProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.UserService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,12 +20,20 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("scoresaber:reset.sub")
|
@Component("scoresaber:reset.sub")
|
||||||
@CommandInfo(name = "reset", description = "Reset your settings")
|
@CommandInfo(name = "reset", description = "Reset your settings")
|
||||||
public class ResetSubCommand extends BatSubCommand {
|
public class ResetSubCommand extends BatSubCommand {
|
||||||
@Override
|
private final UserService userService;
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction event) {
|
|
||||||
ScoreSaberProfile profile = user.getScoreSaberProfile();
|
|
||||||
profile.reset();
|
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
@Autowired
|
||||||
|
public ResetSubCommand(@NonNull UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
||||||
|
UserScoreSaberProfile profile = guild.getProfile(UserScoreSaberProfile.class);
|
||||||
|
profile.reset();
|
||||||
|
userService.saveUser(user);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully reset your settings.")
|
.setDescription("Successfully reset your settings.")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ import cc.fascinated.bat.command.CommandInfo;
|
|||||||
import cc.fascinated.bat.common.Colors;
|
import cc.fascinated.bat.common.Colors;
|
||||||
import cc.fascinated.bat.common.DateUtils;
|
import cc.fascinated.bat.common.DateUtils;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.NumberFormatter;
|
import cc.fascinated.bat.common.NumberUtils;
|
||||||
import cc.fascinated.bat.exception.RateLimitException;
|
import cc.fascinated.bat.exception.RateLimitException;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.user.ScoreSaberProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.UserScoreSaberProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberAccountToken;
|
import cc.fascinated.bat.model.token.beatsaber.scoresaber.ScoreSaberAccountToken;
|
||||||
@ -49,8 +49,8 @@ public class ScoreSaberCommand extends BatCommand {
|
|||||||
* @param interaction The interaction
|
* @param interaction The interaction
|
||||||
*/
|
*/
|
||||||
public static void sendProfileEmbed(boolean isSelf, BatUser user, ScoreSaberService scoreSaberService, SlashCommandInteraction interaction) {
|
public static void sendProfileEmbed(boolean isSelf, BatUser user, ScoreSaberService scoreSaberService, SlashCommandInteraction interaction) {
|
||||||
ScoreSaberProfile profile = user.getScoreSaberProfile();
|
UserScoreSaberProfile profile = user.getProfile(UserScoreSaberProfile.class);
|
||||||
if (profile.getAccountId() == null) {
|
if (profile.getSteamId() == null) {
|
||||||
if (!isSelf) {
|
if (!isSelf) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("%s does not have a linked ScoreSaber account".formatted(user.getDiscordUser().getAsMention()))
|
.setDescription("%s does not have a linked ScoreSaber account".formatted(user.getDiscordUser().getAsMention()))
|
||||||
@ -64,7 +64,7 @@ public class ScoreSaberCommand extends BatCommand {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
long before = System.currentTimeMillis();
|
long before = System.currentTimeMillis();
|
||||||
ScoreSaberAccountToken account = scoreSaberService.getAccount(profile.getAccountId());
|
ScoreSaberAccountToken account = scoreSaberService.getAccount(profile.getSteamId());
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
if (!isSelf) {
|
if (!isSelf) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
@ -84,9 +84,9 @@ public class ScoreSaberCommand extends BatCommand {
|
|||||||
"https://cdn.scoresaber.com/avatars/%s.jpg".formatted(account.getId()))
|
"https://cdn.scoresaber.com/avatars/%s.jpg".formatted(account.getId()))
|
||||||
.addField("Name", account.getName(), true)
|
.addField("Name", account.getName(), true)
|
||||||
.addField("Country", account.getCountry(), true)
|
.addField("Country", account.getCountry(), true)
|
||||||
.addField("Rank", "#" + NumberFormatter.formatCommas(account.getRank()), true)
|
.addField("Rank", "#" + NumberUtils.formatNumberCommas(account.getRank()), true)
|
||||||
.addField("Country Rank", "#" + NumberFormatter.formatCommas(account.getCountryRank()), true)
|
.addField("Country Rank", "#" + NumberUtils.formatNumberCommas(account.getCountryRank()), true)
|
||||||
.addField("PP", NumberFormatter.formatCommas(account.getPp()), true)
|
.addField("PP", NumberUtils.formatNumberCommas(account.getPp()), true)
|
||||||
.addField("Joined", "<t:%s>".formatted(DateUtils.getDateFromString(account.getFirstSeen()).toInstant().toEpochMilli() / 1000), true)
|
.addField("Joined", "<t:%s>".formatted(DateUtils.getDateFromString(account.getFirstSeen()).toInstant().toEpochMilli() / 1000), true)
|
||||||
.setTimestamp(LocalDateTime.now())
|
.setTimestamp(LocalDateTime.now())
|
||||||
.setFooter(fetchTime > 3 ? "Fetched in %sms".formatted(fetchTime) : "Cached", "https://flagcdn.com/h120/%s.png".formatted(account.getCountry().toLowerCase()))
|
.setFooter(fetchTime > 3 ? "Fetched in %sms".formatted(fetchTime) : "Cached", "https://flagcdn.com/h120/%s.png".formatted(account.getCountry().toLowerCase()))
|
||||||
@ -100,7 +100,7 @@ public class ScoreSaberCommand 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 interaction) {
|
||||||
sendProfileEmbed(true, user, scoreSaberService, event);
|
sendProfileEmbed(true, user, scoreSaberService, interaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,17 +33,17 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
OptionMapping option = event.getOption("user");
|
OptionMapping option = interaction.getOption("user");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Please provide a user to view the ScoreSaber profile of")
|
.setDescription("Please provide a user to view the ScoreSaber profile of")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option.getAsUser().isBot()) {
|
if (option.getAsUser().isBot()) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("You cannot view the ScoreSaber profile for a Bot")
|
.setDescription("You cannot view the ScoreSaber profile for a Bot")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -51,11 +51,11 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
BatUser target = userService.getUser(option.getAsUser().getId());
|
BatUser target = userService.getUser(option.getAsUser().getId());
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Unknown user")
|
.setDescription("Unknown user")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ScoreSaberCommand.sendProfileEmbed(false, target, scoreSaberService, event);
|
ScoreSaberCommand.sendProfileEmbed(false, target, scoreSaberService, interaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,10 @@ import cc.fascinated.bat.command.BatSubCommand;
|
|||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.TextChannelUtils;
|
import cc.fascinated.bat.common.TextChannelUtils;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.UserScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.GuildUserScoreFeedProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
||||||
@ -24,23 +25,26 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("scoresaber-user-feed:channel.sub")
|
@Component("scoresaber-user-feed:channel.sub")
|
||||||
@CommandInfo(name = "channel", description = "Sets the feed channel")
|
@CommandInfo(name = "channel", description = "Sets the feed channel")
|
||||||
public class ChannelSubCommand extends BatSubCommand {
|
public class ChannelSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ChannelSubCommand() {
|
public ChannelSubCommand(GuildService guildService) {
|
||||||
super.addOption(OptionType.CHANNEL, "channel", "The channel scores are sent in", false);
|
super.addOption(OptionType.CHANNEL, "channel", "The channel scores are sent in", false);
|
||||||
|
this.guildService = guildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
UserScoreFeedProfile profile = guild.getProfile(UserScoreFeedProfile.class);
|
GuildUserScoreFeedProfile profile = guild.getProfile(GuildUserScoreFeedProfile.class);
|
||||||
OptionMapping option = event.getOption("channel");
|
OptionMapping option = interaction.getOption("channel");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("There is no channel set for the feed notifications.")
|
.setDescription("There is no channel set for the feed notifications.")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("The current feed channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
.setDescription("The current feed channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -48,14 +52,16 @@ public class ChannelSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
GuildChannelUnion targetChannel = option.getAsChannel();
|
GuildChannelUnion targetChannel = option.getAsChannel();
|
||||||
if (targetChannel.getType() != ChannelType.TEXT) {
|
if (targetChannel.getType() != ChannelType.TEXT) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Invalid channel type, please provide a text channel")
|
.setDescription("Invalid channel type, please provide a text channel")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.setChannelId(targetChannel.getId());
|
profile.setChannelId(targetChannel.getId());
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully set the feed channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
.setDescription("Successfully set the feed channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,15 @@ package cc.fascinated.bat.features.scoresaber.command.userfeed;
|
|||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.UserScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.GuildUserScoreFeedProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,11 +20,20 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component("scoresaber-user-feed:reset.sub")
|
@Component("scoresaber-user-feed:reset.sub")
|
||||||
@CommandInfo(name = "reset", description = "Resets the settings")
|
@CommandInfo(name = "reset", description = "Resets the settings")
|
||||||
public class ResetSubCommand extends BatSubCommand {
|
public class ResetSubCommand extends BatSubCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ResetSubCommand(GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
UserScoreFeedProfile profile = guild.getProfile(UserScoreFeedProfile.class);
|
GuildUserScoreFeedProfile profile = guild.getProfile(GuildUserScoreFeedProfile.class);
|
||||||
profile.reset();
|
profile.reset();
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
guildService.saveGuild(guild);
|
||||||
|
|
||||||
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully reset the settings.")
|
.setDescription("Successfully reset the settings.")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package cc.fascinated.bat.features.scoresaber.command.userfeed;
|
|||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.command.BatSubCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.guild.UserScoreFeedProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.GuildUserScoreFeedProfile;
|
||||||
import cc.fascinated.bat.features.scoresaber.profile.user.ScoreSaberProfile;
|
import cc.fascinated.bat.features.scoresaber.profile.UserScoreSaberProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.model.BatUser;
|
||||||
import cc.fascinated.bat.service.GuildService;
|
import cc.fascinated.bat.service.GuildService;
|
||||||
@ -36,12 +36,12 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 interaction) {
|
||||||
UserScoreFeedProfile profile = guild.getProfile(UserScoreFeedProfile.class);
|
GuildUserScoreFeedProfile profile = guild.getProfile(GuildUserScoreFeedProfile.class);
|
||||||
OptionMapping option = event.getOption("user");
|
OptionMapping option = interaction.getOption("user");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
if (profile.getTrackedUsers().isEmpty()) {
|
if (profile.getTrackedUsers().isEmpty()) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("There are no users being tracked in the feed")
|
.setDescription("There are no users being tracked in the feed")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -53,7 +53,7 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
"https://scoresaber.com/u/%s".formatted(accountId)
|
"https://scoresaber.com/u/%s".formatted(accountId)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
event.replyEmbeds(EmbedUtils.genericEmbed()
|
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("The current users being tracked in the feed are:\n%s".formatted(stringBuilder.toString()))
|
.setDescription("The current users being tracked in the feed are:\n%s".formatted(stringBuilder.toString()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -61,27 +61,25 @@ public class UserSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
User target = option.getAsUser();
|
User target = option.getAsUser();
|
||||||
BatUser targetUser = userService.getUser(target.getId());
|
BatUser targetUser = userService.getUser(target.getId());
|
||||||
ScoreSaberProfile targetProfile = targetUser.getScoreSaberProfile();
|
UserScoreSaberProfile targetProfile = targetUser.getProfile(UserScoreSaberProfile.class);
|
||||||
if (targetProfile.getAccountId() == null) {
|
if (targetProfile.getSteamId() == null) {
|
||||||
event.replyEmbeds(EmbedUtils.errorEmbed()
|
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The user you are trying to track does not have a linked ScoreSaber profile")
|
.setDescription("The user you are trying to track does not have a linked ScoreSaber profile")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean added = false;
|
if (profile.getTrackedUsers().contains(targetProfile.getSteamId())) {
|
||||||
if (profile.isUserTracked(targetProfile.getAccountId())) {
|
profile.getTrackedUsers().remove(targetProfile.getSteamId());
|
||||||
profile.removeTrackedUser(targetProfile.getAccountId());
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Successfully removed %s from the feed".formatted(target.getAsMention()))
|
||||||
|
.build()).queue();
|
||||||
} else {
|
} else {
|
||||||
profile.addTrackedUser(targetProfile.getAccountId());
|
profile.getTrackedUsers().add(targetProfile.getSteamId());
|
||||||
added = true;
|
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
}
|
.setDescription("Successfully added %s to the feed".formatted(target.getAsMention()))
|
||||||
|
|
||||||
event.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("Successfully %s %s from the feed".formatted(
|
|
||||||
added ? "added" : "removed",
|
|
||||||
target.getAsMention()
|
|
||||||
))
|
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
||||||
|
guildService.saveGuild(guild);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package cc.fascinated.bat.features.scoresaber.profile;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.Profile;
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class GuildNumberOneScoreFeedProfile extends Profile {
|
||||||
|
/**
|
||||||
|
* The channel ID of the score feed
|
||||||
|
*/
|
||||||
|
private String channelId;
|
||||||
|
|
||||||
|
public GuildNumberOneScoreFeedProfile() {
|
||||||
|
super("scoresaber-number-one-score-feed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the channel as a TextChannel
|
||||||
|
*
|
||||||
|
* @return the channel as a TextChannel
|
||||||
|
*/
|
||||||
|
public TextChannel getAsTextChannel() {
|
||||||
|
return DiscordService.JDA.getTextChannelById(channelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
this.channelId = null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,10 @@
|
|||||||
package cc.fascinated.bat.features.scoresaber.profile.guild;
|
package cc.fascinated.bat.features.scoresaber.profile;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
import cc.fascinated.bat.common.Profile;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -17,8 +14,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
public class GuildUserScoreFeedProfile extends Profile {
|
||||||
public class UserScoreFeedProfile extends Serializable {
|
|
||||||
/**
|
/**
|
||||||
* The channel ID of the score feed
|
* The channel ID of the score feed
|
||||||
*/
|
*/
|
||||||
@ -29,6 +25,10 @@ public class UserScoreFeedProfile extends Serializable {
|
|||||||
*/
|
*/
|
||||||
private List<String> trackedUsers;
|
private List<String> trackedUsers;
|
||||||
|
|
||||||
|
public GuildUserScoreFeedProfile() {
|
||||||
|
super("scoresaber-user-score-feed");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the tracked users
|
* Gets the tracked users
|
||||||
*
|
*
|
||||||
@ -38,20 +38,7 @@ public class UserScoreFeedProfile extends Serializable {
|
|||||||
if (this.trackedUsers == null) {
|
if (this.trackedUsers == null) {
|
||||||
this.trackedUsers = new ArrayList<>();
|
this.trackedUsers = new ArrayList<>();
|
||||||
}
|
}
|
||||||
return trackedUsers;
|
return this.trackedUsers;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a user is being tracked
|
|
||||||
*
|
|
||||||
* @param userId the user ID to check
|
|
||||||
* @return if the user is being tracked
|
|
||||||
*/
|
|
||||||
public boolean isUserTracked(String userId) {
|
|
||||||
if (this.trackedUsers == null) {
|
|
||||||
this.trackedUsers = new ArrayList<>();
|
|
||||||
}
|
|
||||||
return trackedUsers.contains(userId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,7 +70,7 @@ public class UserScoreFeedProfile extends Serializable {
|
|||||||
*
|
*
|
||||||
* @return the channel as a TextChannel
|
* @return the channel as a TextChannel
|
||||||
*/
|
*/
|
||||||
public TextChannel getTextChannel() {
|
public TextChannel getAsTextChannel() {
|
||||||
return DiscordService.JDA.getTextChannelById(channelId);
|
return DiscordService.JDA.getTextChannelById(channelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,18 +79,4 @@ public class UserScoreFeedProfile extends Serializable {
|
|||||||
this.channelId = null;
|
this.channelId = null;
|
||||||
this.trackedUsers = null;
|
this.trackedUsers = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.channelId = document.getString("channelId");
|
|
||||||
this.trackedUsers = document.getList("trackedUsers", String.class, new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
document.put("channelId", this.channelId);
|
|
||||||
document.put("trackedUsers", this.trackedUsers);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package cc.fascinated.bat.features.scoresaber.profile;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.Profile;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
public class UserScoreSaberProfile extends Profile {
|
||||||
|
/**
|
||||||
|
* The Account ID of the ScoreSaber profile
|
||||||
|
*/
|
||||||
|
private String steamId;
|
||||||
|
|
||||||
|
public UserScoreSaberProfile() {
|
||||||
|
super("scoresaber");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
this.steamId = null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,49 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.scoresaber.profile.guild;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class NumberOneScoreFeedProfile extends Serializable {
|
|
||||||
/**
|
|
||||||
* The channel ID of the score feed
|
|
||||||
*/
|
|
||||||
private String channelId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the channel as a TextChannel
|
|
||||||
*
|
|
||||||
* @return the channel as a TextChannel
|
|
||||||
*/
|
|
||||||
public TextChannel getTextChannel() {
|
|
||||||
return DiscordService.JDA.getTextChannelById(channelId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
this.channelId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.channelId = document.getString("channelId");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
document.put("channelId", this.channelId);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package cc.fascinated.bat.features.scoresaber.profile.user;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Serializable;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class ScoreSaberProfile extends Serializable {
|
|
||||||
/**
|
|
||||||
* The Account ID of the ScoreSaber profile
|
|
||||||
*/
|
|
||||||
private String accountId;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
this.accountId = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void load(Document document, Gson gson) {
|
|
||||||
this.accountId = document.getString("accountId");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Document serialize(Gson gson) {
|
|
||||||
Document document = new Document();
|
|
||||||
document.put("accountId", this.accountId);
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +1,11 @@
|
|||||||
package cc.fascinated.bat.features.spotify;
|
package cc.fascinated.bat.features.spotify;
|
||||||
|
|
||||||
import cc.fascinated.bat.Emojis;
|
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.command.Category;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.SpotifyUtils;
|
|
||||||
import cc.fascinated.bat.exception.BatException;
|
|
||||||
import cc.fascinated.bat.features.Feature;
|
import cc.fascinated.bat.features.Feature;
|
||||||
import cc.fascinated.bat.features.spotify.command.SpotifyCommand;
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
import cc.fascinated.bat.features.spotify.profile.SpotifyProfile;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.CommandService;
|
|
||||||
import cc.fascinated.bat.service.SpotifyService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import se.michaelthelin.spotify.model_objects.miscellaneous.CurrentlyPlaying;
|
|
||||||
import se.michaelthelin.spotify.model_objects.specification.AlbumSimplified;
|
|
||||||
import se.michaelthelin.spotify.model_objects.specification.Image;
|
|
||||||
import se.michaelthelin.spotify.model_objects.specification.Track;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
@ -28,153 +13,18 @@ import se.michaelthelin.spotify.model_objects.specification.Track;
|
|||||||
@Component
|
@Component
|
||||||
public class SpotifyFeature extends Feature {
|
public class SpotifyFeature extends Feature {
|
||||||
@Autowired
|
@Autowired
|
||||||
public SpotifyFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
public SpotifyFeature() {
|
||||||
super("Spotify", true,Category.MUSIC);
|
super("Spotify", Category.MUSIC);
|
||||||
|
|
||||||
super.registerCommand(commandService, context.getBean(SpotifyCommand.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the currently playing song.
|
* The embed for when a user needs to link their Spotify account.
|
||||||
*
|
*
|
||||||
* @param spotifyService The Spotify service.
|
* @return The embed.
|
||||||
* @param user The user.
|
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
public static MessageEmbed linkAccountEmbed() {
|
||||||
public static EmbedBuilder currentSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) {
|
|
||||||
SpotifyProfile profile = user.getProfile(SpotifyProfile.class);
|
|
||||||
if (!profile.hasLinkedAccount()) {
|
|
||||||
throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spotifyService.hasTrackPlaying(user)) {
|
|
||||||
throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user);
|
|
||||||
Track track = (Track) currentlyPlaying.getItem();
|
|
||||||
AlbumSimplified album = track.getAlbum();
|
|
||||||
String trackUrl = SpotifyUtils.getTrackUrl(currentlyPlaying);
|
|
||||||
String albumUrl = "https://open.spotify.com/album/" + album.getId();
|
|
||||||
|
|
||||||
StringBuilder artists = new StringBuilder();
|
|
||||||
for (int i = 0; i < track.getArtists().length; i++) {
|
|
||||||
artists.append("**[%s](%s)**".formatted(track.getArtists()[i].getName(), "https://open.spotify.com/artist/" + track.getArtists()[i].getId()));
|
|
||||||
if (i != track.getArtists().length - 1) {
|
|
||||||
artists.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Image albumCover = album.getImages()[0];
|
|
||||||
|
|
||||||
return EmbedUtils.genericEmbed()
|
return EmbedUtils.genericEmbed()
|
||||||
.setAuthor("Listening to %s | %s".formatted(track.getName(), track.getArtists()[0].getName()), trackUrl)
|
.setDescription("You need to link your Spotify account before you can use this command.")
|
||||||
.setThumbnail(albumCover.getUrl())
|
.build();
|
||||||
.setDescription("""
|
|
||||||
➜ Song: **[%s](%s)**
|
|
||||||
➜ Album: **[%s](%s)**
|
|
||||||
➜ Artist%s: %s
|
|
||||||
➜ Position: %s
|
|
||||||
""".formatted(
|
|
||||||
track.getName(), trackUrl,
|
|
||||||
album.getName(), albumUrl,
|
|
||||||
track.getArtists().length > 1 ? "s" : "", artists,
|
|
||||||
SpotifyUtils.getFormattedTime(currentlyPlaying)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Skips the current song.
|
|
||||||
*
|
|
||||||
* @param spotifyService The Spotify service.
|
|
||||||
* @param user The user.
|
|
||||||
*/
|
|
||||||
@SneakyThrows
|
|
||||||
public static EmbedBuilder skipSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) {
|
|
||||||
SpotifyProfile profile = user.getProfile(SpotifyProfile.class);
|
|
||||||
if (!profile.hasLinkedAccount()) {
|
|
||||||
throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spotifyService.hasTrackPlaying(user)) {
|
|
||||||
throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user);
|
|
||||||
Track track = (Track) currentlyPlaying.getItem();
|
|
||||||
String trackName = track.getName();
|
|
||||||
|
|
||||||
spotifyService.skipTrack(user);
|
|
||||||
CurrentlyPlaying newCurrentlyPlaying = SpotifyUtils.getNewTrack(spotifyService, user, trackName);
|
|
||||||
if (newCurrentlyPlaying == null) {
|
|
||||||
return EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("%s There are no more tracks in the queue.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
Track newTrack = (Track) newCurrentlyPlaying.getItem();
|
|
||||||
|
|
||||||
return EmbedUtils.successEmbed()
|
|
||||||
.setDescription("""
|
|
||||||
:track_next: Skipped the track: **[%s | %s](%s)**
|
|
||||||
%s New Track: **[%s | %s](%s)**
|
|
||||||
""".formatted(
|
|
||||||
trackName, track.getArtists()[0].getName(), SpotifyUtils.getTrackUrl(currentlyPlaying),
|
|
||||||
Emojis.CHECK_MARK_EMOJI, newTrack.getName(), newTrack.getArtists()[0].getName(), SpotifyUtils.getTrackUrl(newCurrentlyPlaying)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pauses the current song.
|
|
||||||
*
|
|
||||||
* @param spotifyService The Spotify service.
|
|
||||||
* @param user The user.
|
|
||||||
*/
|
|
||||||
@SneakyThrows
|
|
||||||
public static EmbedBuilder pauseSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) {
|
|
||||||
SpotifyProfile profile = user.getProfile(SpotifyProfile.class);
|
|
||||||
if (!profile.hasLinkedAccount()) {
|
|
||||||
throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spotifyService.hasTrackPlaying(user)) {
|
|
||||||
throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean didPause = spotifyService.pausePlayback(user);
|
|
||||||
CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user);
|
|
||||||
Track track = (Track) currentlyPlaying.getItem();
|
|
||||||
return EmbedUtils.successEmbed()
|
|
||||||
.setDescription(didPause ? ":pause_button: Paused the track **[%s | %s](%s)**".formatted(
|
|
||||||
track.getName(),
|
|
||||||
track.getArtists()[0].getName(),
|
|
||||||
SpotifyUtils.getTrackUrl(currentlyPlaying))
|
|
||||||
: "%s The current track is already paused.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resumes the current song.
|
|
||||||
*
|
|
||||||
* @param spotifyService The Spotify service.
|
|
||||||
* @param user The user.
|
|
||||||
*/
|
|
||||||
@SneakyThrows
|
|
||||||
public static EmbedBuilder resumeSong(@NonNull SpotifyService spotifyService, @NonNull BatUser user) {
|
|
||||||
SpotifyProfile profile = user.getProfile(SpotifyProfile.class);
|
|
||||||
if (!profile.hasLinkedAccount()) {
|
|
||||||
throw new BatException("%s You need to link your Spotify account before you can use this command.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spotifyService.hasTrackPlaying(user)) {
|
|
||||||
throw new BatException("%s You are not currently playing a track.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean didResume = spotifyService.resumePlayback(user);
|
|
||||||
CurrentlyPlaying currentlyPlaying = spotifyService.getCurrentlyPlayingTrack(user);
|
|
||||||
Track track = (Track) currentlyPlaying.getItem();
|
|
||||||
return EmbedUtils.successEmbed()
|
|
||||||
.setDescription(didResume ? ":play_pause: Resumed the track **[%s | %s](%s)**".formatted(
|
|
||||||
track.getName(),
|
|
||||||
track.getArtists()[0].getName(),
|
|
||||||
SpotifyUtils.getTrackUrl(currentlyPlaying))
|
|
||||||
: "%s The current track is already playing.".formatted(Emojis.CROSS_MARK_EMOJI));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user