diff --git a/src/main/java/me/braydon/license/model/License.java b/src/main/java/me/braydon/license/model/License.java index 8ee003b..0bf6d85 100644 --- a/src/main/java/me/braydon/license/model/License.java +++ b/src/main/java/me/braydon/license/model/License.java @@ -94,6 +94,18 @@ public class License { */ @NonNull private Date created; + /** + * Check if the Discord user + * with the given snowflake + * owns this license. + * + * @param snowflake the snowflake + * @return true if owns, otherwise false + */ + public boolean isOwner(long snowflake) { + return ownerSnowflake == snowflake; + } + /** * Check if this license has expired. *
diff --git a/src/main/java/me/braydon/license/service/DiscordService.java b/src/main/java/me/braydon/license/service/DiscordService.java
index eeeb43c..611a0f5 100644
--- a/src/main/java/me/braydon/license/service/DiscordService.java
+++ b/src/main/java/me/braydon/license/service/DiscordService.java
@@ -1,37 +1,62 @@
package me.braydon.license.service;
+import jakarta.annotation.Nonnull;
import jakarta.annotation.PostConstruct;
import lombok.Getter;
import lombok.NonNull;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
+import me.braydon.license.common.MiscUtils;
import me.braydon.license.common.TimeUtils;
import me.braydon.license.model.License;
+import me.braydon.license.repository.LicenseRepository;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.entities.MessageEmbed;
+import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
+import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.requests.ErrorResponse;
import net.dv8tion.jda.api.requests.GatewayIntent;
+import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.info.BuildProperties;
import org.springframework.stereotype.Service;
+import java.awt.*;
+import java.util.Objects;
+import java.util.Optional;
+
/**
* @author Braydon
*/
@Service
@Slf4j(topic = "Discord")
public final class DiscordService {
+ /**
+ * The {@link LicenseRepository} to use.
+ */
+ @Nonnull private final LicenseRepository licenseRepository;
+
/**
* The version of this Springboot application.
*/
@NonNull private final String applicationVersion;
+
+ /**
+ * The salt to use for hashing license keys.
+ */
+ @Value("${salts.licenses}")
+ @NonNull private String licensesSalt;
+
/**
* The name of this Springboot application.
*/
@@ -92,7 +117,9 @@ public final class DiscordService {
private JDA jda;
@Autowired
- public DiscordService(@NonNull BuildProperties buildProperties) {
+ public DiscordService(@NonNull LicenseRepository licenseRepository, @NonNull BuildProperties buildProperties) {
+ this.licenseRepository = licenseRepository;
+ ;
this.applicationVersion = buildProperties.getVersion();
}
@@ -111,6 +138,7 @@ public final class DiscordService {
GatewayIntent.GUILD_MEMBERS
).setStatus(OnlineStatus.DO_NOT_DISTURB)
.setActivity(Activity.watching("your licenses"))
+ .addEventListeners(new EventHandler())
.build();
jda.awaitReady(); // Await JDA to be ready
@@ -118,6 +146,13 @@ public final class DiscordService {
log.info("Logged into {} in {}ms",
jda.getSelfUser().getAsTag(), System.currentTimeMillis() - before
);
+
+ // Registering slash commands
+ jda.updateCommands().addCommands(
+ Commands.slash("license", "Manage one of your licenses")
+ .addOption(OptionType.STRING, "key", "The license key", true)
+ .addOption(OptionType.STRING, "product", "The product the license is for", true)
+ ).queue();
}
/**
@@ -205,4 +240,65 @@ public final class DiscordService {
applicationName, applicationVersion, TimeUtils.dateTime()
)).build();
}
+
+ /**
+ * The event handler for the bot.
+ */
+ public class EventHandler extends ListenerAdapter {
+ @Override
+ public void onSlashCommandInteraction(@NonNull SlashCommandInteractionEvent event) {
+ User user = event.getUser(); // The command executor
+
+ // Handle the license command
+ if (event.getName().equals("license")) {
+ String key = Objects.requireNonNull(event.getOption("key")).getAsString();
+ String product = Objects.requireNonNull(event.getOption("product")).getAsString();
+ event.deferReply().queue(); // Send thinking...
+
+ // License lookup
+ Optional