Astral Realms Documentation Help

AstralVote Overview

AstralVote is the network's Votifier replacement: a standalone Votifier v1/v2 protocol server (master) that receives votes from voting sites and fans them out over RabbitMQ to every Paper server, plus a Paper plugin (paper) that tracks each player's unclaimed votes, enforces a per-service cooldown, sends reminder messages, and runs configurable reward actions when a player claims their votes. It depends on AstralCore (database, messaging, actions, placeholders) and AstralSync (cross-server vote-reminder preference) — both are hard dependencies in plugin.yml.

Everything documented on the following pages is the Paper plugin's surface — the master module is an internal Netty/Votifier server with its own MySQL connection and no player-facing configuration.

Data flow

Voting site → Votifier TCP → master VotifierServer ↓ Vote saved to MySQL (`votes` table) ↓ VoteReceivedPacket → RabbitMQ exchange `astralvote.votes` ↓ paper VoteService (every Paper server, via AstralCore MessagingService) ↓ Player claims vote → configured claim actions

master persists each vote (id, username, ip, service, protocol, processed, created_at) to a shared MySQL votes table and publishes a VoteReceivedPacket carrying only the vote's id. Every Paper server that receives the packet re-fetches the full row through its own CrudRepository<VoteModel> — the packet is a change notification, not a data carrier.

Unclaimed votes and cooldowns

VoteService keeps two in-memory, per-player caches, both populated on join (ConnectionListener) and cleared on quit:

  • Unclaimed votes (cachedUnclaimedVotes) — every votes row for the player where processed = false. Backs the %votes_unclaimed% placeholder and the claim-vote action.

  • Weekly vote count (cachedWeeklyVoteCounts) — a Caffeine AsyncLoadingCache counting the player's votes since the most recent Monday (Europe/Paris timezone), refreshed every 30 minutes and invalidated entirely at midnight Paris time by a repeating task. Backs %votes_weekly%.

Each configured vote service has its own cooldown (a Duration, e.g. "1h30" or "24h"). VoteService tracks the last vote time and last reminder time per service per player (PlayerVoteTime, in-memory only) and, every 5 seconds, checks whether any service's cooldown has elapsed since the player's last vote for it; if so and the player hasn't already been notified for that vote, it sends the VOTE_AVAILABLE message. A vote received while the player is online (VoteReceivedPacket handling) also immediately sends NEW_VOTE_RECEIVED and refreshes the caches.

A player's service is matched by comparing the vote's service string against a configured service's id or name, case-insensitively — see services.

Claiming votes

The claim-vote action calls VoteService#claimVote, which:

  1. Guards against concurrent claims for the same player (a second click while one is in flight is silently ignored) and optimistically empties the player's cached unclaimed-vote list.

  2. Re-fetches unclaimed votes from the database; if none, sends NO_PENDING_VOTES and rolls the guard back.

  3. Marks every fetched vote as processed and batch-updates them.

  4. On success, runs the configured claim-actions list once per claimed vote — claiming 3 unclaimed votes at once runs the whole claim-actions list 3 times — then sends VOTE_CLAIMED with %amount% set to the number of votes claimed.

  5. On any database failure, both the vote rows and the in-memory cache are rolled back to their pre-claim state and UNEXPECTED_ERROR is sent.

Vote reminders

Whether a player receives VOTE_AVAILABLE/VOTE_REMINDER messages at all is gated by a per-player voteRemindersEnabled flag, stored in VotePlayerData and synced across servers by AstralSync (default true for a new player). The toggle-votes-reminders action flips it. See Developer API for the sync adapter.

Where to go next

  • Configurationconfig.yml (services, cooldowns, claim actions) and messages.yml.

  • Actionsclaim-vote, toggle-votes-reminders.

  • Placeholdersvotes_* and the service chain placeholder.

  • Developer APIPlayerVoteEvent and the AstralSync VotePlayerData adapter.

Last modified: 25 July 2026