Skip to content

Implement Classic protocol support#248

Open
catfromplan9 wants to merge 1 commit intounmojang:masterfrom
catfromplan9:classic-protocol
Open

Implement Classic protocol support#248
catfromplan9 wants to merge 1 commit intounmojang:masterfrom
catfromplan9:classic-protocol

Conversation

@catfromplan9
Copy link
Contributor

Closes #247

Feel free to suggest any changes or make changes yourself, getMpPass is a made up route so it doesn't matter what it's called or the parameters (classic uses java web applets page where mppass is pre-filled), and this is the first time I have written anything significant in golang

@catfromplan9
Copy link
Contributor Author

catfromplan9 commented Feb 6, 2026

Should limit number of entries on servers map to 256 or some other reasonable number done

@catfromplan9
Copy link
Contributor Author

catfromplan9 commented Feb 6, 2026

I should also mention, this may have security or performance vulnerabilities since I am a golang novice. It isn't that much code to audit so hopefully things can be cleaned up easily.

For context, a typical classic server will usually on startup contact heartbeat and after the first reply it gets itll say along the lines of "You can join your server here:" followed by the link it got from heartbeat response body. I'm not really sure what to return on heartbeat endpoint since there is no server URL, thats a remnant of the old java web applets that classic was launched using and it'd plop you directly into the server within your browser when you went to the URL

@catfromplan9
Copy link
Contributor Author

Also should clean up the implementation of getting public IP from localhost, in situations where the drasl instance and server are running on the same system, calling an endpoint each time is not ideal.

Copy link
Member

@evan-goode evan-goode left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, would certainly be cool to say we support Classic. I'm skeptical whether this is the best way to do it though. Given that Java in the browser is dead, and some mod/agent is needed anyway to send requests to Drasl instead of minecraft.net, and this would require inventing a new endpoint, wouldn't it be simpler and more useful to mod Classic to do modern Yggdrasil auth? That way, Classic could Just Work in Fjord Launcher with authlib-injector authservers. (well, on my system Classic doesn't work too well, but maybe with some additional compatibility mods).

@catfromplan9
Copy link
Contributor Author

catfromplan9 commented Feb 20, 2026

Interesting, would certainly be cool to say we support Classic. I'm skeptical whether this is the best way to do it though. Given that Java in the browser is dead, and some mod/agent is needed anyway to send requests to Drasl instead of minecraft.net

Already done in Loki as of 2.2.1

and this would require inventing a new endpoint

Yes, getMpPass needs to be created. My launcher already implements this, and if you want I could add documentation to drasl for it.

wouldn't it be simpler and more useful to mod Classic to do modern Yggdrasil auth? That way, Classic could Just Work in Fjord Launcher with authlib-injector authservers. (well, on my system Classic doesn't work too well, but maybe with some additional compatibility mods).

This sorta defeats the point, the goal is to support vanilla. The user could apply a jarmod to backport yggdrasil protocol, but it'd be nice to support vanilla as well.

Classic does not work so well in Fjord Launcher either. I may at some point release my python CLI launcher which has functionality similar to betacraft and supports this route, but for Fjord I think we should probably wait on supporting this until the classic/indev versions are handled better, which is an open issue at the moment

@catfromplan9
Copy link
Contributor Author

I may be able to have getMpPass called by Loki if --mppass is unset and --server + --port is set, so it will just work when using Loki on client and server

@evan-goode
Copy link
Member

This sorta defeats the point, the goal is to support vanilla. The user could apply a jarmod to backport yggdrasil protocol, but it'd be nice to support vanilla as well.

Why?

IMO the goal should be to implement custom auth in a way that is elegant, secure, maintainable, interoperable, simple, etc. In recent versions of Minecraft, staying close to the Vanilla system is a pretty good strategy, maybe with a few additions specified by authlib-injector. But the Classic protocol is so exotic/obscure compared to Yggdrasil, has certain limitations (IP to connect to a MC server must match the IP from which the server initiates request to minecraft.net?), none of the major authservers implement it yet, and it's probably out of scope to be standardized in the authlib-injector spec.

I don't see how the heartbeat protocol would be better than doing Yggdrasil with Loki on Classic. Unless maybe you could serve the Classic client in the browser like old times at https://drasl.example.com/classic/play/a9a021709992b18501618569ea317cf5. Something like https://eaglercraft.com.

@catfromplan9
Copy link
Contributor Author

catfromplan9 commented Feb 23, 2026

Why?

IMO the goal should be to implement custom auth in a way that is elegant, secure, maintainable, interoperable, simple, etc. In recent versions of Minecraft, staying close to the Vanilla system is a pretty good strategy, maybe with a few additions specified by authlib-injector.

It's one route, 2 if including getMpPass. There shouldn't be much if any maintenance burden with adding it.

But the Classic protocol is so exotic/obscure compared to Yggdrasil, has certain limitations (IP to connect to a MC server must match the IP from which the server initiates request to minecraft.net?), none of the major authservers implement it yet, and it's probably out of scope to be standardized in the authlib-injector spec.

Yes its not in authlib-injector spec, but that's not a reason it can't be added to drasl. Some people use modded classic clients (afaik just c0.30) with MCGalaxy, which does support modern Yggdrasil, but if you want to play an arbitrary version this would be helpful, and there's not much reason not to is there? I'm not aware of any other API servers than blessingskin's yggdrasil plugin, but they are not really concerned with supporting older versions. Other API servers are free to implement the heartbeat and getMpPass routes if they would like, but i dont think theres much demand there (or here, for that matter). IMO the api server lacking heartbeat support is not the agent's problem. If the other API server implementations create unique APIs for getting mppass, I'll be willing to add support for that to Loki, but I would prefer they use getMpPass to save me the effort. Also, if people want to, they can of course mod the client for yggdrasil when using those other API servers and use mcgalaxy serverside.

I don't see how the heartbeat protocol would be better than doing Yggdrasil with Loki on Classic.

It's simply not possible, at least not easily. Doing that would require a complex transformer, assuming I find some sort of way to generate a shared serverId value that client and server will check with yggdrasil. I would also need to suppress failed heartbeat errors somehow. I guess we could md5sum the player name and use that as a server ID, if drasl accepts that? But then the problem is that the server simply routinely calls heartbeat, it doesnt call a route on player join which I can intercept, so id need to insert code there and I would also need to insert code on player login before joining server. Minecraft is obfuscated, this is pretty much impossible to do without writing a mod

The easiest way I can think of is continuing to use heartbeat, it would work flawlessly assuming you use Loki + drasl. Also, it serves to document the route and provide an implementation, which I find valuable in its own right. I did seriously consider finding a way to get the yggdrasil APIs to work in classic but I came to the above conclusion which is why I made this PR

Unless maybe you could serve the Classic client in the browser like old times at https://drasl.example.com/classic/play/a9a021709992b18501618569ea317cf5. Something like https://eaglercraft.com.

Yes, having this as a goal would be cool, but not at all necessary to get things working. We could implement a classic server list though, I think that would be cool. So, itd list the IP and port combos for all the classic servers pinging, kinda like how minecraft does, showing the name description player count etc.

@catfromplan9
Copy link
Contributor Author

I can contact someone about getting classic to run in the browser with JS, if you'd like

@catfromplan9
Copy link
Contributor Author

I may be able to have getMpPass called by Loki if --mppass is unset and --server + --port is set, so it will just work when using Loki on client and server

Done: unmojang/Loki@0657b31

Tested with Fjord Launcher and my own python launcher, works wonderfully 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Classic protocol support

2 participants