mirror of
https://github.com/packwiz/packwiz.git
synced 2025-04-19 21:16:30 +02:00
- Fixed creation of duplicate index entries when importing from CurseForge (fixes #224) - Automatically remove duplicates in index - Fixed `packwiz serve` with a custom `--pack-root` argument (fixes #223) - Fixed `packwiz serve` with a custom index.toml location - Cleaned up internal serving code, added comments and better errors - Refactored path handling code - Improved refreshing/exporting performance - Factored out duplicated exporting logic - Replaced GetAllMods calls with cleaner LoadAllMods calls and made the former private - Improved variable names in update command - Improved handling of aliassed files - Changed CheckUpdate to take references to metadata - Removed the ability to use an absolute path to the index file (that probably didn't work anyway) - Behaviour change: order of entries in exported files may be random
113 lines
2.8 KiB
Go
113 lines
2.8 KiB
Go
package modrinth
|
|
|
|
import (
|
|
modrinthApi "codeberg.org/jmansfield/go-modrinth/modrinth"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/mitchellh/mapstructure"
|
|
"github.com/packwiz/packwiz/core"
|
|
)
|
|
|
|
type mrUpdateData struct {
|
|
// TODO(format): change to "project-id"
|
|
ProjectID string `mapstructure:"mod-id"`
|
|
// TODO(format): change to "version-id"
|
|
InstalledVersion string `mapstructure:"version"`
|
|
}
|
|
|
|
func (u mrUpdateData) ToMap() (map[string]interface{}, error) {
|
|
newMap := make(map[string]interface{})
|
|
err := mapstructure.Decode(u, &newMap)
|
|
return newMap, err
|
|
}
|
|
|
|
type mrUpdater struct{}
|
|
|
|
func (u mrUpdater) ParseUpdate(updateUnparsed map[string]interface{}) (interface{}, error) {
|
|
var updateData mrUpdateData
|
|
err := mapstructure.Decode(updateUnparsed, &updateData)
|
|
return updateData, err
|
|
}
|
|
|
|
type cachedStateStore struct {
|
|
ProjectID string
|
|
Version *modrinthApi.Version
|
|
}
|
|
|
|
func (u mrUpdater) CheckUpdate(mods []*core.Mod, pack core.Pack) ([]core.UpdateCheck, error) {
|
|
results := make([]core.UpdateCheck, len(mods))
|
|
|
|
for i, mod := range mods {
|
|
rawData, ok := mod.GetParsedUpdateData("modrinth")
|
|
if !ok {
|
|
results[i] = core.UpdateCheck{Error: errors.New("failed to parse update metadata")}
|
|
continue
|
|
}
|
|
|
|
data := rawData.(mrUpdateData)
|
|
|
|
newVersion, err := getLatestVersion(data.ProjectID, mod.Name, pack)
|
|
if err != nil {
|
|
results[i] = core.UpdateCheck{Error: fmt.Errorf("failed to get latest version: %v", err)}
|
|
continue
|
|
}
|
|
|
|
if *newVersion.ID == data.InstalledVersion { //The latest version from the site is the same as the installed one
|
|
results[i] = core.UpdateCheck{UpdateAvailable: false}
|
|
continue
|
|
}
|
|
|
|
if len(newVersion.Files) == 0 {
|
|
results[i] = core.UpdateCheck{Error: errors.New("new version doesn't have any files")}
|
|
continue
|
|
}
|
|
|
|
newFilename := newVersion.Files[0].Filename
|
|
// Prefer the primary file
|
|
for _, v := range newVersion.Files {
|
|
if *v.Primary {
|
|
newFilename = v.Filename
|
|
}
|
|
}
|
|
|
|
results[i] = core.UpdateCheck{
|
|
UpdateAvailable: true,
|
|
UpdateString: mod.FileName + " -> " + *newFilename,
|
|
CachedState: cachedStateStore{data.ProjectID, newVersion},
|
|
}
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
func (u mrUpdater) DoUpdate(mods []*core.Mod, cachedState []interface{}) error {
|
|
for i, mod := range mods {
|
|
modState := cachedState[i].(cachedStateStore)
|
|
var version = modState.Version
|
|
|
|
var file = version.Files[0]
|
|
// Prefer the primary file
|
|
for _, v := range version.Files {
|
|
if *v.Primary {
|
|
file = v
|
|
}
|
|
}
|
|
|
|
algorithm, hash := getBestHash(file)
|
|
if algorithm == "" {
|
|
return errors.New("file for project " + mod.Name + " doesn't have a valid hash")
|
|
}
|
|
|
|
mod.FileName = *file.Filename
|
|
mod.Download = core.ModDownload{
|
|
URL: *file.URL,
|
|
HashFormat: algorithm,
|
|
Hash: hash,
|
|
}
|
|
mod.Update["modrinth"]["version"] = version.ID
|
|
}
|
|
|
|
return nil
|
|
}
|