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..51944cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,13 @@
io.minimum.minecraft
SuperbVote
- 0.5.5
+ 0.6.1-CORP
+
+
+ UTF-8
+ 21
+ 21
+
@@ -16,19 +22,10 @@
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
-
- 1.8
-
-
org.apache.maven.plugins
maven-shade-plugin
- 2.3
+ 3.6.0
@@ -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,48 @@
org.spigotmc
spigot-api
- 1.14-R0.1-SNAPSHOT
+ 1.19-R0.1-SNAPSHOT
provided
org.projectlombok
lombok
- 1.18.0
+ 1.18.36
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
+
+
+ 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/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/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 cc28dcf..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 {
@@ -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, Collections.emptyMap(), PlayerVotes.Type.CURRENT);
+ }
+ return new PlayerVotes(player, pr.lastKnownUsername, pr.votes, Collections.emptyMap(), PlayerVotes.Type.CURRENT);
} finally {
rwl.readLock().unlock();
}
@@ -160,7 +162,9 @@ 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,
+ 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 ad5c569..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 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), 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, 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, 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 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), 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, (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());
}
@@ -302,12 +322,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),
+ PlayerVotes.deserializeLastVotes(resultSet.getString(4)),
PlayerVotes.Type.CURRENT);
votes.add(pv);
}
@@ -317,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, 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 de23b97..5d3315a 100644
--- a/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java
+++ b/src/main/java/io/minimum/minecraft/superbvote/util/PlayerVotes.java
@@ -1,17 +1,37 @@
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 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;
+ 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();
@@ -21,6 +41,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 6799e13..5b407eb 100644
--- a/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java
+++ b/src/main/java/io/minimum/minecraft/superbvote/votes/SuperbVoteListener.java
@@ -10,6 +10,9 @@
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;
import org.bukkit.entity.Player;
@@ -39,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, 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) {
@@ -88,9 +93,20 @@ private void processVote(PlayerVotes pv, VoteStreak voteStreak, Vote vote, boole
throw new RuntimeException("No vote rewards found for '" + vote + "'");
}
+ if (SuperbVote.getPlugin().getConfig().getBoolean("votes.one-vote-per-day")
+ && pv.hasVoteOnSameDay(vote.getServiceName(), vote.getReceived())) {
+
+ SuperbVote.getPlugin()
+ .getLogger()
+ .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;
}
@@ -102,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) {
@@ -141,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, 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();
}
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/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:
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index c0cbbd1..083c3f7 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -4,16 +4,11 @@ author: tuxed
version: ${project.version}
depend: [Votifier]
softdepend: [Vault, PlaceholderAPI]
-api-version: "1.13"
+api-version: "1.19"
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