restructured and rebuilt project && modPacks downloadable

This commit is contained in:
knoxfighter 2017-09-24 20:10:50 +02:00
parent 737b4d5bb2
commit f11381b014
10 changed files with 987 additions and 925 deletions

View File

@ -12,6 +12,7 @@ import (
"strconv"
"time"
"github.com/gorilla/mux"
"archive/zip"
)
type JSONResponse struct {
@ -34,9 +35,10 @@ func listInstalledModsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
mod_list, err := listInstalledModsByFolder()
resp.Data = mod_list.Mods
mods, err := newMods(config.FactorioModsDir)
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in ListInstalledMods handler: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in list mods: %s", err)
@ -44,6 +46,7 @@ func listInstalledModsHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mods.listInstalledMods().ModsResult
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -69,6 +72,7 @@ func LoginFactorioModPortal(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(statusCode)
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in getUserToken or LoginFactorioModPortal handler: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in Factorio-Login: %s", err)
@ -101,6 +105,7 @@ func ModPortalSearchHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(statusCode)
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in searchModPortal: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in searchModPortal: %s", err)
@ -133,6 +138,7 @@ func ModPortalDetailsHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(statusCode)
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in searchModPortal: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in searchModPortal: %s", err)
@ -162,12 +168,13 @@ func ModPortalInstallHandler(w http.ResponseWriter, r *http.Request) {
filename := r.FormValue("filename")
mod_name := r.FormValue("modName")
var statusCode int
resp.Data, err, statusCode = installMod(username, userKey, downloadUrl, filename, mod_name)
w.WriteHeader(statusCode)
mods, err := newMods(config.FactorioModsDir)
if err == nil {
err = mods.downloadMod(username, userKey, downloadUrl, filename, mod_name)
}
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in installMod: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in installMod: %s", err)
@ -193,16 +200,21 @@ func ToggleModHandler(w http.ResponseWriter, r *http.Request) {
//Get Data out of the request
mod_name := r.FormValue("mod_name")
resp.Data, err = toggleMod(mod_name)
mods, err := newMods(config.FactorioModsDir)
if err == nil {
err = mods.ModSimpleList.toggleMod(mod_name)
}
if err != nil {
resp.Data = fmt.Sprintf("Error in toggleMod: %s", err)
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in listInstalledModsByFolder: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in toggleMod: %s", err)
log.Printf("Error in listInstalledModsByFolder: %s", err)
}
return
}
resp.Data = mods.listInstalledMods().ModsResult
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -221,9 +233,13 @@ func DeleteModHandler(w http.ResponseWriter, r *http.Request) {
//Get Data out of the request
mod_name := r.FormValue("mod_name")
resp.Data, err = deleteMod(mod_name)
mods, err := newMods(config.FactorioModsDir)
if err == nil {
mods.deleteMod(mod_name)
}
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in deleteMod: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in DeleteModHandler: %s", err)
@ -231,6 +247,7 @@ func DeleteModHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mods.listInstalledMods().ModsResult
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -253,21 +270,13 @@ func UpdateModHandler(w http.ResponseWriter, r *http.Request) {
download_url := r.FormValue("downloadUrl")
file_name := r.FormValue("filename")
_, err = deleteMod(mod_name)
if err != nil {
resp.Data = fmt.Sprintf("Error in deleteMod, installing Mod will not be executed: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in deleteMod, installing Mod will not be executed: %s", err)
}
return
}
var statusCode int
resp.Data, err, statusCode = installMod(username, user_key, download_url, file_name, mod_name)
w.WriteHeader(statusCode)
mods, err := newMods(config.FactorioModsDir)
if err == nil {
err = mods.updateMod(mod_name, username, user_key, download_url, file_name)
}
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in deleteMod: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in DeleteModHandler: %s", err)
@ -275,6 +284,7 @@ func UpdateModHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mods.listInstalledMods()
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -292,16 +302,17 @@ func UploadModHandler(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(32 << 20)
//get file out of the POST
for file_key, mod_file := range r.MultipartForm.File["mod_file"] {
err = uploadMod(mod_file)
if err != nil {
resp.ErrorKeys = append(resp.ErrorKeys, file_key)
resp.Error = "An error occurred during upload or saving, pls check manually, if all went well and delete invalid files. (This program also could be crashed)"
mods, err := newMods(config.FactorioModsDir)
if err == nil {
for file_key, mod_file := range r.MultipartForm.File["mod_file"] {
err = mods.uploadMod(mod_file)
if err != nil {
resp.ErrorKeys = append(resp.ErrorKeys, file_key)
resp.Error = "An error occurred during upload or saving, pls check manually, if all went well and delete invalid files. (This program also could be crashed)"
}
}
}
resp.Data, err = listInstalledModsByFolder()
if err != nil {
w.WriteHeader(500)
resp.Data = fmt.Sprintf("Error in uploadMod, listing mods wasn't successful: %s", err)
@ -311,6 +322,7 @@ func UploadModHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mods.listInstalledMods()
resp.Success = true
if err = json.NewEncoder(w).Encode(resp); err != nil {
@ -326,12 +338,10 @@ func ListModPacksHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
var mod_packs ModPackList
err = mod_packs.getModPacks()
resp.Data = mod_packs
mod_pack_map, err := newModPackMap()
if err != nil {
w.WriteHeader(500)
w.WriteHeader(http.StatusInternalServerError)
resp.Data = fmt.Sprintf("Error listing modpack files: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -340,6 +350,7 @@ func ListModPacksHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mod_pack_map.listInstalledModPacks()
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -357,7 +368,11 @@ func CreateModPackHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
resp.Data, err = createModPack(name)
mod_pack_map, err := newModPackMap()
if err == nil {
err = mod_pack_map.createModPack(name)
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
resp.Data = fmt.Sprintf("Error creating modpack file: %s", err)
@ -367,6 +382,7 @@ func CreateModPackHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mod_pack_map.listInstalledModPacks()
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -375,16 +391,61 @@ func CreateModPackHandler(w http.ResponseWriter, r *http.Request) {
}
func DownloadModPackHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/zip;charset=UTF-8")
var err error
vars := mux.Vars(r)
modpack := vars["modpack"]
modFile := config.FactorioModPackDir + "/" + modpack + ".zip"
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", modpack + ".zip"))
log.Printf("%s downloading: %s", r.Host, modFile)
mod_pack_map, err := newModPackMap()
if err != nil {
log.Printf("error on loading modPacks: %s", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
http.ServeFile(w, r, modFile)
if mod_pack_map.checkModPackExists(modpack) {
zip_writer := zip.NewWriter(w)
defer zip_writer.Close()
//iterate over folder and create everything in the zip
err = filepath.Walk(filepath.Join(config.FactorioModPackDir, modpack), func(path string, info os.FileInfo, err error) error {
if info.IsDir() == false {
writer, err := zip_writer.Create(info.Name())
if err != nil {
log.Printf("error on creating new file inside zip: %s", err)
return err
}
file, err := os.Open(path)
if err != nil {
log.Printf("error on opening modfile: %s", err)
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
if err != nil {
log.Printf("error on copying file into zip: %s", err)
return err
}
}
return nil
})
if err != nil {
log.Printf("error on walking over the modpack: %s", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
} else {
log.Printf("requested modPack doesnt exist")
w.WriteHeader(http.StatusNotFound)
return
}
writer_header := w.Header()
writer_header.Set("Content-Type", "application/zip;charset=UTF-8")
writer_header.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", modpack + ".zip"))
}
func DeleteModPackHandler(w http.ResponseWriter, r *http.Request) {
@ -397,7 +458,11 @@ func DeleteModPackHandler(w http.ResponseWriter, r *http.Request) {
name := r.FormValue("name")
resp.Data, err = deleteModPack(name)
mod_pack_map, err := newModPackMap()
if err == nil {
err = mod_pack_map.deleteModPack(name)
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
resp.Data = fmt.Sprintf("Error deleting modpack file: %s", err)
@ -407,6 +472,7 @@ func DeleteModPackHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mod_pack_map.listInstalledModPacks()
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -424,7 +490,11 @@ func LoadModPackHandler(w http.ResponseWriter, r *http.Request) {
name := r.FormValue("name")
resp.Data, err = loadModPack(name)
mod_pack_map, err := newModPackMap()
if err == nil {
mod_pack_map[name].loadModPack()
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
resp.Data = fmt.Sprintf("Error loading modpack file: %s", err)
@ -434,6 +504,7 @@ func LoadModPackHandler(w http.ResponseWriter, r *http.Request) {
return
}
resp.Data = mod_pack_map[name].Mods.listInstalledMods()
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
@ -441,6 +512,38 @@ func LoadModPackHandler(w http.ResponseWriter, r *http.Request) {
}
}
func ModPackToggleModHandler(w http.ResponseWriter, r *http.Request) {
var err error
resp := JSONResponse{
Success: false,
}
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
mod_name := r.FormValue("mod_name")
mod_pack_name := r.FormValue("mod_pack")
mod_pack_map, err := newModPackMap()
if err == nil {
err = mod_pack_map[mod_pack_name].Mods.ModSimpleList.toggleMod(mod_name)
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
resp.Data = fmt.Sprintf("Error loading modpack file: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error loading modpack: %s", err)
}
return
}
resp.Data = mod_pack_map[mod_pack_name].Mods.listInstalledMods()
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error creating loading modpack response: %s", err)
}
}
// Lists all save files in the factorio/saves directory
func ListSaves(w http.ResponseWriter, r *http.Request) {
var err error

212
src/mod_Mods.go Normal file
View File

@ -0,0 +1,212 @@
package main
import (
"log"
"net/http"
"io"
"io/ioutil"
"mime/multipart"
"bytes"
"archive/zip"
)
type Mods struct {
ModSimpleList ModSimpleList `json:"mod_simple_list"`
ModInfoList ModInfoList `json:"mod_info_list"`
}
type ModsResult struct {
ModInfo
Enabled bool `json:"enabled"`
}
type ModsResultList struct {
ModsResult []ModsResult `json:"mods"`
}
func newMods(destination string) (Mods, error) {
var err error
var mods Mods
mods.ModSimpleList, err = newModSimpleList(destination)
if err != nil {
log.Printf("error on creating newModSimpleList: %s", err)
return mods, err
}
mods.ModInfoList, err = newModInfoList(destination)
if err != nil {
log.Printf("error on creating newModInfoList: %s", err)
return mods, err
}
return mods, nil
}
func (mods *Mods) listInstalledMods() ModsResultList {
var result ModsResultList
for _, mod_info := range mods.ModInfoList.Mods {
var mods_result ModsResult
mods_result.Name = mod_info.Name
mods_result.FileName = mod_info.FileName
mods_result.Author = mod_info.Author
mods_result.Title = mod_info.Title
mods_result.Version = mod_info.Version
for _, simple_mod := range mods.ModSimpleList.Mods {
if simple_mod.Name == mods_result.Name {
mods_result.Enabled = simple_mod.Enabled
break
}
}
result.ModsResult = append(result.ModsResult, mods_result)
}
return result
}
func (mods *Mods) deleteMod(mod_name string) (error) {
var err error
err = mods.ModInfoList.deleteMod(mod_name)
if err != nil {
log.Printf("error when deleting mod in ModInfoList: %s", err)
return err
}
err = mods.ModSimpleList.deleteMod(mod_name)
if err != nil {
log.Printf("error when deleting mod in ModSimpleList: %s", err)
return err
}
return nil
}
func (mods *Mods) createMod(mod_name string, file_name string, file_rc io.Reader) (error) {
var err error
//check if mod already exists and delete it
if mods.ModSimpleList.checkModExists(mod_name) {
err = mods.ModSimpleList.deleteMod(mod_name)
if err != nil {
log.Printf("error when deleting mod: %s", err)
return err
}
err = mods.ModInfoList.deleteMod(mod_name)
if err != nil {
log.Printf("error when deleting mod: %s", err)
return err
}
}
//create new mod
err = mods.ModInfoList.createMod(mod_name, file_name, file_rc)
if err != nil {
log.Printf("error on creating mod-file: %s", err)
return err
}
err = mods.ModSimpleList.createMod(mod_name)
if err != nil {
log.Printf("error on adding mod to the mod-list.json: %s", err)
return err
}
return nil
}
func (mods *Mods) downloadMod(username string, userKey string, url string, filename string, mod_id string) (error) {
var err error
//download the mod from the mod portal api
complete_url := "https://mods.factorio.com" + url + "?username=" + username + "&token=" + userKey
response, err := http.Get(complete_url)
if err != nil {
log.Printf("error on downloading mod: %s", err)
return err
}
defer response.Body.Close()
if response.StatusCode != 200 {
text, _ := ioutil.ReadAll(response.Body)
log.Printf("StatusCode: %d \n ResponseBody: %s", response.StatusCode, text)
return err
}
err = mods.createMod(mod_id, filename, response.Body)
if err != nil {
log.Printf("error when creating Mod: %s", err)
return err
}
//done everything is made inside the createMod
return nil
}
func (mods *Mods) uploadMod(header *multipart.FileHeader) (error) {
var err error
if header.Header.Get("Content-Type") != "application/zip" {
log.Print("The uploaded file wasn't a zip-file -> ignore it")
return nil //simply do nothing xD
}
file, err := header.Open()
if err != nil {
log.Printf("error on open file via fileHeader. %s", err)
return err
}
defer file.Close()
var buff bytes.Buffer
file_length, err := buff.ReadFrom(file)
if err != nil {
log.Printf("Error occured while reading bytes.Buffer.ReadFrom: %s", err)
return err
}
zip_reader, err := zip.NewReader(file, file_length)
if err != nil {
log.Printf("Uploaded file could not put into zip.Reader: %s", err)
return err
}
var mod_info ModInfo
err = mod_info.getModInfo(zip_reader)
if err != nil {
log.Printf("Error in getModInfo: %s", err)
return err
}
err = mods.createMod(mod_info.Name, header.Filename, file)
if err != nil {
log.Printf("error on creating Mod: %s", err)
return err
}
return nil
}
func (mods *Mods) updateMod(mod_name string, username string, userKey string, url string, filename string) error {
var err error
err = mods.deleteMod(mod_name)
if err != nil {
log.Printf("updateMod ... error when deleting mod: %s", err)
return err
}
err = mods.downloadMod(username, userKey, url, filename, mod_name)
if err != nil {
log.Printf("updateMod ... error hen downloading the new Mod: %s", err)
return err
}
return nil
}

164
src/mod_modInfo.go Normal file
View File

@ -0,0 +1,164 @@
package main
import (
"log"
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"archive/zip"
"errors"
"io"
)
type ModInfoList struct {
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"`
}
func newModInfoList(destination string) (ModInfoList, error) {
var err error
mod_info_list := ModInfoList{
Destination: destination,
}
err = mod_info_list.listInstalledMods()
if err != nil {
log.Printf("ModInfoList ... error listing installed Mods: %s", err)
return mod_info_list, err
}
return mod_info_list, nil
}
func (mod_info_list *ModInfoList) listInstalledMods() (error) {
var err error
mod_info_list.Mods = nil
err = filepath.Walk(mod_info_list.Destination, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() && filepath.Ext(path) == ".zip" {
zip_file, err := zip.OpenReader(path)
if err != nil {
log.Fatalln(err)
return err
}
var mod_info ModInfo
err = mod_info.getModInfo(&zip_file.Reader)
if err != nil {
log.Fatalf("Error in getModInfo: %s", err)
}
mod_info.FileName = info.Name()
mod_info_list.Mods = append(mod_info_list.Mods, mod_info)
}
return nil
})
if err != nil {
log.Printf("error while walking over the given dir: %s", err)
return err
}
return nil
}
func (mod_info_list *ModInfoList) deleteMod(mod_name string) (error) {
var err error
//search for mod, that should be deleted
for _, mod := range mod_info_list.Mods {
if mod.Name == mod_name {
//delete mod
err = os.Remove(mod_info_list.Destination + "/" + mod.FileName)
if err != nil {
log.Printf("ModInfoList ... error when deleting mod: %s", err)
return err
}
//reload mod-list
err = mod_info_list.listInstalledMods()
if err != nil {
log.Printf("ModInfoList ... error while refreshing installedModList: %s", err)
return err
}
return nil
}
}
log.Printf("the mod-file doesnt exists!")
return nil
}
func (mod_info *ModInfo) getModInfo(reader *zip.Reader) error {
for _, single_file := range reader.File {
if single_file.FileInfo().Name() == "info.json" {
//interpret info.json
rc, err := single_file.Open()
if err != nil {
log.Fatal(err)
return err
}
byte_array, err := ioutil.ReadAll(rc)
rc.Close()
if err != nil {
log.Fatal(err)
return err
}
err = json.Unmarshal(byte_array, mod_info)
if err != nil {
log.Fatalln(err)
return err
}
return nil
}
}
return errors.New("info.json not found in zip-file")
}
func (mod_info_list ModInfoList) createMod(mod_name string, file_name string, mod_file io.Reader) error {
var err error
//save uploaded file
new_file, err := os.Create(mod_info_list.Destination + "/" + file_name)
if err != nil {
log.Printf("error on creating new file - %s: %s", file_name, err)
return err
}
defer new_file.Close()
_, err = io.Copy(new_file, mod_file)
if err != nil {
log.Printf("error on copying file to disk: %s", err)
return err
}
//reload the list
err = new_file.Close()
if err != nil {
log.Printf("error on closing new created zip-file: %s", err)
return err
}
err = mod_info_list.listInstalledMods()
if err != nil {
log.Printf("error on listing mod-infos: %s", err)
return err
}
return nil
}

143
src/mod_modSimple.go Normal file
View File

@ -0,0 +1,143 @@
package main
import (
"log"
"io/ioutil"
"encoding/json"
)
type ModSimple struct {
Name string `json:"name"`
Enabled bool `json:"enabled"`
}
type ModSimpleList struct {
Mods []ModSimple `json:"mods"`
Destination string `json:"-"`
}
func newModSimpleList(destination string) (ModSimpleList, error) {
var err error
mod_simple_list := ModSimpleList{
Destination: destination,
}
err = mod_simple_list.listInstalledMods()
if err != nil {
log.Printf("ModSimpleList ... error list installed mods: %s", err)
return mod_simple_list, err
}
return mod_simple_list, nil
}
func (mod_simple_list *ModSimpleList) listInstalledMods() (error) {
var err error
file, err := ioutil.ReadFile(mod_simple_list.Destination + "/mod-list.json")
if err != nil {
log.Printf("ModSimpleList ... error read the mod-info.json: %s", err)
return err
}
err = json.Unmarshal(file, mod_simple_list)
if err != nil {
log.Printf("ModSimpleList ... error while decode mod-info.json: %s", err)
return err
}
return nil
}
func (mod_simple_list *ModSimpleList) saveModInfoJson() (error) {
var err error
//build json of current state
new_json, _ := json.Marshal(mod_simple_list)
err = ioutil.WriteFile(mod_simple_list.Destination + "/mod-list.json", new_json, 0664)
if err != nil {
log.Printf("error when writing new mod-list: %s", err)
return err
}
return nil
}
func (mod_simple_list *ModSimpleList) deleteMod(mod_name string) (error) {
var err error
for index, mod := range mod_simple_list.Mods {
if mod.Name == mod_name {
slice1 := mod_simple_list.Mods[:index]
slice2 := mod_simple_list.Mods[index + 1:]
var new_mod_list []ModSimple
new_mod_list = append(new_mod_list, slice1...)
new_mod_list = append(new_mod_list, slice2...)
mod_simple_list.Mods = new_mod_list
break
}
}
err = mod_simple_list.saveModInfoJson()
if err != nil {
log.Printf("error when saving new mod_list: %s", err)
return err
}
return nil
}
func (mod_simple_list *ModSimpleList) checkModExists(mod_name string) (bool) {
for _, single_mod := range mod_simple_list.Mods {
if single_mod.Name == mod_name {
return true
}
}
return false
}
func (mod_simple_list *ModSimpleList) createMod(mod_name string) (error) {
var err error
new_mod_simple := ModSimple{
Name: mod_name,
Enabled: true,
}
mod_simple_list.Mods = append(mod_simple_list.Mods, new_mod_simple)
err = mod_simple_list.saveModInfoJson()
if err != nil {
log.Printf("error when saving new Info.json: %s", err)
return err
}
//reloading not necessary, just changed it live xD
return nil
}
func (mod_simple_list *ModSimpleList) toggleMod(mod_name string) error {
var err error
for index, mod := range mod_simple_list.Mods {
if mod.Name == mod_name {
mod_simple_list.Mods[index].Enabled = !mod_simple_list.Mods[index].Enabled
break
}
}
err = mod_simple_list.saveModInfoJson()
if err != nil {
log.Printf("error on savin new ModSimpleList: %s", err)
return err
}
//i changed it already don't need to reload it
return nil
}

280
src/mod_modpacks.go Normal file
View File

@ -0,0 +1,280 @@
package main
import (
"path/filepath"
"log"
"os"
"errors"
"io/ioutil"
"io"
)
type ModPackMap map[string]*ModPack
type ModPack struct {
Mods Mods
}
type ModPackResult struct {
Name string `json:"name"`
Mods ModsResultList `json:"mods"`
}
type ModPackResultList struct {
ModPacks []ModPackResult `json:"mod_packs"`
}
func newModPackMap() (ModPackMap, error) {
var err error
//var mod_pack_map ModPackMap
mod_pack_map := make(ModPackMap)
err = mod_pack_map.reload()
if err != nil {
log.Printf("error on loading the modpacks: %s", err)
return mod_pack_map, err
}
return mod_pack_map, nil
}
func newModPack(mod_pack_folder string) (*ModPack, error) {
var err error
var mod_pack ModPack
mod_pack.Mods, err = newMods(mod_pack_folder)
if err != nil {
log.Printf("error on loading mods in mod_pack_dir: %s", err)
return &mod_pack, err
}
return &mod_pack, err
}
func (mod_pack_map *ModPackMap) reload() error {
var err error
new_mod_pack_map := make(ModPackMap)
err = filepath.Walk(config.FactorioModPackDir, func(path string, info os.FileInfo, err error) error {
if path == config.FactorioModPackDir || !info.IsDir() {
return nil
}
mod_pack_name := filepath.Base(path)
new_mod_pack_map[mod_pack_name], err = newModPack(path)
if err != nil {
log.Printf("error on creating newModPack: %s", err)
return err
}
return nil
})
if err != nil {
log.Printf("error on walking over the ModDir: %s", err)
return err
}
*mod_pack_map = new_mod_pack_map
return nil
}
func (mod_pack_map *ModPackMap) listInstalledModPacks() ModPackResultList {
var mod_pack_result_list ModPackResultList
for mod_pack_name, mod_pack := range *mod_pack_map {
var mod_pack_result ModPackResult
mod_pack_result.Name = mod_pack_name
mod_pack_result.Mods = mod_pack.Mods.listInstalledMods()
mod_pack_result_list.ModPacks = append(mod_pack_result_list.ModPacks, mod_pack_result)
}
return mod_pack_result_list
}
func (mod_pack_map *ModPackMap) createModPack(mod_pack_name string) error {
var err error
mod_pack_folder := filepath.Join(config.FactorioModPackDir, mod_pack_name)
if mod_pack_map.checkModPackExists(mod_pack_name) == true {
log.Printf("ModPack %s already existis", mod_pack_name)
return errors.New("ModPack " + mod_pack_name + " already exists, please choose a different name")
}
source_file_info, err := os.Stat(config.FactorioModsDir)
if err != nil {
log.Printf("error when reading factorioModsDir. %s", err)
return err
}
//Create the modPack-folder
err = os.MkdirAll(mod_pack_folder, source_file_info.Mode())
if err != nil {
log.Printf("error on creating the new ModPack directory: %s", err)
return err
}
files, err := ioutil.ReadDir(config.FactorioModsDir)
if err != nil {
log.Printf("error on reading the dactorio mods dir: %s", err)
return err
}
for _, file := range files {
if file.IsDir() == false {
source_filepath := filepath.Join(config.FactorioModsDir, file.Name())
destination_filepath := filepath.Join(mod_pack_folder, file.Name())
source_file, err := os.Open(source_filepath)
if err != nil {
log.Printf("error on opening source_filepath: %s", err)
return err
}
defer source_file.Close()
destination_file, err := os.Create(destination_filepath)
if err != nil {
log.Printf("error on creating destination_filepath: %s", err)
return err
}
defer destination_file.Close()
_, err = io.Copy(destination_file, source_file)
if err != nil {
log.Printf("error on copying data from source to destination: %s", err)
return err
}
source_file.Close()
destination_file.Close()
}
}
//reload the ModPackList
err = mod_pack_map.reload()
if err != nil {
log.Printf("error on reloading ModPack: %s", err)
return err
}
return nil
}
func (mod_pack_map *ModPackMap) checkModPackExists(mod_pack_name string) bool {
for mod_pack_id := range *mod_pack_map {
if mod_pack_id == mod_pack_name {
return true
}
}
return false
}
func (mod_pack_map *ModPackMap) deleteModPack(mod_pack_name string) error {
var err error
mod_pack_dir := filepath.Join(config.FactorioModPackDir, mod_pack_name)
err = os.RemoveAll(mod_pack_dir)
if err != nil {
log.Printf("error on removing the ModPack: %s", err)
return err
}
err = mod_pack_map.reload()
if err != nil {
log.Printf("error on reloading the ModPackList: %s", err)
return err
}
return nil
}
func (mod_pack *ModPack) loadModPack() error {
var err error
//get filemode, so it can be restored
file_info, err := os.Stat(config.FactorioModsDir)
if err != nil {
log.Printf("error on trying to save folder infos: %s", err)
return err
}
folder_mode := file_info.Mode()
//clean factorio mod directory
err = os.RemoveAll(config.FactorioModsDir)
if err != nil {
log.Printf("error on removing the factorio mods dir: %s", err)
return err
}
err = os.Mkdir(config.FactorioModsDir, folder_mode)
if err != nil {
log.Printf("error on recreating mod dir: %s", err)
return err
}
//copy the modpack folder to the normal mods directory
err = filepath.Walk(mod_pack.Mods.ModInfoList.Destination, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
new_file, err := os.Create(filepath.Join(config.FactorioModsDir, info.Name()))
if err != nil {
log.Printf("error on creting mod file: %s", err)
return err
}
defer new_file.Close()
old_file, err := os.Open(path)
if err != nil {
log.Printf("error on opening modFile: %s", err)
return err
}
defer old_file.Close()
_ ,err = io.Copy(new_file, old_file)
if err != nil {
log.Printf("error on copying data to the new file: %s", err)
return err
}
return nil
})
if err != nil {
log.Printf("error on copying the mod pack: %s", err)
return err
}
//mods, err := newMods(config.FactorioModsDir)
return nil
}
//func modPackToggleMod(mod_pack_name string, mod_name string) (ModPackList, error) {
// //var err error
// //var mod_pack_list ModPackList
// //
// //mod_pack := ModPack{
// // Name: mod_pack_name,
// //}
// //
// //temp_dir, err := mod_pack.create_temp_dir()
// //if err != nil {
// // log.Printf("error when creating temp_dir: %s", err)
// // return mod_pack_list, err
// //}
// //defer os.RemoveAll(temp_dir)
// //
// //var mods_list ModsList
// //err = mods_list.listInstalledMods(temp_dir)
// //if err != nil {
// // log.Printf("error on listing mods in temp_dir: %s", err)
// // return mod_pack_list, err
// //}
// //
// //log.Print(mods_list)
//
// return ModPackList{}, nil
//}

View File

@ -1,232 +1,12 @@
package main
import (
"io/ioutil"
"log"
"encoding/json"
"net/http"
"net/url"
"os"
"io"
"path/filepath"
"archive/zip"
"mime/multipart"
"errors"
"bytes"
"log"
"io/ioutil"
)
type Mod struct {
Name string `json:"name"`
Enabled bool `json:"enabled"`
}
type ModsList struct {
Mods []Mod `json:"mods"`
}
func (mod_list *ModsList) check_mod_exists(mod_name string) bool {
for _, single_mod := range mod_list.Mods {
if single_mod.Name == mod_name {
return true
}
}
return false
}
// List mods installed in the factorio/mods directory
func listInstalledMods() (ModsList, error) {
file, err := ioutil.ReadFile(config.FactorioModsDir + "/mod-list.json")
if err != nil {
log.Println(err.Error())
}
var result ModsList
err_json := json.Unmarshal(file, &result)
if err_json != nil {
log.Println(err_json.Error())
return result, err_json
}
return result, nil
}
type ModInfoList struct {
Mods []ModInfo `json:"mods"`
}
type ModInfo struct {
Name string `json:"name"`
Version string `json:"version"`
Title string `json:"title"`
Author string `json:"author"`
FileName string `json:"file_name"`
Enabled bool `json:"enabled"`
}
func (mod_info *ModInfo) getModInfo(reader *zip.Reader) error {
for _, single_file := range reader.File {
if single_file.FileInfo().Name() == "info.json" {
//interpret info.json
rc, err := single_file.Open()
if err != nil {
log.Fatal(err)
return err
}
byte_array, err := ioutil.ReadAll(rc)
rc.Close()
if err != nil {
log.Fatal(err)
return err
}
//var mod_info ModInfo
err = json.Unmarshal(byte_array, mod_info)
if err != nil {
log.Fatalln(err)
return err
}
return nil
}
}
return errors.New("info.json not found in zip-file!")
}
func listInstalledModsByFolder() (ModInfoList, error) {
//scan ModFolder
var result ModInfoList
var err_o error
err_o = filepath.Walk(config.FactorioModsDir, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() && filepath.Ext(path) == ".zip" {
zip_file, err := zip.OpenReader(path)
if err != nil {
log.Fatalln(err)
return err
}
var mod_info ModInfo
err = mod_info.getModInfo(&zip_file.Reader)
if err != nil {
log.Fatalf("Error in getModInfo: %s", err)
}
mod_info.FileName = info.Name()
result.Mods = append(result.Mods, mod_info)
}
return nil
})
if err_o != nil {
return ModInfoList{}, err_o
}
mod_list_by_json, err_o := listInstalledMods()
if err_o != nil {
return ModInfoList{}, err_o
}
for _, json_mod := range mod_list_by_json.Mods {
for result_index, result_mod := range result.Mods {
if result_mod.Name == json_mod.Name {
result.Mods[result_index].Enabled = json_mod.Enabled
break
}
}
}
return result, nil
}
func toggleMod(mod_name string)([]ModInfo, error) {
var err error
mod_list, err := listInstalledMods()
if err != nil {
return nil, err
}
for index, mod := range mod_list.Mods {
if mod.Name == mod_name {
mod_list.Mods[index].Enabled = !mod_list.Mods[index].Enabled
break
}
}
//build new json
new_json, _ := json.Marshal(mod_list)
ioutil.WriteFile(config.FactorioModsDir + "/mod-list.json", new_json, 0664)
mod_info_list, err := listInstalledModsByFolder()
if err != nil {
log.Fatal(err)
return nil, err
}
return mod_info_list.Mods, nil
}
func deleteMod(mod_name string) ([]ModInfo, error) {
var err error
mod_list, err := listInstalledMods()
if err != nil {
return nil, err
}
for index, mod := range mod_list.Mods {
if mod.Name == mod_name {
slice1 := mod_list.Mods[:index]
slice2 := mod_list.Mods[index + 1:]
var new_mod_list []Mod
new_mod_list = append(new_mod_list, slice1...)
new_mod_list = append(new_mod_list, slice2...)
mod_list.Mods = new_mod_list
break
}
}
//build new json
new_json, _ := json.Marshal(mod_list)
ioutil.WriteFile(config.FactorioModsDir + "/mod-list.json", new_json, 0664)
mod_info_list, err := listInstalledModsByFolder()
if err != nil {
log.Fatal(err)
return nil, err
}
var delete_file_name string
//search for mod in own setup
for index, mod := range mod_info_list.Mods {
if mod.Name == mod_name {
delete_file_name = mod.FileName
//remove mod from list (faster than scanning path new)
slice1 := mod_info_list.Mods[:index]
slice2 := mod_info_list.Mods[index+1:]
var new_mod_list []ModInfo
new_mod_list = append(new_mod_list, slice1...)
new_mod_list = append(new_mod_list, slice2...)
mod_info_list.Mods = new_mod_list
break
}
}
os.Remove(config.FactorioModsDir + "/" + delete_file_name)
return mod_info_list.Mods, nil
}
type LoginErrorResponse struct {
Message string `json:"message"`
Status int `json:"status"`
@ -308,415 +88,3 @@ func getModDetails(modId string) (string, error, int) {
return text_string, nil, resp.StatusCode
}
func installMod(username string, userKey string, url string, filename string, mod_id string) ([]ModInfo, error, int) {
var err error
//download the mod from the mod portal api
complete_url := "https://mods.factorio.com" + url + "?username=" + username + "&token=" + userKey
mod_list, err := listInstalledMods()
if err != nil {
return nil, err, 500
}
if mod_list.check_mod_exists(mod_id) {
log.Printf("delete old mod %s.", mod_id)
_, err = deleteMod(mod_id)
if err != nil {
log.Printf("error on deleting mod: %s", err)
return nil, err, 500
}
}
// don't worry about errors
response, err := http.Get(complete_url)
if err != nil {
log.Fatal(err)
return nil, err, 500
}
if response.StatusCode != 200 {
text, _ := ioutil.ReadAll(response.Body)
log.Printf("StatusCode: %d \n ResponseBody: %s", response.StatusCode, text)
defer response.Body.Close()
return nil, err, response.StatusCode
}
defer response.Body.Close()
//open a file for writing
file, err := os.Create(config.FactorioModsDir + "/" + filename)
if err != nil {
log.Fatal(err)
return nil, err, 500
}
// Use io.Copy to just dump the response body to the file. This supports huge files
_, err = io.Copy(file, response.Body)
if err != nil {
log.Fatal(err)
return nil, err, 500
}
file.Close()
mod_list, err = listInstalledMods()
if err != nil {
return nil, err, 500
}
//add new mod
new_mod_entry := Mod{
Name: mod_id,
Enabled:true,
}
mod_list.Mods = append(mod_list.Mods, new_mod_entry)
//build new json
new_json, _ := json.Marshal(mod_list)
ioutil.WriteFile(config.FactorioModsDir + "/mod-list.json", new_json, 0664)
mod_info_list, err := listInstalledModsByFolder()
if err != nil {
log.Fatal(err)
return nil, err, 500
}
return mod_info_list.Mods, nil, response.StatusCode
}
func uploadMod(header *multipart.FileHeader) (error) {
var err error
if header.Header.Get("Content-Type") != "application/zip" {
log.Print("The uploaded file wasn't a zip-file -> ignore it")
return nil //simply do nothing xD
}
if _,err_file := os.Stat(config.FactorioModsDir + "/" + header.Filename); !os.IsNotExist(err_file) {
log.Print("The uploaded file already exists -> ignore it")
return nil //simply do nothing xD
}
file, err := header.Open()
if err != nil {
log.Printf("error on open file via fileHeader. %s", err)
return err
}
var buff bytes.Buffer
file_length, err := buff.ReadFrom(file)
if err != nil {
log.Printf("Error occured while reading bytes.Buffer.ReadFrom: %s", err)
return err
}
zip_reader, err := zip.NewReader(file, file_length)
if err != nil {
log.Printf("Uploaded file could not put into zip.Reader: %s", err)
return err
}
var mod_info ModInfo
err = mod_info.getModInfo(zip_reader)
if err != nil {
log.Printf("Error in getModInfo: %s", err)
return err
}
//check if mod already exists in mod_list.json
mods_list, err := listInstalledMods()
if err != nil {
log.Printf("Error in listInstalledMods: %s", err)
return err
}
mod_already_exists := mods_list.check_mod_exists(mod_info.Name)
if mod_already_exists {
_, err = deleteMod(mod_info.Name)
if err != nil {
log.Printf("error when trying to delete mod: %s", err)
return err
}
}
//save uploaded file
new_file, err := os.Create(config.FactorioModsDir + "/" + header.Filename)
if err != nil {
log.Printf("error on creating new file - %s: %s", header.Filename, err)
return err
}
defer new_file.Close()
file.Seek(0,0) //reset file-cursor to 0,0
_, err = io.Copy(new_file, file)
if err != nil {
log.Printf("error on copying file to disk: %s", err)
return err
}
//build new json
mods_list, err = listInstalledMods()
if err != nil {
log.Printf("Error in listInstalledMods: %s", err)
return err
}
//add this mod
mods_list.Mods = append(mods_list.Mods, Mod{
Name: mod_info.Name,
Enabled: true,
})
//save mod-list.json with the new mod
new_json, _ := json.Marshal(mods_list)
ioutil.WriteFile(config.FactorioModsDir + "/mod-list.json", new_json, 0664)
return nil
}
type ModPack struct {
Name string `json:"name"`
Mods ModInfoList `json:"mods"`
}
func (mod_pack *ModPack) readModPack(reader zip.Reader) error {
//var err error
var mod_info_list ModInfoList
var pack_list ModsList
for _, mod_file := range reader.File {
mod_file_rc, err := mod_file.Open()
if err != nil {
log.Printf("Error opening mod_file: %s", err)
return err
}
mod_file_b, err := ioutil.ReadAll(mod_file_rc)
if err != nil {
log.Printf("Error on reading file to RAM: %s", err)
return err
}
if filepath.Ext(mod_file.Name) == ".zip" {
mod_file_r := bytes.NewReader(mod_file_b)
single_mod_reader, err := zip.NewReader(mod_file_r, int64(len(mod_file_b)))
if err != nil {
log.Printf("Error on reading byte_array to zip_reader: %s", err)
return err
}
var mod_info ModInfo
err = mod_info.getModInfo(single_mod_reader)
if err != nil {
log.Printf("Error in getModInfo with the zip-byte-array: %s", err)
return err
}
mod_info_list.Mods = append(mod_info_list.Mods, mod_info)
} else if mod_file.Name == "mod-list.json" {
err := json.Unmarshal(mod_file_b, &pack_list)
if err != nil {
log.Printf("Error on Unmashal the mod-info.json: %s", err)
return err
}
}
}
for _, json_mod := range pack_list.Mods {
for result_index, result_mod := range mod_info_list.Mods {
if result_mod.Name == json_mod.Name {
mod_info_list.Mods[result_index].Enabled = json_mod.Enabled
break
}
}
}
mod_pack.Mods = mod_info_list
return nil
}
type ModPackList struct {
ModPacks []ModPack `json:"mod_packs"`
}
func (mod_pack_list *ModPackList) getModPacks() error {
var err error
err = filepath.Walk(config.FactorioModPackDir, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() && filepath.Ext(path) == ".zip" {
//var modpack ModPack
zip_file, err := zip.OpenReader(path)
if err != nil {
log.Printf("error on opening zip-file %s: %s", path, err)
return err
}
defer zip_file.Close()
var mod_pack ModPack
err = mod_pack.readModPack(zip_file.Reader)
if err != nil {
log.Printf("Error in readModPack: %s", err)
return err
}
var extension = filepath.Ext(info.Name())
mod_pack.Name = info.Name()[0:len(info.Name())-len(extension)]
mod_pack_list.ModPacks = append(mod_pack_list.ModPacks, mod_pack)
}
return nil
})
if err != nil {
log.Printf("error while walking over path: %s", err)
return err
}
return nil
}
func createModPack(pack_name string) (ModPackList, error) {
var err error
var mod_pack_list ModPackList
pack_name_file := config.FactorioModPackDir + "/" + pack_name + ".zip"
if _, err := os.Stat(pack_name_file); !os.IsNotExist(err) || pack_name == "" {
log.Printf("ModPack %s already exists", pack_name)
return mod_pack_list, errors.New("ModPack " + pack_name + " already exists, pls choose a different name")
}
file, err := os.Create(pack_name_file)
if err != nil {
log.Printf("error while creating mod-pack file: %s", err)
return mod_pack_list, err
}
zip_file := zip.NewWriter(file)
defer zip_file.Close()
err = filepath.Walk(config.FactorioModsDir, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() && (filepath.Ext(path) == ".zip" || info.Name() == "mod-list.json") {
file_writer, err := zip_file.Create(info.Name())
if err != nil {
log.Printf("Error on creating file inside the zip: %s", err)
return err
}
current_file, err := os.Open(path)
if err != nil {
log.Printf("Error on opening file %s: %s", path, err)
return err
}
defer current_file.Close()
_, err = io.Copy(file_writer, current_file)
if err != nil {
log.Printf("Error while copying file %s into the zip: %s", path, err)
return err
}
}
return nil
})
if err != nil {
log.Printf("Error in Walking over the folder; %s", err)
return mod_pack_list, err
}
zip_file.Close()
err = mod_pack_list.getModPacks()
if err != nil {
return mod_pack_list, err
}
return mod_pack_list, nil
}
func deleteModPack(mod_name string) (ModPackList, error) {
var err error
var mod_pack_list ModPackList
err = os.Remove(config.FactorioModPackDir + "/" + mod_name + ".zip")
if err != nil {
log.Printf("Error when deleting modPack: %s", err)
return mod_pack_list, err
}
err = mod_pack_list.getModPacks()
if err != nil {
log.Printf("error when listing modPacks: %s", err)
return mod_pack_list, err
}
return mod_pack_list, nil
}
func loadModPack(name string) ([]ModInfo, error) {
var err error
zip_rc, err := zip.OpenReader(config.FactorioModPackDir + "/" + name + ".zip")
if err != nil {
log.Printf("Error opening ModPack zip: %s", err)
return nil, err
}
defer zip_rc.Close()
//delete current mods
factorio_mods_dir, err := os.Open(config.FactorioModsDir)
if err != nil {
log.Printf("Error opening factorioModsDir: %s", err)
return nil, err
}
defer factorio_mods_dir.Close()
folder_names, err := factorio_mods_dir.Readdirnames(-1)
if err != nil {
log.Printf("Error on reading dirnames: %s", err)
return nil, err
}
for _, name := range folder_names {
err = os.RemoveAll(filepath.Join(config.FactorioModsDir, name))
if err != nil {
log.Printf("Removing everything in the dir failed: %s", err)
return nil, err
}
}
//unpack zip to mods-directory
for _, single_file := range zip_rc.File {
new_file, err := os.Create(config.FactorioModsDir + "/" + single_file.Name)
if err != nil {
log.Printf("error when creating new file in mod-dir: %s", err)
return nil, err
}
singe_file_rc, err := single_file.Open()
if err != nil {
log.Printf("error when opening file inside zip: %s", err)
return nil, err
}
_, err = io.Copy(new_file, singe_file_rc)
new_file.Close()
singe_file_rc.Close()
if err != nil {
log.Printf("error when copying into the new file: %s", err)
return nil, err
}
}
//read the new mod configuration
mod_info_list, err := listInstalledModsByFolder()
if err != nil {
log.Printf("error when listing mods after extracting a ModPack: %s", err)
return nil, err
}
return mod_info_list.Mods, nil
}

View File

@ -1,244 +0,0 @@
package main
//import (
// "archive/zip"
// "encoding/json"
// "errors"
// "fmt"
// "io/ioutil"
// "log"
// "os"
// "path/filepath"
// "strings"
//)
//
//type ModList struct {
// Mods []Mod `json:"mods"`
//}
//
//
//// List mods installed in the factorio/mods directory
//func listInstalledMods(modDir string) ([]string, error) {
// result := []string{}
//
// files, err := ioutil.ReadDir(modDir)
// if err != nil {
// log.Printf("Error listing installed mods: %s", err)
// return result, err
// }
// for _, f := range files {
// if f.Name() == "mod-list.json" {
// continue
// }
// result = append(result, f.Name())
// }
//
// return result, nil
//}
//
//// Delete mod by provided filename
//func rmMod(modName string) error {
// removed := false
// if modName == "" {
// return errors.New("No mod name provided.")
// }
// // Get list of installed mods
// installedMods, err := listInstalledMods(config.FactorioModsDir)
// if err != nil {
// log.Printf("Error in remove mod list: %s", err)
// return err
// }
//
// // Check if provided mod matches one thats installed else return err
// for _, mod := range installedMods {
// if strings.Contains(mod, modName) {
// log.Printf("Removing mod: %s", mod)
// err := os.Remove(filepath.Join(config.FactorioModsDir, mod))
// if err != nil {
// log.Printf("Error removing mod %s: %s", mod, err)
// return err
// }
// removed = true
// log.Printf("Removed mod: %s", mod)
// }
// }
//
// if !removed {
// log.Printf("Did not remove mod: %s", modName)
// return errors.New(fmt.Sprintf("Did not remove mod: %s", modName))
// }
//
// return nil
//}
//
//func rmModPack(modpack string) error {
// removed := false
// if modpack == "" {
// return errors.New("No mod pack name provided.")
// }
// // Get list of modpacks
// modpacks, err := listModPacks(filepath.Join(config.FactorioDir, "modpacks"))
// if err != nil {
// log.Printf("Error listing modpacks in rmModPack: %s", err)
// return err
// }
//
// for _, m := range modpacks {
// if strings.Contains(m, modpack) {
// log.Printf("Removing modpack: %s", m)
// err := os.Remove(filepath.Join(config.FactorioDir, "modpacks", m))
// if err != nil {
// log.Printf("Error trying to remove modpack: %s: %s", m, err)
// return err
// }
// removed = true
// log.Printf("Removed modpack: %s", m)
// }
// }
//
// if !removed {
// log.Printf("Did not remove modpack: %s", modpack)
// return errors.New(fmt.Sprintf("Did not remove modpack: %s", modpack))
// }
//
// return nil
//}
//
//func createModPackDir() error {
// err := os.Mkdir(filepath.Join(config.FactorioDir, "modpacks"), 0775)
// if err != nil && !os.IsExist(err) {
// log.Printf("Could not create modpacks directory: %s", err)
// return err
// }
//
// return nil
//}
//
//// Create's modpack zip file from provided title, mods parameter is a string of mod filenames
//func createModPack(title string, mods ...string) error {
// zipfile, err := os.Create(filepath.Join(config.FactorioDir, "modpacks", title+".zip"))
// if err != nil {
// log.Printf("Error creating zipfile: %s, error: %s", title, err)
// }
// defer zipfile.Close()
// // Create Zip writer
// z := zip.NewWriter(zipfile)
// defer z.Close()
//
// for _, mod := range mods {
// // Process mod file, add to zipfile
// f, err := os.Open(filepath.Join(config.FactorioDir, "mods", mod))
// if err != nil {
// log.Printf("Error creating modpack file %s for archival: ", mod, err)
// return err
// }
// // Read contents of mod to be compressed
// modfile, err := ioutil.ReadAll(f)
// if err != nil {
// log.Printf("Error reading modfile contents: %s", err)
// continue
// }
// // Add file to zip archive
// fmt.Println(mod)
// zip, err := z.Create(mod)
// if err != nil {
// log.Printf("Error adding file: %s to zip: %s", f.Name, err)
// continue
// }
// // Write file contents to zip archive
// _, err = zip.Write(modfile)
// if err != nil {
// log.Printf("Error writing to zipfile: %s", err)
// continue
// }
// }
//
// err = z.Close()
// if err != nil {
// log.Printf("Error trying to zip: %s, error: %s", title, err)
// }
//
// return nil
//}
//
//func listModPacks(modDir string) ([]string, error) {
// result := []string{}
//
// files, err := ioutil.ReadDir(modDir)
// if err != nil {
// log.Printf("Error listing modpacks: %s", err)
// return result, err
// }
// for _, f := range files {
// result = append(result, f.Name())
// }
//
// return result, nil
//}
//
//// Parses mod-list.json file in factorio/mods
//// returns ModList struct
//func parseModList() (ModList, error) {
// var mods ModList
// modListFile := filepath.Join(config.FactorioModsDir, "mod-list.json")
//
// modList, err := ioutil.ReadFile(modListFile)
// if err != nil {
// log.Printf("Error reading mod-list.json file: %s", err)
// return mods, err
// }
//
// err = json.Unmarshal(modList, &mods)
// if err != nil {
// log.Printf("Error parsing mod-list.json JSON: %s", err)
// return mods, err
// }
//
// return mods, nil
//}
//
//// Toggles Enabled boolean for mod specified in name parameter in mod-list.json file
//func (m *ModList) toggleMod(name string) error {
// found := false
// status := false
//
// for i := range m.Mods {
// if m.Mods[i].Name == name {
// found = true
// if m.Mods[i].Enabled == true {
// m.Mods[i].Enabled = false
// } else {
// m.Mods[i].Enabled = true
// status = true
// }
// }
// }
//
// if found {
// err := m.save()
// if err != nil {
// log.Printf("Error saving changes to mod-list-.json file: %s", err)
// return err
// }
// log.Printf("Mod: %s was toggled to %v", name, status)
// }
//
// return nil
//}
//
//// Saves ModList object to mod-list.json file
//// Overwrites old file
//func (m ModList) save() error {
// modListFile := filepath.Join(config.FactorioModsDir, "mod-list.json")
// b, _ := json.MarshalIndent(m, "", " ")
//
// err := ioutil.WriteFile(modListFile, b, 0644)
// if err != nil {
// log.Printf("Error writing to mod-list.json file: %s", err)
// return err
// }
//
// return nil
//}
//
////TODO Add method to allow downloading all installed mods in zip file

View File

@ -304,6 +304,11 @@ var apiRoutes = Routes{
"/mods/packs/load",
LoadModPackHandler,
}, {
"ModPackToggleMod",
"POST",
"/mods/packs/mod/toggle",
ModPackToggleModHandler,
} ,{
"GetServerSettings",
"GET",
"/settings",

View File

@ -10,6 +10,7 @@ class ModPackOverview extends React.Component {
this.createModPack = this.createModPack.bind(this);
this.deleteModPack = this.deleteModPack.bind(this);
this.loadModPack = this.loadModPack.bind(this);
this.modPackToggleModHandler = this.modPackToggleModHandler.bind(this);
this.state = {
listPacks: []
@ -27,7 +28,6 @@ class ModPackOverview extends React.Component {
method: "GET",
dataType: "JSON",
success: (data) => {
console.log(data);
this.setState({
listPacks: data.data.mod_packs
});
@ -159,7 +159,7 @@ class ModPackOverview extends React.Component {
});
this_class.props.modContentClass.setState({
installedMods: data.data
installedMods: data.data.mods
});
},
error: (jqXHR, status, err) => {
@ -182,6 +182,37 @@ class ModPackOverview extends React.Component {
e.stopPropagation();
}
modPackToggleModHandler(e) {
e.preventDefault();
let $button = $(e.target);
let $row = $button.parents("tr");
let mod_name = $row.data("mod-name");
let mod_pack = $row.parents(".single-modpack").find("h3").html();
$.ajax({
url: "/api/mods/packs/mod/toggle",
method: "POST",
data: {
mod_name: mod_name,
mod_pack: mod_pack
},
dataType: "JSON",
success: (data) => {
this.setState({
listPacks: data.data.mod_packs
});
},
error: (jqXHR, status, err) => {
console.log('api/mods/packs/mod/toggle', status, err.toString());
swal({
title: "Toggle Mod went wrong",
text: err.toString(),
type: "error"
});
}
});
}
test() {
console.log("test called");
}
@ -194,7 +225,7 @@ class ModPackOverview extends React.Component {
this.state.listPacks.map(
(modpack, index) => {
return(
<div className="box collapsed-box">
<div key={modpack.name} className="box single-modpack collapsed-box">
<div className="box-header" data-widget="collapse" style={{cursor: "pointer"}}>
<i className="fa fa-plus"></i>
<h3 className="box-title">{modpack.name}</h3>
@ -216,7 +247,7 @@ class ModPackOverview extends React.Component {
<ModManager
installedMods={modpack.mods.mods}
deleteMod={this.test} //TODO
toggleMod={this.test}
toggleMod={this.modPackToggleModHandler}
updateMod={this.test}
/>
</div>

View File

@ -320,7 +320,7 @@ class ModsContent extends React.Component {
toggleUpdateStatus();
removeVersionAvailableStatus();
this_class.setState({
installedMods: data.data
installedMods: data.data.mods
});
},
error: (jqXHR, status, err) => {