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

Fallback system - download the pack to serve the client in case cdn fails

Dieser Commit ist enthalten in:
onebeastchris 2023-10-18 12:06:42 +02:00
Ursprung 27c1562438
Commit 5d06edd0d1
3 geänderte Dateien mit 23 neuen und 58 gelöschten Zeilen

Datei anzeigen

@ -84,7 +84,7 @@ public class GeyserPathPackCodec extends PathPackCodec {
} }
@Override @Override
protected @NonNull ResourcePack create() { public @NonNull ResourcePack create() {
return ResourcePackLoader.readPack(this.path); return ResourcePackLoader.readPack(this.path);
} }

Datei anzeigen

@ -25,79 +25,54 @@
package org.geysermc.geyser.pack.url; package org.geysermc.geyser.pack.url;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
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.registry.loader.ResourcePackLoader; import org.geysermc.geyser.registry.loader.ResourcePackLoader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.SeekableByteChannel; import java.nio.channels.SeekableByteChannel;
import java.security.MessageDigest; import java.nio.file.Path;
import java.security.NoSuchAlgorithmException;
@RequiredArgsConstructor
public class GeyserUrlPackCodec extends UrlPackCodec { public class GeyserUrlPackCodec extends UrlPackCodec {
private final String url; private final String url;
private final String contentKey; private final String contentKey;
private final GeyserPathPackCodec fallback;
public GeyserUrlPackCodec(String url) { public GeyserUrlPackCodec(String url) {
this(url, "");
}
public GeyserUrlPackCodec(String url, String contentKey) {
this.url = url; this.url = url;
this.contentKey = ""; this.contentKey = contentKey;
this.fallback = new GeyserPathPackCodec(getCachePath(url));
}
private static Path getCachePath(String url) {
return ResourcePackLoader.downloadPack(url);
} }
@Override @Override
public byte @NonNull [] sha256() { public byte @NonNull [] sha256() {
try { return fallback.sha256();
URL resourcePackURL = new URL(this.url);
InputStream inputStream = resourcePackURL.openStream();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
digest.update(buffer, 0, bytesRead);
}
return digest.digest();
} catch (IOException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
} }
@Override @Override
public long size() { public long size() {
URLConnection conn = null; return fallback.size();
try {
conn = new URL(this.url).openConnection();
if(conn instanceof HttpURLConnection) {
((HttpURLConnection)conn).setRequestMethod("HEAD");
}
conn.getInputStream();
return conn.getContentLength();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if(conn instanceof HttpURLConnection) {
((HttpURLConnection)conn).disconnect();
}
}
} }
@Override @Override
public @NonNull SeekableByteChannel serialize(@NonNull ResourcePack resourcePack) throws IOException { public @NonNull SeekableByteChannel serialize(@NonNull ResourcePack resourcePack) throws IOException {
URL resourcePackURL = new URL(this.url); return fallback.serialize(resourcePack);
URLConnection connection = resourcePackURL.openConnection();
return (SeekableByteChannel) Channels.newChannel(connection.getInputStream());
} }
@Override @Override
protected @NonNull ResourcePack create() { @NonNull
return ResourcePackLoader.downloadPack(this.url, this.contentKey); public ResourcePack create() {
return fallback.create();
} }
@Override @Override

Datei anzeigen

@ -29,7 +29,6 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.event.lifecycle.GeyserLoadResourcePacksEvent; import org.geysermc.geyser.api.event.lifecycle.GeyserLoadResourcePacksEvent;
import org.geysermc.geyser.api.pack.ResourcePack; import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.api.pack.ResourcePackManifest;
import org.geysermc.geyser.event.type.GeyserDefineResourcePacksEventImpl; import org.geysermc.geyser.event.type.GeyserDefineResourcePacksEventImpl;
import org.geysermc.geyser.pack.GeyserResourcePack; import org.geysermc.geyser.pack.GeyserResourcePack;
import org.geysermc.geyser.pack.GeyserResourcePackManifest; import org.geysermc.geyser.pack.GeyserResourcePackManifest;
@ -190,26 +189,17 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
for (String url: cdnPacks) { for (String url: cdnPacks) {
GeyserImpl.getInstance().getLogger().info("Loading CDN pack " + url); GeyserImpl.getInstance().getLogger().info("Loading CDN pack " + url);
ResourcePack pack = downloadPack(url, ""); ResourcePack pack = new GeyserUrlPackCodec(url).create();
packMap.put(pack.manifest().header().uuid().toString(), pack); packMap.put(pack.manifest().header().uuid().toString(), pack);
} }
return packMap; return packMap;
} }
public static ResourcePack downloadPack(String url, String contentKey) throws IllegalArgumentException { public static Path downloadPack(String url) throws IllegalArgumentException {
int packHash = url.hashCode(); int packHash = url.hashCode();
Path cachedPath = GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("cdn-packs").resolve(packHash + ".zip"); Path cachedPath = GeyserImpl.getInstance().getBootstrap().getConfigFolder().resolve("cache").resolve("cdn-packs").resolve(packHash + ".zip");
WebUtils.downloadFile(url, cachedPath.toString()); WebUtils.downloadFile(url, cachedPath.toString());
ResourcePack temp = readPack(cachedPath); return cachedPath;
ResourcePackManifest manifest = temp.manifest();
try {
Files.delete(cachedPath);
} catch (IOException e) {
GeyserImpl.getInstance().getLogger().error("Could not delete cached pack", e);
}
return new GeyserResourcePack(new GeyserUrlPackCodec(url, contentKey), manifest, contentKey);
} }
} }