3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-10-04 00:41:13 +02:00

Change fallback system

Dieser Commit ist enthalten in:
onebeastchris 2023-11-09 08:34:45 +01:00
Ursprung 36709143c7
Commit 498a415ac5
4 geänderte Dateien mit 46 neuen und 20 gelöschten Zeilen

Datei anzeigen

@ -282,7 +282,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
// TODO: Proper pack checking - could be that the remote url is offline, the pack changed, or.. something? // TODO: Proper pack checking - could be that the remote url is offline, the pack changed, or.. something?
GeyserImpl.getInstance().getLogger().warning("Received ResourcePackChunkRequestPacket for URL pack " + urlPackCodec.url()); GeyserImpl.getInstance().getLogger().warning("Received ResourcePackChunkRequestPacket for URL pack " + urlPackCodec.url());
WebUtils.checkRemotePackUrl(urlPackCodec.url()); WebUtils.checkUrlAndDownloadRemotePack(urlPackCodec.url());
} }
} }

Datei anzeigen

@ -27,6 +27,7 @@ package org.geysermc.geyser.pack.url;
import lombok.Getter; import lombok.Getter;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.pack.ResourcePack; import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.api.pack.UrlPackCodec; import org.geysermc.geyser.api.pack.UrlPackCodec;
import org.geysermc.geyser.pack.path.GeyserPathPackCodec; import org.geysermc.geyser.pack.path.GeyserPathPackCodec;
@ -39,7 +40,7 @@ public class GeyserUrlPackCodec extends UrlPackCodec {
private final String url; private final String url;
private final String contentKey; private final String contentKey;
@Getter @Getter
private final GeyserPathPackCodec fallback; private GeyserPathPackCodec fallback;
public GeyserUrlPackCodec(String url) throws IllegalArgumentException { public GeyserUrlPackCodec(String url) throws IllegalArgumentException {
this(url, ""); this(url, "");
@ -48,31 +49,49 @@ public class GeyserUrlPackCodec extends UrlPackCodec {
public GeyserUrlPackCodec(String url, String contentKey) throws IllegalArgumentException { public GeyserUrlPackCodec(String url, String contentKey) throws IllegalArgumentException {
this.url = url; this.url = url;
this.contentKey = contentKey; this.contentKey = contentKey;
try {
this.fallback = new GeyserPathPackCodec(ResourcePackLoader.downloadPack(url).get());
} catch (Exception e) {
throw new IllegalArgumentException("Unable to download pack from " + url, e);
}
} }
@Override @Override
public byte @NonNull [] sha256() { public byte @NonNull [] sha256() {
if (this.fallback == null) {
throw new IllegalStateException("Fallback pack not initialized! Needs to be created first.");
}
return fallback.sha256(); return fallback.sha256();
} }
@Override @Override
public long size() { public long size() {
if (this.fallback == null) {
throw new IllegalStateException("Fallback pack not initialized! Needs to be created first.");
}
return fallback.size(); return fallback.size();
} }
@Override @Override
public @NonNull SeekableByteChannel serialize(@NonNull ResourcePack resourcePack) throws IOException { public @NonNull SeekableByteChannel serialize(@NonNull ResourcePack resourcePack) throws IOException {
if (this.fallback == null) {
throw new IllegalStateException("Fallback pack not initialized! Needs to be created first.");
}
return fallback.serialize(resourcePack); return fallback.serialize(resourcePack);
} }
@Override @Override
@NonNull @NonNull
public ResourcePack create() { public ResourcePack create() {
if (this.fallback == null) {
try {
this.fallback = new GeyserPathPackCodec(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());
} catch (Exception e) {
throw new IllegalArgumentException("Unable to download pack from " + url, e);
}
}
return ResourcePackLoader.loadDownloadedPack(this); return ResourcePackLoader.loadDownloadedPack(this);
} }

Datei anzeigen

@ -230,16 +230,20 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
} }
public static CompletableFuture<@Nullable Path> downloadPack(String url) throws IllegalArgumentException { public static CompletableFuture<@Nullable Path> downloadPack(String url) throws IllegalArgumentException {
CompletableFuture<Path> future = WebUtils.checkRemotePackUrl(url); CompletableFuture<Path> future = WebUtils.checkUrlAndDownloadRemotePack(url);
AtomicReference<Path> pathAtomicReference = new AtomicReference<>();
future.whenCompleteAsync((cachedPath, throwable) -> { future.whenCompleteAsync((cachedPath, throwable) -> {
if (cachedPath == null || throwable != null) { if (cachedPath == null) {
return;
}
if (throwable != null) {
GeyserImpl.getInstance().getLogger().error("Failed to download resource pack " + url, throwable);
return; return;
} }
// Check if the pack is a .zip or .mcpack file // Check if the pack is a .zip or .mcpack file
if (!PACK_MATCHER.matches(cachedPath)) { if (!PACK_MATCHER.matches(cachedPath)) {
throw new IllegalArgumentException("Invalid pack! Not a .zip or .mcpack file."); throw new IllegalArgumentException("Invalid pack format! Not a .zip or .mcpack file.");
} }
try { try {
@ -258,10 +262,7 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
} catch (IOException e) { } catch (IOException e) {
throw new IllegalArgumentException(GeyserLocale.getLocaleStringLog("geyser.resource_pack.broken", url), e); throw new IllegalArgumentException(GeyserLocale.getLocaleStringLog("geyser.resource_pack.broken", url), e);
} }
pathAtomicReference.set(cachedPath);
}); });
return future;
return future.thenApplyAsync(x -> pathAtomicReference.get());
} }
} }

Datei anzeigen

@ -105,19 +105,25 @@ public class WebUtils {
* @param url The URL to check * @param url The URL to check
* @return Path to the downloaded pack file * @return Path to the downloaded pack file
*/ */
public static CompletableFuture<@Nullable Path> checkRemotePackUrl(String url) { public static CompletableFuture<@Nullable Path> checkUrlAndDownloadRemotePack(String url) {
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
try { try {
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection(); HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION);
int size = con.getContentLength(); int size = con.getContentLength();
String type = con.getContentType(); String type = con.getContentType();
InputStream in = con.getInputStream();
if (size < 1 || !type.equals("application/zip")) { if (size <= 0) {
GeyserImpl.getInstance().getLogger().error("Invalid resource pack: " + url + " (" + type + ", " + size + " bytes)"); 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;
}
InputStream in = con.getInputStream();
Path fileLocation = GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("remote_packs").resolve(url.hashCode() + ".zip"); Path fileLocation = GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("remote_packs").resolve(url.hashCode() + ".zip");
Files.copy(in, fileLocation, StandardCopyOption.REPLACE_EXISTING); Files.copy(in, fileLocation, StandardCopyOption.REPLACE_EXISTING);