Overview

Each API is exposed as a singleton accessed via a static getInstance() method. Events follow the Fabric event system (Fabric mod) or the Bukkit event system (Paper plugin). All three APIs are read/write — you can both query the current state and mutate areas at runtime. Since 1.0.8 the client and server mods are a single Fabric mod, so its two APIs ship in the same JAR.

Component Environment API class Events class
ProtectedArea (client side) Fabric client ProtectedAreaClientAPI ProtectedAreaEvents
ProtectedArea (server side) Fabric server ProtectedAreaServerAPI ProtectedAreaServerEvents
Plugin Paper (Bukkit) ProtectedAreaPluginAPI Standard Bukkit @EventHandler

Migrating to 1.0.8

Version 1.0.8 merged the former ProtectedAreaServer and ProtectedAreaClient mods into a single Fabric mod. No method signature changed — every call keeps the same name, parameters and return type. Only the package names and the mod id moved, so migrating is a find-and-replace plus a recompile.

Before After
me.marquinho.protectedareaserver.api.*me.marquinho.protectedarea.api.*
me.marquinho.protectedareaserver.models.*me.marquinho.protectedarea.models.*
me.marquinho.protectedareaclient.client.api.*me.marquinho.protectedarea.client.api.*
me.marquinho.protectedareaclient.client.models.*me.marquinho.protectedarea.client.models.*

Update your dependency declaration as well:

"depends": {
  "protectedarea": ">=1.0.8"
}

If you previously depended on both mods, they are now a single entry.

Client Mod API

The client API is available only on the client side of the Fabric mod. Import it from me.marquinho.protectedarea.client.api.

ProtectedAreaClientAPI

Get the singleton instance:

ProtectedAreaClientAPI api = ProtectedAreaClientAPI.getInstance();

Query methods

Method Return type Description
getAreas() Collection<ProtectedArea> All areas currently known to the client.
getArea(String id) Optional<ProtectedArea> Look up an area by its ID.
getPlayerCurrentAreas() Set<String> IDs of cube areas the local player is currently inside.
isPlayerInside(String areaId) boolean Whether the local player is currently inside the given cube area.
getAreasAt(double x, double y, double z, String worldName, String dimension) Collection<ProtectedArea> All cube areas that contain the given world coordinates.

Example

// Check if the local player is in a specific area
ProtectedAreaClientAPI api = ProtectedAreaClientAPI.getInstance();

if (api.isPlayerInside("spawn")) {
    // player is inside the "spawn" area
}

// Get all areas at a given position
Collection<ProtectedArea> areas = api.getAreasAt(100, 64, 200, "world", "minecraft:overworld");
for (ProtectedArea area : areas) {
    System.out.println("Area at position: " + area.getId());
}

Client Events

Events are defined in ProtectedAreaEvents and follow the standard Fabric event pattern. Register listeners during mod initialization.

Event field Callback interface Parameters Fired when
AREA_ADDED AreaCallback (ProtectedArea area) The server sends a new area to the client.
AREA_REMOVED AreaRemovedCallback (String areaId) The server removes an area from the client.
AREAS_CLEARED AreasCleared (none) The client disconnects or the server clears all areas.
PLAYER_ENTERED_AREA AreaCallback (ProtectedArea area) The local player enters a cube area.
PLAYER_LEFT_AREA AreaCallback (ProtectedArea area) The local player leaves a cube area.
PLAYER_CROSSED_FLAT PlayerFlatCrossCallback (ProtectedArea area, boolean toPositiveSide) The local player crosses a flat area boundary.

Example

// In your ClientModInitializer
ProtectedAreaEvents.PLAYER_ENTERED_AREA.register(area -> {
    MinecraftClient.getInstance().player.sendMessage(
        Text.literal("You entered: " + area.getId()), true
    );
});

ProtectedAreaEvents.PLAYER_CROSSED_FLAT.register((area, toPositiveSide) -> {
    String side = toPositiveSide ? "positive" : "negative";
    System.out.println("Crossed flat area " + area.getId() + " to " + side + " side");
});

ProtectedAreaEvents.AREA_ADDED.register(area -> {
    System.out.println("Area received from server: " + area.getId());
});

ProtectedAreaEvents.AREAS_CLEARED.register(() -> {
    System.out.println("All areas cleared (disconnected or server reset)");
});

Server Mod API

The server API is available only on the server side of the Fabric mod. Import it from me.marquinho.protectedarea.api.

ProtectedAreaServerAPI

Get the singleton instance:

ProtectedAreaServerAPI api = ProtectedAreaServerAPI.getInstance();

Query methods

