Compare commits

...

3 Commits

Author SHA1 Message Date
e7f967c6bd Reverted changes that used bubbletea lib
Fixed some minor issues with backup func
added stdout to backup functions
added stdout to launchserver functions
changed tar execs to add verbos for stdout
2026-01-14 15:13:59 -07:00
86ccf302ea Working on adding a TUI 2026-01-14 02:18:47 -07:00
b2c534f29b Fixes Changes and new additions
Fixed an issue where launching server w/o screen failed
New: added an output showing screen sessions after launching
New: added stdout and stdin to screenless launch allowing interacting with server cli
Change: Broke up source code to make it easier to read and make changes
Change: Updated .gitignore
2026-01-13 10:51:18 -07:00
8 changed files with 136 additions and 113 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.vscode
factorio-headless_linux_2.0.72

36
backup.go Normal file
View File

@@ -0,0 +1,36 @@
package main
import (
"fmt"
"os"
"os/exec"
"time"
)
func backUp(cmd string, c GoConfig) {
switch cmd {
case "full":
fmt.Println("Starting full server backup")
t := time.Now()
timeStamp := t.Format(time.RFC3339)
fullBackupName := fmt.Sprintf("%s/ServerBackup.%s.tgz", c.Config.BackupDir, timeStamp)
fullBackup := exec.Command("tar", "-czvf", fullBackupName, c.Config.ServDir)
fullBackup.Stdout = os.Stdout
err := fullBackup.Run()
if err != nil {
fmt.Printf("Backup Failed: %s\n", err)
}
case "saves":
fmt.Println("Backing up saves")
t := time.Now()
timeStamp := t.Format(time.RFC3339)
savesBackupName := fmt.Sprintf("%s/SaveBackup.%s.tgz", c.Config.BackupDir, timeStamp)
saveDir := fmt.Sprintf("%s/saves", c.Config.ServDir)
savesBackup := exec.Command("tar", "-czvf", savesBackupName, saveDir)
savesBackup.Stdout = os.Stdout
err := savesBackup.Run()
if err != nil {
fmt.Printf("Backup Failed: %s\n", err)
}
}
}

38
config.go Normal file
View File

@@ -0,0 +1,38 @@
package main
import (
"log"
"os"
"gopkg.in/yaml.v3"
)
const fmConfig = "config.yml"
type GoConfig struct {
Config struct {
ServDir string `yaml:"serverFolder"`
ServPort int `yaml:"port"`
WorldFile string `yaml:"worldFile"`
ServCfg string `yaml:"serverSettings"`
ServExec string `yaml:"serverExec"`
BackupDir string `yaml:"backupDir"`
UseScreen bool `yaml:"screen"`
ScreenName string `yaml:"screenName"`
} `yaml:"server"`
}
func readCfg(factCfg string) GoConfig {
//read config file (YAML)
fileBytes, err := os.ReadFile(factCfg)
if err != nil {
log.Fatalf("Error reading config file: %v", err)
}
// return Struct
var config GoConfig
err = yaml.Unmarshal(fileBytes, &config)
if err != nil {
log.Fatalf("Error unmarshalling YAML file: %v", err)
}
return config
}

View File

@@ -1,9 +1,9 @@
server:
serverFolder: "factorio"
serverFolder: "factorio-headless_linux_2.0.72/factorio"
port: 34197
worldFile: "factorio/newworld.zip"
serverSettings: "factorio/data/server-settings.json"
backupDir: "backups"
serverExec: "factorio/bin/x64/factorio"
worldFile: "factorio-headless_linux_2.0.72/factorio/Newworlds.zip"
serverSettings: "factorio-headless_linux_2.0.72/factorio/data/server-settings.json"
backupDir: "factorio-headless_linux_2.0.72/backups"
serverExec: "factorio-headless_linux_2.0.72/factorio/bin/x64/factorio"
screen: True
screenName: "Factorio"

Binary file not shown.

4
go.mod
View File

@@ -1,5 +1,7 @@
module gitlab.com/Raum0x2A/factoryman
go 1.22.2
go 1.24.0
toolchain go1.24.4
require gopkg.in/yaml.v3 v3.0.1

42
launchserver.go Normal file
View File

@@ -0,0 +1,42 @@
package main
import (
"fmt"
"log"
"os"
"os/exec"
)
func startStopServer(cmd string, con GoConfig) {
switch cmd {
case "start":
x := fmt.Sprintf("%s --port %d --server-settings %s --start-server %s", con.Config.ServExec, con.Config.ServPort, con.Config.ServCfg, con.Config.WorldFile)
if con.Config.UseScreen { // if screen enabled in confing.yml
fmt.Println("Starting factorio server in screen session")
startScreenCmd := exec.Command("screen", "-dmS", con.Config.ScreenName, "bash", "-c", x, "; exec sh")
startScreenCmd.Stdout = os.Stdout
startScreenCmd.Stderr = os.Stderr
err := startScreenCmd.Run()
if err != nil {
log.Fatalf("Failed to start server: %s", err)
}
} else {
startSrvCmd := exec.Command("bash", "-c", x)
startSrvCmd.Stdout = os.Stdout
startSrvCmd.Stderr = os.Stdout
startSrvCmd.Stdin = os.Stdin
err := startSrvCmd.Run()
if err != nil {
log.Fatalf("Failed to start server: %s", err)
}
}
case "stop":
quitServerCmd := exec.Command("screen", "-S", con.Config.ScreenName, "-p", "0", "-X", "stuff", "/quit\n")
err := quitServerCmd.Run()
if err != nil {
log.Fatalf("Command failed: %s, Error: %v", quitServerCmd.Args, err)
} else {
fmt.Println("Server Stopped")
}
}
}

