File Details
rpessentials-4.1.4.jar
- R
- Mar 25, 2026
- 374.95 KB
- 5
- 1.21.1
- NeoForge
File Name
rpessentials-4.1.4.jar
Supported Versions
- 1.21.1
Curse Maven Snippet
[4.1.4]
Bug blitz & RP features — proximity chat, mute system, staff notes, dice rolls, and more.
Fixed
Wrong
SPEC.save()calls in command setters: Every config setter inRpEssentialsCommandsthat modified a value belonging toChatConfig,ScheduleConfig, orModerationConfigwas incorrectly callingRpEssentialsConfig.SPEC.save()instead of the owning spec. This silently discarded every in-game config change (joinMessage,leaveMessage,chatMessageColor,enableTimestamp, all schedule and moderation setters) on server restart. Each setter now callsconfigValue.save()directly, which resolves to the correct spec.MixinServerCommonPacketListenerImpl— crash on early packet: The blur guardRpEssentialsConfig.ENABLE_BLUR.get()was called at the top ofmodifyPacketwith no try/catch. Any packet arriving before the config spec was built (e.g. during server startup) would throw anIllegalStateExceptionand crash the server. Wrapped intry/catch (IllegalStateException).opsSeeAllignoringOP_LEVEL_BYPASSconfig: The admin-exemption check was hardcoded toreceiver.hasPermissions(2)regardless of the configuredopLevelBypassvalue (0–4). A server withopLevelBypass = 3would grant full name visibility to any OP2+ player. The check now readsRpEssentialsConfig.OP_LEVEL_BYPASS.get().Double nametag handler —
NicknameNametagHandler+ClientNametagRenderer: Both classes subscribed toRenderNameTagEventon the same player entities and both calledevent.setContent(). The result was a race between the two handlers on every nametag render frame.NicknameNametagHandlerhas been removed;ClientNametagRendereris now the sole handler.Hardcoded world data path in all managers:
NicknameManager,LicenseManager,WarnManager,LastConnectionManager, andDeathRPManagerall usednew File("world")as the world root — a path that is only valid in vanilla dedicated server layouts. All managers now delegate to the newRpEssentialsDataPaths.getDataFolder()utility which correctly callsserver.getWorldPath(LevelResource.ROOT).Thread.sleep()blocking the ForkJoinPool common pool: The 500ms nametag sync delay inRpEssentialsEventHandler.onPlayerLoginusedCompletableFuture.runAsync(() -> { Thread.sleep(500); ... }), which blocks one of the shared pool's threads for 500ms per player login. Replaced withCompletableFuture.delayedExecutor(500, TimeUnit.MILLISECONDS)— zero threads blocked.Async
saveToFile()accessing non-thread-safe server state:LicenseManager,NicknameManager, andDeathRPManagercalledServerLifecycleHooks.getCurrentServer()andserver.getProfileCache()from asyncCompletableFuturethreads.ProfileCacheis not thread-safe. The player name snapshot is now taken synchronously on the server thread before the async write begins.WorldBorderManagernon-concurrent maps:hasBeenWarnedandplayerZoneStatewere plainHashMapinstances written from the server tick thread. Converted toConcurrentHashMap.Fallback AFK coordinates hardcoded to a specific server: The
/rp afkcommand had compile-time fallback coordinates (x = -2408.5, y = 127.0, z = 588.5, yaw = 138.29f) that would teleport players to an arbitrary location on any other server whereRpConfigwasn't loaded. The fallback now uses(0, 255, 0)with neutral yaw/pitch.extractPlayerNamefragile string parsing inMixinPlayerList(Bugs 10 & 13): The join/leave message system relied onmessage.replace(" joined the game", "").trim()to extract the player name from the vanilla broadcast, and then calledfindPlayerByName()to look up the player — who might not yet be ingetPlayers()at that point. The mixin now only cancels the vanilla broadcast; the custom message is sent fromRpEssentialsEventHandler.onPlayerLogin/onPlayerLogoutwhere theServerPlayerobject is guaranteed valid. A newIRpPlayerListinterface exposed as a mixin onPlayerListcarries the two helper methods thatRpEssentialsEventHandlernow calls via a cast.Static maps surviving server reloads:
WorldBorderManager.hasBeenWarned,playerZoneState, andsystemInitializedare static fields that persist in the JVM across server restarts in the same process. A new@SubscribeEventhandler onServerStoppingEventcallsWorldBorderManager.clearAllCache()to ensure a clean state on the next start.RpEssentialsPermissions.staffCacheunbounded growth: The staff permission cache never evicted entries for players who disconnected abnormally (withoutinvalidateCachebeing called). A newclearExpiredCache()method removes all entries whose TTL has expired; it is called every 400 ticks fromonServerTick.Tick-0 load spike: At server start,
tickCounter = 0caused all three tick buckets (every 40, every 400, every 1200 ticks) to fire simultaneously on the very first tick. The world border check is now offset by+13and the schedule/cleanup block by+37to spread the initial load.Registered missing config: The config
rpessentials-rp.tomlwasn't registered in the RpEssentials.java causing it to not generate in the files. It is now correctly registered.
Added
Proximity Chat: Chat messages are now optionally limited to a configurable radius.
- New config option
enableProximityChat(default:false) inrpessentials-chat.toml. proximityChatDistance— radius in blocks (default: 32, range 1–256).proximityChatBypassPrefix— prefix to send a global message despite proximity mode (default:!). The prefix is stripped before broadcasting.- Two separate format strings:
proximityChatFormat(proximity) andglobalChatFormat(global / bypass). - Staff members outside radius see a spy-log line (configurable via
MessagesConfig.PROXIMITY_CHAT_SPY_FORMAT).
- New config option
Mute System: New staff moderation tool for silencing players in chat.
/rpessentials mute <player> [minutes] [reason]— mute permanently or temporarily./rpessentials unmute <player>— remove mute./rpessentials mute list— list all active mutes.- Muted players cannot send chat messages, use
/rp action,/rp commerce, or/rp incognito. Staff members are always exempt. - Mutes are persisted in
world/data/rpessentials/mutes.jsonand survive server restarts. - Auto-expiration on player login and via midnight sweep.
- Auto-mute from warns: Optional automatic mute when a player accumulates a configurable number of active warns (
muteAutoFromWarns,muteAutoWarnCount,muteAutoDurationMinutesinrpessentials-moderation.toml). - Players are notified on login if they are still muted (configurable message
MUTE_NOTIFY_ON_JOIN).
Staff Notes: Permanent per-player notes visible only to staff.
/rpessentials note add <player> <text>— add a note to a player's file./rpessentials note list <player>— show all notes for a player (also displayed in/whoisoutput)./rpessentials note remove <player> <noteId>— delete a specific note.- Notes stored in
world/data/rpessentials/notes.json. - Requires OP level 2.
Death RP History: Every RP death is now permanently logged.
- Stores timestamp, player name, UUID, and the broadcast message in
world/data/rpessentials/deathrp-history.json. /rpessentials deathrp history [player]— view all RP deaths (optionally filtered to one player). Requires staff.
- Stores timestamp, player name, UUID, and the broadcast message in
Silent Staff Broadcast: New command to send a message visible only to online staff.
/rpessentials staff broadcast <message>— full color code and§/&support.- Logged to console with a
[STAFF-BROADCAST]prefix.
Staff Statistics Dashboard: One-command overview of server moderation state.
/rpessentials stats— displays: online player count with professions, total active warns, mutes, licenses expiring within 7 days, and the 5 most recent player connections.
Dice Roll System: In-game random number generator for RP scenarios.
/rp dice [diceType]— roll the specified die and broadcast the result to nearby players.- Configurable dice types in
rpessentials-rp.toml: formatname;maxValue(e.g.d6;6) or custom facesname;face1,face2,face3(e.g.coin;Heads,Tails). Default set: d4, d6, d8, d10, d12, d20, d100. diceRollDistance— broadcast radius in blocks (-1 = global, default: 32).- Staff outside radius see a spy-log line.
- Result format and spy format fully configurable via
MessagesConfig(DICE_ROLL_FORMAT,DICE_ROLL_SPY_FORMAT).
RP Command Cooldowns: Prevent spam on
/rp action,/rp commerce, and/rp incognito.- Three independent cooldowns in
rpessentials-rp.toml:actionCooldownSeconds,commerceCooldownSeconds,incognitoCooldownSeconds(default: 0 = disabled). - Cooldown is per-player, stored in-memory, cleared on disconnect.
- Blocked uses show an action-bar message with remaining time.
- Three independent cooldowns in
Changed
SyncNametagDataPacket→SyncFullPlayerStatePacket: The two existing nametag packets (SyncNametagDataPacketandHideNametagsPacket) have been merged into a singleSyncFullPlayerStatePacket. The new packet carries: UUID, display name, prefix, suffix, profession, isStaff, and thehideNametagsflag in one payload. This eliminates the race condition whereHideNametagsPacketandSyncNametagDataPacketcould arrive in any order and cause a nametag flicker. All senders andNetworkHandlerregistrations updated accordingly.ClientNametagCacheupdated to store the new record type.RpEssentials.onServerTick— spread tick offsets: The three periodic buckets now use(tickCounter + offset) % periodwith offsets of0,+13, and+37respectively to prevent the tick-0 multi-burst.
Technical
New classes:
RpEssentialsDataPaths— shared utility for world data path resolution.MuteManager— mute lifecycle management (add, remove, check, persist, expire).StaffNoteManager— staff notes lifecycle management.IRpPlayerList— mixin interface exposingrpSendCustomJoinMessage(ServerPlayer)andrpSendCustomLeaveMessage(ServerPlayer)fromMixinPlayerListtoRpEssentialsEventHandler.SyncFullPlayerStatePacket— replacesSyncNametagDataPacket+HideNametagsPacket.
Modified configs:
rpessentials-chat.toml— new[Proximity Chat]section.rpessentials-moderation.toml— new[Mute System]section.rpessentials-rp.toml— new[Dice System]and[RP Cooldowns]sections.rpessentials-messages.toml— new keys:PROXIMITY_CHAT_SPY_FORMAT,MUTE_RECEIVED,MUTE_EXPIRED,MUTE_NOTIFY_ON_JOIN,DICE_ROLL_FORMAT,DICE_ROLL_SPY_FORMAT,ACTION_COOLDOWN_REMAINING,NOTE_*family,DEATHRP_HISTORY_*family.
rpessentials.mixin.json — MixinPlayerList no longer uses @Invoker; MixinPlayerListAccessor removed. IRpPlayerList used instead.
Migration Notes
- No breaking changes for existing servers.
- All new systems are disabled by default — no behavior change unless explicitly configured.
SyncNametagDataPacketandHideNametagsPacketare gone — clients connecting to a 4.1.4 server must also run 4.1.4.mutes.json,notes.json, anddeathrp-history.jsonare created automatically on first use.- The wrong-SPEC-save fix means some config values that appeared to save but didn't will now actually persist. Review your
rpessentials-chat.toml,rpessentials-schedule.toml, andrpessentials-moderation.tomlafter the first start to confirm values are as expected.