Plugin API
Overview
SCS2 ships a public Java API for other plugins to integrate with the claim system — read claim data, listen to events, drive admin actions, and (since 2.5.0) declare custom flags and role-permissions.
The API is published as a separate artifact SimpleClaimSystem-API via JitPack. Add it as a provided/compileOnly dependency in your build file:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.Xyness</groupId>
<artifactId>SimpleClaimSystem-API</artifactId>
<version>v2.5.0</version>
<scope>provided</scope>
</dependency>
Add SimpleClaimSystem to your plugin.yml as a depend or softdepend, then access the API instance via SCS_API_Provider.get().
The full API reference (every method, every event, every Type class) lives in the SimpleClaimSystem-API README on GitHub. The sections below focus on what's new in 2.5.0.
Custom flags & permissions (2.5.0)
External plugins can declare their own claim flags and role-permissions. Data-only: SCS2 stores the per-claim value and exposes it through claim.getFlag(key) / claim.getPermission(role, key). You write the @EventHandler that checks the value and cancels events — SCS does NOT invoke any handler tied to your definition.
Registering a custom flag
Register in your plugin's onLoad() so SCS's startup migration sees your flag and seeds the default value on existing claims. Runtime registration (in onEnable or later) also works — SCS backfills cached claims and persists to DB — but claims that loaded before the registration are missing the key until the next plugin reload.
import fr.xyness.SimpleClaimSystem.API.FlagDefinition;
import fr.xyness.SimpleClaimSystem.API.SCS_FlagRegistry;
public class MyPlugin extends JavaPlugin {
@Override
public void onLoad() {
SCS_FlagRegistry.registerFlag(FlagDefinition.builder("my_flag")
.defaultValue(true)
// Optional: separate defaults for PROTECTED / SURVIVAL_REQUIRING_CLAIMS world modes
.protectedModeDefault(false)
.survivalRequiringClaimsModeDefault(true)
// Optional metadata used by the GUI (you provide the lang strings)
.titleKey("my_flag-title")
.loreKey("my_flag-lore")
.iconMaterial("DIAMOND")
// Used in diagnostics + SCS_FlagRegistry.unregisterAllOwnedBy(pluginName)
.owningPluginName(getName())
.build());
}
@Override
public void onDisable() {
// Optional cleanup on plugin reload
SCS_FlagRegistry.unregisterAllOwnedBy(getName());
}
// Your own listener checks the flag and cancels the event
@EventHandler
public void onSomething(SomeBukkitEvent event) {
SCS_API api = SCS_API_Provider.get();
api.getClaim(event.getLocation().getChunk()).ifPresent(claim -> {
if (!claim.getFlag("my_flag")) event.setCancelled(true);
});
}
}
Registering a custom role-permission
Same shape, but with per-role defaults. Role names are matched case-insensitively (uppercase-normalized internally). Roles not explicitly listed fall back to fallbackDefault — important for custom roles created by claim owners.
import fr.xyness.SimpleClaimSystem.API.PermissionDefinition;
import fr.xyness.SimpleClaimSystem.API.SCS_FlagRegistry;
@Override
public void onLoad() {
SCS_FlagRegistry.registerPermission(PermissionDefinition.builder("my_perm")
.defaultPerRole("VISITOR", false)
.defaultPerRole("MEMBER", true)
.defaultPerRole("MODERATOR", true)
.fallbackDefault(false) // used by custom claim roles
.titleKey("my_perm-title")
.loreKey("my_perm-lore")
.iconMaterial("DIAMOND")
.owningPluginName(getName())
.build());
}
@EventHandler
public void onSomething(SomeBukkitEvent event) {
Player player = event.getPlayer();
SCS_API api = SCS_API_Provider.get();
api.getClaim(event.getLocation().getChunk()).ifPresent(claim -> {
String role = claim.getRole(player.getUniqueId());
if (!claim.getPermission(role, "my_perm")
&& !player.hasPermission("scs.bypass.my_perm")) {
event.setCancelled(true);
}
});
}
Auto-registered Bukkit permissions
When you register a custom key, SCS automatically declares the matching Bukkit permissions via PluginManager.addPermission:
| Permission node | Default | Purpose |
|---|---|---|
scs.bypass.<key> | op | Bypass the per-claim check (you read it in your own listener). |
scs.flag.<key> (flags only) | op | Allow toggling this flag in the GUI. |
scs.permission.<key> (permissions only) | op | Allow toggling this permission row in the GUI. |
You don't need to declare these in your own plugin.yml. They're cleaned up on unregister.
Runtime registration via SCS_API
The same operations are mirrored on the runtime SCS_API:
SCS_API api = SCS_API_Provider.get();
api.registerCustomFlag(FlagDefinition.builder("dynamic").build());
api.unregisterCustomFlag("dynamic");
api.registerCustomPermission(PermissionDefinition.builder("dynamic_perm").build());
api.unregisterCustomPermission("dynamic_perm");
Runtime registration triggers an immediate backfill on every cached claim (default value written to claims that don't yet have the key, batched into a single DB write). Runtime unregistration strips the key from cached claims.
Caveats
- Default value source-of-truth: the
defaultValuein the builder is used to seed claims that don't have your key yet. After that, the per-claim stored value wins — changing the builder default later won't update existing claims. - No automatic gating: SCS doesn't call your code on any event. The flag is a stored boolean; you write the listener.
- Definition not persisted: only the per-claim value is stored in the DB. If your plugin is uninstalled and SCS restarts, the unknown key is stripped at the next startup migration (same behavior as a removed built-in flag).
For the full API surface (claim queries, events, modifications, favorites, etc.), see the SimpleClaimSystem-API README on GitHub.