From 7c1f59d824f520713535401dbf60245f6672ddeb Mon Sep 17 00:00:00 2001 From: Chikage Date: Tue, 13 Sep 2022 11:38:06 +0800 Subject: [PATCH 01/13] add update cmd and modpack.json model --- cmd/update.go | 17 +++++++++++++ update/model/modPackInfo.go | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 cmd/update.go create mode 100644 update/model/modPackInfo.go diff --git a/cmd/update.go b/cmd/update.go new file mode 100644 index 0000000..56ccf74 --- /dev/null +++ b/cmd/update.go @@ -0,0 +1,17 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(updateCmd) +} + +var updateCmd = &cobra.Command{ + Use: "update", + Short: "Update the server", + Long: `Use file's hash and compare,Update the config and mods file'`, + Run: func(cmd *cobra.Command, args []string) { + }, +} diff --git a/update/model/modPackInfo.go b/update/model/modPackInfo.go new file mode 100644 index 0000000..30fd87c --- /dev/null +++ b/update/model/modPackInfo.go @@ -0,0 +1,50 @@ +package model + +import ( + "encoding/json" + "os" +) + +type modPackInfo struct { + File *[]fileInfo `json:"file"` + GameVersion string `json:"gameVersion"` + Loader string `json:"loader"` + ModPackName string `json:"modPackName"` +} + +type fileInfo struct { + FileHash string `json:"Hash"` + FilePath string `json:"Path"` +} + +func ReadModPackInfo(modPackJsonFile string) (*modPackInfo, error) { + + var modPackJsonByte []byte + var err error + modPackJsonByte, err = os.ReadFile(modPackJsonFile) + if err != nil { + return nil, err + } + + modPackJson := modPackInfo{} + err = json.Unmarshal(modPackJsonByte, &modPackJson) + + if err != nil { + return nil, err + } + return &modPackJson, nil +} + +func WriteModPackInfo(modPack *modPackInfo, modPackJsonFile string) error { + if modPack != nil { + modPackJsonByte, err := json.Marshal(modPack) + if err != nil { + return err + } + err = os.WriteFile(modPackJsonFile, modPackJsonByte, 0644) + if err != nil { + return err + } + } + return nil +} From a0d35075c08452c5d51bef42552586d97a334aed Mon Sep 17 00:00:00 2001 From: Chikage Date: Thu, 15 Sep 2022 15:31:39 +0800 Subject: [PATCH 02/13] add todo and GetDownloadPools From modPackInfo --- update/modPackInfoUtil.go | 15 +++++++++++++++ update/model/modPackInfo.go | 25 +++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 update/modPackInfoUtil.go diff --git a/update/modPackInfoUtil.go b/update/modPackInfoUtil.go new file mode 100644 index 0000000..7fb6059 --- /dev/null +++ b/update/modPackInfoUtil.go @@ -0,0 +1,15 @@ +package update + +import "github.com/nothub/mrpack-install/update/model" + +// GenerateModPackInfo Todo: Generate modPackInfo from modpack +func GenerateModPackInfo() *model.ModPackInfo { + + return nil +} + +// CompareModPackInfo Todo: Compare the two modPackInfo and generate a list of deletions and updates +func CompareModPackInfo(oldVersion *model.ModPackInfo, newVersion *model.ModPackInfo) (delete *model.ModPackInfo, add *model.ModPackInfo) { + + return nil, nil +} diff --git a/update/model/modPackInfo.go b/update/model/modPackInfo.go index 30fd87c..a740c8b 100644 --- a/update/model/modPackInfo.go +++ b/update/model/modPackInfo.go @@ -2,10 +2,12 @@ package model import ( "encoding/json" + "github.com/nothub/mrpack-install/requester" "os" + "path" ) -type modPackInfo struct { +type ModPackInfo struct { File *[]fileInfo `json:"file"` GameVersion string `json:"gameVersion"` Loader string `json:"loader"` @@ -13,11 +15,13 @@ type modPackInfo struct { } type fileInfo struct { - FileHash string `json:"Hash"` - FilePath string `json:"Path"` + FileHash string `json:"Hash"` + FilePath string `json:"Path"` + DownloadLink []string `json:"DownloadLink"` + TargetPath string `json:"TargetPath"` } -func ReadModPackInfo(modPackJsonFile string) (*modPackInfo, error) { +func ReadModPackInfo(modPackJsonFile string) (*ModPackInfo, error) { var modPackJsonByte []byte var err error @@ -26,7 +30,7 @@ func ReadModPackInfo(modPackJsonFile string) (*modPackInfo, error) { return nil, err } - modPackJson := modPackInfo{} + modPackJson := ModPackInfo{} err = json.Unmarshal(modPackJsonByte, &modPackJson) if err != nil { @@ -35,7 +39,7 @@ func ReadModPackInfo(modPackJsonFile string) (*modPackInfo, error) { return &modPackJson, nil } -func WriteModPackInfo(modPack *modPackInfo, modPackJsonFile string) error { +func WriteModPackInfo(modPack *ModPackInfo, modPackJsonFile string) error { if modPack != nil { modPackJsonByte, err := json.Marshal(modPack) if err != nil { @@ -48,3 +52,12 @@ func WriteModPackInfo(modPack *modPackInfo, modPackJsonFile string) error { } return nil } + +func (modPackInfo *ModPackInfo) GetDownloadPool(downloadPools *requester.DownloadPools) *requester.DownloadPools { + for _, file := range *modPackInfo.File { + if file.FilePath == "" && file.DownloadLink != nil { + downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(file.DownloadLink, map[string]string{"sha1": file.FileHash}, path.Base(file.FilePath), path.Dir(file.FilePath))) + } + } + return downloadPools +} From 060eff29892799744563558b8541e651ecb3f8ec Mon Sep 17 00:00:00 2001 From: Chikage Date: Thu, 15 Sep 2022 19:46:12 +0800 Subject: [PATCH 03/13] refactor sha1 --- util/checkSha1.go | 50 ------------------------------------- util/sha1.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 50 deletions(-) delete mode 100644 util/checkSha1.go create mode 100644 util/sha1.go diff --git a/util/checkSha1.go b/util/checkSha1.go deleted file mode 100644 index 93e24db..0000000 --- a/util/checkSha1.go +++ /dev/null @@ -1,50 +0,0 @@ -package util - -import ( - "crypto/sha1" - "encoding/hex" - "errors" - "fmt" - "io" - "net/http" - "os" -) - -func checkSha1(verifyHash string, verifyByte *[]byte) (bool, error) { - s := sha1.New() - s.Write(*verifyByte) - sha1Code := hex.EncodeToString(s.Sum(nil)) - if sha1Code == verifyHash { - return true, nil - } - return false, errors.New(fmt.Sprintf("data Hash Error,the data sha1 is %s,but you give hash is %s", sha1Code, verifyHash)) -} - -func CheckResponseSha1(verifyHash string, verifyResponse *http.Response) (bool, error) { - verifyByte, err := io.ReadAll(verifyResponse.Body) - if err != nil { - return false, err - } - err = verifyResponse.Body.Close() - if err != nil { - return false, err - } - verifyResponse.Body = io.NopCloser(verifyResponse.Body) - return checkSha1(verifyHash, &verifyByte) -} - -func CheckFileSha1(verifyHash string, verifyFile string) (bool, error) { - file, err := os.Open(verifyFile) - if err != nil { - return false, err - } - verifyByte, err := io.ReadAll(file) - if err != nil { - return false, err - } - err = file.Close() - if err != nil { - return false, err - } - return checkSha1(verifyHash, &verifyByte) -} diff --git a/util/sha1.go b/util/sha1.go new file mode 100644 index 0000000..f934c97 --- /dev/null +++ b/util/sha1.go @@ -0,0 +1,63 @@ +package util + +import ( + "crypto/sha1" + "encoding/hex" + "errors" + "fmt" + "io" + "os" +) + +func compareSha1(verifyHash string, newDataHash string) (bool, error) { + if newDataHash == verifyHash { + return true, nil + } + return false, errors.New(fmt.Sprintf("data Hash Error,the data sha1 is %s,but you give hash is %s", newDataHash, verifyHash)) +} + +func getSha1(newData *[]byte) string { + s := sha1.New() + s.Write(*newData) + sha1Code := hex.EncodeToString(s.Sum(nil)) + return sha1Code +} + +func CheckReadCloserSha1(verifyHash string, readCloser io.ReadCloser) (bool, error) { + newFileHash, err := GetReadCloserSha1(readCloser) + if err != nil { + return false, err + } + return compareSha1(verifyHash, newFileHash) +} + +func GetReadCloserSha1(readCloser io.ReadCloser) (string, error) { + verifyByte, err := io.ReadAll(readCloser) + if err != nil { + return "", err + } + err = readCloser.Close() + if err != nil { + return "", err + } + return getSha1(&verifyByte), nil +} + +func CheckFileSha1(verifyHash string, verifyFile string) (bool, error) { + file, err := os.Open(verifyFile) + defer func(file *os.File) { + err := file.Close() + if err != nil { + fmt.Println(err) + } + }(file) + + if err != nil { + return false, err + } + newFileHash, err := GetReadCloserSha1(file) + if err != nil { + return false, err + } + return compareSha1(verifyHash, newFileHash) +} From fd9ed025678aa9150554cf834f66cdcb4e1e9281 Mon Sep 17 00:00:00 2001 From: Chikage Date: Thu, 15 Sep 2022 19:58:35 +0800 Subject: [PATCH 04/13] GenerateModPackInfo after install modpack finish --- cmd/root.go | 10 +++++ update/modPackInfoUtil.go | 76 +++++++++++++++++++++++++++++++++++-- update/model/modPackInfo.go | 31 ++++++++------- 3 files changed, 99 insertions(+), 18 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 9a3f8f9..a0abf55 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,6 +7,7 @@ import ( "github.com/nothub/mrpack-install/modrinth/mrpack" "github.com/nothub/mrpack-install/requester" "github.com/nothub/mrpack-install/server" + "github.com/nothub/mrpack-install/update" "github.com/nothub/mrpack-install/util" "github.com/spf13/cobra" "log" @@ -233,6 +234,15 @@ var rootCmd = &cobra.Command{ log.Fatalln(err) } + info, err := update.GenerateModPackInfo(archivePath) + if err != nil { + fmt.Println(err) + } + err = info.Write(path.Join(serverDir, "modpack.json")) + if err != nil { + fmt.Println(err) + } + if modsUnclean { fmt.Println("There have been problems downloading downloading mods, you probably have to fix some dependency problems manually!") } diff --git a/update/modPackInfoUtil.go b/update/modPackInfoUtil.go index 7fb6059..08798da 100644 --- a/update/modPackInfoUtil.go +++ b/update/modPackInfoUtil.go @@ -1,11 +1,79 @@ package update -import "github.com/nothub/mrpack-install/update/model" +import ( + "archive/zip" + "fmt" + "github.com/nothub/mrpack-install/modrinth/mrpack" + "github.com/nothub/mrpack-install/update/model" + "github.com/nothub/mrpack-install/util" + "strings" +) -// GenerateModPackInfo Todo: Generate modPackInfo from modpack -func GenerateModPackInfo() *model.ModPackInfo { +func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { + var modPackInfo model.ModPackInfo - return nil + modrinthIndex, err := mrpack.ReadIndex(modPackPatch) + if err != nil { + return nil, err + } + + modPackInfo.Dependencies = modrinthIndex.Dependencies + modPackInfo.ModPackVersion = modrinthIndex.VersionId + modPackInfo.ModPackName = modrinthIndex.Name + + // Add modrinth.index file + for _, file := range modrinthIndex.Files { + var tmpFileInfo model.FileInfo + tmpFileInfo.FileHash = string(file.Hashes.Sha1) + tmpFileInfo.TargetPath = file.Path + tmpFileInfo.DownloadLink = file.Downloads + + modPackInfo.File = append(modPackInfo.File, tmpFileInfo) + } + + // Add overrides file + r, err := zip.OpenReader(modPackPatch) + if err != nil { + return nil, err + } + defer func(r *zip.ReadCloser) { + err := r.Close() + if err != nil { + fmt.Println(err) + } + }(r) + + for _, f := range r.File { + if f.FileInfo().IsDir() { + continue + } + + filePath := f.Name + if strings.HasPrefix(filePath, "overrides/") { + filePath = strings.TrimPrefix(filePath, "overrides/") + } else if strings.HasPrefix(filePath, "server-overrides/") { + filePath = strings.TrimPrefix(filePath, "server-overrides/") + } else { + continue + } + + var tmpFileInfo model.FileInfo + + readCloser, err := f.Open() + if err != nil { + return nil, err + } + + tmpFileInfo.FileHash, err = util.GetReadCloserSha1(readCloser) + if err != nil { + return nil, err + } + tmpFileInfo.TargetPath = filePath + + modPackInfo.File = append(modPackInfo.File, tmpFileInfo) + } + + return &modPackInfo, nil } // CompareModPackInfo Todo: Compare the two modPackInfo and generate a list of deletions and updates diff --git a/update/model/modPackInfo.go b/update/model/modPackInfo.go index a740c8b..78d02ad 100644 --- a/update/model/modPackInfo.go +++ b/update/model/modPackInfo.go @@ -1,24 +1,25 @@ package model import ( + "bytes" "encoding/json" + "github.com/nothub/mrpack-install/modrinth/mrpack" "github.com/nothub/mrpack-install/requester" "os" "path" ) type ModPackInfo struct { - File *[]fileInfo `json:"file"` - GameVersion string `json:"gameVersion"` - Loader string `json:"loader"` - ModPackName string `json:"modPackName"` + ModPackVersion string `json:"modPackVersion"` + ModPackName string `json:"modPackName"` + File []FileInfo `json:"file"` + Dependencies mrpack.Dependencies `json:"dependencies"` } -type fileInfo struct { +type FileInfo struct { FileHash string `json:"Hash"` - FilePath string `json:"Path"` - DownloadLink []string `json:"DownloadLink"` TargetPath string `json:"TargetPath"` + DownloadLink []string `json:"DownloadLink"` } func ReadModPackInfo(modPackJsonFile string) (*ModPackInfo, error) { @@ -39,13 +40,15 @@ func ReadModPackInfo(modPackJsonFile string) (*ModPackInfo, error) { return &modPackJson, nil } -func WriteModPackInfo(modPack *ModPackInfo, modPackJsonFile string) error { - if modPack != nil { - modPackJsonByte, err := json.Marshal(modPack) +func (modPackInfo *ModPackInfo) Write(modPackJsonFile string) error { + if modPackInfo != nil { + modPackJsonByte, err := json.Marshal(modPackInfo) + var out bytes.Buffer + err = json.Indent(&out, modPackJsonByte, "", "\t") if err != nil { return err } - err = os.WriteFile(modPackJsonFile, modPackJsonByte, 0644) + err = os.WriteFile(modPackJsonFile, out.Bytes(), 0644) if err != nil { return err } @@ -54,9 +57,9 @@ func WriteModPackInfo(modPack *ModPackInfo, modPackJsonFile string) error { } func (modPackInfo *ModPackInfo) GetDownloadPool(downloadPools *requester.DownloadPools) *requester.DownloadPools { - for _, file := range *modPackInfo.File { - if file.FilePath == "" && file.DownloadLink != nil { - downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(file.DownloadLink, map[string]string{"sha1": file.FileHash}, path.Base(file.FilePath), path.Dir(file.FilePath))) + for _, file := range modPackInfo.File { + if file.DownloadLink != nil { + downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(file.DownloadLink, map[string]string{"sha1": file.FileHash}, path.Base(file.TargetPath), path.Dir(file.TargetPath))) } } return downloadPools From 026cd10aba82271834d2891d7e4531fe332a23b6 Mon Sep 17 00:00:00 2001 From: Chikage Date: Thu, 15 Sep 2022 23:47:25 +0800 Subject: [PATCH 05/13] change structure Use Map as a data structure to get better performance during subsequent processing. --- update/modPackInfoUtil.go | 16 ++++------------ update/model/modPackInfo.go | 9 ++++----- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/update/modPackInfoUtil.go b/update/modPackInfoUtil.go index 08798da..44df0e0 100644 --- a/update/modPackInfoUtil.go +++ b/update/modPackInfoUtil.go @@ -11,6 +11,7 @@ import ( func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { var modPackInfo model.ModPackInfo + modPackInfo.File = make(map[string]model.FileInfo) modrinthIndex, err := mrpack.ReadIndex(modPackPatch) if err != nil { @@ -23,12 +24,7 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { // Add modrinth.index file for _, file := range modrinthIndex.Files { - var tmpFileInfo model.FileInfo - tmpFileInfo.FileHash = string(file.Hashes.Sha1) - tmpFileInfo.TargetPath = file.Path - tmpFileInfo.DownloadLink = file.Downloads - - modPackInfo.File = append(modPackInfo.File, tmpFileInfo) + modPackInfo.File[string(file.Hashes.Sha1)] = model.FileInfo{TargetPath: file.Path, DownloadLink: file.Downloads} } // Add overrides file @@ -57,20 +53,16 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { continue } - var tmpFileInfo model.FileInfo - readCloser, err := f.Open() if err != nil { return nil, err } - tmpFileInfo.FileHash, err = util.GetReadCloserSha1(readCloser) + fileHash, err := util.GetReadCloserSha1(readCloser) if err != nil { return nil, err } - tmpFileInfo.TargetPath = filePath - - modPackInfo.File = append(modPackInfo.File, tmpFileInfo) + modPackInfo.File[fileHash] = model.FileInfo{TargetPath: filePath} } return &modPackInfo, nil diff --git a/update/model/modPackInfo.go b/update/model/modPackInfo.go index 78d02ad..34d370d 100644 --- a/update/model/modPackInfo.go +++ b/update/model/modPackInfo.go @@ -12,12 +12,11 @@ import ( type ModPackInfo struct { ModPackVersion string `json:"modPackVersion"` ModPackName string `json:"modPackName"` - File []FileInfo `json:"file"` + File map[string]FileInfo `json:"file"` Dependencies mrpack.Dependencies `json:"dependencies"` } type FileInfo struct { - FileHash string `json:"Hash"` TargetPath string `json:"TargetPath"` DownloadLink []string `json:"DownloadLink"` } @@ -57,9 +56,9 @@ func (modPackInfo *ModPackInfo) Write(modPackJsonFile string) error { } func (modPackInfo *ModPackInfo) GetDownloadPool(downloadPools *requester.DownloadPools) *requester.DownloadPools { - for _, file := range modPackInfo.File { - if file.DownloadLink != nil { - downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(file.DownloadLink, map[string]string{"sha1": file.FileHash}, path.Base(file.TargetPath), path.Dir(file.TargetPath))) + for key, value := range modPackInfo.File { + if value.DownloadLink != nil { + downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(value.DownloadLink, map[string]string{"sha1": key}, path.Base(value.TargetPath), path.Dir(value.TargetPath))) } } return downloadPools From bfc84e3ed38682dc73f8b41d4ecea1b707bfcb2c Mon Sep 17 00:00:00 2001 From: Chikage Date: Thu, 15 Sep 2022 23:48:06 +0800 Subject: [PATCH 06/13] fix: Extra close --- util/sha1.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/util/sha1.go b/util/sha1.go index f934c97..2b9f7ca 100644 --- a/util/sha1.go +++ b/util/sha1.go @@ -36,10 +36,6 @@ func GetReadCloserSha1(readCloser io.ReadCloser) (string, error) { if err != nil { return "", err } - err = readCloser.Close() - if err != nil { - return "", err - } return getSha1(&verifyByte), nil } From a06afeea97041a1ba12b89a31d38e29135fe169c Mon Sep 17 00:00:00 2001 From: Chikage Date: Thu, 15 Sep 2022 23:51:10 +0800 Subject: [PATCH 07/13] fix: add Close --- update/modPackInfoUtil.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/update/modPackInfoUtil.go b/update/modPackInfoUtil.go index 44df0e0..5c01956 100644 --- a/update/modPackInfoUtil.go +++ b/update/modPackInfoUtil.go @@ -62,6 +62,10 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { if err != nil { return nil, err } + err = readCloser.Close() + if err != nil { + return nil, err + } modPackInfo.File[fileHash] = model.FileInfo{TargetPath: filePath} } From cd52de621501e72b2790fcee059c9d008d3d7bb8 Mon Sep 17 00:00:00 2001 From: Chikage Date: Fri, 16 Sep 2022 09:06:50 +0800 Subject: [PATCH 08/13] Implementing CompareModPackInfo --- update/modPackInfoUtil.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/update/modPackInfoUtil.go b/update/modPackInfoUtil.go index 5c01956..052551d 100644 --- a/update/modPackInfoUtil.go +++ b/update/modPackInfoUtil.go @@ -2,10 +2,12 @@ package update import ( "archive/zip" + "errors" "fmt" "github.com/nothub/mrpack-install/modrinth/mrpack" "github.com/nothub/mrpack-install/update/model" "github.com/nothub/mrpack-install/util" + "reflect" "strings" ) @@ -72,8 +74,17 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { return &modPackInfo, nil } -// CompareModPackInfo Todo: Compare the two modPackInfo and generate a list of deletions and updates -func CompareModPackInfo(oldVersion *model.ModPackInfo, newVersion *model.ModPackInfo) (delete *model.ModPackInfo, add *model.ModPackInfo) { +func CompareModPackInfo(oldVersion model.ModPackInfo, newVersion model.ModPackInfo) (deleteList *model.ModPackInfo, addList *model.ModPackInfo, err error) { + if oldVersion.ModPackName != newVersion.ModPackName || !reflect.DeepEqual(oldVersion.Dependencies, newVersion.Dependencies) { + return nil, nil, errors.New("for mismatched versions, please upgrade manually") + } + + for hash := range oldVersion.File { + if reflect.DeepEqual(newVersion.File[hash], oldVersion.File[hash]) { + delete(oldVersion.File, hash) + delete(newVersion.File, hash) + } + } - return nil, nil + return &oldVersion, &newVersion, nil } From 135b0e3a3bfed2516ee12bb82033f1e4e47d5e83 Mon Sep 17 00:00:00 2001 From: Chikage Date: Fri, 16 Sep 2022 09:07:56 +0800 Subject: [PATCH 09/13] Add update to pre-processing ideas --- cmd/update.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmd/update.go b/cmd/update.go index 56ccf74..1d43c8b 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -1,6 +1,7 @@ package cmd import ( + "github.com/nothub/mrpack-install/update/model" "github.com/spf13/cobra" ) @@ -15,3 +16,19 @@ var updateCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { }, } + +// PreDelete Three scenarios +// 1.File does not exist Notice +// 2.File exists but hash value does not match,Change the original file name to xxx.bak +// 3.File exists and the hash value matches +func PreDelete(deleteList *model.ModPackInfo) error { + return nil +} + +// PreUpdate Three scenarios +// 1.File does not exist +// 2.File exists but hash value does not match,Change the original file name to xxx.bak +// 3.File exists and the hash value matches,Remove the item from the queue +func PreUpdate(updateList *model.ModPackInfo) error { + return nil +} From e93b3de9010f621b8a7e40cefabaf67fc355629f Mon Sep 17 00:00:00 2001 From: Chikage Date: Sat, 17 Sep 2022 12:15:39 +0800 Subject: [PATCH 10/13] Complete the update function --- cmd/update.go | 18 +--- update/modPackInfoUtil.go | 16 ++-- update/model/modPackInfo.go | 18 ++-- update/update.go | 158 ++++++++++++++++++++++++++++++++++++ util/file.go | 20 +++++ 5 files changed, 192 insertions(+), 38 deletions(-) create mode 100644 update/update.go diff --git a/cmd/update.go b/cmd/update.go index 1d43c8b..dc87f7d 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -1,7 +1,6 @@ package cmd import ( - "github.com/nothub/mrpack-install/update/model" "github.com/spf13/cobra" ) @@ -14,21 +13,6 @@ var updateCmd = &cobra.Command{ Short: "Update the server", Long: `Use file's hash and compare,Update the config and mods file'`, Run: func(cmd *cobra.Command, args []string) { - }, -} -// PreDelete Three scenarios -// 1.File does not exist Notice -// 2.File exists but hash value does not match,Change the original file name to xxx.bak -// 3.File exists and the hash value matches -func PreDelete(deleteList *model.ModPackInfo) error { - return nil -} - -// PreUpdate Three scenarios -// 1.File does not exist -// 2.File exists but hash value does not match,Change the original file name to xxx.bak -// 3.File exists and the hash value matches,Remove the item from the queue -func PreUpdate(updateList *model.ModPackInfo) error { - return nil + }, } diff --git a/update/modPackInfoUtil.go b/update/modPackInfoUtil.go index 052551d..ced5c20 100644 --- a/update/modPackInfoUtil.go +++ b/update/modPackInfoUtil.go @@ -13,7 +13,7 @@ import ( func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { var modPackInfo model.ModPackInfo - modPackInfo.File = make(map[string]model.FileInfo) + modPackInfo.File = make(model.FileMap) modrinthIndex, err := mrpack.ReadIndex(modPackPatch) if err != nil { @@ -26,7 +26,7 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { // Add modrinth.index file for _, file := range modrinthIndex.Files { - modPackInfo.File[string(file.Hashes.Sha1)] = model.FileInfo{TargetPath: file.Path, DownloadLink: file.Downloads} + modPackInfo.File[model.Path(file.Path)] = model.FileInfo{Hash: string(file.Hashes.Sha1), DownloadLink: file.Downloads} } // Add overrides file @@ -68,21 +68,21 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { if err != nil { return nil, err } - modPackInfo.File[fileHash] = model.FileInfo{TargetPath: filePath} + modPackInfo.File[model.Path(filePath)] = model.FileInfo{Hash: fileHash} } return &modPackInfo, nil } -func CompareModPackInfo(oldVersion model.ModPackInfo, newVersion model.ModPackInfo) (deleteList *model.ModPackInfo, addList *model.ModPackInfo, err error) { +func CompareModPackInfo(oldVersion model.ModPackInfo, newVersion model.ModPackInfo) (deleteFileInfo *model.ModPackInfo, updateFileInfo *model.ModPackInfo, err error) { if oldVersion.ModPackName != newVersion.ModPackName || !reflect.DeepEqual(oldVersion.Dependencies, newVersion.Dependencies) { return nil, nil, errors.New("for mismatched versions, please upgrade manually") } - for hash := range oldVersion.File { - if reflect.DeepEqual(newVersion.File[hash], oldVersion.File[hash]) { - delete(oldVersion.File, hash) - delete(newVersion.File, hash) + for path := range oldVersion.File { + if newVersion.File[path].Hash == oldVersion.File[path].Hash { + delete(oldVersion.File, path) + delete(newVersion.File, path) } } diff --git a/update/model/modPackInfo.go b/update/model/modPackInfo.go index 34d370d..9d44f9a 100644 --- a/update/model/modPackInfo.go +++ b/update/model/modPackInfo.go @@ -4,20 +4,21 @@ import ( "bytes" "encoding/json" "github.com/nothub/mrpack-install/modrinth/mrpack" - "github.com/nothub/mrpack-install/requester" "os" - "path" ) +type Path string +type FileMap map[Path]FileInfo + type ModPackInfo struct { ModPackVersion string `json:"modPackVersion"` ModPackName string `json:"modPackName"` - File map[string]FileInfo `json:"file"` + File FileMap `json:"file"` Dependencies mrpack.Dependencies `json:"dependencies"` } type FileInfo struct { - TargetPath string `json:"TargetPath"` + Hash string `json:"Hash"` DownloadLink []string `json:"DownloadLink"` } @@ -54,12 +55,3 @@ func (modPackInfo *ModPackInfo) Write(modPackJsonFile string) error { } return nil } - -func (modPackInfo *ModPackInfo) GetDownloadPool(downloadPools *requester.DownloadPools) *requester.DownloadPools { - for key, value := range modPackInfo.File { - if value.DownloadLink != nil { - downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(value.DownloadLink, map[string]string{"sha1": key}, path.Base(value.TargetPath), path.Dir(value.TargetPath))) - } - } - return downloadPools -} diff --git a/update/update.go b/update/update.go new file mode 100644 index 0000000..3d35d1f --- /dev/null +++ b/update/update.go @@ -0,0 +1,158 @@ +package update + +import ( + "archive/zip" + "fmt" + "github.com/nothub/mrpack-install/requester" + "github.com/nothub/mrpack-install/update/model" + "github.com/nothub/mrpack-install/util" + "io" + "os" + "path/filepath" + "strings" +) + +type DetectList map[model.Path]util.DetectType + +// PreDelete Three scenarios +// 1.File does not exist Notice +// 2.File exists but hash value does not match,Change the original file name to xxx.bak +// 3.File exists and the hash value matches +func PreDelete(deleteList *model.ModPackInfo) DetectList { + detectType := make(DetectList, 10) + for filePath := range deleteList.File { + switch util.FileDetection(deleteList.File[filePath].Hash, string(filePath)) { + case util.PathMatchHashMatch: + fmt.Printf("%s will remove\n", filePath) + detectType[filePath] = util.PathMatchHashMatch + case util.PathMatchHashNoMatch: + fmt.Printf("%s will remove,The original file will be move to updateBack folder", filePath) + detectType[filePath] = util.PathMatchHashNoMatch + case util.PathNoMatch: + fmt.Printf("%s isn't exist\n", filePath) + } + } + return detectType +} + +// PreUpdate Three scenarios +// 1.File does not exist +// 2.File exists but hash value does not match,Change the original file name to xxx.bak +// 3.File exists and the hash value matches,Remove the item from the queue +func PreUpdate(updateList *model.ModPackInfo) DetectList { + detectType := make(DetectList, 10) + for filePath := range updateList.File { + switch util.FileDetection(updateList.File[filePath].Hash, string(filePath)) { + case util.PathMatchHashMatch: + delete(updateList.File, filePath) + case util.PathMatchHashNoMatch: + fmt.Printf("%s will update,The original file will be move to updateBack folder", filePath) + detectType[filePath] = util.PathMatchHashNoMatch + case util.PathNoMatch: + fmt.Printf("%s will download\n", filePath) + detectType[filePath] = util.PathNoMatch + } + } + return detectType +} + +func ModPackDeleteDo(deleteList DetectList, serverPath string) { + for filePath := range deleteList { + switch deleteList[filePath] { + case util.PathMatchHashMatch: + err := os.Remove(filepath.Join(serverPath, string(filePath))) + if err != nil { + fmt.Println(err) + } + case util.PathMatchHashNoMatch: + err := os.Rename(filepath.Join(serverPath, string(filePath)), filepath.Join(serverPath, "updateBack", string(filePath))) + if err != nil { + fmt.Println(err) + } + } + } +} + +func ModPackUpdateDo(updateList DetectList, updateFileInfo model.FileMap, serverPath string, modPackPath string, downloadPools requester.DownloadPools) error { + //backup file and download file in modrinth index + for filePath := range updateList { + switch updateList[filePath] { + case util.PathNoMatch: + if updateFileInfo[filePath].DownloadLink != nil { + downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(updateFileInfo[filePath].DownloadLink, map[string]string{"sha1": updateFileInfo[filePath].Hash}, filepath.Base(string(filePath)), filepath.Join(serverPath, filepath.Dir(string(filePath))))) + } + case util.PathMatchHashNoMatch: + err := os.Rename(filepath.Join(serverPath, string(filePath)), filepath.Join(serverPath, "updateBack", string(filePath))) + if err != nil { + return err + } + if updateFileInfo[filePath].DownloadLink != nil { + downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(updateFileInfo[filePath].DownloadLink, map[string]string{"sha1": updateFileInfo[filePath].Hash}, filepath.Base(string(filePath)), filepath.Join(serverPath, filepath.Dir(string(filePath))))) + } + } + } + downloadPools.Do() + + // unzip update file + r, err := zip.OpenReader(modPackPath) + if err != nil { + return err + } + defer func(r *zip.ReadCloser) { + err := r.Close() + if err != nil { + fmt.Println(err) + } + }(r) + + for _, f := range r.File { + if f.FileInfo().IsDir() { + continue + } + + filePathInZip := f.Name + if strings.HasPrefix(filePathInZip, "overrides/") { + filePathInZip = strings.TrimPrefix(filePathInZip, "overrides/") + } else if strings.HasPrefix(filePathInZip, "server-overrides/") { + filePathInZip = strings.TrimPrefix(filePathInZip, "server-overrides/") + } else { + continue + } + + if _, ok := updateFileInfo[model.Path(filePathInZip)]; ok && updateFileInfo[model.Path(filePathInZip)].DownloadLink == nil { + + targetPath := filepath.Join(serverPath, filePathInZip) + + err := os.MkdirAll(filepath.Dir(targetPath), 0755) + if err != nil { + return err + } + + fileReader, err := f.Open() + if err != nil { + return err + } + + outFile, err := os.OpenFile(targetPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + if _, err := io.Copy(outFile, fileReader); err != nil { + return err + } + + err = fileReader.Close() + if err != nil { + return err + } + err = outFile.Close() + if err != nil { + return err + } + + fmt.Println("Override file extracted:", targetPath) + + } + } + return nil +} diff --git a/util/file.go b/util/file.go index 7ca1c1e..feb2d81 100644 --- a/util/file.go +++ b/util/file.go @@ -2,6 +2,14 @@ package util import "os" +type DetectType uint8 + +const ( + PathMatchHashMatch DetectType = 0 + PathMatchHashNoMatch DetectType = 1 + PathNoMatch DetectType = 2 +) + func PathIsFile(path string) bool { info, err := os.Stat(path) if err != nil { @@ -17,3 +25,15 @@ func PathIsDir(path string) bool { } return info.Mode().IsDir() } + +func FileDetection(hash string, path string) DetectType { + _, err := os.Stat(path) + if err != nil { + return PathNoMatch + } + if tmp, _ := CheckFileSha1(hash, path); tmp { + return PathMatchHashMatch + } else { + return PathMatchHashNoMatch + } +} From cd3b4b491a2d30d344383a93af5958a5d22cf3e1 Mon Sep 17 00:00:00 2001 From: Chikage Date: Sat, 17 Sep 2022 14:34:22 +0800 Subject: [PATCH 11/13] Implementing update operations --- cmd/update.go | 154 ++++++++++++++++++++++ update/modPackInfoUtil.go | 20 ++- update/{model/modPackInfo.go => model.go} | 2 +- update/update.go | 45 ++++--- util/file.go | 37 +++++- util/sha1.go | 5 + 6 files changed, 234 insertions(+), 29 deletions(-) rename update/{model/modPackInfo.go => model.go} (98%) diff --git a/cmd/update.go b/cmd/update.go index dc87f7d..0d8f4fc 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -1,10 +1,20 @@ package cmd import ( + "fmt" + modrinth "github.com/nothub/mrpack-install/modrinth/api" + "github.com/nothub/mrpack-install/requester" + "github.com/nothub/mrpack-install/update" + "github.com/nothub/mrpack-install/util" "github.com/spf13/cobra" + "log" + "os" + "path" + "strings" ) func init() { + rootCmd.AddCommand(updateCmd) } @@ -13,6 +23,150 @@ var updateCmd = &cobra.Command{ Short: "Update the server", Long: `Use file's hash and compare,Update the config and mods file'`, Run: func(cmd *cobra.Command, args []string) { + if len(args) < 1 { + err := cmd.Help() + if err != nil { + fmt.Println(err) + } + os.Exit(1) + } + input := args[0] + version := "" + if len(args) > 1 { + version = args[1] + } + + host, err := cmd.Flags().GetString("host") + if err != nil { + log.Fatalln(err) + } + serverDir, err := cmd.Flags().GetString("server-dir") + if err != nil { + log.Fatalln(err) + } + proxy, err := cmd.Flags().GetString("proxy") + if err != nil { + log.Fatalln(err) + } + if proxy != "" { + err := requester.DefaultHttpClient.SetProxy(proxy) + if err != nil { + log.Fatalln(err) + } + } + downloadThreads, err := cmd.Flags().GetInt("download-threads") + if err != nil || downloadThreads > 64 { + downloadThreads = 8 + fmt.Println(err) + } + retryTimes, err := cmd.Flags().GetInt("retry-times") + if err != nil { + retryTimes = 3 + fmt.Println(err) + } + + err = os.MkdirAll(serverDir, 0755) + if err != nil { + log.Fatalln(err) + } + + archivePath := "" + if util.PathIsFile(input) { + archivePath = input + + } else if util.IsValidUrl(input) { + fmt.Println("Downloading mrpack file from", args) + file, err := requester.DefaultHttpClient.DownloadFile(input, serverDir, "") + if err != nil { + log.Fatalln(err) + } + archivePath = file + + } else { // input is project id or slug? + versions, err := modrinth.NewClient(host).GetProjectVersions(input, nil) + if err != nil { + log.Fatalln(err) + } + + // get files uploaded for specified version or latest stable if not specified + var files []modrinth.File = nil + for i := range versions { + if version != "" { + if versions[i].VersionNumber == version { + files = versions[i].Files + break + } + } else { + if versions[i].VersionType == modrinth.ReleaseVersionType { + files = versions[i].Files + break + } + } + } + if len(files) == 0 { + log.Fatalln("No files found for", input, version) + } + + for i := range files { + if strings.HasSuffix(files[i].Filename, ".mrpack") { + fmt.Println("Downloading mrpack file from", files[i].Url) + file, err := requester.DefaultHttpClient.DownloadFile(files[i].Url, serverDir, "") + if err != nil { + log.Fatalln(err) + } + archivePath = file + break + } + } + if archivePath == "" { + log.Fatalln("No mrpack file found for", input, version) + } + } + + if archivePath == "" { + log.Fatalln("An error occured!") + } + + fmt.Println("Processing mrpack file", archivePath) + + var downloads []*requester.Download + downloadPools := requester.NewDownloadPools(requester.DefaultHttpClient, downloads, downloadThreads, retryTimes) + + newModPackInfo, err := update.GenerateModPackInfo(archivePath) + if err != nil { + log.Fatalln(err) + } + oldModPackInfo, err := update.ReadModPackInfo(path.Join(serverDir, "modpack.json")) + if err != nil { + log.Fatalln(err) + } + deleteFileInfo, updateFileInfo, err := update.CompareModPackInfo(*oldModPackInfo, *newModPackInfo) + if err != nil { + return + } + deleteList := update.PreDelete(deleteFileInfo, serverDir) + updateList := update.PreUpdate(updateFileInfo, serverDir) + + fmt.Printf("Would you like to update: [y/N]") + var userInput string + _, err = fmt.Scanln(&userInput) + if err != nil { + log.Fatalln(err) + } + if userInput != "y" { + return + } + + err = update.ModPackDeleteDo(deleteList, serverDir) + if err != nil { + log.Fatalln(err) + } + err = update.ModPackUpdateDo(updateList, updateFileInfo.File, serverDir, archivePath, downloadPools) + if err != nil { + log.Fatalln(err) + } + util.RemoveEmptyDir(serverDir) + fmt.Println("Done :) Have a nice day ✌️") }, } diff --git a/update/modPackInfoUtil.go b/update/modPackInfoUtil.go index ced5c20..2b81561 100644 --- a/update/modPackInfoUtil.go +++ b/update/modPackInfoUtil.go @@ -5,15 +5,14 @@ import ( "errors" "fmt" "github.com/nothub/mrpack-install/modrinth/mrpack" - "github.com/nothub/mrpack-install/update/model" "github.com/nothub/mrpack-install/util" "reflect" "strings" ) -func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { - var modPackInfo model.ModPackInfo - modPackInfo.File = make(model.FileMap) +func GenerateModPackInfo(modPackPatch string) (*ModPackInfo, error) { + var modPackInfo ModPackInfo + modPackInfo.File = make(FileMap) modrinthIndex, err := mrpack.ReadIndex(modPackPatch) if err != nil { @@ -26,7 +25,10 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { // Add modrinth.index file for _, file := range modrinthIndex.Files { - modPackInfo.File[model.Path(file.Path)] = model.FileInfo{Hash: string(file.Hashes.Sha1), DownloadLink: file.Downloads} + if file.Env.Server == "unsupported" { + continue + } + modPackInfo.File[Path(file.Path)] = FileInfo{Hash: string(file.Hashes.Sha1), DownloadLink: file.Downloads} } // Add overrides file @@ -68,13 +70,13 @@ func GenerateModPackInfo(modPackPatch string) (*model.ModPackInfo, error) { if err != nil { return nil, err } - modPackInfo.File[model.Path(filePath)] = model.FileInfo{Hash: fileHash} + modPackInfo.File[Path(filePath)] = FileInfo{Hash: fileHash} } return &modPackInfo, nil } -func CompareModPackInfo(oldVersion model.ModPackInfo, newVersion model.ModPackInfo) (deleteFileInfo *model.ModPackInfo, updateFileInfo *model.ModPackInfo, err error) { +func CompareModPackInfo(oldVersion ModPackInfo, newVersion ModPackInfo) (deleteFileInfo *ModPackInfo, updateFileInfo *ModPackInfo, err error) { if oldVersion.ModPackName != newVersion.ModPackName || !reflect.DeepEqual(oldVersion.Dependencies, newVersion.Dependencies) { return nil, nil, errors.New("for mismatched versions, please upgrade manually") } @@ -84,6 +86,10 @@ func CompareModPackInfo(oldVersion model.ModPackInfo, newVersion model.ModPackIn delete(oldVersion.File, path) delete(newVersion.File, path) } + + if _, ok := newVersion.File[path]; ok { + delete(oldVersion.File, path) + } } return &oldVersion, &newVersion, nil diff --git a/update/model/modPackInfo.go b/update/model.go similarity index 98% rename from update/model/modPackInfo.go rename to update/model.go index 9d44f9a..789b88c 100644 --- a/update/model/modPackInfo.go +++ b/update/model.go @@ -1,4 +1,4 @@ -package model +package update import ( "bytes" diff --git a/update/update.go b/update/update.go index 3d35d1f..cd41409 100644 --- a/update/update.go +++ b/update/update.go @@ -4,7 +4,6 @@ import ( "archive/zip" "fmt" "github.com/nothub/mrpack-install/requester" - "github.com/nothub/mrpack-install/update/model" "github.com/nothub/mrpack-install/util" "io" "os" @@ -12,24 +11,23 @@ import ( "strings" ) -type DetectList map[model.Path]util.DetectType +type DetectList map[Path]util.DetectType // PreDelete Three scenarios // 1.File does not exist Notice // 2.File exists but hash value does not match,Change the original file name to xxx.bak // 3.File exists and the hash value matches -func PreDelete(deleteList *model.ModPackInfo) DetectList { +func PreDelete(deleteList *ModPackInfo, serverPath string) DetectList { detectType := make(DetectList, 10) for filePath := range deleteList.File { - switch util.FileDetection(deleteList.File[filePath].Hash, string(filePath)) { + t := util.FileDetection(deleteList.File[filePath].Hash, filepath.Join(serverPath, string(filePath))) + switch t { case util.PathMatchHashMatch: - fmt.Printf("%s will remove\n", filePath) + fmt.Printf("[Delete]: %s \n", filePath) detectType[filePath] = util.PathMatchHashMatch case util.PathMatchHashNoMatch: - fmt.Printf("%s will remove,The original file will be move to updateBack folder", filePath) + fmt.Printf("[Delete]: %s ,The original file will be move to updateBack folder\n", filePath) detectType[filePath] = util.PathMatchHashNoMatch - case util.PathNoMatch: - fmt.Printf("%s isn't exist\n", filePath) } } return detectType @@ -39,41 +37,46 @@ func PreDelete(deleteList *model.ModPackInfo) DetectList { // 1.File does not exist // 2.File exists but hash value does not match,Change the original file name to xxx.bak // 3.File exists and the hash value matches,Remove the item from the queue -func PreUpdate(updateList *model.ModPackInfo) DetectList { +func PreUpdate(updateList *ModPackInfo, serverPath string) DetectList { detectType := make(DetectList, 10) for filePath := range updateList.File { - switch util.FileDetection(updateList.File[filePath].Hash, string(filePath)) { + switch util.FileDetection(updateList.File[filePath].Hash, filepath.Join(serverPath, string(filePath))) { case util.PathMatchHashMatch: delete(updateList.File, filePath) case util.PathMatchHashNoMatch: - fmt.Printf("%s will update,The original file will be move to updateBack folder", filePath) + fmt.Printf("[Update]: %s ,The original file will be move to updateBack folder\n", filePath) detectType[filePath] = util.PathMatchHashNoMatch case util.PathNoMatch: - fmt.Printf("%s will download\n", filePath) + fmt.Printf("[Download]: %s \n", filePath) detectType[filePath] = util.PathNoMatch } } return detectType } -func ModPackDeleteDo(deleteList DetectList, serverPath string) { +func ModPackDeleteDo(deleteList DetectList, serverPath string) error { for filePath := range deleteList { switch deleteList[filePath] { case util.PathMatchHashMatch: err := os.Remove(filepath.Join(serverPath, string(filePath))) if err != nil { - fmt.Println(err) + return err } case util.PathMatchHashNoMatch: - err := os.Rename(filepath.Join(serverPath, string(filePath)), filepath.Join(serverPath, "updateBack", string(filePath))) + err := os.MkdirAll(filepath.Dir(filepath.Join(serverPath, "updateBack", string(filePath))), 0755) + if err != nil { + return err + } + err = os.Rename(filepath.Join(serverPath, string(filePath)), filepath.Join(serverPath, "updateBack", string(filePath))) if err != nil { - fmt.Println(err) + return err } } } + return nil } -func ModPackUpdateDo(updateList DetectList, updateFileInfo model.FileMap, serverPath string, modPackPath string, downloadPools requester.DownloadPools) error { +func ModPackUpdateDo(updateList DetectList, updateFileInfo FileMap, serverPath string, modPackPath string, downloadPools *requester.DownloadPools) error { //backup file and download file in modrinth index for filePath := range updateList { switch updateList[filePath] { @@ -82,7 +85,11 @@ func ModPackUpdateDo(updateList DetectList, updateFileInfo model.FileMap, server downloadPools.Downloads = append(downloadPools.Downloads, requester.NewDownload(updateFileInfo[filePath].DownloadLink, map[string]string{"sha1": updateFileInfo[filePath].Hash}, filepath.Base(string(filePath)), filepath.Join(serverPath, filepath.Dir(string(filePath))))) } case util.PathMatchHashNoMatch: - err := os.Rename(filepath.Join(serverPath, string(filePath)), filepath.Join(serverPath, "updateBack", string(filePath))) + err := os.MkdirAll(filepath.Dir(filepath.Join(serverPath, "updateBack", string(filePath))), 0755) + if err != nil { + return err + } + err = os.Rename(filepath.Join(serverPath, string(filePath)), filepath.Join(serverPath, "updateBack", string(filePath))) if err != nil { return err } @@ -119,7 +126,7 @@ func ModPackUpdateDo(updateList DetectList, updateFileInfo model.FileMap, server continue } - if _, ok := updateFileInfo[model.Path(filePathInZip)]; ok && updateFileInfo[model.Path(filePathInZip)].DownloadLink == nil { + if _, ok := updateFileInfo[Path(filePathInZip)]; ok && updateFileInfo[Path(filePathInZip)].DownloadLink == nil { targetPath := filepath.Join(serverPath, filePathInZip) diff --git a/util/file.go b/util/file.go index feb2d81..1bc6e8c 100644 --- a/util/file.go +++ b/util/file.go @@ -1,8 +1,13 @@ package util -import "os" +import ( + "fmt" + "os" + "path/filepath" + "strings" +) -type DetectType uint8 +type DetectType int8 const ( PathMatchHashMatch DetectType = 0 @@ -37,3 +42,31 @@ func FileDetection(hash string, path string) DetectType { return PathMatchHashNoMatch } } + +func RemoveEmptyDir(dir string) { + fileNames := make([]string, 0) + dirNames := make([]string, 0) + + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if info.IsDir() { + dirNames = append(dirNames, path) + } else { + fileNames = append(fileNames, path) + } + return err + }) + if err != nil { + panic(err) + } + + fileNamesAll := strings.Join(fileNames, "") + + for i := len(dirNames) - 1; i >= 0; i-- { + if !strings.Contains(fileNamesAll, dirNames[i]) { + err := os.Remove(dirNames[i]) + if err != nil { + fmt.Println(err) + } + } + } +} diff --git a/util/sha1.go b/util/sha1.go index 2b9f7ca..bcfcfe8 100644 --- a/util/sha1.go +++ b/util/sha1.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "log" "os" ) @@ -40,6 +41,10 @@ func GetReadCloserSha1(readCloser io.ReadCloser) (string, error) { } func CheckFileSha1(verifyHash string, verifyFile string) (bool, error) { + _, err := os.Stat(verifyFile) + if err != nil { + log.Fatalln("The validated file does not exist", verifyFile) + } file, err := os.Open(verifyFile) defer func(file *os.File) { err := file.Close() From 091b951a6150becc3477a645c70d1a01e3abcfdc Mon Sep 17 00:00:00 2001 From: Chikage Date: Sat, 17 Sep 2022 15:47:37 +0800 Subject: [PATCH 12/13] Update modpack.json after the update is complete --- cmd/update.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/update.go b/cmd/update.go index 0d8f4fc..a2ccfe5 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -166,6 +166,11 @@ var updateCmd = &cobra.Command{ log.Fatalln(err) } util.RemoveEmptyDir(serverDir) + + err = newModPackInfo.Write(path.Join(serverDir, "modpack.json")) + if err != nil { + fmt.Println(err) + } fmt.Println("Done :) Have a nice day ✌️") }, From dc0b7898f9d17f82e7d9a8e454b578e7c3b84dbe Mon Sep 17 00:00:00 2001 From: Chikage Date: Sat, 17 Sep 2022 16:49:58 +0800 Subject: [PATCH 13/13] Update modpack.json and when finished del mrpack --- cmd/root.go | 12 ++++++++++++ cmd/update.go | 23 +++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index a0abf55..fb5b49e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -116,6 +116,12 @@ var rootCmd = &cobra.Command{ log.Fatalln(err) } archivePath = file + defer func(name string) { + err := os.Remove(name) + if err != nil { + fmt.Println(err) + } + }(archivePath) } else { // input is project id or slug? versions, err := modrinth.NewClient(host).GetProjectVersions(input, nil) @@ -156,6 +162,12 @@ var rootCmd = &cobra.Command{ if archivePath == "" { log.Fatalln("No mrpack file found for", input, version) } + defer func(name string) { + err := os.Remove(name) + if err != nil { + fmt.Println(err) + } + }(archivePath) } if archivePath == "" { diff --git a/cmd/update.go b/cmd/update.go index a2ccfe5..558aaa8 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -81,7 +81,12 @@ var updateCmd = &cobra.Command{ log.Fatalln(err) } archivePath = file - + defer func(name string) { + err := os.Remove(name) + if err != nil { + fmt.Println(err) + } + }(archivePath) } else { // input is project id or slug? versions, err := modrinth.NewClient(host).GetProjectVersions(input, nil) if err != nil { @@ -121,6 +126,12 @@ var updateCmd = &cobra.Command{ if archivePath == "" { log.Fatalln("No mrpack file found for", input, version) } + defer func(name string) { + err := os.Remove(name) + if err != nil { + fmt.Println(err) + } + }(archivePath) } if archivePath == "" { @@ -136,6 +147,10 @@ var updateCmd = &cobra.Command{ if err != nil { log.Fatalln(err) } + err = newModPackInfo.Write(path.Join(serverDir, "modpack.json.update")) + if err != nil { + log.Fatalln(err) + } oldModPackInfo, err := update.ReadModPackInfo(path.Join(serverDir, "modpack.json")) if err != nil { log.Fatalln(err) @@ -167,11 +182,11 @@ var updateCmd = &cobra.Command{ } util.RemoveEmptyDir(serverDir) - err = newModPackInfo.Write(path.Join(serverDir, "modpack.json")) + err = os.Rename(path.Join(serverDir, "modpack.json.update"), path.Join(serverDir, "modpack.json")) if err != nil { - fmt.Println(err) + log.Fatalln(err) } - fmt.Println("Done :) Have a nice day ✌️") + fmt.Println("Done :) Have a nice day ✌️") }, }