Files
factorio-server-manager/src/mod_modInfo.go

231 lines
4.9 KiB
Go
Raw Normal View History

package main
import (
2017-12-22 19:32:33 +01:00
"archive/zip"
"encoding/json"
"errors"
"io"
"io/ioutil"
"lockfile"
"log"
"os"
2019-03-22 00:36:38 +01:00
"path"
2017-12-22 19:32:33 +01:00
"path/filepath"
2018-03-08 01:06:36 +01:00
"strings"
)
type ModInfoList struct {
2017-12-22 19:32:33 +01:00
Mods []ModInfo `json:"mods"`
Destination string `json:"-"`
}
type ModInfo struct {
Name string `json:"name"`
Version string `json:"version"`
Title string `json:"title"`
Author string `json:"author"`
FileName string `json:"file_name"`
FactorioVersion Version `json:"factorio_version"`
Dependencies []string `json:"dependencies"`
Compatibility bool `json:"compatibility"`
}
func newModInfoList(destination string) (ModInfoList, error) {
2017-12-22 19:32:33 +01:00
var err error
2017-12-22 20:13:49 +01:00
modInfoList := ModInfoList{
2017-12-22 19:32:33 +01:00
Destination: destination,
}
2017-12-22 20:13:49 +01:00
err = modInfoList.listInstalledMods()
2017-12-22 19:32:33 +01:00
if err != nil {
log.Printf("ModInfoList ... error listing installed Mods: %s", err)
2017-12-22 20:13:49 +01:00
return modInfoList, err
2017-12-22 19:32:33 +01:00
}
2017-12-22 20:13:49 +01:00
return modInfoList, nil
}
2017-12-22 20:13:49 +01:00
func (modInfoList *ModInfoList) listInstalledMods() error {
2017-12-22 19:32:33 +01:00
var err error
2017-12-22 20:13:49 +01:00
modInfoList.Mods = nil
2017-12-22 19:32:33 +01:00
2017-12-22 20:13:49 +01:00
err = filepath.Walk(modInfoList.Destination, func(path string, info os.FileInfo, err error) error {
2017-12-22 19:32:33 +01:00
if !info.IsDir() && filepath.Ext(path) == ".zip" {
2018-03-08 01:06:36 +01:00
2017-12-22 19:32:33 +01:00
err = fileLock.RLock(path)
if err != nil && err == lockfile.ErrorAlreadyLocked {
log.Println(err)
return nil
} else if err != nil {
log.Printf("error locking file: %s", err)
return err
}
defer fileLock.RUnlock(path)
2017-12-22 20:13:49 +01:00
zipFile, err := zip.OpenReader(path)
2017-12-22 19:32:33 +01:00
if err != nil {
log.Fatalln(err)
return err
}
2017-12-22 20:13:49 +01:00
var modInfo ModInfo
err = modInfo.getModInfo(&zipFile.Reader)
2017-12-22 19:32:33 +01:00
if err != nil {
log.Fatalf("Error in getModInfo: %s", err)
}
2017-12-22 20:13:49 +01:00
modInfo.FileName = info.Name()
2018-03-08 01:06:36 +01:00
var base Version
var op string
for _, dep := range modInfo.Dependencies {
dep = strings.TrimSpace(dep)
if dep == "" {
continue
}
parts := strings.Split(dep, " ")
if len(parts) > 3 {
log.Printf("skipping dependency '%s' in '%s': invalid format\n", dep, modInfo.Name)
continue
}
if parts[0] != "base" {
continue
}
if len(parts) == 1 {
base = modInfo.FactorioVersion
op = ">="
continue
}
op = parts[1]
if err := base.UnmarshalText([]byte(parts[2])); err != nil {
log.Printf("skipping dependency '%s' in '%s': %v\n", dep, modInfo.Name, err)
continue
}
break
}
if !base.Equals(NilVersion) {
modInfo.Compatibility = FactorioServ.Version.Compare(base, op)
} else {
2018-05-25 15:52:46 +02:00
log.Println("error finding basemodDependency. Using FactorioVersion...")
modInfo.Compatibility = !FactorioServ.Version.Less(modInfo.FactorioVersion)
2018-03-08 01:06:36 +01:00
}
2017-12-22 20:13:49 +01:00
modInfoList.Mods = append(modInfoList.Mods, modInfo)
2017-12-22 19:32:33 +01:00
}
return nil
})
if err != nil {
log.Printf("error while walking over the given dir: %s", err)
return err
}
return nil
}
2017-12-22 20:13:49 +01:00
func (modInfoList *ModInfoList) deleteMod(modName string) error {
2017-12-22 19:32:33 +01:00
var err error
//search for mod, that should be deleted
2017-12-22 20:13:49 +01:00
for _, mod := range modInfoList.Mods {
if mod.Name == modName {
2019-03-22 00:36:38 +01:00
filePath := path.Join(modInfoList.Destination, mod.FileName)
2017-12-22 19:32:33 +01:00
fileLock.LockW(filePath)
//delete mod
err = os.Remove(filePath)
fileLock.Unlock(filePath)
if err != nil {
log.Printf("ModInfoList ... error when deleting mod: %s", err)
return err
}
//reload mod-list
2017-12-22 20:13:49 +01:00
err = modInfoList.listInstalledMods()
2017-12-22 19:32:33 +01:00
if err != nil {
log.Printf("ModInfoList ... error while refreshing installedModList: %s", err)
return err
}
return nil
}
}
2018-01-10 16:15:31 +01:00
log.Printf("the mod-file for mod %s doesn't exists!", modName)
2017-12-22 19:32:33 +01:00
return nil
}
2017-12-22 20:13:49 +01:00
func (modInfo *ModInfo) getModInfo(reader *zip.Reader) error {
for _, singleFile := range reader.File {
if singleFile.FileInfo().Name() == "info.json" {
2017-12-22 19:32:33 +01:00
//interpret info.json
2017-12-22 20:13:49 +01:00
rc, err := singleFile.Open()
2017-12-22 19:32:33 +01:00
if err != nil {
log.Fatal(err)
return err
}
2017-12-22 20:13:49 +01:00
byteArray, err := ioutil.ReadAll(rc)
2017-12-22 19:32:33 +01:00
rc.Close()
if err != nil {
log.Fatal(err)
return err
}
2017-12-22 20:13:49 +01:00
err = json.Unmarshal(byteArray, modInfo)
2017-12-22 19:32:33 +01:00
if err != nil {
log.Fatalln(err)
return err
}
return nil
}
}
return errors.New("info.json not found in zip-file")
}
2017-12-22 20:13:49 +01:00
func (modInfoList *ModInfoList) createMod(modName string, fileName string, modFile io.Reader) error {
2017-12-22 19:32:33 +01:00
var err error
//save uploaded file
2019-03-22 00:36:38 +01:00
filePath := path.Join(modInfoList.Destination, fileName)
2017-12-22 20:13:49 +01:00
newFile, err := os.Create(filePath)
2017-12-22 19:32:33 +01:00
if err != nil {
2017-12-22 20:13:49 +01:00
log.Printf("error on creating new file - %s: %s", fileName, err)
2017-12-22 19:32:33 +01:00
return err
}
2017-12-22 20:13:49 +01:00
defer newFile.Close()
2017-12-22 19:32:33 +01:00
fileLock.LockW(filePath)
2017-12-22 20:13:49 +01:00
_, err = io.Copy(newFile, modFile)
2017-12-22 19:32:33 +01:00
if err != nil {
log.Printf("error on copying file to disk: %s", err)
return err
}
2017-12-22 20:13:49 +01:00
err = newFile.Close()
2017-12-22 19:32:33 +01:00
if err != nil {
log.Printf("error on closing new created zip-file: %s", err)
return err
}
fileLock.Unlock(filePath)
//reload the list
2017-12-22 20:13:49 +01:00
err = modInfoList.listInstalledMods()
2017-12-22 19:32:33 +01:00
if err != nil {
log.Printf("error on listing mod-infos: %s", err)
return err
}
return nil
}