Skip to content

Commit 2cb7628

Browse files
author
Mitch Roote
authored
Merge pull request #54 from bostelk/server-settings
Server settings first-pass
2 parents 42c8cbd + 196b6de commit 2cb7628

File tree

6 files changed

+249
-138
lines changed

6 files changed

+249
-138
lines changed
File renamed without changes.

src/factorio_server.go

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
"io/ioutil"
7+
"log"
8+
"os"
9+
"os/exec"
10+
"path/filepath"
11+
"runtime"
12+
"strconv"
13+
)
14+
15+
type FactorioServer struct {
16+
Cmd *exec.Cmd
17+
Savefile string
18+
Latency int `json:"latency"`
19+
Port int `json:"port"`
20+
Running bool `json:"running"`
21+
StdOut io.ReadCloser
22+
StdErr io.ReadCloser
23+
StdIn io.WriteCloser
24+
Settings FactorioServerSettings
25+
}
26+
27+
type FactorioServerSettings struct {
28+
Name string `json:"name"`
29+
Description string `json:"description"`
30+
Tags []string `json:"tags"`
31+
MaxPlayers int `json:"max_players"`
32+
Visibility string `json:"visibility"`
33+
Username string `json:"username"`
34+
Password string `json:"password"`
35+
Token string `json:"token"`
36+
GamePassword string `json:"game_password"`
37+
RequireUserVerification bool `json:"require_user_verification"`
38+
MaxUploadInKilobytesPerSecond int `json:"max_upload_in_kilobytes_per_second"`
39+
IgnorePlayerLimitForReturningPlayers bool `json:"ignore_player_limit_for_returning_players"`
40+
AllowCommands string `json:"allow_commands"`
41+
AutosaveInterval int `json:"autosave_interval"`
42+
AutosaveSlots int `json:"autosave_slots"`
43+
AfkAutoKickInterval int `json:"afk_autokick_interval"`
44+
AutoPause bool `json:"auto_pause"`
45+
OnlyAdminsCanPauseThegame bool `json:"only_admins_can_pause_the_game"`
46+
Admins []string `json:"admins"`
47+
}
48+
49+
func createSave(filePath string) (string, error) {
50+
err := os.MkdirAll(filepath.Base(filePath), 0755)
51+
if err != nil {
52+
log.Printf("Error in creating Factorio save: %s", err)
53+
return "", err
54+
}
55+
56+
args := []string{"--create", filePath}
57+
cmdOutput, err := exec.Command(config.FactorioBinary, args...).Output()
58+
if err != nil {
59+
log.Printf("Error in creating Factorio save: %s", err)
60+
return "", err
61+
}
62+
63+
result := string(cmdOutput)
64+
65+
return result, nil
66+
}
67+
68+
func initFactorio() *FactorioServer {
69+
f := FactorioServer{}
70+
71+
// default settings from server-settings.example.json
72+
f.Settings = FactorioServerSettings{
73+
Name: "Factorio",
74+
Description: "Created by Factorio Server Manager",
75+
Tags: []string{},
76+
MaxPlayers: 0,
77+
Visibility: "public",
78+
Username: "",
79+
Password: "",
80+
Token: "",
81+
GamePassword: "",
82+
RequireUserVerification: true,
83+
MaxUploadInKilobytesPerSecond: 0,
84+
IgnorePlayerLimitForReturningPlayers: false,
85+
AllowCommands: "admins-only",
86+
AutosaveInterval: 10,
87+
AutosaveSlots: 5,
88+
AfkAutoKickInterval: 0,
89+
AutoPause: true,
90+
OnlyAdminsCanPauseThegame: true,
91+
Admins: []string{},
92+
}
93+
94+
return &f
95+
}
96+
97+
func (f *FactorioServer) Run() error {
98+
var err error
99+
100+
data, err := json.MarshalIndent(f.Settings, "", " ")
101+
if err != nil {
102+
log.Println("Failed to marshal FactorioServerSettings: ", err)
103+
} else {
104+
ioutil.WriteFile(filepath.Join(config.FactorioDir, "server-settings.json"), data, 0755)
105+
}
106+
107+
args := []string{
108+
"--start-server", filepath.Join(config.FactorioSavesDir, f.Savefile),
109+
"--port", strconv.Itoa(f.Port),
110+
"--server-settings", filepath.Join(config.FactorioDir, "server-settings.json"),
111+
}
112+
113+
log.Println("Starting server with command: ", config.FactorioBinary, args)
114+
115+
f.Cmd = exec.Command(config.FactorioBinary, args...)
116+
117+
f.StdOut, err = f.Cmd.StdoutPipe()
118+
if err != nil {
119+
log.Printf("Error opening stdout pipe: %s", err)
120+
return err
121+
}
122+
123+
f.StdIn, err = f.Cmd.StdinPipe()
124+
if err != nil {
125+
log.Printf("Error opening stdin pipe: %s", err)
126+
return err
127+
}
128+
129+
f.StdErr, err = f.Cmd.StderrPipe()
130+
if err != nil {
131+
log.Printf("Error opening stderr pipe: %s", err)
132+
return err
133+
}
134+
135+
go io.Copy(os.Stdout, f.StdOut)
136+
go io.Copy(os.Stderr, f.StdErr)
137+
138+
err = f.Cmd.Start()
139+
if err != nil {
140+
log.Printf("Error starting server process: %s", err)
141+
return err
142+
}
143+
144+
f.Running = true
145+
146+
err = f.Cmd.Wait()
147+
if err != nil {
148+
log.Printf("Command exited with error: %s", err)
149+
return err
150+
}
151+
152+
return nil
153+
}
154+
155+
func (f *FactorioServer) Stop() error {
156+
// TODO: Find an alternative to os.Kill on Windows. os.Interupt
157+
// is not implemented. Maps will not be saved.
158+
if runtime.GOOS == "windows" {
159+
err := f.Cmd.Process.Signal(os.Kill)
160+
if err != nil {
161+
log.Printf("Error sending SIGKILLL to Factorio process: %s", err)
162+
return err
163+
} else {
164+
f.Running = false
165+
log.Println("Sent SIGKILL to Factorio process. Factorio forced to exit.")
166+
}
167+
} else {
168+
err := f.Cmd.Process.Signal(os.Interrupt)
169+
if err != nil {
170+
log.Printf("Error sending SIGINT to Factorio process: %s", err)
171+
return err
172+
} else {
173+
f.Running = false
174+
log.Printf("Sent SIGINT to Factorio process. Factorio shutting down...")
175+
}
176+
}
177+
178+
return nil
179+
}

