Fix hash serialisation in JSON, check index hash

This commit is contained in:
comp500 2019-06-24 17:27:28 +01:00
parent 533c7a3ed5
commit 12bf090895
No known key found for this signature in database
GPG Key ID: 214C822FFEC586B5
11 changed files with 105 additions and 26 deletions

View File

@ -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();

View File

@ -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");
} }

View File

@ -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;
} }
} }

View File

@ -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");
} }

View File

@ -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());

View File

@ -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);
}
}
}
}

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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!");
} }
} }