Method Return type Description
getAreas() Collection<ProtectedArea> All registered areas.
getArea(String id) Optional<ProtectedArea> Look up an area by ID.
getAreaAt(double x, double y, double z, String dimension) Optional<ProtectedArea> Most relevant area containing the position: highest priority first, smallest volume as tie-break. Dimension areas are included, so this can return the dimension area when no cube area covers the position.
getAreasAt(double x, double y, double z, String dimension) Collection<ProtectedArea> Every area containing the position, dimension areas included.
canPlayerEnter(ServerPlayerEntity player, String areaId) boolean Whether the player is allowed to enter the area (checks NO_ENTRY rule and exceptions).
getPlayersInArea(String areaId) int Number of players currently inside the area.
getPlayersListInArea(String areaId) List<ServerPlayerEntity> Players currently inside the area.
hasRule(String areaId, AreaRule rule) boolean Whether the area has the given rule active.
hasException(String areaId, String playerName, AreaRule rule) boolean Whether the player has an exception for the given rule in the area.
getAdvancedRules(String areaId) Collection<?> All advanced rules configured on the area.

Action methods

Method Description
createArea(String id, double x1, double y1, double z1, double x2, double y2, double z2, String dimension) Create a new cube area.
createFlatArea(String id, double flatPosition, double x1, double y1, double z1, double x2, double y2, double z2, String dimension) Create a new flat (2D crossing plane) area.
removeArea(String id) Delete an area permanently.
removeAreasByFolder(String folderPrefix) Delete all areas whose ID starts with the given folder prefix (e.g. "solo/"). Returns the number of areas removed. Each removed area is broadcast to connected clients.
addRule(String areaId, AreaRule rule) Add a basic rule to the area.
removeRule(String areaId, AreaRule rule) Remove a basic rule from the area.
addException(String areaId, String playerName, AreaRule rule) Grant a player an exception to a rule.
removeException(String areaId, String playerName, AreaRule rule) Revoke a player exception.
setLimit(String areaId, int limit) Set the maximum simultaneous players allowed in the area.
removeLimit(String areaId) Remove the player limit.
setLimitBlocked(String areaId, boolean blocked) Toggle whether new entries are blocked when the limit is reached.
setSkybox(String areaId, String name) Assign a skybox asset to the area (PNG filename without extension).
removeSkybox(String areaId) Remove the skybox from the area.
setPriority(String areaId, int priority) Set the area priority (higher wins for skybox and conflicting rules).
expelPlayer(ServerPlayerEntity player, String areaId) Teleport the player out of the area.
returnPlayer(ServerPlayerEntity player, String areaId) Teleport the player back into the area.
addBlockRule(String areaId, AdvancedRuleType type, String blockId) Add an advanced block rule.
removeBlockRule(String areaId, AdvancedRuleType type, String blockId) Remove an advanced block rule.
addEntityRule(String areaId, AdvancedRuleType type, String entityId) Add an advanced entity rule.
removeEntityRule(String areaId, AdvancedRuleType type, String entityId) Remove an advanced entity rule.

Example

ProtectedAreaServerAPI api = ProtectedAreaServerAPI.getInstance();

// Create a cube area programmatically
api.createArea("shop", 100, 60, 200, 120, 80, 220, "minecraft:overworld");

// Apply rules
api.addRule("shop", AreaRule.NO_PVP);
api.addRule("shop", AreaRule.NO_DROP);

// Give a specific player an exception to NO_DROP
api.addException("shop", "Steve", AreaRule.NO_DROP);

// Assign a skybox
api.setSkybox("shop", "marketplace");

// Set a player limit of 10 and block entry when full
api.setLimit("shop", 10);
api.setLimitBlocked("shop", true);

// Check players inside
int count = api.getPlayersInArea("shop");
System.out.println("Players in shop: " + count);

List<ServerPlayerEntity> players = api.getPlayersListInArea("shop");
for (ServerPlayerEntity p : players) {
    System.out.println("  - " + p.getName().getString());
}

// Remove all areas in a folder at once
int removed = api.removeAreasByFolder("events/");
System.out.println("Removed " + removed + " areas from events/");

Server Events

Events are defined in ProtectedAreaServerEvents. Register listeners in your ModInitializer.

Event field Callback interface Parameters Fired when
AREA_CREATED AreaCallback (ProtectedArea area) A new area is created (command or API).
AREA_REMOVED AreaRemovedCallback (String areaId) An area is removed (command or API).
PLAYER_ENTERED_AREA PlayerAreaCallback (ServerPlayerEntity player, ProtectedArea area) A player enters a cube area.
PLAYER_LEFT_AREA PlayerAreaCallback (ServerPlayerEntity player, ProtectedArea area) A player leaves a cube area.
PLAYER_CROSSED_FLAT PlayerFlatCrossCallback (ServerPlayerEntity player, ProtectedArea area, boolean toPositiveSide) A player crosses a flat area boundary.
RULE_BLOCKED RuleBlockedCallback (ServerPlayerEntity player, ProtectedArea area, AreaRule rule) A basic rule blocks a player action.
ADVANCED_RULE_BLOCKED AdvancedRuleBlockedCallback (ServerPlayerEntity player, ProtectedArea area, AdvancedRuleType ruleType, String targetId) An advanced rule blocks a player action.

