22
33** Modern, transparent community voting for PaperMC 1.21.x**
44
5- A privacy-first, lightweight, and production-ready ** yes/no voting plugin** for Minecraft servers — designed for modern communities that value fairness, trust, and data integrity.
6- ModNVote is built by [ ** MODN METL LTD** ] ( https://modnmetl.com ) and open-sourced to promote transparent community decision-making.
5+ A privacy-first, lightweight, and production-ready ** yes/no voting plugin** for Minecraft servers — designed for communities that value fairness, trust, and auditability.
76
8- ![ CI] ( https://github.com/MODNMETL/ModNVote/actions/workflows/ci.yml/badge.svg )
9- ![ Java] ( https://img.shields.io/badge/Java-21-007396 )
10- ![ Paper] ( https://img.shields.io/badge/Paper-1.21.x-blue )
11- ![ License: MIT] ( https://img.shields.io/badge/License-MIT-green )
12- ![ Release] ( https://img.shields.io/github/v/release/MODNMETL/ModNVote?display_name=tag )
7+ This version includes enhanced ** tamper detection** , ** vote-privacy protection** , and ** automatic integrity alerts** .
138
149---
1510
16- ## ✨ Features
17-
18- - ` /modnvote yes ` or ` /modnvote no ` — anonymous voting (1 per UUID).
19- - ` /modnvote status ` — displays live YES/NO tallies.
20- - ` /modnvote verify ` — cryptographically validates vote integrity.
21- - ` /modnvote audit ` — shows how many votes came from bypass-permitted users.
22- - ` /modnvote fullaudit ` — groups voters by IP to check for irregularities (no vote disclosure).
23- - ` /modnvote reset ` — admin command to clear all votes.
24- - ` /modnvote reload ` — reloads configuration without restarting the server.
25- - ** IP-based duplicate prevention** with configurable bypass permission.
26- - ** SQLite persistence** for reliability and restart safety.
27- - ** Integrity hashing** ensures tallies cannot be silently altered.
28- - ** PlaceholderAPI support** for scoreboard and UI integration.
11+ ## ✨ Key Features
12+
13+ - Anonymous voting (` /modnvote yes|no ` ) — * no vote choice is ever logged to console by the plugin* .
14+ - Live status: ` /modnvote status `
15+ - Shows YES/NO tallies
16+ - Confirms whether ** this tally includes a vote from you**
17+ - Shows whether the tally is ** cryptographically VALID or COMPROMISED**
18+ - Cryptographic verification: ` /modnvote verify `
19+ - Recomputes HMAC from current participants and tallies
20+ - Broadcasts a ** tamper warning** server-wide if integrity fails
21+ - Votes are only accepted when:
22+ - The current tally/HMAC are cryptographically valid, or
23+ - No votes have yet been recorded (fresh round)
24+ - After each accepted vote:
25+ - The tally is updated
26+ - A ** new cryptographic seal (HMAC)** is applied
27+ - The player is told that their vote has been applied and the seal updated
28+ - Admin tools:
29+ - ` /modnvote reset `
30+ - ` /modnvote reload `
31+ - ` /modnvote audit `
32+ - ` /modnvote fullaudit `
33+ - IP duplicate-vote prevention with configurable bypass permission
34+ - SQLite persistence for reliability and restart safety
35+ - PlaceholderAPI support
2936
3037> ModNVote is a successor to the PineVote plugin, rebuilt for broader use under the MODN METL brand.
3138
3239---
3340
34- ## ⚙️ Configuration
41+ ## 🔐 Privacy & Integrity
3542
36- Default excerpt from ` config.yml ` :
43+ ### Vote secrecy
3744
38- ``` yaml
39- permissions :
40- bypass_node : modnvote.bypass # or use your existing alt-protection node (e.g. noaltsexploit.bypass)
45+ ModNVote does ** not** log:
4146
42- logging :
43- audit_votes_to_console : true # Logs when a vote is recorded (never reveals who voted for what)
44- audit_bypass_to_console : true # Logs bypass usage (without disclosing vote choice)
45- ` ` `
47+ - which player voted YES or NO
48+ - any direct mapping of identity → vote choice
49+
50+ It only uses per-player UUIDs and IPs internally to enforce “one vote per person / per location” and for audit tools like ` /audit ` and ` /fullaudit ` .
51+
52+ Minecraft itself will still log commands like ` /modnvote yes ` to the server log — this is handled by the server, not by ModNVote.
53+
54+ ### Tamper detection & protection
55+
56+ ModNVote maintains:
4657
47- > 🧠 ModNVote never logs **what** a player voted — only that a valid vote was recorded.
48- > This keeps your voting process auditable yet fully private.
58+ - A list of all participants’ UUIDs for the current round
59+ - An internal tally: YES and NO counts
60+ - A cryptographic HMAC (using a per-round secret pepper) over:
61+ - round id
62+ - YES count
63+ - NO count
64+ - the sorted list of participant UUIDs
65+
66+ If any of this is altered offline (for example via manual database editing):
67+
68+ - ` /modnvote verify ` reports ** Verification failed**
69+ - A ** server-wide warning broadcast** is sent
70+ - An error is logged to console
71+ - Future votes are ** blocked** until the integrity issue is resolved (e.g. by restoring a valid backup)
72+
73+ ### Verified before and after each vote
74+
75+ When a player casts a vote:
76+
77+ 1 . The plugin first checks the current tally’s integrity.
78+ - If ** no votes exist yet** , it reports that it is starting a fresh sealed tally.
79+ - If integrity is ** valid** , it tells the player that the tally has been cryptographically verified and that their vote is now being applied.
80+ - If integrity is ** compromised or an error occurs** , the vote is blocked and the player is advised to contact staff.
81+ 2 . After the vote is accepted:
82+ - The tally is updated
83+ - A new HMAC is computed
84+ - The player is told that their vote has been recorded and the cryptographic seal has been updated.
4985
5086---
5187
52- ## 🧭 Roadmap
88+ ## 📝 Commands
89+
90+ | Command | Permission | Description |
91+ | --------| ------------| -------------|
92+ | ` /modnvote yes ` | ` modnvote.vote ` | Cast a YES vote (only if integrity is valid or no votes exist yet) |
93+ | ` /modnvote no ` | ` modnvote.vote ` | Cast a NO vote (same integrity rules as above) |
94+ | ` /modnvote status ` | ` modnvote.status ` | View tallies, integrity status, and whether this tally includes your vote |
95+ | ` /modnvote verify ` | ` modnvote.verify ` | Run a full integrity check against stored HMAC |
96+ | ` /modnvote reset ` | ` modnvote.admin.reset ` | Reset all votes for the current round |
97+ | ` /modnvote reload ` | ` modnvote.admin.reload ` | Reload configuration from ` config.yml ` |
98+ | ` /modnvote audit ` | ` modnvote.admin.audit ` | View totals, bypass counts, and tallies |
99+ | ` /modnvote fullaudit ` | ` modnvote.admin.fullaudit ` | Group voters by IP (without revealing which way they voted) |
53100
54- - [ ] MySQL database support for large networks
55- - [ ] Configurable voting periods with automatic start/end
56- - [ ] Player login reminders about active votes
57- - [ ] Admin confirmation before vote resets
58- - [ ] ` /modnvote stop` command to end voting early (without wiping results)
59- - [ ] Multi-question polls and rich voting UIs
101+ ---
60102
61- Want to contribute ideas or code? Open an issue or pull request!
103+ ## ⚙️ Configuration (excerpt)
104+
105+ ``` yaml
106+ # plugins/ModNVote/config.yml
107+
108+ messages :
109+ voted_yes : " &aThanks — your &2YES &avote has been recorded and the cryptographic seal has been updated."
110+ voted_no : " &aThanks — your &cNO &avote has been recorded and the cryptographic seal has been updated."
111+ already_voted : " &cYou have already voted."
112+ duplicate_ip : " &cA vote from your location has already been recorded."
113+ reset_done : " &eAll votes reset."
114+ reloaded : " &eModNVote configuration reloaded."
115+
116+ audit_summary : " Audit » Total: {total}, With bypass: {bypass} ({percent}%) | YES: {yes}, NO: {no}"
117+ fullaudit_header : " Full audit (grouped by IP). Showing voters with bypass; non-bypass on same IP listed under each group."
118+
119+ verify_no_votes : " &7No votes have been cast yet; nothing to verify."
120+ verify_valid : " &aVerification passed: tally matches participant set."
121+ verify_invalid : " &cVerification failed: tally does NOT match participant set."
122+ verify_error : " &cVerification failed due to an internal error; please contact staff."
123+ verify_broadcast_compromised : " [ModNVote] &cWARNING: vote integrity check FAILED. Vote data may have been altered. Please contact staff."
124+
125+ integrity_compromised_vote_block : " &cVoting is currently disabled because the vote integrity check has failed. Please contact staff."
126+ integrity_error_vote_block : " &cYour vote could not be processed due to an internal integrity error. Please try again later or contact staff."
127+ integrity_ok_before_vote : " &aCurrent tally integrity has been cryptographically validated. Applying your vote..."
128+ integrity_ok_first_vote : " &aNo votes recorded yet. Starting a fresh cryptographically sealed tally with your vote."
129+
130+ status_includes_you : " &bThis tally &aDOES &binclude a vote from you."
131+ status_excludes_you : " &bThis tally &cDOES NOT &binclude a vote from you."
132+
133+ permissions :
134+ # Default bypass node used to allow multiple players on the same IP to vote
135+ # (e.g. siblings in the same household).
136+ bypass_node : " modnvote.bypass"
137+ # If you already use an alt-protection plugin, you can set this to its bypass node instead
138+ # (for example: "noaltsexploits.bypass").
139+
140+ cache :
141+ refresh_seconds : 30
142+
143+ logging :
144+ # To protect privacy, ModNVote no longer logs votes to console.
145+ audit_votes_to_console : false
146+ # You may still log bypass usage if desired (does not reveal vote choice).
147+ audit_bypass_to_console : true
148+
149+ integrity :
150+ # Pattern for storing per-round pepper keys on disk
151+ pepper_file_pattern : " round-%d.key"
152+ ` ` `
62153
63154---
64155
65- # # 🤝 Contributing
156+ ## 🧩 PlaceholderAPI
66157
67- Contributions are welcome and encouraged.
68- Please fork the repository and submit a pull request via GitHub — following standard Java + Paper plugin best practices.
158+ If PlaceholderAPI is present, ModNVote registers:
69159
70- Before submitting, ensure your code :
71- - Passes `gradlew build` without warnings or errors
72- - Uses modern Java 21 syntax and adheres to the existing style
73- - Includes concise comments for non-trivial logic
160+ | Placeholder | Description |
161+ |------------|-------------|
162+ | ` %modnvote_yes%` | Number of YES votes |
163+ | `%modnvote_no%` | Number of NO votes |
164+ | `%modnvote_total%` | Total number of votes |
165+
166+ Example usage (scoreboard or GUI) :
167+
168+ ` ` ` text
169+ Yes Votes: %modnvote_yes%
170+ No Votes: %modnvote_no%
171+ Total: %modnvote_total%
172+ ` ` `
74173
75174---
76175
77- # # 🔐 Security
176+ # # 📦 Installation
78177
79- If you discover a vulnerability, please **do not** post it publicly.
80- Instead, email the maintainers at **security@modnmetl.com**.
81- Responsible disclosure ensures fixes can be deployed before details are released.
178+ 1. Download the latest `modnvote-x.x.x.jar` from GitHub Releases.
179+ 2. Drop the jar into your server’s `plugins/` directory.
180+ 3. Start (or restart) your Paper server.
181+ 4. Edit `plugins/ModNVote/config.yml` if needed.
182+ 5. Run `/modnvote reload` to apply changes.
82183
83184---
84185
@@ -87,19 +188,20 @@ Responsible disclosure ensures fixes can be deployed before details are released
87188This project is licensed under the **MIT License** — see the [LICENSE](./LICENSE) file for details.
88189You are free to use, modify, and distribute this software with attribution.
89190
90- ```
91- Copyright (c) 2025 MODN METL LTD
92- Developed by Jamie Edward Thompson (@jamjet3 )
191+ ` ` ` text
192+ Copyright (c) 2025
193+ MODN METL LTD
194+ Developed by Jamie E. Thompson (@jamjet3)
93195` ` `
94196
95197---
96198
97199# # 🏗️ Credits
98200
99- - **Development Lead:** [ Jamie Edward Thompson](https://github.com/jamjet3)
201+ - **Development Lead:** Jamie E. Thompson ([@jamjet3 ](https://github.com/jamjet3) )
100202- **Maintainer:** [MODN METL LTD](https://github.com/MODNMETL)
101203- **Community Testing:** Pinecraft Equestrian SMP
102- - **Build System:** Gradle + ShadowJar
204+ - **Build System:** Gradle
103205- **Supported Platforms:** PaperMC 1.21.x
104206
105207---
0 commit comments