Elytrium / Elytrium/LimboAPI

[ENHANCEMENT] Public API for plugins to register as PRE_LIMBO GPR handler

Open
#272 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
310
Forks
121
PR merge metrics
No merged PRs in 30d

Description

## Describe the feature you'd like to have implemented

Add a public API method to LimboAPI that allows plugins to register themselves as `PRE_LIMBO_PROFILE_REQUEST` handlers, so their `GameProfileRequestEvent` listener runs **before** LimboAPI's `hookLoginSession` reads the event and sends `LoginSuccess` to the client.

Something like:

```java
// In LimboAPI class
public void registerPreProfileRequestPlugin(String pluginId);
```

Plugins would call this in their initialization:

```java
LimboAPI limboApi = (LimboAPI) ProxyServer.getInstance()
.getPluginManager().getPlugin("limboapi").orElseThrow();
limboApi.registerPreProfileRequestPlugin("qqauth");
```

## Is your feature request related to an existing problem? Please describe.

Yes — it relates to **Issue #143** (`[BUG] LimboAPI causes "Chat validation error"`).

Auth plugins that replace the player UUID in `GameProfileRequestEvent` (e.g., JPremium, The QQAuth plugin I am currently developing, and similar "premium → offline UUID mapping" plugins) run into a race condition with LimboAPI's `EventManagerHook`:

1. LimboAPI intercepts `GameProfileRequestEvent` at `@Subscribe(order = PostOrder.FIRST)`
2. It fires PRE_LIMBO plugins (`floodgate`, `geyser`) via an internal `FIRE_METHOD`
3. However, other GPR handlers (like auth plugins' UUID replacement) remain in the standard Velocity event chain
4. Due to async interleaving, `hookLoginSession` reads `event.getGameProfile()` — and sends `LoginSuccess` to the client — **before** the auth plugin's GPR handler has replaced the UUID
5. The result: client receives `LoginSuccess(UUID=premiumUuid)`, the backend Paper server sees the replaced (offline) UUID → UUID mismatch → **"Chat validation error"** on the sending client

The current workaround is to manually add the auth plugin's ID to `PRE_LIMBO_PROFILE_REQUEST_PLUGINS` in LimboAPI's `config.yml`, but this requires users to know about this config option and manually maintain it. Many users are not aware of this configuration item, and self registration should be the responsibility of the plugin.

## Additional context

The current code in `EventManagerHook.reloadHandlers()` (Settings.java line 97) hardcodes `List.of("floodgate", "geyser")` as defaults. A plugin can register itself at runtime via the proposed API, and `reloadHandlers()` would merge both sources:

```java
// In reloadHandlers()
if (Settings.IMP.MAIN.PRE_LIMBO_PROFILE_REQUEST_PLUGINS.contains(id)
|| this.plugin.getRegisteredPreLimboPlugins().contains(id)) {
preEvents.add(handler);
newHandlers.remove(handler);
}
```

This is backward-compatible — users who already configured it manually via `config.yml` keep working, and plugins that call the new API get handled automatically.

**Related discussion:** Issue #143 — the bug report that this feature would help resolve.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.