An open API service indexing awesome lists of open source software.

https://github.com/ultikits/ultitools-reborn

A library for Minecraft server plugin development.
https://github.com/ultikits/ultitools-reborn

bukkit bukkit-plugin library minecraft minecraft-plugin spigot spigot-plugin spigot-plugin-api

Last synced: 3 months ago
JSON representation

A library for Minecraft server plugin development.

Awesome Lists containing this project

README

          






UltiTools-API

The Modern Spigot Plugin Framework

Build Minecraft plugins the way you'd build a Spring Boot app — annotations, dependency injection, ORM, and scheduled tasks. Java 8+ compatible, Minecraft 1.8 - 1.21.



GitHub License
GitHub release (latest by date)
Maven Central
GitHub Repo stars
Minecraft Version
Java Version
Spigot Rating
bStats Players
bStats Servers
CodeFactor

---


English | 中文文档

| [![discord](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/6TVRRF47) | Join our Discord! | 加入官方 QQ 群! | [![discord](https://img.shields.io/badge/Tencent_QQ-EB1923?style=for-the-badge&logo=TencentQQ&logoColor=white)](https://qm.qq.com/q/i5GeDH6a7C) |
|-----------------------------------------------------------------------------------------------------------------------------------------|----------------------------|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|


## Why UltiTools?

Writing Spigot plugins often means pages of boilerplate — registering commands manually, wiring up listeners, building raw SQL, scheduling BukkitRunnables everywhere. UltiTools-API eliminates all of that.

**What you get:**

| Feature | Traditional Spigot | With UltiTools-API |
|---------|-------------------|-------------------|
| Commands | `onCommand()` switch/case | `@CmdMapping(format = "pay ")` |
| Listeners | Manual registration in `onEnable()` | `@EventListener` auto-discovered |
| Dependency injection | Static singletons everywhere | `@Autowired` like Spring |
| Data storage | Raw JDBC or custom file I/O | `@Table` + `@Column` ORM, works with MySQL/SQLite/JSON |
| Config | `getConfig().getString(...)` | `@ConfigEntry` on typed fields with validation |
| Scheduled tasks | `new BukkitRunnable()` boilerplate | `@Scheduled(period = 6000)` on any method |
| Feature toggles | Manual `if` checks | `@ConditionalOnConfig` skips entire components |
| Transactions | Manual try/catch/rollback | `@Transactional` AOP proxy |


## Quick Look

A complete UltiTools module in under 50 lines:

```java
// Main class — just one annotation to enable auto-scanning
@UltiToolsModule(scanBasePackages = {"com.example.myplugin"})
public class MyPlugin extends UltiToolsPlugin {
@Override
public boolean registerSelf() { return true; }

@Override
public void unregisterSelf() { }
}
```

```java
// Define your data — works with MySQL, SQLite, and JSON automatically
@Data @Builder @NoArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Table("homes")
public class HomeEntity extends AbstractDataEntity {
@Column("player_id") private String playerId;
@Column("name") private String name;
@Column("world") private String world;
@Column("x") private double x;
@Column("y") private double y;
@Column("z") private double z;
}
```

```java
// Write commands like controllers — auto-registered, auto-completed
@CmdTarget(CmdTarget.CmdTargetType.PLAYER)
@CmdExecutor(alias = {"home"}, permission = "myplugin.home")
public class HomeCommand extends AbstractCommandExecutor {

@Autowired
private HomeService homeService;

@CmdMapping(format = "tp ")
public void teleport(@CmdSender Player player, @CmdParam("name") String name) {
homeService.teleport(player, name);
}

@CmdMapping(format = "set ")
public void setHome(@CmdSender Player player, @CmdParam("name") String name) {
homeService.setHome(player, name, player.getLocation());
player.sendMessage("Home set!");
}

@CmdMapping(format = "list")
public void listHomes(@CmdSender Player player) {
homeService.getHomes(player).forEach(h ->
player.sendMessage(" - " + h.getName())
);
}
}
```

```java
// Service with DI, query DSL, and scheduled tasks
@Service
public class HomeService {

@Autowired
private UltiToolsPlugin plugin;

public void teleport(Player player, String name) {
HomeEntity home = plugin.getDataOperator(HomeEntity.class)
.query()
.where("playerId").eq(player.getUniqueId().toString())
.and("name").eq(name)
.first();

if (home != null) {
Location loc = new Location(
Bukkit.getWorld(home.getWorld()),
home.getX(), home.getY(), home.getZ()
);
player.teleport(loc);
}
}

public List getHomes(Player player) {
return plugin.getDataOperator(HomeEntity.class)
.query()
.where("playerId").eq(player.getUniqueId().toString())
.orderBy("name")
.list();
}

@Scheduled(period = 72000, async = true) // Cleanup every hour
public void cleanupExpiredHomes() {
// Automatically called by the framework — no BukkitRunnable needed
}
}
```

That's it. No `onCommand()` switches, no manual listener registration, no `new BukkitRunnable()` boilerplate, no raw SQL.


## Features

### Annotation-Driven Commands
Map subcommands directly to methods. Parameters are parsed and type-converted automatically.

```java
@CmdMapping(format = "pay ")
public void pay(@CmdSender Player sender, @CmdParam("player") String target, @CmdParam("amount") double amount) {
// 'amount' is already a double — no manual parsing
}
```

### IoC Container with `@Autowired`
Spring-like dependency injection with three-level cache for circular dependency resolution.

```java
@Service
public class EconomyService {
@Autowired
private TransactionLogger logger; // Auto-injected

@Transactional
public void transfer(UUID from, UUID to, double amount) {
// Automatic rollback on exception
}
}
```

### Fluent Query DSL
Chain conditions, ordering, and pagination — works across MySQL, SQLite, and JSON storage.

```java
List richPlayers = plugin.getDataOperator(AccountEntity.class)
.query()
.where("balance").gte(10000)
.orderByDesc("balance")
.limit(10)
.list();

boolean exists = plugin.getDataOperator(AccountEntity.class)
.query()
.where("owner").eq(uuid)
.and("name").eq("savings")
.exists();
```

### `@Scheduled` Tasks
Declare scheduled methods — the framework handles BukkitRunnable creation, registration, and cleanup.

```java
@Service
public class InterestService {
@Scheduled(delay = 100, period = 36000, async = true) // 30min cycle, async
public void distributeInterest() {
// Called automatically. Cancelled when plugin unloads.
}

@Scheduled(delay = 20) // One-shot: runs once after 1 second
public void onStartup() {
// Initialization logic
}
}
```

### Config Validation
Invalid config values are automatically caught and reset to safe defaults on load and reload.

```java
@Getter @Setter
@ConfigEntity(path = "config/config.yml")
public class EcoConfig extends AbstractConfigEntity {

@ConfigEntry(path = "interestRate", comment = "Interest rate per cycle")
@Range(min = 0.0, max = 1.0)
private double interestRate = 0.0003;

@ConfigEntry(path = "currency_name", comment = "Currency display name")
@NotEmpty
private String currencyName = "Gold Coin";

@ConfigEntry(path = "motd", comment = "Server message of the day")
@Size(min = 1, max = 256)
private String motd = "Welcome!";
}
```

### `@ConditionalOnConfig`
Toggle entire features on/off from config — no `if` checks scattered through code.

```java
@Service
@ConditionalOnConfig(value = "config/config.yml", path = "enableInterest")
public class InterestService {
// This bean is never created if enableInterest: false
}

@CmdExecutor(alias = {"warp"}, permission = "myplugin.warp")
@ConditionalOnConfig(value = "config/config.yml", path = "enableWarp")
public class WarpCommands extends AbstractCommandExecutor {
// Command doesn't exist if enableWarp: false
}
```

### AOP Proxies
`@Transactional` and `@ExceptionCatch` via CGLIB runtime proxies — no boilerplate try/catch.

```java
@Service
public class BankService {
@Transactional(propagation = Propagation.REQUIRED)
public void transfer(UUID from, UUID to, double amount) {
withdraw(from, amount);
deposit(to, amount); // Rolls back both if this throws
}

@ExceptionCatch(value = IOException.class, silent = true)
public String readExternalData() {
// Returns null on IOException instead of crashing
}
}
```

### More Built-in

- **GUI Framework** — Inventory GUIs with pagination via ObliviateInvs
- **i18n** — Built-in internationalization with `i18n("key")`
- **Hot Module Loading** — Load/unload plugin modules without server restart
- **WebSocket + UltiPanel** — Remote server management (commands, files, monitoring, logs)
- **Plugin Sandbox** — Class blacklisting, path traversal protection, command blocklists


## Getting Started

### Requirements

- **Java**: 8 or higher
- **Minecraft**: 1.8 - 1.21 (Spigot/Paper)
- **UltiTools Plugin**: Install on your server

### Add the Dependency

**Maven**
```xml

com.ultikits
UltiTools-API
6.2.0

```

**Gradle**
```groovy
implementation 'com.ultikits:UltiTools-API:6.2.0'
```

### Create `plugin.yml`

```yaml
name: MyPlugin
version: '${project.version}'
main: com.example.myplugin.MyPlugin
api-version: 600
authors: [ YourName ]
```

### Write Your Plugin

```java
@UltiToolsModule(scanBasePackages = {"com.example.myplugin"})
public class MyPlugin extends UltiToolsPlugin {
@Override
public boolean registerSelf() {
return true; // Commands, listeners, services are all auto-registered!
}

@Override
public void unregisterSelf() { }
}
```

Add `@CmdExecutor` on command classes, `@EventListener` on listener classes, and `@Service` on services. The framework discovers and wires everything automatically.

For detailed guides, see the [Developer Documentation](https://dev.ultikits.com/en/) or [Project Wiki](docs/wiki/README.md).


## Documentation

| Document | Description |
|----------|-------------|
| [Developer Docs](https://dev.ultikits.com/en/) | Full documentation site |
| [Project Wiki](docs/wiki/README.md) | Complete project documentation |
| [Architecture Guide](docs/wiki/ARCHITECTURE.md) | System architecture overview |
| [IoC Container](docs/wiki/modules/IOC_CONTAINER.md) | Dependency injection guide |
| [Command System](docs/wiki/modules/COMMAND_SYSTEM.md) | Command development guide |
| [Data Storage](docs/wiki/modules/DATA_STORAGE.md) | Database operations guide |
| [Quick Start Tutorial](docs/wiki/tutorials/QUICK_START.md) | First module tutorial |
| [API Reference](docs/wiki/api/INDEX.md) | API quick reference |


## Project Structure

```
UltiTools-Reborn/
├── src/main/java/com/ultikits/ultitools/
│ ├── UltiTools.java # Main plugin entry
│ ├── abstracts/ # Base classes (UltiToolsPlugin, AbstractCommandExecutor, etc.)
│ ├── annotations/ # Framework annotations (@Service, @CmdExecutor, @Scheduled, etc.)
│ │ └── config/ # Validation annotations (@Range, @NotEmpty, @Size, @Pattern)
│ ├── aop/ # AOP system (CglibProxyFactory, TransactionInterceptor)
│ ├── context/ # IoC container (SimpleContainer, ComponentScanner)
│ ├── manager/ # Core managers (Command, Listener, Config, Plugin, Task)
│ ├── interfaces/ # Core interfaces (DataOperator, Query, DataStore) + impl/
│ ├── websocket/ # UltiPanel WebSocket client + handlers
│ └── utils/ # SecurityPolicy, CloudAuthManager, ApiRateLimiter
├── docs/wiki/ # Project documentation
└── pom.xml
```


## Contributing

[Submit an Issue](https://github.com/UltiKits/UltiTools-Reborn/issues/new/choose) for bugs and suggestions.

### Main Contributors
| Contributor | Role |
|-------------|------|
| [@wisdommen](https://github.com/wisdommen) | Founder, UltiKits Author |
| [@qianmo2233](https://github.com/qianmo2233) | Developer, Documentation Maintainer |
| [@Shpries](https://github.com/Shpries) | Developer |
| [@JueChenChen](https://github.com/JueChenChen) | Issue Feedback & Suggestions |
| 拾柒 | Graphic Designer |


## License

MIT License — see [LICENSE](LICENSE) for details.


## WakaTime Statistics

Development Timeline
wakatime timeline




wakatime week


## Acknowledgments

| | |
|---------------------------------------------------------------------------------------------------------------------------|------------------------|
| ![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge&logo=openjdk&logoColor=white) | Development language |
| ![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=white) | CI/CD |
| ![wakatime](https://img.shields.io/badge/IntelliJ_IDEA-000000.svg?style=for-the-badge&logo=intellij-idea&logoColor=white) | IDE |
| ![Claude](https://img.shields.io/badge/Claude-191919?style=for-the-badge&logo=anthropic&logoColor=white) | AI-assisted development |
| ![wakatime](https://img.shields.io/badge/apache_maven-C71A36?style=for-the-badge&logo=apachemaven&logoColor=white) | Build tool |