From e595fd6d4084dbb36acb71672625941fe17ef501 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 22 Jul 2026 16:13:11 -0600 Subject: [PATCH 1/3] Fix proxy queued vote delay check --- .../votingplugin/listeners/PlayerVoteListener.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/PlayerVoteListener.java b/VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/PlayerVoteListener.java index 1319675d3..8f9527b1e 100644 --- a/VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/PlayerVoteListener.java +++ b/VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/PlayerVoteListener.java @@ -145,7 +145,9 @@ public void onplayerVote(PlayerVoteEvent event) { } } - if (voteSite.isWaitUntilVoteDelay() && !user.canVoteSite(voteSite)) { + boolean queuedProxyVoteAlreadyRecorded = ProxyVoteDelayCheck.isQueuedVoteAlreadyRecorded(event.isBungee(), + event.getTime(), user.getTime(voteSite)); + if (voteSite.isWaitUntilVoteDelay() && !queuedProxyVoteAlreadyRecorded && !user.canVoteSite(voteSite)) { if (!event.isRealVote()) { plugin.getLogger().info(user.getPlayerName() + " did a not real vote, bypassing WaitUntilVoteDelay"); } else { @@ -157,6 +159,10 @@ public void onplayerVote(PlayerVoteEvent event) { .info(user.getPlayerName() + " has bypass permission for WaitUntilVoteDelay, bypassing"); } } + if (queuedProxyVoteAlreadyRecorded) { + plugin.debug("Allowing queued proxy vote for " + user.getPlayerName() + " on " + voteSite.getKey() + + "; proxy vote time already matches LastVotes: " + event.getTime()); + } UUID voteUUID = UUID.randomUUID(); if (event.isBungee() && event.getBungeeTextTotals() != null) { From ae659465613d40e0d4a8d31b82e00a415d4eca41 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 22 Jul 2026 16:13:12 -0600 Subject: [PATCH 2/3] Add proxy vote delay helper --- .../listeners/ProxyVoteDelayCheck.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/ProxyVoteDelayCheck.java diff --git a/VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/ProxyVoteDelayCheck.java b/VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/ProxyVoteDelayCheck.java new file mode 100644 index 000000000..48a52e406 --- /dev/null +++ b/VotingPlugin/src/main/java/com/bencodez/votingplugin/listeners/ProxyVoteDelayCheck.java @@ -0,0 +1,24 @@ +package com.bencodez.votingplugin.listeners; + +/** + * Handles the WaitUntilVoteDelay exception for votes queued by a proxy. + */ +public final class ProxyVoteDelayCheck { + + private ProxyVoteDelayCheck() { + } + + /** + * A proxy stores the real vote timestamp before its queued message reaches the + * backend. The backend must accept that one delivery when the stored timestamp + * is the same timestamp carried by the message. + * + * @param proxyVote true when the vote was forwarded by VotingPlugin's proxy + * @param messageVoteTime real vote time included in the proxy message + * @param storedVoteTime current backend last-vote time for the site + * @return true when the delay check should allow the queued delivery + */ + public static boolean isQueuedVoteAlreadyRecorded(boolean proxyVote, long messageVoteTime, long storedVoteTime) { + return proxyVote && messageVoteTime > 0L && messageVoteTime == storedVoteTime; + } +} From f99782117a9a043433b660c9d583050372efe452 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 22 Jul 2026 16:13:14 -0600 Subject: [PATCH 3/3] Test proxy queued vote delay check --- .../tests/ProxyVoteDelayCheckTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/ProxyVoteDelayCheckTest.java diff --git a/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/ProxyVoteDelayCheckTest.java b/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/ProxyVoteDelayCheckTest.java new file mode 100644 index 000000000..2e2c67add --- /dev/null +++ b/VotingPlugin/src/test/java/com/bencodez/votingplugin/tests/ProxyVoteDelayCheckTest.java @@ -0,0 +1,23 @@ +package com.bencodez.votingplugin.tests; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import com.bencodez.votingplugin.listeners.ProxyVoteDelayCheck; + +class ProxyVoteDelayCheckTest { + + @Test + void acceptsQueuedProxyVoteWhenTheProxyTimestampIsAlreadyStored() { + assertTrue(ProxyVoteDelayCheck.isQueuedVoteAlreadyRecorded(true, 12345L, 12345L)); + } + + @Test + void doesNotBypassTheDelayForDirectOrStaleProxyVotes() { + assertFalse(ProxyVoteDelayCheck.isQueuedVoteAlreadyRecorded(false, 12345L, 12345L)); + assertFalse(ProxyVoteDelayCheck.isQueuedVoteAlreadyRecorded(true, 12344L, 12345L)); + assertFalse(ProxyVoteDelayCheck.isQueuedVoteAlreadyRecorded(true, 0L, 0L)); + } +}