diff --git a/src/main/java/net/hypr/doki/Config.java b/src/main/java/net/hypr/doki/Config.java index 506f47b..28bcbf8 100644 --- a/src/main/java/net/hypr/doki/Config.java +++ b/src/main/java/net/hypr/doki/Config.java @@ -13,7 +13,6 @@ public class Config { @SuppressWarnings("unused") private String token; @SuppressWarnings("unused") private String prefix; @SuppressWarnings("unused") private DBConfig mariadb; - @SuppressWarnings("unused") private boolean levelling = false; /** * Returns the configuration object for this bot @@ -37,7 +36,6 @@ public class Config { return token; } public String getPrefix() { return prefix; } - public boolean getLevelling() { return levelling; } public DBConfig getDbConfig() { return mariadb; diff --git a/src/main/java/net/hypr/doki/Doki.java b/src/main/java/net/hypr/doki/Doki.java index 1beb95a..c2095f5 100644 --- a/src/main/java/net/hypr/doki/Doki.java +++ b/src/main/java/net/hypr/doki/Doki.java @@ -6,8 +6,6 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.requests.GatewayIntent; -import net.hypr.doki.listeners.LevellingListener; -import org.apache.commons.dbcp2.BasicDataSource; import org.slf4j.Logger; import java.io.IOException; @@ -16,7 +14,6 @@ public class Doki { private static final Logger log = Logging.getLogger(); private static JDA jda; private static Config config; - private static final BasicDataSource dataSource = new BasicDataSource(); private Doki(JDA jda, Config config) { Doki.jda = jda; @@ -27,7 +24,6 @@ public class Doki { return jda; } public static String getPrefix() { return config.getPrefix(); } - public static BasicDataSource getDataSource() { return dataSource; } public static void start() throws IOException, InterruptedException { config = Config.readConfig(); @@ -38,19 +34,6 @@ public class Doki { .build() .awaitReady(); - // Connect to the DB - if (config.getLevelling()) { - Config.DBConfig dbConfig = config.getDbConfig(); - dataSource.setDriverClassName("org.mariadb.jdbc.Driver"); - dataSource.setUrl("jdbc:mariadb://" + dbConfig.getHost() + ":" + dbConfig.getPortNumber() + "/" + dbConfig.getDatabase()); - dataSource.setUsername(dbConfig.getUser()); - dataSource.setPassword(dbConfig.getPassword()); - dataSource.setMaxTotal(10); - dataSource.setMaxIdle(5); - dataSource.setMinIdle(2); - dataSource.setInitialSize(10); - } - // Print some information about the bot log.info("Bot connected as {}", jda.getSelfUser().getAsTag()); log.info("The bot is present in the following guilds:"); @@ -68,11 +51,6 @@ public class Doki { CommandsBuilder.newBuilder(437970062922612737L) .textCommandBuilder(textCommandsBuilder -> textCommandsBuilder.addPrefix(getPrefix())) .build(jda, "net.hypr.doki.commands"); //Registering listeners is taken care of by the lib - if (config.getLevelling()) { - jda.addEventListener(new LevellingListener()); - } else { - log.info("Levelling is disabled"); - } } catch (Exception e) { log.error("Failed to start the bot", e); System.exit(-1); diff --git a/src/main/java/net/hypr/doki/commands/levelling/Leaderboard.java b/src/main/java/net/hypr/doki/commands/levelling/Leaderboard.java deleted file mode 100644 index 36f17ed..0000000 --- a/src/main/java/net/hypr/doki/commands/levelling/Leaderboard.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.hypr.doki.commands.levelling; - -import com.freya02.botcommands.api.annotations.CommandMarker; -import com.freya02.botcommands.api.prefixed.CommandEvent; -import com.freya02.botcommands.api.prefixed.TextCommand; -import com.freya02.botcommands.api.prefixed.annotations.Category; -import com.freya02.botcommands.api.prefixed.annotations.Description; -import com.freya02.botcommands.api.prefixed.annotations.JDATextCommand; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.User; -import net.hypr.doki.utils.DBUtils; -import net.hypr.doki.utils.UserRecord; - -import java.awt.*; -import java.sql.SQLException; -import java.util.List; - -@CommandMarker -@Category("Levelling") -@Description("Get the global leaderboard") -public class Leaderboard extends TextCommand { - @JDATextCommand(name = "leaderboard", order = 1, aliases = { "lb" }) - public void execute(CommandEvent event) throws SQLException { - List userRecords = DBUtils.getAllUserRecords(event.getGuild().getIdLong()); - // Sort the leaderboard highest level first - userRecords.sort((o1, o2) -> o2.totalXp - o1.totalXp); - EmbedBuilder whoIsEmbed = buildLeaderboardEmbed(userRecords, event); - event.reply(whoIsEmbed.build()).queue(); - } - - private EmbedBuilder buildLeaderboardEmbed(List userRecords , CommandEvent event) { - StringBuilder leaderboard = new StringBuilder(); - JDA jda = event.getJDA(); - int idx = 1; - for (UserRecord record : userRecords) { - User user = jda.retrieveUserById(record.user_id).complete(); - leaderboard - .append("**") - .append(idx) - .append(".** ") - .append(user.getName()) - .append(" - ") - .append(record.level) - .append(" (") - .append(record.totalXp) - .append(" Total XP)\n"); - idx += 1; - if (idx > 10) break; // Break out after 10 records is reached - } - return new EmbedBuilder() - .setTitle(event.getGuild().getName() + " Leaderboard") - .setDescription(leaderboard) - .setColor(new Color(210,138,39)); - } -} diff --git a/src/main/java/net/hypr/doki/commands/levelling/Rank.java b/src/main/java/net/hypr/doki/commands/levelling/Rank.java deleted file mode 100644 index a9a66be..0000000 --- a/src/main/java/net/hypr/doki/commands/levelling/Rank.java +++ /dev/null @@ -1,46 +0,0 @@ -package net.hypr.doki.commands.levelling; - -import com.freya02.botcommands.api.annotations.CommandMarker; -import com.freya02.botcommands.api.prefixed.BaseCommandEvent; -import com.freya02.botcommands.api.prefixed.CommandEvent; -import com.freya02.botcommands.api.prefixed.TextCommand; -import com.freya02.botcommands.api.prefixed.annotations.Category; -import com.freya02.botcommands.api.prefixed.annotations.Description; -import com.freya02.botcommands.api.prefixed.annotations.JDATextCommand; -import com.freya02.botcommands.api.prefixed.annotations.TextOption; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.hypr.doki.utils.DBUtils; -import net.hypr.doki.utils.UserRecord; - -import java.sql.SQLException; - -@CommandMarker -@Category("Levelling") -@Description("Get a user's rank") -public class Rank extends TextCommand { - @JDATextCommand(name = "rank", order = 1) - public void execute(BaseCommandEvent event, @TextOption Member member) throws SQLException { - UserRecord userRecord = DBUtils.getUserRecord(member.getIdLong(), event.getGuild().getIdLong()); - EmbedBuilder rankEmbed = buildRankEmbed(member, userRecord); - event.reply(rankEmbed.build()).queue(); - } - - @JDATextCommand(name = "rank", order = 2) - public void execute(CommandEvent event) throws SQLException { - UserRecord userRecord = DBUtils.getUserRecord(event.getMember().getIdLong(), event.getGuild().getIdLong()); - EmbedBuilder whoIsEmbed = buildRankEmbed(event.getMember(), userRecord); - event.reply(whoIsEmbed.build()).queue(); - } - - private EmbedBuilder buildRankEmbed(Member user, UserRecord userRecord) { - int xpToNextLevel = (((userRecord.level + 1) * 5) * 40) - userRecord.xp; - return new EmbedBuilder() - .setAuthor(user.getUser().getName(), null, user.getEffectiveAvatarUrl()) - .setThumbnail(user.getEffectiveAvatarUrl()) - .addField("Level", String.valueOf(userRecord.level), true) - .addField("XP", String.valueOf(userRecord.xp), true) - .addField("XP Until level " + (userRecord.level + 1), String.valueOf(xpToNextLevel), true) - .setColor(user.getColor()); - } -} diff --git a/src/main/java/net/hypr/doki/listeners/LevellingListener.java b/src/main/java/net/hypr/doki/listeners/LevellingListener.java deleted file mode 100644 index bf8afff..0000000 --- a/src/main/java/net/hypr/doki/listeners/LevellingListener.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.hypr.doki.listeners; - -import com.freya02.botcommands.api.Logging; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.message.MessageReceivedEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import net.hypr.doki.Doki; -import net.hypr.doki.utils.DBUtils; -import net.hypr.doki.utils.LevellingUtils; -import net.hypr.doki.utils.UserRecord; -import org.slf4j.Logger; - -import java.sql.SQLException; -import java.time.Duration; -import java.time.LocalDateTime; - -public class LevellingListener extends ListenerAdapter { - @Override - public void onMessageReceived(MessageReceivedEvent event) { - Logger log = Logging.getLogger(); - - /* Ignore the message if one of the following conditions is met: - - Message is from self user - - Message is from a bot - - Message is command (starts with bot prefix) - - Message is a Direct Message to the bot - */ - try { - event.getGuild(); - } catch (IllegalStateException ex) { - log.debug("Ignoring direct message with ID {}", event.getMessageId()); - return; - } - - if ( - Doki.getJDA().getSelfUser().getId().equals(event.getAuthor().getId()) || - event.getAuthor().isBot() || - event.getMessage().getContentStripped().startsWith(Doki.getPrefix()) - ) { - log.debug("Ignoring self/bot message with ID {}", event.getMessageId()); - return; - } - - User user = event.getAuthor(); - Guild guild = event.getGuild(); - boolean userIsInDb = DBUtils.doesUserRecordExist(user.getIdLong(), guild.getIdLong()); - if (userIsInDb) { - try { - UserRecord rec = DBUtils.getUserRecord(user.getIdLong(), guild.getIdLong()); - Duration timeSinceLastMessage = Duration.between( - rec.lastMessage.toLocalDateTime(), - LocalDateTime.now() - ); - if (timeSinceLastMessage.compareTo(Duration.ofHours(1)) > 0) { - // it has been over an hour since the user last sent a message that affected XP - LevellingUtils.incrementXp(log, rec); - } else { - log.debug("Ignoring message ID {} as not enough time has passed", event.getMessageId()); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } - } else { - log.info("No record of user ID {} in server {}, creating blank record", user.getId(), guild.getId()); - try { - UserRecord rec = DBUtils.createUserRecord(user.getIdLong(), guild.getIdLong()); - LevellingUtils.incrementXp(log, rec); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - } -} diff --git a/src/main/java/net/hypr/doki/utils/DBUtils.java b/src/main/java/net/hypr/doki/utils/DBUtils.java deleted file mode 100644 index 352ee52..0000000 --- a/src/main/java/net/hypr/doki/utils/DBUtils.java +++ /dev/null @@ -1,154 +0,0 @@ -package net.hypr.doki.utils; - -import com.freya02.botcommands.api.Logging; -import net.hypr.doki.Doki; -import org.apache.commons.dbcp2.BasicDataSource; -import org.apache.commons.dbutils.QueryRunner; -import org.apache.commons.dbutils.ResultSetHandler; -import org.slf4j.Logger; - -import java.math.BigInteger; -import java.sql.*; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class DBUtils { - /** - * Checks if the user record exists - * @param user_id User ID to search for - * @param server_id Server ID to search for - * @return Whether the record exists or not - */ - public static boolean doesUserRecordExist(long user_id, long server_id) { - Logger log = Logging.getLogger(); - BasicDataSource dataSource = Doki.getDataSource(); - QueryRunner qr = new QueryRunner(dataSource); - ResultSetHandler> resultSetHandler = rs -> { - Set rows = new HashSet<>(); - while (rs.next()) { - rows.add(BigInteger.valueOf(rs.getLong(1))); - } - return rows; - }; - - // Find out if the user is already in the DB - try { - log.debug("Searching DB for (usr{},srv:{})", user_id, server_id); - Set foundIds = qr.query("SELECT user_id FROM users WHERE user_id = " + user_id + " AND server_id = " + server_id, resultSetHandler); - log.debug("Matching records: {}", foundIds.size()); - return !foundIds.isEmpty(); - } catch (SQLException ignored) { - log.debug("An SQL error occurred"); - return false; - } - } - - /** - * Creates a new user record - * @param user_id The users ID - * @param server_id The server ID - * @throws SQLException A SQL exception - */ - public static UserRecord createUserRecord(long user_id, long server_id) throws SQLException { - Logger log = Logging.getLogger(); - log.info("Creating record (usr:{},srv:{})", user_id, server_id); - BasicDataSource dataSource = Doki.getDataSource(); - Connection conn = dataSource.getConnection(); - PreparedStatement stmt = conn.prepareStatement( - "INSERT INTO users (user_id, server_id, last_message) VALUES (?, ?, ?)" - ); - stmt.setLong(1, user_id); - stmt.setLong(2, server_id); - stmt.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now())); - stmt.execute(); - log.info("Record (usr:{},srv:{}) created!", user_id, server_id); - return new UserRecord(user_id, server_id); - } - - /** - * Updates a user record - * @param user_id User ID of the record to update - * @param server_id Server ID of the record to update - * @param now The current time - * @param xp The new XP count - * @param totalXp The new total XP count - * @param level The new level - * @throws SQLException A SQL exception - */ - public static void updateUserRecord(long user_id, long server_id, Timestamp now, int xp, int totalXp, int level) throws SQLException { - Logger log = Logging.getLogger(); - log.info("Updating record (usr:{},srv:{})", user_id, server_id); - BasicDataSource dataSource = Doki.getDataSource(); - Connection conn = dataSource.getConnection(); - PreparedStatement stmt = conn.prepareStatement( - "UPDATE users SET last_message = ?, xp = ?, total_xp = ?, level = ? WHERE user_id = ? AND server_id = ?" - ); - stmt.setTimestamp(1, now); - stmt.setInt(2, xp); - stmt.setInt(3, totalXp); - stmt.setInt(4, level); - stmt.setLong(5, user_id); - stmt.setLong(6, server_id); - stmt.executeQuery(); - log.info("Updated record (usr:{},srv:{})!", user_id, server_id); - } - - /** - * Gets a user record - * @param user_id The User ID of the record to get - * @param server_id The Server ID of the record to get - * @return The found UserRecord - * @throws SQLException A SQL exception - */ - public static UserRecord getUserRecord(long user_id, long server_id) throws SQLException { - BasicDataSource dataSource = Doki.getDataSource(); - Connection conn = dataSource.getConnection(); - PreparedStatement stmt = conn.prepareStatement( - "SELECT user_id, server_id, last_message, xp, total_xp, level FROM users WHERE user_id = ? AND server_id = ?" - ); - stmt.setLong(1, user_id); - stmt.setLong(2, server_id); - ResultSet rs = stmt.executeQuery(); - rs.next(); - return new UserRecord( - rs.getLong("user_id"), - rs.getLong("server_id"), - rs.getTimestamp("last_message"), - rs.getInt("xp"), - rs.getInt("total_xp"), - rs.getInt("level") - ); - } - - /** - * Get all user records for a server - * @param server_id The Server ID - * @return A List of UserRecords - * @throws SQLException A SQL exception - */ - public static List getAllUserRecords(long server_id) throws SQLException { - BasicDataSource dataSource = Doki.getDataSource(); - Connection conn = dataSource.getConnection(); - PreparedStatement stmt = conn.prepareStatement( - "SELECT user_id, last_message, xp, total_xp, level FROM users WHERE server_id = ?" - ); - stmt.setLong(1, server_id); - ResultSet rs = stmt.executeQuery(); - List userRecordList = new ArrayList<>(); - while (rs.next()) { - userRecordList.add(new UserRecord( - rs.getLong("user_id"), - server_id, - rs.getTimestamp("last_message"), - rs.getInt("xp"), - rs.getInt("total_xp"), - rs.getInt("level") - )); - } - return userRecordList; - } -} - diff --git a/src/main/java/net/hypr/doki/utils/LevellingUtils.java b/src/main/java/net/hypr/doki/utils/LevellingUtils.java deleted file mode 100644 index 0173367..0000000 --- a/src/main/java/net/hypr/doki/utils/LevellingUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.hypr.doki.utils; - -import org.slf4j.Logger; - -import java.sql.SQLException; -import java.sql.Timestamp; -import java.time.LocalDateTime; -import java.util.Random; - -public class LevellingUtils { - public static void incrementXp(Logger logger, UserRecord userRecord) throws SQLException { - Random random = new Random(); - // Random increment between 15 and 25 - int xpInc = (random.nextInt(10) + 16) * 3; - int xpNew = userRecord.xp + xpInc; - int totalXp = userRecord.xp + xpInc; - int levelNew = userRecord.level; - if (xpNew >= ((userRecord.level + 1) * 5) * 40) { - levelNew ++; - xpNew = 0; - } - DBUtils.updateUserRecord( - userRecord.user_id, - userRecord.server_id, - Timestamp.valueOf(LocalDateTime.now()), - xpNew, - totalXp, - levelNew - ); - logger.info("Incremented {}'s XP in {} ({} -> {})", userRecord.user_id, userRecord.server_id, userRecord.xp, xpNew); - if (levelNew > userRecord.level) { - logger.info("Incremented {}'s level in {} ({} -> {})", userRecord.user_id, userRecord.server_id, userRecord.level, levelNew); - } - } -} diff --git a/src/main/java/net/hypr/doki/utils/UserRecord.java b/src/main/java/net/hypr/doki/utils/UserRecord.java deleted file mode 100644 index 281c5a0..0000000 --- a/src/main/java/net/hypr/doki/utils/UserRecord.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.hypr.doki.utils; - - -import java.sql.Timestamp; - -public class UserRecord { - public final long user_id; - public final long server_id; - public final Timestamp lastMessage; - public final int xp; - public int totalXp; - public final int level; - - /** - * Instantiates a new UserRecord - * @param user_id The User ID - * @param server_id The Server/Guild ID - */ - public UserRecord (long user_id, long server_id) { - this.user_id = user_id; - this.server_id = server_id; - this.lastMessage = new Timestamp(0); - this.xp = 0; - this.level = 1; - } - - /** - * Instantiates a new UserRecord - * @param user_id The User ID - * @param server_id The Server/Guild ID - * @param lastMessage The timestamp of the user's last message - * @param xp The user's XP - * @param totalXp The user's total XP - * @param level The user's level - */ - public UserRecord (long user_id, long server_id, Timestamp lastMessage, int xp, int totalXp, int level) { - this.user_id = user_id; - this.server_id = server_id; - this.lastMessage = lastMessage; - this.xp = xp; - this.totalXp = totalXp; - this.level = level; - } -}