Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-20 15:00:11 +01:00
We need to ensure no invalid packs end up being loaded - otherwise, chaos ensues since the client will either show bogus resource pack size values (invalid sizes), or skip resource packs altogether (if not properly zipped).
Dieser Commit ist enthalten in:
Ursprung
cdd2aba244
Commit
15b8b93d44
@ -55,15 +55,13 @@ import org.geysermc.geyser.util.WebUtils;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.*;
|
||||
|
||||
public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
|
||||
private boolean networkSettingsRequested = false;
|
||||
private final Deque<String> packsToSent = new ArrayDeque<>();
|
||||
private final List<UUID> brokenResourcePacks = new ArrayList<>();
|
||||
|
||||
private SessionLoadResourcePacksEventImpl resourcePackLoadEvent;
|
||||
|
||||
@ -281,9 +279,13 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
// Check for packs that the client should normally download on its own. If the client cannot find the pack, we provide it instead.
|
||||
if (codec instanceof UrlPackCodec urlPackCodec) {
|
||||
if (!GameProtocol.isPre1_20_30(this.session)) {
|
||||
GeyserImpl.getInstance().getLogger().warning("Received a request for a remote pack that the client should have already downloaded!" +
|
||||
"Is the pack at the URL " + urlPackCodec.url() + " still available?");
|
||||
WebUtils.checkUrlAndDownloadRemotePack(urlPackCodec.url());
|
||||
// Ensure we don't a. spam console, and b. spam download/check requests
|
||||
if (!brokenResourcePacks.contains(packet.getPackId())) {
|
||||
brokenResourcePacks.add(packet.getPackId());
|
||||
GeyserImpl.getInstance().getLogger().warning("Received a request for a remote pack that the client should have already downloaded!" +
|
||||
"Is the pack at the URL " + urlPackCodec.url() + " still available?");
|
||||
WebUtils.checkUrlAndDownloadRemotePack(urlPackCodec.url());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import org.geysermc.geyser.registry.loader.ResourcePackLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class GeyserUrlPackCodec extends UrlPackCodec {
|
||||
private final String url;
|
||||
@ -80,16 +81,17 @@ public class GeyserUrlPackCodec extends UrlPackCodec {
|
||||
public ResourcePack create() {
|
||||
if (this.fallback == null) {
|
||||
try {
|
||||
this.fallback = new GeyserPathPackCodec(ResourcePackLoader.downloadPack(url).whenComplete((pack, throwable) -> {
|
||||
final Path downloadedPack = ResourcePackLoader.downloadPack(url).whenComplete((pack, throwable) -> {
|
||||
if (throwable != null) {
|
||||
GeyserImpl.getInstance().getLogger().error("Failed to download pack from " + url, throwable);
|
||||
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).join());
|
||||
}).join();
|
||||
this.fallback = new GeyserPathPackCodec(downloadedPack);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("Unable to download pack from " + url, e);
|
||||
throw new IllegalArgumentException("Failed to download pack from " + url, e);
|
||||
}
|
||||
}
|
||||
return ResourcePackLoader.readPack(this);
|
||||
|
@ -254,7 +254,7 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
|
||||
// Check if a "manifest.json" or "pack_manifest.json" file is located directly in the zip... does not work otherwise.
|
||||
// (something like MyZip.zip/manifest.json) will not, but will if it's a subfolder (MyPack.zip/MyPack/manifest.json)
|
||||
if (zip.getEntry("manifest.json") != null || zip.getEntry("pack_manifest.json") != null) {
|
||||
GeyserImpl.getInstance().getLogger().warning("The remote resource pack from " + url + " contains a manifest.json file at the root of the zip file. " +
|
||||
throw new IllegalArgumentException("The remote resource pack from " + url + " contains a manifest.json file at the root of the zip file. " +
|
||||
"This is not supported for remote packs, and will cause Bedrock clients to fall back to request the pack from the server. " +
|
||||
"Please put the pack file in a subfolder, and provide that zip in the URL.");
|
||||
}
|
||||
|
@ -115,12 +115,12 @@ public class WebUtils {
|
||||
|
||||
if (size <= 0) {
|
||||
GeyserImpl.getInstance().getLogger().error(String.format("Invalid size from remote pack URL: %s (size: %d)", url, size));
|
||||
//return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type == null || !type.equals("application/zip")) {
|
||||
GeyserImpl.getInstance().getLogger().error(String.format("Invalid application type from remote pack URL: %s (type: %s)", url, type));
|
||||
//return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream in = con.getInputStream();
|
||||
@ -129,17 +129,15 @@ public class WebUtils {
|
||||
|
||||
if (Files.size(fileLocation) != size) {
|
||||
GeyserImpl.getInstance().getLogger().error("Downloaded pack has " + Files.size(fileLocation) + " bytes, expected " + size + " bytes");
|
||||
//Files.delete(fileLocation);
|
||||
//return null;
|
||||
Files.delete(fileLocation);
|
||||
return null;
|
||||
}
|
||||
|
||||
return fileLocation;
|
||||
} catch (MalformedURLException e) {
|
||||
GeyserImpl.getInstance().getLogger().error("Malformed URL: " + url);
|
||||
return null;
|
||||
throw new IllegalArgumentException("Malformed URL: " + url);
|
||||
} catch (IOException e) {
|
||||
GeyserImpl.getInstance().getLogger().error("Unable to download and save file: " + url + ")");
|
||||
return null;
|
||||
throw new RuntimeException("Unable to download and save file: " + url + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren