@@ -24,7 +24,6 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
|
|||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
import org.jackhuang.hmcl.task.TaskExecutor;
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.util.Charsets;
|
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
import org.jackhuang.hmcl.util.VersionNumber;
|
import org.jackhuang.hmcl.util.VersionNumber;
|
||||||
|
|
||||||
@@ -35,6 +34,8 @@ import java.util.List;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
@@ -79,7 +80,7 @@ public class NewFileUpgrader extends IUpgrader {
|
|||||||
File file = new File(realPath);
|
File file = new File(realPath);
|
||||||
realPath = file.getAbsolutePath();
|
realPath = file.getAbsolutePath();
|
||||||
try {
|
try {
|
||||||
realPath = java.net.URLDecoder.decode(realPath, Charsets.DEFAULT_CHARSET.name());
|
realPath = java.net.URLDecoder.decode(realPath, UTF_8.name());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
|
|||||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilSession;
|
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilSession;
|
||||||
import org.jackhuang.hmcl.game.Arguments;
|
import org.jackhuang.hmcl.game.Arguments;
|
||||||
import org.jackhuang.hmcl.task.GetTask;
|
import org.jackhuang.hmcl.task.GetTask;
|
||||||
import org.jackhuang.hmcl.util.Charsets;
|
|
||||||
import org.jackhuang.hmcl.util.ExceptionalSupplier;
|
import org.jackhuang.hmcl.util.ExceptionalSupplier;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.NetworkUtils;
|
import org.jackhuang.hmcl.util.NetworkUtils;
|
||||||
@@ -34,6 +33,8 @@ import java.util.Base64;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
public class AuthlibInjectorAccount extends YggdrasilAccount {
|
public class AuthlibInjectorAccount extends YggdrasilAccount {
|
||||||
private final String serverBaseURL;
|
private final String serverBaseURL;
|
||||||
private final ExceptionalSupplier<String, ?> injectorJarPath;
|
private final ExceptionalSupplier<String, ?> injectorJarPath;
|
||||||
@@ -69,7 +70,7 @@ public class AuthlibInjectorAccount extends YggdrasilAccount {
|
|||||||
Arguments arguments = Arguments.addJVMArguments(null, arg);
|
Arguments arguments = Arguments.addJVMArguments(null, arg);
|
||||||
|
|
||||||
if (flag.get())
|
if (flag.get())
|
||||||
arguments = Arguments.addJVMArguments(arguments, "-Dorg.to2mbn.authlibinjector.config.prefetched=" + new String(Base64.getEncoder().encode(getTask.getResult().getBytes()), Charsets.UTF_8));
|
arguments = Arguments.addJVMArguments(arguments, "-Dorg.to2mbn.authlibinjector.config.prefetched=" + new String(Base64.getEncoder().encode(getTask.getResult().getBytes()), UTF_8));
|
||||||
|
|
||||||
return info.setArguments(arguments);
|
return info.setArguments(arguments);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -19,12 +19,13 @@ package org.jackhuang.hmcl.auth.offline;
|
|||||||
|
|
||||||
import org.jackhuang.hmcl.auth.AccountFactory;
|
import org.jackhuang.hmcl.auth.AccountFactory;
|
||||||
import org.jackhuang.hmcl.auth.CharacterSelector;
|
import org.jackhuang.hmcl.auth.CharacterSelector;
|
||||||
import org.jackhuang.hmcl.util.DigestUtils;
|
|
||||||
import org.jackhuang.hmcl.util.UUIDTypeAdapter;
|
import org.jackhuang.hmcl.util.UUIDTypeAdapter;
|
||||||
|
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.DigestUtils.digest;
|
||||||
|
import static org.jackhuang.hmcl.util.Hex.encodeHex;
|
||||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,7 +57,7 @@ public class OfflineAccountFactory extends AccountFactory<OfflineAccount> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String getUUIDFromUserName(String username) {
|
private static String getUUIDFromUserName(String username) {
|
||||||
return DigestUtils.md5Hex(username);
|
return encodeHex(digest("MD5", username));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import java.net.Proxy;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
public class YggdrasilService {
|
public class YggdrasilService {
|
||||||
|
|
||||||
private final YggdrasilProvider provider;
|
private final YggdrasilProvider provider;
|
||||||
@@ -99,7 +101,7 @@ public class YggdrasilService {
|
|||||||
|
|
||||||
return Optional.ofNullable(profile.getProperties())
|
return Optional.ofNullable(profile.getProperties())
|
||||||
.map(properties -> properties.get("textures"))
|
.map(properties -> properties.get("textures"))
|
||||||
.map(encodedTextures -> new String(Base64.getDecoder().decode(encodedTextures), Charsets.UTF_8))
|
.map(encodedTextures -> new String(Base64.getDecoder().decode(encodedTextures), UTF_8))
|
||||||
.map(Lang.liftFunction(textures -> fromJson(textures, TextureResponse.class)))
|
.map(Lang.liftFunction(textures -> fromJson(textures, TextureResponse.class)))
|
||||||
.map(TextureResponse::getTextures);
|
.map(TextureResponse::getTextures);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.jackhuang.hmcl.game.AssetObject;
|
|||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.DigestUtils;
|
|
||||||
import org.jackhuang.hmcl.util.FileUtils;
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
import org.jackhuang.hmcl.util.NetworkUtils;
|
import org.jackhuang.hmcl.util.NetworkUtils;
|
||||||
@@ -35,6 +34,9 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.DigestUtils.digest;
|
||||||
|
import static org.jackhuang.hmcl.util.Hex.encodeHex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
@@ -91,7 +93,7 @@ public final class GameAssetDownloadTask extends Task {
|
|||||||
try {
|
try {
|
||||||
// check the checksum of file to ensure that the file is not need to re-download.
|
// check the checksum of file to ensure that the file is not need to re-download.
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
String sha1 = DigestUtils.sha1Hex(FileUtils.readBytes(file));
|
String sha1 = encodeHex(digest("SHA-1", FileUtils.readBytes(file)));
|
||||||
if (sha1.equals(assetObject.getHash())) {
|
if (sha1.equals(assetObject.getHash())) {
|
||||||
++downloaded;
|
++downloaded;
|
||||||
Logging.LOG.finest("File $file has been downloaded successfully, skipped downloading");
|
Logging.LOG.finest("File $file has been downloaded successfully, skipped downloading");
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
|
|||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.*;
|
import org.jackhuang.hmcl.util.*;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.DigestUtils.digest;
|
||||||
|
import static org.jackhuang.hmcl.util.Hex.encodeHex;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -77,7 +80,7 @@ public final class LibraryDownloadTask extends Task {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
byte[] fileData = FileUtils.readBytes(libPath);
|
byte[] fileData = FileUtils.readBytes(libPath);
|
||||||
boolean valid = checksums.contains(DigestUtils.sha1Hex(fileData));
|
boolean valid = checksums.contains(encodeHex(digest("SHA-1", fileData)));
|
||||||
if ((!valid) && (libPath.getName().endsWith(".jar"))) {
|
if ((!valid) && (libPath.getName().endsWith(".jar"))) {
|
||||||
}
|
}
|
||||||
return validateJar(fileData, checksums);
|
return validateJar(fileData, checksums);
|
||||||
@@ -98,7 +101,7 @@ public final class LibraryDownloadTask extends Task {
|
|||||||
hashes = new String(eData, Charset.forName("UTF-8")).split("\n");
|
hashes = new String(eData, Charset.forName("UTF-8")).split("\n");
|
||||||
}
|
}
|
||||||
if (!entry.isDirectory()) {
|
if (!entry.isDirectory()) {
|
||||||
files.put(entry.getName(), DigestUtils.sha1Hex(eData));
|
files.put(entry.getName(), encodeHex(digest("SHA-1", eData)));
|
||||||
}
|
}
|
||||||
entry = jar.getNextJarEntry();
|
entry = jar.getNextJarEntry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,14 @@ package org.jackhuang.hmcl.game;
|
|||||||
|
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
import org.apache.commons.compress.archivers.zip.ZipFile;
|
import org.apache.commons.compress.archivers.zip.ZipFile;
|
||||||
import org.jackhuang.hmcl.util.Charsets;
|
|
||||||
import org.jackhuang.hmcl.util.IOUtils;
|
import org.jackhuang.hmcl.util.IOUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
*/
|
*/
|
||||||
@@ -55,7 +56,7 @@ public final class GameVersion {
|
|||||||
private static Optional<String> getVersionOfOldMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException {
|
private static Optional<String> getVersionOfOldMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException {
|
||||||
byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry));
|
byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry));
|
||||||
|
|
||||||
byte[] bytes = "Minecraft Minecraft ".getBytes(Charsets.US_ASCII);
|
byte[] bytes = "Minecraft Minecraft ".getBytes(US_ASCII);
|
||||||
int j = matchArray(tmp, bytes);
|
int j = matchArray(tmp, bytes);
|
||||||
if (j < 0)
|
if (j < 0)
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
@@ -64,25 +65,25 @@ public final class GameVersion {
|
|||||||
if ((j = lessThan32(tmp, i)) < 0)
|
if ((j = lessThan32(tmp, i)) < 0)
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
return Optional.of(new String(tmp, i, j - i, Charsets.US_ASCII));
|
return Optional.of(new String(tmp, i, j - i, US_ASCII));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<String> getVersionOfNewMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException {
|
private static Optional<String> getVersionOfNewMinecraft(ZipFile file, ZipArchiveEntry entry) throws IOException {
|
||||||
byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry));
|
byte[] tmp = IOUtils.readFullyAsByteArray(file.getInputStream(entry));
|
||||||
|
|
||||||
byte[] str = "-server.txt".getBytes(Charsets.US_ASCII);
|
byte[] str = "-server.txt".getBytes(US_ASCII);
|
||||||
int j = matchArray(tmp, str);
|
int j = matchArray(tmp, str);
|
||||||
if (j < 0) return Optional.empty();
|
if (j < 0) return Optional.empty();
|
||||||
int i = j + str.length;
|
int i = j + str.length;
|
||||||
i += 11;
|
i += 11;
|
||||||
j = lessThan32(tmp, i);
|
j = lessThan32(tmp, i);
|
||||||
if (j < 0) return Optional.empty();
|
if (j < 0) return Optional.empty();
|
||||||
String result = new String(tmp, i, j - i, Charsets.US_ASCII);
|
String result = new String(tmp, i, j - i, US_ASCII);
|
||||||
|
|
||||||
char ch = result.charAt(0);
|
char ch = result.charAt(0);
|
||||||
// 1.8.1+
|
// 1.8.1+
|
||||||
if (ch < '0' || ch > '9') {
|
if (ch < '0' || ch > '9') {
|
||||||
str = "Can't keep up! Did the system time change, or is the server overloaded?".getBytes(Charsets.US_ASCII);
|
str = "Can't keep up! Did the system time change, or is the server overloaded?".getBytes(US_ASCII);
|
||||||
j = matchArray(tmp, str);
|
j = matchArray(tmp, str);
|
||||||
if (j < 0) return Optional.empty();
|
if (j < 0) return Optional.empty();
|
||||||
i = -1;
|
i = -1;
|
||||||
@@ -100,7 +101,7 @@ public final class GameVersion {
|
|||||||
while (tmp[k] >= 48 && tmp[k] <= 57 || tmp[k] == (int) '-' || tmp[k] == (int) '.' || tmp[k] >= 97 && tmp[k] <= (int) 'z')
|
while (tmp[k] >= 48 && tmp[k] <= 57 || tmp[k] == (int) '-' || tmp[k] == (int) '.' || tmp[k] >= 97 && tmp[k] <= (int) 'z')
|
||||||
k--;
|
k--;
|
||||||
k++;
|
k++;
|
||||||
return Optional.of(new String(tmp, k, i - k + 1, Charsets.US_ASCII));
|
return Optional.of(new String(tmp, k, i - k + 1, US_ASCII));
|
||||||
}
|
}
|
||||||
return Optional.of(result);
|
return Optional.of(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import org.apache.commons.compress.archivers.ArchiveEntry;
|
|||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.Constants;
|
import org.jackhuang.hmcl.util.Constants;
|
||||||
import org.jackhuang.hmcl.util.DigestUtils;
|
|
||||||
import org.jackhuang.hmcl.util.FileUtils;
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -29,6 +28,9 @@ import java.io.FileInputStream;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.DigestUtils.digest;
|
||||||
|
import static org.jackhuang.hmcl.util.Hex.encodeHex;
|
||||||
|
|
||||||
public final class MinecraftInstanceTask<T> extends Task {
|
public final class MinecraftInstanceTask<T> extends Task {
|
||||||
|
|
||||||
private final File zipFile;
|
private final File zipFile;
|
||||||
@@ -62,7 +64,7 @@ public final class MinecraftInstanceTask<T> extends Task {
|
|||||||
if (path.startsWith("/") || path.startsWith("\\"))
|
if (path.startsWith("/") || path.startsWith("\\"))
|
||||||
path = path.substring(1);
|
path = path.substring(1);
|
||||||
|
|
||||||
overrides.add(new ModpackConfiguration.FileInformation(path, DigestUtils.sha1Hex(zip)));
|
overrides.add(new ModpackConfiguration.FileInformation(path, encodeHex(digest("SHA-1", zip))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package org.jackhuang.hmcl.mod;
|
|||||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.util.DigestUtils;
|
|
||||||
import org.jackhuang.hmcl.util.FileUtils;
|
import org.jackhuang.hmcl.util.FileUtils;
|
||||||
import org.jackhuang.hmcl.util.IOUtils;
|
import org.jackhuang.hmcl.util.IOUtils;
|
||||||
|
|
||||||
@@ -31,6 +30,9 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.DigestUtils.digest;
|
||||||
|
import static org.jackhuang.hmcl.util.Hex.encodeHex;
|
||||||
|
|
||||||
public class ModpackInstallTask<T> extends Task {
|
public class ModpackInstallTask<T> extends Task {
|
||||||
|
|
||||||
private final File modpackFile;
|
private final File modpackFile;
|
||||||
@@ -92,8 +94,8 @@ public class ModpackInstallTask<T> extends Task {
|
|||||||
byte[] data = os.toByteArray();
|
byte[] data = os.toByteArray();
|
||||||
|
|
||||||
if (files.contains(path) && entryFile.exists()) {
|
if (files.contains(path) && entryFile.exists()) {
|
||||||
String oldHash = DigestUtils.sha1Hex(new FileInputStream(entryFile));
|
String oldHash = encodeHex(digest("SHA-1", new FileInputStream(entryFile)));
|
||||||
String newHash = DigestUtils.sha1Hex(new ByteArrayInputStream(data));
|
String newHash = encodeHex(digest("SHA-1", new ByteArrayInputStream(data)));
|
||||||
if (!oldHash.equals(newHash)) {
|
if (!oldHash.equals(newHash)) {
|
||||||
try (FileOutputStream fos = new FileOutputStream(entryFile)) {
|
try (FileOutputStream fos = new FileOutputStream(entryFile)) {
|
||||||
IOUtils.copyTo(new ByteArrayInputStream(data), fos, buf);
|
IOUtils.copyTo(new ByteArrayInputStream(data), fos, buf);
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ import java.net.URL;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.DigestUtils.getDigest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A task that can download a file online.
|
* A task that can download a file online.
|
||||||
*
|
*
|
||||||
@@ -154,7 +156,7 @@ public class FileDownloadTask extends Task {
|
|||||||
temp = FileUtils.createTempFile();
|
temp = FileUtils.createTempFile();
|
||||||
rFile = new RandomAccessFile(temp, "rw");
|
rFile = new RandomAccessFile(temp, "rw");
|
||||||
|
|
||||||
MessageDigest digest = DigestUtils.getSha1Digest();
|
MessageDigest digest = getDigest("SHA-1");
|
||||||
|
|
||||||
stream = con.getInputStream();
|
stream = con.getInputStream();
|
||||||
int lastDownloaded = 0, downloaded = 0;
|
int lastDownloaded = 0, downloaded = 0;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.task;
|
package org.jackhuang.hmcl.task;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.util.Charsets;
|
|
||||||
import org.jackhuang.hmcl.util.IOUtils;
|
import org.jackhuang.hmcl.util.IOUtils;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
import org.jackhuang.hmcl.util.NetworkUtils;
|
import org.jackhuang.hmcl.util.NetworkUtils;
|
||||||
@@ -31,6 +30,8 @@ import java.net.URL;
|
|||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author huang
|
* @author huang
|
||||||
@@ -52,7 +53,7 @@ public final class GetTask extends TaskResult<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GetTask(URL url, Proxy proxy, String id) {
|
public GetTask(URL url, Proxy proxy, String id) {
|
||||||
this(url, proxy, id, Charsets.DEFAULT_CHARSET);
|
this(url, proxy, id, UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetTask(URL url, Proxy proxy, String id, Charset charset) {
|
public GetTask(URL url, Proxy proxy, String id, Charset charset) {
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Hello Minecraft!.
|
|
||||||
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
|
||||||
*/
|
|
||||||
package org.jackhuang.hmcl.util;
|
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.UnsupportedCharsetException;
|
|
||||||
|
|
||||||
public final class Charsets {
|
|
||||||
|
|
||||||
private Charsets() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
|
||||||
|
|
||||||
public static final Charset US_ASCII = Charset.forName("US-ASCII");
|
|
||||||
|
|
||||||
public static final Charset UTF_16 = Charset.forName("UTF-16");
|
|
||||||
|
|
||||||
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
|
|
||||||
|
|
||||||
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
|
|
||||||
|
|
||||||
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
|
||||||
|
|
||||||
public static final Charset DEFAULT_CHARSET = UTF_8;
|
|
||||||
|
|
||||||
public static Charset toCharset(String charset) {
|
|
||||||
if (charset == null)
|
|
||||||
return Charset.defaultCharset();
|
|
||||||
try {
|
|
||||||
return Charset.forName(charset);
|
|
||||||
} catch (UnsupportedCharsetException ignored) {
|
|
||||||
return Charset.defaultCharset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Charset toCharset() {
|
|
||||||
return toCharset(System.getProperty("sun.jnu.encoding", Constants.DEFAULT_ENCODING));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -43,8 +43,6 @@ public final class Constants {
|
|||||||
private Constants() {
|
private Constants() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String DEFAULT_ENCODING = "UTF-8";
|
|
||||||
public static final Charset DEFAULT_CHARSET = Charsets.UTF_8;
|
|
||||||
public static final Charset SYSTEM_CHARSET = Charset.forName(OperatingSystem.ENCODING);
|
public static final Charset SYSTEM_CHARSET = Charset.forName(OperatingSystem.ENCODING);
|
||||||
|
|
||||||
public static final String DEFAULT_LIBRARY_URL = "https://libraries.minecraft.net/";
|
public static final String DEFAULT_LIBRARY_URL = "https://libraries.minecraft.net/";
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import java.io.InputStream;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
@@ -33,11 +35,6 @@ public final class DigestUtils {
|
|||||||
|
|
||||||
private static final int STREAM_BUFFER_LENGTH = 1024;
|
private static final int STREAM_BUFFER_LENGTH = 1024;
|
||||||
|
|
||||||
private static byte[] digest(MessageDigest digest, InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return updateDigest(digest, data).digest();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MessageDigest getDigest(String algorithm) {
|
public static MessageDigest getDigest(String algorithm) {
|
||||||
try {
|
try {
|
||||||
return MessageDigest.getInstance(algorithm);
|
return MessageDigest.getInstance(algorithm);
|
||||||
@@ -46,193 +43,23 @@ public final class DigestUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageDigest getMd2Digest() {
|
public static byte[] digest(String algorithm, String data) {
|
||||||
return getDigest("MD2");
|
return digest(algorithm, data.getBytes(UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageDigest getMd5Digest() {
|
public static byte[] digest(String algorithm, byte[] data) {
|
||||||
return getDigest("MD5");
|
return getDigest(algorithm).digest(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageDigest getSha1Digest() {
|
public static byte[] digest(String algorithm, InputStream data) throws IOException {
|
||||||
return getDigest("SHA-1");
|
return digest(getDigest(algorithm), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageDigest getSha256Digest() {
|
public static byte[] digest(MessageDigest digest, InputStream data) throws IOException {
|
||||||
return getDigest("SHA-256");
|
return updateDigest(digest, data).digest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageDigest getSha384Digest() {
|
public static MessageDigest updateDigest(MessageDigest digest, InputStream data) throws IOException {
|
||||||
return getDigest("SHA-384");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MessageDigest getSha512Digest() {
|
|
||||||
return getDigest("SHA-512");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] md2(byte[] data) {
|
|
||||||
return getMd2Digest().digest(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] md2(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return digest(getMd2Digest(), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] md2(String data) {
|
|
||||||
return md2(data.getBytes(Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md2Hex(byte[] data) {
|
|
||||||
return Hex.encodeHexString(md2(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md2Hex(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return Hex.encodeHexString(md2(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md2Hex(String data) {
|
|
||||||
return Hex.encodeHexString(md2(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] md5(byte[] data) {
|
|
||||||
return getMd5Digest().digest(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] md5(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return digest(getMd5Digest(), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] md5(String data) {
|
|
||||||
return md5(data.getBytes(Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5Hex(byte[] data) {
|
|
||||||
return Hex.encodeHexString(md5(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5Hex(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return Hex.encodeHexString(md5(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5Hex(String data) {
|
|
||||||
return Hex.encodeHexString(md5(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha1(byte[] data) {
|
|
||||||
return getSha1Digest().digest(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha1(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return digest(getSha1Digest(), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha1(String data) {
|
|
||||||
return sha1(data.getBytes(Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha1Hex(byte[] data) {
|
|
||||||
return Hex.encodeHexString(sha1(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha1Hex(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return Hex.encodeHexString(sha1(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha1Hex(String data) {
|
|
||||||
return Hex.encodeHexString(sha1(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha256(byte[] data) {
|
|
||||||
return getSha256Digest().digest(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha256(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return digest(getSha256Digest(), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha256(String data) {
|
|
||||||
return sha256(data.getBytes(Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha256Hex(byte[] data) {
|
|
||||||
return Hex.encodeHexString(sha256(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha256Hex(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return Hex.encodeHexString(sha256(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha256Hex(String data) {
|
|
||||||
return Hex.encodeHexString(sha256(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha384(byte[] data) {
|
|
||||||
return getSha384Digest().digest(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha384(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return digest(getSha384Digest(), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha384(String data) {
|
|
||||||
return sha384(data.getBytes(Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha384Hex(byte[] data) {
|
|
||||||
return Hex.encodeHexString(sha384(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha384Hex(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return Hex.encodeHexString(sha384(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha384Hex(String data) {
|
|
||||||
return Hex.encodeHexString(sha384(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha512(byte[] data) {
|
|
||||||
return getSha512Digest().digest(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha512(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return digest(getSha512Digest(), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] sha512(String data) {
|
|
||||||
return sha512(data.getBytes(Charsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha512Hex(byte[] data) {
|
|
||||||
return Hex.encodeHexString(sha512(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha512Hex(InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
return Hex.encodeHexString(sha512(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String sha512Hex(String data) {
|
|
||||||
return Hex.encodeHexString(sha512(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MessageDigest updateDigest(MessageDigest messageDigest, byte[] valueToDigest) {
|
|
||||||
messageDigest.update(valueToDigest);
|
|
||||||
return messageDigest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MessageDigest updateDigest(MessageDigest digest, InputStream data)
|
|
||||||
throws IOException {
|
|
||||||
byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
|
byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
|
||||||
int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
|
int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
|
||||||
|
|
||||||
@@ -244,8 +71,4 @@ public final class DigestUtils {
|
|||||||
return digest;
|
return digest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageDigest updateDigest(MessageDigest messageDigest, String valueToDigest) {
|
|
||||||
messageDigest.update(valueToDigest.getBytes(Charsets.UTF_8));
|
|
||||||
return messageDigest;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author huang
|
* @author huang
|
||||||
@@ -44,7 +46,7 @@ public final class FileUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String readText(File file) throws IOException {
|
public static String readText(File file) throws IOException {
|
||||||
return readText(file, Charsets.DEFAULT_CHARSET);
|
return readText(file, UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String readText(File file, Charset charset) throws IOException {
|
public static String readText(File file, Charset charset) throws IOException {
|
||||||
@@ -60,7 +62,7 @@ public final class FileUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void writeText(File file, String text) throws IOException {
|
public static void writeText(File file, String text) throws IOException {
|
||||||
writeText(file, text, Charsets.DEFAULT_CHARSET);
|
writeText(file, text, UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeText(File file, String text, Charset charset) throws IOException {
|
public static void writeText(File file, String text, Charset charset) throws IOException {
|
||||||
|
|||||||
@@ -17,20 +17,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util;
|
package org.jackhuang.hmcl.util;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.io.IOException;
|
||||||
|
|
||||||
public final class Hex {
|
public final class Hex {
|
||||||
|
|
||||||
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||||
|
|
||||||
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
public static byte[] decodeHex(String str) throws IOException {
|
||||||
private final Charset charset;
|
char[] data = str.toCharArray();
|
||||||
|
|
||||||
public static byte[] decodeHex(char[] data) throws Exception {
|
|
||||||
int len = data.length;
|
int len = data.length;
|
||||||
|
|
||||||
if ((len & 0x1) != 0)
|
if ((len & 0x1) != 0)
|
||||||
throw new Exception("Odd number of characters.");
|
throw new IOException("Odd number of characters.");
|
||||||
|
|
||||||
byte[] out = new byte[len >> 1];
|
byte[] out = new byte[len >> 1];
|
||||||
|
|
||||||
@@ -46,83 +44,24 @@ public final class Hex {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char[] encodeHex(byte[] data) {
|
public static String encodeHex(byte[] data) {
|
||||||
return encodeHex(data, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
|
|
||||||
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static char[] encodeHex(byte[] data, char[] toDigits) {
|
|
||||||
int l = data.length;
|
int l = data.length;
|
||||||
char[] out = new char[l << 1];
|
char[] out = new char[l << 1];
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int j = 0; i < l; i++) {
|
for (int j = 0; i < l; i++) {
|
||||||
out[(j++)] = toDigits[((0xF0 & data[i]) >>> 4)];
|
out[(j++)] = DIGITS_LOWER[((0xF0 & data[i]) >>> 4)];
|
||||||
out[(j++)] = toDigits[(0xF & data[i])];
|
out[(j++)] = DIGITS_LOWER[(0xF & data[i])];
|
||||||
}
|
}
|
||||||
return out;
|
return new String(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String encodeHexString(byte[] data) {
|
private static int toDigit(char ch, int index) throws IOException {
|
||||||
return new String(encodeHex(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static int toDigit(char ch, int index) {
|
|
||||||
int digit = Character.digit(ch, 16);
|
int digit = Character.digit(ch, 16);
|
||||||
if (digit == -1)
|
if (digit == -1)
|
||||||
throw new IllegalArgumentException("Illegal hexadecimal character " + ch + " at index " + index);
|
throw new IOException("Illegal hexadecimal character " + ch + " at index " + index);
|
||||||
return digit;
|
return digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hex() {
|
private Hex() {}
|
||||||
this(Charsets.DEFAULT_CHARSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hex(Charset charset) {
|
|
||||||
this.charset = charset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] decode(byte[] array) throws Exception {
|
|
||||||
return decodeHex(new String(array, getCharset()).toCharArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object decode(Object object) throws Exception {
|
|
||||||
try {
|
|
||||||
char[] charArray = (object instanceof String) ? ((String) object).toCharArray() : (char[]) object;
|
|
||||||
return decodeHex(charArray);
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new Exception(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] encode(byte[] array) {
|
|
||||||
return encodeHexString(array).getBytes(getCharset());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object encode(Object object)
|
|
||||||
throws Exception {
|
|
||||||
try {
|
|
||||||
byte[] byteArray = (object instanceof String) ? ((String) object).getBytes(getCharset()) : (byte[]) object;
|
|
||||||
|
|
||||||
return encodeHex(byteArray);
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new Exception(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Charset getCharset() {
|
|
||||||
return this.charset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCharsetName() {
|
|
||||||
return this.charset.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + "[charsetName=" + this.charset + "]";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
import static org.jackhuang.hmcl.util.StringUtils.*;
|
import static org.jackhuang.hmcl.util.StringUtils.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +87,7 @@ public final class NetworkUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String doPost(URL url, String post, String contentType, Proxy proxy) throws IOException {
|
public static String doPost(URL url, String post, String contentType, Proxy proxy) throws IOException {
|
||||||
byte[] bytes = post.getBytes(Charsets.UTF_8);
|
byte[] bytes = post.getBytes(UTF_8);
|
||||||
|
|
||||||
HttpURLConnection con = createConnection(url, proxy);
|
HttpURLConnection con = createConnection(url, proxy);
|
||||||
con.setRequestMethod("POST");
|
con.setRequestMethod("POST");
|
||||||
@@ -108,12 +109,12 @@ public final class NetworkUtils {
|
|||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
is = con.getInputStream();
|
is = con.getInputStream();
|
||||||
return IOUtils.readFullyAsString(is, Charsets.UTF_8);
|
return IOUtils.readFullyAsString(is, UTF_8);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
IOUtils.closeQuietly(is);
|
IOUtils.closeQuietly(is);
|
||||||
is = con.getErrorStream();
|
is = con.getErrorStream();
|
||||||
if (is != null)
|
if (is != null)
|
||||||
return IOUtils.readFullyAsString(is, Charsets.UTF_8);
|
return IOUtils.readFullyAsString(is, UTF_8);
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(is);
|
IOUtils.closeQuietly(is);
|
||||||
|
|||||||
Reference in New Issue
Block a user