Example

// In your ModInitializer
ProtectedAreaServerEvents.PLAYER_ENTERED_AREA.register((player, area) -> {
    player.sendMessage(Text.literal("Welcome to " + area.getId() + "!"), false);
});

ProtectedAreaServerEvents.PLAYER_LEFT_AREA.register((player, area) -> {
    player.sendMessage(Text.literal("You left " + area.getId()), false);
});

ProtectedAreaServerEvents.PLAYER_CROSSED_FLAT.register((player, area, toPositiveSide) -> {
    if (toPositiveSide) {
        player.sendMessage(Text.literal("Entered restricted zone"), false);
    }
});

ProtectedAreaServerEvents.RULE_BLOCKED.register((player, area, rule) -> {
    // Log every blocked action
    System.out.println(player.getName().getString() + " was blocked by " + rule + " in " + area.getId());
});

ProtectedAreaServerEvents.AREA_CREATED.register(area -> {
    System.out.println("New area created: " + area.getId());
});

Plugin API

The Paper plugin API mirrors the server mod API but uses standard Bukkit/Paper types. Import it from me.marquinho.protectedAreaPlugin.api.

ProtectedAreaPluginAPI

Get the singleton instance:

ProtectedAreaPluginAPI api = ProtectedAreaPluginAPI.getInstance();

Query methods

Method Return type Description
getAreas() Collection<ProtectedArea> All registered areas.
getArea(String id) Optional<ProtectedArea> Look up an area by ID.
getAreaAt(Location location) Optional<ProtectedArea> Most relevant area containing the location: highest priority first, smallest volume as tie-break. Dimension areas are included, so this can return the dimension area when no cube area covers the location.
getAreasAt(Location location) Collection<ProtectedArea> Every area containing the location, dimension areas included.
canPlayerEnter(Player player, String areaId) boolean Whether the player is allowed to enter the area.
getPlayersInArea(String areaId) int Number of players currently inside the area.
getPlayersListInArea(String areaId) List<Player> Players currently inside the area.
hasRule(String areaId, AreaRule rule) boolean Whether the area has the given rule active.
hasException(String areaId, String playerName, AreaRule rule) boolean Whether the player has an exception for the given rule.
getAdvancedRules(String areaId) Collection<?> All advanced rules on the area.

Action methods

The action methods are identical to the Server Mod API but accept org.bukkit.entity.Player instead of ServerPlayerEntity:

Method Description
createArea(String id, double x1, double y1, double z1, double x2, double y2, double z2, String dimension) Create a new cube area.
createFlatArea(String id, double flatPosition, double x1, double y1, double z1, double x2, double y2, double z2, String dimension) Create a new flat area.
removeArea(String id) Delete an area permanently.
removeAreasByFolder(String folderPrefix) Delete all areas whose ID starts with the given folder prefix (e.g. "solo/"). Returns the number of areas removed. Each removed area is broadcast to connected clients.
addRule(String areaId, AreaRule rule) Add a basic rule.
removeRule(String areaId, AreaRule rule) Remove a basic rule.
addException(String areaId, String playerName, AreaRule rule) Grant a player an exception.
removeException(String areaId, String playerName, AreaRule rule) Revoke a player exception.
setLimit(String areaId, int limit) Set the player limit.
removeLimit(String areaId) Remove the player limit.
setLimitBlocked(String areaId, boolean blocked) Toggle entry blocking when limit is reached.
setSkybox(String areaId, String name) Assign a skybox to the area.
removeSkybox(String areaId) Remove the skybox.
setPriority(String areaId, int priority) Set the area priority.
expelPlayer(Player player, String areaId) Teleport the player out of the area.
returnPlayer(Player player, String areaId) Teleport the player back into the area.
addBlockRule(String areaId, AdvancedRuleType type, String blockId) Add an advanced block rule.
removeBlockRule(String areaId, AdvancedRuleType type, String blockId) Remove an advanced block rule.
addEntityRule(String areaId, AdvancedRuleType type, String entityId) Add an advanced entity rule.
removeEntityRule(String areaId, AdvancedRuleType type, String entityId) Remove an advanced entity rule.

Example

