File Details
rpessentials-4.1.3.jar
- R
- Mar 22, 2026
- 334.70 KB
- 76
- 1.21.1
- NeoForge
File Name
rpessentials-4.1.3.jar
Supported Versions
- 1.21.1
Curse Maven Snippet
[4.1.3]
GUI overhaul, cross-midnight schedule, tooltip fixes, license system improvements.
Added
/rpessentials license reissue <player> <profession>: New staff command to give a replacement license item to a player who already has the profession but lost the physical item. The profession data and restrictions are unchanged — only the item is re-created and given. The action is logged to the audit log asREISSUE. Requires OP level 2.LicenseHelper(new class): Shared utility that creates and gives a physical license item to a player. Used by bothgiveLicense()inRpEssentialsCommandsandSetPlayerProfilePacket, ensuring both paths produce an identical item and perform the same side-effects (tag add, cache invalidation, client restriction sync).Cross-midnight schedule support (
RpEssentialsScheduleManager): The schedule system now handles sessions that span midnight (e.g. 22:00 → 02:00). Before this fix, players were incorrectly kicked at 00:00 even if the configured closing time was 02:00.DaySchedule.isOpen()now handles both same-day (open < close) and cross-midnight (close < open) sessions.- New
getActiveSchedule()method: checks today's session first, then yesterday's if it crosses midnight and is still active. minutesUntilClose()calculates remaining time correctly across midnight.tickMidnightSweep()no longer resetshasOpenedToday/hasClosedTodayif a cross-midnight session is still ongoing at 00:00.checkWarnings()is now based onminutesUntilClose()with a 2-minute tolerance window instead of exact clock comparison, preventing missed warnings due to tick granularity.isInSlot()(Death Hours, HRP Hours) reusesDaySchedule.isOpen()— cross-midnight support applies to those systems as well.
Profession selector revoke button (Profile Manager GUI): When navigating to a profession the selected player already owns, a §c✖ Revoke license button appears between the
◀and▶arrows. Clicking it sends a revoke packet to the server, removes the license, applies the tag removal, marks the physical item as revoked, and updates the local list immediately for visual feedback.Full i18n for admin GUIs: All previously hardcoded French strings in
ProfessionEditorScreenandPlayerProfileScreenare now translated via the Minecraft language system (Component.translatable/I18n.get). New keys added toen_us.jsonandfr_fr.json:- Color palette:
rpessentials.gui.color.*(10 colors, shared between both screens) - Profession editor:
rpessentials.gui.profession_editor.* - Player profile:
rpessentials.gui.player_profile.* - Shared:
rpessentials.gui.btn_more
- Color palette:
Tab autocomplete for restrictions (Profession Editor GUI): The restriction input field now supports keyboard-driven autocomplete identical to Minecraft command completion.
- Typing any character immediately filters the item/block registry.
- Tab cycles forward through suggestions, Shift+Tab cycles backward.
- ↓ / ↑ arrows navigate the list.
- Enter validates and adds the selected suggestion.
- Escape closes the dropdown without adding.
- Click on any line also selects it.
- The dropdown is rendered as an overlay after
super.render(), so it always appears above all other widgets and is never hidden behind them. - Two-pass matching: prefix matches first, then contains matches.
Full profession list in Profile Manager GUI:
OpenPlayerProfileGuiPacket.PlayerDatanow carriesList<String> currentLicenses(the complete license list) instead of a singleString currentLicense. The profession selector navigates all professions; owned ones are shown in red with a✔ Already ownedindicator. The list of active licenses is displayed below the selector. On load, the cursor starts on the first unowned profession for convenience.Profession save confirmation with summary (
SaveProfessionPacket): After saving a profession from the GUI, the admin now receives a detailed confirmation message listing the display name, color preview, and each restriction category with its entry count and the first 3 items (e.g.Equipment: minecraft:diamond_sword, minecraft:iron_sword (2)).
Changed
ProfessionEditorScreen— "New profession" button relocated: The button has moved from the right-hand form area to the bottom of the left panel (the profession list), which is the more instinctive position since that is where the list of professions lives.SetPlayerProfilePacket— full license flow from GUI: Granting a profession through the Profile Manager GUI now triggers the same complete flow as the/license givecommand: physical item created with correct name/lore/NBT, vanilla scoreboard tag added, cache invalidated, client restriction sync sent. Previously the item was never created and the tag was never set.SetPlayerProfilePacket— duplicate license guard: If the selected player already holds the chosen profession when clicking "Apply", the server returns an informational message to the admin (already has this license — use /license reissue to give a replacement item) instead of silently duplicating the entry.SetPlayerProfilePacket—revokeModefield: The packet now carries aboolean revokeMode. Whentrue, thelicenseIdis revoked rather than granted. This cleanly separates the give and revoke paths in a single packet type without needing a second packet.ProfessionConfig.GLOBAL_UNBREAKABLE_BLOCKSandCONTAINER_OPEN_RESTRICTIONSnow shown in item tooltips:ProfessionRestrictionEventHandler.onItemTooltippreviously only showed craft, item-use, and equipment restrictions. It now also shows:Mining: ✘ — <profession>for blocks inglobalUnbreakableBlocks.Open: ✘ — <profession>for containers incontainerOpenRestrictions(wildcard patterns supported).- The whole method is wrapped in
try/catch (IllegalStateException)to avoid crashes if the config is not yet loaded at tooltip render time.
Fixed
License item name ignoring color code from GUI: The GUI saves profession colors as
&e-style codes.Component.literal()does not parse&or§— it renders them as literal characters.LicenseHelpernow calls.replace("&", "§")on the color prefix before passing it throughColorHelper.parseColors(), producing a correctly colored item name regardless of whether the code was entered via the GUI (&e) or hand-edited in the config (§e).Revoked license message displayed twice:
TempLicenseExpirationManager.markRevokedLicenseItems()was writing the revoke title and body directly intoDataComponents.LORE, whileLicenseItem.appendHoverText()was independently reading therevokedflag and appending the same lines at render time. Because the Minecraft tooltip system concatenates lore andappendHoverTextoutput, the message appeared twice.markRevokedLicenseItems()now only sets therevoked = trueflag in CUSTOM_DATA and leaves all visual rendering exclusively toappendHoverText().Cross-midnight session players kicked at midnight:
isServerOpen()only checked today'sDaySchedule, so any session defined withclose < open(e.g. 22:00 → 02:00) would appear closed from 00:00 onwards even though it should remain open until 02:00. Fixed bygetActiveSchedule()which additionally checks yesterday's schedule for an ongoing cross-midnight session.SaveProfessionPacketcompilation error:String MAX_INLINE = 3;— incompatible types (intassigned toString). Fixed toint max = 3;.
Technical
LicenseHelper.java— new shared class innet.rp.rpessentials.profession.OpenPlayerProfileGuiPacket.PlayerData—String currentLicensereplaced byList<String> currentLicenses. StreamCodec updated accordingly.RequestOpenGuiPacket.handlePlayerProfileGui()— now populates the full license list viaLicenseManager.getLicenses().RpEssentialsScheduleManager—getActiveSchedule()added as the main entry point for all open/close checks.DaySchedulegainscrossesMidnight()andminutesUntilClose().isInSlot()refactored to delegate toDaySchedule.isOpen().RpEssentials.onServerTick()— schedule block updated to usegetActiveSchedule()for warning and closing detection. Opening detection still usesgetTodaySchedule()to fire at the correct wall-clock time.MessagesConfig— three new keys:LICENSE_REISSUE_STAFF,LICENSE_REISSUE_PLAYER,LICENSE_REISSUE_NOT_FOUND.

