From 55ce2fb581dfb5346c69e2ea89a7a39c93994398 Mon Sep 17 00:00:00 2001 From: comp500 Date: Mon, 14 Feb 2022 18:21:22 +0000 Subject: [PATCH] Use new SHA1/MD5 hashes from CurseForge API --- curseforge/curseforge.go | 19 +++++++++---------- curseforge/request.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/curseforge/curseforge.go b/curseforge/curseforge.go index 3ad39b8..d5fc01f 100644 --- a/curseforge/curseforge.go +++ b/curseforge/curseforge.go @@ -179,16 +179,16 @@ func createModFile(modInfo modInfo, fileInfo modFileInfo, index *core.Index) err return err } + hash, hashFormat := fileInfo.getBestHash() + modMeta := core.Mod{ Name: modInfo.Name, FileName: fileInfo.FileName, Side: core.UniversalSide, Download: core.ModDownload{ - URL: u, - // TODO: murmur2 hashing may be unstable in curse api, calculate the hash manually? - // TODO: check if the hash is invalid (e.g. 0) - HashFormat: "murmur2", - Hash: strconv.Itoa(fileInfo.Fingerprint), + URL: u, + HashFormat: hashFormat, + Hash: hash, }, Update: updateMap, } @@ -421,12 +421,11 @@ func (u cfUpdater) DoUpdate(mods []*core.Mod, cachedState []interface{}) error { v.FileName = fileInfoData.FileName v.Name = modState.Name + hash, hashFormat := fileInfoData.getBestHash() v.Download = core.ModDownload{ - URL: u, - // TODO: murmur2 hashing may be unstable in curse api, calculate the hash manually? - // TODO: check if the hash is invalid (e.g. 0) - HashFormat: "murmur2", - Hash: strconv.Itoa(fileInfoData.Fingerprint), + URL: u, + HashFormat: hashFormat, + Hash: hash, } v.Update["curseforge"]["project-id"] = modState.ID diff --git a/curseforge/request.go b/curseforge/request.go index 23c91eb..116d8f9 100644 --- a/curseforge/request.go +++ b/curseforge/request.go @@ -124,6 +124,12 @@ const ( modloaderTypeFabric ) +//noinspection GoUnusedConst +const ( + hashAlgoSHA1 int = iota + 1 + hashAlgoMD5 +) + // modInfo is a subset of the deserialised JSON response from the Curse API for mods (addons) type modInfo struct { Name string `json:"name"` @@ -244,6 +250,37 @@ type modFileInfo struct { ModID int `json:"addonId"` Type int `json:"type"` } `json:"dependencies"` + + Hashes []struct { + Value string `json:"value"` + Algorithm int `json:"algorithm"` + } `json:"hashes"` +} + +func (i modFileInfo) getBestHash() (hash string, hashFormat string) { + // TODO: check if the hash is invalid (e.g. 0) + hash = strconv.Itoa(i.Fingerprint) + hashFormat = "murmur2" + hashPreferred := 0 + + // Prefer SHA1, then MD5 if found: + if i.Hashes != nil { + for _, v := range i.Hashes { + if v.Algorithm == hashAlgoMD5 && hashPreferred < 1 { + hashPreferred = 1 + + hash = v.Value + hashFormat = "md5" + } else if v.Algorithm == hashAlgoSHA1 && hashPreferred < 2 { + hashPreferred = 2 + + hash = v.Value + hashFormat = "sha1" + } + } + } + + return } func getFileInfo(modID int, fileID int) (modFileInfo, error) {