
RpEssentials
Nickname players, configurable Jobs, Schedule system (for opening/closing), chat formatting, last connection tracker and much more! Read the description to learn more about it
Список изменений
[4.0.0]
⚠ Breaking Change: The mod ID has changed from oneriaserverutilities to rpessentials. Automatic migration is included — no manual action required on first launch.
Added
-
Per-Day Schedule System: The schedule system now supports individual opening/closing times per day of the week.
- Each day (
MONDAYthroughSUNDAY) has its ownenabled,open, andclosefields. - Disabled days are treated as fully closed.
/rpessentials config set scheduleDay <DAY> <open|close|enabled> <value>— live update without restart.canPlayerJoin()now displays the next open day and its hours in the kick message. Placeholders:{day},{open},{close}./rpessentials scheduleand/schedulenow display the full week at a glance with the current day highlighted.
- Each day (
-
Death Hours: New optional schedule layer that activates RP death during configured time slots, independently of the global Death RP toggle.
- Configurable via
[Death Hours]section inrpessentials-schedule.toml. - Supports multiple slots and cross-midnight ranges.
- When enabled,
isDeathRPEnabled()checks the current time before applying the global state. - Disabled by default.
- Configurable via
-
HRP Hours: New optional schedule layer for HRP (out-of-roleplay) period management.
- Two tiers: tolerated (noted but not punished) and allowed (fully free).
- Broadcast message sent once per slot start to all connected players.
- Configurable display mode:
CHAT,ACTION_BAR,TITLE,IMMERSIVE. - Disabled by default — entirely ignored when
enableHrpHours = false.
-
Auto-Unwhitelist: Automatic removal of inactive players from the whitelist.
- Configurable inactivity threshold (days).
- Runs once per day at midnight.
- Requires
enableLastConnection = true. - Staff members online at the time receive a clickable cancel button to immediately re-whitelist the player.
- Optional extra commands executed per removed player. Placeholders:
{player},{uuid}. - Disabled by default.
-
Vanilla Tag Auto-Management on License: When a license is given or revoked, the corresponding vanilla
/tagis automatically added or removed.- Tag name = profession ID. No configuration required.
-
/rpessentials setrole: New command to assign a role to a player.- Removes all existing role tags, adds the new tag, and sets the corresponding LuckPerms group.
- Roles configurable in
rpessentials-core.tomlunder[Roles]. Format:roleId;lpGroup. - Autocompletion of available roles.
- No recompilation required to add or modify roles.
- Requires OP level 3.
- Replaces
commandadmin.jsfrom KubeJS.
-
/warn— Player-First Autocomplete:/warn infoand/warn removenow accept a player name as the first argument, followed by a warn ID.- Autocompletion step 1: only players who have at least one warn are suggested.
- Autocompletion step 2: only warn IDs belonging to the selected player are suggested, with the reason shown as tooltip.
- Existing handlers
warnInfoandwarnRemoveare reused unchanged — only the command tree structure changed.
Improved
-
RpEssentials.onServerTick():- Added
WorldBorderManager.tick()— was missing, zones were completely silent. - Added
TempLicenseExpirationManager.tickMidnightSweep()— was missing, RP license expiration was never triggered. - Added
LastConnectionManager.tickAutoUnwhitelist()— new. - Added
CraftingAndArmorRestrictionEventHandler.cleanupCaches()every 400 ticks — was missing. tickCounterincrements at the end of the method to ensure all modulo conditions fire correctly on tick 0.
- Added
-
ScheduleConfig:- Replaced single
openingTime/closingTimepair with per-day blocks. - Added
[Death Hours]and[HRP Hours]sections. - Welcome sound volume range extended to 10.0 to match other sound configs.
- All message placeholders unified:
{open},{close},{day},{minutes}.
- Replaced single
-
RpEssentialsScheduleManager:- Full rewrite. Now parses a
Map<DayOfWeek, DaySchedule>at reload. isServerOpen()checks the current day against the map.canPlayerJoin()resolves and displays the next open day.getTimeUntilNextEvent()walks forward up to 7 days to find the next opening.- HRP notification logic (
tickHrpNotifications) is internal totick()— no external call needed. getSchedules()exposed for display in/rpessentials schedule.isInSlot()public utility for cross-midnight time range checking, shared with Death Hours and HRP Hours.
- Full rewrite. Now parses a
-
giveLicense()/revokeLicense():- Added automatic vanilla tag management (
tag <player> add/remove <professionId>).
- Added automatic vanilla tag management (
Technical
-
New Classes:
NametagConfig— Server-side nametag config (rpessentials-nametag.toml).SyncNametagDataPacket— Server→client packet carrying display name, prefix, suffix, profession, isStaff.ClientNametagCache— Thread-safe client-side cache for nametag data received via packet.NametagOcclusionCache— Per-UUID raycast result cache with 50ms TTL.NametagFormatter— Token resolution for nametag format strings.NametagEventHandler—@EventBusSubscriber(Dist.CLIENT), handlesRenderNameTagEvent.
-
Enhanced Classes:
RpEssentials— RegistersNametagConfig.SPEC, fixedonServerTick()(see Improved).RpEssentialsConfig— Added[Roles]section.ScheduleConfig— Full rewrite (see Improved).RpEssentialsScheduleManager— Full rewrite (see Improved).ModerationConfig— Added[Auto Unwhitelist]section (autoUnwhitelistEnabled,autoUnwhitelistDays,autoUnwhitelistExtraCommands).LastConnectionManager— AddedtickAutoUnwhitelist()with staff notification and clickable undo button.RpEssentialsCommands— Added/setrole,/warn info <player> [id],/warn remove <player> <id>,scheduleDayconfig setter. RemovedsetOpeningTime/setClosingTime(replaced bysetDayTime/setDayEnabled).NetworkHandler— RegisteredSyncNametagDataPacket.NicknameManager—setNickname()/removeNickname()now broadcastSyncNametagDataPacketto all players.LicenseManager—addLicense()/removeLicense()now broadcastSyncNametagDataPacketto all players.ClientEventHandler— ResetsClientNametagCacheandNametagOcclusionCacheon disconnect.DeathRPManager—isDeathRPEnabled()now checks Death Hours before applying the global state.RpEssentialsEventHandler— BroadcastsSyncNametagDataPacketfor all online players on login.
-
Data Storage:
- No new files. Data directory path changed from
world/data/oneriamod/toworld/data/rpessentials/(migration automatic).
- No new files. Data directory path changed from
-
Removed:
commandadmin.js(KubeJS) — replaced by/rpessentials setrole.
Configuration
- New File:
rpessentials-nametag.toml
| Section | Key | Default | Description |
|---|---|---|---|
[Behaviour] | enabled | false | Master switch |
[Behaviour] | hideBehindBlocks | true | Block occlusion raycast |
[Obfuscation] | obfuscationEnabled | true | Distance obfuscation |
[Obfuscation] | obfuscationDistance | 10.0 | Distance threshold (blocks) |
[Obfuscation] | obfuscationColor | &8 | Color of obfuscated name |
[Obfuscation] | obfuscationLength | -1 | Fixed length (-1 = real name length) |
[Format] | format | $prefix$name | Readable format |
[Format] | formatObfuscated | $obfuscated | Obfuscated format |
[Rendering] | renderDistance | -1.0 | Max render distance (-1 = vanilla) |
[Rendering] | showWhileSneaking | false | Show nametag while sneaking |
[Staff] | staffAlwaysSeeReal | true | Staff bypass all restrictions |
- New Section:
[Roles]inrpessentials-core.toml
| Key | Default | Description |
|---|---|---|
roles | ["admin;admin", "modo;modo", "builder;builder", "joueur;joueur"] | Role definitions (roleId;lpGroup) |
- New Section:
[Auto Unwhitelist]inrpessentials-moderation.toml
| Key | Default | Description |
|---|---|---|
autoUnwhitelistEnabled | false | Enable auto-unwhitelist |
autoUnwhitelistDays | 30 | Days of inactivity threshold |
autoUnwhitelistExtraCommands | [] | Extra commands on removal ({player}, {uuid}) |
-
New Sections in
rpessentials-schedule.toml[Days.MONDAY]through[Days.SUNDAY]— each withenabled,open,close.[Death Hours]—deathHoursEnabled,deathHoursSlots.[HRP Hours]—enableHrpHours,hrpToleratedSlots,hrpAllowedSlots,hrpToleratedMessage,hrpAllowedMessage,hrpMessageMode.
Migration Notes
- Fully automatic —
ConfigMigratorhandles all four migration phases on first launch:- Phase 1:
oneriaserverutilities-server.toml→config/oneria/oneria-*.toml(v1/v2). - Phase 2:
config/oneria-professions.toml→config/oneria/(v2 root). - Phase 3:
config/oneria/oneria-*.toml→config/rpessentials/rpessentials-*.toml(v3.x). - Phase 4:
world/data/oneriamod/→world/data/rpessentials/(all versions, triggered onServerStartingEvent).
- Phase 1:
- All original files are backed up as
.migrated.bak— nothing is deleted. rpessentials-schedule.tomlis regenerated with new per-day structure. PreviousopeningTime/closingTimevalues are not migrated — set the new per-day fields manually after first launch.- The new
rpessentials-nametag.tomlis generated automatically with all defaults on first start. - Clients connecting to a v4.0.0 server must also run v4.0.0 — packet IDs changed with the modid rename.
[3.2.0] - 2026-03-14
The mod is now fully translated into English. Every player-facing message is also configurable via a new dedicated config file.
Added
-
Full English Translation: Every player-facing message in the mod has been translated to English — this was long overdue.
- All command feedback, warn notifications, private messaging prompts, last connection output, Death RP status, profession restriction messages, whois results, help menu, and player list are now in English.
- The
"Hors-ligne"fallback in/whois,"Aucun joueur avec le nickname","Cliquer pour répondre","[MP] Vous écrivez à", and every other French string have been replaced. - The default value of
WARN_JOIN_MESSAGEinoneria-moderation.tomlis now in English for new installations.
-
New Config File —
oneria-messages.toml: All translated messages are exposed as configurable values.- Server admins can customize or re-translate every message without recompiling the mod.
- Fully supports
§and&color codes in all values. - Reloadable at runtime with
/oneria config reload— no restart required. - Generated automatically on first server start under
config/oneria/oneria-messages.toml. - Organized into clear sections:
[System],[Private Messaging],[Warn System],[Last Connection],[Death RP],[Whois],[Player List],[Help],[Profession Restrictions].
Technical
-
New Classes:
MessagesConfig— NeoForgeModConfigSpec-based config class exposing all user-facing strings asConfigValue<String>. Includesget(configValue, replacements...)andformatDuration(minutes)helpers for placeholder substitution and duration formatting.
-
Enhanced Classes:
RpEssentials— RegistersMessagesConfig.SPECunderoneria/oneria-messages.toml.OneriaCommands— All French hardcoded strings replaced withMessagesConfig.get(...)calls acrosswarnSystemCheck(),updateConfigString(),updateConfigDouble(),showHelp(),playerList(),whoisCommand(),lastConnectionPlayer(),lastConnectionList(),warnAdd(),warnTemp(),warnRemove(),warnClear(),warnPurge(),myWarn(),displayWarnList(),warnInfo(),checkLicense(),deathRpSetGlobal(),deathRpSetPlayer(),deathRpResetPlayer(),deathRpStatus(). Allconfig set deathRp*labels also anglicised.OneriaMessagingManager—"Cliquer pour répondre","[MP] Vous écrivez à","[MP] ... vous écrit","[MP] Vous n'avez personne à qui répondre.","[MP] Ce joueur n'est plus connecté."all replaced withMessagesConfigcalls.ProfessionRestrictionManager— French fallback strings ingetCraftBlockedMessage(),getBlockBreakBlockedMessage(),getItemUseBlockedMessage(),getEquipmentBlockedMessage(), andgetRequiredProfessions()replaced withMessagesConfigcalls.ModerationConfig— Default value ofWARN_JOIN_MESSAGEupdated to English.
Configuration
- New File:
config/oneria/oneria-messages.toml
| Section | Keys |
|---|---|
[System] | configNotLoaded, configUnavailable, configNotBuilt, configUpdated, commandPlayerOnly |
[Private Messaging] | hoverReply, toSender, fromTarget, noOneToReply, targetOffline, consoleTo, consoleFrom |
[Warn System] | receivedPermanent, receivedTemporary, notFound, removeFailed, removedPlayer, clearedPlayer, systemDisabled, systemDisabledConfig, listHeader, listNone, listNoneSelf, listNoneStaff, purgeDone, infoHeader, label keys, type/tag keys, duration format keys |
[Last Connection] | disabled, playerNotFound, noData, noDataList, online, offline, unknown, box label keys, listHeader |
[Death RP] | configUnavailable, globalEnabled, globalDisabled, playerEnabled, playerDisabled, overrideReset, status display keys |
[Whois] | notFound, resultsHeader |
[Player List] | header |
[Help] | All help menu line keys |
[Profession Restrictions] | Fallback message keys, noneAvailable, systemNotInit, hasLicense, noLicense |
Migration Notes
- No breaking changes — fully backward compatible with 3.1.1.
- The new
oneria-messages.tomlfile is generated automatically on first start — no manual action required. - All existing config files (
oneria-core.toml,oneria-chat.toml, etc.) are unchanged. - Servers already running 3.1.1 will retain their
WARN_JOIN_MESSAGEFrench value from their existingoneria-moderation.toml— only new installations get the English default. To update, edit thejoinMessagekey inoneria-moderation.tomlmanually.
[3.1.1] - 2026-03-12
Added
- Death RP System: New system allowing staff to mark players as subject to permanent death (RP perma-death).
- When a marked player dies, the vanilla death message is completely suppressed and replaced by a fully configurable custom message broadcast to all online players.
- Suppression works reliably in both singleplayer and multiplayer via Mixin
@RedirectonPlayerList.broadcastSystemMessage()insideServerPlayer.die()— the player's death itself is never cancelled, only the broadcast. - A configurable sound is played to all online players on death.
- Optional automatic whitelist removal on death.
- Global toggle:
/oneria deathrp enable <true|false>— enables or disables the system for all players without an individual override. Broadcasts a configurable message and sound to all online players when toggled. - Individual override:
/oneria deathrp player <player> enable <true|false>— sets a per-player override, taking priority over the global state. Sends a configurable message and sound to the target player only. - Override reset:
/oneria deathrp player <player> reset— removes the individual override; the player then follows the global state again. - Status command:
/oneria deathrp status— displays the current global state, whitelist removal setting, and the full list of individual overrides with player names. - All four display modes supported for notification messages:
CHAT,ACTION_BAR,TITLE,IMMERSIVE(with automatic fallback toACTION_BARif ImmersiveMessages is absent client-side). - Separate configurable messages and sounds for global activation vs. deactivation, and for individual activation vs. deactivation.
- Individual overrides persisted in
world/data/oneriamod/deathrp.json—UUID (McUsername)key format, async save, survives server restarts. - All commands require OP level 2.
Technical
-
New Classes:
DeathRPManager— Core manager: in-memory state, JSON persistence (lazy init, async save, retrocompatible UUID key format), death handling, toggle notifications, sound broadcasting, andsendMessageToPlayer()utility with all four display modes.MixinDeathMessage—@Redirectmixin onServerPlayer.die()intercepting the singlebroadcastSystemMessage()call to suppress the vanilla death message for marked players without affecting the death itself.
-
Enhanced Classes:
OneriaConfig— Added 19 new config entries in a dedicated[DeathRP]section (global enabled, whitelist remove, death message, death sound, individual toggle messages/modes/sounds, global toggle messages/modes/sounds).OneriaCommands— Added/oneria deathrpsubcommand tree (4 commands). AddedupdateConfigString()andupdateConfigDouble()helper methods. Added all DeathRP keys to/oneria config set.
-
New Mixin:
MixinDeathMessageregistered inoneria.mixins.json.
Configuration
- New Section:
[DeathRP]inoneria-core.toml
| Clé | Défaut | Description |
|---|---|---|
globalEnabled | false | Activation globale du système |
whitelistRemove | false | Retirer de la whitelist à la mort |
deathMessage | "&c[Mort RP] &f%player%..." | Message de mort (%player%, %realname%) |
deathSound | "minecraft:entity.wither.death" | Son joué à tous à la mort |
deathSoundVolume | 1.0 | Volume du son de mort |
deathSoundPitch | 1.0 | Pitch du son de mort |
playerToggle.enableMessage | "&6[Mort RP] ..." | Message d'activation individuelle |
playerToggle.enableMessageMode | "CHAT" | Mode d'affichage (CHAT/ACTION_BAR/TITLE/IMMERSIVE) |
playerToggle.disableMessage | "&6[Mort RP] ..." | Message de désactivation individuelle |
playerToggle.disableMessageMode | "CHAT" | Mode d'affichage |
playerToggle.toggleSound | "minecraft:block.note_block.pling" | Son de toggle individuel |
globalToggle.enableMessage | "&6[Mort RP] ..." | Message d'activation globale (%staff%) |
globalToggle.enableMessageMode | "CHAT" | Mode d'affichage |
globalToggle.disableMessage | "&6[Mort RP] ..." | Message de désactivation globale (%staff%) |
globalToggle.disableMessageMode | "CHAT" | Mode d'affichage |
globalToggle.globalToggleSound | "minecraft:ui.toast.challenge_complete" | Son de toggle global |
Tous ces paramètres sont modifiables en live via /oneria config set <clé> <valeur> sans redémarrage.
Migration Notes
- Aucun changement cassant — entièrement rétrocompatible avec 3.1.0.
- Le système est désactivé par défaut (
globalEnabled = false). - Aucun joueur n'est marqué au démarrage — les overrides individuels sont vides jusqu'à usage explicite des commandes.
[3.1.0] - 2026-03-08
Added
-
Last Connection Tracking:
- Automatic recording of each player's last login and logout times.
- Data stored in
world/data/oneriamod/lastconnection.json—UUID (McUsername)key format, consistent with all other mod data files. - Async save via
CompletableFuture, synchronous load on startup. - Login is recorded immediately on connection; logout is recorded on disconnection.
- Staff commands:
/oneria lastconnection <player>— displays a player's last login, last logout and current online status./oneria lastconnection list [count]— lists the N most recent connections sorted by descending date (default: 20).
- Fully configurable in
oneria-moderation.toml, new[Last Connection]section:enableLastConnection— enable/disable the entire tracking system.trackLogout— toggle logout time recording independently.dateFormat— JavaSimpleDateFormatpattern used for both storage and display.
-
Warn System:
- Full staff warning system with permanent and temporary warns.
- Data stored in
world/data/oneriamod/warns.json— auto-incremental integer IDs, recalculated from the current max after every deletion to avoid gaps and collisions. - Warned player is notified immediately in chat with the reason, duration, and an invite to run
/mywarn. - Configurable staff broadcast on warn add and warn remove.
- Active warn count notified to the player on every login (configurable message with
{count}placeholder). - Optional automatic purge of expired temp-warns on player login.
- Staff commands (requires
isStaff):/oneria warn add <player> <reason>— issue a permanent warn./oneria warn temp <player> <minutes> <reason>— issue a temporary warn with configurable max duration./oneria warn remove <warnId>— remove a specific warn; notifies the player if online./oneria warn list [player]— list all warns, or all warns for a specific player./oneria warn info <warnId>— show full details of a warn (issuer, reason, date, remaining time)./oneria warn clear <player>— remove all warns for a player at once; notifies the player if online./oneria warn purge— manually purge all expired temp-warns.
- Player command (available to all):
/mywarn— display own active warns with reason, issuer, date and remaining duration.
- Fully configurable in
oneria-moderation.toml, new[Warn System]section:enableWarnSystem— enable/disable the entire system.notifyOnJoin— toggle login notification.joinMessage— customizable login notification message ({count}placeholder).maxTempDays— maximum allowed duration for/oneria warn temp(0 = unlimited).autoPurgeExpired— toggle automatic purge of expired warns on player login.addedBroadcastFormat— staff broadcast format on warn add ({id},{staff},{player},{reason},{expiry}).removedBroadcastFormat— staff broadcast format on warn remove ({id},{staff}).
Fixed
lastConnectionPlayer— Lambda Capture:targetUUIDwas reassigned inside anif/elseblock, making it non-effectively-final and causing a compilation error when captured in asendSuccesslambda.- Fixed by capturing
final UUID finalTargetUUIDafter the null-check early return.
Technical
-
New Classes:
LastConnectionManager— connection tracking manager, lazy init + async save pattern consistent withNicknameManager.WarnManager— warn manager withWarnEntryinner class, auto-incremental IDs, async save pattern consistent withLicenseManager. ExposesrecalculateCounter()called after every deletion (removeWarn,clearWarns,purgeExpiredWarns).
-
Modified Classes:
ModerationConfig— two new config sections:[Last Connection]and[Warn System].OneriaEventHandler—onPlayerLoginnow callsLastConnectionManager.recordLogin()immediately (before the deferred block), and the deferred block includesnotifyWarnsOnJoin()andautoPurgeWarnsOnJoin().onPlayerLogoutnow callsLastConnectionManager.recordLogout().OneriaCommands— two new command modules:lastconnection(2 handlers) andwarn(13 handlers +/mywarnstandalone alias).
-
Data Storage:
world/data/oneriamod/lastconnection.json— last login/logout per player, keyed byUUID (McUsername).world/data/oneriamod/warns.json— full warn registry, JSON array ofWarnEntryobjects.
Migration Notes
- No breaking changes — fully backward compatible with 3.0.3.
- Both new data files are created automatically on first use; no manual action required.
oneria-moderation.tomlgains two new sections on first launch — existing options are untouched.- Both systems are disabled-safe: setting
enableLastConnectionorenableWarnSystemtofalsecompletely bypasses all related logic with no side effects.
[3.0.3] - 2026-03-03
Added
-
Custom
/listCommand:- Replaces vanilla
/listwith a cleaner output showing nicknames and real usernames in parentheses. - Players without a nickname are displayed by their real username only.
- Replaces vanilla
-
/oneria helpCommand:- Displays available commands to the player.
- Staff players see an additional section with staff-only commands.
[3.0.2] - 2026-03-03
Added
- Revoked License Visual Marker:
- Physical license items are now visually marked when their license has been revoked.
- Lore is updated with
✖ PERMIS RÉVOQUÉandCe permis n'est plus valide.on the item directly. - Marking is triggered on player login, every 10 minutes server-side, and immediately on
/license revokeif the player is online. - Uses a
revokedflag stored in the item'sCUSTOM_DATAto avoid duplicate marking. - Items given before this update (without
professionIdin CUSTOM_DATA) are not affected.
Technical
- Modified Classes:
TempLicenseExpirationManager— addedmarkRevokedLicenseItems(ServerPlayer), called on login and in midnight sweep.OneriaEventHandler— callsmarkRevokedLicenseItems()on player login.OneriaCommands—revokeLicense()now callsmarkRevokedLicenseItems()immediately if player is online.RpEssentials— added 10-minute tick (% 12000) to sweep all online players.OneriaCommands—giveLicense()now storesprofessionIdin itemCUSTOM_DATAfor future revoke detection.
[3.0.1] - 2026-03-03
Fixed
-
License Revocation — No Longer Removes Item From Inventory:
/license revokenow only removes the profession fromlicenses.jsonand invalidates permissions.- The physical license item is kept in the player's inventory as a decorative object.
- Profession restrictions are lifted immediately via
ProfessionSyncHelper.syncToPlayer(). - Player is notified that their license has been revoked.
-
RevokedLicenseManager— Removed:- The class has been entirely removed as it no longer serves a purpose.
- All references in
OneriaEventHandlerandOneriaCommandshave been cleaned up.
-
OneriaEventHandler— Raw Thread Replaced:- The
new Thread(() -> { Thread.sleep(2000); ... }).start()pattern on player login has been replaced withCompletableFuture.runAsync(). - Eliminates the creation of one OS thread per player connection under load.
server.execute()ensures the deferred logic still runs on the server thread.- Added imports
net.minecraft.server.MinecraftServerandnet.neoforged.neoforge.server.ServerLifecycleHooks.
- The
-
RpEssentials.onServerTick()—serverVariable Scope:var serverwas declared inside theif (tickCounter++ % 40 == 0)block, making it invisible to the rest of the method.- Now declared once at the top of the method and reused by all blocks.
Added
-
TempLicenseExpirationManager— Automatic RP License Expiration:- New class handling automatic expiration of RP licenses issued via
/license giverp. - Two triggers:
checkOnLogin(player, server)on player connection, andtickMidnightSweep(server, hour, minute)called fromonServerTick()every 60 seconds (effective once per day at midnight). - On expiration: removes from
licenses-temp.json, removes fromlicenses.jsonas a safety measure, invalidates cache, syncs client restrictions, and notifies the player if online. - Physical item is kept in inventory — player is informed it is no longer valid.
- All expirations logged to
license-audit.jsonwith actionEXPIRE_RP. - Takes
MinecraftServeras an explicit parameter — never usesplayer.getServer()which is@Nullable.
- New class handling automatic expiration of RP licenses issued via
-
LicenseManager— Two New Methods:removeTempLicense(TempLicenseEntry)— removes a specific entry fromlicenses-temp.json, matched bytargetUUID+profession+expiresAt.logActionSystem(action, targetName, targetUUID, profession, extra)— logs an audit entry without a human staff actor, used for system-triggered actions such asEXPIRE_RP.
Technical
-
Removed Classes:
RevokedLicenseManager— fully deleted, no replacement needed.
-
New Classes:
TempLicenseExpirationManager— automatic expiration logic for RP licenses.
-
Modified Classes:
OneriaEventHandler— removedRevokedLicenseManagercalls, replaced raw thread, addedTempLicenseExpirationManager.checkOnLogin().RpEssentials— fixedserverscope inonServerTick(), addedtickMidnightSweepcall every 1200 ticks.OneriaCommands—revokeLicense()no longer callsRevokedLicenseManager, now callsProfessionSyncHelper.syncToPlayer()immediately after revocation.giveLicense()also callssyncToPlayer().LicenseManager— addedremoveTempLicense()andlogActionSystem().
Migration Notes
- No configuration changes required.
RevokedLicenseManageris gone — if you have any custom patches referencing it, remove them.- Players who had licenses revoked in 3.0.0 and still have the physical item in their inventory will keep it. Their permissions are already removed in
licenses.json— no action needed.
[3.0.0] - 2026-03-02
⚠ Breaking Change: Configuration entirely restructured into 5 separate files under config/oneria/.
Automatic migration is included — no manual action required on first launch.
Added
-
License Audit Log: Every license action permanently recorded in
world/data/oneriamod/license-audit.json:- Tracks
GIVE,REVOKE, andGIVE_RPactions. - Stores timestamp, staff name & UUID, target name & UUID, profession, and extra info.
- Persists across restarts — full history always available.
- Logged to server console simultaneously for real-time monitoring.
- Tracks
-
Temporary License Registry: RP licenses issued via
/license giverpnow tracked inworld/data/oneriamod/licenses-temp.json:- Stores issuance date, expiration date, duration in days, staff emitter, and recipient.
- Acts as a permanent administrative registry — no automatic expiration logic (date is printed on the physical item).
- Also logged to
license-audit.jsonwith the expiration date as extra info.
-
Config Split — 5 separate files: The monolithic
RpEssentials-server.tomlhas been split into themed config files underconfig/oneria/:oneria-core.toml— Obfuscation, Permissions, WorldBorder & Zones.oneria-chat.toml— Chat formatting, timestamps, markdown, join/leave messages.oneria-schedule.toml— Schedule system, warnings, welcome message & sound.oneria-moderation.toml— Silent commands and teleportation platforms.oneria-professions.toml— Profession definitions and restrictions (moved fromconfig/root toconfig/oneria/).
-
ConfigMigrator — Automatic migration on first launch:
- Detects the legacy
RpEssentials-server.tomlon startup. - Parses all values and redistributes them into the 5 new files, preserving every custom value.
- Handles renamed keys automatically (e.g.
serverClosedMessage→msgServerClosed,warningMessage→msgWarning). - Renames the legacy file to
.migrated.bak— your data is never deleted. - Skips migration entirely if new files already exist — safe to restart multiple times.
- Full migration report logged to server console.
- Detects the legacy
-
OneriaPatternUtils: New shared wildcard pattern matching utility:
- Used by both
ClientProfessionRestrictionsandProfessionSyncHelper. - Eliminates duplicated matching logic across the codebase.
- Used by both
Improved
-
LicenseManager — Enriched API:
- New inner classes:
AuditEntryandTempLicenseEntry. - New methods:
logAction(),addTempLicense(),getAuditLog(),getAllTempLicenses(). - All three files share the same async save pattern via
CompletableFuture. reload()now resets and reloads all three files simultaneously.
- New inner classes:
-
Thread Safety — ConcurrentHashMap across all managers:
OneriaPermissions,LicenseManager,ProfessionRestrictionManager,NicknameManager, andProfessionRestrictionEventHandlermigrated toConcurrentHashMap.- Eliminates race conditions under high player count or concurrent server-side events.
-
Regex cache in ProfessionRestrictionManager:
- Wildcard patterns (e.g.
minecraft:*_sword) are now compiled once viacomputeIfAbsent()and cached in aConcurrentHashMap. - Avoids repeated
Pattern.compile()calls on every craft, break, use, and equip check.
- Wildcard patterns (e.g.
-
Async I/O in NicknameManager:
- File reads and writes now run via
CompletableFutureto avoid blocking the server thread.
- File reads and writes now run via
-
Tick-based filtering in CraftingAndArmorRestrictionEventHandler:
- Equipment checks no longer run on every tick.
- Reduces CPU overhead on servers with many simultaneous online players.
-
OneriaCommands — modifyList() factorization:
- The 9 handlers for whitelist/blacklist/alwaysvisible (add/remove/list × 3 lists) are now delegated to a single
modifyList()method. - Eliminates ~60 lines of duplicated logic.
- Original formatting style preserved (1522 lines vs 1606 — reduction from factorization only, no logic removed).
- The 9 handlers for whitelist/blacklist/alwaysvisible (add/remove/list × 3 lists) are now delegated to a single
-
OneriaCommands — giveLicense(), revokeLicense(), giveRPLicense():
- Now call
LicenseManager.logAction()on every action. giveRPLicense()additionally callsLicenseManager.addTempLicense()to register the temp entry.- Staff player resolved from
CommandSourceStack— supports both player and console execution.
- Now call
Fixed
- UUID Bug in ProfessionRestrictionManager:
isExemptFromProfessionRestrictions()was comparing by player name instead of UUID.- Player name changes no longer silently break profession exemptions.
Technical
-
New Classes:
ConfigMigrator— One-shot migration utility, runs beforeregisterConfig()on startup.OneriaPatternUtils— Shared wildcard pattern matching, used byClientProfessionRestrictionsandProfessionSyncHelper.ChatConfig— Config class for chat system and join/leave messages (oneria-chat.toml).ScheduleConfig— Config class for schedule, messages, and welcome system (oneria-schedule.toml).ModerationConfig— Config class for silent commands and platforms (oneria-moderation.toml).
-
Enhanced Classes:
LicenseManager— Three-file I/O,AuditEntry/TempLicenseEntryinner classes, full audit & temp license API.OneriaCommands—giveLicense(),revokeLicense(),giveRPLicense()wired to audit log and temp registry.modifyList()factorization.OneriaConfig— Now only contains Obfuscation, Permissions, and WorldBorder/Zones. Chat, Schedule, Moderation extracted to dedicated classes.RpEssentials— Registers 5 configs with explicitoneria/paths, callsConfigMigrator.migrateIfNeeded()before registration.ProfessionRestrictionManager— ConcurrentHashMap, regex cache, UUID-based exemption check.NicknameManager— Async I/O via CompletableFuture.CraftingAndArmorRestrictionEventHandler— Tick-based equipment check filtering.ClientProfessionRestrictions/ProfessionSyncHelper— Deduplicated via OneriaPatternUtils.
-
Data Storage:
world/data/oneriamod/license-audit.json— Append-only audit log, JSON array ofAuditEntryobjects.world/data/oneriamod/licenses-temp.json— RP license registry, JSON array ofTempLicenseEntryobjects.
Migration Notes
- Fully automatic —
ConfigMigratorhandles everything on first launch. No manual action required. - Legacy
RpEssentials-server.tomlis backed up asRpEssentials-server.toml.migrated.bakin the sameconfig/folder. oneria-professions.tomlmoves fromconfig/root toconfig/oneria/— handled by the migrator.- If migration fails for any reason, the legacy file is left completely untouched and a detailed error is logged. Contact the dev team for manual migration assistance.
- All custom values (whitelist, platforms, schedules, messages, zones, etc.) are fully preserved through migration.
