EssentialsC API / Warps API

Warps API

Warp definitions, categories, costs, and teleport state. Package net.godlycow.org.essc.api.warp.

Overview

The warps module manages named teleport destinations - create, move, categorise, price, and permission-gate them. Unlike homes, kits, and RTP, warps expose no Bukkit events - you get a fully synchronous read API plus async writes, so custom warp GUIs and admin tools are easy.

Reads are synchronous, writes are async. Queries like findWarp() and getAllWarps() return immediately from cache. Mutations like createWarp(), deleteWarp(), and updateWarp() return a CompletableFuture because they write to storage.

Warp

interface net.godlycow.org.essc.api.warp.Warp

Immutable description of one warp. You read these from WarpManager; you never build one yourself.

Method Returns Description
String getName()StringWarp id, e.g. spawn.
Location getLocation()LocationLive destination (world + coordinates).
String getPermission()StringPermission required to use this warp, or empty.
double getCost()doubleEconomy cost to teleport (0 = free).
boolean isHidden()booleanWhether the warp is hidden from listings (still usable).
String getDescription()StringOptional description shown in warp menus.
String getCategory()StringCategory name used for grouping, or empty.
WarpIntrospection.java
Warp warp = warps.findWarp("spawn");
if (warp == null) return;

// getLocation() returns a fresh clone - safe to mutate.
Location loc = warp.getLocation();
boolean gated = !warp.getPermission().isEmpty();
double cost = warp.getCost();

player.sendMessage(warp.getName()
    + " - " + (warp.isHidden() ? "hidden" : "public")
    + (gated ? " (permission: " + warp.getPermission() + ")" : "")
    + (cost > 0 ? " ($" + cost + ")" : ""));

WarpManager

interface net.godlycow.org.essc.api.warp.WarpManager

Obtain via api.getWarpManager().

Reads

Method Returns Description
boolean isWarpSystemEnabled()booleanWhether the warps system is enabled in config.
Warp findWarp(String name)WarpLooks up a warp by id, or null.
Collection<Warp> getAllWarps()Collection<Warp>Every warp, hidden or not.
List<Warp> getVisibleWarps()List<Warp>Warps that show up in listings (not hidden).
List<Warp> getWarpsByCategory(String category)List<Warp>Warps in a category.
Set<String> getCategories()Set<String>All category names in use.
boolean warpExists(String name)booleanWhether a warp id exists.

Writes (async)

Method Returns Description
CompletableFuture<Boolean> createWarp(String name, Location location)booleanCreates a warp. Completes false if the name is taken.
CompletableFuture<Boolean> deleteWarp(String name)booleanDeletes a warp. Completes false if it didn't exist.
CompletableFuture<Boolean> updateWarp(Warp warp)booleanPersists changes to an existing warp (e.g. after moving it).

Teleport state

Method Returns Description
boolean hasPendingWarp(UUID player)booleanWhether the player has an in-progress warp teleport.
boolean isOnCooldown(UUID player)booleanWhether the player is inside the warp cooldown window.
long getRemainingCooldownSeconds(UUID player)longSeconds left on the cooldown, or 0.
CompletableFuture<Integer> fetchWarpUsage(UUID player, String warpName)intHow many times the player has used a specific warp.
void reload()voidReloads warp config + storage. Re-query anything cached.

Categories & visibility

Warps group naturally into categories. A common pattern is a paged GUI built from the category set:

WarpCategories.java
WarpManager warps = api.getWarpManager();

// Top level: one button per category.
for (String category : warps.getCategories()) {
    List<Warp> inCat = warps.getWarpsByCategory(category);
    gui.addButton(category, inCat.size() + " warps");
}

// Uncategorised warps still show in "Other".
List<Warp> visible = warps.getVisibleWarps();
for (Warp warp : visible) {
    if (warp.getCategory().isEmpty()) {
        gui.addButton(warp.getName(), warp.getDescription());
    }
}
Hidden ≠ locked. isHidden() only hides a warp from listings - it doesn't gate teleports. Permission gating is done through getPermission(). Check both when building a menu for a player.

Worked examples

Create a warp from your own command

SetWarpCommand.java
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    if (!(sender instanceof Player p) || args.length == 0) return true;

    WarpManager warps = api.getWarpManager();
    if (!api.isWarpSystemEnabled()) {
        p.sendMessage("The warps system is disabled.");
        return true;
    }

    warps.createWarp(args[0], p.getLocation()).thenAccept(created -> {
        if (created) {
            p.sendMessage("Warp '" + args[0] + "' created at your location.");
        } else {
            p.sendMessage("A warp with that name already exists.");
        }
    });
    return true;
}

Move a warp to a new location

MoveWarp.java
// There is no dedicated move method - read, mutate, persist.
Warp warp = warps.findWarp("shop");
if (warp == null) return;

// Location is cloned, so mutate freely.
Location newLoc = warp.getLocation();
newLoc.setX(100); newLoc.setZ(-200);

// Persist via the async update path.
warps.updateWarp(warp).thenAccept(saved -> {
    player.sendMessage(saved ? "Warp moved." : "Failed to save warp.");
});

Respect costs & permissions in your own teleport

UseWarp.java
Warp warp = warps.findWarp("vip_lounge");
if (warp == null) return;

// Permission gate.
if (!warp.getPermission().isEmpty()
        && !player.hasPermission(warp.getPermission())) {
    player.sendMessage("You don't have permission to use that warp.");
    return;
}

// Cooldown gate.
if (warps.isOnCooldown(player.getUniqueId())
        && !player.hasPermission("essentialsc.warp.bypass.cooldown")) {
    player.sendMessage("Warp cooldown: "
        + warps.getRemainingCooldownSeconds(player.getUniqueId()) + "s");
    return;
}

// Cost gate (with your own economy integration).
double cost = warp.getCost();
if (cost > 0 && balance < cost) {
    player.sendMessage("You need $" + cost + " to use that warp.");
    return;
}

player.teleportAsync(warp.getLocation());

// Track usage for later analytics.
warps.fetchWarpUsage(player.getUniqueId(), warp.getName())
    .thenAccept(count -> getLogger().info(player.getName()
        + " used " + warp.getName() + " (" + (count + 1) + " total)"));