diff --git a/src/main/java/dev/plex/futura/Futura.java b/src/main/java/dev/plex/futura/Futura.java index 3ca27cb..840a7d4 100644 --- a/src/main/java/dev/plex/futura/Futura.java +++ b/src/main/java/dev/plex/futura/Futura.java @@ -1,6 +1,8 @@ package dev.plex.futura; import dev.plex.futura.bot.BotHandler; +import dev.plex.futura.bot.linking.LinkingManager; +import dev.plex.futura.bot.listener.LinkingListener; import dev.plex.futura.config.Config; import dev.plex.futura.listener.ChatListener; import org.bstats.bukkit.Metrics; @@ -13,6 +15,7 @@ public final class Futura extends JavaPlugin private static Futura plugin; private BotHandler botHandler; + private LinkingManager linkingManager; public Config config; public Config messages; @@ -31,6 +34,7 @@ public final class Futura extends JavaPlugin this.saveResource("messages.yml", false); } botHandler = new BotHandler(); + linkingManager = new LinkingManager(); } @Override @@ -43,6 +47,7 @@ public final class Futura extends JavaPlugin if (this.botHandler.ready()) { this.botHandler.jda().addEventListener(chatListener); + this.botHandler.jda().addEventListener(new LinkingListener()); } // Metrics @ https://bstats.org/plugin/bukkit/Futura/20848 @@ -63,4 +68,9 @@ public final class Futura extends JavaPlugin { return this.botHandler; } + + public LinkingManager linkingManager() + { + return this.linkingManager; + } } diff --git a/src/main/java/dev/plex/futura/bot/linking/LinkingManager.java b/src/main/java/dev/plex/futura/bot/linking/LinkingManager.java new file mode 100644 index 0000000..706140b --- /dev/null +++ b/src/main/java/dev/plex/futura/bot/linking/LinkingManager.java @@ -0,0 +1,74 @@ +package dev.plex.futura.bot.linking; + +import com.google.common.collect.Maps; +import dev.plex.futura.Futura; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.apache.commons.lang3.RandomStringUtils; +import org.bukkit.entity.Player; + +import java.util.Map; +import java.util.UUID; + +/** + * @author Taah + * @since 6:51 PM [02-08-2024] + */ +public class LinkingManager +{ + private static final Map CODES = Maps.newHashMap(); + private final boolean enabled; + + public LinkingManager() + { + this.enabled = Futura.plugin().config.getBoolean("discord.linking.enabled", false); + } + + public void requestCode(Player player) + { + if (!Futura.plugin().botHandler().ready()) + { + player.sendMessage("The bot is not connected / online. Please contact an administrator."); + return; + } + if (!this.enabled) + { + player.sendMessage(MiniMessage.miniMessage().deserialize(Futura.plugin().messages.getString("linkingDisabled", "Discord to Minecraft account linking is currently disabled."))); + return; + } + + //TODO: Check if user is already linked on cache loaded from database + + final UUID uuid = player.getUniqueId(); + + if (CODES.containsKey(uuid)) + { + player.sendMessage(MiniMessage.miniMessage().deserialize(Futura.plugin().messages.getString("accountLinkingInProgress", "Can't request a new code currently, user has already requested a code. Please try again in a minute."))); + return; + } + + final String code = RandomStringUtils.randomAlphanumeric(8).toLowerCase(); + CODES.put(uuid, code); + + final int expirationTime = Futura.plugin().config.getInt("discord.linking.expirationTime", 60); + final String codeRequested = Futura.plugin().messages.getString("codeRequested", "The code you have requested is %code%. Please do not share this. In order to link your account, message the %bot-name% bot with your code. This code will expire in %expirationTime% seconds.") + .replace("%code%", code) + .replace("%bot-name%", Futura.plugin().botHandler().jda().getSelfUser().getName()) + .replace("%expiration-time%", String.valueOf(expirationTime)); + + player.sendMessage(MiniMessage.miniMessage().deserialize(codeRequested)); + Futura.plugin().getServer().getScheduler().runTaskLater(Futura.plugin(), () -> + { + CODES.remove(uuid); + }, 20L * expirationTime); + } + + public UUID matchCode(String code) + { + final Map.Entry uuidStringEntry = CODES.entrySet().stream().filter(entry -> entry.getValue().equals(code)).findFirst().orElse(null); + if (uuidStringEntry == null) + { + return null; + } + return uuidStringEntry.getKey(); + } +} diff --git a/src/main/java/dev/plex/futura/bot/listener/LinkingListener.java b/src/main/java/dev/plex/futura/bot/listener/LinkingListener.java new file mode 100644 index 0000000..7d36e46 --- /dev/null +++ b/src/main/java/dev/plex/futura/bot/listener/LinkingListener.java @@ -0,0 +1,32 @@ +package dev.plex.futura.bot.listener; + +import dev.plex.futura.Futura; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +/** + * @author Taah + * @since 7:05 PM [02-08-2024] + */ +public class LinkingListener extends ListenerAdapter +{ + @Override + public void onMessageReceived(@NotNull MessageReceivedEvent event) + { + if (event.getAuthor().isBot()) return; + if (event.getChannelType() != ChannelType.PRIVATE) return; + final String messageContent = event.getMessage().getContentRaw().toLowerCase(); + final UUID uuid = Futura.plugin().linkingManager().matchCode(messageContent); + if (uuid == null) + { + // Invalid Code + return; + } + + //TODO: Code was valid, link user, store user in cache and future database + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index fbe4f09..5b8c0aa 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -9,6 +9,8 @@ discord: # linking: enabled: false + # Time in seconds the code will be valid for until it expires and a new one will have to be requested for + expirationTime: 60 # You can leave this blank for no role to be given on linking role: "" # Roles sync if LuckPerms is on the server only @@ -18,3 +20,13 @@ discord: # luckpermsGroupName: "discordRoleId" roles: sync: false + + database: + # sqlite, mysql + type: sqlite + auth: + user: "" + password: "" + host: "" + port: 3306 + database: "" diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index ca177b6..b88a26a 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -5,4 +5,9 @@ joinServer: "**%player% has joined the server!" leftServer: "**%player% has left the server!" serverOffline: ":octagonal_sign: **Server is now offline!**" -serverOnline: ":white_check_mark: **Server is now online!**" \ No newline at end of file +serverOnline: ":white_check_mark: **Server is now online!**" + + +linkingDisabled: "Discord to Minecraft account linking is currently disabled." +accountLinkingInProgress: "Can't request a new code currently, user has already requested a code. Please try again in a minute." +codeRequested: "The code you have requested is %code%. Please do not share this. In order to link your account, message the %bot-name% bot with your code. This code will expire in %expiration-time% seconds." \ No newline at end of file