-
-
Notifications
You must be signed in to change notification settings - Fork 686
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
Implement support for Minecraft Education Edition 1.12.60 #536
Conversation
connector/src/main/java/org/geysermc/connector/utils/SkinUtils.java
Outdated
Show resolved
Hide resolved
Stuff To Do (possibly not impacting this PR though):
|
My docs for signedToken are wrong. You have to:
The token format is: UUID|DATESTAMP|SIGNATURE and mine was 356 characters long. It may be worth writing a small tool that can pull this from a single MCEE device or even just doing the full authentication loop to grab it down real-time. NOTE: Treat this token as private though its not really too bad if it gets accidently leaked (you would only be able to accept connections from MCEE in the same tenancy on that port and would not have access to the users details nor be able to use the token to do anything with the account). However I may have missed a security implication. |
Mappings are pretty much done. Comparison screenshot: Blocks with no documented DV I've recorded at https://github.com/bundabrg/mappings-education/issues/3 to work out. Pause screen bug is very likely skin related. It's sending the skins of all the players and the client probably only decodes it when displaying the escape screen. |
Also the player logs in with their tenant username. So likely need a config variable that allows someone to prefix connections coming in from this port or even a regex pattern that gives server owners control over how to mangle the username. |
5d73c2f
to
7c20e94
Compare
Some changes:
New config looks like this: bedrock:
# The IP address that will listen for connections
address: 0.0.0.0
# The port that will listen for connections
port: 19132
# The MOTD that will be broadcasted to Minecraft: Bedrock Edition clients
motd1: "GeyserMC"
motd2: "Another GeyserMC forced host."
# Edition - bedrock or education
edition: bedrock
# Version - Version number or latest for latest
version: latest
# Settings for education edition
education:
# Education edition requires a signed token. You can retrieve this by running an edu-friendly ProxyPass
# between two MCEE devices and copying the 'jwt' from the ServerToClientHandshakePacket (everything after jwt=
# and before the closing brace into the 'encoded' box at https://jwt.io. From the decoded side copy the
# value of "signedToken" into this config entry. It should be in the format UUID|UUID|DATESTAMP|SIGNATURE.
# The token only allows clients in the same Tenant to connect. Ignore this when not using Education Mode.
# NOTE this token will expire after 2 weeks so this will be replaced by proper authentication in the
# near future.
token: dead...beef |
So is your current code aiming for multiple versions of Bedrock connecting at the same time? |
No, that would be too tricky with all the static classes and how intermingled everything is. That would require a major refactor. I did look at that and started interfacing everything out but its a big job. I opted for going half way, supporting multiple versions but one per running instance. If you want to run multiple versions you just spin up multiple Geysers with different config.yml settings on different ports. Thats how I do it (I have bedrock on port 19133, and education on port 19132) |
I think the config option for it is fine, its unlikely there will be people that want to support both editions at the same time |
If they do they can have multiple instances |
It could work, but not sure how many changes would be needed. It might be the case of renaming the bootstrap class for the second one and recompiling it. |
I think that if people have an option to support both that they will do that. |
The only possibly reason would be when its not standalone as you can't run multiple plugins of the same name. Due to how Bukkits ClassLoader works the plugins are not isolated so you'd have to shade it into a new path as well. So you could in theory just recompile a second plugin shaded with a different path. I can't imagine you'd need more than 2 really.
|
Something interesting that may be of interest to someone in the future. It technically is probably possible to support multiple versions/editions on the same port. Unconnected Pings can be flooded for every version (btw this should be disabled for serverhosts who likely don't want useless broadcasts) and when a player connects they send their protocol version first in the LoginPacket This would require eliminating any static calls that have protocol side-effects and have all references via the GeyserSession which would hold the version class with references. Not something I'm aiming for here but certainly achievable and my changes here make it easier to implement. |
Latest change allows the following:
The way it works is that the tokens.yml file contains a list of OAuth2 refresh token for each tenant. When a signedToken is older than 7 days it is renewed, along with the refreshToken, automatically and the new refreshToken written back to this file. The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure on why a lot of this commit was needed as it seems to change a lot of unnecessary things
2947e1b
...ain/java/org/geysermc/connector/network/translators/inventory/PlayerInventoryTranslator.java
Outdated
Show resolved
Hide resolved
...java/org/geysermc/connector/network/translators/inventory/updater/ChestInventoryUpdater.java
Outdated
Show resolved
Hide resolved
.../main/java/org/geysermc/connector/network/translators/item/translators/BannerTranslator.java
Outdated
Show resolved
Hide resolved
.../main/java/org/geysermc/connector/network/translators/item/translators/PotionTranslator.java
Outdated
Show resolved
Hide resolved
Also noticed you changed the submodule locations to be version-specific, we shouldn't do this as we should always support 1 version of bedrock which should be the latest. Having the different edition folders is fine though. |
Happy to drop the version part (I agree its not worth having versioned mappings yet). It was more POC to show that its easy to do and should Bedrock servers start having versioned maps easy enough to implement later anyway. |
Rebased on top of master and I took the opportunity to refactor and try reduce number of changes files. Main Changes:
|
# Conflicts: # connector/src/main/resources/bedrock/mappings
# Conflicts: # connector/src/main/java/org/geysermc/connector/entity/FallingBlockEntity.java # connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java
Just chipping in as someone from a tertiary education institution exploring Minecraft as a remote-learning education tool: yes, we would absolutely love true cross platform. There's alot of roadblocks because different stakeholders (faculty, students and IT staff) all want to use different editions for different reasons (for example, licensing EE is easier, but god forbid any kind of remote multiplayer). Keeping the backend game servers on Java while allowing any clients to connect via proxies will achieve the perfect balance of flexibility (Spigot programming to add just about anything) and client coverage. |
Closes #4
Update legacy_block_ids.json
# Conflicts: # connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java # connector/src/main/resources/mappings
# Conflicts: # connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java # connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java
# Conflicts: # connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java
# Conflicts: # connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java
# Conflicts: # connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java # connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockBlockPickRequestPacketTranslator.java # connector/src/main/java/org/geysermc/connector/network/translators/inventory/AnvilInventoryTranslator.java # connector/src/main/java/org/geysermc/connector/network/translators/item/ToolItemEntry.java # connector/src/main/resources/mappings
Just adding a note that I'll be working on implementing MCEE support through a GeyserPlugin instead as I believe it may be easier to maintain long term. Once I have something stable I'll likely close this and link the plugin instead. This may also indirectly help support multiple Bedrock versions as the plugin allows detecting the codec version and implementing a version specific translation layer. |
Do you think adding support via BedrockBackwards would work? |
Closing this in favour of the plugin. I'll provide a quick summary here: I've now published a release of a native geyser plugin GeyserReversion. This provides support for multiversion support in Geyser as well though for now it primarily provides support for Minecraft Education v1.14.31. This will require a build of Geyser that supports plugins. You can find one here: GeyserReversion: Quickstart:
For the devs: This works by providing a chain of translation layers to translate from the client to the server. Each layer is responsible for handling packets in their section and is able to inject new packets if needed. A good example is that any crafting inventory transactions require the layer to cache part of some packets and combine them with some later packets so each layer has to retain some state. We also provide some helpers to allow easier mappings for blocks, items, enchantments whilst taking care to name them correctly etc. Please report bugs using this plugin to the Github link here and not to Geyser issues unless its reproducible without the plugin enabled. In answer to support in BedrockBackwards unfortunately the work to get translation between layers and full state between each was greater than creating the code to simply extend BedrockServer and provide it as a pure library. The library can be found at https://github.com/bundabrg/Reversion though I've not yet had a chance to work on its documentation yet, |
Overview
This provides the following:
Notes
config.yml
is changed to allow you to select the edition of the bedrock listener. If you wish to support multiple versions at the same time you will need to run multiple copies of GeyserMC with differentconfig.yml
filesChanges
tokens.yml
Screenshots
Screenshot from MCEE 1.12.16 to 1.15.2 PaperMC server through both ProxyPass and GeyserMC: -
How to host Minecraft Education
The main differences we are interested in between MCEE and MCPE is:
Point 2 means that the server must have a valid token for a client to connect otherwise the client will fail with an error indicating that the server is not allowed to be access.
Generating a new Tenant Token
When a new MCEE tenant needs to be added use the following command:
This will provide a URL that must be copy and pasted into your web browser. It starts an OAuth2 authorization flow and allows you to log into your account. Once logged in you will just get a blank page with an address in your address bar. Copy this whole address into the next step.
Now enter the following command:
This will go obtain the token and automatically save to
tokens.yml
.The same user, and anyone else in the same tenant, can now log into the server. Multiple tenants are supported.
At no time does the server itself ever get access to the password of the user. It only gets access to an OAuth2 token that grants it access to specific minecraft resources and can renew this token indefinitely. If the user changes their password then the OAUTH token will be revoked.
Example Config
Issues
Getting the inital token is a little messy. Maybe a better way can be implemented.Todo
Bugs