mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-05-05 03:56:31 +02:00
Fix hash serialisation in JSON, check index hash
This commit is contained in:
parent
533c7a3ed5
commit
12bf090895
@ -21,6 +21,7 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonIOException;
|
import com.google.gson.JsonIOException;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
@ -30,6 +31,7 @@ import link.infra.packwiz.installer.metadata.IndexFile;
|
|||||||
import link.infra.packwiz.installer.metadata.ManifestFile;
|
import link.infra.packwiz.installer.metadata.ManifestFile;
|
||||||
import link.infra.packwiz.installer.metadata.PackFile;
|
import link.infra.packwiz.installer.metadata.PackFile;
|
||||||
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
||||||
|
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||||
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
||||||
import link.infra.packwiz.installer.request.HandlerManager;
|
import link.infra.packwiz.installer.request.HandlerManager;
|
||||||
import link.infra.packwiz.installer.ui.IUserInterface;
|
import link.infra.packwiz.installer.ui.IUserInterface;
|
||||||
@ -109,7 +111,7 @@ public class UpdateManager {
|
|||||||
this.checkOptions();
|
this.checkOptions();
|
||||||
|
|
||||||
ui.submitProgress(new InstallProgress("Loading manifest file..."));
|
ui.submitProgress(new InstallProgress("Loading manifest file..."));
|
||||||
Gson gson = new Gson();
|
Gson gson = new GsonBuilder().registerTypeAdapter(Hash.class, new Hash.TypeHandler()).create();
|
||||||
ManifestFile manifest;
|
ManifestFile manifest;
|
||||||
try {
|
try {
|
||||||
manifest = gson.fromJson(new FileReader(Paths.get(opts.packFolder, opts.manifestFile).toString()),
|
manifest = gson.fromJson(new FileReader(Paths.get(opts.packFolder, opts.manifestFile).toString()),
|
||||||
@ -141,12 +143,12 @@ public class UpdateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (manifest.packFileHash != null && packFileSource.hashIsEqual(manifest.packFileHash)) {
|
if (manifest.packFileHash != null && packFileSource.hashIsEqual(manifest.packFileHash)) {
|
||||||
System.out.println("Hash already up to date!");
|
System.out.println("Modpack is already up to date!");
|
||||||
// WOOO it's already up to date
|
|
||||||
// todo: --force?
|
// todo: --force?
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(pf.name);
|
System.out.println("Modpack name: " + pf.name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
processIndex(HandlerManager.getNewLoc(opts.downloadURI, pf.index.file),
|
processIndex(HandlerManager.getNewLoc(opts.downloadURI, pf.index.file),
|
||||||
@ -172,7 +174,13 @@ public class UpdateManager {
|
|||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processIndex(URI indexUri, Object indexHash, String hashFormat, ManifestFile manifest) {
|
protected void processIndex(URI indexUri, Hash indexHash, String hashFormat, ManifestFile manifest) {
|
||||||
|
if (manifest.indexFileHash != null && manifest.indexFileHash.equals(indexHash)) {
|
||||||
|
System.out.println("Modpack files are already up to date!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
manifest.indexFileHash = indexHash;
|
||||||
|
|
||||||
GeneralHashingSource indexFileSource;
|
GeneralHashingSource indexFileSource;
|
||||||
try {
|
try {
|
||||||
Source src = HandlerManager.getFileSource(indexUri);
|
Source src = HandlerManager.getFileSource(indexUri);
|
||||||
@ -192,10 +200,8 @@ public class UpdateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!indexFileSource.hashIsEqual(indexHash)) {
|
if (!indexFileSource.hashIsEqual(indexHash)) {
|
||||||
System.out.println("Hash problems!!!!!!!");
|
|
||||||
System.out.println(indexHash);
|
|
||||||
System.out.println(indexFileSource.getHash());
|
|
||||||
// TODO: throw exception
|
// TODO: throw exception
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manifest.cachedFiles == null) {
|
if (manifest.cachedFiles == null) {
|
||||||
@ -211,7 +217,7 @@ public class UpdateManager {
|
|||||||
return f;
|
return f;
|
||||||
}).filter(f -> {
|
}).filter(f -> {
|
||||||
ManifestFile.File cachedFile = manifest.cachedFiles.get(f.file);
|
ManifestFile.File cachedFile = manifest.cachedFiles.get(f.file);
|
||||||
Object newHash;
|
Hash newHash;
|
||||||
try {
|
try {
|
||||||
newHash = HashUtils.getHash(f.hashFormat, f.hash);
|
newHash = HashUtils.getHash(f.hashFormat, f.hash);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -266,7 +272,7 @@ public class UpdateManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object hash;
|
Hash hash;
|
||||||
String fileHashFormat;
|
String fileHashFormat;
|
||||||
if (f.linkedFile != null) {
|
if (f.linkedFile != null) {
|
||||||
hash = f.linkedFile.getHash();
|
hash = f.linkedFile.getHash();
|
||||||
|
@ -9,6 +9,7 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
import com.moandjiezana.toml.Toml;
|
import com.moandjiezana.toml.Toml;
|
||||||
|
|
||||||
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
import link.infra.packwiz.installer.metadata.hash.GeneralHashingSource;
|
||||||
|
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||||
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
||||||
import link.infra.packwiz.installer.request.HandlerManager;
|
import link.infra.packwiz.installer.request.HandlerManager;
|
||||||
import okio.Okio;
|
import okio.Okio;
|
||||||
@ -42,7 +43,7 @@ public class IndexFile {
|
|||||||
if (hashFormat == null || hashFormat.length() == 0) {
|
if (hashFormat == null || hashFormat.length() == 0) {
|
||||||
hashFormat = parentIndexFile.hashFormat;
|
hashFormat = parentIndexFile.hashFormat;
|
||||||
}
|
}
|
||||||
Object fileHash = HashUtils.getHash(hashFormat, hash);
|
Hash fileHash = HashUtils.getHash(hashFormat, hash);
|
||||||
linkedFileURI = HandlerManager.getNewLoc(indexUri, file);
|
linkedFileURI = HandlerManager.getNewLoc(indexUri, file);
|
||||||
Source src = HandlerManager.getFileSource(linkedFileURI);
|
Source src = HandlerManager.getFileSource(linkedFileURI);
|
||||||
GeneralHashingSource fileStream = HashUtils.getHasher(hashFormat).getHashingSource(src);
|
GeneralHashingSource fileStream = HashUtils.getHasher(hashFormat).getHashingSource(src);
|
||||||
@ -68,7 +69,7 @@ public class IndexFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getHash() throws Exception {
|
public Hash getHash() throws Exception {
|
||||||
if (hash == null) {
|
if (hash == null) {
|
||||||
throw new Exception("Index file doesn't have a hash");
|
throw new Exception("Index file doesn't have a hash");
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,18 @@ package link.infra.packwiz.installer.metadata;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||||
|
|
||||||
public class ManifestFile {
|
public class ManifestFile {
|
||||||
|
|
||||||
public Object packFileHash = null;
|
public Hash packFileHash = null;
|
||||||
public Object indexFileHash = null;
|
public Hash indexFileHash = null;
|
||||||
public Map<URI, File> cachedFiles;
|
public Map<URI, File> cachedFiles;
|
||||||
|
|
||||||
public static class File {
|
public static class File {
|
||||||
public Object hash = null;
|
public Hash hash = null;
|
||||||
public boolean isOptional = false;
|
public boolean isOptional = false;
|
||||||
public boolean optionValue = true;
|
public boolean optionValue = true;
|
||||||
public Object linkedFileHash = null;
|
public Hash linkedFileHash = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ import com.google.gson.annotations.JsonAdapter;
|
|||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import link.infra.packwiz.installer.UpdateManager.Options.Side;
|
import link.infra.packwiz.installer.UpdateManager.Options.Side;
|
||||||
|
import link.infra.packwiz.installer.metadata.hash.Hash;
|
||||||
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
||||||
import link.infra.packwiz.installer.request.HandlerManager;
|
import link.infra.packwiz.installer.request.HandlerManager;
|
||||||
import okio.Source;
|
import okio.Source;
|
||||||
@ -50,7 +51,7 @@ public class ModFile {
|
|||||||
return HandlerManager.getFileSource(newLoc);
|
return HandlerManager.getFileSource(newLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getHash() throws Exception {
|
public Hash getHash() throws Exception {
|
||||||
if (download == null) {
|
if (download == null) {
|
||||||
throw new Exception("Metadata file doesn't have download");
|
throw new Exception("Metadata file doesn't have download");
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ public abstract class GeneralHashingSource extends ForwardingSource {
|
|||||||
super(delegate);
|
super(delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Object getHash();
|
public abstract Hash getHash();
|
||||||
|
|
||||||
public boolean hashIsEqual(Object compareTo) {
|
public boolean hashIsEqual(Object compareTo) {
|
||||||
return compareTo.equals(getHash());
|
return compareTo.equals(getHash());
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package link.infra.packwiz.installer.metadata.hash;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
public abstract class Hash {
|
||||||
|
protected abstract String getStringValue();
|
||||||
|
|
||||||
|
protected abstract String getType();
|
||||||
|
|
||||||
|
public static class TypeHandler implements JsonDeserializer<Hash>, JsonSerializer<Hash> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Hash src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject out = new JsonObject();
|
||||||
|
out.add("type", new JsonPrimitive(src.getType()));
|
||||||
|
out.add("value", new JsonPrimitive(src.getStringValue()));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Hash deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
JsonObject obj = json.getAsJsonObject();
|
||||||
|
String type, value;
|
||||||
|
try {
|
||||||
|
type = obj.get("type").getAsString();
|
||||||
|
value = obj.get("value").getAsString();
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
throw new JsonParseException("Invalid hash JSON data");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return HashUtils.getHash(type, value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JsonParseException("Failed to create hash object", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ public class HashUtils {
|
|||||||
return hasher;
|
return hasher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object getHash(String type, String value) throws Exception {
|
public static Hash getHash(String type, String value) throws Exception {
|
||||||
if (hashTypeConversion.containsKey(type)) {
|
if (hashTypeConversion.containsKey(type)) {
|
||||||
return hashTypeConversion.get(type).getHash(value);
|
return hashTypeConversion.get(type).getHash(value);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ public class HashingSourceHasher implements IHasher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getHash() {
|
public Hash getHash() {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = new HashingSourceHash(delegateHashing.hash().hex());
|
value = new HashingSourceHash(delegateHashing.hash().hex());
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ public class HashingSourceHasher implements IHasher {
|
|||||||
// this some funky inner class stuff
|
// this some funky inner class stuff
|
||||||
// each of these classes is specific to the instance of the HasherHashingSource
|
// each of these classes is specific to the instance of the HasherHashingSource
|
||||||
// therefore HashingSourceHashes from different parent instances will be not instanceof each other
|
// therefore HashingSourceHashes from different parent instances will be not instanceof each other
|
||||||
private class HashingSourceHash {
|
private class HashingSourceHash extends Hash {
|
||||||
String value;
|
String value;
|
||||||
private HashingSourceHash(String value) {
|
private HashingSourceHash(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
@ -56,6 +56,16 @@ public class HashingSourceHasher implements IHasher {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return type + ": " + value;
|
return type + ": " + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getStringValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -69,7 +79,7 @@ public class HashingSourceHasher implements IHasher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getHash(String value) {
|
public Hash getHash(String value) {
|
||||||
return new HashingSourceHash(value);
|
return new HashingSourceHash(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,5 +4,5 @@ import okio.Source;
|
|||||||
|
|
||||||
public interface IHasher {
|
public interface IHasher {
|
||||||
public GeneralHashingSource getHashingSource(Source delegate);
|
public GeneralHashingSource getHashingSource(Source delegate);
|
||||||
public Object getHash(String value);
|
public Hash getHash(String value);
|
||||||
}
|
}
|
@ -28,7 +28,7 @@ public class Murmur2Hasher implements IHasher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getHash() {
|
public Hash getHash() {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
byte[] data = computeNormalizedArray(internalBuffer.readByteArray());
|
byte[] data = computeNormalizedArray(internalBuffer.readByteArray());
|
||||||
value = new Murmur2Hash(Murmur2Lib.hash32(data, data.length, 1));
|
value = new Murmur2Hash(Murmur2Lib.hash32(data, data.length, 1));
|
||||||
@ -54,7 +54,7 @@ public class Murmur2Hasher implements IHasher {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Murmur2Hash {
|
private class Murmur2Hash extends Hash {
|
||||||
int value;
|
int value;
|
||||||
private Murmur2Hash(String value) {
|
private Murmur2Hash(String value) {
|
||||||
// Parsing as long then casting to int converts values gt int max value but lt uint max value
|
// Parsing as long then casting to int converts values gt int max value but lt uint max value
|
||||||
@ -79,6 +79,16 @@ public class Murmur2Hasher implements IHasher {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "murmur2: " + value;
|
return "murmur2: " + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getStringValue() {
|
||||||
|
return Integer.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return "murmur2";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -87,7 +97,7 @@ public class Murmur2Hasher implements IHasher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getHash(String value) {
|
public Hash getHash(String value) {
|
||||||
return new Murmur2Hash(value);
|
return new Murmur2Hash(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ public class CLIHandler implements IUserInterface {
|
|||||||
@Override
|
@Override
|
||||||
public void executeManager(Runnable task) {
|
public void executeManager(Runnable task) {
|
||||||
task.run();
|
task.run();
|
||||||
|
System.out.println("Finished successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user