diff --git a/build.gradle.kts b/build.gradle.kts index bbf34d0..0e912a3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -56,7 +56,7 @@ tasks { //exclude(dependency("net.kyori:.*:.*")) } listOf( - "net.kyori", +// "net.kyori", "net.dv8tion.jda" ).forEach { relocate(it, "${rootProject.group}.lib.$it") } } diff --git a/src/main/java/com/alttd/proxydiscordlink/DiscordLink.java b/src/main/java/com/alttd/proxydiscordlink/DiscordLink.java index 7f336d4..247c282 100644 --- a/src/main/java/com/alttd/proxydiscordlink/DiscordLink.java +++ b/src/main/java/com/alttd/proxydiscordlink/DiscordLink.java @@ -1,16 +1,15 @@ package com.alttd.proxydiscordlink; import com.alttd.proxydiscordlink.bot.Bot; -import com.alttd.proxydiscordlink.commands.MinecraftCommand; +import com.alttd.proxydiscordlink.minecraft.commands.MinecraftCommand; import com.alttd.proxydiscordlink.config.BotConfig; import com.alttd.proxydiscordlink.config.Config; import com.alttd.proxydiscordlink.database.Database; import com.alttd.proxydiscordlink.database.DatabaseConnection; -import com.alttd.proxydiscordlink.listeners.PlayerJoin; -import com.alttd.proxydiscordlink.listeners.PlayerLeave; +import com.alttd.proxydiscordlink.minecraft.listeners.PlayerJoin; +import com.alttd.proxydiscordlink.minecraft.listeners.PlayerLeave; import com.alttd.proxydiscordlink.util.ALogger; import com.alttd.proxydiscordlink.util.Cache; -import com.alttd.proxydiscordlink.util.JarLoader; import com.google.inject.Inject; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; @@ -81,15 +80,6 @@ public class DiscordLink { } public void loadBot() { -// String JDAVersion = "4.2.0"; -// String JDABuild = "168"; -// String JDAUrl = "https://github.com/DV8FromTheWorld/JDA/releases/download/v" + JDAVersion + "/JDA-" + JDAVersion + "_" + JDABuild + "-withDependencies.jar"; -// String JDAFile = "jda-" + JDAVersion + "_" + JDABuild + ".jar"; -// if (new JarLoader().loadJar(JDAUrl, new File(new File(getDataDirectory(), "libs"), JDAFile))) { -// ALogger.info("JDA successfully loaded"); -// } else { -// ALogger.error("JDA could not be loaded!"); -// } bot = new Bot(); bot.connect(); } diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/Bot.java b/src/main/java/com/alttd/proxydiscordlink/bot/Bot.java index 9dd0c02..bdb7de2 100644 --- a/src/main/java/com/alttd/proxydiscordlink/bot/Bot.java +++ b/src/main/java/com/alttd/proxydiscordlink/bot/Bot.java @@ -1,11 +1,15 @@ package com.alttd.proxydiscordlink.bot; +import com.alttd.proxydiscordlink.bot.listeners.DiscordMessageListener; +import com.alttd.proxydiscordlink.bot.listeners.DiscordRoleListener; import com.alttd.proxydiscordlink.config.BotConfig; import com.alttd.proxydiscordlink.util.ALogger; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.utils.MemberCachePolicy; import javax.security.auth.login.LoginException; import java.util.concurrent.TimeUnit; @@ -16,9 +20,14 @@ public class Bot { public void connect() { disconnect(); try { - jda = JDABuilder.createDefault(BotConfig.BOT_TOKEN).build(); + jda = JDABuilder + .createDefault(BotConfig.BOT_TOKEN) + .setMemberCachePolicy(MemberCachePolicy.ALL) + .enableIntents(GatewayIntent.GUILD_MEMBERS) + .build(); jda.setAutoReconnect(true); - jda.addEventListener(new JDAListener()); + jda.addEventListener(new DiscordMessageListener(), + new DiscordRoleListener()); DiscordCommand.loadCommands(); } catch (LoginException e) { jda = null; diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/DiscordCommand.java b/src/main/java/com/alttd/proxydiscordlink/bot/DiscordCommand.java index 5353d34..f9c6f68 100644 --- a/src/main/java/com/alttd/proxydiscordlink/bot/DiscordCommand.java +++ b/src/main/java/com/alttd/proxydiscordlink/bot/DiscordCommand.java @@ -19,7 +19,7 @@ public abstract class DiscordCommand { public abstract void handleCommand(Message message, String sender, String command, String[] args); - protected static void loadCommands() { + public static void loadCommands() { commands = new ArrayList<>(); loadCommand(new DiscordStaffList(), @@ -31,7 +31,7 @@ public abstract class DiscordCommand { Collections.addAll(commands, discordCommands); } - protected static List getCommands() { + public static List getCommands() { return commands; } } diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/JDAListener.java b/src/main/java/com/alttd/proxydiscordlink/bot/listeners/DiscordMessageListener.java similarity index 86% rename from src/main/java/com/alttd/proxydiscordlink/bot/JDAListener.java rename to src/main/java/com/alttd/proxydiscordlink/bot/listeners/DiscordMessageListener.java index f08c896..7256df8 100644 --- a/src/main/java/com/alttd/proxydiscordlink/bot/JDAListener.java +++ b/src/main/java/com/alttd/proxydiscordlink/bot/listeners/DiscordMessageListener.java @@ -1,18 +1,20 @@ -package com.alttd.proxydiscordlink.bot; +package com.alttd.proxydiscordlink.bot.listeners; import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.bot.Bot; +import com.alttd.proxydiscordlink.bot.DiscordCommand; import com.alttd.proxydiscordlink.config.BotConfig; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import java.util.Arrays; -public class JDAListener extends ListenerAdapter { +public class DiscordMessageListener extends ListenerAdapter { private DiscordLink plugin; private final Bot bot; - public JDAListener() { + public DiscordMessageListener() { plugin = DiscordLink.getPlugin(); bot = plugin.getBot(); } diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/listeners/DiscordRoleListener.java b/src/main/java/com/alttd/proxydiscordlink/bot/listeners/DiscordRoleListener.java new file mode 100644 index 0000000..fbe3d46 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/listeners/DiscordRoleListener.java @@ -0,0 +1,79 @@ +package com.alttd.proxydiscordlink.bot.listeners; + +import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.bot.Bot; +import com.alttd.proxydiscordlink.bot.objects.DiscordRole; +import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; +import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleAddEvent; +import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.Template; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.stream.Collectors; + +public class DiscordRoleListener extends ListenerAdapter { + private DiscordLink plugin; + private final Bot bot; + private final MiniMessage miniMessage; + + public DiscordRoleListener() { + plugin = DiscordLink.getPlugin(); + bot = plugin.getBot(); + miniMessage = MiniMessage.get(); + } + + /** + * Checks if the user needs to be updated based on the roles that got added + * TODO If the user isn't linked maybe ask them to link? + * Announces that the user got a role assigned if the role has an announcement for it. + */ + @Override + public void onGuildMemberRoleAdd(@NotNull GuildMemberRoleAddEvent event) { + List added_roles = DiscordRole.getDiscordRoles().stream() + .filter(discordRole -> event.getRoles().stream() + .anyMatch(role -> role.getIdLong() == discordRole.getId())) + .collect(Collectors.toList()); + + if (added_roles.isEmpty()) + return; + + DiscordLinkPlayer player = DiscordLinkPlayer.getDiscordLinkPlayer(event.getUser().getIdLong()); + + if (player == null) { + //TODO mayb ask the player to link to get their in game rank? + return; + } + + player.update(added_roles, true); + added_roles.forEach(discordRole -> { + if (!discordRole.getAnnouncement().isEmpty()) { + Component component = miniMessage.parse( + discordRole.getAnnouncement(), + Template.of("player", player.getUsername())); + + DiscordLink.getPlugin().getProxy().getAllPlayers() + .forEach(onlinePlayer -> onlinePlayer.sendMessage(component)); + } + }); + } + + /** + * Checks if the user needs to be updated based on the roles that got removed + */ + @Override + public void onGuildMemberRoleRemove(@NotNull GuildMemberRoleRemoveEvent event) { + List removed_roles = DiscordRole.getDiscordRoles().stream() + .filter(discordRole -> event.getRoles().stream() + .anyMatch(role -> role.getIdLong() == discordRole.getId())) + .collect(Collectors.toList()); + if (removed_roles.isEmpty()) + return; + + DiscordLink.getPlugin().getDatabase().getPlayer(event.getUser().getIdLong()) + .update(removed_roles, false); + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/objects/DiscordRole.java b/src/main/java/com/alttd/proxydiscordlink/bot/objects/DiscordRole.java new file mode 100644 index 0000000..6ee2a5c --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/objects/DiscordRole.java @@ -0,0 +1,64 @@ +package com.alttd.proxydiscordlink.bot.objects; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class DiscordRole { + + private final long id; + private final String luckpermsName; + private final String displayName; + private final boolean updateToMinecraft; + private final String announcement; + + public DiscordRole(long id, String luckpermsName, String displayName, boolean updateToMinecraft, String announcement) { + this.id = id; + this.luckpermsName = luckpermsName; + this.displayName = displayName; + this.updateToMinecraft = updateToMinecraft; + this.announcement = announcement; + } + + public long getId() { + return id; + } + + public String getDisplayName() { + return displayName; + } + + public String getLuckpermsName() { + return luckpermsName; + } + + public boolean isUpdateToMinecraft() { + return updateToMinecraft; + } + + public String getAnnouncement() { + return announcement; + } + + //Static stuff + + private static final List discordRoles = new ArrayList<>(); + + public static List getDiscordRoles() { + return Collections.unmodifiableList(discordRoles); + } + + public static void addDiscordRole(DiscordRole discordRole) { + if (!discordRoles.contains(discordRole)) + discordRoles.add(discordRole); + } + + public static void removeDiscordRole(DiscordRole discordRole) { + discordRoles.remove(discordRole); + } + + public static void cleanDiscordRoles() { + discordRoles.clear(); + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/config/BotConfig.java b/src/main/java/com/alttd/proxydiscordlink/config/BotConfig.java index 528e78a..5479427 100644 --- a/src/main/java/com/alttd/proxydiscordlink/config/BotConfig.java +++ b/src/main/java/com/alttd/proxydiscordlink/config/BotConfig.java @@ -1,5 +1,7 @@ package com.alttd.proxydiscordlink.config; +import com.alttd.proxydiscordlink.bot.objects.DiscordRole; +import com.alttd.proxydiscordlink.util.ALogger; import com.google.common.base.Throwables; import com.google.common.reflect.TypeToken; import ninja.leaping.configurate.ConfigurationNode; @@ -164,8 +166,8 @@ public class BotConfig { public static String BOT_TOKEN = "unconfigured"; public static String COMMAND_CHANNEL = "unconfigured"; - private static void settings() - { + + private static void settings() { BOT_TOKEN = getString("settings.token", BOT_TOKEN); COMMAND_CHANNEL = getString("settings.command_channel", COMMAND_CHANNEL); } @@ -173,9 +175,37 @@ public class BotConfig { public static String SL_MINIMUMRANK = "trainee"; public static String SL_HOVERMESSAGE = "Click here to message %player% on %servername%."; public static String SL_CLICKCOMMAND = "/msg %player%"; + private static void stafflist() { SL_MINIMUMRANK = getString("commands.staff-list.minimum-rank", SL_MINIMUMRANK); SL_HOVERMESSAGE = getString("commands.staff-list.hover-message", SL_HOVERMESSAGE); SL_CLICKCOMMAND = getString("commands.staff-list.click-command", SL_CLICKCOMMAND); } + + private static void roles() { + DiscordRole.cleanDiscordRoles(); + ConfigurationNode node = getNode("sync-roles"); + if (node.getChildrenMap().isEmpty()) + ALogger.warn("No roles found in BotConfig, add them to use sync-roles feature:\n" + + "sync-roles:\n\t" + + "example_rank:\n\t\t" + + "role-id: 0\n\t\t" + + "luckperms-name: example\n\t\t" + + "display-name: Example Rank\n\t\t" + + "update-to-minecraft: true\n\t\t" + + "announcement: got example rank!"); + node.getChildrenMap().forEach((key, value) -> { + long id = value.getNode("role-id").getLong(-1); + String luckpermsName = value.getNode("luckperms-name").getString("example"); + String display_name = value.getNode("display-name").getString("Example"); + boolean updateToMinecraft = value.getNode("update-to-minecraft").getBoolean(false); + String announcement = value.getNode("announcement").getString(" got example rank!"); + + if (id == -1) + ALogger.error("Invalid id in BotConfig for roles."); + else + DiscordRole.addDiscordRole(new DiscordRole(id, luckpermsName, display_name, updateToMinecraft, announcement)); + + }); + } } diff --git a/src/main/java/com/alttd/proxydiscordlink/database/Database.java b/src/main/java/com/alttd/proxydiscordlink/database/Database.java index c750fb0..4b2a066 100644 --- a/src/main/java/com/alttd/proxydiscordlink/database/Database.java +++ b/src/main/java/com/alttd/proxydiscordlink/database/Database.java @@ -1,6 +1,9 @@ package com.alttd.proxydiscordlink.database; +import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; import com.alttd.proxydiscordlink.util.ALogger; +import com.alttd.proxydiscordlink.util.Cache; import com.alttd.proxydiscordlink.util.Utilities; import com.velocitypowered.api.proxy.Player; @@ -76,58 +79,25 @@ public class Database { } - public void syncPlayerData(Player player) { - - ResultSet resultSet = getPlayerData(player.getUniqueId()); - try { - if (!resultSet.next()) return; - - String discordNickname = resultSet.getString("player_nickname"); - String playerNickname = getNick(player.getUniqueId()); - - boolean correctName = resultSet.getString("player_name").equals(player.getUsername()); - boolean correctNick = Objects.equals(discordNickname, playerNickname); - boolean correctRankName = resultSet.getString("player_rank").equals(Utilities.getRankName(player)); - boolean correctRank = resultSet.getBoolean("player_isdonor") == (Utilities.isDonor(player)); - - if (correctName && correctNick && correctRankName && correctRank) { - return; - } - - syncPlayer(resultSet, player, playerNickname); - } catch (SQLException exception) { - exception.printStackTrace(); - } - } - - public ResultSet getPlayerData(UUID uuid) { - try { - return getStringResult("SELECT * FROM linked_accounts WHERE player_uuid = ?", uuid.toString()); - } catch (SQLException e) { - e.printStackTrace(); - } - return null; - } - - private void syncPlayer(ResultSet resultSet, Player player, String playerNickname) { + public void syncPlayer(DiscordLinkPlayer player) { try { + String playerNickname = getNick(player.getUuid()); String sql = "INSERT INTO updates " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, 1) " + "ON DUPLICATE KEY UPDATE player_uuid = ?"; PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(sql); - int donor = Utilities.isDonor(player) ? 1 : 0; - String uuid = player.getUniqueId().toString(); + String uuid = player.getUuid().toString(); - statement.setString(1, player.getUniqueId().toString()); + statement.setString(1, player.getUuid().toString()); statement.setString(2, player.getUsername()); statement.setString(3, playerNickname); - statement.setString(4, Utilities.getRankName(player)); - statement.setInt(5, donor); - statement.setInt(6, resultSet.getInt("player_isnitro")); - statement.setString(7, resultSet.getString("discord_username")); - statement.setString(8, resultSet.getString("discord_id")); + statement.setString(4, Utilities.getRankName(player.getUuid())); + statement.setInt(5, player.isDonor() ? 1 : 0); + statement.setInt(6, player.isNitro() ? 1 : 0); + statement.setString(7, player.getDiscordUsername()); + statement.setLong(8, player.getUserId()); statement.setString(9, uuid); statement.execute(); @@ -285,6 +255,60 @@ public class Database { return null; } + /** + * Should only be used internally + * @param user_id gets the player with this user id + * @return null or the requested DiscordLinkPlayer + */ + public DiscordLinkPlayer getPlayer(long user_id) { + DiscordLinkPlayer discordLinkPlayer = DiscordLinkPlayer.getDiscordLinkPlayer(user_id); + + if (discordLinkPlayer != null) + return discordLinkPlayer; + try { + PreparedStatement statement = DatabaseConnection.getConnection() + .prepareStatement("SELECT * FROM linked_accounts WHERE discord_id = ?"); + + statement.setLong(1, user_id); + return getPlayer(statement.executeQuery()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return null; + } + + /** + * Should only be used internally + * @param uuid gets the player with this uuid + * @return null or the requested DiscordLinkPlayer + */ + public DiscordLinkPlayer getPlayer(UUID uuid) { + try { + PreparedStatement statement = DatabaseConnection.getConnection() + .prepareStatement("SELECT * FROM linked_accounts WHERE player_uuid = ?"); + + statement.setString(1, uuid.toString()); + return getPlayer(statement.executeQuery()); + } catch (SQLException exception) { + exception.printStackTrace(); + } + return null; + } + + private DiscordLinkPlayer getPlayer(ResultSet resultSet) throws SQLException { + if (resultSet.next()) { + return new DiscordLinkPlayer( + resultSet.getLong("discord_id"), + UUID.fromString(resultSet.getString("player_uuid")), + resultSet.getString("player_name"), + resultSet.getString("discord_username"), + resultSet.getInt("player_isdonor") == 1, + resultSet.getInt("player_isnitro") == 1 + ); + } + return null; + } + private ResultSet getStringResult(String query, String... parameters) throws SQLException { PreparedStatement statement = DatabaseConnection.getConnection().prepareStatement(query); diff --git a/src/main/java/com/alttd/proxydiscordlink/listeners/PlayerJoin.java b/src/main/java/com/alttd/proxydiscordlink/listeners/PlayerJoin.java deleted file mode 100644 index 1dfef29..0000000 --- a/src/main/java/com/alttd/proxydiscordlink/listeners/PlayerJoin.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.alttd.proxydiscordlink.listeners; - -import com.alttd.proxydiscordlink.database.Database; -import com.alttd.proxydiscordlink.DiscordLink; -import com.alttd.proxydiscordlink.util.ALogger; -import com.alttd.proxydiscordlink.util.Utilities; -import com.velocitypowered.api.event.PostOrder; -import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.connection.LoginEvent; -import com.velocitypowered.api.proxy.Player; -import net.luckperms.api.LuckPerms; -import net.luckperms.api.model.group.Group; -import net.luckperms.api.model.user.User; -import net.luckperms.api.node.Node; -import net.luckperms.api.node.types.InheritanceNode; - -public class PlayerJoin { - - @Subscribe(order = PostOrder.LATE) - public void playerLogin(LoginEvent event) { - Player player = event.getPlayer(); - Database database = DiscordLink.getPlugin().getDatabase(); - - if (database.playerIsLinked(player)) { - database.syncPlayerData(player); - - boolean isNitro = database.hasDiscordNitro(player); - boolean hasNitro = Utilities.hasMinecraftNitro(player); - - LuckPerms luckPermsAPI = Utilities.getLuckPerms(); - Group discord = luckPermsAPI.getGroupManager().getGroup("discord"); - - if (discord == null) { - ALogger.error("Unable to find discord group in DiscordLink"); - return; - } - - if (isNitro && !hasNitro) { - luckPermsAPI.getUserManager().modifyUser(player.getUniqueId(), (User user) -> { - Node node = InheritanceNode.builder(discord).build(); - user.data().add(node); - }); - - } else if (!isNitro && hasNitro) { - luckPermsAPI.getUserManager().modifyUser(player.getUniqueId(), (User user) -> { - Node node = InheritanceNode.builder(discord).build(); - user.data().remove(node); - }); - } - } - } -} diff --git a/src/main/java/com/alttd/proxydiscordlink/commands/MinecraftCommand.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/MinecraftCommand.java similarity index 91% rename from src/main/java/com/alttd/proxydiscordlink/commands/MinecraftCommand.java rename to src/main/java/com/alttd/proxydiscordlink/minecraft/commands/MinecraftCommand.java index ac11707..6e9f6f5 100644 --- a/src/main/java/com/alttd/proxydiscordlink/commands/MinecraftCommand.java +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/MinecraftCommand.java @@ -1,9 +1,9 @@ -package com.alttd.proxydiscordlink.commands; +package com.alttd.proxydiscordlink.minecraft.commands; -import com.alttd.proxydiscordlink.commands.subcommands.CheckLinked; -import com.alttd.proxydiscordlink.commands.subcommands.Link; -import com.alttd.proxydiscordlink.commands.subcommands.Reload; -import com.alttd.proxydiscordlink.commands.subcommands.Unlink; +import com.alttd.proxydiscordlink.minecraft.commands.subcommands.CheckLinked; +import com.alttd.proxydiscordlink.minecraft.commands.subcommands.Link; +import com.alttd.proxydiscordlink.minecraft.commands.subcommands.Reload; +import com.alttd.proxydiscordlink.minecraft.commands.subcommands.Unlink; import com.alttd.proxydiscordlink.config.Config; import com.mojang.brigadier.arguments.StringArgumentType; import com.velocitypowered.api.command.CommandSource; diff --git a/src/main/java/com/alttd/proxydiscordlink/commands/SubCommand.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/SubCommand.java similarity index 84% rename from src/main/java/com/alttd/proxydiscordlink/commands/SubCommand.java rename to src/main/java/com/alttd/proxydiscordlink/minecraft/commands/SubCommand.java index 36d8f71..5df0e9f 100644 --- a/src/main/java/com/alttd/proxydiscordlink/commands/SubCommand.java +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/SubCommand.java @@ -1,4 +1,4 @@ -package com.alttd.proxydiscordlink.commands; +package com.alttd.proxydiscordlink.minecraft.commands; import com.velocitypowered.api.command.CommandSource; diff --git a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/CheckLinked.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/CheckLinked.java similarity index 95% rename from src/main/java/com/alttd/proxydiscordlink/commands/subcommands/CheckLinked.java rename to src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/CheckLinked.java index 95ed7c1..dc9797d 100644 --- a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/CheckLinked.java +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/CheckLinked.java @@ -1,7 +1,7 @@ -package com.alttd.proxydiscordlink.commands.subcommands; +package com.alttd.proxydiscordlink.minecraft.commands.subcommands; import com.alttd.proxydiscordlink.DiscordLink; -import com.alttd.proxydiscordlink.commands.SubCommand; +import com.alttd.proxydiscordlink.minecraft.commands.SubCommand; import com.alttd.proxydiscordlink.config.Config; import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.Player; diff --git a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Link.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Link.java similarity index 91% rename from src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Link.java rename to src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Link.java index 7838aef..6abf7f4 100644 --- a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Link.java +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Link.java @@ -1,7 +1,7 @@ -package com.alttd.proxydiscordlink.commands.subcommands; +package com.alttd.proxydiscordlink.minecraft.commands.subcommands; import com.alttd.proxydiscordlink.DiscordLink; -import com.alttd.proxydiscordlink.commands.SubCommand; +import com.alttd.proxydiscordlink.minecraft.commands.SubCommand; import com.alttd.proxydiscordlink.config.Config; import com.alttd.proxydiscordlink.database.Database; import com.alttd.proxydiscordlink.util.Utilities; @@ -62,7 +62,7 @@ public class Link implements SubCommand { player.sendMessage(miniMessage.parse(Config.GIVE_CODE, Template.of("code", authCode))); DiscordLink.getPlugin().getCache() .cacheCode(player.getUniqueId(), authCode); - database.storeDataInCache(player, authCode, Utilities.getRankName(player), Utilities.isDonor(player)); + database.storeDataInCache(player, authCode, Utilities.getRankName(player.getUniqueId()), Utilities.isDonor(player.getUniqueId())); } @Override diff --git a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Reload.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Reload.java similarity index 89% rename from src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Reload.java rename to src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Reload.java index 5c17611..b0c1eba 100644 --- a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Reload.java +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Reload.java @@ -1,7 +1,7 @@ -package com.alttd.proxydiscordlink.commands.subcommands; +package com.alttd.proxydiscordlink.minecraft.commands.subcommands; import com.alttd.proxydiscordlink.DiscordLink; -import com.alttd.proxydiscordlink.commands.SubCommand; +import com.alttd.proxydiscordlink.minecraft.commands.SubCommand; import com.alttd.proxydiscordlink.config.Config; import com.velocitypowered.api.command.CommandSource; import net.kyori.adventure.text.minimessage.MiniMessage; diff --git a/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Sync.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Sync.java new file mode 100644 index 0000000..6e57716 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Sync.java @@ -0,0 +1,33 @@ +package com.alttd.proxydiscordlink.minecraft.commands.subcommands; + +import com.alttd.proxydiscordlink.minecraft.commands.SubCommand; +import com.velocitypowered.api.command.CommandSource; + +import java.util.List; + +public class Sync implements SubCommand { //TODO implement + @Override + public String getName() { + return null; + } + + @Override + public String getPermission() { + return null; + } + + @Override + public void execute(String[] args, CommandSource source) { + + } + + @Override + public List suggest(String[] args) { + return null; + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Unlink.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Unlink.java similarity index 93% rename from src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Unlink.java rename to src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Unlink.java index 137e61c..47ebafb 100644 --- a/src/main/java/com/alttd/proxydiscordlink/commands/subcommands/Unlink.java +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/commands/subcommands/Unlink.java @@ -1,7 +1,7 @@ -package com.alttd.proxydiscordlink.commands.subcommands; +package com.alttd.proxydiscordlink.minecraft.commands.subcommands; import com.alttd.proxydiscordlink.DiscordLink; -import com.alttd.proxydiscordlink.commands.SubCommand; +import com.alttd.proxydiscordlink.minecraft.commands.SubCommand; import com.alttd.proxydiscordlink.config.Config; import com.alttd.proxydiscordlink.database.Database; import com.velocitypowered.api.command.CommandSource; diff --git a/src/main/java/com/alttd/proxydiscordlink/minecraft/listeners/PlayerJoin.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/listeners/PlayerJoin.java new file mode 100644 index 0000000..8c50c34 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/listeners/PlayerJoin.java @@ -0,0 +1,57 @@ +package com.alttd.proxydiscordlink.minecraft.listeners; + +import com.alttd.proxydiscordlink.database.Database; +import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; +import com.alttd.proxydiscordlink.util.ALogger; +import com.alttd.proxydiscordlink.util.Utilities; +import com.velocitypowered.api.event.PostOrder; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.LoginEvent; +import com.velocitypowered.api.proxy.Player; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.model.group.Group; +import net.luckperms.api.model.user.User; +import net.luckperms.api.node.Node; +import net.luckperms.api.node.types.InheritanceNode; + +public class PlayerJoin { + + @Subscribe(order = PostOrder.LATE) + public void playerLogin(LoginEvent event) { + Player player = event.getPlayer(); + Database database = DiscordLink.getPlugin().getDatabase(); + + if (database.playerIsLinked(player) && DiscordLinkPlayer.getDiscordLinkPlayer(event.getPlayer().getUniqueId()) == null) { + //TODO remove islinked? + + + //TODO I don't think all the below is needed anymore? +// database.syncPlayerData(player); +// +// boolean isNitro = database.hasDiscordNitro(player); +// boolean hasNitro = Utilities.hasMinecraftNitro(player); +// +// LuckPerms luckPermsAPI = Utilities.getLuckPerms(); +// Group discord = luckPermsAPI.getGroupManager().getGroup("discord"); +// +// if (discord == null) { +// ALogger.error("Unable to find discord group in DiscordLink"); +// return; +// } +// +// if (isNitro && !hasNitro) { +// luckPermsAPI.getUserManager().modifyUser(player.getUniqueId(), (User user) -> { +// Node node = InheritanceNode.builder(discord).build(); +// user.data().add(node); +// }); +// +// } else if (!isNitro && hasNitro) { +// luckPermsAPI.getUserManager().modifyUser(player.getUniqueId(), (User user) -> { +// Node node = InheritanceNode.builder(discord).build(); +// user.data().remove(node); +// }); +// } + } + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/listeners/PlayerLeave.java b/src/main/java/com/alttd/proxydiscordlink/minecraft/listeners/PlayerLeave.java similarity index 93% rename from src/main/java/com/alttd/proxydiscordlink/listeners/PlayerLeave.java rename to src/main/java/com/alttd/proxydiscordlink/minecraft/listeners/PlayerLeave.java index c823926..45d8004 100644 --- a/src/main/java/com/alttd/proxydiscordlink/listeners/PlayerLeave.java +++ b/src/main/java/com/alttd/proxydiscordlink/minecraft/listeners/PlayerLeave.java @@ -1,4 +1,4 @@ -package com.alttd.proxydiscordlink.listeners; +package com.alttd.proxydiscordlink.minecraft.listeners; import com.alttd.proxydiscordlink.database.Database; import com.alttd.proxydiscordlink.DiscordLink; diff --git a/src/main/java/com/alttd/proxydiscordlink/objects/DiscordLinkPlayer.java b/src/main/java/com/alttd/proxydiscordlink/objects/DiscordLinkPlayer.java new file mode 100644 index 0000000..5d4d85f --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/objects/DiscordLinkPlayer.java @@ -0,0 +1,111 @@ +package com.alttd.proxydiscordlink.objects; + +import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.bot.objects.DiscordRole; +import com.alttd.proxydiscordlink.database.Database; +import com.alttd.proxydiscordlink.util.ALogger; +import com.alttd.proxydiscordlink.util.Utilities; +import net.luckperms.api.model.user.User; +import net.luckperms.api.node.NodeBuilder; +import net.luckperms.api.node.types.PermissionNode; + +import java.util.*; + +public class DiscordLinkPlayer { + private final long userId; + private final UUID uuid; + private final String username; + private final String discordUsername; + private boolean isDonor; + private boolean isNitro; + + public DiscordLinkPlayer(long userId, UUID uuid, String username, String discordUsername, boolean isDonor, boolean isNitro) { + this.userId = userId; + this.uuid = uuid; + this.username = username; + this.isDonor = isDonor; + this.isNitro = isNitro; + this.discordUsername = discordUsername; + } + + public long getUserId() { + return userId; + } + + public UUID getUuid() { + return uuid; + } + + public String getUsername() { + return username; + } + + public boolean isDonor() { + return isDonor; + } + + public boolean isNitro() { + return isNitro; + } + + public String getDiscordUsername() { + return discordUsername; + } + + public void update(List roles, boolean added) { + User user = Utilities.getLuckPerms().getUserManager().getUser(getUuid()); + if (user == null) + { + ALogger.error("Tried updating a user luckperms couldn't find: " + getUuid()); + return; + } + + for (DiscordRole role : roles) { + if (role.getDisplayName().equalsIgnoreCase("nitro")) + isNitro = added; //FIXME this should be a list instead of a bool (separate table for roles they have) + if (List.of("viceroy", "count", "duke", "archduke").contains(role.getDisplayName().toLowerCase())) + isDonor = added; //FIXME this should be a list instead of a bool (separate table for roles they have) + if (!role.isUpdateToMinecraft()) + continue; + PermissionNode group = PermissionNode.builder("group." + role.getLuckpermsName()).build(); + if (!user.getNodes().contains(group)) + if (added) + user.getNodes().add(group); + else + user.getNodes().remove(group); + } + DiscordLink.getPlugin().getDatabase().syncPlayer(this); + //TODO implement + } + + //Static stuff + + private static final List discordLinkPlayers = new ArrayList<>(); + + public static List getDiscordLinkPlayers() { + return Collections.unmodifiableList(discordLinkPlayers); + } + + public static void addDiscordLinkPlayer(DiscordLinkPlayer discordLinkPlayer) { + if (!discordLinkPlayers.contains(discordLinkPlayer)) + discordLinkPlayers.add(discordLinkPlayer); + } + + public static void removeDiscordLinkPlayer(DiscordLinkPlayer discordLinkPlayer) { + discordLinkPlayers.remove(discordLinkPlayer); + } + + public static DiscordLinkPlayer getDiscordLinkPlayer(long userId) { + return discordLinkPlayers.stream() + .filter(discordLinkPlayer -> discordLinkPlayer.getUserId() == userId) + .findFirst() + .orElse(null); + } + + public static DiscordLinkPlayer getDiscordLinkPlayer(UUID uuid) { + return discordLinkPlayers.stream() + .filter(o1 -> o1.getUuid().equals(uuid)) + .findFirst() + .orElseGet(() -> DiscordLink.getPlugin().getDatabase().getPlayer(uuid)); + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java b/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java index 052de82..94cf0b0 100644 --- a/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java +++ b/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java @@ -13,6 +13,7 @@ import net.luckperms.api.node.types.InheritanceNode; import java.util.Random; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; public class Utilities { @@ -26,8 +27,8 @@ public class Utilities { return luckPerms; } - public static boolean isDonor(Player player) { - User user = getLuckPerms().getUserManager().getUser(player.getUniqueId()); + public static boolean isDonor(UUID uuid) { + User user = getLuckPerms().getUserManager().getUser(uuid); if (user == null) { ALogger.error("Unable to find user in isDonor!"); return false; @@ -83,8 +84,8 @@ public class Utilities { return salt.toString(); } - public static String getRankName(Player player) { - return getLuckPerms().getUserManager().getUser(player.getUniqueId()).getPrimaryGroup(); + public static String getRankName(UUID uuid) { + return getLuckPerms().getUserManager().getUser(uuid).getPrimaryGroup(); } public static String capitalize(String str) {