Fix polls not surviving bot restarts

This commit is contained in:
pixtaded 2025-03-19 23:36:46 +03:00
parent b31828bff5
commit 1f4a607adb
5 changed files with 33 additions and 28 deletions

View File

@ -57,9 +57,16 @@ public class Bot {
logger.info("Database shutdown complete.");
}));
jda.awaitReady();
initinalizeDatabaze();
registerCommands();
}
private static void initinalizeDatabaze() {
logger.info("Initializing the database...");
Database.initializeDatabase();
Database.loadPolls();
}
private static Config readConfig() {
File file = new File("./config.json");

View File

@ -1,6 +1,5 @@
package ru.emotilt.antiplatka.command;
import java.time.Duration;
import java.util.Objects;
import net.dv8tion.jda.api.entities.Member;
@ -38,14 +37,14 @@ public class PollMute extends Command {
BotPollMute.Builder pollbuilder = new BotPollMute.Builder()
.targetUser(member)
.endTimestamp(System.currentTimeMillis() + (Duration.ofMinutes(Bot.config.pollDurations.mute).toMinutes() * 60 * 1000));
.endTimestamp(System.currentTimeMillis() + ((long) Bot.config.pollDurations.mute * 60 * 1000));
interaction
.reply(pollbuilder.buildMessage(String.format("Голосование за мут %s", member.getAsMention())).build())
.queue(i -> i.retrieveOriginal().queue(message -> {
pollbuilder.channel(interaction.getChannel()).message(message);
BotPoll poll = pollbuilder.build();
Database.addPoll(message.getId(), poll);
Database.addPoll(message.getId(), poll, "mute");
}));
}

View File

@ -4,8 +4,9 @@ import java.sql.*;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import ru.emotilt.antiplatka.Bot;
@ -17,19 +18,15 @@ public class Database {
private static final Map<String, BotPoll> currentPolls = new ConcurrentHashMap<>();
private static final ExecutorService asyncWriter = Executors.newCachedThreadPool();
static {
initializeDatabase();
loadPolls();
}
private static void initializeDatabase() {
public static void initializeDatabase() {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
String table = """
CREATE TABLE IF NOT EXISTS polls (
id TEXT PRIMARY KEY,
channelId TEXT,
endTimestamp INTEGER,
type TEXT
type TEXT,
userId TEXT
)
""";
conn.createStatement().execute(table);
@ -38,9 +35,9 @@ public class Database {
}
}
public static void addPoll(String id, BotPoll poll) {
public static void addPoll(String id, BotPoll poll, String type) {
currentPolls.put(id, poll);
asyncWriter.submit(() -> writePollToDatabase(id, poll));
asyncWriter.submit(() -> writePollToDatabase(id, poll, type));
}
public static void removePoll(String id) {
@ -49,9 +46,9 @@ public class Database {
}
@SuppressWarnings("SwitchStatementWithTooFewBranches")
private static void loadPolls() {
public static void loadPolls() {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
String selectSQL = "SELECT id, channelId, endTimestamp, type FROM polls";
String selectSQL = "SELECT id, channelId, endTimestamp, type, userId FROM polls";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(selectSQL)) {
while (rs.next()) {
@ -59,17 +56,16 @@ public class Database {
String channelId = rs.getString("channelId");
long endTimestamp = rs.getLong("endTimestamp");
String type = rs.getString("type");
AtomicReference<Message> messageReference = new AtomicReference<>();
TextChannel channel = Objects.requireNonNull(Bot.getJda().getChannelById(TextChannel.class, channelId));
channel.retrieveMessageById(id).queue(messageReference::set);
Message message = messageReference.get();
Guild guild = Objects.requireNonNull(Bot.getJda().getGuildById(Bot.config.guildId));
Member member = guild.getMemberById(rs.getString("userId"));
TextChannel channel = guild.getChannelById(TextChannel.class, channelId);
Message message = Objects.requireNonNull(channel).retrieveMessageById(id).complete();
BotPoll poll;
switch (type) {
case "PollMute" -> poll = new BotPollMute.Builder()
case "mute" -> poll = new BotPollMute.Builder()
.message(message)
.targetUser(message.getMentions().getMembers().get(0))
.targetUser(member)
.channel(channel)
.endTimestamp(endTimestamp)
.build();
@ -83,14 +79,15 @@ public class Database {
}
}
private static void writePollToDatabase(String id, BotPoll poll) {
private static void writePollToDatabase(String id, BotPoll poll, String type) {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
String insertSQL = "INSERT OR REPLACE INTO polls (id, channelId, endTimestamp, type) VALUES (?, ?, ?, ?)";
String insertSQL = "INSERT OR REPLACE INTO polls (id, channelId, endTimestamp, type, userId) VALUES (?, ?, ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertSQL)) {
pstmt.setString(1, id);
pstmt.setString(2, Objects.requireNonNull(poll.channel).getId());
pstmt.setString(3, Objects.requireNonNull(poll.message).getId());
pstmt.setString(4, poll.getClass().getName());
pstmt.setLong(3, poll.endTimestamp);
pstmt.setString(4, Objects.requireNonNull(type));
pstmt.setString(5, poll.targetUser.getId());
pstmt.executeUpdate();
}
} catch (SQLException e) {

View File

@ -123,7 +123,7 @@ public class OnMessageReceivedEvent extends ListenerAdapter {
return text + " Никто не проголосовал.";
}
if (!isVictory) {
return text + String.format(" Голосование не преодолело порог в **%d%%.", Bot.config.threshold);
return text + String.format(" Голосование не преодолело порог в **%d%%**.", Bot.config.threshold);
}
return text;
}
@ -157,7 +157,7 @@ public class OnMessageReceivedEvent extends ListenerAdapter {
resultMessage.delete().queue();
resultMessage.getChannel().retrieveMessageById(pollMessageId)
.queue(message -> message.delete().queue());
Database.removePoll(resultMessage.getId());
Database.removePoll(pollMessageId);
}
private static class PollResults {

View File

@ -22,6 +22,7 @@ public abstract class BotPoll {
public final Member targetUser;
public final MessageChannel channel;
public final Duration pollDuration;
public final long endTimestamp;
@SuppressWarnings("method.invocation")
protected BotPoll(Builder<?> builder) {
@ -29,6 +30,7 @@ public abstract class BotPoll {
this.targetUser = Objects.requireNonNull(builder.targetUser);
this.channel = Objects.requireNonNull(builder.channel);
this.pollDuration = Objects.requireNonNull(builder.pollDuration);
this.endTimestamp = builder.endTimestamp;
schedulePollCompletion(message);
}