Legacy Lands Library
repository·main·Indexed 21 days ago
https://github.com/legacylands/legacy-lands-libraryA modular toolkit for Minecraft plugin development built on the Fairy Framework, providing high-performance utilities for Spigot, Paper, and Folia environments. It includes an annotation module for automatic processing via AnnotationProcessingService and an AOP module featuring a hybrid proxy pipeline (JDK Dynamic Proxies and ByteBuddy) with built-in aspects for retries, circuit breaking, rate limiting, and security.
What's inside legacy-lands-library
- The Configuration module is a wrapper around SimplixStorage. It provides serialization annotations and a factory pattern to accelerate development. The module handles thread safety internally, making it safe for use in multi-threaded environments.
Overview of the Task Scheduler module
mainThe Task Scheduler is a high-performance task execution platform designed to offload resource-intensive or IO-bound computations from a primary service server (such as a Bukkit/Java server) to specialized servers or languages. It follows distributed processing principles to prevent bottlenecks in centralized architectures.Overview of legacy-lands-library
mainlegacy-lands-libraryis a modular plugin utility library built on top of the Fairy Framework. It is designed to run as a plugin and encapsulates various existing libraries to simplify the development process for modern Minecraft plugins. It leverages Java 21 features and provides cross-platform support for Spigot, Paper, and Folia.Overview of Task Scheduler (Rust)
mainTask Scheduler is a high-performance task execution backend written in Rust. It provides a gRPC service that allows clients to submit tasks (potentially with dependencies) defined via Protocol Buffers. The system leverages Rust's asynchronous capabilities (tokio), concurrency features, and efficient data structures to ensure fast, robust, and scalable task execution. It supports both synchronous and asynchronous task functions, with parameters passed as ProtobufAnymessages and decoded into typed Rust values internally.Use the mongodb module for data storage
mainThe
mongodbmodule is a wrapper around Morphia designed specifically for Minecraft plugin development. It provides aMongoConfigimplementation to simplify setup.Note: This module is strictly tied to MongoDB. There is no support for other database types (like MySQL or PostgreSQL) because the design prioritizes MongoDB's schema-less nature, horizontal scalability (sharding), and document model which aligns with the dynamic and complex data structures found in Minecraft.
How AOP proxying works
mainThe AOP module uses a hybrid proxy pipeline that automatically selects the optimal strategy based on the target type:
- JDK Dynamic Proxies: Automatically used for interface types.
- ByteBuddy Class Proxies: Automatically used for concrete classes, which preserves field state through synchronized copy-on-invoke semantics.
Each plugin maintains its own aspect metadata via ClassLoader Isolation, preventing cross-plugin interference.
The proxy creation flow follows these steps:
AOPServicereceives a target object or class.AspectProxyFactorydetermines the proxy type (JDK or ByteBuddy).- Applicable interceptors are gathered based on method annotations.
- Interceptors are ordered by priority and wrapped into an execution chain.
- The proxy is returned for transparent method interception.
Explore the core modules of legacy-lands-library
mainThe library is composed of several specialized modules. Depending on your needs, you can integrate specific functionalities:
- foundation: Core testing infrastructure, utilities, and base abstractions.
- annotation: Annotation processing with flexible scanning and lifecycle management.
- aop: Aspect-Oriented Programming with ClassLoader isolation (logging, thread safety, performance monitoring).
- commons: Utilities for VarHandle injection, task/virtual thread scheduling, JSON, and random generation.
- configuration: Configuration framework built on SimplixStorage with serialization.
- mongodb: MongoDB integration via Morphia.
- cache: Multi-tier caching (Caffeine and Redis) with lock management.
- player: Distributed data management for high-performance entity-relationship networks.
- script: JavaScript execution engine wrapper supporting
Rhino,Nashorn, andV8. - experimental/third-party-schedulers: Distributed task processing via gRPC external schedulers (implemented in Rust). Ideal for offloading heavy computations like machine learning or anti-cheat logic to backends that cannot access the Bukkit API.
Use PromptX for AI-assisted development
mainPromptX is an AI capability enhancement framework used in this project to manage AI roles and long-term memory. It allows AI agents (primarily Claude Code) to switch into specific professional modes and persist project-specific knowledge, such as module architectures and API designs, to overcome context window limitations.
Key features include:
- Role System: Quickly switches the AI to a specific professional mode (e.g.,
java-backend-developer). - Memory Management: Enables the AI to internalize and remember professional knowledge, best practices, and project structures for long-term use.
- Role System: Quickly switches the AI to a specific professional mode (e.g.,
How the multi-tier cache design works
mainThe Player module uses a three-tier architecture to balance performance and persistence:
- L1 Cache (Caffeine): Local memory cache on each server instance. Provides nanosecond-level performance for online players. Supports automatic expiration and size-based eviction.
- L2 Cache (Redis): Distributed cache for hot and shared data. Provides millisecond-level performance and enables cross-server synchronization via distributed locks and Redis Stream message queues.
- Persistence Layer (MongoDB): Reliable persistent storage for large datasets and historical data, supporting complex queries and indexing.
Data Flow:
- Read Path: L1 (Caffeine) $\rightarrow$ L2 (Redis) $\rightarrow$ Database (MongoDB). Data found in lower tiers automatically populates higher tiers.
- Write Path: L1 (Caffeine) $\rightarrow$ L2 (Redis) via Redis Stream $\rightarrow$ Database (MongoDB) via scheduled tasks or explicit calls.
Manage variable environments with ScriptScope
mainUse
ScriptScopeto isolate variable environments. This allows you to set, get, and remove variables that are only accessible within a specific execution context, preventing global namespace pollution.Note:
V8ScriptEnginedoes not supportScriptScope.RhinoScriptEngine scriptEngine = new RhinoScriptEngine(); RhinoScriptScope scriptScope = RhinoScriptScope.of(scriptEngine); // Set variables scriptScope.setVariable("x", 10); scriptScope.setVariable("name", "Legacy"); // Execute in scope Object result = scriptEngine.execute("'Hello, ' + name + '! x = ' + x", scriptScope); // Get/Remove variables Object value = scriptScope.getVariable("name"); scriptScope.removeVariable("name");Handle query results with MorphiaCursor
mainThe
.iterator()method on a query returns aMorphiaCursor.Warning: Iterators returned by this library are not thread-safe. You should consume the results (e.g., by calling
.toList()) or manage synchronization manually if accessing the cursor across threads.Implement Rate Limiting with @RateLimiter
mainThe
@RateLimiterannotation provides multiple strategies to control the rate of requests. It supports different algorithms to handle traffic spikes or maintain constant throughput. You can also implement per-key rate limiting (e.g., per user) usingkeyExpressionand provide fallback methods for when limits are exceeded.public interface RateLimitService { @RateLimiter(limit = 5, period = 1000) String fixedWindowOperation(String input); @RateLimiter( limit = 2, period = 1000, keyExpression = "{#arg0}" ) String perUserOperation(String userId, String data); }