README: rewrite in first-person — annoyed-dev origin story tone

This commit is contained in:
s8n-ru 2026-04-30 19:43:58 +01:00
parent cacd49b52d
commit a5bd58c577

117
README.md
View file

@ -1,62 +1,66 @@
# Auth-Limbo
Auth-limbo + login-restore fix for Paper 1.21+.
[![Build](https://github.com/s8n-ru/auth-limbo/actions/workflows/build.yml/badge.svg)](https://github.com/s8n-ru/auth-limbo/actions/workflows/build.yml)
[![License: AGPL--3.0](https://img.shields.io/badge/license-AGPL--3.0-lightgrey.svg)](LICENSE)
[![Paper](https://img.shields.io/badge/Paper-1.21.11%2B-lightgrey.svg)](https://papermc.io/)
[![Java](https://img.shields.io/badge/Java-21%2B-lightgrey.svg)](https://adoptium.net/)
A small Paper plugin that fixes a chronic AuthMe-ReReloaded post-login
teleport bug and bundles a void auth-limbo world so you don't need
Multiverse-Core just to host one void world.
A small Paper plugin I wrote because AuthMe's post-login teleport kept
dumping my players at world spawn instead of where they last were.
Tried every config flag, removed Multiverse, tried forks. Nothing
fixed it. So this does.
Two jobs: hosts a void `auth_limbo` world (so I could stop running
Multiverse-Core for one world I never visited) and replaces AuthMe's
broken post-login teleport with one that actually works.
---
## The problem
After a player runs `/login`, AuthMe is supposed to teleport them back
to the coordinates they had when they last quit. In current
AuthMe-ReReloaded forks (verified on the HaHaWTH fork b49), this
restore-teleport often fails: players land at world spawn instead of
their saved location.
Friend logs in, types `/login`, AuthMe is supposed to teleport them
back to where they were. They land at world spawn instead. Every
time.
Root cause is a known Paper teleport-race documented at
[PaperMC/Paper#4085](https://github.com/PaperMC/Paper/issues/4085).
AuthMe's `teleportOnLogin` flow calls `Player#teleportAsync` without
preloading the destination chunk first. The future resolves before the
chunk is loaded, Paper's safety logic then snaps the player back to the
nearest loaded position, and that position is world spawn.
Spent a day chasing this. Disabled Multiverse-Core. Disabled GrimAC.
Disabled UnexpectedSpawn. Disabled Essentials. Even ran with just
AuthMe loaded and the bug stayed.
We tried fixing this in AuthMe config. We tried removing Multiverse.
The bug kept reappearing. AuthLimbo is the long-term fix.
Eventually traced it to
[PaperMC/Paper#4085](https://github.com/PaperMC/Paper/issues/4085) —
`Player#teleportAsync` resolves before the destination chunk loads,
Paper's safety logic snaps the player to the nearest loaded chunk,
and that chunk is world spawn. AuthMe's `teleportOnLogin` flow walks
right into it.
Filed a mental bug report against AuthMe, decided writing my own
listener was faster than waiting on a fork.
---
## What this plugin does
## What it does
Two things, narrowly.
Two things and that's it.
1. **Hosts a void `auth_limbo` world.** A custom `ChunkGenerator`
produces empty chunks, an optional 5x5 barrier platform sits under
spawn, and the world is configured with no daylight cycle, no
weather, no mob spawning, and no PvP. AuthMe can use it as its
pre-auth limbo without you installing Multiverse-Core.
1. **Void `auth_limbo` world.** A custom `ChunkGenerator` produces
empty chunks. A 5x5 barrier platform sits under spawn so unauth
players don't fall forever. No daylight cycle, no weather, no mob
spawning, no PvP. AuthMe uses it as the pre-auth limbo. No
Multiverse-Core needed.
2. **Overrides AuthMe's restore-teleport.** A `LoginEvent` listener at
`MONITOR` priority runs *after* AuthMe's own broken teleport, reads
the player's saved quit-location directly from
`plugins/AuthMe/authme.db`, pins the destination chunk via
2. **Authoritative restore-teleport.** A `LoginEvent` listener at
`MONITOR` priority fires *after* AuthMe's broken teleport, reads
the saved quit-location straight out of
`plugins/AuthMe/authme.db`, pins the destination chunk with
`Chunk#addPluginChunkTicket`, then chains
`World#getChunkAtAsyncUrgently` into an authoritative
`Player#teleportAsync`. This is the canonical fix described in
[PaperMC/Paper#4085](https://github.com/PaperMC/Paper/issues/4085)
and used by
[PaperLib's `AsyncTeleportPaper`](https://github.com/PaperMC/PaperLib).
`Player#teleportAsync`. Same pattern
[PaperLib's `AsyncTeleportPaper`](https://github.com/PaperMC/PaperLib)
uses, just narrower.
That is the entire surface area. No password handling, no permissions
beyond admin commands, no register flow, no chat formatting. AuthMe owns
all of that.
That's the whole surface area. No password handling, no permissions
beyond admin commands, no register flow, no chat formatting. AuthMe
owns all of that.
---
@ -64,21 +68,23 @@ all of that.
1. Download `AuthLimbo-1.0.0.jar` from the
[Releases page](https://github.com/s8n-ru/auth-limbo/releases).
2. Drop it into your server's `plugins/` directory.
3. Restart the server (do not use `/reload`).
2. Drop it in your `plugins/` directory.
3. Restart the server. Don't `/reload` — it'll break things. Just
restart.
AuthMe-ReReloaded is a **hard dependency**. The plugin will refuse to
AuthMe-ReReloaded is a **hard dependency**. The plugin refuses to
load without it.
For the `itzg/minecraft-server` Docker image, see
[`docs/installation.md`](docs/installation.md) for the `PLUGINS:`
environment variable form.
environment-variable form.
---
## Configuration
`plugins/AuthLimbo/config.yml` is created on first start. Defaults:
Defaults work. `plugins/AuthLimbo/config.yml` is created on first
start. If you want to tweak:
```yaml
limbo:
@ -112,14 +118,14 @@ Aliases: `/alimbo`.
---
## Compatibility
## What I tested
| Component | Status | Notes |
|-----------------------------------|----------|----------------------------------------|
| Paper 1.21.11 | Yes | Primary target. |
| Purpur 1.21.11 | Yes | Same Paper API surface. |
| Folia | Unknown | Untested. Login event threading may differ. |
| AuthMe-ReReloaded (HaHaWTH b49) | Yes | Verified on production server. |
| AuthMe-ReReloaded (HaHaWTH b49) | Yes | Verified on production. |
| AuthMe-ReReloaded other 5.x forks | Untested | Schema is the same, should work. |
| Multiverse-Core | Untested | Not required. Possible teleport-intercept conflict — see [`docs/compatibility.md`](docs/compatibility.md). |
@ -131,23 +137,21 @@ Aliases: `/alimbo`.
mvn clean package
```
The shaded jar lands at `target/AuthLimbo-1.0.0.jar`. Requires Java
21+ and a Maven 3.9+ install. The `lib/AuthMe-5.6.0-FORK-Universal.jar`
in the repo is referenced as a `system`-scope dependency so the build
does not need any private repository credentials.
Shaded jar lands at `target/AuthLimbo-1.0.0.jar`. Java 21, Maven 3.9.
Standard. The `lib/AuthMe-5.6.0-FORK-Universal.jar` is referenced as
a `system`-scope dep so the build doesn't need any private repo
credentials.
---
## Why not just use Multiverse-Core for the void world?
Multiverse-Core is a 2 MB plugin that does world creation, world
listing, dimension portals, world-specific permissions, world inventory
separation, and a dozen other things. It also intercepts teleports for
its own portal and respawn logic, which is exactly the contention point
we are trying to avoid here. AuthLimbo is ~400 lines of code and only
manages the one void world AuthMe needs. If you are already running
Multiverse for other reasons, you can ignore the limbo manager and only
benefit from the LoginEvent fix.
Multiverse-Core does a dozen things. I needed one void world. Also
Multiverse intercepts teleports for portals and respawn, which is the
exact contention I was running from. This plugin is ~400 lines and
only manages the one world AuthMe needs. If you already run
Multiverse for legit reasons, ignore the limbo manager and just use
the teleport fix.
---
@ -164,4 +168,5 @@ no obligation beyond GPLv3 (no source-sharing required).
## Author
Built by [s8n-ru](https://github.com/s8n-ru).
Built by [s8n-ru](https://github.com/s8n-ru). If this fixes your
headache too, cool. If not, file an issue, I'll look.