// In your JavaPlugin
ProtectedAreaPluginAPI api = ProtectedAreaPluginAPI.getInstance();

// Create an area using Bukkit Location helpers
api.createArea("pvp-arena", -50, 60, -50, 50, 100, 50, "minecraft:overworld");
api.addRule("pvp-arena", AreaRule.NO_ENTRY);

// Grant VIP players an exception
api.addException("pvp-arena", "VIPPlayer", AreaRule.NO_ENTRY);

// Query at a Bukkit location
Location loc = player.getLocation();
Optional<ProtectedArea> area = api.getAreaAt(loc);
area.ifPresent(a -> player.sendMessage("You are in: " + a.getId()));

// Check how many players are in an area
int count = api.getPlayersInArea("pvp-arena");
System.out.println("Players in arena: " + count);

// Get the actual list of players
List<Player> players = api.getPlayersListInArea("pvp-arena");
for (Player p : players) {
    p.sendMessage("The arena is starting!");
}

// Remove all areas in a folder at once
int removed = api.removeAreasByFolder("events/");
System.out.println("Removed " + removed + " areas from events/");

Bukkit Events

The plugin fires standard Bukkit events. Listen to them with @EventHandler on a class that implements Listener.

Event class Key getters Fired when
PlayerEnteredAreaEvent getPlayer(), getArea() A player enters a cube area.
PlayerLeftAreaEvent getPlayer(), getArea() A player leaves a cube area.
PlayerCrossedFlatEvent getPlayer(), getArea(), isToPositiveSide() A player crosses a flat area boundary.
AreaRuleBlockedEvent getPlayer(), getArea(), getRule() A basic rule blocks a player action.
AreaAdvancedRuleBlockedEvent getPlayer(), getArea(), getRuleType(), getTargetId() An advanced rule blocks a player action.

Example

public class AreaListener implements Listener {

    @EventHandler
    public void onEnter(PlayerEnteredAreaEvent event) {
        event.getPlayer().sendMessage("Welcome to " + event.getArea().getId() + "!");
    }

    @EventHandler
    public void onLeave(PlayerLeftAreaEvent event) {
        event.getPlayer().sendMessage("You left " + event.getArea().getId());
    }

    @EventHandler
    public void onCrossFlat(PlayerCrossedFlatEvent event) {
        String side = event.isToPositiveSide() ? "positive" : "negative";
        event.getPlayer().sendMessage("Crossed into " + side + " side of " + event.getArea().getId());
    }

    @EventHandler
    public void onRuleBlocked(AreaRuleBlockedEvent event) {
        event.getPlayer().sendMessage(
            ChatColor.RED + "Action blocked by rule: " + event.getRule().name()
        );
    }

    @EventHandler
    public void onAdvancedRuleBlocked(AreaAdvancedRuleBlockedEvent event) {
        event.getPlayer().sendMessage(
            ChatColor.RED + "Advanced rule blocked: " + event.getRuleType() + " on " + event.getTargetId()
        );
    }
}

Register the listener in your plugin's onEnable:

@Override
public void onEnable() {
    getServer().getPluginManager().registerEvents(new AreaListener(), this);
}

Enums Reference

AreaRule

Used for basic rules and exceptions. Shared across all three APIs.

Value Description
NO_BREAKPrevent block breaking.
NO_PLACEPrevent block placing.
NO_INTERACTPrevent block/entity interaction.
NO_MOBGRIEFINGPrevent mob griefing (creeper explosions, enderman picking blocks, etc.).
NO_PVPPrevent player-vs-player damage.
NO_ENTITYATTACKPrevent attacking entities.
NO_DAMAGEPrevent all damage to players inside the area.
NO_DROPPrevent dropping items.
NO_COLLECTPrevent picking up items.
NO_SPAWNPrevent entity spawning.
NO_ENTRYPrevent players from entering the area.
NO_EXITPrevent players from leaving the area.

AdvancedRuleType

Used for fine-grained per-block or per-entity rules.

Value Description
YES_BREAKAllow breaking a specific block type (overrides NO_BREAK).
YES_PLACEAllow placing a specific block type (overrides NO_PLACE).
YES_INTERACTAllow interacting with a specific block/entity (overrides NO_INTERACT).
YES_DROPAllow dropping a specific item (overrides NO_DROP).
YES_COLLECTAllow collecting a specific item (overrides NO_COLLECT).
NO_BREAKBlock breaking of a specific block type (granular deny).
NO_PLACEBlock placing of a specific block type (granular deny).
NO_INTERACTBlock interaction with a specific block/entity (granular deny).
NO_DROPBlock dropping of a specific item (granular deny).
NO_COLLECTBlock collecting of a specific item (granular deny).