You've already forked factorio-server-manager
mirror of
https://github.com/OpenFactorioServerManager/factorio-server-manager.git
synced 2025-07-13 01:10:25 +02:00
wip
This commit is contained in:
@ -1,8 +1,10 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/apexskier/httpauth"
|
||||
)
|
||||
@ -19,8 +21,18 @@ type User struct {
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
func initAuth() *AuthHTTP {
|
||||
return &AuthHTTP{}
|
||||
var once sync.Once
|
||||
var instantiated *AuthHTTP
|
||||
|
||||
func GetAuth() *AuthHTTP {
|
||||
once.Do(func() {
|
||||
Auth := &AuthHTTP{}
|
||||
config := bootstrap.GetConfig()
|
||||
_ = Auth.CreateAuth(config.DatabaseFile, config.CookieEncryptionKey)
|
||||
_ = Auth.CreateOrUpdateUser(config.Username, config.Password, "admin", "")
|
||||
instantiated = Auth
|
||||
})
|
||||
return instantiated
|
||||
}
|
||||
|
||||
func (auth *AuthHTTP) CreateAuth(backendFile string, cookieKey string) error {
|
@ -1,9 +1,11 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@ -52,14 +54,14 @@ func ReadRequestBody(w http.ResponseWriter, r *http.Request, resp *interface{})
|
||||
// Lists all save files in the factorio/saves directory
|
||||
func ListSaves(w http.ResponseWriter, r *http.Request) {
|
||||
var resp interface{}
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
defer func() {
|
||||
WriteResponse(w, resp)
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
savesList, err := listSaves(config.FactorioSavesDir)
|
||||
savesList, err := factorio.ListSaves(config.FactorioSavesDir)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error listing save files: %s", err)
|
||||
log.Println(resp)
|
||||
@ -67,7 +69,7 @@ func ListSaves(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
loadLatest := Save{Name: "Load Latest"}
|
||||
loadLatest := factorio.Save{Name: "Load Latest"}
|
||||
savesList = append(savesList, loadLatest)
|
||||
|
||||
resp = savesList
|
||||
@ -75,7 +77,7 @@ func ListSaves(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func DLSave(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
vars := mux.Vars(r)
|
||||
save := vars["save"]
|
||||
saveName := filepath.Join(config.FactorioSavesDir, save)
|
||||
@ -96,6 +98,7 @@ func UploadSave(w http.ResponseWriter, r *http.Request) {
|
||||
log.Println("Uploading save file")
|
||||
|
||||
r.ParseMultipartForm(32 << 20)
|
||||
config := bootstrap.GetConfig()
|
||||
|
||||
for _, saveFile := range r.MultipartForm.File["savefile"] {
|
||||
ext := filepath.Ext(saveFile.Filename)
|
||||
@ -149,7 +152,7 @@ func RemoveSave(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
name := vars["save"]
|
||||
|
||||
save, err := findSave(name)
|
||||
save, err := factorio.FindSave(name)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error finding save {%s}: %s", name, err)
|
||||
log.Println(resp)
|
||||
@ -157,7 +160,7 @@ func RemoveSave(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = save.remove()
|
||||
err = save.Remove()
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error removing save {%s}: %s", name, err)
|
||||
log.Println(resp)
|
||||
@ -188,9 +191,9 @@ func CreateSaveHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
saveFile := filepath.Join(config.FactorioSavesDir, saveName)
|
||||
cmdOut, err := createSave(saveFile)
|
||||
cmdOut, err := factorio.CreateSave(saveFile)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error creating save {%s}: %s", saveName, err)
|
||||
log.Println(resp)
|
||||
@ -211,8 +214,8 @@ func LogTail(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
resp, err = tailLog(config.FactorioLog)
|
||||
config := bootstrap.GetConfig()
|
||||
resp, err = factorio.TailLog(config.FactorioLog)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Could not tail %s: %s", config.FactorioLog, err)
|
||||
return
|
||||
@ -229,8 +232,8 @@ func LoadConfig(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
configContents, err := loadConfig(config.FactorioConfigFile)
|
||||
config := bootstrap.GetConfig()
|
||||
configContents, err := factorio.LoadConfig(config.FactorioConfigFile)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Could not retrieve config.ini: %s", err)
|
||||
log.Println(resp)
|
||||
@ -246,14 +249,14 @@ func LoadConfig(w http.ResponseWriter, r *http.Request) {
|
||||
func StartServer(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
var resp interface{}
|
||||
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
defer func() {
|
||||
WriteResponse(w, resp)
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
if FactorioServ.Running {
|
||||
if server.Running {
|
||||
resp = "Factorio server is already running"
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
return
|
||||
@ -268,7 +271,7 @@ func StartServer(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
log.Printf("Starting Factorio server with settings: %v", string(body))
|
||||
|
||||
err = json.Unmarshal(body, &FactorioServ)
|
||||
err = json.Unmarshal(body, &server)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error unmarshalling server settings JSON: %s", err)
|
||||
log.Println(resp)
|
||||
@ -277,7 +280,7 @@ func StartServer(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Check if savefile was submitted with request to start server.
|
||||
if FactorioServ.Savefile == "" {
|
||||
if server.Savefile == "" {
|
||||
resp = "Error starting Factorio server: No save file provided"
|
||||
log.Println(resp)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
@ -285,7 +288,7 @@ func StartServer(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
go func() {
|
||||
err = FactorioServ.Run()
|
||||
err = server.Run()
|
||||
if err != nil {
|
||||
log.Printf("Error starting Factorio server: %+v", err)
|
||||
return
|
||||
@ -295,7 +298,7 @@ func StartServer(w http.ResponseWriter, r *http.Request) {
|
||||
timeout := 0
|
||||
for timeout <= 3 {
|
||||
time.Sleep(1 * time.Second)
|
||||
if FactorioServ.Running {
|
||||
if server.Running {
|
||||
break
|
||||
} else {
|
||||
log.Printf("Did not detect running Factorio server attempt: %+v", timeout)
|
||||
@ -304,14 +307,14 @@ func StartServer(w http.ResponseWriter, r *http.Request) {
|
||||
timeout++
|
||||
}
|
||||
|
||||
if FactorioServ.Running == false {
|
||||
if server.Running == false {
|
||||
resp = fmt.Sprintf("Error starting Factorio server: %s", err)
|
||||
log.Println(resp)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
resp = fmt.Sprintf("Factorio server with save: %s started on port: %d", FactorioServ.Savefile, FactorioServ.Port)
|
||||
resp = fmt.Sprintf("Factorio server with save: %s started on port: %d", server.Savefile, server.Port)
|
||||
log.Println(resp)
|
||||
}
|
||||
|
||||
@ -323,9 +326,9 @@ func StopServer(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
if FactorioServ.Running {
|
||||
err := FactorioServ.Stop()
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
if server.Running {
|
||||
err := server.Stop()
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error stopping factorio server: %s", err)
|
||||
log.Println(resp)
|
||||
@ -350,9 +353,9 @@ func KillServer(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
if FactorioServ.Running {
|
||||
err := FactorioServ.Kill()
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
if server.Running {
|
||||
err := server.Kill()
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error killing factorio server: %s", err)
|
||||
log.Println(resp)
|
||||
@ -375,12 +378,12 @@ func CheckServer(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
if FactorioServ.Running {
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
if server.Running {
|
||||
resp["status"] = "running"
|
||||
resp["port"] = strconv.Itoa(FactorioServ.Port)
|
||||
resp["savefile"] = FactorioServ.Savefile
|
||||
resp["address"] = FactorioServ.BindIP
|
||||
resp["port"] = strconv.Itoa(server.Port)
|
||||
resp["savefile"] = server.Savefile
|
||||
resp["address"] = server.BindIP
|
||||
} else {
|
||||
resp["status"] = "stopped"
|
||||
}
|
||||
@ -394,9 +397,9 @@ func FactorioVersion(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
resp["version"] = FactorioServ.Version.String()
|
||||
resp["base_mod_version"] = FactorioServ.BaseModVersion
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
resp["version"] = server.Version.String()
|
||||
resp["base_mod_version"] = server.BaseModVersion
|
||||
}
|
||||
|
||||
// Unmarshall the User object from the given bytearray
|
||||
@ -433,7 +436,7 @@ func LoginUser(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
log.Printf("Logging in user: %s", user.Username)
|
||||
|
||||
Auth := GetAuth()
|
||||
err = Auth.aaa.Login(w, r, user.Username, user.Password, "/")
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error loggin in user: %s, error: %s", user.Username, err)
|
||||
@ -453,7 +456,7 @@ func LogoutUser(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
Auth := GetAuth()
|
||||
if err = Auth.aaa.Logout(w, r); err != nil {
|
||||
log.Printf("Error logging out current user")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
@ -473,7 +476,7 @@ func GetCurrentLogin(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
Auth := GetAuth()
|
||||
user, err := Auth.aaa.CurrentUser(w, r)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error getting user status: %s, error: %s", user.Username, err)
|
||||
@ -493,7 +496,7 @@ func ListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
Auth := GetAuth()
|
||||
users, err := Auth.listUsers()
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error listing users: %s", err)
|
||||
@ -524,7 +527,7 @@ func AddUser(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Auth := GetAuth()
|
||||
err = Auth.addUser(user.Username, user.Password, user.Email, user.Role)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error in adding user {%s}: %s", user.Username, err)
|
||||
@ -554,7 +557,7 @@ func RemoveUser(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Auth := GetAuth()
|
||||
err = Auth.removeUser(user.Username)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error in removing user {%s}, error: %s", user.Username, err)
|
||||
@ -574,8 +577,8 @@ func GetServerSettings(w http.ResponseWriter, r *http.Request) {
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
resp = FactorioServ.Settings
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
resp = server.Settings
|
||||
|
||||
log.Printf("Sent server settings response")
|
||||
}
|
||||
@ -594,8 +597,8 @@ func UpdateServerSettings(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
log.Printf("Received settings JSON: %s", body)
|
||||
|
||||
err = json.Unmarshal(body, &FactorioServ.Settings)
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
err = json.Unmarshal(body, &server.Settings)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error unmarhaling server settings JSON: %s", err)
|
||||
log.Println(resp)
|
||||
@ -603,14 +606,14 @@ func UpdateServerSettings(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
settings, err := json.MarshalIndent(&FactorioServ.Settings, "", " ")
|
||||
settings, err := json.MarshalIndent(&server.Settings, "", " ")
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Failed to marshal server settings: %s", err)
|
||||
log.Println(resp)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
err = ioutil.WriteFile(filepath.Join(config.FactorioConfigDir, config.SettingsFile), settings, 0644)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Failed to save server settings: %v\n", err)
|
||||
@ -621,9 +624,9 @@ func UpdateServerSettings(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
log.Printf("Saved Factorio server settings in server-settings.json")
|
||||
|
||||
if (FactorioServ.Version.Greater(Version{0, 17, 0})) {
|
||||
if (server.Version.Greater(factorio.Version{0, 17, 0})) {
|
||||
// save admins to adminJson
|
||||
admins, err := json.MarshalIndent(FactorioServ.Settings["admins"], "", " ")
|
||||
admins, err := json.MarshalIndent(server.Settings["admins"], "", " ")
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Failed to marshal admins-Setting: %s", err)
|
||||
log.Println(resp)
|
@ -1,10 +1,12 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
@ -12,8 +14,8 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func CheckModPackExists(modPackMap ModPackMap, modPackName string, w http.ResponseWriter, resp interface{}) error {
|
||||
exists := modPackMap.checkModPackExists(modPackName)
|
||||
func CheckModPackExists(modPackMap factorio.ModPackMap, modPackName string, w http.ResponseWriter, resp interface{}) error {
|
||||
exists := modPackMap.CheckModPackExists(modPackName)
|
||||
if !exists {
|
||||
resp = fmt.Sprintf("requested modPack {%s} does not exist", modPackName)
|
||||
log.Println(resp)
|
||||
@ -23,8 +25,8 @@ func CheckModPackExists(modPackMap ModPackMap, modPackName string, w http.Respon
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateNewModPackMap(w http.ResponseWriter, resp *interface{}) (modPackMap ModPackMap, err error) {
|
||||
modPackMap, err = newModPackMap()
|
||||
func CreateNewModPackMap(w http.ResponseWriter, resp *interface{}) (modPackMap factorio.ModPackMap, err error) {
|
||||
modPackMap, err = factorio.NewModPackMap()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
*resp = fmt.Sprintf("Error creating modpackmap aka. list of all modpacks files : %s", err)
|
||||
@ -33,7 +35,7 @@ func CreateNewModPackMap(w http.ResponseWriter, resp *interface{}) (modPackMap M
|
||||
return
|
||||
}
|
||||
|
||||
func ReadModPackRequest(w http.ResponseWriter, r *http.Request, resp *interface{}) (err error, packMap ModPackMap, modPackName string) {
|
||||
func ReadModPackRequest(w http.ResponseWriter, r *http.Request, resp *interface{}) (err error, packMap factorio.ModPackMap, modPackName string) {
|
||||
vars := mux.Vars(r)
|
||||
modPackName = vars["modpack"]
|
||||
|
||||
@ -67,7 +69,7 @@ func ModPackListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = modPackMap.listInstalledModPacks()
|
||||
resp = modPackMap.ListInstalledModPacks()
|
||||
}
|
||||
|
||||
func ModPackCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -93,7 +95,7 @@ func ModPackCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = modPackMap.createModPack(modPackStruct.Name)
|
||||
err = modPackMap.CreateModPack(modPackStruct.Name)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
resp = fmt.Sprintf("Error creating modpack file: %s", err)
|
||||
@ -101,7 +103,7 @@ func ModPackCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = modPackMap.listInstalledModPacks()
|
||||
resp = modPackMap.ListInstalledModPacks()
|
||||
}
|
||||
|
||||
func ModPackDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -119,7 +121,7 @@ func ModPackDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = modPackMap.deleteModPack(modPackName)
|
||||
err = modPackMap.DeleteModPack(modPackName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
resp = fmt.Sprintf("Error deleting modpack file: %s", err)
|
||||
@ -146,6 +148,8 @@ func ModPackDownloadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
zipWriter := zip.NewWriter(w)
|
||||
defer zipWriter.Close()
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
|
||||
//iterate over folder and create everything in the zip
|
||||
err = filepath.Walk(filepath.Join(config.FactorioModPackDir, modPackName), func(path string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() == false {
|
||||
@ -205,7 +209,7 @@ func ModPackLoadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = modPackMap[modPackName].loadModPack()
|
||||
err = modPackMap[modPackName].LoadModPack()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
resp = fmt.Sprintf("Error loading modpack file: %s", err)
|
||||
@ -213,7 +217,7 @@ func ModPackLoadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = modPackMap[modPackName].Mods.listInstalledMods()
|
||||
resp = modPackMap[modPackName].Mods.ListInstalledMods()
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
@ -233,7 +237,7 @@ func ModPackModListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = modPackMap[modPackName].Mods.listInstalledMods()
|
||||
resp = modPackMap[modPackName].Mods.ListInstalledMods()
|
||||
}
|
||||
|
||||
func ModPackModToggleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -259,7 +263,7 @@ func ModPackModToggleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err, resp = packMap[packName].Mods.ModSimpleList.toggleMod(modPackStruct.ModName)
|
||||
err, resp = packMap[packName].Mods.ModSimpleList.ToggleMod(modPackStruct.ModName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
resp = fmt.Sprintf("Error toggling mod inside modPack: %s", err)
|
||||
@ -291,7 +295,7 @@ func ModPackModDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = packMap[packName].Mods.deleteMod(modPackStruct.Name)
|
||||
err = packMap[packName].Mods.DeleteMod(modPackStruct.Name)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
resp = fmt.Sprintf("Error deleting mod {%s} in modpack {%s}: %s", modPackStruct.Name, packName, err)
|
||||
@ -328,7 +332,7 @@ func ModPackModUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = packMap[packName].Mods.updateMod(modPackStruct.ModName, modPackStruct.DownloadUrl, modPackStruct.Filename)
|
||||
err = packMap[packName].Mods.UpdateMod(modPackStruct.ModName, modPackStruct.DownloadUrl, modPackStruct.Filename)
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
@ -337,7 +341,7 @@ func ModPackModUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
installedMods := packMap[packName].Mods.listInstalledMods().ModsResult
|
||||
installedMods := packMap[packName].Mods.ListInstalledMods().ModsResult
|
||||
var found = false
|
||||
for _, mod := range installedMods {
|
||||
if mod.Name == modPackStruct.ModName {
|
||||
@ -368,7 +372,7 @@ func ModPackModDeleteAllHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Delete Modpack
|
||||
err = packMap.deleteModPack(packName)
|
||||
err = packMap.DeleteModPack(packName)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error deleting modPackDir: %s", err)
|
||||
log.Println(resp)
|
||||
@ -376,7 +380,7 @@ func ModPackModDeleteAllHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// recreate modPack without mods
|
||||
err = packMap.createEmptyModPack(packName)
|
||||
err = packMap.CreateEmptyModPack(packName)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error recreating modPackDir: %s", err)
|
||||
log.Println(resp)
|
||||
@ -407,7 +411,7 @@ func ModPackModUploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err, modPackMap, modPackName := ReadModPackRequest(w, r, &resp)
|
||||
|
||||
err = modPackMap[modPackName].Mods.uploadMod(formFile, fileHeader)
|
||||
err = modPackMap[modPackName].Mods.UploadMod(formFile, fileHeader)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("error saving file to modPack: %s", err)
|
||||
log.Println(resp)
|
||||
@ -415,7 +419,7 @@ func ModPackModUploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = modPackMap[modPackName].Mods.listInstalledMods()
|
||||
resp = modPackMap[modPackName].Mods.ListInstalledMods()
|
||||
}
|
||||
|
||||
func ModPackModPortalInstallHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -444,9 +448,9 @@ func ModPackModPortalInstallHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
mods := packMap[packName].Mods
|
||||
modList := packMap[packName].Mods
|
||||
|
||||
err = mods.downloadMod(data.DownloadURL, data.Filename, data.ModName)
|
||||
err = modList.DownloadMod(data.DownloadURL, data.Filename, data.ModName)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error downloading a mod: %s", err)
|
||||
log.Println(resp)
|
||||
@ -454,7 +458,7 @@ func ModPackModPortalInstallHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = mods.listInstalledMods()
|
||||
resp = modList.ListInstalledMods()
|
||||
}
|
||||
|
||||
func ModPackModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -469,7 +473,7 @@ func ModPackModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Reque
|
||||
|
||||
var data []struct {
|
||||
Name string `json:"name"`
|
||||
Version Version `json:"version"`
|
||||
Version factorio.Version `json:"version"`
|
||||
}
|
||||
err = ReadFromRequestBody(w, r, &resp, &data)
|
||||
if err != nil {
|
||||
@ -480,10 +484,9 @@ func ModPackModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Reque
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
mods := packMap[packName].Mods
|
||||
modList := packMap[packName].Mods
|
||||
for _, datum := range data {
|
||||
details, err, statusCode := modPortalModDetails(datum.Name)
|
||||
details, err, statusCode := factorio.ModPortalModDetails(datum.Name)
|
||||
if err != nil || statusCode != http.StatusOK {
|
||||
resp = fmt.Sprintf("Error in getting mod details from mod portal: %s", err)
|
||||
log.Println(resp)
|
||||
@ -493,11 +496,12 @@ func ModPackModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Reque
|
||||
|
||||
//find correct mod-version
|
||||
var found = false
|
||||
|
||||
for _, release := range details.Releases {
|
||||
if release.Version.Equals(datum.Version) {
|
||||
found = true
|
||||
|
||||
err := mods.downloadMod(release.DownloadURL, release.FileName, details.Name)
|
||||
err := modList.DownloadMod(release.DownloadURL, release.FileName, details.Name)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error downloading mod {%s}, error: %s", details.Name, err)
|
||||
log.Println(resp)
|
||||
@ -514,5 +518,5 @@ func ModPackModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
}
|
||||
|
||||
resp = mods.listInstalledMods()
|
||||
resp = modList.ListInstalledMods()
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
@ -31,14 +32,14 @@ func SetupModPacks(t *testing.T, empty bool, emptyMods bool) {
|
||||
}
|
||||
assert.NoError(t, err, `Error creating "dev_packs/test" directory`)
|
||||
|
||||
mods, err := newMods("dev_packs/test")
|
||||
modList, err := factorio.NewMods("dev_packs/test")
|
||||
assert.NoError(t, err, "error creating mods")
|
||||
|
||||
if !emptyMods {
|
||||
err = mods.downloadMod("/download/belt-balancer/5e9f9db4bf9d30000c5303f2", "belt-balancer_2.1.3.zip", "belt-balancer")
|
||||
err = modList.DownloadMod("/download/belt-balancer/5e9f9db4bf9d30000c5303f2", "belt-balancer_2.1.3.zip", "belt-balancer")
|
||||
assert.NoError(t, err, `Error downloading Mod "belt-balancer"`)
|
||||
|
||||
err = mods.downloadMod("/download/train-station-overview/5e8a0a8ee8864f000d0cb022", "train-station-overview_2.0.3.zip", "train-station-overview")
|
||||
err = modList.DownloadMod("/download/train-station-overview/5e8a0a8ee8864f000d0cb022", "train-station-overview_2.0.3.zip", "train-station-overview")
|
||||
assert.NoError(t, err, `Error downloading Mod "train-station-overview"`)
|
||||
}
|
||||
}
|
||||
@ -182,16 +183,16 @@ func TestModPackLoadHandler(t *testing.T) {
|
||||
CallRoute(t, method, baseRoute, route, nil, handlerFunc, http.StatusOK, expected)
|
||||
|
||||
// check if mods are really loaded
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
mods, err := newMods("dev")
|
||||
modList, err := factorio.NewMods("dev")
|
||||
assert.NoError(t, err, "Error creating mods object")
|
||||
|
||||
packModsJson, err := json.Marshal(packMap["test"].Mods)
|
||||
assert.NoError(t, err, "Error marshalling mods from modPack")
|
||||
|
||||
modsJson, err := json.Marshal(mods)
|
||||
modsJson, err := json.Marshal(modList)
|
||||
assert.NoError(t, err, "Error marshalling mods object")
|
||||
|
||||
assert.JSONEq(t, string(packModsJson), string(modsJson), "loaded mods and modPack are not identical")
|
||||
@ -208,16 +209,16 @@ func TestModPackLoadHandler(t *testing.T) {
|
||||
CallRoute(t, method, baseRoute, route, nil, handlerFunc, http.StatusOK, expected)
|
||||
|
||||
// check if mods are really loaded
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
mods, err := newMods("dev")
|
||||
modList, err := factorio.NewMods("dev")
|
||||
assert.NoError(t, err, "Error creating mods object")
|
||||
|
||||
packModsJson, err := json.Marshal(packMap["test"].Mods)
|
||||
assert.NoError(t, err, "Error marshalling mods from modPack")
|
||||
|
||||
modsJson, err := json.Marshal(mods)
|
||||
modsJson, err := json.Marshal(modList)
|
||||
assert.NoError(t, err, "Error marshalling mods object")
|
||||
|
||||
assert.JSONEq(t, string(packModsJson), string(modsJson), "loaded mods and modPack are not identical")
|
||||
@ -266,7 +267,7 @@ func TestModPackModToggleHandler(t *testing.T) {
|
||||
CallRoute(t, method, baseRoute, route, requestBody, handlerFunc, http.StatusOK, expected)
|
||||
|
||||
// check if changes happened
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
found := false
|
||||
@ -293,7 +294,7 @@ func TestModPackModToggleHandler(t *testing.T) {
|
||||
|
||||
CallRoute(t, method, baseRoute, route, requestBody, handlerFunc, http.StatusOK, expected)
|
||||
|
||||
packMap, err = newModPackMap()
|
||||
packMap, err = factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
found = false
|
||||
@ -338,10 +339,10 @@ func TestModPackModDeleteHandler(t *testing.T) {
|
||||
CallRoute(t, method, baseRoute, route, requestBody, handlerFunc, http.StatusOK, `true`)
|
||||
|
||||
// check if mod is really not installed anymore
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
if packMap["test"].Mods.ModSimpleList.checkModExists("belt-balancer") {
|
||||
if packMap["test"].Mods.ModSimpleList.CheckModExists("belt-balancer") {
|
||||
t.Fatalf("Mod is still installed, it should be gone by now")
|
||||
}
|
||||
})
|
||||
@ -370,7 +371,7 @@ func TestModPackModDeleteAllHandler(t *testing.T) {
|
||||
CallRoute(t, method, baseRoute, route, nil, handlerFunc, http.StatusOK, "true")
|
||||
|
||||
// check if really empty
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
if len(packMap["test"].Mods.ModInfoList.Mods) != 0 {
|
||||
@ -405,10 +406,10 @@ func TestModPackModUpdateHandler(t *testing.T) {
|
||||
defer CleanupModPacks(t)
|
||||
|
||||
// disable "belt-balancer" mod, so we can test, if it is still deactivated after
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
err, _ = packMap["test"].Mods.ModSimpleList.toggleMod("belt-balancer")
|
||||
err, _ = packMap["test"].Mods.ModSimpleList.ToggleMod("belt-balancer")
|
||||
assert.NoError(t, err, "Error toggling mod")
|
||||
|
||||
expected := `{"name":"belt-balancer","version":"2.1.2","title":"Belt Balancer","author":"knoxfighter","file_name":"belt-balancer_2.1.2.zip","factorio_version":"0.18.0.0","dependencies":null,"compatibility":true,"enabled":false}`
|
||||
@ -440,7 +441,7 @@ func TestModPackModUpdateHandler(t *testing.T) {
|
||||
CallRoute(t, method, baseRoute, route, strings.NewReader(requestBody), handlerFunc, http.StatusInternalServerError, "")
|
||||
|
||||
// check if old mod is still there
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "Error creating modPackMap")
|
||||
|
||||
var found = false
|
||||
@ -524,19 +525,19 @@ func TestModPackModUploadHandler(t *testing.T) {
|
||||
}
|
||||
|
||||
// check if mod is uploaded correctly
|
||||
packMap, err := newModPackMap()
|
||||
packMap, err := factorio.NewModPackMap()
|
||||
assert.NoError(t, err, "error creating modPackMap")
|
||||
|
||||
expected := ModsResultList{
|
||||
ModsResult: []ModsResult{
|
||||
expected := factorio.ModsResultList{
|
||||
ModsResult: []factorio.ModsResult{
|
||||
{
|
||||
ModInfo: ModInfo{
|
||||
ModInfo: factorio.ModInfo{
|
||||
Name: "belt-balancer",
|
||||
Version: "2.1.3",
|
||||
Title: "Belt Balancer",
|
||||
Author: "knoxfighter",
|
||||
FileName: "belt-balancer_2.1.3.zip",
|
||||
FactorioVersion: Version{0, 18, 0, 0},
|
||||
FactorioVersion: factorio.Version{0, 18, 0, 0},
|
||||
Dependencies: nil,
|
||||
Compatibility: true,
|
||||
},
|
||||
@ -545,7 +546,7 @@ func TestModPackModUploadHandler(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
actual := packMap["test"].Mods.listInstalledMods()
|
||||
actual := packMap["test"].Mods.ListInstalledMods()
|
||||
assert.Equal(t, expected, actual, `New mod is not correctly installed. expected "%v" - actual "%v"`, expected, actual)
|
||||
})
|
||||
|
@ -1,8 +1,9 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
@ -18,7 +19,7 @@ func ModPortalListModsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
var statusCode int
|
||||
resp, err, statusCode = modPortalList()
|
||||
resp, err, statusCode = factorio.ModPortalList()
|
||||
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error in listing mods from mod portal: %s", err)
|
||||
@ -45,7 +46,7 @@ func ModPortalModInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
modId := vars["mod"]
|
||||
|
||||
var statusCode int
|
||||
resp, err, statusCode = modPortalModDetails(modId)
|
||||
resp, err, statusCode = factorio.ModPortalModDetails(modId)
|
||||
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error in getting mod details from mod portal: %s", err)
|
||||
@ -83,7 +84,7 @@ func ModPortalInstallHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = mods.downloadMod(data.DownloadURL, data.Filename, data.ModName)
|
||||
err = mods.DownloadMod(data.DownloadURL, data.Filename, data.ModName)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error downloading a mod: %s", err)
|
||||
log.Println(resp)
|
||||
@ -91,7 +92,7 @@ func ModPortalInstallHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = mods.listInstalledMods()
|
||||
resp = mods.ListInstalledMods()
|
||||
}
|
||||
|
||||
func ModPortalLoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -113,7 +114,7 @@ func ModPortalLoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
loginStatus, err, statusCode := factorioLogin(data.Username, data.Password)
|
||||
loginStatus, err, statusCode := factorio.FactorioLogin(data.Username, data.Password)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error trying to login into Factorio: %s", err)
|
||||
log.Println(resp)
|
||||
@ -136,8 +137,8 @@ func ModPortalLoginStatusHandler(w http.ResponseWriter, r *http.Request) {
|
||||
WriteResponse(w, resp)
|
||||
}()
|
||||
|
||||
var credentials FactorioCredentials
|
||||
resp, err = credentials.load()
|
||||
var credentials factorio.Credentials
|
||||
resp, err = credentials.Load()
|
||||
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error getting the factorio credentials: %s", err)
|
||||
@ -155,8 +156,8 @@ func ModPortalLogoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||
WriteResponse(w, resp)
|
||||
}()
|
||||
|
||||
var credentials FactorioCredentials
|
||||
err = credentials.del()
|
||||
var credentials factorio.Credentials
|
||||
err = credentials.Del()
|
||||
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error on logging out of factorio: %s", err)
|
||||
@ -180,20 +181,20 @@ func ModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var data []struct {
|
||||
Name string `json:"name"`
|
||||
Version Version `json:"version"`
|
||||
Version factorio.Version `json:"version"`
|
||||
}
|
||||
err = ReadFromRequestBody(w, r, &resp, &data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
mods, err := CreateNewMods(w, &resp)
|
||||
modList, err := CreateNewMods(w, &resp)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, datum := range data {
|
||||
details, err, statusCode := modPortalModDetails(datum.Name)
|
||||
details, err, statusCode := factorio.ModPortalModDetails(datum.Name)
|
||||
if err != nil || statusCode != http.StatusOK {
|
||||
resp = fmt.Sprintf("Error in getting mod details from mod portal: %s", err)
|
||||
log.Println(resp)
|
||||
@ -207,7 +208,7 @@ func ModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if release.Version.Equals(datum.Version) {
|
||||
found = true
|
||||
|
||||
err := mods.downloadMod(release.DownloadURL, release.FileName, details.Name)
|
||||
err := modList.DownloadMod(release.DownloadURL, release.FileName, details.Name)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error downloading mod {%s}, error: %s", details.Name, err)
|
||||
log.Println(resp)
|
||||
@ -223,5 +224,5 @@ func ModPortalInstallMultipleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
resp = mods.listInstalledMods()
|
||||
resp = modList.ListInstalledMods()
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
@ -1,38 +1,22 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"github.com/mroote/factorio-server-manager/lockfile"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ModPortalStruct struct {
|
||||
DownloadsCount int `json:"downloads_count"`
|
||||
Name string `json:"name"`
|
||||
Owner string `json:"owner"`
|
||||
Releases []struct {
|
||||
DownloadURL string `json:"download_url"`
|
||||
FileName string `json:"file_name"`
|
||||
InfoJSON struct {
|
||||
FactorioVersion string `json:"factorio_version"`
|
||||
} `json:"info_json"`
|
||||
ReleasedAt time.Time `json:"released_at"`
|
||||
Sha1 string `json:"sha1"`
|
||||
Version Version `json:"version"`
|
||||
} `json:"releases"`
|
||||
Summary string `json:"summary"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
func CreateNewMods(w http.ResponseWriter, resp *interface{}) (mods Mods, err error) {
|
||||
mods, err = newMods(config.FactorioModsDir)
|
||||
func CreateNewMods(w http.ResponseWriter, resp *interface{}) (modList factorio.Mods, err error) {
|
||||
config := bootstrap.GetConfig()
|
||||
modList, err = factorio.NewMods(config.FactorioModsDir)
|
||||
if err != nil {
|
||||
*resp = fmt.Sprintf("Error creating mods object: %s", err)
|
||||
log.Println(*resp)
|
||||
@ -69,12 +53,12 @@ func ListInstalledModsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
mods, err := CreateNewMods(w, &resp)
|
||||
modList, err := CreateNewMods(w, &resp)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp = mods.listInstalledMods().ModsResult
|
||||
resp = modList.ListInstalledMods().ModsResult
|
||||
}
|
||||
|
||||
func ModToggleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -101,7 +85,7 @@ func ModToggleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err, resp = mods.ModSimpleList.toggleMod(data.Name)
|
||||
err, resp = mods.ModSimpleList.ToggleMod(data.Name)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error in toggling mod in simple list: %s", err)
|
||||
log.Println(resp)
|
||||
@ -130,12 +114,12 @@ func ModDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
mods, err := CreateNewMods(w, &resp)
|
||||
modList, err := CreateNewMods(w, &resp)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = mods.deleteMod(data.Name)
|
||||
err = modList.DeleteMod(data.Name)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
resp = fmt.Sprintf("Error in deleting mod {%s}: %s", data.Name, err)
|
||||
@ -157,7 +141,7 @@ func ModDeleteAllHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
//delete mods folder
|
||||
err = deleteAllMods()
|
||||
err = factorio.DeleteAllMods()
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error deleting all mods: %s", err)
|
||||
log.Println(resp)
|
||||
@ -195,14 +179,14 @@ func ModUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = mods.updateMod(modData.Name, modData.DownloadUrl, modData.Filename)
|
||||
err = mods.UpdateMod(modData.Name, modData.DownloadUrl, modData.Filename)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("Error updating mod {%s}: %s", modData.Name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
installedMods := mods.listInstalledMods().ModsResult
|
||||
installedMods := mods.ListInstalledMods().ModsResult
|
||||
for _, mod := range installedMods {
|
||||
if mod.Name == modData.Name {
|
||||
resp = mod
|
||||
@ -240,7 +224,7 @@ func ModUploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = mods.uploadMod(formFile, fileHeader)
|
||||
err = mods.UploadMod(formFile, fileHeader)
|
||||
if err != nil {
|
||||
resp = fmt.Sprintf("error saving file to mods: %s", err)
|
||||
log.Println(resp)
|
||||
@ -248,7 +232,7 @@ func ModUploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
resp = mods.listInstalledMods()
|
||||
resp = mods.ListInstalledMods()
|
||||
}
|
||||
|
||||
func ModDownloadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -256,17 +240,17 @@ func ModDownloadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
zipWriter := zip.NewWriter(w)
|
||||
defer zipWriter.Close()
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
//iterate over folder and create everything in the zip
|
||||
err = filepath.Walk(config.FactorioModsDir, func(path string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() == false {
|
||||
//Lock the file, that we are want to read
|
||||
err := fileLock.RLock(path)
|
||||
err := factorio.FileLock.RLock(path)
|
||||
if err != nil {
|
||||
log.Printf("error locking file for reading, something else has locked it")
|
||||
return err
|
||||
}
|
||||
defer fileLock.RUnlock(path)
|
||||
defer factorio.FileLock.RUnlock(path)
|
||||
|
||||
writer, err := zipWriter.Create(info.Name())
|
||||
if err != nil {
|
||||
@ -330,9 +314,9 @@ func LoadModsFromSaveHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
path := filepath.Join(config.FactorioSavesDir, saveFileStruct.Name)
|
||||
f, err := OpenArchiveFile(path, "level.dat")
|
||||
f, err := factorio.OpenArchiveFile(path, "level.dat")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
resp = fmt.Sprintf("cannot open save level file: %v", err)
|
||||
@ -342,7 +326,7 @@ func LoadModsFromSaveHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var header SaveHeader
|
||||
var header factorio.SaveHeader
|
||||
err = header.ReadFrom(f)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
@ -1,8 +1,10 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"io"
|
||||
@ -20,23 +22,27 @@ func TestMain(m *testing.M) {
|
||||
var err error
|
||||
|
||||
// basic setup stuff
|
||||
parseFlags()
|
||||
bootstrap.SetFlags(bootstrap.Flags{
|
||||
|
||||
})
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
config.FactorioModsDir = "dev"
|
||||
config.FactorioModPackDir = "dev_packs"
|
||||
FactorioServ = new(FactorioServer)
|
||||
FactorioServ.Version = Version{1, 0, 0, 0}
|
||||
FactorioServ := new(factorio.Server)
|
||||
FactorioServ.Version = factorio.Version{1, 0, 0, 0}
|
||||
FactorioServ.BaseModVersion = "1.0.0"
|
||||
|
||||
// check login status
|
||||
var cred FactorioCredentials
|
||||
load, err := cred.load()
|
||||
var cred factorio.Credentials
|
||||
load, err := cred.Load()
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading factorio credentials: %s", err)
|
||||
return
|
||||
}
|
||||
if !load {
|
||||
// no credentials found, login...
|
||||
_, err, _ = factorioLogin(os.Getenv("factorio_username"), os.Getenv("factorio_password"))
|
||||
_, err, _ = factorio.FactorioLogin(os.Getenv("factorio_username"), os.Getenv("factorio_password"))
|
||||
if err != nil {
|
||||
log.Printf("Error logging in into factorio: %s", err)
|
||||
return
|
||||
@ -64,18 +70,18 @@ func SetupMods(t *testing.T, empty bool) {
|
||||
return
|
||||
}
|
||||
|
||||
mods, err := newMods(config.FactorioModsDir)
|
||||
mod, err := factorio.NewMods(config.FactorioModsDir)
|
||||
if err != nil {
|
||||
t.Fatalf("couldn't create Mods object: %s", err)
|
||||
}
|
||||
|
||||
if !empty {
|
||||
err := mods.downloadMod("/download/belt-balancer/5e9f9db4bf9d30000c5303f2", "belt-balancer_2.1.3.zip", "belt-balancer")
|
||||
err := mod.DownloadMod("/download/belt-balancer/5e9f9db4bf9d30000c5303f2", "belt-balancer_2.1.3.zip", "belt-balancer")
|
||||
if err != nil {
|
||||
t.Fatalf(`Error downloading Mod "belt-balancer": %s`, err)
|
||||
}
|
||||
|
||||
err = mods.downloadMod("/download/train-station-overview/5e8a0a8ee8864f000d0cb022", "train-station-overview_2.0.3.zip", "train-station-overview")
|
||||
err = mod.DownloadMod("/download/train-station-overview/5e8a0a8ee8864f000d0cb022", "train-station-overview_2.0.3.zip", "train-station-overview")
|
||||
if err != nil {
|
||||
t.Fatalf(`Error downloading Mod "train-station-overview": %s`, err)
|
||||
}
|
||||
@ -179,12 +185,12 @@ func TestModToggleHandler(t *testing.T) {
|
||||
CallRoute(t, method, route, route, requestBody, handlerFunc, http.StatusOK, expected)
|
||||
|
||||
// check if changes happenes
|
||||
mods, err := newMods("dev")
|
||||
modList, err := factorio.NewMods("dev")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating Mods object: %s", err)
|
||||
}
|
||||
found := false
|
||||
for _, mod := range mods.ModSimpleList.Mods {
|
||||
for _, mod := range modList.ModSimpleList.Mods {
|
||||
if mod.Name == "belt-balancer" {
|
||||
// this mod has to be deactivated now
|
||||
if mod.Enabled {
|
||||
@ -207,12 +213,12 @@ func TestModToggleHandler(t *testing.T) {
|
||||
|
||||
CallRoute(t, method, route, route, requestBody, handlerFunc, http.StatusOK, expected)
|
||||
|
||||
mods, err = newMods("dev")
|
||||
modList, err = factorio.NewMods("dev")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating Mods object: %s", err)
|
||||
}
|
||||
found = false
|
||||
for _, mod := range mods.ModSimpleList.Mods {
|
||||
for _, mod := range modList.ModSimpleList.Mods {
|
||||
if mod.Name == "belt-balancer" {
|
||||
// this mod has to be deactivated now
|
||||
if !mod.Enabled {
|
||||
@ -250,11 +256,11 @@ func TestModDeleteHandler(t *testing.T) {
|
||||
CallRoute(t, method, route, route, requestBody, handlerFunc, http.StatusOK, `"belt-balancer"`)
|
||||
|
||||
// check if mod is really not installed anymore
|
||||
mods, err := newMods("dev")
|
||||
_, err := factorio.NewMods("dev")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating Mods object: %s", err)
|
||||
}
|
||||
if mods.ModSimpleList.checkModExists("belt-balancer") {
|
||||
if factorio.ModSimpleList.CheckModExists("belt-balancer")) {
|
||||
t.Fatalf("Mod is still installed, it should be gone by now")
|
||||
}
|
||||
})
|
||||
@ -280,11 +286,11 @@ func TestModDeleteAllHandler(t *testing.T) {
|
||||
CallRoute(t, method, route, route, nil, handlerFunc, http.StatusOK, "null")
|
||||
|
||||
// check if no mods are there
|
||||
mods, err := newMods("dev")
|
||||
modList, err := factorio.NewMods("dev")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating mods object: %s", err)
|
||||
}
|
||||
if len(mods.listInstalledMods().ModsResult) != 0 {
|
||||
if len(modList.ListInstalledMods().ModsResult) != 0 {
|
||||
t.Fatalf("Mods are still there!")
|
||||
}
|
||||
})
|
||||
@ -313,11 +319,11 @@ func TestModUpdateHandler(t *testing.T) {
|
||||
defer CleanupMods(t)
|
||||
|
||||
// disable "belt-balancer" mod, so we can test, if it is still deactivated after
|
||||
mods, err := newMods("dev")
|
||||
modList, err := factorio.NewMods("dev")
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating mods object: %s", err)
|
||||
}
|
||||
err, _ = mods.ModSimpleList.toggleMod("belt-balancer")
|
||||
err, _ = modList.ModSimpleList.ToggleMod("belt-balancer")
|
||||
if err != nil {
|
||||
t.Fatalf("Error toggling mod: %s", err)
|
||||
}
|
||||
@ -416,19 +422,19 @@ func TestModUploadHandler(t *testing.T) {
|
||||
}
|
||||
|
||||
// check if mod is uploaded correctly
|
||||
mods, err := newMods("dev")
|
||||
modList, err := factorio.NewMods("dev")
|
||||
assert.NoError(t, err, "error creating mods object")
|
||||
|
||||
expected := ModsResultList{
|
||||
ModsResult: []ModsResult{
|
||||
expected := factorio.ModsResultList{
|
||||
ModsResult: []factorio.ModsResult{
|
||||
{
|
||||
ModInfo: ModInfo{
|
||||
ModInfo: factorio.ModInfo{
|
||||
Name: "belt-balancer",
|
||||
Version: "2.1.3",
|
||||
Title: "Belt Balancer",
|
||||
Author: "knoxfighter",
|
||||
FileName: "belt-balancer_2.1.3.zip",
|
||||
FactorioVersion: Version{0, 18, 0, 0},
|
||||
FactorioVersion: factorio.Version{0, 18, 0, 0},
|
||||
Dependencies: nil,
|
||||
Compatibility: true,
|
||||
},
|
||||
@ -437,7 +443,7 @@ func TestModUploadHandler(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
actual := mods.listInstalledMods()
|
||||
actual := modList.ListInstalledMods()
|
||||
assert.Equal(t, expected, actual, `New mod is not correctly installed. expected "%v" - actual "%v"`, expected, actual)
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"log"
|
||||
@ -58,9 +58,9 @@ func NewRouter() *mux.Router {
|
||||
Methods("GET").
|
||||
Name("Websocket").
|
||||
Handler(AuthorizeHandler(ws))
|
||||
ws.Handle("command send", commandSend)
|
||||
ws.Handle("log subscribe", logSubscribe)
|
||||
ws.Handle("server status subscribe", serverStatusSubscribe)
|
||||
ws.Handle("command send", CommandSend)
|
||||
ws.Handle("log subscribe", LogSubscribe)
|
||||
ws.Handle("server status subscribe", ServerStatusSubscribe)
|
||||
|
||||
// Serves the frontend application from the app directory
|
||||
// Uses basic file server to serve index.html and Javascript application
|
||||
@ -115,6 +115,7 @@ func NewRouter() *mux.Router {
|
||||
// Redirects user to login page if no session is found
|
||||
func AuthorizeHandler(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
Auth := GetAuth()
|
||||
if err := Auth.aaa.Authorize(w, r, true); err != nil {
|
||||
log.Printf("Unauthenticated request %s %s %s", r.Method, r.Host, r.RequestURI)
|
||||
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/gorilla/websocket"
|
@ -1,9 +1,11 @@
|
||||
package main
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"log"
|
||||
"path/filepath"
|
||||
time "time"
|
||||
"time"
|
||||
|
||||
"github.com/hpcloud/tail"
|
||||
)
|
||||
@ -18,8 +20,9 @@ func IsClosed(ch <-chan Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func logSubscribe(client *Client, data interface{}) {
|
||||
func LogSubscribe(client *Client, data interface{}) {
|
||||
go func() {
|
||||
config := bootstrap.GetConfig()
|
||||
logfile := filepath.Join(config.FactorioDir, "factorio-server-console.log")
|
||||
t, err := tail.TailFile(logfile, tail.Config{Follow: true, Poll: true})
|
||||
if err != nil {
|
||||
@ -38,12 +41,13 @@ func logSubscribe(client *Client, data interface{}) {
|
||||
}()
|
||||
}
|
||||
|
||||
func commandSend(client *Client, data interface{}) {
|
||||
if FactorioServ.Running {
|
||||
func CommandSend(client *Client, data interface{}) {
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
if server.Running {
|
||||
go func() {
|
||||
log.Printf("Received command: %v", data)
|
||||
|
||||
reqId, err := FactorioServ.Rcon.Write(data.(string))
|
||||
reqId, err := server.Rcon.Write(data.(string))
|
||||
if err != nil {
|
||||
log.Printf("Error sending rcon command: %s", err)
|
||||
return
|
||||
@ -61,16 +65,16 @@ func commandSend(client *Client, data interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func serverStatusSubscribe(client *Client, data interface{}) {
|
||||
|
||||
func ServerStatusSubscribe(client *Client, data interface{}) {
|
||||
var server, _ = factorio.GetFactorioServer()
|
||||
log.Printf("Subcribed to Server Status")
|
||||
go func() {
|
||||
isRunning := FactorioServ.Running
|
||||
isRunning := server.Running
|
||||
|
||||
// always check if status has changed
|
||||
for {
|
||||
if isRunning != FactorioServ.Running {
|
||||
isRunning = FactorioServ.Running
|
||||
if isRunning != server.Running {
|
||||
isRunning = server.Running
|
||||
|
||||
log.Printf("Server Status has changed")
|
||||
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"log"
|
||||
@ -6,12 +6,12 @@ import (
|
||||
"github.com/go-ini/ini"
|
||||
)
|
||||
|
||||
// Loads config.ini file from the factorio config directory
|
||||
func loadConfig(filename string) (map[string]map[string]string, error) {
|
||||
log.Printf("Loading config file: %s", filename)
|
||||
// Loads bootstrap.ini file from the factorio bootstrap directory
|
||||
func LoadConfig(filename string) (map[string]map[string]string, error) {
|
||||
log.Printf("Loading bootstrap file: %s", filename)
|
||||
cfg, err := ini.Load(filename)
|
||||
if err != nil {
|
||||
log.Printf("Error loading config.ini file: %s", err)
|
||||
log.Printf("Error loading bootstrap.ini file: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ func loadConfig(filename string) (map[string]map[string]string, error) {
|
||||
result[sectionName] = map[string]string{}
|
||||
result[sectionName] = s.KeysHash()
|
||||
}
|
||||
log.Printf("Encoding config.ini to JSON")
|
||||
log.Printf("Encoding bootstrap.ini to JSON")
|
||||
|
||||
return result, nil
|
||||
}
|
@ -1,21 +1,22 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
type FactorioCredentials struct {
|
||||
type Credentials struct {
|
||||
Username string `json:"username"`
|
||||
Userkey string `json:"userkey"`
|
||||
}
|
||||
|
||||
func (credentials *FactorioCredentials) save() error {
|
||||
func (credentials *Credentials) Save() error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
credentialsJson, err := json.Marshal(credentials)
|
||||
if err != nil {
|
||||
log.Printf("error mashalling the credentials: %s", err)
|
||||
@ -31,23 +32,23 @@ func (credentials *FactorioCredentials) save() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (credentials *FactorioCredentials) load() (bool, error) {
|
||||
func (credentials *Credentials) Load() (bool, error) {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
if _, err := os.Stat(config.FactorioCredentialsFile); os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
fileBytes, err := ioutil.ReadFile(config.FactorioCredentialsFile)
|
||||
if err != nil {
|
||||
credentials.del()
|
||||
credentials.Del()
|
||||
log.Printf("error reading CredentialsFile: %s", err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fileBytes, credentials)
|
||||
if err != nil {
|
||||
credentials.del()
|
||||
credentials.Del()
|
||||
log.Printf("error on unmarshal credentials_file: %s", err)
|
||||
return false, err
|
||||
}
|
||||
@ -55,14 +56,14 @@ func (credentials *FactorioCredentials) load() (bool, error) {
|
||||
if credentials.Userkey != "" && credentials.Username != "" {
|
||||
return true, nil
|
||||
} else {
|
||||
credentials.del()
|
||||
credentials.Del()
|
||||
return false, errors.New("incredients incomplete")
|
||||
}
|
||||
}
|
||||
|
||||
func (credentials *FactorioCredentials) del() error {
|
||||
func (credentials *Credentials) Del() error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
err = os.Remove(config.FactorioCredentialsFile)
|
||||
if err != nil {
|
||||
log.Printf("error delete the credentialfile: %s", err)
|
@ -1,14 +1,17 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"log"
|
||||
|
||||
"github.com/hpcloud/tail"
|
||||
)
|
||||
|
||||
func tailLog(filename string) ([]string, error) {
|
||||
func TailLog(filename string) ([]string, error) {
|
||||
result := []string{}
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
|
||||
t, err := tail.TailFile(config.FactorioLog, tail.Config{Follow: false})
|
||||
if err != nil {
|
||||
log.Printf("Error tailing log %s", err)
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
@ -26,9 +26,9 @@ type ModsResultList struct {
|
||||
ModsResult []ModsResult `json:"mods"`
|
||||
}
|
||||
|
||||
var fileLock lockfile.FileLock = lockfile.NewLock()
|
||||
var FileLock lockfile.FileLock = lockfile.NewLock()
|
||||
|
||||
func newMods(destination string) (Mods, error) {
|
||||
func NewMods(destination string) (Mods, error) {
|
||||
var err error
|
||||
var mods Mods
|
||||
|
||||
@ -47,7 +47,7 @@ func newMods(destination string) (Mods, error) {
|
||||
return mods, nil
|
||||
}
|
||||
|
||||
func (mods *Mods) listInstalledMods() ModsResultList {
|
||||
func (mods *Mods) ListInstalledMods() ModsResultList {
|
||||
result := ModsResultList{make([]ModsResult, 0)}
|
||||
|
||||
for _, modInfo := range mods.ModInfoList.Mods {
|
||||
@ -73,7 +73,7 @@ func (mods *Mods) listInstalledMods() ModsResultList {
|
||||
return result
|
||||
}
|
||||
|
||||
func (mods *Mods) deleteMod(modName string) error {
|
||||
func (mods *Mods) DeleteMod(modName string) error {
|
||||
var err error
|
||||
|
||||
err = mods.ModInfoList.deleteMod(modName)
|
||||
@ -95,7 +95,7 @@ func (mods *Mods) createMod(modName string, fileName string, fileRc io.Reader) e
|
||||
var err error
|
||||
|
||||
//check if mod already exists and delete it
|
||||
if mods.ModSimpleList.checkModExists(modName) {
|
||||
if mods.ModSimpleList.CheckModExists(modName) {
|
||||
err = mods.ModInfoList.deleteMod(modName)
|
||||
if err != nil {
|
||||
log.Printf("error when deleting mod: %s", err)
|
||||
@ -118,7 +118,7 @@ func (mods *Mods) createMod(modName string, fileName string, fileRc io.Reader) e
|
||||
}
|
||||
|
||||
// also add to ModSimpleList if not there yet
|
||||
if !mods.ModSimpleList.checkModExists(modName) {
|
||||
if !mods.ModSimpleList.CheckModExists(modName) {
|
||||
err = mods.ModSimpleList.createMod(modName)
|
||||
if err != nil {
|
||||
log.Printf("error creating mod in modSimpleList: %s", err)
|
||||
@ -129,11 +129,11 @@ func (mods *Mods) createMod(modName string, fileName string, fileRc io.Reader) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mods *Mods) downloadMod(url string, filename string, modId string) error {
|
||||
func (mods *Mods) DownloadMod(url string, filename string, modId string) error {
|
||||
var err error
|
||||
|
||||
var credentials FactorioCredentials
|
||||
status, err := credentials.load()
|
||||
var credentials Credentials
|
||||
status, err := credentials.Load()
|
||||
if err != nil {
|
||||
log.Printf("error loading credentials: %s", err)
|
||||
return err
|
||||
@ -175,7 +175,7 @@ func (mods *Mods) downloadMod(url string, filename string, modId string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mods *Mods) uploadMod(file multipart.File, header *multipart.FileHeader) error {
|
||||
func (mods *Mods) UploadMod(file multipart.File, header *multipart.FileHeader) error {
|
||||
var err error
|
||||
|
||||
if filepath.Ext(header.Filename) != ".zip" {
|
||||
@ -211,10 +211,10 @@ func (mods *Mods) uploadMod(file multipart.File, header *multipart.FileHeader) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mods *Mods) updateMod(modName string, url string, filename string) error {
|
||||
func (mods *Mods) UpdateMod(modName string, url string, filename string) error {
|
||||
var err error
|
||||
|
||||
err = mods.downloadMod(url, filename, modName)
|
||||
err = mods.DownloadMod(url, filename, modName)
|
||||
if err != nil {
|
||||
log.Printf("updateMod ... error when downloading the new Mod: %s", err)
|
||||
return err
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
@ -50,7 +50,7 @@ func (modInfoList *ModInfoList) listInstalledMods() error {
|
||||
err = filepath.Walk(modInfoList.Destination, func(path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() && filepath.Ext(path) == ".zip" {
|
||||
|
||||
err = fileLock.RLock(path)
|
||||
err = FileLock.RLock(path)
|
||||
if err != nil && err == lockfile.ErrorAlreadyLocked {
|
||||
log.Println(err)
|
||||
return nil
|
||||
@ -58,7 +58,7 @@ func (modInfoList *ModInfoList) listInstalledMods() error {
|
||||
log.Printf("error locking file: %s", err)
|
||||
return err
|
||||
}
|
||||
defer fileLock.RUnlock(path)
|
||||
defer FileLock.RUnlock(path)
|
||||
|
||||
zipFile, err := zip.OpenReader(path)
|
||||
if err != nil {
|
||||
@ -107,11 +107,13 @@ func (modInfoList *ModInfoList) listInstalledMods() error {
|
||||
break
|
||||
}
|
||||
|
||||
server, _ := GetFactorioServer()
|
||||
|
||||
if !base.Equals(NilVersion) {
|
||||
modInfo.Compatibility = FactorioServ.Version.Compare(base, op)
|
||||
modInfo.Compatibility = server.Version.Compare(base, op)
|
||||
} else {
|
||||
log.Println("error finding basemodDependency. Using FactorioVersion...")
|
||||
modInfo.Compatibility = !FactorioServ.Version.Less(modInfo.FactorioVersion)
|
||||
modInfo.Compatibility = !server.Version.Less(modInfo.FactorioVersion)
|
||||
}
|
||||
|
||||
modInfoList.Mods = append(modInfoList.Mods, modInfo)
|
||||
@ -136,10 +138,10 @@ func (modInfoList *ModInfoList) deleteMod(modName string) error {
|
||||
if mod.Name == modName {
|
||||
filePath := filepath.Join(modInfoList.Destination, mod.FileName)
|
||||
|
||||
fileLock.LockW(filePath)
|
||||
FileLock.LockW(filePath)
|
||||
//delete mod
|
||||
err = os.Remove(filePath)
|
||||
fileLock.Unlock(filePath)
|
||||
FileLock.Unlock(filePath)
|
||||
if err != nil {
|
||||
log.Printf("ModInfoList ... error when deleting mod: %s", err)
|
||||
return err
|
||||
@ -207,7 +209,7 @@ func (modInfoList *ModInfoList) createMod(modName string, fileName string, modFi
|
||||
}
|
||||
defer newFile.Close()
|
||||
|
||||
fileLock.LockW(filePath)
|
||||
FileLock.LockW(filePath)
|
||||
|
||||
_, err = io.Copy(newFile, modFile)
|
||||
if err != nil {
|
||||
@ -221,7 +223,7 @@ func (modInfoList *ModInfoList) createMod(modName string, fileName string, modFi
|
||||
return err
|
||||
}
|
||||
|
||||
fileLock.Unlock(filePath)
|
||||
FileLock.Unlock(filePath)
|
||||
|
||||
//reload the list
|
||||
err = modInfoList.listInstalledMods()
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -108,7 +108,7 @@ func (modSimpleList *ModSimpleList) deleteMod(modName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (modSimpleList *ModSimpleList) checkModExists(modName string) bool {
|
||||
func (modSimpleList *ModSimpleList) CheckModExists(modName string) bool {
|
||||
for _, singleMod := range modSimpleList.Mods {
|
||||
if singleMod.Name == modName {
|
||||
return true
|
||||
@ -139,7 +139,7 @@ func (modSimpleList *ModSimpleList) createMod(modName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (modSimpleList *ModSimpleList) toggleMod(modName string) (error, bool) {
|
||||
func (modSimpleList *ModSimpleList) ToggleMod(modName string) (error, bool) {
|
||||
var err error
|
||||
var newEnabled bool
|
||||
|
@ -1,7 +1,8 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@ -22,7 +23,7 @@ type ModPackResultList struct {
|
||||
ModPacks []ModPackResult `json:"mod_packs"`
|
||||
}
|
||||
|
||||
func newModPackMap() (ModPackMap, error) {
|
||||
func NewModPackMap() (ModPackMap, error) {
|
||||
var err error
|
||||
modPackMap := make(ModPackMap)
|
||||
|
||||
@ -39,7 +40,7 @@ func newModPack(modPackFolder string) (*ModPack, error) {
|
||||
var err error
|
||||
var modPack ModPack
|
||||
|
||||
modPack.Mods, err = newMods(modPackFolder)
|
||||
modPack.Mods, err = NewMods(modPackFolder)
|
||||
if err != nil {
|
||||
log.Printf("error on loading mods in mod_pack_dir: %s", err)
|
||||
return &modPack, err
|
||||
@ -51,6 +52,7 @@ func newModPack(modPackFolder string) (*ModPack, error) {
|
||||
func (modPackMap *ModPackMap) reload() error {
|
||||
var err error
|
||||
newModPackMap := make(ModPackMap)
|
||||
config := bootstrap.GetConfig()
|
||||
|
||||
err = filepath.Walk(config.FactorioModPackDir, func(path string, info os.FileInfo, err error) error {
|
||||
if path == config.FactorioModPackDir || !info.IsDir() {
|
||||
@ -77,13 +79,13 @@ func (modPackMap *ModPackMap) reload() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (modPackMap *ModPackMap) listInstalledModPacks() ModPackResultList {
|
||||
func (modPackMap *ModPackMap) ListInstalledModPacks() ModPackResultList {
|
||||
var modPackResultList ModPackResultList
|
||||
|
||||
for modPackName, modPack := range *modPackMap {
|
||||
var modPackResult ModPackResult
|
||||
modPackResult.Name = modPackName
|
||||
modPackResult.Mods = modPack.Mods.listInstalledMods()
|
||||
modPackResult.Mods = modPack.Mods.ListInstalledMods()
|
||||
|
||||
modPackResultList.ModPacks = append(modPackResultList.ModPacks, modPackResult)
|
||||
}
|
||||
@ -91,12 +93,12 @@ func (modPackMap *ModPackMap) listInstalledModPacks() ModPackResultList {
|
||||
return modPackResultList
|
||||
}
|
||||
|
||||
func (modPackMap *ModPackMap) createModPack(modPackName string) error {
|
||||
func (modPackMap *ModPackMap) CreateModPack(modPackName string) error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
modPackFolder := filepath.Join(config.FactorioModPackDir, modPackName)
|
||||
|
||||
if modPackMap.checkModPackExists(modPackName) == true {
|
||||
if modPackMap.CheckModPackExists(modPackName) == true {
|
||||
log.Printf("ModPack %s already existis", modPackName)
|
||||
return errors.New("ModPack " + modPackName + " already exists, please choose a different name")
|
||||
}
|
||||
@ -160,12 +162,12 @@ func (modPackMap *ModPackMap) createModPack(modPackName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (modPackMap *ModPackMap) createEmptyModPack(packName string) error {
|
||||
func (modPackMap *ModPackMap) CreateEmptyModPack(packName string) error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
modPackFolder := filepath.Join(config.FactorioModPackDir, packName)
|
||||
|
||||
if modPackMap.checkModPackExists(packName) == true {
|
||||
if modPackMap.CheckModPackExists(packName) == true {
|
||||
log.Printf("ModPack %s already existis", packName)
|
||||
return errors.New("ModPack " + packName + " already exists, please choose a different name")
|
||||
}
|
||||
@ -185,7 +187,7 @@ func (modPackMap *ModPackMap) createEmptyModPack(packName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (modPackMap *ModPackMap) checkModPackExists(modPackName string) bool {
|
||||
func (modPackMap *ModPackMap) CheckModPackExists(modPackName string) bool {
|
||||
for modPackId := range *modPackMap {
|
||||
if modPackId == modPackName {
|
||||
return true
|
||||
@ -195,9 +197,9 @@ func (modPackMap *ModPackMap) checkModPackExists(modPackName string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (modPackMap *ModPackMap) deleteModPack(modPackName string) error {
|
||||
func (modPackMap *ModPackMap) DeleteModPack(modPackName string) error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
modPackDir := filepath.Join(config.FactorioModPackDir, modPackName)
|
||||
|
||||
err = os.RemoveAll(modPackDir)
|
||||
@ -215,9 +217,9 @@ func (modPackMap *ModPackMap) deleteModPack(modPackName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (modPack *ModPack) loadModPack() error {
|
||||
func (modPack *ModPack) LoadModPack() error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
//get filemode, so it can be restored
|
||||
fileInfo, err := os.Stat(config.FactorioModsDir)
|
||||
if err != nil {
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -7,10 +7,29 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ModPortalStruct struct {
|
||||
DownloadsCount int `json:"downloads_count"`
|
||||
Name string `json:"name"`
|
||||
Owner string `json:"owner"`
|
||||
Releases []struct {
|
||||
DownloadURL string `json:"download_url"`
|
||||
FileName string `json:"file_name"`
|
||||
InfoJSON struct {
|
||||
FactorioVersion string `json:"factorio_version"`
|
||||
} `json:"info_json"`
|
||||
ReleasedAt time.Time `json:"released_at"`
|
||||
Sha1 string `json:"sha1"`
|
||||
Version Version `json:"version"`
|
||||
} `json:"releases"`
|
||||
Summary string `json:"summary"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
// get all mods uploaded to the factorio modPortal
|
||||
func modPortalList() (interface{}, error, int) {
|
||||
func ModPortalList() (interface{}, error, int) {
|
||||
req, err := http.NewRequest(http.MethodGet, "https://mods.factorio.com/api/mods?page_size=max", nil)
|
||||
if err != nil {
|
||||
return "error", err, 500
|
||||
@ -34,7 +53,7 @@ func modPortalList() (interface{}, error, int) {
|
||||
}
|
||||
|
||||
// get the details (mod-info, releases, etc.) from a specific mod from the modPortal
|
||||
func modPortalModDetails(modId string) (ModPortalStruct, error, int) {
|
||||
func ModPortalModDetails(modId string) (ModPortalStruct, error, int) {
|
||||
var jsonVal ModPortalStruct
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "https://mods.factorio.com/api/mods/"+modId, nil)
|
||||
@ -59,7 +78,7 @@ func modPortalModDetails(modId string) (ModPortalStruct, error, int) {
|
||||
}
|
||||
|
||||
//Log the user into factorio, so mods can be downloaded
|
||||
func factorioLogin(username string, password string) (string, error, int) {
|
||||
func FactorioLogin(username string, password string) (string, error, int) {
|
||||
var err error
|
||||
|
||||
resp, err := http.PostForm("https://auth.factorio.com/api-login",
|
||||
@ -92,12 +111,12 @@ func factorioLogin(username string, password string) (string, error, int) {
|
||||
return err.Error(), err, http.StatusInternalServerError
|
||||
}
|
||||
|
||||
credentials := FactorioCredentials{
|
||||
credentials := Credentials{
|
||||
Username: username,
|
||||
Userkey: successResponse[0],
|
||||
}
|
||||
|
||||
err = credentials.save()
|
||||
err = credentials.Save()
|
||||
if err != nil {
|
||||
log.Printf("error saving the credentials. %s", err)
|
||||
return err.Error(), err, http.StatusInternalServerError
|
@ -1,10 +1,11 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
@ -20,9 +21,9 @@ type LoginSuccessResponse struct {
|
||||
UserKey []string `json:""`
|
||||
}
|
||||
|
||||
func deleteAllMods() error {
|
||||
func DeleteAllMods() error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
modsDirInfo, err := os.Stat(config.FactorioModsDir)
|
||||
if err != nil {
|
||||
log.Printf("error getting stats of FactorioModsDir: %s", err)
|
||||
@ -46,13 +47,12 @@ func deleteAllMods() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func modStartUp() {
|
||||
var err error
|
||||
|
||||
func ModStartUp() {
|
||||
config := bootstrap.GetConfig()
|
||||
//get main-folder info
|
||||
factorioDirInfo, err := os.Stat(config.FactorioDir)
|
||||
if err != nil {
|
||||
log.Printf("error getting stats from FactorioDir: %s", err)
|
||||
log.Printf("error getting stats from FactorioDir %s with error %s", config.FactorioDir, err)
|
||||
return
|
||||
}
|
||||
factorioDirPerm := factorioDirInfo.Mode().Perm()
|
||||
@ -66,7 +66,7 @@ func modStartUp() {
|
||||
//crate mod_pack dir
|
||||
if _, err = os.Stat(config.FactorioModPackDir); os.IsNotExist(err) {
|
||||
log.Println("no ModPackDir found ... creating one ...")
|
||||
os.Mkdir(config.FactorioModPackDir, factorioDirPerm)
|
||||
_ = os.Mkdir(config.FactorioModPackDir, factorioDirPerm)
|
||||
}
|
||||
|
||||
oldModpackDir := filepath.Join(config.FactorioDir, "modpacks")
|
||||
@ -125,7 +125,7 @@ func modStartUp() {
|
||||
}
|
||||
defer modPackFile.Close()
|
||||
|
||||
mods, err := newMods(modPackDir)
|
||||
mods, err := NewMods(modPackDir)
|
||||
if err != nil {
|
||||
log.Printf("error reading mods: %s", err)
|
||||
return err
|
@ -1,6 +1,7 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
@ -9,8 +10,10 @@ import (
|
||||
|
||||
func connectRC() error {
|
||||
var err error
|
||||
config := bootstrap.GetConfig()
|
||||
rconAddr := config.ServerIP + ":" + strconv.Itoa(config.FactorioRconPort)
|
||||
FactorioServ.Rcon, err = rcon.Dial(rconAddr, config.FactorioRconPass)
|
||||
server, err := GetFactorioServer()
|
||||
server.Rcon, err = rcon.Dial(rconAddr, config.FactorioRconPass)
|
||||
if err != nil {
|
||||
log.Printf("Cannot create rcon session: %s", err)
|
||||
return err
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"archive/zip"
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"testing"
|
@ -1,8 +1,9 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -21,7 +22,7 @@ func (s Save) String() string {
|
||||
}
|
||||
|
||||
// Lists save files in factorio/saves
|
||||
func listSaves(saveDir string) (saves []Save, err error) {
|
||||
func ListSaves(saveDir string) (saves []Save, err error) {
|
||||
saves = []Save{}
|
||||
err = filepath.Walk(saveDir, func(path string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() && info.Name() == "saves" {
|
||||
@ -37,8 +38,9 @@ func listSaves(saveDir string) (saves []Save, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func findSave(name string) (*Save, error) {
|
||||
saves, err := listSaves(config.FactorioSavesDir)
|
||||
func FindSave(name string) (*Save, error) {
|
||||
config := bootstrap.GetConfig()
|
||||
saves, err := ListSaves(config.FactorioSavesDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listing saves: %v", err)
|
||||
}
|
||||
@ -52,16 +54,16 @@ func findSave(name string) (*Save, error) {
|
||||
return nil, errors.New("save not found")
|
||||
}
|
||||
|
||||
func (s *Save) remove() error {
|
||||
func (s *Save) Remove() error {
|
||||
if s.Name == "" {
|
||||
return errors.New("save name cannot be blank")
|
||||
}
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
return os.Remove(filepath.Join(config.FactorioSavesDir, s.Name))
|
||||
}
|
||||
|
||||
// Create savefiles for Factorio
|
||||
func createSave(filePath string) (string, error) {
|
||||
func CreateSave(filePath string) (string, error) {
|
||||
err := os.MkdirAll(filepath.Dir(filePath), 0755)
|
||||
if err != nil {
|
||||
log.Printf("Error in creating Factorio save: %s", err)
|
||||
@ -69,6 +71,7 @@ func createSave(filePath string) (string, error) {
|
||||
}
|
||||
|
||||
args := []string{"--create", filePath}
|
||||
config := bootstrap.GetConfig()
|
||||
cmdOutput, err := exec.Command(config.FactorioBinary, args...).Output()
|
||||
if err != nil {
|
||||
log.Printf("Error in creating Factorio save: %s", err)
|
@ -1,24 +1,24 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/majormjr/rcon"
|
||||
)
|
||||
|
||||
type FactorioServer struct {
|
||||
type Server struct {
|
||||
Cmd *exec.Cmd `json:"-"`
|
||||
Savefile string `json:"savefile"`
|
||||
Latency int `json:"latency"`
|
||||
@ -35,24 +35,22 @@ type FactorioServer struct {
|
||||
LogChan chan []string `json:"-"`
|
||||
}
|
||||
|
||||
func randomPort() int {
|
||||
// Returns random port to use for rcon connection
|
||||
return rand.Intn(45000-40000) + 40000
|
||||
}
|
||||
var instantiated Server
|
||||
var once sync.Once
|
||||
|
||||
func autostart() {
|
||||
func (f *Server) autostart() {
|
||||
|
||||
var err error
|
||||
if FactorioServ.BindIP == "" {
|
||||
FactorioServ.BindIP = "0.0.0.0"
|
||||
if f.BindIP == "" {
|
||||
f.BindIP = "0.0.0.0"
|
||||
|
||||
}
|
||||
if FactorioServ.Port == 0 {
|
||||
FactorioServ.Port = 34197
|
||||
if f.Port == 0 {
|
||||
f.Port = 34197
|
||||
}
|
||||
FactorioServ.Savefile = "Load Latest"
|
||||
f.Savefile = "Load Latest"
|
||||
|
||||
err = FactorioServ.Run()
|
||||
err = f.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Error starting Factorio server: %+v", err)
|
||||
@ -61,12 +59,14 @@ func autostart() {
|
||||
|
||||
}
|
||||
|
||||
func initFactorio() (f *FactorioServer, err error) {
|
||||
f = new(FactorioServer)
|
||||
func GetFactorioServer() (f Server, err error) {
|
||||
once.Do(func() {
|
||||
f = Server{}
|
||||
f.Settings = make(map[string]interface{})
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
if err = os.MkdirAll(config.FactorioConfigDir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("failed to create config directory: %v", err)
|
||||
log.Printf("failed to create bootstrap directory: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
settingsPath := filepath.Join(config.FactorioConfigDir, config.SettingsFile)
|
||||
@ -80,49 +80,56 @@ func initFactorio() (f *FactorioServer, err error) {
|
||||
|
||||
example, err := os.Open(examplePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open example server settings: %v", err)
|
||||
log.Printf("failed to open example server settings: %v", err)
|
||||
return
|
||||
}
|
||||
defer example.Close()
|
||||
|
||||
settings, err = os.Create(settingsPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create server settings file: %v", err)
|
||||
log.Printf("failed to create server settings file: %v", err)
|
||||
return
|
||||
}
|
||||
defer settings.Close()
|
||||
|
||||
_, err = io.Copy(settings, example)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to copy example server settings: %v", err)
|
||||
log.Printf("failed to copy example server settings: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = example.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to close example server settings: %s", err)
|
||||
log.Printf("failed to close example server settings: %s", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// otherwise, open file normally
|
||||
settings, err = os.Open(settingsPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open server settings file: %v", err)
|
||||
log.Printf("failed to open server settings file: %v", err)
|
||||
return
|
||||
}
|
||||
defer settings.Close()
|
||||
}
|
||||
|
||||
// before reading reset offset
|
||||
if _, err = settings.Seek(0, 0); err != nil {
|
||||
return nil, fmt.Errorf("error while seeking in settings file: %v", err)
|
||||
log.Printf("error while seeking in settings file: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewDecoder(settings).Decode(&f.Settings); err != nil {
|
||||
return nil, fmt.Errorf("error reading %s: %v", settingsPath, err)
|
||||
log.Printf("error reading %s: %v", settingsPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Loaded Factorio settings from %s\n", settingsPath)
|
||||
|
||||
out := []byte{}
|
||||
//Load factorio version
|
||||
if config.glibcCustom == "true" {
|
||||
out, err = exec.Command(config.glibcLocation, "--library-path", config.glibcLibLoc, config.FactorioBinary, "--version").Output()
|
||||
if config.GlibcCustom == "true" {
|
||||
out, err = exec.Command(config.GlibcLocation, "--library-path", config.GlibcLibLoc, config.FactorioBinary, "--version").Output()
|
||||
} else {
|
||||
out, err = exec.Command(config.FactorioBinary, "--version").Output()
|
||||
}
|
||||
@ -160,35 +167,38 @@ func initFactorio() (f *FactorioServer, err error) {
|
||||
if (f.Version.Greater(Version{0, 17, 0})) {
|
||||
if _, err := os.Stat(filepath.Join(config.FactorioConfigDir, config.FactorioAdminFile)); os.IsNotExist(err) {
|
||||
//save empty admins-file
|
||||
ioutil.WriteFile(filepath.Join(config.FactorioConfigDir, config.FactorioAdminFile), []byte("[]"), 0664)
|
||||
_ = ioutil.WriteFile(filepath.Join(config.FactorioConfigDir, config.FactorioAdminFile), []byte("[]"), 0664)
|
||||
} else {
|
||||
data, err := ioutil.ReadFile(filepath.Join(config.FactorioConfigDir, config.FactorioAdminFile))
|
||||
if err != nil {
|
||||
log.Printf("Error loading FactorioAdminFile: %s", err)
|
||||
return f, err
|
||||
return
|
||||
}
|
||||
|
||||
var jsonData interface{}
|
||||
err = json.Unmarshal(data, &jsonData)
|
||||
if err != nil {
|
||||
log.Printf("Error unmarshalling FactorioAdminFile: %s", err)
|
||||
return f, err
|
||||
return
|
||||
}
|
||||
|
||||
f.Settings["admins"] = jsonData
|
||||
}
|
||||
}
|
||||
|
||||
if config.autostart == "true" {
|
||||
go autostart()
|
||||
}
|
||||
instantiated = f
|
||||
|
||||
return
|
||||
if config.Autostart == "true" {
|
||||
go instantiated.autostart()
|
||||
}
|
||||
})
|
||||
|
||||
return instantiated, nil
|
||||
}
|
||||
|
||||
func (f *FactorioServer) Run() error {
|
||||
func (f *Server) Run() error {
|
||||
var err error
|
||||
|
||||
config := bootstrap.GetConfig()
|
||||
data, err := json.MarshalIndent(f.Settings, "", " ")
|
||||
if err != nil {
|
||||
log.Println("Failed to marshal FactorioServerSettings: ", err)
|
||||
@ -200,9 +210,9 @@ func (f *FactorioServer) Run() error {
|
||||
|
||||
//The factorio server refenences its executable-path, since we execute the ld.so file and pass the factorio binary as a parameter
|
||||
//the game would use the path to the ld.so file as it's executable path and crash, to prevent this the parameter "--executable-path" is added
|
||||
if config.glibcCustom == "true" {
|
||||
log.Println("Custom glibc selected, glibc.so location:", config.glibcLocation, " lib location:", config.glibcLibLoc)
|
||||
args = append(args, "--library-path", config.glibcLibLoc, config.FactorioBinary, "--executable-path", config.FactorioBinary)
|
||||
if config.GlibcCustom == "true" {
|
||||
log.Println("Custom glibc selected, glibc.so location:", config.GlibcLocation, " lib location:", config.GlibcLibLoc)
|
||||
args = append(args, "--library-path", config.GlibcLibLoc, config.FactorioBinary, "--executable-path", config.FactorioBinary)
|
||||
}
|
||||
|
||||
args = append(args,
|
||||
@ -222,9 +232,9 @@ func (f *FactorioServer) Run() error {
|
||||
args = append(args, "--start-server", filepath.Join(config.FactorioSavesDir, f.Savefile))
|
||||
}
|
||||
|
||||
if config.glibcCustom == "true" {
|
||||
log.Println("Starting server with command: ", config.glibcLocation, args)
|
||||
f.Cmd = exec.Command(config.glibcLocation, args...)
|
||||
if config.GlibcCustom == "true" {
|
||||
log.Println("Starting server with command: ", config.GlibcLocation, args)
|
||||
f.Cmd = exec.Command(config.GlibcLocation, args...)
|
||||
} else {
|
||||
log.Println("Starting server with command: ", config.FactorioBinary, args)
|
||||
f.Cmd = exec.Command(config.FactorioBinary, args...)
|
||||
@ -268,7 +278,7 @@ func (f *FactorioServer) Run() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FactorioServer) parseRunningCommand(std io.ReadCloser) (err error) {
|
||||
func (f *Server) parseRunningCommand(std io.ReadCloser) (err error) {
|
||||
stdScanner := bufio.NewScanner(std)
|
||||
for stdScanner.Scan() {
|
||||
log.Printf("Factorio Server: %s", stdScanner.Text())
|
||||
@ -308,7 +318,8 @@ func (f *FactorioServer) parseRunningCommand(std io.ReadCloser) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FactorioServer) writeLog(logline string) error {
|
||||
func (f *Server) writeLog(logline string) error {
|
||||
config := bootstrap.GetConfig()
|
||||
logfileName := filepath.Join(config.FactorioDir, "factorio-server-console.log")
|
||||
file, err := os.OpenFile(logfileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
@ -327,7 +338,7 @@ func (f *FactorioServer) writeLog(logline string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FactorioServer) checkLogError(logline []string) error {
|
||||
func (f *Server) checkLogError(logline []string) error {
|
||||
// TODO Handle errors generated by running Factorio Server
|
||||
log.Println(logline)
|
||||
|
@ -1,7 +1,7 @@
|
||||
// use this file only when compiling not windows (all unix systems)
|
||||
// +build !windows
|
||||
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"log"
|
||||
@ -10,7 +10,7 @@ import (
|
||||
|
||||
// Stubs for windows-only functions
|
||||
|
||||
func (f *FactorioServer) Kill() error {
|
||||
func (f *Server) Kill() error {
|
||||
err := f.Cmd.Process.Signal(os.Kill)
|
||||
if err != nil {
|
||||
if err.Error() == "os: process already finished" {
|
||||
@ -31,7 +31,7 @@ func (f *FactorioServer) Kill() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FactorioServer) Stop() error {
|
||||
func (f *Server) Stop() error {
|
||||
err := f.Cmd.Process.Signal(os.Interrupt)
|
||||
if err != nil {
|
||||
if err.Error() == "os: process already finished" {
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"log"
|
||||
@ -42,7 +42,7 @@ func setCtrlHandlingIsDisabledForThisProcess(disabled bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FactorioServer) Kill() error {
|
||||
func (f *Server) Kill() error {
|
||||
err := f.Cmd.Process.Signal(os.Kill)
|
||||
if err != nil {
|
||||
if err.Error() == "os: process already finished" {
|
||||
@ -58,7 +58,7 @@ func (f *FactorioServer) Kill() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FactorioServer) Stop() error {
|
||||
func (f *Server) Stop() error {
|
||||
// Disable our own handling of CTRL+C, so we don't close when we send it to the console.
|
||||
setCtrlHandlingIsDisabledForThisProcess(true)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package main
|
||||
package factorio
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
153
src/main.go
153
src/main.go
@ -1,140 +1,69 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/mroote/factorio-server-manager/api"
|
||||
"github.com/mroote/factorio-server-manager/bootstrap"
|
||||
"github.com/mroote/factorio-server-manager/factorio"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
FactorioDir string `json:"factorio_dir"`
|
||||
FactorioSavesDir string `json:"saves_dir"`
|
||||
FactorioModsDir string `json:"mods_dir"`
|
||||
FactorioModPackDir string `json:"mod_pack_dir"`
|
||||
FactorioConfigFile string `json:"config_file"`
|
||||
FactorioConfigDir string `json:"config_directory"`
|
||||
FactorioLog string `json:"logfile"`
|
||||
FactorioBinary string `json:"factorio_binary"`
|
||||
FactorioRconPort int `json:"rcon_port"`
|
||||
FactorioRconPass string `json:"rcon_pass"`
|
||||
FactorioCredentialsFile string `json:"factorio_credentials_file"`
|
||||
FactorioIP string `json:"factorio_ip"`
|
||||
FactorioAdminFile string `json:"-"`
|
||||
ServerIP string `json:"server_ip"`
|
||||
ServerPort string `json:"server_port"`
|
||||
MaxUploadSize int64 `json:"max_upload_size"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
DatabaseFile string `json:"database_file"`
|
||||
CookieEncryptionKey string `json:"cookie_encryption_key"`
|
||||
SettingsFile string `json:"settings_file"`
|
||||
LogFile string `json:"log_file"`
|
||||
ConfFile string
|
||||
glibcCustom string
|
||||
glibcLocation string
|
||||
glibcLibLoc string
|
||||
autostart string
|
||||
}
|
||||
func main() {
|
||||
// parse command flags and pass them to bootstrap
|
||||
flags := parseFlags()
|
||||
bootstrap.SetFlags(flags)
|
||||
|
||||
var (
|
||||
config Config
|
||||
FactorioServ *FactorioServer
|
||||
Auth *AuthHTTP
|
||||
)
|
||||
// get the all configs based on the flags
|
||||
config := bootstrap.GetConfig()
|
||||
|
||||
func failOnError(err error, msg string) {
|
||||
// setup the required files for the mods
|
||||
factorio.ModStartUp()
|
||||
|
||||
// Initialize Factorio Server struct
|
||||
_, err := factorio.GetFactorioServer()
|
||||
if err != nil {
|
||||
log.Printf("%s: %s", msg, err)
|
||||
panic(fmt.Sprintf("%s: %s", msg, err))
|
||||
log.Printf("Error occurred during Server initializaion: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Initialize authentication system
|
||||
api.GetAuth()
|
||||
|
||||
// Initialize HTTP router
|
||||
router := api.NewRouter()
|
||||
log.Printf("Starting server on: %s:%s", config.ServerIP, config.ServerPort)
|
||||
log.Fatal(http.ListenAndServe(config.ServerIP+":"+config.ServerPort, router))
|
||||
|
||||
}
|
||||
|
||||
// Loads server configuration files
|
||||
// JSON config file contains default values,
|
||||
// config file will overwrite any provided flags
|
||||
func loadServerConfig(f string) {
|
||||
file, err := os.Open(f)
|
||||
failOnError(err, "Error loading config file.")
|
||||
|
||||
decoder := json.NewDecoder(file)
|
||||
err = decoder.Decode(&config)
|
||||
failOnError(err, "Error decoding JSON config file.")
|
||||
|
||||
config.FactorioRconPort = randomPort()
|
||||
}
|
||||
|
||||
func parseFlags() {
|
||||
confFile := flag.String("conf", "./conf.json", "Specify location of Factorio Server Manager config file.")
|
||||
func parseFlags() bootstrap.Flags {
|
||||
confFile := flag.String("conf", "./conf.json", "Specify location of Factorio Server Manager bootstrap file.")
|
||||
factorioDir := flag.String("dir", "./", "Specify location of Factorio directory.")
|
||||
serverIP := flag.String("host", "0.0.0.0", "Specify IP for webserver to listen on.")
|
||||
factorioIP := flag.String("game-bind-address", "0.0.0.0", "Specify IP for Fcatorio gamer server to listen on.")
|
||||
factorioPort := flag.String("port", "8080", "Specify a port for the server.")
|
||||
factorioConfigFile := flag.String("config", "config/config.ini", "Specify location of Factorio config.ini file")
|
||||
factorioConfigFile := flag.String("bootstrap", "bootstrap/bootstrap.ini", "Specify location of Factorio bootstrap.ini file")
|
||||
factorioMaxUpload := flag.Int64("max-upload", 1024*1024*20, "Maximum filesize for uploaded files (default 20MB).")
|
||||
factorioBinary := flag.String("bin", "bin/x64/factorio", "Location of Factorio Server binary file")
|
||||
glibcCustom := flag.String("glibc-custom", "false", "By default false, if custom glibc is required set this to true and add glibc-loc and glibc-lib-loc parameters")
|
||||
glibcLocation := flag.String("glibc-loc", "/opt/glibc-2.18/lib/ld-2.18.so", "Location glibc ld.so file if needed (ex. /opt/glibc-2.18/lib/ld-2.18.so)")
|
||||
glibcLibLoc := flag.String("glibc-lib-loc", "/opt/glibc-2.18/lib", "Location of glibc lib folder (ex. /opt/glibc-2.18/lib)")
|
||||
autostart := flag.String("autostart", "false", "Autostart factorio server on bootup of FSM, default false [true/false]")
|
||||
|
||||
flag.Parse()
|
||||
config.autostart = *autostart
|
||||
config.glibcCustom = *glibcCustom
|
||||
config.glibcLocation = *glibcLocation
|
||||
config.glibcLibLoc = *glibcLibLoc
|
||||
config.ConfFile = *confFile
|
||||
config.FactorioDir = *factorioDir
|
||||
config.ServerIP = *serverIP
|
||||
config.FactorioIP = *factorioIP
|
||||
config.ServerPort = *factorioPort
|
||||
config.FactorioSavesDir = filepath.Join(config.FactorioDir, "saves")
|
||||
config.FactorioModsDir = filepath.Join(config.FactorioDir, "mods")
|
||||
config.FactorioModPackDir = "./mod_packs"
|
||||
config.FactorioConfigDir = filepath.Join(config.FactorioDir, "config")
|
||||
config.FactorioConfigFile = filepath.Join(config.FactorioDir, *factorioConfigFile)
|
||||
config.FactorioBinary = filepath.Join(config.FactorioDir, *factorioBinary)
|
||||
config.FactorioCredentialsFile = "./factorio.auth"
|
||||
config.FactorioAdminFile = "server-adminlist.json"
|
||||
config.MaxUploadSize = *factorioMaxUpload
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
appdata := os.Getenv("APPDATA")
|
||||
config.FactorioLog = filepath.Join(appdata, "Factorio", "factorio-current.log")
|
||||
} else {
|
||||
config.FactorioLog = filepath.Join(config.FactorioDir, "factorio-current.log")
|
||||
return bootstrap.Flags{
|
||||
ConfFile: confFile,
|
||||
FactorioDir: factorioDir,
|
||||
ServerIP: serverIP,
|
||||
FactorioIP: factorioIP,
|
||||
FactorioPort: factorioPort,
|
||||
FactorioConfigFile: factorioConfigFile,
|
||||
FactorioMaxUpload: factorioMaxUpload,
|
||||
FactorioBinary: factorioBinary,
|
||||
GlibcCustom: glibcCustom,
|
||||
GlibcLocation: glibcLocation,
|
||||
GlibcLibLoc: glibcLibLoc,
|
||||
Autostart: autostart,
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
// Parse configuration flags
|
||||
parseFlags()
|
||||
// Load server config from file
|
||||
loadServerConfig(config.ConfFile)
|
||||
// create mod-stuff
|
||||
modStartUp()
|
||||
|
||||
// Initialize Factorio Server struct
|
||||
FactorioServ, err = initFactorio()
|
||||
if err != nil {
|
||||
log.Printf("Error occurred during FactorioServer initializaion: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Initialize authentication system
|
||||
Auth = initAuth()
|
||||
Auth.CreateAuth(config.DatabaseFile, config.CookieEncryptionKey)
|
||||
Auth.CreateOrUpdateUser(config.Username, config.Password, "admin", "")
|
||||
|
||||
// Initialize HTTP router
|
||||
router := NewRouter()
|
||||
log.Printf("Starting server on: %s:%s", config.ServerIP, config.ServerPort)
|
||||
log.Fatal(http.ListenAndServe(config.ServerIP+":"+config.ServerPort, router))
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user