Added Mod and server downloader #1

Merged
Raum0x2A merged 8 commits from develop into main 2026-05-04 13:47:19 +00:00
7 changed files with 151 additions and 7 deletions
Showing only changes of commit 2548261d66 - Show all commits

21
cli.go
View File

@@ -6,7 +6,8 @@ import (
)
func cliToolMode() {
var c = readCfg(fmConfig)
var c = readCfg("config.yml")
modlist := string(c.Server.ServDir) + "/mods/mod-list.json"
if verifyConfig(c) {
if len(os.Args) > 1 {
switch os.Args[1] {
@@ -18,6 +19,22 @@ func cliToolMode() {
fmt.Printf("Start Server: %s start\nStop Server: %s stop\n", os.Args[0], os.Args[0])
fmt.Printf("Run backup\n\tFull backup: %s backup full", os.Args[0])
fmt.Printf("\n\tBackup saves: %s backup saves\n", os.Args[0])
case "mod":
if len(os.Args) > 2 {
switch os.Args[2] {
case "download":
if !findmodlist(modlist) {
fmt.Printf("FAILED TO FIND MOD LIST")
} else {
fmt.Printf("found %s\n", modlist)
downloadMods(modlist)
}
default:
fmt.Println("Invalid mod option: use 'update'")
}
} else {
fmt.Println("Missing mod option: use 'update'")
}
case "backup":
if len(os.Args) > 2 {
switch os.Args[2] {
@@ -35,7 +52,7 @@ func cliToolMode() {
fmt.Printf("Unknown command: %s. Use 'start', 'stop', or 'backup'.\n", os.Args[1])
}
} else {
fmt.Println("Use 'start', 'stop', or 'backup' command\nex. factoryman start\nTo configure edit 'conifg.yml'")
fmt.Println("Use 'start', 'stop', or 'backup' command\nex. factoryman start\nTo configure edit 'config.yml'")
}
}
}

View File

@@ -9,8 +9,6 @@ import (
"gopkg.in/yaml.v3"
)
const fmConfig = "config.yml"
type GoConfig struct {
Server struct { // server specific settings
ServDir string `yaml:"serverFolder"`
@@ -24,6 +22,8 @@ type GoConfig struct {
BackupDir string `yaml:"backupDir"`
UseScreen bool `yaml:"screen"`
ScreenName string `yaml:"screenName"`
UserName string `yaml:"username"`
ApiToken string `yaml:"apitoken"`
} `yaml:"factoryman"`
}

View File

@@ -1,6 +1,6 @@
server:
serverFolder: "factorio"
worldFile: "factorio/data/saves/newworld.zip"
worldFile: "factorio/saves/test.zip"
serverSettings: "factorio/data/server-settings.json"
serverExec: "factorio/bin/x64/factorio"
port: 34197
@@ -8,4 +8,6 @@ server:
factoryman:
screen: True
screenName: "Factorio"
backupDir: "factorio/backups"
backupDir: "factorio/backups"
username: ""
apitoken: ""

Binary file not shown.

37
jsonStruts.go Normal file
View File

@@ -0,0 +1,37 @@
package main
type Mod struct {
Name string `json:"name"`
Enabled bool `json:"enabled"`
Version string `json:"version,omitempty"`
}
type ModList struct {
Mods []Mod `json:"mods"`
}
type ModPortal struct {
Category string `json:"category"`
DownloadCount int `json:"downloads_count"`
Name string `json:"name"`
Owner string `json:"owner"`
Releases []Release `json:"releases"`
Score float64 `json:"score"`
Summary string `json:"summary"`
Thumbnail string `json:"thumbnail"`
Title string `json:"title"`
}
type Release struct {
DownloadUrl string `json:"download_url"`
Filename string `json:"file_name"`
InfoJson InfoJSON `json:"info_json"`
ReleaseTime string `json:"released_at"`
Sha1 string `json:"sha1"`
Version string `json:"version"`
}
type InfoJSON struct {
Dependencies []string `json:"dependencies"`
FactorioVersion string `json:"factorio_version"`
}

View File

@@ -11,7 +11,7 @@ func startStopServer(cmd string, con GoConfig) {
switch cmd {
case "start":
x := fmt.Sprintf("%s --port %d --server-settings %s --start-server %s", con.Server.ServExec, con.Server.ServPort, con.Server.ServCfg, con.Server.WorldFile)
if con.Factoryman.UseScreen { // if screen enabled in confing.yml
if con.Factoryman.UseScreen { // if screen enabled in config.yml
fmt.Println("Starting factorio server in screen session")
startScreenCmd := exec.Command("screen", "-dmS", con.Factoryman.ScreenName, "bash", "-c", x, "; exec sh")
startScreenCmd.Stdout = os.Stdout

88
mods.go Normal file
View File

@@ -0,0 +1,88 @@
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
)
func findmodlist(modlist string) bool {
if !isItReal(modlist) {
return false
} else {
return true
}
}
func download(filedest string, url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
out, err := os.Create(filedest)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return err
}
func downloadMods(modlist string) {
var c = readCfg("config.yml")
fmt.Printf("Updating mods from %s\n", modlist)
file, err := os.Open(modlist)
if err != nil {
log.Fatalf("Error reading modlist: %v", err)
}
defer file.Close()
var modList ModList
decoder := json.NewDecoder(file)
if err := decoder.Decode(&modList); err != nil {
log.Fatalf("Error reading JSON: %v", err)
}
for _, mod := range modList.Mods {
switch mod.Name {
case "base":
fmt.Println("Skipping base...")
case "elevated-rails":
fmt.Println("Skipping elevated-rails...")
case "quality":
fmt.Println("Skipping quality...")
case "space-age":
fmt.Println("Skipping space-age...")
default:
modportalurl := fmt.Sprintf("https://mods.factorio.com/api/mods/%s", mod.Name)
resp, err := http.Get(modportalurl)
if err != nil {
log.Fatalf("Error reading JSON: %v", err)
}
defer resp.Body.Close()
var moddata ModPortal
if err := json.NewDecoder(resp.Body).Decode(&moddata); err != nil {
log.Fatalf("Error reading JSON: %v", err)
}
fmt.Printf("Mod: %s, Ver: %s, Enabled: %t\n", mod.Name, mod.Version, mod.Enabled)
accessToken := fmt.Sprintf("?username=%s&token=%s", c.Factoryman.UserName, c.Factoryman.ApiToken)
modDownloadUrl := fmt.Sprintf("https://mods.factorio.com%s%s", moddata.Releases[len(moddata.Releases)-1].DownloadUrl, accessToken)
fmt.Println(modDownloadUrl)
downloadErr := download(string(c.Server.ServDir+"/mods/"+moddata.Releases[len(moddata.Releases)-1].Filename), modDownloadUrl)
if downloadErr != nil {
log.Fatalf("Error downloading: %v", downloadErr)
}
fmt.Printf("Downloaded: %s\n", moddata.Releases[len(moddata.Releases)-1].Filename)
}
}
}