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:
Ursprung
27c1562438
Commit
5d06edd0d1
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren