v0.10.0: Per-world settings, config restructure, data migration, leaderboard, activity log, placeholders, bug fixes#74
Merged
Merged
Conversation
Clean up orphaned temp/backup files before creating backup ZIP. Skip .tmp and .bak files in addDirectoryToZip visitor. Delete incomplete ZIP on backup failure.
Zone lookup exception in catch block now returns early (fail-safe) instead of falling through to apply power loss. Log at WARN level.
Add adminBypassEnabled field to PlayerData with JSON serialization. toggleAdminBypass now saves to player data file. On connect, restore bypass if saved and player still has admin perm. Clear stale bypass flag if player lost admin permission.
Add allowExplosionsInClaims config option (default false). When enabled, explosions are permitted in faction-claimed chunks (not zones). Full per-relation support deferred to HyperProtect-Mixin update.
Add color_legacy, name_colored, tag_colored, name_colored_legacy, and tag_colored_legacy placeholders to both expansions. Implement PAPI Relational interface for rel_factions_relation and rel_factions_relation_color. Add hexToNearestLegacyCode utility with exact match and Euclidean RGB distance fallback.
Add hardcoreMode config option. When enabled, faction power uses a shared pool instead of individual player power. Death subtracts from the faction pool (no floor), kills add to it, and regen applies to the pool directly. Persisted in data/hardcore_power.json.
Add /f leaderboard (alias /f top) command and GUI page with ranked faction listing. Sort modes: Power, Territory, Balance, Members. Includes nav bar integration for both faction and new player views.
Replace all double-precision floating point with BigDecimal across 23 economy files for currency precision. Uses string constructor, scale 2, HALF_UP rounding. Backward-compatible JSON deserialization handles both old double and new string formats.
Add treasury_balance, treasury_balance_raw, treasury_autopay, and treasury_limit placeholders to both HyperFactionsExpansion (PAPI) and WiFlowExpansion. Uses BigDecimal formatting from EconomyManager.
Wire LogsViewerPage into faction nav bar with /f logs command. Add AdminActivityLogPage for server-wide log aggregation with type, time, and player filters.
Add WorldsConfig module (config/worlds.json) for configuring per-world behavior: claiming, power loss, faction/ally friendly fire. Supports wildcard patterns (% matches any sequence) with priority resolution. Integrates with ClaimManager (claiming), PlayerDeathSystem (power loss), and ProtectionChecker (friendly fire). Admin commands: /f admin world list|info|set|reset. Legacy whitelist/blacklist in CoreConfig still works as fallback when worlds module is disabled.
Add comprehensive changelog entry covering all 10 issues, BigDecimal refactor, and per-world settings. Update README feature tables with new capabilities: per-world settings, hardcore mode, leaderboard, expanded placeholders.
Fix #Title.Text selector crash on logs page — #Title is a $C.@container slot (Group), not a Label. Added #LogsTitle ID to the $C.@title template and target that instead. Enable the View All button in the dashboard activity feed to navigate to the logs viewer page.
…cersCanEdit accessors Remove 12 unused accessor methods (memberBreak, memberPlace, memberInteract, officerBreak, officerPlace, officerInteract, allyBreak, allyPlace, allyInteract, outsiderBreak, outsiderPlace, outsiderInteract) and 10 unused builder methods (withOutsiderBreak/Place/Interact, withAllyBreak/Place/Interact, withMemberBreak/Place/Interact, withPvpEnabled, withOfficersCanEdit) from FactionPermissions — all verified zero callers. Fix pvpEnabled() and officersCanEdit() to use get() instead of getRaw() for consistent fail-closed parent-child flag resolution behavior.
Add treasuryDeposit, treasuryWithdraw, and treasuryTransfer flags to the defaults and locks sections, nested under a "treasury" key. Enables server admins to set default treasury permissions and lock them for all factions. Existing getEffectiveFactionPermissions() already iterates all locks, so treasury flags are automatically enforced without additional wiring.
Create FactionsConfig (faction gameplay: faction, power, claims, combat, spawn protection, relations, invites, stuck) and ServerConfig (server behavior: teleport, auto-save, messages, GUI, permissions, updates). Add 9 new claim protection overrides to FactionsConfig: outsiderPickup, outsiderDrop, 3-way explosions (factionless/enemy/neutral), fireSpread, 3-way outsider entity damage (factionless/enemy/neutral). Move territoryNotificationsEnabled from CoreConfig to AnnouncementConfig. Mark CoreConfig as @deprecated legacy fallback reader. Re-route all ConfigManager convenience methods to new backing configs. Legacy config.json is still loaded as fallback if present.
Extract faction/server settings from monolithic config.json into config/factions.json + config/server.json. Transform allowExplosionsInClaims into 3 granular flags (factionless/enemy/neutral). Add 6 new claim protection settings with behavior-preserving defaults. Move territoryNotifications into config/announcements.json. Delete config.json after extraction — configVersion now lives in config/server.json. All data extracted before deletion, auto-backup created by MigrationRunner.
shouldBlockExplosion: replace single allowExplosionsInClaims with 3-way check (factionless/enemy/neutral). Explosion hooks lack player UUID, so all 3 must be true to allow — documented limitation. shouldBlockFireSpread: replace hardcoded block with configurable fireSpreadAllowed check. canPickupItem: replace hardcoded outsider deny with outsiderPickupAllowed config check. canDamagePlayerChunk: add outsider entity damage 3-way check by relationship (factionless/enemy/neutral) to claim owner. ItemDropProtectionSystem: add claim-based outsider drop check using outsiderDropAllowed config (allies exempt).
…ction settings Rewrite protection docs as 4 focused documents (claims, zones, global, systems) with protection.md as navigation hub. Update all config references from CoreConfig/config.json to FactionsConfig/ServerConfig. Document 9 new claim protection settings, 3-way explosion/damage configs, V5→V6 migration, and explosion source attribution limitation. Fix treasury GUI note, update storage file structure, update README quick-start.
…yperProtect lifecycle CoreConfig is null after V5→V6 migration deletes config.json, causing NPE in initHyperProtectMixinLifecycle() and AdminUpdateHandler. All HyperProtect config methods already exist on ServerConfig.
Add per-UUID locking to JsonPlayerStorage to serialize concurrent writes to the same player file. The previous async load-increment-save pattern allowed two rapid kills to both read stale data, losing an increment. savePlayerPower (called by regen timers) could also overwrite kill/death data via its own unsynchronized load-modify-save cycle. - Add updatePlayerData(UUID, Consumer) to PlayerStorage for atomic read-modify-write with per-UUID ReentrantLock - Extract savePlayerDataSync() to share between savePlayerData, savePlayerPower, and updatePlayerData - Lock savePlayerData and savePlayerPower to prevent cross-method races - Extract trackKillDeath() helper in PlayerDeathSystem, replacing 5 identical copy-pasted load-increment-save blocks
Add roles section to config/factions.json allowing server owners to customize role names (e.g. Boss/Underboss/Soldier) and short forms (e.g. BO/UB/SO). All GUIs, commands, and log messages now use configured display names instead of hardcoded role names. - Add getRoleDisplayName/getRoleShortName to ConfigManager - New placeholders: factions_role_display, factions_role_short - Validate display names non-empty, short names ≤4 chars - Update /who, /members, /promote, /demote, all GUI pages - Update PAPI and WiFlow placeholder expansions
Move all data files into data/ subdirectory for cleaner organization. DataV0ToV1Migration automatically moves factions/, players/, chat/, economy/, zones.json, invites.json, and join_requests.json on first startup. Creates ZIP backup before migrating for safe rollback. - data/.version marker tracks data layout version (1) - Fresh installs create data/ directly, no migration needed - If crash before marker write, migration re-runs on next startup - Register migration in MigrationRegistry - Update HyperFactions startup to resolve data dir from marker
Upgrade economy, invites, and join request storage to use StorageUtils.writeAtomic() for crash-safe writes with SHA-256 verification. Expand backup archives to include chat history, economy, invites, and join requests alongside existing data. - JsonEconomyStorage, InviteManager, JoinRequestManager now atomic - .bak files cleaned up after successful writes - Orphaned .tmp/.bak cleaned on startup - BackupManager and MigrationRunner include all data/ contents
…placeholders - config.md: add roles section with mafia theme example - storage.md: expand safe-save mechanism, data directory migration - placeholders.md: update tables (35→37), add role_display/role_short - data-import.md: document DataV0ToV1Migration detection logic - readme.md: update doc index links - README.md: mention customizable role display names
Add 2 new per-role faction permission flags (CrateUse, NpcTame) across all 4 relationship levels (8 flags total, 45→53). Add 3 new zone flags (crate_pickup, crate_place, npc_tame) in Entity Interaction category (34→37 flags). UseHook routes interaction class names to specific InteractionType for independent protection checks. NPC handler uses NPC_TAME type instead of generic INTERACT.
All 7 ECS protection systems now cancel events when the world name cannot be determined or an exception occurs (previously allowed the action silently). Denied block placements now teleport the player to reset client-predicted ghost blocks that enabled pillar climbing. BlockBreak/BlockPlace evaluate canInteract() once instead of twice. Debug logging standardized with [ECS:*] and [OG:*] prefixes. NpcInteractionProtectionHandler registered in EventRegistration.
Instance World Protection: - Default instance-% wildcard rule blocks claiming in temp instance worlds - /f sethome blocked in worlds where claiming is disallowed - Automatic cleanup of stale claims/homes on startup and config reload Zone Notification Settings: - Per-zone notification toggle (notify on entry true/false) - Customizable upper/lower title text overrides - Admin commands: /f admin zone notify, /f admin zone title - Zone info displays notification settings - TerritoryNotifier uses Zone-aware factories for notification data
Rebalances the 36-flag zone settings page from a lopsided 2-column layout (16 left / 20 right) to 3 balanced columns grouped thematically: Left (Combat, Damage, Death), Middle (Building, Interaction, Entity Interaction), Right (Transport, Items, Spawning). Container widened from 720 to 880px and shortened from 840 to 680px.
Consolidate zone name editing, type changing, and notification settings into a single properties page. Zone list replaces separate Rename/Type buttons with a unified Settings button. Type change modal and flags page now navigate back to properties when opened from that context.
ATOMIC_MOVE fails on Windows when antivirus or file indexer holds a brief handle on the target file. StorageUtils.writeAtomic() now retries 3 times with increasing delays (50/100/150ms) before falling back to a non-atomic move, which is still safe since the .bak backup already exists at that point. All 8 storage callers benefit automatically.
…ard, admin info redesign Add per-player and global K/D reset, new "Actions" admin page with two-step confirmation, faction K/D as default leaderboard sort (cached refresh), and admin commands `/f admin info` and `/f admin who`. Redesign admin player info as two-column layout mirroring /f who data: first joined, last online, faction card with View Faction button, compact membership history, power/combat controls on right. Redesign admin faction info with two-column layout and disband button.
Add Admin Version page to admin nav bar showing mod versions and integration statuses (permissions, protection, placeholders, economy). /f admin version works from both GUI (players) and console. VaultEconomyProvider.getEconomyName() detects registered economy plugin name via reflection (e.g. "Ecotale") for display in GUI and chat. Fix HyperProtect version always showing "1.0.0" — HyperProtectIntegration hardcoded the version when lazily creating the bridge. Now detects actual version from JAR filename in earlyplugins/.
Merge [Unreleased] and old [0.10.0] sections into a single [Unreleased] entry. Organize Added section by feature area (Gameplay, Protection, GUI & Admin, Config & Storage, Placeholders). Group Changed entries by theme. Version header will be added at release time.
Bump version headers from 0.9.0 to 0.10.0 across all 18 docs files. Add new commands (leaderboard, logs, admin info/ who/version/world), config settings (hardcoreMode, K/D cache, worlds, claim overrides), placeholders (35→49), zone flags (37→40), per-UUID locking, and role display names. Update README counts and JitPack version reference.
Replace duplicated 3-line input parsing pattern across 35 command files with a single call to CommandUtil.parseRawArgs(). Removes ~70 lines of boilerplate while preserving identical behavior. Skipped ChatSubCommand and MoneySubCommand routing logic which genuinely needs the parts array for command dispatch.
Create centralized UIPaths.java with 110 named constants replacing 150 hardcoded "HyperFactions/..." string literals across 70 GUI files. Eliminates typo risk and makes path references discoverable.
Add NavEntry interface implemented by all three page registry Entry records, and NavBarUtil with shared buildButtons() and hasPermission() methods. Reduces duplicated loop logic across NavBarHelper, NewPlayerNavBarHelper, and AdminNavBarHelper.
Extract 81 openXxx() methods from GuiManager (2834 lines) into three dedicated opener classes: FactionPageOpener (35 methods), AdminPageOpener (38 methods), NewPlayerPageOpener (8 methods). GuiManager retains page registration, closePage, getters/setters, and thin delegation methods that preserve the existing public API.
Add forRemoval=true to all bare @deprecated annotations with appropriate since versions. Remove stale TODO block in PowerSubCommand (text-only output is the permanent design).
Add FactionPageOpener, AdminPageOpener, NewPlayerPageOpener, UIPaths, NavBarUtil, NavEntry to architecture.md and gui.md. Update GuiManager description to reflect delegation pattern. Add WP3-WP7 refactoring entries to CHANGELOG.
Convert all 399 source files to 2-space indentation, add Checkstyle 10.26.1 with customized Google Java Style config (warnings-only mode). Changes applied: - 4-space to 2-space indentation - Google Java Style import ordering (static first, alphabetized) - Javadoc stubs on all public methods and types - Consistent brace placement (NeedBraces, LeftCurlyEol, RightCurly) - Operator wrapping (trailing operators moved to next line) - Blank line separators between declarations - Default cases added to switch statements Checkstyle config: 120-char line limit, star imports allowed, relaxed Javadoc (public scope only), common abbreviations permitted.
Restructure to full-width stats row (power, combat, KDR, faction card), move UUID into header subtitle, and split body into history + controls columns. Add Origin enum to track navigation source so Back returns to the correct page (players list vs faction members).
Consolidate duplicated color methods (getRoleColor, getReasonColor, getLogTypeColor) from 8 GUI pages into a shared GuiColors utility with semantic resolution methods. Fix 2 color inconsistencies in AdminPlayerInfoPage (officer #87CEEB→#00AAFF, offline #FF5555→#888888). Update CurseForge description, docs, and README with accurate v0.10.0 counts (44 commands, 64 pages, 49 placeholders, 11 config files) and new feature sections.
…rsion detection ConfigFile.load() now recursively compares serialized keys against disk JSON and auto-saves when new keys are detected, fixing modules like FactionPermissionsConfig that bypass base helpers. Migrate old ZenithDevHQ update URL to HyperSystemsDev on load (custom URLs preserved). Update defaults in ServerConfig and CoreConfig. Fix HyperProtect-Mixin update checker showing v0.0.0 by detecting version from JAR filename before branching, and setting the system property early for AdminVersionPage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
HyperFactions v0.10.0 — 10 GitHub issues resolved plus significant unrequested improvements across config management, data storage, admin tooling, protection, and economy precision.
New Features
Gameplay
config/worlds.jsonwith per-world claiming, powerLoss, and friendlyFire. Wildcard patterns (%), priority resolution, and admin commandsCrateUse,NpcTame, 8 flags total) and 3 new zone flags (crate_pickup,crate_place,npc_tame). Requires HyperProtect-Mixin CaptureCrateGate + SimpleInstantInteractionGate NPC entriesinstance-%wildcard rule blocks claiming in temporary instance worlds;/f sethomeblocked in disallowed worlds; stale claim/home cleanup on startup and reloadrolessection inconfig/factions.jsonfor custom role names and abbreviations. All GUIs, commands, and messages use configured names. New placeholders:factions_role_display,factions_role_shortGUI & Information
/f leaderboardwith POWER/TERRITORY/BALANCE/MEMBERS/K:D sort modes, pagination, and nav bar/f logs, admin global log with type/player/time filtersPersistence & Placeholders
treasury_balance,treasury_balance_raw,treasury_autopay,treasury_limitname_colored,tag_colored, legacy variants, relational PAPI placeholdersVaultEconomyProvider.getEconomyName()detects registered economy plugin name via reflection (e.g. "Active (Ecotale)")Admin Improvements
K/D Management & Info Redesign
/f admin info [faction]and/f admin who [player]open admin GUIs directly from chat/f admin versionshows mod versions, server version, Java version, and all integration statuses with color-coded status. Console prints text outputBug Fixes
.tmp/.bakorphans during backup, clean up before zipping, delete incomplete ZIPs on failureJsonPlayerStorageto serialize concurrent writes; atomicupdatePlayerDatamethod prevents power regen from overwriting kill/death incrementsATOMIC_MOVEfails when antivirus/indexer holds a file handle;StorageUtils.writeAtomic()now retries with backoff (3 attempts) then falls back to non-atomic moveHyperProtectIntegrationnow detects actual version from JAR filename inearlyplugins/instead of hardcoding "1.0.0"Infrastructure
Config Restructure (V5 → V6 Migration)
Split monolithic
config.jsoninto two module configs with automatic migration:config/factions.json— Faction gameplay: power, claims, combat, relations, invites, stuck, rolesconfig/server.json— Server behavior: teleport, autoSave, messages, GUI, permissions, updates9 new claim protection overrides in
config/factions.json:outsiderPickupAllowed,outsiderDropAllowedfactionlessExplosionsAllowed,enemyExplosionsAllowed,neutralExplosionsAllowed(replacesallowExplosionsInClaims)fireSpreadAllowed(was hardcoded block)factionlessDamageAllowed,enemyDamageAllowed,neutralDamageAllowedTreasury permission flags (
treasuryDeposit,treasuryWithdraw,treasuryTransfer) added tofaction-permissions.json.Data Directory Restructure (v0 → v1 Migration)
All data files moved into
data/subdirectory with automatic migration:data/.versionmarker written last — crash before marker = re-run on next startupdata/directlySafe-Save Hardening
StorageUtils.writeAtomic()(economy, invites, join requests upgraded from direct writes).bakfiles cleaned up after successful atomic writes — no more indefinite accumulationJsonPlayerStorage— all writes to the same player file serialized viaReentrantLockwriteAtomic()retriesATOMIC_MOVE3× with 50/100/150ms backoff, then falls back to non-atomic moveRefactoring
doubletoBigDecimal(~21 files) for currency precisionFactionPermissionsCoreConfigdeprecated — Replaced byFactionsConfigandServerConfig#Title.Textselector targeting Group instead of Label; "View All" button enabled on dashboardtrackKillDeath()helperCloses
Fixes #59, fixes #61, fixes #62, fixes #65, fixes #66, fixes #67, fixes #68, fixes #69, fixes #71, fixes #72
Test Plan
Core Features
./gradlew :HyperFactions:shadowJarData & Config Migration
data/,.version= 1, backup createdconfig.jsonsplits correctly via V5→V6.bakfiles don't accumulate after savesGUI & Leaderboard
/f leaderboard,/f top, all sort modes and pagination/f logsnav bar entry,/f admin logwith filters/f admin who <player>with membership history and View Faction button/f admin info <faction>and/f admin who <player>open correct GUIsIssue Verification
.tmpin data dir →/f admin backupsucceedsPOWER_LOSS=false→ no power lossallowExplosionsInClaims— explosions in claimed territoryProtection
/f permfaction-permissions.jsonauto-generates with new flagsRoles & Config
config/factions.json,/f admin reload, verify GUIs/commands/placeholdersRace Conditions
/f who