src/handlers.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,12 +529,11 @@ func LoadConfig(w http.ResponseWriter, r *http.Request) {
529529
if err := json.NewEncoder(w).Encode(resp); err != nil {
530530
log.Printf("Error tailing logfile", err)
531531
}
532-
return
532+
} else {
533+
resp.Data = configContents
534+
resp.Success = true
533535
}
534536

535-
resp.Data = configContents
536-
resp.Success = true
537-
538537
if err := json.NewEncoder(w).Encode(resp); err != nil {
539538
log.Printf("Error encoding config file JSON reponse: ", err)
540539
}
@@ -931,3 +930,21 @@ func RemoveUser(w http.ResponseWriter, r *http.Request) {
931930
}
932931
}
933932
}
933+
934+
// Return JSON response of config.ini file
935+
func GetServerSettings(w http.ResponseWriter, r *http.Request) {
936+
resp := JSONResponse{
937+
Success: false,
938+
}
939+
940+
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
941+
942+
resp.Data = FactorioServ.Settings
943+
resp.Success = true
944+
945+
if err := json.NewEncoder(w).Encode(resp); err != nil {
946+
log.Printf("Error encoding server settings JSON reponse: ", err)
947+
}
948+
949+
log.Printf("Sent server settings response")
950+
}

src/routes.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,5 +220,10 @@ var apiRoutes = Routes{
220220
"POST",
221221
"/mods/packs/add",
222222
CreateModPackHandler,
223+
}, {
224+
"GetServerSettings",
225+
"GET",
226+
"/settings",
227+
GetServerSettings,
223228
},
224229
}

src/server.go

Lines changed: 0 additions & 133 deletions
This file was deleted.

0 commit comments

Comments
 (0)