117
main.go
View File

@@ -2,123 +2,26 @@ package main
import (
"fmt"
"log"
"os"
"os/exec"
"time"
"gopkg.in/yaml.v3"
)
const fmConfig = "config.yml"
type GoConfig struct {
Config struct {
ServDir string `yaml:"serverFolder"`
ServPort int `yaml:"port"`
WorldFile string `yaml:"worldFile"`
ServCfg string `yaml:"serverSettings"`
ServExec string `yaml:"serverExec"`
BackupDir string `yaml:"backupDir"`
UseScreen bool `yaml:"screen"`
ScreenName string `yaml:"screenName"`
} `yaml:"server"`
}
func readCfg(factCfg string) GoConfig {
//read config file (YAML)
fileBytes, err := os.ReadFile(factCfg)
if err != nil {
log.Fatalf("Error reading config file: %v", err)
}
// return Struct
var config GoConfig
err = yaml.Unmarshal(fileBytes, &config)
if err != nil {
log.Fatalf("Error unmarshalling YAML file: %v", err)
}
return config
}
func startStopServer(cmd string, con GoConfig) {
switch cmd {
case "start":
x := fmt.Sprintf("%s --port %d --server-settings %s --start-server %s", con.Config.ServExec, con.Config.ServPort, con.Config.ServCfg, con.Config.WorldFile)
//x := fmt.Sprintf("%s --port %d --server-settings %s --start-server %s; exec sh", con.Config.ServExec, con.Config.ServPort, con.Config.ServCfg, con.Config.WorldFile)
///home/raum/factorio-serverfmt.Println(x)
if con.Config.UseScreen {
fmt.Println("Starting factorio server in screen session")
startScreenCmd := exec.Command("screen", "-dmS", con.Config.ScreenName, "bash", "-c", x, "; exec sh")
err := startScreenCmd.Run()
if err != nil {
log.Fatalf("Failed to start server: %s", err)
} else {
fmt.Printf("Started server on port %d, in screen named %s\n", con.Config.ServPort, con.Config.ScreenName)
}
} else {
startSrvCmd := exec.Command(x)
err := startSrvCmd.Run()
if err != nil {
log.Fatalf("Failed to start server: %s", err)
}
}
case "stop":
quitServerCmd := exec.Command("screen", "-S", con.Config.ScreenName, "-p", "0", "-X", "stuff", "/quit\n")
err := quitServerCmd.Run()
if err != nil {
log.Fatalf("Command failed: %s, Error: %v", quitServerCmd.Args, err)
} else {
fmt.Printf("Server in screen %s stopped\n", con.Config.ScreenName)
}
fmt.Println("Waiting for server to shutdown\r")
//time.Sleep(20 * time.Second)
//fmt.Println("Closing screen session ", con.Config.ScreenName)
//stopScreenCmd := exec.Command("screen", "-S", con.Config.ScreenName, "-p", "0", "-X", "stuff", "exit\n")
//err = stopScreenCmd.Run()
//if err != nil {
// log.Fatalf("Command failed: %s, Error: %v", stopScreenCmd.Args, err)
//} else {
// fmt.Printf("Screen \"%s\" closed\n", con.Config.ScreenName)
//}
}
}
func backUp(cmd string, c GoConfig) {
switch cmd {
case "full":
fmt.Println("Starting full server backup")
t := time.Now()
timeStamp := t.Format(time.RFC3339)
fullBackupName := fmt.Sprintf("%s/ServerBackup.%s.tgz", c.Config.BackupDir, timeStamp)
fullBackup := exec.Command("tar", "-czf", fullBackupName, c.Config.ServDir)
err := fullBackup.Run()
if err != nil {
fmt.Printf("Backup Failed: %s\n", err)
}
case "saves":
fmt.Println("Backing up saves")
t := time.Now()
timeStamp := t.Format(time.RFC3339)
savesBackupName := fmt.Sprintf("%s/SaveBackup.%s.tgz", c.Config.BackupDir, timeStamp)
saveDir := fmt.Sprintf("%s/saves", c.Config.ServDir)
savesBackup := exec.Command("tar", "-czf", savesBackupName, saveDir)
err := savesBackup.Run()
if err != nil {
fmt.Printf("Backup Failed: %s\n", err)
}
}
}
var c = readCfg(fmConfig)
func main() {
c := readCfg(fmConfig)
if len(os.Args) > 1 {
if len(os.Args) == 1 {
fmt.Println("Use 'start', 'stop', or 'backup' command")
fmt.Println("ex. factoryman start")
fmt.Println("To configure edit 'conifg.yml'")
} else if len(os.Args) > 1 {
switch os.Args[1] {
case "start":
startStopServer("start", c)
case "stop":
startStopServer("stop", c)
case "help", "h", "--help", "-h":
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 "backup":
if len(os.Args) > 2 {
switch os.Args[2] {