Developer API
ArenaPvP exposes a public Java API that other plugins can use to query player state, arena information, queue status, and leaderboards.
Group management is handled by the GroupManager plugin, which has its own separate API. See the GroupManager integration page for details.
Getting Started
Add ArenaPvP's jar as a compileOnly dependency:
dependencies {
compileOnly(files("libs/arenapvp.jar"))
}
All public types live under com.arenapvp.api:
| Interface | Description |
|---|---|
ArenaPvPAPI | Main entry point — provides sub-managers |
ArenaPvPProvider | Static provider to obtain the API instance |
PlayerManager | Player state queries |
ArenaManager | Arena instance queries |
QueueManager | Matchmaking queue queries |
LeaderboardManager | Statistics, ratings, and rankings |
Obtaining the API
import com.arenapvp.api.ArenaPvPAPI;
import com.arenapvp.api.ArenaPvPProvider;
// Safe access (recommended)
if (ArenaPvPProvider.isAvailable()) {
ArenaPvPAPI api = ArenaPvPProvider.get();
// use the API
}
// Direct access — throws IllegalStateException if not loaded
ArenaPvPAPI api = ArenaPvPProvider.get();
Cache the ArenaPvPAPI reference — the instance doesn't change during server lifetime.
PlayerManager
Queries about individual player state. All methods take a UUID.
| Method | Returns | Description |
|---|---|---|
isInArena(UUID) | boolean | Player is inside an arena match |
isInQueue(UUID) | boolean | Player is in a matchmaking queue |
isInPendingMatch(UUID) | boolean | Match found, waiting for instance |
isSpectator(UUID) | boolean | Player is spectating |
isExternalSpectator(UUID) | boolean | Spectating without being a participant |
isInTransfer(UUID) | boolean | Being teleported in/out of arena |
isInGroup(UUID) | boolean | Belongs to a group (requires GroupManager) |
isBusy(UUID) | boolean | In arena, queue, pending, or transfer |
getArenaInstanceId(UUID) | Optional<UUID> | Instance ID if in an arena |
getQueueCategory(UUID) | Optional<String> | Category code if in a queue |
PlayerManager pm = api.getPlayerManager();
if (pm.isBusy(playerUuid)) {
// Don't teleport or interact
return;
}
pm.getArenaInstanceId(playerUuid).ifPresent(id -> {
System.out.println("In arena: " + id);
});
ArenaManager
Read-only queries about active arena instances.
| Method | Returns | Description |
|---|---|---|
getActiveInstances() | Collection<ArenaSnapshot> | All active instances |
getInstanceById(UUID) | Optional<ArenaSnapshot> | Instance by ID |
getInstanceByPlayer(UUID) | Optional<ArenaSnapshot> | Instance containing a player |
getTotalPlayersInArenas() | int | Total players across all arenas |
getActiveInstanceCount() | int | Number of active instances |
getActiveInstanceCountByCategory(String) | int | Active instances in a category |
hasActiveInstances() | boolean | Whether any instance is active |
ArenaManager am = api.getArenaManager();
am.getInstanceByPlayer(playerUuid).ifPresent(snapshot -> {
System.out.println("Arena: " + snapshot.getArenaName());
System.out.println("Type: " + snapshot.getArenaType());
System.out.println("Players: " + snapshot.getPlayerCount() + "/" + snapshot.getMaxPlayers());
});
QueueManager
Read-only queries about matchmaking state.
| Method | Returns | Description |
|---|---|---|
getQueueSize() | int | Total groups in all queues |
getQueueSizeByCategory(String) | int | Groups in queue for a category |
getPendingMatchCount() | int | Matches waiting for instance creation |
isPlayerInQueue(UUID) | boolean | Player is in any queue |
isPlayerInPendingMatch(UUID) | boolean | Player has a pending match |
LeaderboardManager
Statistics, ratings, and ranking queries by arena category. New players have a default rating of 1000.
| Method | Returns | Description |
|---|---|---|
getRating(String category, UUID) | int | Player rating (default: 1000) |
getStats(String category, UUID) | Optional<PlayerStats> | Player stats in a category |
getTotalStats(UUID) | TotalStats | Aggregated stats across all categories |
getTopByRating(String category, int limit) | List<PlayerStats> | Top players (limit: 1–100) |
LeaderboardManager lb = api.getLeaderboardManager();
int rating = lb.getRating("2-FFA", playerUuid);
lb.getStats("2-FFA", playerUuid).ifPresent(stats -> {
System.out.println("K/D: " + stats.getKdRatio());
System.out.println("W/L: " + stats.getWlRatio());
});
List<LeaderboardManager.PlayerStats> top = lb.getTopByRating("2-FFA", 10);
for (int i = 0; i < top.size(); i++) {
var s = top.get(i);
System.out.println((i + 1) + ". " + s.getDisplayName() + " — " + s.getRating());
}
Data Types
All returned objects are immutable snapshots — they represent state at the moment of the query.
ArenaSnapshot
| Method | Type | Description |
|---|---|---|
getInstanceId() | UUID | Instance identifier |
getArenaName() | String | Template name |
getCategoryCode() | String | Category (e.g. "2-FFA") |
getArenaType() | String | Type (e.g. "FFA", "TDM") |
getMaxPlayers() | int | Max players |
getPlayerUuids() | Collection<UUID> | All player UUIDs |
getTeam1Uuids() | Collection<UUID> | Team 1 UUIDs |
getTeam2Uuids() | Collection<UUID> | Team 2 UUIDs |
getAlivePlayerUuids() | Collection<UUID> | Alive players |
getPlayerCount() | int | Current player count |
isMatchStarted() | boolean | Match has started |
isActive() | boolean | Instance is active |
isDeathmatch() | boolean | Deathmatch mode |
isCaptureMode() | boolean | Capture (TCTO) mode |
isTeamBased() | boolean | Team-based arena |
getWorldName() | String | World name (may be null) |
PlayerStats
| Method | Type | Description |
|---|---|---|
getPlayerId() | UUID | Player UUID |
getDisplayName() | String | Player name |
getKills() | int | Kills |
getDeaths() | int | Deaths |
getWins() | int | Wins |
getLosses() | int | Losses |
getRating() | int | Rating |
getKdRatio() | double | Kill/death ratio |
getWlRatio() | double | Win/loss ratio |
getLastUpdated() | long | Last update (epoch millis) |
TotalStats
| Method | Type | Description |
|---|---|---|
getKills() | int | Total kills across all categories |
getDeaths() | int | Total deaths |
getWins() | int | Total wins |
getLosses() | int | Total losses |
getKdRatio() | double | Global K/D ratio |
getWlRatio() | double | Global W/L ratio |
Thread Safety
- All query methods are safe to call from any thread.
- Returned snapshot objects are fully immutable — safe to cache or pass between threads.
Full Example
import com.arenapvp.api.*;
public class MyPlugin {
private ArenaPvPAPI arenaApi;
public void onEnable() {
if (!ArenaPvPProvider.isAvailable()) {
System.out.println("ArenaPvP is not available!");
return;
}
arenaApi = ArenaPvPProvider.get();
System.out.println("Connected to ArenaPvP API");
}
public void showPlayerInfo(UUID playerUuid) {
PlayerManager players = arenaApi.getPlayerManager();
if (players.isBusy(playerUuid)) {
System.out.println("Player is busy");
players.getArenaInstanceId(playerUuid).ifPresent(instanceId -> {
arenaApi.getArenaManager()
.getInstanceById(instanceId)
.ifPresent(arena -> {
System.out.println("Arena: " + arena.getArenaName());
System.out.println("Mode: " + arena.getArenaType());
});
});
}
// Rating
int rating = arenaApi.getLeaderboardManager().getRating("2-FFA", playerUuid);
System.out.println("2v2 FFA Rating: " + rating);
}
public void showServerStats() {
ArenaManager arenas = arenaApi.getArenaManager();
QueueManager queues = arenaApi.getQueueManager();
System.out.println("Active arenas: " + arenas.getActiveInstanceCount());
System.out.println("Players fighting: " + arenas.getTotalPlayersInArenas());
System.out.println("Players in queue: " + queues.getQueueSize());
}
}
Package Structure
com.arenapvp.api
├── ArenaPvPAPI.java # Main entry point
├── ArenaPvPProvider.java # Static provider
├── PlayerManager.java # Player state queries
├── ArenaManager.java # Arena instance queries
├── QueueManager.java # Queue state queries
├── LeaderboardManager.java # Stats, ratings & rankings
└── impl/ # Internal — do not depend on
Only depend on interfaces in com.arenapvp.api. The impl package is internal and subject to change.