3
0
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:
onebeastchris 2023-11-09 12:44:27 +01:00
Ursprung cdd2aba244
Commit 15b8b93d44
4 geänderte Dateien mit 21 neuen und 19 gelöschten Zeilen

Datei anzeigen

@ -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());
}
}
}

Datei anzeigen

@ -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);

Datei anzeigen

@ -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.");
}

Datei anzeigen

@ -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 + ")");
}
});
}