Repository navigation
Add owner-configured DateVoteMilestones with durable occurrence accounting #1699
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
bca3881
3c29bd8
1f787df
073634b
bd3c738
ff41566
31f5f2e
e2f5503
57ebcbc
897f386
1535e27
87545cc
26441c1
63d9a58
d6d6dbc
b4aa30d
42f5819
cf51409
42398de
f0cc7f1
013c9bb
4aa8f3c
071ba3e
0061705
18f2fe9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -331,7 +331,12 @@ private synchronized AtomicBoolean basicBungeeUpdateAdmission() { | |
| private VotingPluginConfigHealth configHealth; | ||
| private VotifierIntegration votifierIntegration; | ||
| @Getter | ||
| private VotifierVoteOverflowQueue votifierVoteOverflowQueue; | ||
| private volatile VotifierVoteOverflowQueue votifierVoteOverflowQueue; | ||
| private VotiferEvent localVotifierListener; | ||
| private boolean acceptedVoteIngressRegistered; | ||
| private boolean timeQueueIngressRegistered; | ||
| private volatile boolean localVotifierIngressReady; | ||
| private volatile boolean localVotifierIngressClosed; | ||
| private VoteLogManager voteLogManager; | ||
| private VotingPluginWebhookManager webhookManager; | ||
|
|
||
|
|
@@ -613,6 +618,11 @@ private void loadBungeeHandler() { | |
| @Getter | ||
| private VoteStreakHandler voteStreakHandler; | ||
|
|
||
| @Getter | ||
| private final com.bencodez.votingplugin.specialrewards.datemilestones.DateVoteMilestones dateVoteMilestones = | ||
| new com.bencodez.votingplugin.specialrewards.datemilestones.DateVoteMilestones(this); | ||
|
|
||
|
|
||
| /** | ||
| * Registers a directly editable rewards path from SpecialRewards.yml. | ||
| * | ||
|
|
@@ -626,6 +636,7 @@ public void loadDirectlyDefined() { | |
| VoteSiteRewardRegistrar.register(this); | ||
| VotePartyRewardRegistrar.register(this); | ||
| VoteMilestoneRewardRegistrar.register(this); | ||
| dateVoteMilestones.reload(); | ||
| VoteStreakRewardRegistrar.register(this); | ||
| TopVoterRewardRegistrar.register(this); | ||
| VoteShopRewardRegistrar.register(this); | ||
|
|
@@ -697,8 +708,36 @@ private void metrics() { | |
| new VotingPluginMetrics().load(plugin); | ||
| } | ||
|
|
||
| /** Publish accepted and transport ingress only after the complete vote pipeline is initialized. */ | ||
| void initializeDateVoteIngress(Runnable openProxy) { | ||
| if (localVotifierIngressClosed) throw new IllegalStateException("Vote ingress is shutting down"); | ||
| if (localVotifierIngressReady) return; | ||
| if (voteMilestonesManager == null || voteStreakHandler == null || voteParty == null || specialRewards == null | ||
| || topVoterHandler == null || voteShopManager == null || placeholders == null) { | ||
| throw new IllegalStateException("Accepted-vote handlers must initialize before transport ingress"); | ||
| } | ||
| getDateVoteMilestones().reload(); | ||
| if (!acceptedVoteIngressRegistered) { | ||
| getServer().getPluginManager().registerEvents(new PlayerVoteListener(this), this); | ||
| acceptedVoteIngressRegistered = true; | ||
| } | ||
| // Construction itself schedules persisted replay. Open it only after its consumer. | ||
| if (!timeQueueIngressRegistered && (!getBungeeSettings().isUseBungeecoord() || !getBungeeSettings().isGloblalDataEnabled())) { | ||
| timeQueueHandler = new TimeQueueHandler(this); | ||
| getServer().getPluginManager().registerEvents(timeQueueHandler, this); | ||
| timeQueueIngressRegistered = true; | ||
| } | ||
| if (getBungeeSettings().isUseBungeecoord()) openProxy.run(); | ||
|
BenCodez marked this conversation as resolved.
BenCodez marked this conversation as resolved.
|
||
| localVotifierIngressReady = true; | ||
| VotifierVoteOverflowQueue overflow = votifierVoteOverflowQueue; | ||
| if (overflow != null) overflow.start(); | ||
| } | ||
|
|
||
| @Override | ||
| public void onPostLoad() { | ||
| loadVoteTimer(); | ||
| checkVotifier(); | ||
| registerEarlyVotifierIngress(); | ||
| ensureCommunicationSecret(); | ||
| // auto conversion for Shop.yml | ||
| if (plugin.getShopFile().isJustCreated()) { | ||
|
|
@@ -726,7 +765,6 @@ public void onPostLoad() { | |
|
|
||
| voteTester = new VoteTester(plugin); | ||
|
|
||
| loadVoteTimer(); | ||
| BoundedScheduledExecutor setupReminderWorker = new BoundedScheduledExecutor(1, 4); | ||
| setupReminderWorker.setThreadFactory(runnable -> { | ||
| Thread worker = new Thread(runnable, "VotingPlugin-SiteSetupReminder"); | ||
|
|
@@ -739,13 +777,8 @@ public void onPostLoad() { | |
| autoCreateVoteSitesSetupReminder.start(); | ||
| getVotingPluginUserManager().startSharedPointTransferRecovery(); | ||
|
|
||
| if (bungeeSettings.isUseBungeecoord()) { | ||
| loadBungeeHandler(); | ||
| } | ||
| // Proxy ingress opens below, after every accepted-vote handler is initialized. | ||
|
|
||
| if (!bungeeSettings.isUseBungeecoord() || !bungeeSettings.isGloblalDataEnabled()) { | ||
| this.timeQueueHandler = new TimeQueueHandler(this); | ||
| } | ||
|
|
||
| if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { | ||
| if (getConfigFile().isLoadInteralExpansion()) { | ||
|
|
@@ -760,7 +793,6 @@ public void onPostLoad() { | |
| voteStreakHandler.reload(); | ||
|
|
||
| registerCommands(); | ||
| checkVotifier(); | ||
| registerEvents(); | ||
| refreshPlaceholderPlayerPresence(); | ||
|
|
||
|
|
@@ -850,11 +882,7 @@ public Object getObject(OfflinePlayer player) { | |
| } | ||
|
|
||
| VotingPluginRewardRegistrar.register(this); | ||
| // Recovered Votifier votes may now traverse the fully initialized vote, | ||
| // reward, placeholder, shop, and vote-party pipeline. | ||
| if (votifierVoteOverflowQueue != null) { | ||
| votifierVoteOverflowQueue.start(); | ||
| } | ||
| initializeDateVoteIngress(this::loadBungeeHandler); | ||
|
BenCodez marked this conversation as resolved.
|
||
|
|
||
| plugin.getLogger().info("Enabled VotingPlugin " + plugin.getDescription().getVersion()); | ||
| if (plugin.getDescription().getVersion().contains("SNAPSHOT")) { | ||
|
|
@@ -1995,6 +2023,9 @@ private void shutdownVoteReminders() { | |
|
|
||
| @Override | ||
| public void onUnLoad() { | ||
| localVotifierIngressClosed = true; | ||
| localVotifierIngressReady = false; | ||
| if (localVotifierListener != null) localVotifierListener.stop(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the durable overflow already contains 256 recovered entries, or has less free capacity than the capture registry needs, this AGENTS.md reference: AGENTS.md:L326-L327 Useful? React with 👍 / 👎. |
||
| stopAutoCreateVoteSitesSetupReminder(); | ||
| placeholderPlayerPresence.clear(); | ||
| stopBackendHostedControlLifecycle(); | ||
|
|
@@ -2076,19 +2107,24 @@ private void registerCommands() { | |
|
|
||
| } | ||
|
|
||
| /** | ||
| * Register events. | ||
| */ | ||
| /** Capture external events early; only the existing bounded workers may buffer/process them. */ | ||
| void registerEarlyVotifierIngress() { | ||
| if (localVotifierIngressClosed || !isVotifierLoaded() || localVotifierListener != null) return; | ||
| VotiferEvent listener = new VotiferEvent(this, () -> localVotifierIngressReady); | ||
| // Publish the memory owner before capture. Its independent worker loads | ||
| // disk state; vote-executor cancellation cannot discard queue setup. | ||
| votifierVoteOverflowQueue = VotifierVoteOverflowQueue.initializeConfirmedAsync(this, | ||
| listener::processVoteConfirmed, () -> localVotifierIngressReady && !localVotifierIngressClosed); | ||
| localVotifierListener = listener; | ||
| if (localVotifierIngressReady) votifierVoteOverflowQueue.start(); | ||
| getServer().getPluginManager().registerEvents(listener, this); | ||
| } | ||
|
|
||
| private void registerEvents() { | ||
| PluginManager pm = getServer().getPluginManager(); | ||
|
|
||
| pm.registerEvents(new PlayerJoinEvent(this), this); | ||
| if (isVotifierLoaded()) { | ||
| VotiferEvent votifierEvent = new VotiferEvent(this); | ||
| votifierVoteOverflowQueue = new VotifierVoteOverflowQueue(this, votifierEvent::processVote); | ||
| pm.registerEvents(votifierEvent, this); | ||
| } | ||
| pm.registerEvents(new PlayerVoteListener(this), this); | ||
| pm.registerEvents(new com.bencodez.votingplugin.listeners.DateVoteMenuOpenGuard(), this); | ||
| pm.registerEvents(new PlayerPostVoteLoggerListener(this), this); | ||
| pm.registerEvents(new PlayerSpecialRewardLoggerListener(this), this); | ||
| pm.registerEvents(new VoteShopPurchaseLoggerListener(this), this); | ||
|
|
@@ -2102,9 +2138,6 @@ private void registerEvents() { | |
| pm.registerEvents(new PlayerInteract(this), this); | ||
| } | ||
|
|
||
| if (timeQueueHandler != null) { | ||
| pm.registerEvents(timeQueueHandler, plugin); | ||
| } | ||
|
|
||
| pm.registerEvents(new VotingPluginUpdateEvent(this), this); | ||
| /* | ||
|
|
@@ -2182,6 +2215,8 @@ private void reloadPlugin(boolean userStorage, boolean reconcileHostedControl, | |
| // Re-evaluate after storage has reloaded; UserManager keeps this lifecycle task unique. | ||
| getVotingPluginUserManager().startSharedPointTransferRecovery(); | ||
|
|
||
| getOptions().setServer(bungeeSettings.getServer()); | ||
| getDateVoteMilestones().reload(); | ||
| reloadBackendProxyRuntime(updateActiveBackendRuntime, userStorage); | ||
| checkYMLError(); | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.