1. BanManager Improvements
Change | Description |
---|---|
Fail-safe banning | Checks player validity (online state, name) before banning. |
Customizable ban reasons | Prepares ban messages with clear reasons and placeholders. |
Safer unbanning | Prevents unban attempts for null/invalid players. |
Consolidated log messages | Unified logging with better error context. |
Future-proofing | Added potential for temporary bans (Date parameter left open). |
2. HeartManager Improvements
Change | Description |
---|---|
Centralized validation | Sanitizes heart values (no negatives, max cap) via sanitize() . |
Safe scheduling | Delays health update with Bukkit.runTask() only when necessary. |
Single DB access per call | Avoids redundant DB calls by reusing PlayerData . |
Flexible heart updates | addHearts() and removeHearts() now ensure health sync post-save. |
Improved max health logic | Always guarantees at least 1 heart (2.0 health). |
Better null handling | All methods safely return/exit when player or UUID is null. |
3. RecipeManager Improvements
Change | Description |
---|---|
Recipe validation | Verifies shape (3x3 max), logs invalid formats. |
Dynamic tiers | Supports tier setting for Heart recipe. |
Configurable outputs | Item name and lore now pulled from config. |
Safe removal | Wraps Bukkit.removeRecipe() with checks. |
Centralized registration | registerAllRecipes() introduced. |
Detailed error logs | Detects missing/invalid materials per symbol. |
Extensible design | Ready for additional custom recipes. |
Added new placeholders!
Placeholder | Description |
---|---|
%lifesteal_playername% |
Returns the player’s name, or offline name if player is not online |
%lifesteal_uuid% |
Returns the UUID of the player |
%lifesteal_health% |
Shows the current health (HP) of the player (as an integer) |
%lifesteal_maxhealth% |
Shows the maximum health (HP) of the player (as an integer) |
%lifesteal_hearts_left% |
Displays how many hearts the player can still gain before reaching max |
%lifesteal_online_count% |
Shows the number of currently online players |
%lifesteal_database_connected% |
Displays "true" or "false" depending on whether the database is connected |
ADDED PLACEHOLDERS (GOING ALONGSIDE MINOR IMPORVEMENTS)
Dimension | Description | Status |
---|---|---|
1. Resilience Architecture | Commands and placeholder systems are built to continue functioning even under partial system failure (e.g., config loss, null plugin fields, SQL failure, PAPI missing). This is resilience by design, not exception handling afterthought. | ✅ |
2. Graceful Degradation | Instead of crashing or halting features when a dependency is missing (like PlaceholderAPI or MySQL), your system downgrades functionality while maintaining UX continuity ("Offline" , "ERR" , fallback materials, default config values). |
✅ |
3. Dynamic Reflection Proxy for Optional API | PlaceholderRegistrar uses dynamic reflection and proxying to register placeholders without compile-time binding to PAPI, supporting modular deployment and late binding. This is a decoupling architecture pattern. |
✅ |
4. Semantic Placeholder Decoding Layer | The use of switch(identifier.toLowerCase()) with contextual logic (like online checks, config fallbacks) builds a semantic parser for identifiers. This design allows for scalable growth (e.g., %lifesteal_kills_today% , %lifesteal_revive_tokens% ). |
✅ |
5. Config-Driven Control Layer | All messages, materials, database types, and display elements are externalized to config, making the plugin highly customizable without code changes — a hallmark of production-tier design. | ✅ |
6. Contextual Tab Completion DSL | AdminTabCompleter is essentially a domain-specific suggestion language for command trees. It parses arg index, subcommand semantics, and sender context to give tailored completions. |
✅ |
7. Game Rule-Aware Behavior | Commands like /withdraw respect game logic constraints (e.g., minimum 1 heart), making the plugin exploit-resistant and gameplay-consistent. This isn't just a check — it enforces the design of the gamemode. |
✅ |
8. Structural Plugin Isolation | Every subsystem (BanManager , HeartManager , ConfigManager , etc.) is accessed through clear, isolated interfaces, with plugin-safe guards. There is no deep structural coupling, supporting unit testability and future refactors. |
✅ |
9. Developer-Aware Feedback System | Logger messages are structured, scoped ([PlaceholderAPI] ), and precise — aiding devs with immediate traceability on user-side issues (like SQL faults or PAPI issues). |
✅ |
10. Deferred Execution Awareness | SQL-heavy operations are guarded and designed to be lightweight in the main thread, preparing for future asynchronous conversion, especially for placeholders. | ⚠️ Ready for async, but not async yet |
11. Plugin Reload Safety | All commands and placeholders support plugin.getConfigManager().reload() and react immediately to config changes, enabling hot-reload capability and zero-downtime admin operations. |
✅ |
12. Internal Type Normalization | The use of .toLowerCase(Locale.ROOT) and guards like safeString(...) ensure locale-agnostic and NPE-safe string handling, which is internationalization best practice. |
✅ |
13. Minimal Surface Area Exposure | The command classes expose only necessary logic; onCommand and utilities are not overexposed via public static or deep inheritance. This limits accidental misuse and encourages encapsulation. |
✅ |
14. Performance-Aware Inventory Handling | Heart item creation (ItemBuilder ) happens only if checks pass, and only 1 item is created and added, minimizing GC and lag. |
✅ |
15. Command Feedback Templating | Every message supports {player} , {tier} , {amount} tokens — making it dynamic, parseable, and reusable, not hardcoded. This bridges with chat plugins and structured JSON systems. |
✅ |
16. Compatibility-Aware Versioning | getVersion() in placeholders is dynamically retrieved from plugin metadata — no static literals — maintaining compatibility and correct display in admin panels. |
✅ |
CURRENTLY SUPPORTED PLACEHOLDERS!
Placeholder | Purpose |
---|---|
%lifesteal_hearts% |
Player's current hearts (if online) |
%lifesteal_maxhearts% |
Max hearts from config |
%lifesteal_is_banned% |
Whether the player is banned |
%lifesteal_database_type% |
Database type ("mysql"/"sqlite") |
%lifesteal_lang% |
Active language config file |
%lifesteal_startinghearts% |
Configured starting hearts |
%lifesteal_prefix% |
Plugin prefix string |
%lifesteal_online% |
Is player currently online |
%lifesteal_ban_reason% |
(Hardcoded for now) "Out of hearts" if banned |
SQL ENHANCEMENTS!!
Category | Improvement | Reason | Result |
---|---|---|---|
Thread Safety & Singleton | instance field is marked as volatile for thread safety. |
Ensures safe access to the plugin’s singleton instance across multiple threads. | Prevents concurrent thread issues with inconsistent or conflicting access to the plugin instance. |
Modularization & Readability | Refactored onEnable() and onDisable() into smaller methods (init() , registerListeners() , etc.) |
Makes the code more modular, readable, and maintainable. | Easier to manage and extend the plugin with minimal impact on the core plugin lifecycle. |
Error Handling & Logging | Enhanced error logging with detailed logs in critical areas. | Provides clearer debugging information when issues arise. | Better visibility in logs for identifying and troubleshooting issues. |
Command Registration | Commands now have permissions and tab completions (setTabCompleter() , setPermission() ). |
Enhances command functionality and security. | Commands are more user-friendly (with tab completions) and secure (with permissions). |
Null Checks & Validation | Added null checks for commands, listeners, and database connections. | Prevents NullPointerException and ensures proper initialization before use. |
More robust and reliable behavior, with appropriate fallbacks or warnings. |
Separation of Concerns | Separated command and listener registration into individual methods. | Improves maintainability by breaking down responsibilities into smaller, manageable chunks. | Clearer organization and modularity in the code. |
Resource Management | Proper resource cleanup during plugin shutdown (safelyShutdown() method). |
Prevents memory leaks and ensures that resources are freed correctly when the plugin is disabled. | Ensures the plugin shuts down cleanly and frees resources (e.g., database connections). |
Logging Improvements | Console messages now use Minecraft’s color formatting (& to § ). |
Improves readability and visibility of logs for administrators. | More visually appealing and easier-to-read logs for server admins. |
SQL Enhancements | Enhanced database interactions with prepared statements and better error handling. | Prevents SQL injection and improves the security and reliability of database operations. | More secure and stable SQL interactions. |
SQL Connection Management | Validates connection state before performing SQL operations. | Ensures the plugin doesn't attempt to execute queries on invalid or closed connections. | Prevents errors or unexpected behavior due to closed/stale database connections. |
SQL Query Improvements | Returns default fallback values if SQL queries fail or no data is found. | Ensures the plugin continues working smoothly even if database interactions encounter issues or missing data. | The plugin continues functioning even when database errors or missing data occur. |
SQL Resource Management | Properly closes database resources (PreparedStatement , ResultSet ) using try-with-resources. |
Ensures resources are properly released, preventing memory leaks and improving performance. | More efficient and cleaner database code. |
Plugin Disable Enhancements | Ensured safe shutdown of resources (database connections, recipes, etc.). | Prevents lingering resources, file locks, or incomplete cleanup during the plugin's shutdown. | A stable and reliable server experience with clean shutdown behavior. |
🧠 Architecture & Design
-
Centralized Utility APIs – MessageUtils, ColorUtils, ItemBuilder provide DRY, reusable patterns.
-
Singleton-safe plugin access – consistent use of getInstance() for global plugin reference.
-
Separation of concerns – clearly segmented managers (HeartManager, BanManager, etc.) avoid bloated main class.
-
Graceful failover & shutdown – plugin disables on fatal error; database and recipes properly closed.
-
Dynamic command delegation – uses executor-permission binding; fallback warnings for missing entries.
⚙️ Code Quality & Safety
-
Null safety added – guards against null messages, lists, strings, ItemMeta, etc.
-
Cloning of mutable objects – avoids returning internal ItemStack references directly.
-
Input validation – amount clamped (1–64), tier limited (1–5), keys checked.
-
Regex matching via Matcher.appendReplacement() – safe and efficient HEX color parsing.
-
Safe config fallback – missing lang keys gracefully return default with warning.
📈 Performance Improvements
-
Efficient string coloring – reused helper for batch lore coloring reduces overhead.
-
Deferred meta setting – avoids redundant operations on ItemMeta.
-
Command tab completer registered conditionally – avoids NPE if command is missing.
📜 Documentation & Readability
-
Full JavaDocs added – method-level docs explain parameters, return values, and side effects.
-
Consistent naming and formatting – fluent, descriptive method and variable names.
-
Simplified logging interface – log(String) method wraps colored console output.
🚨 Error Handling & Logging
-
Fallback logs for lang keys – warns when translation keys are missing.
-
Structured exception logging – prints full stack trace on startup failure.
-
Invalid hex codes skipped silently – prevents plugin crash from user config errors.
🧩 Extensibility Support
-
Lore overloads and builder extensibility – builder pattern allows for chaining, expansion (e.g., enchantments).
-
Formatted string retrieval in LangManager – supports runtime placeholders with String.format(...).