All versions
1.2.1
Release
Protectcord 1.2.1 - Production Release4 months ago 58
Compatibility
Minecraft: Java Edition
1.21.x
1.20.x
1.19.x
1.18.x
1.17.x
1.16.x
1.15.x
1.14.x
1.13.x
1.12.x
1.11.x
1.10.x
1.9.x
1.8.8–1.8.9
Platform
Paper
Changes
Luckperms & PlaceholderAPI & NeoAuthme support has been added!
Changelog
[v1.2.1] - 2026-03-24
Version: 1.2.1 Release Type: Major Feature Update
New Features
Account Per IP Limiting
- Account Per IP Limit — Limit simultaneous connections from the same IP address
- Configurable maximum accounts per IP (default: 3)
- Two enforcement modes:
BLOCKorKICK_OLDEST BLOCKmode: Prevents new connections when limit reachedKICK_OLDESTmode: Automatically kicks oldest session to allow new connection- Whitelisted players automatically bypass limit
- Disabled by default for backward compatibility
- Thread-safe session tracking with automatic cleanup on disconnect
- Local/private IPs bypass tracking (127.0.0.1, 192.168.x.x, etc.)
PlaceholderAPI Integration
- 10 built-in placeholders available out of the box — no expansion download required
%protectcord_warnings%— total warning count%protectcord_warnings_active%— active warning count%protectcord_is_banned%— whether the player is currently banned (true/false)%protectcord_ban_reason%— active ban reason%protectcord_ban_expiry%— ban expiry (Permanentfor permanent bans)%protectcord_is_muted%— whether the player is currently muted (true/false)%protectcord_mute_reason%— active mute reason%protectcord_mute_expiry%— mute expiry (Permanentfor permanent mutes)%protectcord_ip_count%— number of unique IPs tracked for the player%protectcord_trusted_ip_count%— number of trusted IPs- All placeholders support offline players
LuckPerms Integration
- 3 additional placeholders when LuckPerms is present:
%protectcord_rank%— player's primary LuckPerms group%protectcord_prefix%— player's LuckPerms prefix%protectcord_suffix%— player's LuckPerms suffix
- Soft dependency — returns empty string gracefully if LuckPerms is not installed
- LuckPerms hook registered automatically on startup when detected
Staff IP Protection
- New system to protect staff accounts from unauthorized IP access
- Monitors players with
protectcord.ip.protectedpermission for IP changes - Three configurable actions:
kick-and-alert,alert-only,auto-ban - Auto-trust first IP on login (
staff-ip-protection.auto-trust-first-ip) /pc trustip add|remove|list|clear <player> [ip]command for managing trusted IPs- New permission:
protectcord.trustipfor trustip command access - New permission:
protectcord.ip.protectedto mark a player as monitored - New permission:
protectcord.ip.fullto view unmasked IPs in alerts
NeoAuthMe Integration
- Staff IP Protection hooks into NeoAuthMe's login event when AuthMe is installed
- IP check is deferred until after NeoAuthMe authentication completes, preventing false positives
- Uses
RegisteredListener+ reflection to attach tofr.xephi.authme.events.LoginEvent'sHandlerListat runtime — no compile-time AuthMe dependency - Enable with
staff-ip-protection.neoauthme-integration: truein config
IP Masking
- New
ip-maskingconfig section to mask player IPs in alerts and commands - Modes:
last-octet,last-two-octets,full-mask - Players with
protectcord.ip.fullpermission always see full IPs
Storage & Database Improvements
- New
databaseconfig section supportingYAMLandMYSQLstorage backends - MySQL support with HikariCP connection pooling
/pc migrate <from> <to>— migrate data between storage backends/pc purge <days>— purge old warning records/pc alts <player>— view alternate accounts sharing the same IP
Moderation Commands
/pc clear <player>— clear all warnings for a player/pc remove <player> <id>— remove a specific warning by ID/pc alts <player>— list known alts sharing an IP- Offline player support added to
/pc warn,/pc ban,/pc mute,/pc unmute,/pc warnings - Anonymous
/reportsupport (player can choose to report anonymously) - Predefined reasons tab-complete for
/report
Bug Fixes
- Fixed plugin crash on Paper 1.21+ —
NeoAuthMeHookpreviously causedIllegalPluginAccessExceptionby registering@EventHandleron the baseEventclass. Rewritten to useRegisteredListenerwith reflection - Fixed plugin disabling on fresh install — Plugin no longer disables itself when the API key is unconfigured. A warning is logged and IP checking is skipped until the key is set
Configuration Changes
New sections added to config.yml since v1.1.0:
# Account Per IP Limit
account-per-ip-limit:
enabled: false
max-accounts: 3
enforcement: "BLOCK" # "BLOCK" or "KICK_OLDEST"
messages:
account-limit-reached: |
&c&lConnection Limit Reached
&7Maximum accounts per IP: &c{max}
&7Current connections from your IP: &c{current}
account-limit-kicked: |
&c&lYou have been disconnected
&7A new account connected from your IP address.
# Storage backend
database:
type: "YAML" # "YAML" or "MYSQL"
mysql:
host: "localhost"
port: 3306
database: "protectcord"
username: "root"
password: ""
table-prefix: "pc_"
pool:
max-pool-size: 10
min-idle: 2
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
# IP masking
ip-masking:
enabled: false
mask-format: "last-octet" # "last-octet", "last-two-octets", "full-mask"
# Staff IP Protection
staff-ip-protection:
enabled: false
action: "kick-and-alert" # "kick-and-alert", "alert-only", "auto-ban"
protected-permission: "protectcord.ip.protected"
auto-trust-first-ip: true
kick-message: "&cYour IP address has changed. Please contact a staff member."
alert-message: "&c[ProtectCord] &f{player} logged in from an untrusted IP: {ip}"
neoauthme-integration: false
Compatibility
- Fully backward compatible with v1.1.0 YAML data
- softdepend updated:
[NeoAuthMe, PlaceholderAPI, LuckPerms] - PlaceholderAPI required for PAPI placeholders (optional soft dependency)
- LuckPerms required for rank/prefix/suffix placeholders (optional soft dependency)
- Tested on Paper 1.13 - 1.21+
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:y05wfnBZ:Y2LUU9UB"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:y05wfnBZ:Y2LUU9UB"
}

