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 sending CDN entries to Bedrock clients to download resource packs from #4205
base: master
Are you sure you want to change the base?
Conversation
- Deprecate GeyserLoadResourcePacksEvent in favor of GeyserDefineResourcePacksEvent - Load CDNentries properly
In the config I would use, probably, |
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.
just a quick review without much depth - and i agree with Camo.
it would be nice if ResourcePackCDNEntry
could be RemoteResourcePack
, but it doesn't implement ResourcePack
so... unsure about. the naming so far feels clunky tbh.
also consider using fastutil more, in the core module.
/** | ||
* Gets an unmodifiable list of {@link ResourcePackCDNEntry}s that will be sent to the client. | ||
* | ||
* @return an unmodifiable list of resource pack CDN entries that will be sent to the client. | ||
*/ | ||
public abstract @NonNull List<ResourcePackCDNEntry> cdnEntries(); |
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.
Its not like we have a formal style guide, but if the javadoc body is the same as the @return
tag, can we just have the return tag only?
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.
Makes sense, but this has been accepted before & i'd rather keep it consistent (or change all instances of that in api)
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.
RFC :P
and it exists elsewhere afaik
api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineResourcePacksEvent.java
Outdated
Show resolved
Hide resolved
api/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserLoadResourcePacksEvent.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/registry/loader/ResourcePackLoader.java
Outdated
Show resolved
Hide resolved
core/src/main/java/org/geysermc/geyser/registry/loader/ResourcePackLoader.java
Outdated
Show resolved
Hide resolved
…licate deprecation annotation
Yeah naming really isn't my strong suit, I agree. I kind of like RemotePack actually. |
How exactly are pack versions handled with this? Is it just pulled from the downloaded pack? What happens if the version of the pack at the link is updated while the server is running? |
We don't extract / need the pack version, just the pack UUID. Konica and I had a brief talk where he mentioned that possibility where a pack UUID might change mid-game. Possible solutions:
More generally, we'd need to find out what exactly the client would do in the event that the pack is provided and the one received in said pack mismatch. |
Hmm ok but then how does this work? Does this mean the client has to download the entire pack every time to check if the version changed? The normal ResourcePackStack and ResourcePacksInfo packets have a field for version. So does a CDN entry also require an entry in the normal Entry list and this just tells the client where it can download said pack? Or will the client just download a CDN entry and not check the version at all? I'm mainly wondering how this works if the user just adds an entry to their config for one of these. In this scenario you're saying we never have to know the pack version? |
After some testing:
|
Instead: - add UrlPackCodec & GeyserUrlPackCodec - try and provide the resource pack via a stream from the url - either because the client does not support packs via the url, or because it failed to get the packs
…t, since it seems to work without it !?
…haos ensues since the client will either show bogus resource pack size values (invalid sizes), or skip resource packs altogether (if not properly zipped).
From more testing locally, here's what i found:
Further, the resource pack can be either a If anyone wishes to test this PR, you can set up a working file server using caddy and the following config - please do not use it in production, it doesnt even use https.
It however would ensure correct content type/content lengths being set. On a positive note, downloading even a 100MB pack is insanely quick! |
Is it possible we can make a website that tests if a website hosting a pack is working correctly? We can also bundle such functionality in Geyser, but a website means it would be applicable to a wider Bedrock audience. |
Said functionality would already be bundled in this PR :) |
OK, neat. We should add to the config comment that you should expect your pack to be analyzed/downloaded within Geyser. |
Well, we basically have to download it. We need to include the pack in the same resource pack stack packet, and we need to get the UUID/version for it. |
# Conflicts: # core/src/main/java/org/geysermc/geyser/configuration/GeyserConfiguration.java # core/src/main/java/org/geysermc/geyser/network/UpstreamPacketHandler.java
- better exception catching - proper error handling - caching of packs if size, etag, and last modified are the same
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.
Looks fine for the most part, just one small thing
contentKey = Files.exists(keyFile) ? Files.readString(keyFile, StandardCharsets.UTF_8) : ""; | ||
} catch (IOException e) { | ||
GeyserImpl.getInstance().getLogger().error("Failed to read content key for resource pack " + path.getFileName(), e); | ||
contentKey = ""; |
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.
See above
* @return the encryption key of the resource pack | ||
*/ | ||
@NonNull | ||
public abstract String contentKey(); |
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.
I personally don't like empty strings, can we make contentKey null when there is no contentKey?
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.
https://github.com/GeyserMC/Geyser/blob/master/api/src/main/java/org/geysermc/geyser/api/pack/ResourcePack.java#L54-L60
Not against it; however, this is already being done the same way for other resource packs - i'd rather keep it consistent.
Since 1.20.30, it is possible to send clients a link to download a resource pack from - instead of having to add the pack to Geyser's pack folder. This should help with proxy networks & overall traffic usage, as now resource intensive pack sending can be offloaded to a designated location. However, unlike on Java, it is possible to send multiple entries for the client to load packs from!
Notes:
Or, an extension/a plugin could manually query the Bedrock client version and add either a link, or a pack (depending on version).Update: If the client fails at getting the packs from the url, or does not support the entries, it will request the packs the old way.Changes:
GeyserUrlPackCodec
(andUrlPackCodec
for api) that can create a pack based on url + content keyresource-pack-urls
entry in the config for remote packsRFC:
Should users be able to set pack encryption keys for the url's in the config?No, users should use api instead for that.What should be done if the link stops working (e.g. because packs do not actually provide the correct pack anymore? Should Geyser then attempt to reload all packs (or just the remote packs)?Geyser will then serve the cached pack, and re-run a check of the url once - and warn about it.We can detect it if the client sends a
ResourcePackChunkRequestPacket
- if the pack requested there is one with the UrlPackCodec, we can assume that either1. the client does not support remote packto my knowledge , all platforms now do, or that 2. the remote pack changed/an error occurred/etc and that Geyser might want to re-check it.However, it is not currently possible to modify registry contents, which makes that a bit more challenging.
Should Geyser download the remote packs once and provide that, or should Geyser rather try and get it directly from the url?We'll be downloading the pack once, and cache it to avoid unnecessary re-downloadsTODO:
Would close #4060 - atleast the resource pack part.