# 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: MIT](https://img.shields.io/badge/license-MIT-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. --- ## 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. 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. We tried fixing this in AuthMe config. We tried removing Multiverse. The bug kept reappearing. AuthLimbo is the long-term fix. --- ## What this plugin does Two things, narrowly. 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. 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 `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). 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. --- ## Install 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`). AuthMe-ReReloaded is a **hard dependency**. The plugin will refuse to load without it. For the `itzg/minecraft-server` Docker image, see [`docs/installation.md`](docs/installation.md) for the `PLUGINS:` environment variable form. --- ## Configuration `plugins/AuthLimbo/config.yml` is created on first start. Defaults: ```yaml limbo: world: auth_limbo # Bukkit world name spawn-x: 0.5 spawn-y: 128.0 spawn-z: 0.5 build-platform: true # 5x5 barrier under spawn platform-y: 127 authme: db-path: plugins/AuthMe/authme.db teleport-delay-ticks: 10 # ticks to wait after LoginEvent preload-chunks: true # forceload chunk before teleport debug: false # verbose logging ``` Full reference in [`docs/configuration.md`](docs/configuration.md). --- ## Commands | Command | Permission | Effect | |----------------------------|---------------------|-----------------------------------------------------| | `/authlimbo reload` | `authlimbo.admin` | Reload `config.yml`. | | `/authlimbo tp ` | `authlimbo.admin` | Manually teleport a player to their saved location. | Aliases: `/alimbo`. --- ## Compatibility | 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 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). | --- ## Build from source ```bash 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. --- ## 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. --- ## License MIT. See [`LICENSE`](LICENSE). --- ## Author Built by [s8n-ru](https://github.com/s8n-ru).