Описание
# EverlastingUtils
EverlastingUtils is a powerful, server-side utility and API library for the Fabric modding toolchain. It provides a robust framework for common, yet complex, features that mod developers frequently need, allowing them to focus more on their mod's unique content.
> **For Players:** If a mod you downloaded requires "EverlastingUtils," you just need to install this library in your `mods` folder. **You can ignore all the technical information below.**
>
> **Legacy Versions:** If you are using older versions of mods that require this library, please download EverlastingUtils version `1.0.2`.
### Dependencies
* [Fabric API](https://modrinth.com/mod/fabric-api)
* [Fabric Language Kotlin](https://modrinth.com/mod/fabric-language-kotlin)
---
>
> Attention Developers
> The information from this point forward is intended for mod developers looking to use EverlastingUtils as a dependency in their own projects.
>
## Core Features
EverlastingUtils is designed to accelerate development by providing ready-to-use, high-quality systems for:
* **Configuration**: A type-safe, multi-file configuration system with JSONC support, live reloading, and automatic version migration.
* **Task Scheduling**: A server-aware scheduler that properly handles synchronous (main thread) and asynchronous tasks, preventing common concurrency issues.
* **Commands**: A fluent, Brigadier-based command builder with integrated permission handling.
* **GUIs**: A simple yet powerful framework for creating interactive inventory-based GUIs, including standard and anvil types.
* **Utilities**: A collection of helpers for things like MiniMessage color parsing and toggleable, per-mod debug logging.
---
## System Spotlights
### Configuration System (`ConfigManager`)
The `ConfigManager` is a sophisticated system designed to handle all aspects of configuration management with minimal boilerplate.
**Key Functionalities:**
* **Type-Safe & Modern**: Uses Kotlin data classes for type-safe config access and JSONC for human-readable files with comments.
* **Live Reloading**: Automatically reloads configuration files from disk when they are changed, allowing server owners to adjust settings without a restart.
* **Multi-File Support**: Manages a main `config.jsonc` and any number of "secondary" configs in sub-directories, perfect for organizing complex data like Pokémon or loot pools.
* **Automatic Migration**: When you release a new version of your mod, the `ConfigManager` compares the version number in the user's config file with your mod's current version. If they don't match, it automatically merges their existing settings into a new, updated config structure, preserving their changes.
* **Metadata & Comments**: Programmatically add header comments, footer comments, and per-field descriptions to your config files, making them self-documenting.
**Example Usage:**
```kotlin
// 1. Define your configuration structure
data class MyConfig(
override val version: String = "1.0.0",
override val configId: String = "mymod", // Used for the config folder name
var debugMode: Boolean = false,
var welcomeMessage: String = "Welcome to my server!"
) : ConfigData
// 2. Initialize the manager in your mod's entry point
val configManager = ConfigManager(
currentVersion = "1.0.0", // Your mod's current version
defaultConfig = MyConfig(),
configClass = MyConfig::class,
metadata = ConfigMetadata(
headerComments = listOf("Main configuration for MyMod."),
sectionComments = mapOf("debugMode" to "Enables detailed console logging.")
)
)
// 3. Access your config anywhere
val isDebug = configManager.getCurrentConfig().debugMode
```
### Task Scheduler (`SchedulerManager`)
The `SchedulerManager` provides a safe and efficient way to schedule delayed or repeating tasks, built specifically for the Minecraft server environment.
**Key Functionalities:**
* **Server-Aware**: The scheduler is tied to the server lifecycle. It automatically shuts down when the server stops and recreates its thread pool on restart, preventing thread leaks and errors.
* **Sync vs. Async**: Easily specify whether a task should run **synchronously** on the main server thread (necessary for almost all Minecraft API calls) or **asynchronously** on a worker thread (for heavy, non-API work like database queries).
* **Efficient Threading**: Uses a shared, managed thread pool to prevent individual mods from creating excessive threads and bogging down the server.
* **Tracked Tasks**: All scheduled tasks are tracked by a unique ID, allowing you to cancel them later if needed.
**Example Usage:**
```kotlin
// In your server-side initializer (e.g., inside ServerLifecycleEvents.SERVER_STARTED)
val server = ... // Get the MinecraftServer instance
// Schedule a task to run every 5 minutes on the main server thread
SchedulerManager.scheduleAtFixedRate(
id = "mymod-broadcast-task", // Unique ID for this task
server = server,
initialDelay = 0,
period = 5,
unit = TimeUnit.MINUTES,
runAsync = false, // IMPORTANT: false runs on the main server thread
task = {
// This code is safe to run because runAsync is false
server.playerManager.broadcast(Text.literal("It has been 5 minutes!"), false)
}
)
```
---
## Other Features
### Command System (`CommandManager`)
A fluent builder for creating Brigadier commands with less boilerplate. It handles permission checks automatically, supporting both vanilla OP levels and the Fabric Permissions API.
```kotlin
val commandManager = CommandManager(modId = "mymod")
commandManager.command("hello", permission = "mymod.hello") {
executes { context ->
context.source.sendFeedback({ Text.literal("Hello, world!") }, false)
1 // Success
}
subcommand("admin") {
executes { context -> /* ... */ }
}
}
// Don't forget to register it!
commandManager.register()
```
### GUI Framework (`CustomGui` & `AnvilGuiManager`)
Quickly create interactive GUIs for your players with callback-based logic, dynamic updates, and full MiniMessage support for titles and lore.
```kotlin
// Example of a simple chest GUI
CustomGui.openGuiFormatted(
player = player,
title = "My Awesome GUI",
layout = listOf(
CustomGui.createFormattedButton(
ItemStack(Items.DIAMOND),
"Click Me!",
listOf("This is a button."),
player
)
),
onInteract = { context ->
if (context.slotIndex == 0) {
player.sendMessage(Text.literal("You clicked the button!"))
CustomGui.closeGui(player)
}
},
onClose = { /* ... */ }
)
```
---
## For Developers: Getting Started
To use EverlastingUtils in your project, add it to your dependencies.
#### build.gradle.kts
```kotlin
repositories {
// Add the repository where EverlastingUtils is hosted
maven { url = "https://api.modrinth.com/maven" }
}
dependencies {
// Add the library as a dependency
modImplementation("maven.modrinth:e-utils:1.1.2") // Replace with the latest version
}
```
#### fabric.mod.json
Make sure to declare the dependency in your `fabric.mod.json` file.
```json
"depends": {
"everlastingutils": ">=1.1.2" // Replace with the version you are using
}
```