Nexal Vote
A complete voting reward system for NuVotifier. Players earn vote points and reward commands for every vote, build daily streaks that multiply their points, unlock milestone rewards, and spend their points in a reward shop. The whole server works towards vote parties, and leaderboards, placeholders and an admin menu keep everyone up to date.
Features
- Vote Tracking - Records every NuVotifier vote with its time and voting site, for online and offline players
- Vote Rewards - Vote points (2 per vote by default) and console commands for every vote
- Streak Multipliers - Consecutive daily votes multiply the points (1.5x, 2x, 2.5x, 3x by default); the vote that reaches a bonus already gets it
- Milestones - Rewards at vote counts (10, 50, 100, 500 by default), each given once, also when reached while offline
- Vote Parties - When the server reaches a vote goal, every online player is rewarded
- Reward Shop - A menu where players spend vote points, optionally combined with Cost API prices (Vault, PlayerPoints, experience, items)
- Vote Menu -
/voteopens a menu with your vote stats, every vote site with whether you can vote there again and a countdown, a vote party progress bar, the top 3 voters and a shop button; or lists clickable links in chat - Leaderboards - Weekly, monthly, 3-month, yearly and all-time rankings in a menu
- Vote Reminders - Periodic reminders to online players who have not voted today
- Admin Menu - Settings, streak multipliers, shop prices, player data, statistics, vote party progress, reload, export and import from
/vote admin - Admin Statistics - Today's votes, unique voters, top site and vote party progress
- PlaceholderAPI - Votes, points, streaks, ranks, leaderboards, vote party and milestone placeholders
- Dual Storage - JSON or MySQL/MariaDB, with export and import to move between them
- Customizable Messages - Every message and menu line in
messages.yml, with sounds
Technologies
- Paper API 1.20.1+ - Minecraft server API (Spigot compatible)
- Utilizer - Configuration, messages, menus, tasks
- ACF - Command framework
- nexal-core - JSON and SQL persistence (MariaDB/MySQL), Cost API, help menus
- NuVotifier - Vote events (optional, required to receive votes)
- PlaceholderAPI - Placeholder integration (optional)
- Vault / PlayerPoints - Extra shop prices (optional)
Commands
Player Commands
| Command | Description | Permission |
|---|---|---|
/vote | Open the vote sites menu, or list the links in chat | nexalvote.vote |
/vote help [page] | Show the commands | nexalvote.vote |
/vote shop (store, rewards) | Open the reward shop | nexalvote.shop |
/vote leaderboard (lb, top) | Open the leaderboard | nexalvote.leaderboard |
/vote stats | View your vote statistics | nexalvote.stats |
/vote stats \<player> | View another player's statistics (also from the console) | nexalvote.stats.others |
/v is an alias of /vote.
Admin Commands
| Command | Description | Permission |
|---|---|---|
/vote admin | Open the admin menu (the console gets the admin commands) | nexalvote.admin |
/vote admin help [page] | List the admin commands | nexalvote.admin |
/vote admin give \<player> \<points> | Give vote points | nexalvote.admin |
/vote admin take \<player> \<points> | Take vote points (refused if the player has fewer) | nexalvote.admin |
/vote admin set \<player> \<points> | Set a player's vote points | nexalvote.admin |
/vote admin fakevote \<player> | Simulate a vote for an online player | nexalvote.admin |
/vote admin party | Start a vote party now | nexalvote.admin |
/vote admin party set \<votes> | Set the vote party progress | nexalvote.admin |
/vote admin stats | Show today's vote statistics | nexalvote.admin |
/vote admin export | Export all data to plugins/NexalVote/export/ | nexalvote.admin |
/vote admin import | Import the export folder into the current storage | nexalvote.admin |
/vote admin reload | Reload config.yml and messages.yml | nexalvote.admin |
Permissions
| Permission | Description | Default |
|---|---|---|
nexalvote.vote | Use /vote and /vote help | true |
nexalvote.shop | Use the reward shop | true |
nexalvote.leaderboard | View the leaderboard | true |
nexalvote.stats | View your own statistics | true |
nexalvote.stats.others | View other players' statistics | op |
nexalvote.admin | Admin menu and commands | op |
Placeholders
Requires PlaceholderAPI.
| Placeholder | Description |
|---|---|
%nexalvote_votes% | Total votes |
%nexalvote_total% | Total votes (same as votes) |
%nexalvote_points% | Vote points balance |
%nexalvote_streak% | Current streak in days |
%nexalvote_multiplier% | Current streak multiplier |
%nexalvote_rank% | All-time rank, or Unranked |
%nexalvote_votes_\<site>% | Votes on a site, by the service name Votifier reports |
%nexalvote_votes_today% | Server-wide votes today |
%nexalvote_party_current% | Vote party progress |
%nexalvote_party_needed% | Votes still needed for the vote party |
%nexalvote_party_threshold% | Vote party goal |
%nexalvote_milestone_next% | Next milestone, or Complete! |
%nexalvote_milestone_progress% | Progress to the next milestone, e.g. 45/50 |
%nexalvote_leaderboard_\<pos>% | All-time player at a position |
%nexalvote_leaderboard_\<pos>_\<period>% | Player at a position for week, month, 3months or year |
%nexalvote_leaderboard_votes_\<pos>% | All-time votes at a position |
%nexalvote_leaderboard_votes_\<pos>_\<period>% | Votes at a position for a period |
Ranks and leaderboards are refreshed in the background after each vote and at least once a minute.
party_current, party_needed, party_threshold and votes_today also work without a player
(global holograms, Discord bots), and so do the leaderboard_* placeholders for positions 1 to 10,
with or without a period. Positions past 10 need a player.
Configuration
Most settings can also be changed in-game: /vote admin, then Configuration.
config.yml
# Storage type: "json" or "sql"
storage:
type: "json"
sql:
host: "localhost"
port: 3306
database: "minecraft"
username: "root"
password: ""
# Minutes between background saves of data.json (0 to disable)
auto-save-minutes: 5
# What /vote shows: "gui" (vote sites menu) or "chat" (clickable links)
vote-command-mode: "gui"
# Vote sites shown by /vote. The keys are only names for this list; per-site counts use
# the service name the site sends through Votifier.
vote-sites:
planetminecraft:
name: "\<green>\<bold>PlanetMinecraft\</bold>\</green>"
material: EMERALD
url: "https://www.planetminecraft.com/server/yourserver/vote/"
# For the menu's "voted" state: the Votifier service name (defaults to the key, any case)
# and the hours the site waits between votes (defaults to 24)
service: "PlanetMinecraft"
cooldown-hours: 24
lore:
- "\<gray>Vote on PlanetMinecraft\</gray>"
# Rewards for every vote. Commands run from the console and support %player%, %service%
# (the site's Votifier service name) and %points% (the points this vote gave).
# 2 points per vote makes every default streak multiplier a whole number (3, 4, 5, 6).
# Configs from 1.0.2 and older keep their value.
rewards:
points-per-vote: 2
commands:
- "eco give %player% 100"
# Streak bonuses: point multipliers after this many days in a row
streak-bonuses:
3:
multiplier: 1.5
message: "\<green>\<bold>3-Day Streak!\</bold>\</green> \<gray>+50% vote points!\</gray>"
7:
multiplier: 2.0
message: "\<gold>\<bold>Weekly Streak!\</bold>\</gold> \<gray>Double vote points!\</gray>"
# Milestones: rewards at vote counts, given once. Commands support %player%; the sound
# plays with the milestone-reached message.
milestones:
10:
name: "\<gold>Bronze Voter\</gold>"
commands:
- "lp user %player% parent add bronze_voter"
sound: ENTITY_PLAYER_LEVELUP
# Vote party: rewards every online player when the server reaches the goal. The commands
# run once per online player and support %player%.
vote-party:
enabled: true
# Votes from all players needed to start a party; the count starts over after each party
threshold: 100
rewards:
- "give %player% diamond 5"
# Reminders to online players who have not voted today
reminders:
enabled: true
interval-minutes: 15
# Reward shop. cost.vote-points is the price in vote points; other keys under cost are
# Cost API prices charged as well (vault, playerpoints, exp, levels, items, ...).
# Commands support %player%.
shop:
items:
diamond_kit:
name: "\<aqua>\<bold>Diamond Kit\</bold>\</aqua>"
material: DIAMOND
lore:
- "\<gray>A starter diamond kit\</gray>"
cost:
vote-points: 10
commands:
- "kit give %player% diamond"
# The period /vote leaderboard opens on: week, month, 3months, year or alltime
leaderboard:
default-period: "month"
# Menu titles, and the /vote menu's materials and refresh interval
gui:
vote-links:
title: "<gradient:#3498DB:#5DADE2>\<bold>Vote Sites\</bold>\</gradient>"
refresh-seconds: 10
accent-material: LIGHT_BLUE_STAINED_GLASS_PANE
party-material: FIREWORK_ROCKET
shop-material: EMERALD
empty-top-material: SKELETON_SKULL
leaderboard:
title: "<gradient:#3498DB:#5DADE2>\<bold>Vote Leaderboard\</bold>\</gradient>"
shop:
title: "<gradient:#3498DB:#5DADE2>\<bold>Vote Shop\</bold>\</gradient>"
Shop prices written as cost.points by version 1.0.2 and older are renamed to cost.vote-points on startup. For a PlayerPoints price, use cost.playerpoints.
The /vote menu
[glass] [glass] . . [your stats] . . [glass] [glass]
vote sites: up to 4 spaced out, or 7 per row over two rows
[glass] [party] . [#2] [#1] [#3] . [shop] [close]
Each vote site shows ✔ Voted with the time until the site can be voted on again, or ✘ Not Voted Yet; sites not voted on yet glow. Clicking a site sends its link in chat, a top voter opens the leaderboard, and the shop button opens the shop. The menu redraws every refresh-seconds while open. Its texts are under gui.vote-links in messages.yml.
messages.yml
All messages are fully customizable with MiniMessage colors, sounds and titles, including the menu lines under gui, the chat links (vote-link-entry, with click and hover) and the streak bonus message (streak-bonus).
The vote, streak bonus and vote party sounds are set on vote-received, streak-bonus and vote-party-triggered. Up to 1.0.2 they were also in config.yml (sounds.vote, sounds.streak, vote-party.sound); those values are moved onto the messages on startup.
Database Schema
When using SQL storage, the plugin creates the following tables. JSON storage keeps the same data under the same names in data.json.
vote_users
| Column | Type | Key | Description |
|---|---|---|---|
id | VARCHAR(36) | PK | Player UUID |
total_votes | INT | Total votes | |
vote_points | INT | Vote points balance | |
current_streak | INT | Current streak in days | |
last_vote_date | BIGINT | Start of the day of the last vote (epoch millis) | |
votes_json | MEDIUMTEXT | Vote history of the last year: timestamp and site of each vote | |
claimed_milestones_json | TEXT | Milestones already given | |
site_votes_json | TEXT | All-time votes per site; added to existing tables on startup |
vote_state
| Column | Type | Key | Description |
|---|---|---|---|
id | VARCHAR(36) | PK | Always server |
party_votes | INT | Vote party progress |
Key Legend: PK = Primary Key
Up to version 1.0.2 the vote party progress was kept in party_state.json. It is moved into the selected storage on startup and the file is renamed to party_state.json.migrated.
Installation
- Place the JAR in the
pluginsfolder - Install NuVotifier to receive votes; optionally PlaceholderAPI, Vault or PlayerPoints
- Start or restart the server
- Set your vote site URLs and rewards in
config.yml, or in-game with/vote admin - Reload with
/vote admin reload
To move from JSON to SQL: /vote admin export, set storage.type: sql, restart, then /vote admin import.