Astral Realms Documentation Help

Developer API

AstralVote exposes its state through one service hung off the main plugin instance, one custom Bukkit event fired when a vote is received, and a SyncAPI snapshot adapter for the player's vote-reminder preference. There is no static *API façade — external plugins reach everything through the plugin instance.

Plugin handle

import com.astralrealms.vote.AstralVote; AstralVote plugin = AstralVote.getPlugin(AstralVote.class); VoteService votes = plugin.votes();

Custom Bukkit events

AstralVote fires one custom event, in com.astralrealms.vote.event.

PlayerVoteEvent

Fully qualified name: com.astralrealms.vote.event.PlayerVoteEvent (extends AstralCore's AbstractEvent, constructed with isAsync = true).

Fired by VoteService from its VoteReceivedPacket handler, after the corresponding VoteModel row has been fetched, the player has been found online on this server, NEW_VOTE_RECEIVED has been sent, and the unclaimed-vote/last-vote-time caches have already been updated. Not cancellable — it's a notification, not a gate, and fires async (on the messaging callback thread), not on the main thread.

Getter

Type

Value

getPlayer()

Player

The player who voted (must be online on this server for the event to fire at all).

getService()

String

The vote's raw service string, as stored on the VoteModel row (Votifier's service name, not necessarily a configured service id/name).

getTimestamp()

long

The vote's createdAt (epoch millis).

@EventHandler public void onVote(PlayerVoteEvent event) { getLogger().info(event.getPlayer().getName() + " voted on " + event.getService()); }

VoteService

Access via plugin.votes(). Owns the in-memory unclaimed-vote and weekly-vote-count caches described in Overview and the reminder/claim flows.

Method

Returns

Use

load(Player player)

void

Populates the weekly-count cache and last-vote-time map for a joining player, then sends VOTE_REMINDER if applicable. Called by ConnectionListener on PlayerJoinEvent.

findUnclaimed(Player player)

CompletableFuture<List<VoteModel>>

Fetches (and caches) every unprocessed VoteModel row for the player.

getWeeklyVoteCount(String name)

CompletableFuture<Integer>

Uncached DB query for votes since the most recent Monday, Europe/Paris.

getCachedWeeklyVoteCount(Player player)

int

Cached weekly count, 0 if not yet loaded. Backs %votes_weekly%.

getCachedUnclaimedCount(UUID playerId)

int

Cached unclaimed-vote count, 0 if not yet loaded. Backs %votes_unclaimed%.

claimVote(Player player)

void

Runs the full claim flow — see Claiming votes. What the claim-vote action calls.

invalidateCache(Player player)

void

Drops the player's cached unclaimed votes, weekly count, and last-vote-times. Called by ConnectionListener on PlayerQuitEvent.

Model classes

VoteModel

The votes table row (@Entity("votes"), shared MySQL database with the standalone master module).

public class VoteModel implements Unique { UUID uniqueId; // @Id, column "id" String username; String ip; String service; // raw Votifier service name, not a config service id/name int protocol; // Votifier protocol version (1 or 2) boolean processed; long updatedAt; // @UpdatedAt long createdAt; // @CreatedAt }

markAsProcessed() sets processed = true; this is what claimVote calls before the batch update.

PlayerVoteTime

In-memory only (not persisted). Tracks, per configured service id, the player's last vote time and last reminder-notify time — the state the cooldown/reminder check in Overview reads.

public record PlayerVoteTime(Map<String, Long> lastVoteTimes, Map<String, Long> lastNotifyTimes) { }

Cross-server player data

VoteSnapshotAdapter (key astralvote:player_data) is registered with SyncAPI in AstralVote#onEnable, making VotePlayerData a cross-server-synced snapshot for every online player.

public class VotePlayerData { boolean voteRemindersEnabled; }

create(Player) seeds a new player with voteRemindersEnabled = true. apply(...) is a no-op — the flag has no direct effect on the player beyond gating the reminder checks in VoteService, which read it directly through SyncAPI#findData rather than through any apply-time side effect.

import com.astralrealms.vote.storage.VotePlayerData; import com.astralrealms.sync.SyncAPI; SyncAPI.findData(player.getUniqueId(), VotePlayerData.class) .ifPresent(data -> { boolean wantsReminders = data.voteRemindersEnabled(); });

See Actions (which flips this flag) and AstralSync's Adapter Interfaces for the base contract.

Registered actions

AstralVote registers two executable actions into AstralCore's action registry via registerActionGloballyclaim-vote and toggle-votes-reminders. Any plugin's menus, dialogs, or action lists can invoke them by name. See Actions for the full list with their behavior.

Messaging

AstralVote's master module publishes VoteReceivedPacket (a single voteId UUID) on the RabbitMQ exchange astralvote.votes, registered by VotePacketRegistry. The Paper plugin subscribes to that exchange through AstralCore's MessagingService in VoteService's constructor and re-fetches the full VoteModel row by id on receipt — the packet only signals that a new vote exists, it never carries vote data itself.

Last modified: 25 July 2026