Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mixin implementation #869

Open
66Leo66 opened this issue Aug 3, 2022 · 10 comments
Open

Mixin implementation #869

66Leo66 opened this issue Aug 3, 2022 · 10 comments
Labels
enhancement New feature or change request

Comments

@66Leo66
Copy link

66Leo66 commented Aug 3, 2022

Can we implement the function like how the fabric mod EasyAuth does?

That is, keep server in online-mode, and do some mixin injection to allow offline players to join.

@66Leo66 66Leo66 added the enhancement New feature or change request label Aug 3, 2022
@games647 games647 changed the title Another implementation of auto-login Mixin implementation Aug 3, 2022
@games647
Copy link
Owner

games647 commented Aug 3, 2022

Really good idea, because it would also improve the compatibility with other projects as it hooks directly in the Spigot code. So we could also fire normal join events.

However I don't know how good we could integrate a Mixin solution to the supported platforms: Spigot, Bungee and Velocity. Fabric includes the Mixin support from the start (and also Sponge has support for it). These do integrate a custom loader, but our supported platforms do not.
Years ago, we also thought about depending only on ProtocolSupport. They re-implement the vanilla code and replace the login classes during runtime. There they could also fire vanilla events, but server software specific optimizations in forks would be replaced too.

@66Leo66
Copy link
Author

66Leo66 commented Aug 3, 2022

Can we use ProtocolLib to do with protocol or packet? This (allow non-premium users with online-mode=true) seems only some login-protocol stuff and ProtocolLib should be able to deal with it (I haven't checked their doc yet). In this way we don't need to modify the game on our own.

@games647
Copy link
Owner

games647 commented Aug 3, 2022

This (allow non-premium users with online-mode=true) seems only some login-protocol stuff and ProtocolLib should be able to deal with it

Setting the server in onlinemode means that all client requests will be answered with authentication requests. Reverting back to offline mode is difficult, because we would need to cancel these outgoing requests and also answer them correctly to the server with fake data. Especially the last part is difficult, because the server would verify the data. Therefore requires to disabling/intercepting the Mojang check and furthermore disable the network encryption.

Although difficult, it could be possible. This then fires the normal vanilla events, but there also the topic about hybrid onlinemode servers. What led to requiring offlinemode is that there are plugins and server features that check for the onlinemode. If enabled, they perform a Mojang API lookup. This is not valid for the offline players, playing on it. Offline mode seems to be better choice in our opinion.

Nevertheless, I'm interested in what you think.

@games647
Copy link
Owner

games647 commented Aug 3, 2022

So what might work is an simulating Bukkit.getOnlineMode() -> true only for the LoginListener of Spigot. Although this seems to very difficult and potentially breaking.

@66Leo66
Copy link
Author

66Leo66 commented Aug 3, 2022

Could we modify PlayerLoginEvent and re-implement the Premium auth which is just some sort of HTTPs request, and cancel the original event to prevent offline players from being kicked?

@games647
Copy link
Owner

games647 commented Aug 3, 2022

Spigot fires no event before sending the Encryption_Begin packet. So there nothing to cancel. AsyncPlayerPreLoginEvent runs for example after it has been sent. Re-implement Mojang endpoint is possible although difficult, because you would need to match request to the fake endpoint. Furthermore as explained, Spigot then enables encryption for onlinemode connections, which also needs to be disabled.

Then we also have the mixed onlinemode issue explained above.

@66Leo66
Copy link
Author

66Leo66 commented Aug 3, 2022

Spigot fires no event before sending the Encryption_Begin packet. So there nothing to cancel. AsyncPlayerPreLoginEvent runs for example after it has been sent. Re-implement Mojang endpoint is possible although difficult, because you would need to match request to the fake endpoint. Furthermore as explained, Spigot then enables encryption for onlinemode connections, which also needs to be disabled.

Then we also have the mixed onlinemode issue explained above.

ProtocolLib seemed to support handling login start packets. And I didn't see EasyAuth do with encryptions explicitly so maybe we don't need to as well. Their technical details are at here.

I couldn't understand why we need to make a "fake endpoint". My meaning was to talk to real auth server to confirm premium users and have them logged in through the normal procedure while skip online auth for offline players and log them in directly (by canceling some packets and sending PACKET_SUCCESS or something). All these should be able to be done after we got LOGIN_START packet.

If enabled, they perform a Mojang API lookup.

As long as we can handle player profile stuff correctly at Bukkit side, nothing should go wrong, for plugins seldom communicate with Mojang servers directly (I guess).

@games647
Copy link
Owner

games647 commented Aug 3, 2022

BTW to prevent any conflicts I always meant cancelling server-side (server -> client) packets to this point.

ProtocolLib seemed to support handling login start packets.

Yes they do, but we need to handle the logic behind it. This means cancelling the packets and somehow answer it with a valid reply. It's similar to the current behavior, but onlinemode=true in the server.properties makes it more complicated. In offline-mode authentication, some login steps are just skipped, which makes a re-implementation of those easier.

The big issue is how can we bypass the verification in the server implementation if it expects onlinemode without support of Mixins? Once that's solved, we also need a way to revert the changes made for onlinemode like the fact that in onlinemode all following packets are encrypted (not the case in offlinemode).

The current behavior is:

  • Handle the login logic ourself
  • Re-supply a start packet
  • Fake the UUID based on Spigot's BungeeCord support
  • Enable encryption

All these steps involve our own implementation or existing separate methods. So we only need to call methods (enableEncryption(...)) and change fields (spoofUUID). This all possible from an external view.

And I didn't see EasyAuth do with encryptions explicitly so maybe we don't need to as well.

Yes, because they could use Mixins. Therefore we could access internal data and intercept the incoming method call. How can we do that without Mixin?

Onlinemode:
https://github.com/NikitaCartes/EasyAuth/blob/a44984a708e4779ab835bff64bb99e557511bb29/src/main/java/xyz/nikitacartes/easyauth/mixin/ServerLoginNetworkHandlerMixin.java#L71

Offline:
https://github.com/NikitaCartes/EasyAuth/blob/a44984a708e4779ab835bff64bb99e557511bb29/src/main/java/xyz/nikitacartes/easyauth/mixin/ServerLoginNetworkHandlerMixin.java#L94

I couldn't understand why we need to make a "fake endpoint".

Yes, but how would skip it without Mixins? Cancelling the packets won't work, because the server still expects a valid answer to its request.

As long as we can handle player profile stuff correctly at Bukkit side, nothing should go wrong

How do you expect we do that? Intercepting the API requests, because the server has implementations like these: https://github.com/PaperMC/Paper/blob/7044a9c538edb16239a0579722968d395842cdbe/patches/server/0102-Add-setting-for-proxy-online-mode-status.patch#L52

We would need to change/replace them too.

@games647 games647 added the awaiting answer Waiting on issuer answer label Aug 9, 2022
@66Leo66
Copy link
Author

66Leo66 commented Aug 14, 2022

I'm sorry that my knowledge of plugin development is very shallow, so it's difficult to discuss more in-depth about specific implementations and compatibility. Thank you for taking the time to discuss this with me, and I look forward to this feature being implemented or partially supported in the future.

@games647 games647 removed the awaiting answer Waiting on issuer answer label Aug 15, 2022
@SzczurekYT
Copy link
Contributor

Maybe this could be used: https://github.com/vectrix-space/ignite
It's a wrapper around the server jar, to let you use mixins.
The plugin could have two versions: the normal one, that we have today, and another one using this lib for these user that are willing to setup their server to use mixins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or change request
Projects
None yet
Development

No branches or pull requests

3 participants