# ☕ Java API

NexusProxy exposes a small public Java API for other Velocity plugins.

The API is mainly focused on:

* Player presence
* Global player counts
* Server player counts
* Proxy player counts
* Friends data
* Online friend data
* Player snapshots

{% hint style="info" %}
The Java API is intended for Velocity plugins that want to read NexusProxy data.

It is not required for normal server owners.
{% endhint %}

***

### What The API Is Used For

You can use the NexusProxy API to access data such as:

* Find a player by name
* Find a player by UUID
* Get the global network player count
* Get the player count on a backend server
* Get the player count on a proxy
* Check if two players are friends
* Get a player's friend IDs
* Get a player's friend count
* Get a player's online friend count
* Find a friend snapshot

***

### Getting The API

Use the NexusProxy provider to access the API instance.

```java
Optional<NexusProxyApi> apiOptional = NexusProxyProvider.get();
```

Always check if the API is present before using it.

```java
NexusProxyProvider.get().ifPresent(api -> {
    // Use the API here
});
```

{% hint style="warning" %}
Do not assume NexusProxy is always loaded.

Your plugin should safely handle the API not being available.
{% endhint %}

***

### Basic Usage Example

```java
Optional<NexusProxyApi> optionalApi = NexusProxyProvider.get();

if (optionalApi.isEmpty()) {
    return;
}

NexusProxyApi api = optionalApi.get();

// Use the API here
```

***

### Provider

The API provider gives access to the NexusProxy API instance.

| Method                     | Description                        |
| -------------------------- | ---------------------------------- |
| `NexusProxyProvider.get()` | Returns `Optional<NexusProxyApi>`. |

Example:

```java
Optional<NexusProxyApi> api = NexusProxyProvider.get();
```

Recommended usage:

```java
NexusProxyProvider.get().ifPresent(api -> {
    int online = api.globalPlayerCount();
});
```

***

### Presence API

The presence API lets your plugin read player location and online information known by NexusProxy.

Available methods:

| Method                | Description                                   |
| --------------------- | --------------------------------------------- |
| `findByName`          | Finds a player snapshot by username.          |
| `findByUniqueId`      | Finds a player snapshot by UUID.              |
| `globalPlayerCount`   | Returns the global online player count.       |
| `playerCountOnServer` | Returns the player count on a backend server. |
| `playerCountOnProxy`  | Returns the player count on a proxy.          |

***

### Find Player By Name

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    Optional<PlayerSnapshot> snapshot = api.findByName("Steve");

    snapshot.ifPresent(player -> {
        String username = player.username();
        String serverName = player.serverName();
        String proxyId = player.proxyId();
    });
});
```

***

### Find Player By UUID

Example concept:

```java
UUID uuid = UUID.fromString("00000000-0000-0000-0000-000000000000");

NexusProxyProvider.get().ifPresent(api -> {
    Optional<PlayerSnapshot> snapshot = api.findByUniqueId(uuid);

    snapshot.ifPresent(player -> {
        String username = player.username();
        boolean online = player.online();
    });
});
```

***

### Global Player Count

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    int globalOnline = api.globalPlayerCount();
});
```

This can be used for:

* Network status commands
* Custom dashboards
* Scoreboard systems
* Admin tools
* External integrations

***

### Server Player Count

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    int lobbyOnline = api.playerCountOnServer("lobby");
});
```

{% hint style="warning" %}
The server name should match the backend server name configured in Velocity.
{% endhint %}

***

### Proxy Player Count

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    int proxyOnline = api.playerCountOnProxy("Proxy-1");
});
```

{% hint style="warning" %}
The proxy ID should match the `cluster.proxy_id` configured in `nexusproxy.yml`.
{% endhint %}

***

### Friends API

The Friends API allows other Velocity plugins to access friend-related data.

Available methods:

| Method              | Description                             |
| ------------------- | --------------------------------------- |
| `areFriends`        | Checks if two players are friends.      |
| `friendIds`         | Returns a player's friend UUIDs.        |
| `friendCount`       | Returns a player's total friend count.  |
| `onlineFriendCount` | Returns a player's online friend count. |
| `findFriend`        | Finds a friend snapshot.                |

{% hint style="info" %}
Friends API data depends on the Friends module and your storage setup.
{% endhint %}

***

### Check If Two Players Are Friends

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    boolean friends = api.areFriends(playerOneUuid, playerTwoUuid);

    if (friends) {
        // Players are friends
    }
});
```

***

### Get Friend IDs

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    Collection<UUID> friends = api.friendIds(playerUuid);

    for (UUID friendId : friends) {
        // Use friend UUID
    }
});
```

***

### Get Friend Count

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    int totalFriends = api.friendCount(playerUuid);
});
```

***

### Get Online Friend Count

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    int onlineFriends = api.onlineFriendCount(playerUuid);
});
```

{% hint style="info" %}
For accurate online friend counts in multi-proxy networks, Redis is recommended.
{% endhint %}

***

### Find Friend

Example concept:

```java
NexusProxyProvider.get().ifPresent(api -> {
    Optional<PlayerSnapshot> friend = api.findFriend(playerUuid, friendUuid);

    friend.ifPresent(snapshot -> {
        String username = snapshot.username();
        String serverName = snapshot.serverName();
        boolean online = snapshot.online();
    });
});
```

