Releases: HyperSystemsDev/HyperPerms
HyperPerms v2.9.0
Hotfix: Web Editor Session Create
Fixed
- Web editor returning 500 on
/hp editor— The gzip compression introduced in 2.8.9 was applied to all session create requests, but the Cloudflare Worker API does not supportContent-Encoding: gzipon incoming request bodies. This caused every/hp editorcommand to fail with "Server returned status 500". Compression is now only applied to payloads exceeding 500KB, keeping normal requests uncompressed while still protecting very large servers from HTTP 413 errors.
If you are on 2.8.9, update immediately.
HyperPerms v2.8.9
Architecture Rehaul & MMOSkillTree Integration
First-Class MMOSkillTree Support
HyperPerms now has full, first-class integration with MMOSkillTree — one of the biggest plugins on Hytale.
- 200+ permission nodes registered across admin, command, skill, boost, and alternate prefix categories
- All 23 skill nodes —
mmoskilltree.skill.mining,.woodcutting,.excavation,.harvesting,.fishing,.swords,.daggers,.polearms,.staves,.axes,.blunt,.archery,.unarmed,.defense,.taming,.acrobatics,.crafting,.repair,.alchemy,.enchanting,.cooking,.smithing,.building - All 140 XP boost permission nodes covering personal and global boosts for all skills, skill categories, and all-skills targets with varying multipliers, durations, and cooldowns
ziggfreed.*alternate prefix support — MMOSkillTree checks permissions through bothmmoskilltree.*andziggfreed.mmoskilltree.*prefixes. HyperPerms now correctly resolves both via bidirectional aliases- Hytale command path aliases —
com.ziggfreed.mmoskilltree.command.*paths resolve to theirmmoskilltree.command.*equivalents - Wildcard expansion for all MMST permission categories
- Tab completion & web editor now show all MMST permission nodes
- Updated RPG & Survival templates with appropriate MMST permissions at each rank tier (XP boosts scale with rank progression)
Staged Plugin Lifecycle
The plugin initialization system has been completely rewritten with a clean, modular architecture:
- 11 ordered stages: Config → Storage → CoreManager → Resolver → Registry → Chat → Integration → Web → Scheduler → Analytics → DefaultGroups
PluginLifecycleorchestrator initializes stages in order and shuts them down in reverse — if any stage fails, previously initialized stages are safely torn downServiceContainerprovides typed dependency injection across all stagesHyperPerms.javareduced from ~400 lines of monolithic init to ~25 lines — all setup logic now lives in dedicatedStageimplementations
Annotation-Based Command Framework
The entire command system has been rebuilt using a declarative annotation-driven approach:
- New annotations:
@CommandGroup,@Command,@Arg,@OptionalArg,@Permission,@Confirm CommandScannerautomatically discovers and registers annotated command methods at startupCommandDispatcherhandles argument parsing, permission checks, and confirmation flows- 5 annotated command groups replace 42 individual command classes:
GroupCommands,UserCommands,DebugCommands,RootCommands,PermsCommands,BackupCommands - Net reduction of ~1,500 lines with significantly better maintainability
Web Editor Improvements
- Gzip compressed session requests — Session create payloads are now gzip compressed before sending to the API, preventing HTTP 413 errors on servers with many groups and permissions
Bug Fixes
- Fixed config being null during early stage initialization
- Fixed default groups being created before storage was fully ready
- Integrated 2.8.8's centralized sync and diff-based permission logic into the new lifecycle system
HyperPerms v2.8.8
[2.8.8] - 2026-02-23
Server Version: 2026.02.19-1a311a592
Fixed
- Permission pollution in Hytale's permissions.json -
syncPermissionsToHytale()previously pushed all resolved permissions on every change, causing hundreds of permissions to accumulate. Now uses diff-based sync that computes the delta between Hytale's current state and HyperPerms' resolved set, only adding missing and removing stale permissions - Race condition in concurrent permission syncs - Multiple threads (command thread, scheduler, CF pool, web editor) could call
syncPermissionsToHytale()simultaneously for the same user, racing on Hytale's non-thread-safeHashSetview fromgetUserPermissions(). Added per-UUID synchronization locks and defensive copying of the live view - Scattered manual sync calls - Six user commands and
HyperPermsPermissionProvidereach had their own inlinesyncPermissionsToHytale()call via bootstrap reflection. Centralized all sync logic into aCacheInvalidator.setSyncListener()hook — every cache invalidation now automatically triggers Hytale sync for affected online users - Group commands invalidated entire cache - Group permission/property changes (
setperm,unsetperm,setprefix,setsuffix,setweight,setexpiry,parent add/remove) calledinvalidateAll()instead of targetedinvalidateGroup(), causing unnecessary cache churn for unrelated users - Expired permissions not synced to Hytale -
ExpiryCleanupTaskremoved expired nodes but didn't invalidate the cache or trigger Hytale sync, so expired permissions remained active until the player reconnected - Inconsistent cache invalidation API - Some commands used
getCache().invalidate()(bypassing sync) while others usedgetCacheInvalidator().invalidate()(with sync). Unified all commands to usegetCacheInvalidator()
v2.8.7
Fixed
- Permissions not applied after permissions.json wipe -
syncPermissionsToHytale()only removed negated permissions from Hytale's internal storage but never added granted permissions. After an OOM crash wiped Hytale'spermissions.json, third-party plugins (OrbisGuard, etc.) usingPermissionsModule.hasPermission()saw an empty permission set. Now pushes all expanded granted permissions (with wildcard and alias resolution) to other providers, then removes denied permissions — ensuring negations still override grants - JSON storage data loss on JVM crash -
saveUser(),saveGroup(), andsaveTrack()usedFiles.writeString()withTRUNCATE_EXISTING, which could leave files empty or corrupt if the JVM crashed mid-write. Now writes to a.tmpfile first, then atomically renames to the target path - Corrupt JSON file crashes entire load -
loadAllUsers(),loadAllGroups(), andloadAllTracks()only caughtIOException, notJsonParseException(aRuntimeException). A single corrupt file would crash the entire load and prevent all other files from loading. Now catches all exceptions, logs a warning with the filename and error, and continues loading remaining files
v2.8.6 — MariaDB/MySQL Storage, Command Refactor & Bug Fixes
Highlights
MariaDB/MySQL Storage Backend — HyperPerms now supports database-backed storage for multi-server deployments. Connect all your servers to a shared MariaDB or MySQL database with a single config change.
Massive Command Refactor — The monolithic 3,000-line command handler has been decomposed into 48 focused command classes organized by domain, making the codebase significantly more maintainable.
Critical Bug Fixes — Permissions now properly sync to Hytale after group commands, tab list sorts by weight, and prefix/suffix priorities no longer reset to 0 from the web editor.
Added
MariaDB/MySQL Storage Backend
- Full
MariaDBStorageProvider(~1,050 lines) with HikariCP connection pooling - Complete async CRUD for users, groups, tracks, and permission nodes
- JSON dump backup/restore strategy for networked databases
- 5-table schema:
users,groups,user_nodes,group_nodes,tracks(InnoDB, utf8mb4) - Configure via
storage.type: "mariadb"or"mysql"inconfig.json - Full connection options: host, port, database, username, password, poolSize, useSSL
useSSLconfig option with automatic migration from older config versions- HikariCP 6.2.1 and MariaDB JDBC 3.5.1 bundled in shadow JAR
Category-Based Debug Logging
- New
Logger.DebugCategoryenum with 10 categories:RESOLUTION,CACHE,STORAGE,CONTEXT,INHERITANCE,INTEGRATION,CHAT,WEB,MIGRATION,EXPIRY - Each toggleable individually via
/hp debug toggle <category> - Debug traces throughout the chat pipeline (
ChatListener,ChatManager,ChatFormatter,PrefixSuffixResolver) - Debug traces for integration setup (Factions, WerChat, PlaceholderAPI, MysticNameTags, VaultUnlocked)
Permissions & Documentation
- Registered missing
hytale.mods.outdated.notifypermission node matching Hytale'sHytalePermissionsclass - Startup warning when vanilla OP/Default groups contain custom permissions that will be silently lost on restart
- Added
UPDATES_ALL,UPDATES_TOGGLE,UPDATES_NOTIFYpermission constants
Developer Experience
- JitPack publishing — depend on HyperPerms via
com.github.HyperSystemsDev:HyperPerms:<version> - CONTRIBUTING.md — contributor guide with build setup, code style, and branch strategy
- Standalone build support for JitPack/CI environments
Fixed
Critical: Permissions Not Syncing After Group Commands
User group commands (/hp user addgroup, removegroup, promote, demote, setprimarygroup, clone) only invalidated the Caffeine permission cache but missed ChatAPI/TabListAPI cache invalidation and Hytale permission sync. Negated permissions weren't being removed from Hytale's internal storage after command-based group changes. Now calls full cache invalidation and syncPermissionsToHytale().
Tab List Not Sorting by Group Weight
TabListListener never actually sorted entries by group weight — players were sent in arbitrary order and the client sorted alphabetically. Now sorts the ServerPlayerListPlayer[] array by group weight (descending) before sending packets.
Web Editor Resetting Prefix/Suffix Priority to 0
SessionData.GroupDto was missing prefixPriority and suffixPriority fields, so saving from the web editor silently reset priorities to 0.
Prefix Priority Using Stale Data
PrefixSuffixResolver loaded groups from raw storage instead of the GroupManager cache, meaning prefix priority changes via commands could be ignored until the async storage save completed. Now uses GroupManager.loadGroup() for all group lookups.
Primary Group Excluded from Prefix Priority
PrefixSuffixResolver only used user.getInheritedGroups(), not the user's primary group field. If the primary group wasn't also an inherited group node, it wouldn't participate in prefix priority comparison. Now includes the primary group consistently with PermissionResolver.
Other Fixes
- Web editor HTTP/2 connection failures — Forced HTTP/1.1 to prevent "header parser received no bytes" errors when ALPN negotiation fails
- Noisy gamemode group warnings — Hytale calls
addUserToGroupwith virtual gamemode groups on every login; downgraded from warning to debug level - MariaDB resource leak — Fixed unclosed connection in backup/restore, missing backups directory initialization, and redundant
setAutoCommitcall
Changed
- Build system overhaul — Hytale Server API now resolved automatically from
maven.hytale.cominstead of local JAR files. VaultUnlocked upgraded to 2.19.0 via Maven - Hytale permissions alignment — Aligned with
hytale-permissions-docsv1.1.0: documented multi-provider aggregation, nondeterministic iteration avoidance, wildcard restrictions, andpermissions.jsoninitialization semantics
Refactored
- Command system — Decomposed monolithic
HyperPermsCommand(3,000 lines) into 48 focused command classes undercom.hyperperms.command.*organized by domain (user/,group/,debug/,util/). Root command is now 90 lines - ConfigManager — New
com.hyperperms.configpackage with typed config files (CoreConfig,CacheConfig,ChatConfig,DebugConfig,IntegrationConfig,WebEditorConfig) and validation - PermissionHolderBase — Shared node storage and
PermissionHolderAPI extracted fromGroupandUser— removes ~200 lines of duplication - AbstractStorageProvider — Shared executor lifecycle, health tracking, and
runAsync()extracted from JSON and SQLite providers - AbstractSqlLuckPermsReader — Shared SQL migration logic extracted from H2 and SQL readers — removes ~300 lines of duplication
- SimpleContextCalculator — Generic base class for 5 context calculators with
computeValue()template method - CommandUtil — Common message colors,
join()helper, and confirmation tracking centralized - ReflectionUtil — Centralized reflection helpers for integration classes
Upgrade Notes
- MariaDB setup: Set
storage.typeto"mariadb"or"mysql"inconfig.jsonand configure themysqlblock with your connection details. Schema is created automatically on first run. - Config migration: The
useSSLoption is automatically added to existing configs on upgrade. - No breaking changes: All existing JSON and SQLite storage continues to work without modification.
Full Changelog: 2.8.5...2.8.6
HyperPerms v2.8.5
[2.8.5] - 2026-02-17
Server Version: 2026.02.17-255364b8e
Fixed
- Server compatibility: Compile against latest Hytale server JAR to resolve
NoSuchMethodErroronPacketHandler.write()(TabListListener crash) - User load race condition:
UserManagerImpl.loadUser()now uses first-writer-wins to prevent concurrent loads from replacing a user whose username was already set byonPlayerConnect - Server version warning: Manifest now specifies target server version (prevents PluginManager "does not specify a target server version" warning)
Added
- Offline player resolution:
resolveUser()now falls back to storage lookup and PlayerDB API when in-memory search fails, enabling commands like/hp user <name> infoto work for offline players - PlayerDB integration: New
PlayerDBServiceutility for looking up any Hytale player by username via the playerdb.co API (5-minute TTL cache) - Online player safety net: New
findOnlineUuidByName()onPlayerContextProviderresolves players who are connected but whose async user load hasn't completed yet
Changed
- PlayerResolver extraction: Moved inline
resolveUser()logic fromHyperPermsCommandto dedicatedPlayerResolverutility with 5-step resolution chain (UUID parse → loaded users → online players → storage → PlayerDB) - Improved logging: Player connect/disconnect, user loading, and permission sync now use info level for better server diagnostics
- Target-aware build: Compile against release or prerelease server JAR via
-PhytaleTargetGradle flag
HyperPerms v2.8.4
Changed
- HyperFactions permission registry overhaul: Reorganized all HyperFactions permissions into a proper hierarchical structure with category wildcards (
hyperfactions.faction.*,hyperfactions.member.*,hyperfactions.territory.*, etc.) and better descriptions - Runtime discovery namespace filtering: Only keeps permissions whose namespace matches the plugin's JAR filename, manifest Name, or manifest Group — eliminates false positives from bundled/relocated dependencies
Fixed
- Web editor showing
com.*command path permissions: Hytale command path format permissions (e.g.,com.hyperfactions.hyperfactions.command.faction) are now filtered from the web UI plugin permission scanner (still used internally for wildcard resolution) - Runtime discovery no longer skips HyperSystems plugins: Removed hardcoded exclusion of
hyperhomes,hyperwarps,hyperfactionsfrom discovery — these plugins register their own permissions via the built-in registry and discovery should not interfere
Full Changelog: https://github.com/HyperSystemsDev/HyperPerms/blob/main/CHANGELOG.md
HyperPerms v2.8.3
Added
- MysticNameTags Integration - First-class soft dependency with reflection-based detection
- Event-driven cache invalidation on permission/group changes via HyperPerms EventBus
- Calls
TagManager.clearCanUseCache()andMysticNameTagsAPI.refreshNameplate()on changes so tags update without relog - Group-level permission changes invalidate all online players who may inherit from the affected group
- LuckPerms conflict detection with warning log
- Local
CachedTagDatawith 5-second TTL for API method results - Public API:
getActiveTagDisplay,getActiveTagId,getAvailableTagCount,hasTagPermission,refreshPlayerTags, etc. - Configurable via
config.jsonmysticnametagssection (enabled, refresh toggles, tag permission prefix) - Auto-migration adds config section to existing configs
- PlaceholderAPI Expansion - 5 new MysticNameTags placeholders
%hyperperms_tag%- Active tag ID%hyperperms_tag_display%- Active tag display text (colored)%hyperperms_tag_count%- Number of available tags%hyperperms_tags%- All available tag IDs (comma-separated)%hyperperms_has_tag_<name>%- Check tag permission (true/false)
- Temporary Permissions Developer API - Full public API for managing timed permissions programmatically
- New
TemporaryPermissionInforecord DTO withgetRemaining()andisExpired()methods PermissionHolderinterface: 12 new methods for setting, querying, and modifying temporary permissionssetPermission(perm, value, Duration/Instant)- Set permissions with expiryisTemporaryPermission(perm)/getPermissionExpiry(perm)/getPermissionRemaining(perm)- Query expiry statesetPermissionExpiry(perm, Instant)/adjustPermissionExpiry(perm, Duration)- Modify or remove expirygetTemporaryPermissions()- Enumerate all active temporary permissionsaddGroup(name, Duration/Instant)- Temporary group membership via interface
HyperPermsAPItop-level convenience methods:setTemporaryPermission(),getTemporaryPermissions(),isTemporaryPermission(),getPermissionRemaining()- All methods are backward-compatible default methods — no breaking changes
- New
- Permission Enumeration API -
getResolvedPermissions(UUID)onHyperPermsAPI- Returns all granted permission strings for a user including inherited permissions from group hierarchy
- Enables plugins to scan permissions by prefix without depending on the native provider chain
Fixed
- EssentialsPlus Compatibility - Fixed provider ordering causing parameterized permission queries to fail silently
- Hytale's native provider was first in the chain and couldn't resolve HyperPerms virtual groups
ensureFirstProvider()now reorders the provider chain so HyperPerms is always first- Fixes
essentialsplus.sethome.limit.[n],essentialsplus.home.reduce.cooldown.*, and similar queries
- Compilation Warnings - Resolved all 63 compiler warnings for a completely clean build
- Fixed 56
dangling-doc-commentswarnings in migration record types - Fixed 4
unchecked/rawtypeswarnings inAsyncPermissionCheckBuilder - Fixed 3
text-blockstrailing whitespace warnings inSQLiteAnalyticsStorage
- Fixed 56
HyperPerms v2.8.2
Added
- Temporary Permissions - Duration/expiry support for permissions and group membership
/hp user setperm <player> <perm> [value] [duration]- Set permissions with optional expiry (e.g.1d,2h30m,1w)/hp group setperm <group> <perm> [value] [duration]- Same for groups/hp user setexpiry <player> <perm> <duration|permanent>- Modify expiry on existing permissions/hp group setexpiry <group> <perm> <duration|permanent>- Same for groups/hp group parent add <group> <parent> [duration]- Temporary group inheritance/hp user addgroup <player> <group> [duration]- Temporary group membership- All duration arguments are optional, defaulting to permanent (backwards compatible)
/hp user infoand/hp group infonow display expiry in amber for temporary permissions- Uses existing
TimeUtilduration parsing (30s,5m,2h,1d,1w, combos,permanent)
Fixed
- Web Editor Expiry Pipeline - Fixed web editor silently dropping expiry data when applying changes
Change.javanow carries expiry field through the DTO pipelineWebEditorServicereads expiry from JSON in all parsing pathsChangeApplier.buildNode()applies expiry when building permission nodes- Web editor UI already supported expiry — only the Java-side pipeline was broken
HyperPerms v2.8.1
Fixed
- Permission Negation Bug - Fixed critical bug where negated permissions set via web editor were granted instead of denied
- Web editor sent conflicting data (
-permissionprefix withvalue: false), causing double negation in the permission resolver - Backend
ChangeAppliernow normalizes-prefix permissions to always usevalue: true - Frontend
toBackendNodenow sends correct value for negated permissions
- Web editor sent conflicting data (
- Permission Display - Fixed
/hp group infoand/hp user infoshowing raw internal format for negated permissions- Was showing
+ -hytale.command.spawnor- -hytale.command.spawn - Now correctly shows
- hytale.command.spawnwith red color - Also fixed in
/hp user treeinheritance display
- Was showing
- Command Feedback - Fixed setperm commands showing "Granted" for denied permissions
/hp group setperm group perm falsenow correctly says "Denied perm on group"/hp group setperm group -permnow correctly says "Denied perm on group"
- Permission List Sorting - Group and user info commands now display permissions in alphabetical order
Changed
- Build System - Fixed Shadow JAR clobbering in multi-project Gradle builds