Skip to content

EternalCodeTeam/EternalCodeCommons

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

140 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

EternalCode Commons

A collection of utilities and abstractions for Minecraft plugin development.

Gradle Chat on Discord Supports Paper

About

EternalCode Commons is a modular utility library for Minecraft plugin development. It provides platform-agnostic abstractions for scheduling, time parsing, cooldowns, and more β€” with ready-made implementations for Bukkit, Paper, and Folia.

Modules

Module Description Java Platform
eternalcode-commons-shared Core utilities β€” scheduling API, time parsing, cooldowns, progress bars, lazy init 17 Any
eternalcode-commons-bukkit Bukkit/Spigot/Paper scheduler implementation, item utils, position adapters 17 Bukkit/Paper
eternalcode-commons-folia Folia scheduler implementation 17 Folia
eternalcode-commons-adventure Kyori Adventure helpers β€” legacy color conversion, auto-clickable URLs 21 Any
eternalcode-commons-loom Virtual thread scheduler (platform-agnostic) 21 Any
eternalcode-commons-bukkit-loom Virtual thread scheduler for Bukkit/Paper 21 Bukkit/Paper
eternalcode-commons-folia-loom Virtual thread scheduler for Folia (region-aware) 21 Folia
eternalcode-commons-updater Modrinth update checker 17 Any

Getting Started

Add the EternalCode repository and the modules you need to your build.gradle.kts:

repositories {
    maven("https://repo.eternalcode.pl/releases")
}

dependencies {
    // Core utilities (scheduling API, time parsing, cooldowns, etc.)
    implementation("com.eternalcode:eternalcode-commons-shared:1.4.2")

    // Pick your platform's scheduler implementation:
    implementation("com.eternalcode:eternalcode-commons-bukkit:1.4.2")   // Bukkit/Paper
    // implementation("com.eternalcode:eternalcode-commons-folia:1.4.2") // Folia

    // Optional: virtual thread scheduler (Java 21+)
    implementation("com.eternalcode:eternalcode-commons-bukkit-loom:1.4.2")   // Bukkit/Paper
    // implementation("com.eternalcode:eternalcode-commons-folia-loom:1.4.2") // Folia

    // Optional: Adventure text utilities
    implementation("com.eternalcode:eternalcode-commons-adventure:1.4.2")

    // Optional: Modrinth update checker
    implementation("com.eternalcode:eternalcode-commons-updater:1.4.2")
}

Quick Examples

Scheduler (Bukkit/Paper)

The MinecraftScheduler interface wraps Bukkit's scheduler with Duration-based API and async support:

public class MyPlugin extends JavaPlugin {

    private MinecraftScheduler scheduler;

    @Override
    public void onEnable() {
        this.scheduler = new BukkitSchedulerImpl(this);
    }

    public void example(Player player) {
        // Run once, async
        scheduler.runAsync(() -> {
            String data = database.load(player.getUniqueId());

            // Switch back to main thread
            scheduler.run(() -> player.sendMessage(data));
        });

        // Repeating task with delay
        scheduler.timer(() -> player.sendMessage("tick"), Duration.ofSeconds(1), Duration.ofSeconds(5));
    }
}

Virtual Thread Scheduler (Java 21+, Bukkit/Paper)

BukkitLoomScheduler provides a fluent async pipeline using Java 21 virtual threads:

public class MyPlugin extends JavaPlugin {

    private BukkitLoomScheduler scheduler;

    @Override
    public void onEnable() {
        this.scheduler = BukkitLoomScheduler.create(this);
    }

    @Override
    public void onDisable() {
        this.scheduler.shutdown(Duration.ofSeconds(5));
    }

    public void loadData(Player player) {
        scheduler.supplyAsync(() -> database.load(player.getUniqueId()))  // virtual thread
            .thenApply(data -> transform(data))                           // virtual thread
            .thenAcceptSync(result -> player.sendMessage(result))         // main thread
            .exceptionally(e -> getLogger().severe(e.getMessage()));
    }
}

Rule: Async / thenApply β†’ virtual thread (never call Bukkit API here). Sync / thenAcceptSync β†’ main thread.

Virtual Thread Scheduler (Java 21+, Folia)

Folia has no single main thread β€” use the correct context for each operation:

FoliaLoomScheduler scheduler = FoliaLoomScheduler.create(plugin);

// Player operations
scheduler.forEntity(player)
    .supplyAsync(() -> database.load(player.getUniqueId()))
    .thenAcceptSync(data -> player.sendMessage(data));  // player's region thread

// Block operations
scheduler.forLocation(location)
    .runSync(() -> location.getBlock().setType(Material.STONE));  // location's region thread

// Global operations (broadcast, plugin state)
scheduler.forGlobal()
    .runSync(() -> Bukkit.broadcast(Component.text("Hello!")));

Duration Parsing

Parse human-readable durations from user input:

// Pre-built parsers
Duration duration = DurationParser.TIME_UNITS.parse("1h30m");    // 1 hour 30 minutes
Duration duration2 = DurationParser.DATE_TIME_UNITS.parse("2d12h"); // 2 days 12 hours

// Or build a custom one
TemporalAmountParser<Duration> parser = new DurationParser()
    .withUnit("s", ChronoUnit.SECONDS)
    .withUnit("m", ChronoUnit.MINUTES);

Duration result = parser.parse("5m30s"); // 5 minutes 30 seconds

Cooldowns (Delay)

Track per-player (or any key) cooldowns backed by Caffeine:

Delay<UUID> cooldown = Delay.withDefault(() -> Duration.ofSeconds(10));

public void onCommand(Player player) {
    if (cooldown.hasDelay(player.getUniqueId())) {
        Duration remaining = cooldown.getRemaining(player.getUniqueId());
        player.sendMessage("Wait " + remaining.toSeconds() + "s");
        return;
    }

    cooldown.markDelay(player.getUniqueId());
    // ... execute command
}

Progress Bar

Render a customizable text progress bar:

ProgressBar bar = ProgressBar.builder()
    .length(20)
    .filledChar("β–ˆ")
    .emptyChar("β–‘")
    .filledColor("Β§a")
    .emptyColor("Β§7")
    .brackets("Β§8[", "Β§8]")
    .build();

String rendered = bar.render(current, max);
// e.g. Β§8[Β§aβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘Β§8]

Update Checker (Modrinth)

Check for new plugin versions on Modrinth:

UpdateChecker checker = new ModrinthUpdateChecker();
UpdateResult result = checker.check("your-modrinth-project-id", new Version(getDescription().getVersion()));

if (result.isUpdateAvailable()) {
    getLogger().info("New version available: " + result.latestVersion());
    getLogger().info("Download: " + result.downloadUrl());
}

Adventure Utilities

Convert legacy &-color codes to Adventure components, and make URLs clickable:

// Parse &-color codes to Adventure component
Component component = AdventureUtil.component("&aHello &bWorld!");

// Auto-linkify URLs in a component
Component withLinks = new AdventureUrlPostProcessor().apply(component);

// Convert Β§-color codes (e.g. from config) to &-codes before parsing
String normalized = new AdventureLegacyColorPreProcessor().apply(rawString);

πŸ“„ License

This project is licensed under the GNU General Public License v3.0 β€” see the LICENSE file for details.

πŸ”— Links

About

🏳 Commons library for dedicated eternalcode projects.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors

Languages