***

### PlayerSnapshot

`PlayerSnapshot` represents known player presence data.

Available data:

| Method       | Description                                                    |
| ------------ | -------------------------------------------------------------- |
| `uniqueId`   | Returns the player's UUID.                                     |
| `username`   | Returns the player's username.                                 |
| `proxyId`    | Returns the proxy ID where the player is connected.            |
| `serverName` | Returns the backend server name where the player is connected. |
| `online`     | Returns whether the player is online.                          |

***

### PlayerSnapshot Example

```java
NexusProxyProvider.get().ifPresent(api -> {
    Optional<PlayerSnapshot> optionalSnapshot = api.findByName("Steve");

    if (optionalSnapshot.isEmpty()) {
        return;
    }

    PlayerSnapshot snapshot = optionalSnapshot.get();

    UUID uniqueId = snapshot.uniqueId();
    String username = snapshot.username();
    String proxyId = snapshot.proxyId();
    String serverName = snapshot.serverName();
    boolean online = snapshot.online();
});
```

***

### Example: Create A Network Status Command

Example concept:

```java
public void sendNetworkStatus(CommandSource source) {
    Optional<NexusProxyApi> optionalApi = NexusProxyProvider.get();

    if (optionalApi.isEmpty()) {
        source.sendMessage(Component.text("NexusProxy API is not available."));
        return;
    }

    NexusProxyApi api = optionalApi.get();

    int globalOnline = api.globalPlayerCount();
    int lobbyOnline = api.playerCountOnServer("lobby");
    int survivalOnline = api.playerCountOnServer("survival");

    source.sendMessage(Component.text("Network online: " + globalOnline));
    source.sendMessage(Component.text("Lobby online: " + lobbyOnline));
    source.sendMessage(Component.text("Survival online: " + survivalOnline));
}
```

***

### Example: Check A Player's Friends Count

Example concept:

```java
public void sendFriendsInfo(CommandSource source, UUID playerUuid) {
    Optional<NexusProxyApi> optionalApi = NexusProxyProvider.get();

    if (optionalApi.isEmpty()) {
        source.sendMessage(Component.text("NexusProxy API is not available."));
        return;
    }

    NexusProxyApi api = optionalApi.get();

    int totalFriends = api.friendCount(playerUuid);
    int onlineFriends = api.onlineFriendCount(playerUuid);

    source.sendMessage(Component.text("Friends: " + onlineFriends + "/" + totalFriends + " online"));
}
```

***

### Redis And API Data

Some API data can depend on Redis when using multiple Velocity proxies.

Redis is recommended for:

* Global online count
* Proxy online count
* Server online count across proxies
* Player presence snapshots
* Online friend count
* Friend location data

{% hint style="warning" %}
If Redis is disabled on a multi-proxy network, presence data may be incomplete or inaccurate.
{% endhint %}

***

### Database And API Data

Friends-related API methods may depend on database storage.

Database storage is recommended for:

* Friend relationships
* Friend counts
* Known player profiles
* Persistent friends data

Supported database types:

```yaml
mysql
mongodb
mongo
```

{% hint style="info" %}
For production networks using the Friends API, Redis + MySQL or MongoDB is recommended.
{% endhint %}

***

### Best Practices

* Always check if `NexusProxyProvider.get()` returns an API instance.
* Do not block the proxy thread with heavy database or network work.
* Cache carefully if your plugin calls the API frequently.
* Do not assume a player snapshot always exists.
* Use exact Velocity server names for server count queries.
* Use exact `cluster.proxy_id` values for proxy count queries.
* Handle offline players safely.
* Test your plugin with Redis enabled if your network uses multiple proxies.

***

### Common Issues

#### API is not available

Check that:

* NexusProxy is installed on the Velocity proxy.
* NexusProxy loaded successfully.
* Your plugin loads after NexusProxy.
* Your plugin checks `NexusProxyProvider.get()` safely.
* NexusProxy API classes are available to your plugin at compile time.

***

#### Player snapshot is empty

Check that:

* The player name or UUID is correct.
* The player is known by NexusProxy.
* The player is online if your use case requires online presence.
* Redis is enabled if checking across multiple proxies.

***

#### Player count is wrong

Check that:

* Redis is enabled for multi-proxy networks.
* Every proxy uses the same Redis settings.
* Every proxy has a unique `cluster.proxy_id`.
* The server name matches Velocity exactly.
* The proxy ID matches `cluster.proxy_id`.

***

#### Friends data is empty

Check that:

* The Friends module is enabled.
* Database storage is enabled.
* Friend data exists.
* The UUIDs are correct.
* Redis is enabled if checking online friend data.

***

### Notes For Developers

The examples on this page are simplified and may need imports or minor adjustments depending on your project setup.

Use the API classes provided with your NexusProxy build as the source of truth for package names, method signatures, and return types.

***

### Summary

The NexusProxy Java API allows other Velocity plugins to read player presence and friends data.

It is useful for custom commands, dashboards, scoreboards, network tools, staff utilities, and integrations that need access to NexusProxy online and friends information.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nexusproxy.nemesismc.net/java-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
