soiz1's picture
Upload folder using huggingface_hub
d46f4a3 verified
package com.mojang.realmsclient.client;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
import com.mojang.logging.LogUtils;
import com.mojang.realmsclient.dto.WorldDownload;
import com.mojang.realmsclient.exception.RealmsDefaultUncaughtExceptionHandler;
import com.mojang.realmsclient.gui.screens.RealmsDownloadLatestWorldScreen;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.NbtException;
import net.minecraft.nbt.ReportedNbtException;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.validation.ContentValidationException;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.CountingOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
@OnlyIn(Dist.CLIENT)
public class FileDownload {
static final Logger LOGGER = LogUtils.getLogger();
volatile boolean cancelled;
volatile boolean finished;
volatile boolean error;
volatile boolean extracting;
@Nullable
private volatile File tempFile;
volatile File resourcePackPath;
@Nullable
private volatile HttpGet request;
@Nullable
private Thread currentThread;
private final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
private static final String[] INVALID_FILE_NAMES = new String[]{
"CON",
"COM",
"PRN",
"AUX",
"CLOCK$",
"NUL",
"COM1",
"COM2",
"COM3",
"COM4",
"COM5",
"COM6",
"COM7",
"COM8",
"COM9",
"LPT1",
"LPT2",
"LPT3",
"LPT4",
"LPT5",
"LPT6",
"LPT7",
"LPT8",
"LPT9"
};
public long contentLength(String p_86990_) {
CloseableHttpClient closeablehttpclient = null;
HttpGet httpget = null;
long i;
try {
httpget = new HttpGet(p_86990_);
closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
CloseableHttpResponse closeablehttpresponse = closeablehttpclient.execute(httpget);
return Long.parseLong(closeablehttpresponse.getFirstHeader("Content-Length").getValue());
} catch (Throwable throwable) {
LOGGER.error("Unable to get content length for download");
i = 0L;
} finally {
if (httpget != null) {
httpget.releaseConnection();
}
if (closeablehttpclient != null) {
try {
closeablehttpclient.close();
} catch (IOException ioexception) {
LOGGER.error("Could not close http client", (Throwable)ioexception);
}
}
}
return i;
}
public void download(WorldDownload p_86983_, String p_86984_, RealmsDownloadLatestWorldScreen.DownloadStatus p_86985_, LevelStorageSource p_86986_) {
if (this.currentThread == null) {
this.currentThread = new Thread(
() -> {
CloseableHttpClient closeablehttpclient = null;
try {
this.tempFile = File.createTempFile("backup", ".tar.gz");
this.request = new HttpGet(p_86983_.downloadLink);
closeablehttpclient = HttpClientBuilder.create().setDefaultRequestConfig(this.requestConfig).build();
HttpResponse httpresponse = closeablehttpclient.execute(this.request);
p_86985_.totalBytes = Long.parseLong(httpresponse.getFirstHeader("Content-Length").getValue());
if (httpresponse.getStatusLine().getStatusCode() == 200) {
OutputStream outputstream = new FileOutputStream(this.tempFile);
FileDownload.ProgressListener filedownload$progresslistener = new FileDownload.ProgressListener(
p_86984_.trim(), this.tempFile, p_86986_, p_86985_
);
FileDownload.DownloadCountingOutputStream filedownload$downloadcountingoutputstream = new FileDownload.DownloadCountingOutputStream(
outputstream
);
filedownload$downloadcountingoutputstream.setListener(filedownload$progresslistener);
IOUtils.copy(httpresponse.getEntity().getContent(), filedownload$downloadcountingoutputstream);
return;
}
this.error = true;
this.request.abort();
} catch (Exception exception1) {
LOGGER.error("Caught exception while downloading: {}", exception1.getMessage());
this.error = true;
return;
} finally {
this.request.releaseConnection();
if (this.tempFile != null) {
this.tempFile.delete();
}
if (!this.error) {
if (!p_86983_.resourcePackUrl.isEmpty() && !p_86983_.resourcePackHash.isEmpty()) {
try {
this.tempFile = File.createTempFile("resources", ".tar.gz");
this.request = new HttpGet(p_86983_.resourcePackUrl);
HttpResponse httpresponse1 = closeablehttpclient.execute(this.request);
p_86985_.totalBytes = Long.parseLong(httpresponse1.getFirstHeader("Content-Length").getValue());
if (httpresponse1.getStatusLine().getStatusCode() != 200) {
this.error = true;
this.request.abort();
return;
}
OutputStream outputstream1 = new FileOutputStream(this.tempFile);
FileDownload.ResourcePackProgressListener filedownload$resourcepackprogresslistener = new FileDownload.ResourcePackProgressListener(
this.tempFile, p_86985_, p_86983_
);
FileDownload.DownloadCountingOutputStream filedownload$downloadcountingoutputstream1 = new FileDownload.DownloadCountingOutputStream(
outputstream1
);
filedownload$downloadcountingoutputstream1.setListener(filedownload$resourcepackprogresslistener);
IOUtils.copy(httpresponse1.getEntity().getContent(), filedownload$downloadcountingoutputstream1);
} catch (Exception exception) {
LOGGER.error("Caught exception while downloading: {}", exception.getMessage());
this.error = true;
} finally {
this.request.releaseConnection();
if (this.tempFile != null) {
this.tempFile.delete();
}
}
} else {
this.finished = true;
}
}
if (closeablehttpclient != null) {
try {
closeablehttpclient.close();
} catch (IOException ioexception) {
LOGGER.error("Failed to close Realms download client");
}
}
}
}
);
this.currentThread.setUncaughtExceptionHandler(new RealmsDefaultUncaughtExceptionHandler(LOGGER));
this.currentThread.start();
}
}
public void cancel() {
if (this.request != null) {
this.request.abort();
}
if (this.tempFile != null) {
this.tempFile.delete();
}
this.cancelled = true;
}
public boolean isFinished() {
return this.finished;
}
public boolean isError() {
return this.error;
}
public boolean isExtracting() {
return this.extracting;
}
public static String findAvailableFolderName(String p_87002_) {
p_87002_ = p_87002_.replaceAll("[\\./\"]", "_");
for (String s : INVALID_FILE_NAMES) {
if (p_87002_.equalsIgnoreCase(s)) {
p_87002_ = "_" + p_87002_ + "_";
}
}
return p_87002_;
}
void untarGzipArchive(String p_86992_, @Nullable File p_86993_, LevelStorageSource p_86994_) throws IOException {
Pattern pattern = Pattern.compile(".*-([0-9]+)$");
int i = 1;
for (char c0 : SharedConstants.ILLEGAL_FILE_CHARACTERS) {
p_86992_ = p_86992_.replace(c0, '_');
}
if (StringUtils.isEmpty(p_86992_)) {
p_86992_ = "Realm";
}
p_86992_ = findAvailableFolderName(p_86992_);
try {
for (LevelStorageSource.LevelDirectory levelstoragesource$leveldirectory : p_86994_.findLevelCandidates()) {
String s1 = levelstoragesource$leveldirectory.directoryName();
if (s1.toLowerCase(Locale.ROOT).startsWith(p_86992_.toLowerCase(Locale.ROOT))) {
Matcher matcher = pattern.matcher(s1);
if (matcher.matches()) {
int j = Integer.parseInt(matcher.group(1));
if (j > i) {
i = j;
}
} else {
i++;
}
}
}
} catch (Exception exception1) {
LOGGER.error("Error getting level list", (Throwable)exception1);
this.error = true;
return;
}
String s;
if (p_86994_.isNewLevelIdAcceptable(p_86992_) && i <= 1) {
s = p_86992_;
} else {
s = p_86992_ + (i == 1 ? "" : "-" + i);
if (!p_86994_.isNewLevelIdAcceptable(s)) {
boolean flag = false;
while (!flag) {
i++;
s = p_86992_ + (i == 1 ? "" : "-" + i);
if (p_86994_.isNewLevelIdAcceptable(s)) {
flag = true;
}
}
}
}
TarArchiveInputStream tararchiveinputstream = null;
File file1 = new File(Minecraft.getInstance().gameDirectory.getAbsolutePath(), "saves");
try {
file1.mkdir();
tararchiveinputstream = new TarArchiveInputStream(new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(p_86993_))));
for (TarArchiveEntry tararchiveentry = tararchiveinputstream.getNextTarEntry();
tararchiveentry != null;
tararchiveentry = tararchiveinputstream.getNextTarEntry()
) {
File file2 = new File(file1, tararchiveentry.getName().replace("world", s));
if (tararchiveentry.isDirectory()) {
file2.mkdirs();
} else {
file2.createNewFile();
try (FileOutputStream fileoutputstream = new FileOutputStream(file2)) {
IOUtils.copy(tararchiveinputstream, fileoutputstream);
}
}
}
} catch (Exception exception) {
LOGGER.error("Error extracting world", (Throwable)exception);
this.error = true;
} finally {
if (tararchiveinputstream != null) {
tararchiveinputstream.close();
}
if (p_86993_ != null) {
p_86993_.delete();
}
try (LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = p_86994_.validateAndCreateAccess(s)) {
levelstoragesource$levelstorageaccess.renameAndDropPlayer(s);
} catch (NbtException | ReportedNbtException | IOException ioexception) {
LOGGER.error("Failed to modify unpacked realms level {}", s, ioexception);
} catch (ContentValidationException contentvalidationexception) {
LOGGER.warn("{}", contentvalidationexception.getMessage());
}
this.resourcePackPath = new File(file1, s + File.separator + "resources.zip");
}
}
@OnlyIn(Dist.CLIENT)
static class DownloadCountingOutputStream extends CountingOutputStream {
@Nullable
private ActionListener listener;
public DownloadCountingOutputStream(OutputStream p_193509_) {
super(p_193509_);
}
public void setListener(ActionListener p_87017_) {
this.listener = p_87017_;
}
@Override
protected void afterWrite(int p_87019_) throws IOException {
super.afterWrite(p_87019_);
if (this.listener != null) {
this.listener.actionPerformed(new ActionEvent(this, 0, null));
}
}
}
@OnlyIn(Dist.CLIENT)
class ProgressListener implements ActionListener {
private final String worldName;
private final File tempFile;
private final LevelStorageSource levelStorageSource;
private final RealmsDownloadLatestWorldScreen.DownloadStatus downloadStatus;
ProgressListener(
final String p_87027_, final File p_87028_, final LevelStorageSource p_87029_, final RealmsDownloadLatestWorldScreen.DownloadStatus p_87030_
) {
this.worldName = p_87027_;
this.tempFile = p_87028_;
this.levelStorageSource = p_87029_;
this.downloadStatus = p_87030_;
}
@Override
public void actionPerformed(ActionEvent p_87039_) {
this.downloadStatus.bytesWritten = ((FileDownload.DownloadCountingOutputStream)p_87039_.getSource()).getByteCount();
if (this.downloadStatus.bytesWritten >= this.downloadStatus.totalBytes && !FileDownload.this.cancelled && !FileDownload.this.error) {
try {
FileDownload.this.extracting = true;
FileDownload.this.untarGzipArchive(this.worldName, this.tempFile, this.levelStorageSource);
} catch (IOException ioexception) {
FileDownload.LOGGER.error("Error extracting archive", (Throwable)ioexception);
FileDownload.this.error = true;
}
}
}
}
@OnlyIn(Dist.CLIENT)
class ResourcePackProgressListener implements ActionListener {
private final File tempFile;
private final RealmsDownloadLatestWorldScreen.DownloadStatus downloadStatus;
private final WorldDownload worldDownload;
ResourcePackProgressListener(final File p_87046_, final RealmsDownloadLatestWorldScreen.DownloadStatus p_87047_, final WorldDownload p_87048_) {
this.tempFile = p_87046_;
this.downloadStatus = p_87047_;
this.worldDownload = p_87048_;
}
@Override
public void actionPerformed(ActionEvent p_87056_) {
this.downloadStatus.bytesWritten = ((FileDownload.DownloadCountingOutputStream)p_87056_.getSource()).getByteCount();
if (this.downloadStatus.bytesWritten >= this.downloadStatus.totalBytes && !FileDownload.this.cancelled) {
try {
String s = Hashing.sha1().hashBytes(Files.toByteArray(this.tempFile)).toString();
if (s.equals(this.worldDownload.resourcePackHash)) {
FileUtils.copyFile(this.tempFile, FileDownload.this.resourcePackPath);
FileDownload.this.finished = true;
} else {
FileDownload.LOGGER.error("Resourcepack had wrong hash (expected {}, found {}). Deleting it.", this.worldDownload.resourcePackHash, s);
FileUtils.deleteQuietly(this.tempFile);
FileDownload.this.error = true;
}
} catch (IOException ioexception) {
FileDownload.LOGGER.error("Error copying resourcepack file: {}", ioexception.getMessage());
FileDownload.this.error = true;
}
}
}
}
}