mirror of
https://github.com/OpenFactorioServerManager/factorio-server-manager.git
synced 2025-02-09 13:47:17 +02:00
This commit is contained in:
parent
4dc8cf40ef
commit
20d5466780
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@ -13,86 +14,71 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FactorioServer struct {
|
type FactorioServer struct {
|
||||||
Cmd *exec.Cmd
|
Cmd *exec.Cmd `json:"-"`
|
||||||
Savefile string
|
Savefile string `json:"-"`
|
||||||
Latency int `json:"latency"`
|
Latency int `json:"latency"`
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
Running bool `json:"running"`
|
Running bool `json:"running"`
|
||||||
StdOut io.ReadCloser
|
StdOut io.ReadCloser `json:"-"`
|
||||||
StdErr io.ReadCloser
|
StdErr io.ReadCloser `json:"-"`
|
||||||
StdIn io.WriteCloser
|
StdIn io.WriteCloser `json:"-"`
|
||||||
Settings FactorioServerSettings
|
Settings map[string]interface{} `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FactorioServerSettings struct {
|
func initFactorio() (f *FactorioServer, err error) {
|
||||||
Name string `json:"name"`
|
f = new(FactorioServer)
|
||||||
Description string `json:"description"`
|
f.Settings = make(map[string]interface{})
|
||||||
Tags []string `json:"tags"`
|
|
||||||
MaxPlayers int `json:"max_players"`
|
|
||||||
Visibility string `json:"visibility"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Token string `json:"token"`
|
|
||||||
GamePassword string `json:"game_password"`
|
|
||||||
RequireUserVerification bool `json:"require_user_verification"`
|
|
||||||
MaxUploadInKilobytesPerSecond int `json:"max_upload_in_kilobytes_per_second"`
|
|
||||||
IgnorePlayerLimitForReturningPlayers bool `json:"ignore_player_limit_for_returning_players"`
|
|
||||||
AllowCommands string `json:"allow_commands"`
|
|
||||||
AutosaveInterval int `json:"autosave_interval"`
|
|
||||||
AutosaveSlots int `json:"autosave_slots"`
|
|
||||||
AfkAutoKickInterval int `json:"afk_autokick_interval"`
|
|
||||||
AutoPause bool `json:"auto_pause"`
|
|
||||||
OnlyAdminsCanPauseThegame bool `json:"only_admins_can_pause_the_game"`
|
|
||||||
Admins []string `json:"admins"`
|
|
||||||
AutosaveOnlyOnServer bool `json:"autosave_only_on_server"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func initFactorio() *FactorioServer {
|
if err = os.MkdirAll(config.FactorioConfigDir, 0755); err != nil {
|
||||||
f := FactorioServer{}
|
return nil, fmt.Errorf("failed to create config directory: %v", err)
|
||||||
settingsFile := filepath.Join(config.FactorioConfigDir, config.SettingsFile)
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(settingsFile); err == nil {
|
settingsPath := filepath.Join(config.FactorioConfigDir, config.SettingsFile)
|
||||||
// server-settings.json file exists
|
var settings *os.File
|
||||||
settings, err := os.Open(settingsFile)
|
|
||||||
|
if _, err := os.Stat(settingsPath); os.IsNotExist(err) {
|
||||||
|
// copy example settings to supplied settings file, if not exists
|
||||||
|
log.Printf("Server settings at %s not found, copying example server settings.\n", settingsPath)
|
||||||
|
|
||||||
|
examplePath := filepath.Join(config.FactorioDir, "data", "server-settings.example.json")
|
||||||
|
|
||||||
|
example, err := os.Open(examplePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error in reading %s: %s", settingsFile, err)
|
return nil, fmt.Errorf("failed to open example server settings: %v", err)
|
||||||
|
}
|
||||||
|
defer example.Close()
|
||||||
|
|
||||||
|
settings, err = os.Create(settingsPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create server settings file: %v", err)
|
||||||
}
|
}
|
||||||
defer settings.Close()
|
defer settings.Close()
|
||||||
|
|
||||||
settingsParser := json.NewDecoder(settings)
|
_, err = io.Copy(settings, example)
|
||||||
if err = settingsParser.Decode(&f.Settings); err != nil {
|
if err != nil {
|
||||||
log.Printf("Error in reading %s: %s", settingsFile, err)
|
return nil, fmt.Errorf("failed to copy example server settings: %v", err)
|
||||||
}
|
}
|
||||||
log.Printf("Loaded Factorio settings from %s, settings: %+v", settingsFile, &f.Settings)
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// default settings from server-settings.example.json
|
// otherwise, open file normally
|
||||||
f.Settings = FactorioServerSettings{
|
settings, err = os.Open(settingsPath)
|
||||||
Name: "Factorio",
|
if err != nil {
|
||||||
Description: "Created by Factorio Server Manager",
|
return nil, fmt.Errorf("failed to open server settings file: %v", err)
|
||||||
Tags: []string{},
|
|
||||||
MaxPlayers: 0,
|
|
||||||
Visibility: "public",
|
|
||||||
Username: "",
|
|
||||||
Password: "",
|
|
||||||
Token: "",
|
|
||||||
GamePassword: "",
|
|
||||||
RequireUserVerification: true,
|
|
||||||
MaxUploadInKilobytesPerSecond: 0,
|
|
||||||
IgnorePlayerLimitForReturningPlayers: false,
|
|
||||||
AllowCommands: "admins-only",
|
|
||||||
AutosaveInterval: 10,
|
|
||||||
AutosaveSlots: 5,
|
|
||||||
AfkAutoKickInterval: 0,
|
|
||||||
AutosaveOnlyOnServer: true,
|
|
||||||
AutoPause: true,
|
|
||||||
OnlyAdminsCanPauseThegame: true,
|
|
||||||
Admins: []string{},
|
|
||||||
}
|
}
|
||||||
log.Printf("Loaded Default Factorio settings settings: %+v", &f.Settings)
|
defer settings.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &f
|
// before reading reset offset
|
||||||
|
if _, err = settings.Seek(0, 0); err != nil {
|
||||||
|
return nil, fmt.Errorf("error while seeking in settings file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = json.NewDecoder(settings).Decode(&f.Settings); err != nil {
|
||||||
|
return nil, fmt.Errorf("error reading %s: %v", settingsPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Loaded Factorio settings from %s\n", settingsPath)
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FactorioServer) Run() error {
|
func (f *FactorioServer) Run() error {
|
||||||
|
@ -993,7 +993,10 @@ func UpdateServerSettings(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Printf("Failed to marshal server settings: %s", err)
|
log.Printf("Failed to marshal server settings: %s", err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
ioutil.WriteFile(filepath.Join(config.FactorioDir, "server-settings.json"), settings, 0644)
|
if err = ioutil.WriteFile(filepath.Join(config.FactorioConfigDir, config.SettingsFile), settings, 0644); err != nil {
|
||||||
|
log.Printf("Failed to save server settings: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
log.Printf("Saved Factorio server settings in server-settings.json")
|
log.Printf("Saved Factorio server settings in server-settings.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
src/main.go
14
src/main.go
@ -86,8 +86,14 @@ func parseFlags() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Parse configuration flags
|
||||||
parseFlags()
|
parseFlags()
|
||||||
|
// Load server config from file
|
||||||
loadServerConfig(config.ConfFile)
|
loadServerConfig(config.ConfFile)
|
||||||
|
// Create mod pack dir if missing
|
||||||
|
createModPackDir()
|
||||||
|
|
||||||
// Set logging output to file
|
// Set logging output to file
|
||||||
logPath := filepath.Join(config.FactorioDir, config.LogFile)
|
logPath := filepath.Join(config.FactorioDir, config.LogFile)
|
||||||
@ -99,15 +105,19 @@ func main() {
|
|||||||
log.SetOutput(logFile)
|
log.SetOutput(logFile)
|
||||||
|
|
||||||
// Initialize Factorio Server struct
|
// Initialize Factorio Server struct
|
||||||
FactorioServ = initFactorio()
|
FactorioServ, err = initFactorio()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error occurred during FactorioServer initializaion: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize authentication system
|
// Initialize authentication system
|
||||||
Auth = initAuth()
|
Auth = initAuth()
|
||||||
Auth.CreateAuth(config.DatabaseFile, config.CookieEncryptionKey)
|
Auth.CreateAuth(config.DatabaseFile, config.CookieEncryptionKey)
|
||||||
Auth.CreateOrUpdateUser(config.Username, config.Password, "admin", "")
|
Auth.CreateOrUpdateUser(config.Username, config.Password, "admin", "")
|
||||||
|
|
||||||
|
// Initialize HTTP router
|
||||||
router := NewRouter()
|
router := NewRouter()
|
||||||
createModPackDir()
|
|
||||||
|
|
||||||
fmt.Printf("Starting server on: %s:%s", config.ServerIP, config.ServerPort)
|
fmt.Printf("Starting server on: %s:%s", config.ServerIP, config.ServerPort)
|
||||||
log.Fatal(http.ListenAndServe(config.ServerIP+":"+config.ServerPort, router))
|
log.Fatal(http.ListenAndServe(config.ServerIP+":"+config.ServerPort, router))
|
||||||
|
@ -77,6 +77,17 @@ class ConfigContent extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
formTypeField(key, setting) {
|
formTypeField(key, setting) {
|
||||||
|
if (key.startsWith("_comment_")) {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
key={key}
|
||||||
|
ref={key}
|
||||||
|
id={key}
|
||||||
|
defaultValue={setting}
|
||||||
|
type="hidden"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
if (typeof setting === "number") {
|
if (typeof setting === "number") {
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
@ -163,13 +174,17 @@ class ConfigContent extends React.Component {
|
|||||||
<div className="table-responsive">
|
<div className="table-responsive">
|
||||||
<form ref="settingsForm" className="form-horizontal" onSubmit={this.updateServerSettings}>
|
<form ref="settingsForm" className="form-horizontal" onSubmit={this.updateServerSettings}>
|
||||||
{Object.keys(this.state.serverSettings).map(function(key) {
|
{Object.keys(this.state.serverSettings).map(function(key) {
|
||||||
|
if (key.startsWith("_comment_"))
|
||||||
|
return(<div>{this.formTypeField(key, setting)}</div>);
|
||||||
var setting = this.state.serverSettings[key]
|
var setting = this.state.serverSettings[key]
|
||||||
var setting_key = key.replace(/_/g, " ")
|
var setting_key = key.replace(/_/g, " ")
|
||||||
|
var comment = this.state.serverSettings["_comment_" + key]
|
||||||
return(
|
return(
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label for={key} className="control-label col-md-3">{setting_key}</label>
|
<label for={key} className="control-label col-md-3">{setting_key}</label>
|
||||||
<div className="col-md-6">
|
<div className="col-md-6">
|
||||||
{this.formTypeField(key, setting)}
|
{this.formTypeField(key, setting)}
|
||||||
|
<p className="help-block">{comment}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user