Skip to main content

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​

  1. Vote Tracking - Records every NuVotifier vote with its time and voting site, for online and offline players
  2. Vote Rewards - Vote points (2 per vote by default) and console commands for every vote
  3. 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
  4. Milestones - Rewards at vote counts (10, 50, 100, 500 by default), each given once, also when reached while offline
  5. Vote Parties - When the server reaches a vote goal, every online player is rewarded
  6. Reward Shop - A menu where players spend vote points, optionally combined with Cost API prices (Vault, PlayerPoints, experience, items)
  7. Vote Menu - /vote opens 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
  8. Leaderboards - Weekly, monthly, 3-month, yearly and all-time rankings in a menu
  9. Vote Reminders - Periodic reminders to online players who have not voted today
  10. Admin Menu - Settings, streak multipliers, shop prices, player data, statistics, vote party progress, reload, export and import from /vote admin
  11. Admin Statistics - Today's votes, unique voters, top site and vote party progress
  12. PlaceholderAPI - Votes, points, streaks, ranks, leaderboards, vote party and milestone placeholders
  13. Dual Storage - JSON or MySQL/MariaDB, with export and import to move between them
  14. 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​

CommandDescriptionPermission
/voteOpen the vote sites menu, or list the links in chatnexalvote.vote
/vote help [page]Show the commandsnexalvote.vote
/vote shop (store, rewards)Open the reward shopnexalvote.shop
/vote leaderboard (lb, top)Open the leaderboardnexalvote.leaderboard
/vote statsView your vote statisticsnexalvote.stats
/vote stats \<player>View another player's statistics (also from the console)nexalvote.stats.others

/v is an alias of /vote.

Admin Commands​

CommandDescriptionPermission
/vote adminOpen the admin menu (the console gets the admin commands)nexalvote.admin
/vote admin help [page]List the admin commandsnexalvote.admin
/vote admin give \<player> \<points>Give vote pointsnexalvote.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 pointsnexalvote.admin
/vote admin fakevote \<player>Simulate a vote for an online playernexalvote.admin
/vote admin partyStart a vote party nownexalvote.admin
/vote admin party set \<votes>Set the vote party progressnexalvote.admin
/vote admin statsShow today's vote statisticsnexalvote.admin
/vote admin exportExport all data to plugins/NexalVote/export/nexalvote.admin
/vote admin importImport the export folder into the current storagenexalvote.admin
/vote admin reloadReload config.yml and messages.ymlnexalvote.admin

Permissions​

PermissionDescriptionDefault
nexalvote.voteUse /vote and /vote helptrue
nexalvote.shopUse the reward shoptrue
nexalvote.leaderboardView the leaderboardtrue
nexalvote.statsView your own statisticstrue
nexalvote.stats.othersView other players' statisticsop
nexalvote.adminAdmin menu and commandsop

Placeholders​

Requires PlaceholderAPI.

PlaceholderDescription
%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​

ColumnTypeKeyDescription
idVARCHAR(36)PKPlayer UUID
total_votesINTTotal votes
vote_pointsINTVote points balance
current_streakINTCurrent streak in days
last_vote_dateBIGINTStart of the day of the last vote (epoch millis)
votes_jsonMEDIUMTEXTVote history of the last year: timestamp and site of each vote
claimed_milestones_jsonTEXTMilestones already given
site_votes_jsonTEXTAll-time votes per site; added to existing tables on startup

vote_state​

ColumnTypeKeyDescription
idVARCHAR(36)PKAlways server
party_votesINTVote 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​

  1. Place the JAR in the plugins folder
  2. Install NuVotifier to receive votes; optionally PlaceholderAPI, Vault or PlayerPoints
  3. Start or restart the server
  4. Set your vote site URLs and rewards in config.yml, or in-game with /vote admin
  5. Reload with /vote admin reload

To move from JSON to SQL: /vote admin export, set storage.type: sql, restart, then /vote admin import.