Developer API
ArenaPvP exposes a public Java API that other plugins can use to query player state, arena information, queue status, group data, and leaderboards.
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 |
GroupManager | Group queries and operations |
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 |
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);
});
GroupManager
Queries
| Method | Returns | Description |
|---|---|---|
getPlayerGroup(UUID) | Optional<GroupInfo> | Group the player belongs to |
getGroup(UUID groupId) | Optional<GroupInfo> | Group by its ID |
getAllGroups() | Collection<GroupInfo> | All active groups |
isGroupLeader(UUID) | boolean | Whether the player is a group leader |
areInSameGroup(UUID, UUID) | boolean | Whether two players share a group |
getMaxGroupSize() | int | Maximum allowed group size |
Operations
All operations return a GroupResult with isSuccess(), getMessage(), and getGroupId().
| Method | Description |
|---|---|
createGroup(UUID leaderUuid) | Create a new group |
dissolveGroup(UUID leaderUuid) | Dissolve (leader only) |
invitePlayer(UUID inviter, UUID invited) | Send invitation |
kickMember(UUID leader, UUID member) | Kick a member |
leaveGroup(UUID player) | Leave group |
transferLeadership(UUID current, UUID new) | Transfer leadership |
GroupManager gm = api.getGroupManager();
GroupManager.GroupResult result = gm.createGroup(leaderUuid);
if (result.isSuccess()) {
UUID groupId = result.getGroupId();
gm.invitePlayer(leaderUuid, friendUuid);
}
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.
GroupInfo
| Method | Type | Description |
|---|---|---|
getId() | UUID | Group identifier |
getLeaderUuid() | UUID | Leader UUID |
getLeaderName() | String | Leader display name |
getMemberUuids() | List<UUID> | All member UUIDs |
getMemberNames() | Map<UUID, String> | UUID → display name |
getSize() | int | Group size |
getOnlineCount() | int | Online members |
getType() | String | "PERMANENT" or "TEMPORARY" |
isActive() | boolean | Whether the group is active |
isMember(UUID) | boolean | Whether a player is in this group |
GroupResult
| Method | Type | Description |
|---|---|---|
isSuccess() | boolean | Whether the operation succeeded |
getMessage() | String | Human-readable result message |
getGroupId() | UUID | Affected group ID (may be null) |
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.
- Group operations should ideally be called from the server 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);
// Group
arenaApi.getGroupManager()
.getPlayerGroup(playerUuid)
.ifPresent(group -> {
System.out.println("Group: " + group.getLeaderName());
System.out.println("Members: " + group.getSize());
});
}
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("Groups in queue: " + queues.getQueueSize());
}
}
Package Structure
com.arenapvp.api
├── ArenaPvPAPI.java # Main entry point
├── ArenaPvPProvider.java # Static provider
├── PlayerManager.java # Player state queries
├── GroupManager.java # Group queries & operations
├── 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.