From 2fa2ab9a174d19f4e44b20006dca28921fa2f833 Mon Sep 17 00:00:00 2001 From: kikelkik Date: Tue, 7 Feb 2023 21:50:32 +0100 Subject: [PATCH 1/9] bump versions, fix warnings --- .gitignore | 4 ++ pom.xml | 47 +++++++++++-------- .../rewards/matchers/RewardMatchers.java | 2 +- src/main/resources/plugin.yml | 2 +- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 3eea975..738cfa4 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,7 @@ buildNumber.properties .classpath .project .settings/* + +# IntelliJ +.idea/ +*.iml diff --git a/pom.xml b/pom.xml index 60ba58d..52aaf1a 100644 --- a/pom.xml +++ b/pom.xml @@ -8,6 +8,12 @@ SuperbVote 0.5.5 + + UTF-8 + 17 + 17 + + @@ -16,19 +22,10 @@ - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - 1.8 - 1.8 - - org.apache.maven.plugins maven-shade-plugin - 2.3 + 3.4.1 @@ -40,6 +37,13 @@ io.minimum.minecraft.superbvote.slf4j + + + + maven + + + @@ -59,7 +63,7 @@ clip-repo - http://repo.extendedclip.com/content/repositories/placeholderapi/ + https://repo.extendedclip.com/content/repositories/placeholderapi/ bintray-nuvotifier-repo @@ -75,38 +79,43 @@ org.spigotmc spigot-api - 1.14-R0.1-SNAPSHOT + 1.19-R0.1-SNAPSHOT provided org.projectlombok lombok - 1.18.0 + 1.18.26 provided - com.github.NuVotifier.NuVotifier - nuvotifier-bukkit - v2.6.0 + com.github.NuVotifier + NuVotifier + 2.7.2 provided com.zaxxer HikariCP - 2.7.6 + 5.0.1 compile me.clip placeholderapi - 2.8.2 + 2.11.2 provided com.github.MilkBowl VaultAPI - 1.7 + 1.7.1 provided + + org.apache.commons + commons-lang3 + 3.12.0 + \ No newline at end of file diff --git a/src/main/java/io/minimum/minecraft/superbvote/votes/rewards/matchers/RewardMatchers.java b/src/main/java/io/minimum/minecraft/superbvote/votes/rewards/matchers/RewardMatchers.java index ef0e9d3..4f52fdd 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/votes/rewards/matchers/RewardMatchers.java +++ b/src/main/java/io/minimum/minecraft/superbvote/votes/rewards/matchers/RewardMatchers.java @@ -5,7 +5,7 @@ import com.google.common.collect.ImmutableSet; import io.minimum.minecraft.superbvote.SuperbVote; import net.milkbowl.vault.permission.Permission; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.plugin.RegisteredServiceProvider; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c0cbbd1..cd4302b 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,7 +4,7 @@ author: tuxed version: ${project.version} depend: [Votifier] softdepend: [Vault, PlaceholderAPI] -api-version: "1.13" +api-version: "1.19" commands: superbvote: description: SuperbVote main command. From 2f7eadd48be07213647ab7e0873dfcf41f5165aa Mon Sep 17 00:00:00 2001 From: kikelkik Date: Tue, 7 Feb 2023 22:54:36 +0100 Subject: [PATCH 2/9] add votes.one-vote-per-day option (same player can vote maximum once today) --- .../minecraft/superbvote/votes/SuperbVoteListener.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java index 6799e13..e4303a8 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java +++ b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java @@ -3,6 +3,7 @@ import com.vexsoftware.votifier.model.VotifierEvent; import io.minimum.minecraft.superbvote.SuperbVote; import io.minimum.minecraft.superbvote.commands.SuperbVoteCommand; +import io.minimum.minecraft.superbvote.configuration.SuperbVoteConfiguration; import io.minimum.minecraft.superbvote.configuration.message.MessageContext; import io.minimum.minecraft.superbvote.signboard.TopPlayerSignFetcher; import io.minimum.minecraft.superbvote.storage.MysqlVoteStorage; @@ -88,6 +89,14 @@ private void processVote(PlayerVotes pv, VoteStreak voteStreak, Vote vote, boole throw new RuntimeException("No vote rewards found for '" + vote + "'"); } + boolean hasAlreadyVoted = SuperbVote.getPlugin() + .getVoteStorage() + .hasVotedToday(vote.getUuid()); // TODO: use getVotes(vote.getReceived()) and add lastVote to PlayerVotes + if (hasAlreadyVoted && SuperbVote.getPlugin().getConfig().getBoolean("votes.one-vote-per-day")) { + Date todoReplace = new Date(); // TODO: replace with lastVote date + SuperbVote.getPlugin().getLogger().log(Level.INFO, "Discarding vote: " + vote.getName() + " already voted the same day at " + todoReplace); + return; + } if (queue) { if (!SuperbVote.getPlugin().getConfiguration().shouldQueueVotes()) { SuperbVote.getPlugin().getLogger().log(Level.WARNING, "Ignoring vote from " + vote.getName() + " (service: " + From 0dab784833d7ee19a4d31733c93ca56a0c142b9d Mon Sep 17 00:00:00 2001 From: kikelkik Date: Tue, 7 Feb 2023 23:26:58 +0100 Subject: [PATCH 3/9] compare last vote with received vote date (vote processing might have been queued) --- .../superbvote/storage/JsonVoteStorage.java | 9 ++++++--- .../superbvote/storage/MysqlVoteStorage.java | 19 ++++++++++--------- .../superbvote/util/PlayerVotes.java | 4 ++++ .../superbvote/votes/SuperbVoteListener.java | 18 ++++++++++-------- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java b/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java index cc28dcf..05d3735 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java +++ b/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java @@ -143,8 +143,10 @@ public PlayerVotes getVotes(UUID player) { rwl.readLock().lock(); try { PlayerRecord pr = voteCounts.get(player); - return new PlayerVotes(player, pr != null ? pr.lastKnownUsername : null, pr == null ? 0 : pr.votes, - PlayerVotes.Type.CURRENT); + if (pr == null) { + return new PlayerVotes(player, null, 0, null, PlayerVotes.Type.CURRENT); + } + return new PlayerVotes(player, pr.lastKnownUsername, pr.votes, Date.from(Instant.ofEpochMilli(pr.lastVoted)), PlayerVotes.Type.CURRENT); } finally { rwl.readLock().unlock(); } @@ -160,7 +162,8 @@ public List getTopVoters(int amount, int page) { .sorted(Collections.reverseOrder(Comparator.comparing(Map.Entry::getValue))) .skip(skip) .limit(amount) - .map(e -> new PlayerVotes(e.getKey(), e.getValue().lastKnownUsername, e.getValue().votes, PlayerVotes.Type.CURRENT)) + .map(e -> new PlayerVotes(e.getKey(), e.getValue().lastKnownUsername, e.getValue().votes, + Date.from(Instant.ofEpochMilli(e.getValue().lastVoted)), PlayerVotes.Type.CURRENT)) .collect(Collectors.toList()); } finally { rwl.readLock().unlock(); diff --git a/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java b/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java index ad5c569..d5dcab1 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java +++ b/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java @@ -216,19 +216,19 @@ public void clearVotes() { public PlayerVotes getVotes(UUID player) { Preconditions.checkNotNull(player, "player"); try (Connection connection = dbPool.getConnection()) { - try (PreparedStatement statement = connection.prepareStatement("SELECT last_name, votes FROM " + tableName + " WHERE uuid = ?")) { + try (PreparedStatement statement = connection.prepareStatement("SELECT last_name, votes, last_vote FROM " + tableName + " WHERE uuid = ?")) { statement.setString(1, player.toString()); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { - return new PlayerVotes(player, resultSet.getString(1), resultSet.getInt(2), PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, resultSet.getString(1), resultSet.getInt(2), resultSet.getDate(3), PlayerVotes.Type.CURRENT); } else { - return new PlayerVotes(player, null, 0, PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, null, 0, null, PlayerVotes.Type.CURRENT); } } } } catch (SQLException e) { SuperbVote.getPlugin().getLogger().log(Level.SEVERE, "Unable to get votes for " + player.toString(), e); - return new PlayerVotes(player, null, 0, PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, null, 0, null, PlayerVotes.Type.CURRENT); } } @@ -236,14 +236,14 @@ public PlayerVotes getVotes(UUID player) { public List getTopVoters(int amount, int page) { int offset = page * amount; try (Connection connection = dbPool.getConnection()) { - try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes FROM " + tableName + " WHERE votes > 0 ORDER BY votes DESC " + + try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes, last_vote FROM " + tableName + " WHERE votes > 0 ORDER BY votes DESC " + "LIMIT " + amount + " OFFSET " + offset)) { try (ResultSet resultSet = statement.executeQuery()) { List records = new ArrayList<>(); while (resultSet.next()) { UUID uuid = UUID.fromString(resultSet.getString(1)); String name = resultSet.getString(2); - records.add(new PlayerVotes(uuid, name, resultSet.getInt(3), PlayerVotes.Type.CURRENT)); + records.add(new PlayerVotes(uuid, name, resultSet.getInt(3), resultSet.getDate(4), PlayerVotes.Type.CURRENT)); } return records; } @@ -293,7 +293,7 @@ public List getAllPlayersWithNoVotesToday(List onlinePlayers) List votes = new ArrayList<>(); try (Connection connection = dbPool.getConnection()) { String valueStatement = Joiner.on(", ").join(Collections.nCopies(onlinePlayers.size(), "?")); - try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes, (DATE(last_vote) = CURRENT_DATE()) AS has_voted_today FROM " + tableName + " WHERE uuid IN (" + valueStatement + ")")) { + try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes, last_vote, (DATE(last_vote) = CURRENT_DATE()) AS has_voted_today FROM " + tableName + " WHERE uuid IN (" + valueStatement + ")")) { for (int i = 0; i < onlinePlayers.size(); i++) { statement.setString(i + 1, onlinePlayers.get(i).toString()); } @@ -302,12 +302,13 @@ public List getAllPlayersWithNoVotesToday(List onlinePlayers) while (resultSet.next()) { UUID uuid = UUID.fromString(resultSet.getString(1)); found.add(uuid); - if (resultSet.getBoolean(4)) { + if (resultSet.getBoolean(5)) { continue; // already voted today } PlayerVotes pv = new PlayerVotes(UUID.fromString(resultSet.getString(1)), resultSet.getString(2), resultSet.getInt(3), + resultSet.getDate(4), PlayerVotes.Type.CURRENT); votes.add(pv); } @@ -317,7 +318,7 @@ public List getAllPlayersWithNoVotesToday(List onlinePlayers) List missing = new ArrayList<>(onlinePlayers); missing.removeAll(found); for (UUID uuid : missing) { - votes.add(new PlayerVotes(uuid, null, 0, PlayerVotes.Type.CURRENT)); + votes.add(new PlayerVotes(uuid, null, 0, null, PlayerVotes.Type.CURRENT)); } } return votes; diff --git a/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java b/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java index de23b97..4d0d604 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java +++ b/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java @@ -1,5 +1,7 @@ package io.minimum.minecraft.superbvote.util; +import java.util.Date; +import javax.annotation.Nullable; import lombok.Value; import org.bukkit.Bukkit; @@ -10,6 +12,8 @@ public class PlayerVotes { private final UUID uuid; private final String associatedUsername; private final int votes; + @Nullable + private final Date lastVote; private final Type type; public String getAssociatedUsername() { diff --git a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java index e4303a8..f415b74 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java +++ b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java @@ -11,6 +11,7 @@ import io.minimum.minecraft.superbvote.util.BrokenNag; import io.minimum.minecraft.superbvote.util.PlayerVotes; import io.minimum.minecraft.superbvote.votes.rewards.VoteReward; +import org.apache.commons.lang3.time.DateUtils; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; @@ -43,7 +44,7 @@ public void onVote(final VotifierEvent event) { VoteStorage voteStorage = SuperbVote.getPlugin().getVoteStorage(); VoteStreak voteStreak = voteStorage.getVoteStreakIfSupported(op.getUniqueId(), false); PlayerVotes pvCurrent = voteStorage.getVotes(op.getUniqueId()); - PlayerVotes pv = new PlayerVotes(op.getUniqueId(), op.getName(), pvCurrent.getVotes() + 1, PlayerVotes.Type.FUTURE); + PlayerVotes pv = new PlayerVotes(op.getUniqueId(), op.getName(), pvCurrent.getVotes() + 1, pvCurrent.getLastVote(), PlayerVotes.Type.FUTURE); Vote vote = new Vote(op.getName(), op.getUniqueId(), event.getVote().getServiceName(), event.getVote().getAddress().equals(SuperbVoteCommand.FAKE_HOST_NAME_FOR_VOTE), worldName, new Date()); @@ -89,12 +90,13 @@ private void processVote(PlayerVotes pv, VoteStreak voteStreak, Vote vote, boole throw new RuntimeException("No vote rewards found for '" + vote + "'"); } - boolean hasAlreadyVoted = SuperbVote.getPlugin() - .getVoteStorage() - .hasVotedToday(vote.getUuid()); // TODO: use getVotes(vote.getReceived()) and add lastVote to PlayerVotes - if (hasAlreadyVoted && SuperbVote.getPlugin().getConfig().getBoolean("votes.one-vote-per-day")) { - Date todoReplace = new Date(); // TODO: replace with lastVote date - SuperbVote.getPlugin().getLogger().log(Level.INFO, "Discarding vote: " + vote.getName() + " already voted the same day at " + todoReplace); + if (pv.getLastVote() != null + && DateUtils.isSameDay(pv.getLastVote(), vote.getReceived()) + && SuperbVote.getPlugin().getConfig().getBoolean("votes.one-vote-per-day")) { + + SuperbVote.getPlugin() + .getLogger() + .log(Level.INFO, "Discarding vote: " + vote.getName() + " already received a vote the same day at " + vote.getReceived()); return; } if (queue) { @@ -150,7 +152,7 @@ public void onPlayerJoin(PlayerJoinEvent event) { if (!votes.isEmpty()) { for (Vote vote : votes) { processVote(pv, voteStreak, vote, false, false, true); - pv = new PlayerVotes(pv.getUuid(), event.getPlayer().getName(),pv.getVotes() + 1, PlayerVotes.Type.CURRENT); + pv = new PlayerVotes(pv.getUuid(), event.getPlayer().getName(),pv.getVotes() + 1, pv.getLastVote(), PlayerVotes.Type.CURRENT); } afterVoteProcessing(); } From f6db5e2c360710e9e4f7aedc2bddf8e528a6c5f9 Mon Sep 17 00:00:00 2001 From: kikelkik Date: Wed, 8 Feb 2023 00:09:18 +0100 Subject: [PATCH 4/9] add config option --- src/main/resources/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 53d9838..a4cb1e3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -26,6 +26,9 @@ votes: # Whether or not to treat fake votes as real votes process-fake-votes: true + # Whether to allow only one vote per day for each player + one-vote-per-day: false + # Streaks configuration # Important: Streaks does not support JSON storage streaks: From 2866b50f986d9cdc124590509a3a6630e0ab8bc4 Mon Sep 17 00:00:00 2001 From: kikelkik Date: Wed, 8 Feb 2023 00:13:31 +0100 Subject: [PATCH 5/9] lazy evaluate configuration first --- .../minecraft/superbvote/votes/SuperbVoteListener.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java index f415b74..38777ad 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java +++ b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java @@ -90,9 +90,9 @@ private void processVote(PlayerVotes pv, VoteStreak voteStreak, Vote vote, boole throw new RuntimeException("No vote rewards found for '" + vote + "'"); } - if (pv.getLastVote() != null - && DateUtils.isSameDay(pv.getLastVote(), vote.getReceived()) - && SuperbVote.getPlugin().getConfig().getBoolean("votes.one-vote-per-day")) { + if (SuperbVote.getPlugin().getConfig().getBoolean("votes.one-vote-per-day") + && pv.getLastVote() != null + && DateUtils.isSameDay(pv.getLastVote(), vote.getReceived())) { SuperbVote.getPlugin() .getLogger() From e2354269f1278bd0cf32d2c505f6d056eb595638 Mon Sep 17 00:00:00 2001 From: kikelkik Date: Tue, 28 Mar 2023 13:25:39 +0200 Subject: [PATCH 6/9] don't register vote/votestreak if disabled --- pom.xml | 2 +- .../minimum/minecraft/superbvote/SuperbVote.java | 15 +++++++++++---- src/main/resources/plugin.yml | 5 ----- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 52aaf1a..40be8e3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.minimum.minecraft SuperbVote - 0.5.5 + 0.5.6-CORP-2 UTF-8 diff --git a/src/main/java/io/minimum/minecraft/superbvote/SuperbVote.java b/src/main/java/io/minimum/minecraft/superbvote/SuperbVote.java index 047df05..22b86ec 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/SuperbVote.java +++ b/src/main/java/io/minimum/minecraft/superbvote/SuperbVote.java @@ -75,8 +75,7 @@ public void onEnable() { } getCommand("superbvote").setExecutor(new SuperbVoteCommand()); - getCommand("vote").setExecutor(configuration.getVoteCommand()); - getCommand("votestreak").setExecutor(configuration.getVoteStreakCommand()); + registerCommands(); getServer().getPluginManager().registerEvents(new SuperbVoteListener(), this); getServer().getPluginManager().registerEvents(new TopPlayerSignListener(), this); @@ -124,8 +123,7 @@ public void reloadPlugin() { scoreboardHandler.reload(); voteServiceCooldown = new VoteServiceCooldown(getConfig().getInt("votes.cooldown-per-service", 3600)); getServer().getScheduler().runTaskAsynchronously(this, getScoreboardHandler()::doPopulate); - getCommand("vote").setExecutor(configuration.getVoteCommand()); - getCommand("votestreak").setExecutor(configuration.getVoteStreakCommand()); + registerCommands(); if (voteReminderTask != null) { voteReminderTask.cancel(); @@ -141,4 +139,13 @@ public void reloadPlugin() { public ClassLoader _exposeClassLoader() { return getClassLoader(); } + + private void registerCommands() { + if (configuration.getVoteCommand() != null) { + getCommand("vote").setExecutor(configuration.getVoteCommand()); + } + if (configuration.getVoteStreakCommand() != null) { + getCommand("votestreak").setExecutor(configuration.getVoteStreakCommand()); + } + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index cd4302b..083c3f7 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -9,11 +9,6 @@ commands: superbvote: description: SuperbVote main command. aliases: [sv] - vote: - description: SuperbVote vote command. - votestreak: - description: SuperbVote vote streak command. - aliases: [vstreak] permissions: superbvote.notify: default: true From 2bd5d69641dfd2de6aa6e9ad4ea2b0546255c0f5 Mon Sep 17 00:00:00 2001 From: kikelkik <14167723+kikelkik@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:18:58 +0100 Subject: [PATCH 7/9] store last vote dates grouped by corresponding vote service (#1) * store last vote dates grouped by corresponding vote service Corpium/Corpium#143 * don't check latest version for -CORP specifier * fix latest vote dates --- pom.xml | 17 +++-- .../SuperbVoteConfiguration.java | 5 ++ .../superbvote/storage/JsonVoteStorage.java | 9 +-- .../superbvote/storage/MysqlVoteStorage.java | 64 +++++++++++------ .../superbvote/storage/VoteStorage.java | 2 +- .../superbvote/util/PlayerVotes.java | 69 +++++++++++++++++-- .../superbvote/util/SpigotUpdater.java | 4 +- .../superbvote/votes/SuperbVoteListener.java | 29 +++++--- 8 files changed, 147 insertions(+), 52 deletions(-) diff --git a/pom.xml b/pom.xml index 40be8e3..02ebe21 100644 --- a/pom.xml +++ b/pom.xml @@ -6,12 +6,12 @@ io.minimum.minecraft SuperbVote - 0.5.6-CORP-2 + 0.6.0-CORP UTF-8 - 17 - 17 + 21 + 21 @@ -25,7 +25,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.6.0 @@ -85,7 +85,7 @@ org.projectlombok lombok - 1.18.26 + 1.18.36 provided @@ -117,5 +117,10 @@ commons-lang3 3.12.0 + + com.fasterxml.jackson.core + jackson-databind + 2.18.1 + - \ No newline at end of file + diff --git a/src/main/java/io/minimum/minecraft/superbvote/configuration/SuperbVoteConfiguration.java b/src/main/java/io/minimum/minecraft/superbvote/configuration/SuperbVoteConfiguration.java index 8923d03..6c7b0aa 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/configuration/SuperbVoteConfiguration.java +++ b/src/main/java/io/minimum/minecraft/superbvote/configuration/SuperbVoteConfiguration.java @@ -202,6 +202,11 @@ public VoteStorage initializeVoteStorage() throws IOException { file = "votes.json"; SuperbVote.getPlugin().getLogger().info("No file found in configuration, using 'votes.json'."); } + if (configuration.getBoolean("votes.one-vote-per-day")) { + SuperbVote.getPlugin().getLogger() + .warning("votes.one-vote-per-day=true is not fully supported with JSON storage! " + + "Use mysql instead if you need this feature to work properly."); + } return new JsonVoteStorage(new File(SuperbVote.getPlugin().getDataFolder(), file)); case "mysql": String host = configuration.getString("storage.mysql.host", "localhost"); diff --git a/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java b/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java index 05d3735..115577b 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java +++ b/src/main/java/io/minimum/minecraft/superbvote/storage/JsonVoteStorage.java @@ -90,7 +90,7 @@ private VotingFile migrateOldVersion(Map votes) throws IOExceptio } @Override - public void addVote(Vote vote) { + public void addVote(Vote vote, PlayerVotes playerVotes) { Preconditions.checkNotNull(vote, "vote"); rwl.writeLock().lock(); try { @@ -144,9 +144,9 @@ public PlayerVotes getVotes(UUID player) { try { PlayerRecord pr = voteCounts.get(player); if (pr == null) { - return new PlayerVotes(player, null, 0, null, PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, null, 0, Collections.emptyMap(), PlayerVotes.Type.CURRENT); } - return new PlayerVotes(player, pr.lastKnownUsername, pr.votes, Date.from(Instant.ofEpochMilli(pr.lastVoted)), PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, pr.lastKnownUsername, pr.votes, Collections.emptyMap(), PlayerVotes.Type.CURRENT); } finally { rwl.readLock().unlock(); } @@ -163,7 +163,8 @@ public List getTopVoters(int amount, int page) { .skip(skip) .limit(amount) .map(e -> new PlayerVotes(e.getKey(), e.getValue().lastKnownUsername, e.getValue().votes, - Date.from(Instant.ofEpochMilli(e.getValue().lastVoted)), PlayerVotes.Type.CURRENT)) + Collections.emptyMap(), + PlayerVotes.Type.CURRENT)) .collect(Collectors.toList()); } finally { rwl.readLock().unlock(); diff --git a/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java b/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java index d5dcab1..0eee25b 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java +++ b/src/main/java/io/minimum/minecraft/superbvote/storage/MysqlVoteStorage.java @@ -29,7 +29,8 @@ public class MysqlVoteStorage implements ExtendedVoteStorage { private static final int TABLE_VERSION_2 = 2; private static final int TABLE_VERSION_3 = 3; private static final int TABLE_VERSION_4 = 4; - private static final int TABLE_VERSION_CURRENT = TABLE_VERSION_4; + private static final int TABLE_VERSION_5 = 5; + private static final int TABLE_VERSION_CURRENT = TABLE_VERSION_5; private final HikariPool dbPool; private final String tableName, streaksTableName; @@ -47,7 +48,7 @@ public void initialize() { try (ResultSet t = connection.getMetaData().getTables(null, null, tableName, null)) { if (!t.next()) { try (Statement statement = connection.createStatement()) { - statement.executeUpdate("CREATE TABLE " + tableName + " (uuid VARCHAR(36) PRIMARY KEY NOT NULL, last_name VARCHAR(16), votes INT NOT NULL, last_vote TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP)"); + statement.executeUpdate("CREATE TABLE " + tableName + " (uuid VARCHAR(36) PRIMARY KEY NOT NULL, last_name VARCHAR(16), votes INT NOT NULL, last_vote TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, last_votes VARCHAR(256))"); // This may speed up leaderboards statement.executeUpdate("CREATE INDEX uuid_votes_idx ON " + tableName + " (uuid, votes)"); } @@ -74,6 +75,12 @@ public void initialize() { statement.executeUpdate("ALTER TABLE " + tableName + " MODIFY votes int(11) NOT NULL DEFAULT 0"); } } + if (ver < TABLE_VERSION_5) { + try (Statement statement = connection.createStatement()) { + statement.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN last_votes VARCHAR(256)"); + } + isUpdated = true; + } } } } @@ -106,28 +113,34 @@ public void initialize() { } @Override - public void addVote(Vote vote) { + public void addVote(Vote vote, PlayerVotes playerVotes) { if (readOnly) return; Preconditions.checkNotNull(vote, "vote"); try (Connection connection = dbPool.getConnection()) { + Timestamp voteReceivedTimestamp = new Timestamp(vote.getReceived() + .getTime()); if (vote.getName() != null) { - try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + tableName + " (uuid, last_name, votes, last_vote) VALUES (?, ?, 1, ?)" + - " ON DUPLICATE KEY UPDATE votes = votes + 1, last_name = ?, last_vote = ?")) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + tableName + " (uuid, last_name, votes, last_vote, last_votes) VALUES (?, ?, 1, ?, ?)" + + " ON DUPLICATE KEY UPDATE votes = votes + 1, last_name = ?, last_vote = ?, last_votes = ?")) { statement.setString(1, vote.getUuid().toString()); statement.setString(2, vote.getName()); - statement.setTimestamp(3, new Timestamp(vote.getReceived().getTime())); - statement.setString(4, vote.getName()); - statement.setTimestamp(5, new Timestamp(vote.getReceived().getTime())); + statement.setTimestamp(3, voteReceivedTimestamp); + statement.setString(4, playerVotes.getSerializedLastVotes()); + statement.setString(5, vote.getName()); + statement.setTimestamp(6, voteReceivedTimestamp); + statement.setString(7, playerVotes.getSerializedLastVotes()); statement.executeUpdate(); } } else { - try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + tableName + " (uuid, last_name, votes, last_vote) VALUES (?, NULL, 1, ?)" + - " ON DUPLICATE KEY UPDATE votes = votes + 1, last_vote = ?")) { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + tableName + " (uuid, last_name, votes, last_vote, last_votes) VALUES (?, NULL, 1, ?, ?)" + + " ON DUPLICATE KEY UPDATE votes = votes + 1, last_vote = ?, last_votes = ?")) { statement.setString(1, vote.getUuid().toString()); - statement.setTimestamp(2, new Timestamp(vote.getReceived().getTime())); - statement.setTimestamp(3, new Timestamp(vote.getReceived().getTime())); + statement.setTimestamp(2, voteReceivedTimestamp); + statement.setString(3, playerVotes.getSerializedLastVotes()); + statement.setTimestamp(4, voteReceivedTimestamp); + statement.setString(5, playerVotes.getSerializedLastVotes()); statement.executeUpdate(); } } @@ -184,7 +197,7 @@ public void setVotes(UUID player, int votes, long ts) { Preconditions.checkNotNull(player, "player"); try (Connection connection = dbPool.getConnection()) { - try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + tableName + " (uuid, votes, last_vote) VALUES (?, ?, ?)" + + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + tableName + " (uuid, votes, last_vote, last_votes) VALUES (?, ?, ?, NULL)" + " ON DUPLICATE KEY UPDATE votes = ?, last_vote = ?")) { statement.setString(1, player.toString()); statement.setInt(2, votes); @@ -216,19 +229,23 @@ public void clearVotes() { public PlayerVotes getVotes(UUID player) { Preconditions.checkNotNull(player, "player"); try (Connection connection = dbPool.getConnection()) { - try (PreparedStatement statement = connection.prepareStatement("SELECT last_name, votes, last_vote FROM " + tableName + " WHERE uuid = ?")) { + try (PreparedStatement statement = connection.prepareStatement("SELECT last_name, votes, last_votes FROM " + tableName + " WHERE uuid = ?")) { statement.setString(1, player.toString()); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { - return new PlayerVotes(player, resultSet.getString(1), resultSet.getInt(2), resultSet.getDate(3), PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, + resultSet.getString(1), + resultSet.getInt(2), + PlayerVotes.deserializeLastVotes(resultSet.getString(3)), + PlayerVotes.Type.CURRENT); } else { - return new PlayerVotes(player, null, 0, null, PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, null, 0, Collections.emptyMap(), PlayerVotes.Type.CURRENT); } } } } catch (SQLException e) { SuperbVote.getPlugin().getLogger().log(Level.SEVERE, "Unable to get votes for " + player.toString(), e); - return new PlayerVotes(player, null, 0, null, PlayerVotes.Type.CURRENT); + return new PlayerVotes(player, null, 0, Collections.emptyMap(), PlayerVotes.Type.CURRENT); } } @@ -236,14 +253,17 @@ public PlayerVotes getVotes(UUID player) { public List getTopVoters(int amount, int page) { int offset = page * amount; try (Connection connection = dbPool.getConnection()) { - try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes, last_vote FROM " + tableName + " WHERE votes > 0 ORDER BY votes DESC " + + try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes, last_votes FROM " + tableName + " WHERE votes > 0 ORDER BY votes DESC " + "LIMIT " + amount + " OFFSET " + offset)) { try (ResultSet resultSet = statement.executeQuery()) { List records = new ArrayList<>(); while (resultSet.next()) { UUID uuid = UUID.fromString(resultSet.getString(1)); String name = resultSet.getString(2); - records.add(new PlayerVotes(uuid, name, resultSet.getInt(3), resultSet.getDate(4), PlayerVotes.Type.CURRENT)); + records.add(new PlayerVotes(uuid, name, + resultSet.getInt(3), + PlayerVotes.deserializeLastVotes(resultSet.getString(4)), + PlayerVotes.Type.CURRENT)); } return records; } @@ -293,7 +313,7 @@ public List getAllPlayersWithNoVotesToday(List onlinePlayers) List votes = new ArrayList<>(); try (Connection connection = dbPool.getConnection()) { String valueStatement = Joiner.on(", ").join(Collections.nCopies(onlinePlayers.size(), "?")); - try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes, last_vote, (DATE(last_vote) = CURRENT_DATE()) AS has_voted_today FROM " + tableName + " WHERE uuid IN (" + valueStatement + ")")) { + try (PreparedStatement statement = connection.prepareStatement("SELECT uuid, last_name, votes, last_votes, (DATE(last_vote) = CURRENT_DATE()) AS has_voted_today FROM " + tableName + " WHERE uuid IN (" + valueStatement + ")")) { for (int i = 0; i < onlinePlayers.size(); i++) { statement.setString(i + 1, onlinePlayers.get(i).toString()); } @@ -308,7 +328,7 @@ public List getAllPlayersWithNoVotesToday(List onlinePlayers) PlayerVotes pv = new PlayerVotes(UUID.fromString(resultSet.getString(1)), resultSet.getString(2), resultSet.getInt(3), - resultSet.getDate(4), + PlayerVotes.deserializeLastVotes(resultSet.getString(4)), PlayerVotes.Type.CURRENT); votes.add(pv); } @@ -318,7 +338,7 @@ public List getAllPlayersWithNoVotesToday(List onlinePlayers) List missing = new ArrayList<>(onlinePlayers); missing.removeAll(found); for (UUID uuid : missing) { - votes.add(new PlayerVotes(uuid, null, 0, null, PlayerVotes.Type.CURRENT)); + votes.add(new PlayerVotes(uuid, null, 0, Collections.emptyMap(), PlayerVotes.Type.CURRENT)); } } return votes; diff --git a/src/main/java/io/minimum/minecraft/superbvote/storage/VoteStorage.java b/src/main/java/io/minimum/minecraft/superbvote/storage/VoteStorage.java index f27a35d..52f3bd9 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/storage/VoteStorage.java +++ b/src/main/java/io/minimum/minecraft/superbvote/storage/VoteStorage.java @@ -8,7 +8,7 @@ import java.util.UUID; public interface VoteStorage { - void addVote(Vote vote); + void addVote(Vote vote, PlayerVotes playerVotes); default void setVotes(UUID player, int votes) { setVotes(player, votes, System.currentTimeMillis()); diff --git a/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java b/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java index 4d0d604..f209c23 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java +++ b/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java @@ -1,19 +1,27 @@ package io.minimum.minecraft.superbvote.util; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.minimum.minecraft.superbvote.SuperbVote; import java.util.Date; -import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; import lombok.Value; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; import org.bukkit.Bukkit; -import java.util.UUID; - @Value public class PlayerVotes { + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private final UUID uuid; private final String associatedUsername; private final int votes; - @Nullable - private final Date lastVote; + private final Map lastVotes; private final Type type; public String getAssociatedUsername() { @@ -25,6 +33,55 @@ public String getAssociatedUsername() { public enum Type { CURRENT, - FUTURE + FUTURE; + + } + public boolean hasVoteOnSameDay(String serviceName, Date voteDate) { + Date lastVoteDate = lastVotes.get(serviceName); + if (lastVoteDate == null) { + return false; + } + if (lastVoteDate.equals(voteDate)) { + // the new vote is just about being processed right now + return false; + } + return DateUtils.isSameDay(lastVoteDate, voteDate); + } + + public void updateLastVotes(String serviceName, Date voteReceived) { + lastVotes.put(serviceName, voteReceived); + } + + public String getSerializedLastVotes() { + try { + Map preprocessed = new HashMap<>(); + for (Map.Entry entry : lastVotes.entrySet()) { + long dateSeconds = entry.getValue().getTime() / 1000; + preprocessed.put(entry.getKey(), new Date(dateSeconds)); + } + return OBJECT_MAPPER.writeValueAsString(preprocessed); + } catch (JsonProcessingException e) { + SuperbVote.getPlugin() + .getLogger() + .severe("Could not serialize last votes to JSON: " + lastVotes + "\n" + e.getMessage()); + return ""; + } + } + + public static Map deserializeLastVotes(String lastVotesString) { + if (StringUtils.isBlank(lastVotesString)) { + return new HashMap<>(); + } + try { + Map lastVotes = OBJECT_MAPPER.readValue(lastVotesString, new TypeReference<>() {}); + return lastVotes.entrySet() + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new Date(e.getValue() * 1000))); + } catch (JsonProcessingException e) { + SuperbVote.getPlugin() + .getLogger() + .severe("Could not deserialize last votes from JSON: " + lastVotesString + "\n" + e.getMessage()); + return new HashMap<>(); + } } } diff --git a/src/main/java/io/minimum/minecraft/superbvote/util/SpigotUpdater.java b/src/main/java/io/minimum/minecraft/superbvote/util/SpigotUpdater.java index e8a89c1..7ecd387 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/util/SpigotUpdater.java +++ b/src/main/java/io/minimum/minecraft/superbvote/util/SpigotUpdater.java @@ -1,7 +1,7 @@ package io.minimum.minecraft.superbvote.util; import com.google.common.io.ByteStreams; -import io.minimum.minecraft.superbvote.SuperbVote;; +import io.minimum.minecraft.superbvote.SuperbVote; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.event.EventHandler; @@ -39,7 +39,7 @@ private static String getLatestVersion() throws IOException { @Override public void run() { String myVersion = SuperbVote.getPlugin().getDescription().getVersion(); - if (myVersion.endsWith("-SNAPSHOT")) { + if (myVersion.endsWith("-SNAPSHOT") || myVersion.endsWith("-CORP")) { // Nothing to do. return; } diff --git a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java index 38777ad..5b407eb 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java +++ b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java @@ -3,7 +3,6 @@ import com.vexsoftware.votifier.model.VotifierEvent; import io.minimum.minecraft.superbvote.SuperbVote; import io.minimum.minecraft.superbvote.commands.SuperbVoteCommand; -import io.minimum.minecraft.superbvote.configuration.SuperbVoteConfiguration; import io.minimum.minecraft.superbvote.configuration.message.MessageContext; import io.minimum.minecraft.superbvote.signboard.TopPlayerSignFetcher; import io.minimum.minecraft.superbvote.storage.MysqlVoteStorage; @@ -11,6 +10,8 @@ import io.minimum.minecraft.superbvote.util.BrokenNag; import io.minimum.minecraft.superbvote.util.PlayerVotes; import io.minimum.minecraft.superbvote.votes.rewards.VoteReward; +import java.util.HashMap; +import java.util.Map; import org.apache.commons.lang3.time.DateUtils; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; @@ -41,13 +42,15 @@ public void onVote(final VotifierEvent event) { worldName = op.getPlayer().getWorld().getName(); } - VoteStorage voteStorage = SuperbVote.getPlugin().getVoteStorage(); - VoteStreak voteStreak = voteStorage.getVoteStreakIfSupported(op.getUniqueId(), false); - PlayerVotes pvCurrent = voteStorage.getVotes(op.getUniqueId()); - PlayerVotes pv = new PlayerVotes(op.getUniqueId(), op.getName(), pvCurrent.getVotes() + 1, pvCurrent.getLastVote(), PlayerVotes.Type.FUTURE); Vote vote = new Vote(op.getName(), op.getUniqueId(), event.getVote().getServiceName(), event.getVote().getAddress().equals(SuperbVoteCommand.FAKE_HOST_NAME_FOR_VOTE), worldName, new Date()); + VoteStorage voteStorage = SuperbVote.getPlugin().getVoteStorage(); + PlayerVotes pvCurrent = voteStorage.getVotes(op.getUniqueId()); + PlayerVotes pv = new PlayerVotes(op.getUniqueId(), op.getName(), pvCurrent.getVotes() + 1, + pvCurrent.getLastVotes(), PlayerVotes.Type.FUTURE); + + VoteStreak voteStreak = voteStorage.getVoteStreakIfSupported(op.getUniqueId(), false); if (!vote.isFakeVote()) { if (SuperbVote.getPlugin().getConfiguration().getStreaksConfiguration().isSharedCooldownPerService()) { if (voteStreak == null) { @@ -91,17 +94,19 @@ private void processVote(PlayerVotes pv, VoteStreak voteStreak, Vote vote, boole } if (SuperbVote.getPlugin().getConfig().getBoolean("votes.one-vote-per-day") - && pv.getLastVote() != null - && DateUtils.isSameDay(pv.getLastVote(), vote.getReceived())) { + && pv.hasVoteOnSameDay(vote.getServiceName(), vote.getReceived())) { SuperbVote.getPlugin() .getLogger() - .log(Level.INFO, "Discarding vote: " + vote.getName() + " already received a vote the same day at " + vote.getReceived()); + .log(Level.INFO, "Discarding vote: " + vote.getName() + + " already received a vote the same day at " + pv.getLastVotes().get(vote.getServiceName()) + + " for service:" + vote.getServiceName()); return; } + pv.updateLastVotes(vote.getServiceName(), vote.getReceived()); if (queue) { if (!SuperbVote.getPlugin().getConfiguration().shouldQueueVotes()) { - SuperbVote.getPlugin().getLogger().log(Level.WARNING, "Ignoring vote from " + vote.getName() + " (service: " + + SuperbVote.getPlugin().getLogger().log(Level.WARNING, "Ignoring vote from " + vote.getName() + " (service:" + vote.getServiceName() + ") because they aren't online."); return; } @@ -113,7 +118,7 @@ private void processVote(PlayerVotes pv, VoteStreak voteStreak, Vote vote, boole SuperbVote.getPlugin().getQueuedVotes().addVote(vote); } else { if (!vote.isFakeVote() || SuperbVote.getPlugin().getConfig().getBoolean("votes.process-fake-votes")) { - SuperbVote.getPlugin().getVoteStorage().addVote(vote); + SuperbVote.getPlugin().getVoteStorage().addVote(vote, pv); } if (!wasQueued) { @@ -152,7 +157,9 @@ public void onPlayerJoin(PlayerJoinEvent event) { if (!votes.isEmpty()) { for (Vote vote : votes) { processVote(pv, voteStreak, vote, false, false, true); - pv = new PlayerVotes(pv.getUuid(), event.getPlayer().getName(),pv.getVotes() + 1, pv.getLastVote(), PlayerVotes.Type.CURRENT); + pv = new PlayerVotes(pv.getUuid(), event.getPlayer().getName(),pv.getVotes() + 1, + pv.getLastVotes(), PlayerVotes.Type.CURRENT); + pv.updateLastVotes(vote.getServiceName(), vote.getReceived()); } afterVoteProcessing(); } From d4c307a49f63c40e7fdb710c041c2756ac846600 Mon Sep 17 00:00:00 2001 From: kikelkik <14167723+kikelkik@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:01:06 +0100 Subject: [PATCH 8/9] fix failing votes if player never voted before (no entry in database) Corpium/Corpium#177 --- pom.xml | 2 +- .../io/minimum/minecraft/superbvote/util/PlayerVotes.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 02ebe21..51944cc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.minimum.minecraft SuperbVote - 0.6.0-CORP + 0.6.1-CORP UTF-8 diff --git a/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java b/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java index f209c23..5d3315a 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java +++ b/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java @@ -24,6 +24,14 @@ public class PlayerVotes { private final Map lastVotes; private final Type type; + public PlayerVotes(UUID uuid, String associatedUsername, int votes, Map lastVotes, Type type) { + this.uuid = uuid; + this.associatedUsername = associatedUsername; + this.votes = votes; + this.lastVotes = new HashMap<>(lastVotes); + this.type = type; + } + public String getAssociatedUsername() { if (associatedUsername == null) { return Bukkit.getOfflinePlayer(uuid).getName(); From 13a02ac242a036ee7b361ec225f5b1614d591ddd Mon Sep 17 00:00:00 2001 From: kikelkik <14167723+kikelkik@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:57:06 +0100 Subject: [PATCH 9/9] ignore vote for unknown player name Corpium/Corpium#185 --- pom.xml | 2 +- .../minecraft/superbvote/votes/SuperbVoteListener.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 51944cc..bce5d87 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.minimum.minecraft SuperbVote - 0.6.1-CORP + 0.6.2-CORP UTF-8 diff --git a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java index 5b407eb..3d5f3d2 100644 --- a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java +++ b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java @@ -36,7 +36,14 @@ public void onVote(final VotifierEvent event) { } Bukkit.getScheduler().runTaskAsynchronously(SuperbVote.getPlugin(), () -> { - OfflinePlayer op = Bukkit.getOfflinePlayer(event.getVote().getUsername()); + String voteUsername = event.getVote() + .getUsername(); + OfflinePlayer op = Bukkit.getOfflinePlayer(voteUsername); + if (!op.hasPlayedBefore()) { + SuperbVote.getPlugin().getLogger().log(Level.WARNING, "Ignoring vote from " + voteUsername + + " (service: " + event.getVote().getServiceName() + "): Unknown player."); + return; + } String worldName = null; if (op.isOnline()) { worldName = op.getPlayer().getWorld().getName();