Releases: adrielorihuela/HybridAuth
Release list
HybridAuth 1.2.1
Brings the fork up to Velocity 4.1.1. Nothing this fork adds has changed, so upgrading is
replacing the jar.
From upstream
Four commits from PaperMC/Velocity, covering the 4.1.0 and
4.1.1 releases.
The one worth knowing about: the console switches from JLine's FFM terminal backend to its JNI
one. FFM is the canonical choice on modern Java, but it has been crashing the JVM on window
resize (jline3#2139), and downgrading JLine instead
would have brought back four CVEs. Upstream will move back once the fix lands.
velocity-api is now published at 4.1.1, so plugins built against it resolve that version.
From this fork
Documentation only. Several pages still referred to the configuration file by a name it had two
versions ago, and CLAUDE.md still claimed permission nodes carried the velocity. prefix, which
stopped being true when they moved to hybridauth.command.* with the older prefixes kept as
fallbacks. Anybody following those pages would have gone looking for a file that is not there.
Upgrading from 1.2.0
Replace the jar. Nothing else changes.
HybridAuth 1.2.0
HybridVelocity is now HybridAuth. The name says what it does rather than what it forked from.
The proxy also keeps your plugins up to date by itself now, and the configuration has moved into a
config/ directory. Nothing you have configured stops working, and there is no migration step to
follow.
Plugins that update themselves
List what you want and the proxy handles the rest. Five sources, mixed freely:
[plugins]
hangar = [
"ViaVersion"
]
modrinth = [
"ViaBackwards"
]
github = [
"ViaVersion/ViaRewind"
]
geyser = [
"geyser",
"floodgate"
]
luckperms = falseThose are the defaults, so a fresh install arrives with ViaVersion, ViaBackwards, ViaRewind, Geyser
and Floodgate already listed. Empty lists make no network requests at all.
On every start, before plugins are loaded, each one is downloaded if it is missing and updated if a
newer build exists. They are fetched all at once and start-up waits for the last of them, so the
loader never sees a half-finished directory.
Only what needs updating is downloaded. Each start makes one small JSON request per plugin,
hashes what is already on disk, and downloads only the ones that differ. A start with nothing to do
transfers a few kilobytes.
Decided by the checksum, never by the file name
A file name proves only that something of that name is there — not that it is this build, not that
it is intact, and not that it is what the source is serving today. So the digest decides, and the
same digest verifies the download, which means a corrupted file never reaches plugins/.
Hangar, Modrinth, GitHub and GeyserMC all publish one. LuckPerms publishes none anywhere, in any
format, so it falls back to the name and says so in the log rather than passing for a check that
did not happen.
Stable builds first, and only as far down as needed
Hangar and Modrinth are asked for a release, then a beta, then an alpha, and the newest build of
the highest tier available is installed. Both halves matter: unfiltered, Hangar answers ViaVersion
with 5.12.0-SNAPSHOT+1053, and Simple Voice Chat has thirteen Velocity builds of which not one is
a release.
Stability wins over recency, which is worth knowing before it surprises you — Simple Voice Chat
installs 2.5.28 (beta) rather than the newer 2.6.18, because 2.6.18 is an alpha. Anything below
a release carries its channel in the log.
GeyserMC and LuckPerms publish continuous builds and have no release channel at all, so their
latest build is what everyone runs, including from their own download pages.
When something goes wrong
- The jar is already installed → a warning, and the proxy starts with the version you have. A
source being down does not take your proxy down. - The jar is not there at all → the proxy refuses to start and says which plugin and why.
Older jars of the same plugin are deleted, including ones you put there by hand: two jars
claiming one plugin id make the loader refuse whichever it reads second. Every deletion is logged.
github entries are owner/repo; the owner cannot be left out. Geyser and Floodgate have their own
list rather than going under hangar, where their entry is only a link elsewhere with no file name,
version or checksum behind it.
A GitHub token
config/github.token is created empty for you. One line, nothing else.
It raises GitHub's limit from 60 requests an hour to 5000, but it does more than that: a private
repository, or a public one belonging to an account GitHub has flagged, answers 404 on its normal
download link with or without a token. Releases are fetched through the API instead, which serves
them normally when a token is present — so listing your own repository works even then.
A fine-grained token with no permissions at all is enough, since this reads nothing but public
releases. It is a separate file for the same reason the forwarding secret is: configurations get
pasted into issues and screenshots.
The rename
| The jar | HybridAuth-1.2.0.jar |
| The command | /hybridauth, with ha, hv, hybridvelocity and velocity still working |
| Permissions | hybridauth.command.*, with hybridvelocity.command.* and velocity.command.* still honoured |
| Configuration | config/HybridAuth.toml |
Permissions carry over including denials. A -velocity.command.server.lobby written long ago
still blocks. Any node saying no denies, and an explicit deny on the current node beats an older
grant.
config/
The configuration and the forwarding secret live in config/ now.
Upgrading needs nothing from you. Any earlier name is moved into place on the first start,
contents intact: hybridvelocity.toml, or upstream Velocity's velocity.toml, from config/ or
from beside the jar. Pointing this jar at an existing Velocity installation and starting it remains
the entire migration.
Your forwarding secret is moved, never regenerated. A fresh secret is accepted by the proxy
without complaint and rejected by every backend using modern forwarding, so the only symptom would
have been players being kicked with nothing in the log to explain it.
There is also a new hybridauth-config-version beside config-version. The fork was writing its
own numbers into upstream Velocity's key, which would have made a future Velocity migration believe
it had already run. Existing configurations are corrected on first start.
Upgrading from 1.1.2
Replace the jar and start it. Everything rearranges itself.
HybridAuth 1.1.2
Bedrock players are no longer asked to authenticate.
What changed
Anyone joining through GeyserMC has already been authenticated by Floodgate against Xbox Live.
Until now, offline authentication asked them for a password on top of that — a second password for
an identity somebody else had already verified, typed into a chat window that is awkward on a phone
or a controller. The proxy now leaves them alone.
This is not configurable, because there is no situation in which asking twice is the right
answer. Their security stays Geyser and Floodgate's business; keep Floodgate configured as you
would on any other proxy.
They are recognised two ways, and either is enough:
- Floodgate's API, which is authoritative and the only thing that recognises a Bedrock player
who has linked a Java account — linked players keep their real Java UUID, so nothing about
their identity looks like Bedrock. - The shape of the UUID, as a fallback: Floodgate leaves the top half of an unlinked player's
UUID at zero, which a Java offline UUID can never be.
The console says Floodgate detected; Bedrock players will skip offline authentication. the first
time the proxy has to decide about somebody.
Worth knowing
If Floodgate is installed but its API cannot be reached, the proxy logs a warning and falls back to
the UUID shape. That still covers unlinked Bedrock players, but a linked one would be asked to
register. The warning is there so you notice.
Upgrading from 1.1.1
Replace the jar. Nothing in your configuration changes.
HybridAuth 1.1.1
Upstream Velocity merged, the permissions and the main command named after the fork, and a clear
message instead of a crash when the Java version is wrong.
Named after the fork
The main command is now /hybridvelocity, with /hv and /velocity kept as aliases.
Permission nodes move from velocity.command.* to hybridvelocity.command.*. Nothing you have
already granted stops working: the old nodes are still honoured as a fallback, including negations —
a -velocity.command.server.lobby still blocks. Migrate when it suits you.
Java 25
The proxy has always required Java 25; the whole thing is compiled for it. Until now, starting on an
older runtime produced a bare UnsupportedClassVersionError naming an internal class. It now prints
what is wrong and what to do about it.
The getting-started guide has heap and collector settings worth using if you want the proxy to sit in
less memory.
Upstream
Merges five Velocity commits: a reference-counting fix for packets forwarded through
handleGeneric, JSpecify annotations exported at runtime, dependency bumps, and lmbda 3.0.0.
The jar is larger than 1.1.0 — upstream stopped trimming unused fastutil classes from the shaded jar
in its dependency-bump commit, and re-adding those exclusions would risk runtime failures that never
show up at build time. This is disk size, not memory: classes are only loaded when used.
Also
- The runnable jar drops the
-allsuffix. It isHybridVelocity-1.1.1.jar. - CI runs on JDK 25, which is what the artifacts actually require.
-Dvelocity.packet-decode-logging=trueis no longer a default JVM argument. It is a debug flag.
Upgrading from 1.1.0
Replace the jar. Configuration and permissions carry over untouched.
HybridAuth 1.1.0
Non-premium players can now join alongside premium ones, and are asked for a password before they
reach any of your servers.
Offline player authentication
A player Mojang cannot verify is no longer kicked. They get an offline identity and wait on an
authentication server that runs inside the proxy — nothing extra to install, configure or
monitor — until they register or log in. Premium players are untouched and see no prompt.
/register <password> <password>and/login <password>, then/changepasswordonce in.- Passwords are bcrypt hashes with a per-record salt, in an embedded SQLite database at
auth/player-passwords.db. Back that file up: it is the only copy. - While waiting, the command list is stripped to the single command that applies. Nothing from any
other plugin is listed or tab-completable, and every permission is denied. - Everything fails closed. If the database or the authentication server is unavailable, players are
refused rather than let through. - Three wrong passwords disconnect; so does 60 seconds of silence.
On by default. Set enabled = false under [offline-auth] for stock Velocity behaviour.
Per-server shortcut commands
List a server under comandos in [servers] and it gets a command named after it, so players type
/lobby instead of /server lobby. Available to everyone by default, restrictable per server with
velocity.command.server.<name>.
Renamed to the fork
- The configuration is
hybridvelocity.toml. An existingvelocity.tomlis renamed on first start
with its contents intact and migrated in place, so upgrading is just swapping the jar. - Both jars carry the fork name:
HybridVelocity-1.1.0-all.jaris the one you run.
Compatibility
Tested with ViaVersion, ViaBackwards, ViaRewind, Geyser and Floodgate. Plugins, API and performance
are unchanged from Velocity.
Upgrading from 1.0.0
Replace the jar and start. Note that offline authentication turns on: if you do not want it, set
enabled = false under [offline-auth] after the first start.
Known limitations
- No password recovery. A forgotten password needs an operator to delete the player's row.
- No IP-based account limit, and no rate limit on registration beyond the three-strike lockout.
- The authentication server needs a TCP port of its own on loopback (30065 by default); it cannot
share the proxy's.
Full documentation: docs/guide/
HybridAuth 1.0.0
First tagged release of HybridVelocity, a fork of Velocity.
Hybrid offline profiles on online-mode proxies
An online-mode proxy no longer disconnects players that Mojang does not recognise. When the
session server returns 204, the player is accepted with a .-suffixed username and an offline
UUID derived from that dotted name, so offline players can never collide with the premium
account of the same name. The player public key is dropped, since it belongs to the Mojang
account UUID and would break signed chat and commands.
See docs/hybrid-offline-profiles.md.
Per-server shortcut commands
Servers listed in the new comandos option inside [servers] get their own command named
after the server:
[servers]
Lobby = "127.0.0.1:30066"
Survival = "127.0.0.1:30067"
try = ["Lobby"]
comandos = ["Lobby", "Survival"]Players can then run /Lobby instead of /server Lobby. The commands are available to
everyone by default and can be restricted per server with
velocity.command.server.<name in lowercase>, using the same permissive tri-state check as
/server, so a permissions plugin can deny them explicitly. /velocity reload re-registers
them.
Planned
An offline register/login gate, specified in docs/update-plan.md. Not
implemented in this release.
Installation
Download HybridVelocity-1.0.0.jar and run it like any Velocity proxy. It generates a default
velocity.toml on first startup, and boots with:
[INFO]: Booting up HybridVelocity 1.0.0...
The bundled plugin API is still upstream Velocity
4.1.0-SNAPSHOT, so existing Velocity
plugins keep working unchanged.