diff --git a/.gitignore b/.gitignore
index ecfce688..ca2aa0b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,4 @@ frontend/node_modules
frontend/dist
frontend/build
UIMod/onboard_bundled/v2
+UIMod/logs/*
\ No newline at end of file
diff --git a/UIMod/onboard_bundled/localization/en-US.json b/UIMod/onboard_bundled/localization/en-US.json
index bda9e741..9426d739 100644
--- a/UIMod/onboard_bundled/localization/en-US.json
+++ b/UIMod/onboard_bundled/localization/en-US.json
@@ -60,7 +60,7 @@
"UIText_UPNPEnabled": "UPNP Enabled",
"UIText_UPNPEnabledInfo": "Enable automatic UPNP port forwarding",
"UIText_LocalIpAddress": "Local IP Address",
- "UIText_LocalIpAddressInfo": "IP address to bind to",
+ "UIText_LocalIpAddressInfo": "IP address to bind to. Recommended to leave at 0.0.0.0 unless you really know what you're doing.",
"UIText_StartLocalHost": "Start Local Host",
"UIText_StartLocalHostInfo": "Keep this true. This is required for the server to work.",
"UIText_ServerVisible": "Server Visible",
@@ -84,7 +84,12 @@
"UIText_AllowAutoGameServerUpdates": "Enable Auto Game Server Updates",
"UIText_AllowAutoGameServerUpdatesInfo": "Allow the gameserver to automatically query for and update to the latest version. Attention: Restarts the server when a new version was found and installed. Will send multiple warning messages to the sever with SAY commands 60-10 seconds before the restart.",
"UIText_AutoStartServerOnStartup": "Auto Start Server on Startup",
- "UIText_AutoStartServerOnStartupInfo": "Automatically start the gameserver when the SSUI is started. Defaults to false."
+ "UIText_AutoStartServerOnStartupInfo": "Automatically start the gameserver when the SSUI is started. Defaults to false.",
+ "UIText_CreateSSUILogFile": "Create SSUI Log Files",
+ "UIText_CreateSSUILogFileInfo": "Create log files for the SSUI log in UIMod/logs. Defaults to false.",
+ "UIText_CreateGameServerLogFile": "Create Game Server Log File",
+ "UIText_CreateGameServerLogFileInfo": "Create a unique log file per server start for the gameserver in UIMod/logs. Defaults to false."
+
},
"terrain": {
"UIText_TerrainSettingsHeader": "Optional world generation settings",
diff --git a/UIMod/onboard_bundled/ui/config.html b/UIMod/onboard_bundled/ui/config.html
index b080d61c..b6cd90cc 100644
--- a/UIMod/onboard_bundled/ui/config.html
+++ b/UIMod/onboard_bundled/ui/config.html
@@ -256,6 +256,24 @@
{{.UIText_AdvancedConfiguration}}
{{.UIText_AllowAutoGameServerUpdatesInfo}}
+
+
+
+
diff --git a/src/config/config.go b/src/config/config.go
index b4d1d1a9..c7ffdb01 100644
--- a/src/config/config.go
+++ b/src/config/config.go
@@ -51,11 +51,12 @@ type JsonConfig struct {
StartLocation string `json:"StartLocation"`
// Logging and debug settings
- Debug *bool `json:"Debug"`
- CreateSSUILogFile *bool `json:"CreateSSUILogFile"`
- LogLevel int `json:"LogLevel"`
- SubsystemFilters []string `json:"subsystemFilters"`
- AdvertiserOverride string `json:"AdvertiserOverride"`
+ Debug *bool `json:"Debug"`
+ CreateSSUILogFile *bool `json:"CreateSSUILogFile"`
+ CreateGameServerLogFile *bool `json:"CreateGameServerLogFile"`
+ LogLevel int `json:"LogLevel"`
+ SubsystemFilters []string `json:"subsystemFilters"`
+ AdvertiserOverride string `json:"AdvertiserOverride"`
// Authentication Settings
Users map[string]string `json:"users"` // Map of username to hashed password
@@ -230,6 +231,10 @@ func applyConfig(cfg *JsonConfig) {
CreateSSUILogFile = createSSUILogFileVal
cfg.CreateSSUILogFile = &createSSUILogFileVal
+ createGameServerLogFileVal := getBool(cfg.CreateGameServerLogFile, "CREATE_GAMESERVER_LOGFILE", false)
+ CreateGameServerLogFile = createGameServerLogFileVal
+ cfg.CreateGameServerLogFile = &createGameServerLogFileVal
+
LogLevel = getInt(cfg.LogLevel, "LOG_LEVEL", 20)
isUpdateEnabledVal := getBool(cfg.IsUpdateEnabled, "IS_UPDATE_ENABLED", true)
@@ -369,6 +374,7 @@ func safeSaveConfig() error {
AuthTokenLifetime: AuthTokenLifetime,
Debug: &IsDebugMode,
CreateSSUILogFile: &CreateSSUILogFile,
+ CreateGameServerLogFile: &CreateGameServerLogFile,
LogLevel: LogLevel,
LogClutterToConsole: &LogClutterToConsole,
SubsystemFilters: SubsystemFilters,
diff --git a/src/config/getters.go b/src/config/getters.go
index a71d7ab0..cd637768 100644
--- a/src/config/getters.go
+++ b/src/config/getters.go
@@ -297,6 +297,12 @@ func GetCreateSSUILogFile() bool {
return CreateSSUILogFile
}
+func GetCreateGameServerLogFile() bool {
+ ConfigMu.RLock()
+ defer ConfigMu.RUnlock()
+ return CreateGameServerLogFile
+}
+
func GetLogLevel() int {
ConfigMu.RLock()
defer ConfigMu.RUnlock()
diff --git a/src/config/vars.go b/src/config/vars.go
index f1e6e192..3aafbbff 100644
--- a/src/config/vars.go
+++ b/src/config/vars.go
@@ -47,6 +47,7 @@ var (
var (
IsDebugMode bool //only used for pprof server, keep it like this and check the log level instead. Debug = 10
CreateSSUILogFile bool
+ CreateGameServerLogFile bool
LogLevel int
IsFirstTimeSetup bool
SSEMessageBufferSize = 2000
diff --git a/src/managers/gamemgr/serverlog.go b/src/managers/gamemgr/serverlog.go
index fc950cff..31d7f694 100644
--- a/src/managers/gamemgr/serverlog.go
+++ b/src/managers/gamemgr/serverlog.go
@@ -6,14 +6,20 @@ import (
"io"
"os"
"os/exec"
+ "path"
"runtime"
"strconv"
"time"
+ "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config"
"github.com/JacksonTheMaster/StationeersServerUI/v5/src/core/ssestream"
"github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger"
+ "github.com/google/uuid"
)
+const defaultLogFolderMode = 0755
+const defaultLogFileMode = 0644
+
// readPipe for Windows
func readPipe(pipe io.ReadCloser) {
scanner := bufio.NewScanner(pipe)
@@ -21,6 +27,7 @@ func readPipe(pipe io.ReadCloser) {
for scanner.Scan() {
output := scanner.Text()
ssestream.BroadcastConsoleOutput(output)
+ logToFile(output)
}
if err := scanner.Err(); err != nil {
logger.Core.Debug("Pipe error: " + err.Error())
@@ -91,6 +98,7 @@ func tailLogFile(logFilePath string) {
for scanner.Scan() {
output := scanner.Text()
ssestream.BroadcastConsoleOutput(output)
+ logToFile(output)
}
if err := scanner.Err(); err != nil {
@@ -106,3 +114,43 @@ func tailLogFile(logFilePath string) {
logger.Core.Debug("Received logDone signal, stopping tail -F")
}
+
+func logToFile(message string) {
+ if config.GetCreateGameServerLogFile() {
+ logFileFolder := config.GetLogFolder()
+ // Check if the log folder exists, if not create it
+ _, err := os.Stat(logFileFolder)
+ if os.IsNotExist(err) {
+ err := os.Mkdir(logFileFolder, defaultLogFolderMode)
+ if err != nil {
+ logger.Core.Error("Error creating log folder: " + err.Error())
+ return
+ }
+ } else if err != nil {
+ logger.Core.Error("Error checking log folder: " + err.Error())
+ return
+ }
+
+ if GameServerUUID != uuid.Nil {
+ logFileName := fmt.Sprintf("serverlog_%s_%s.log", time.Now().Format("200601021504"), GameServerUUID.String())
+ logFilePath := path.Join(logFileFolder, logFileName)
+
+ // append the log file to the log folder
+ file, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, defaultLogFileMode)
+ if err != nil {
+ logger.Core.Error("Error opening log file: " + err.Error())
+ return
+ }
+ defer file.Close()
+
+ _, err = file.WriteString(message + "\n")
+ if err != nil {
+ logger.Core.Error("Error writing to log file: " + err.Error())
+ return
+ }
+ } else {
+ logger.Core.Error("Game Server UUID not set, cannot log to file")
+ return
+ }
+ }
+}
diff --git a/src/web/configpage.go b/src/web/configpage.go
index a7e77269..a03598fb 100644
--- a/src/web/configpage.go
+++ b/src/web/configpage.go
@@ -105,6 +105,22 @@ func ServeConfigPage(w http.ResponseWriter, r *http.Request) {
autoGameServerUpdatesFalseSelected = "selected"
}
+ createSSUILogFileTrueSelected := ""
+ createSSUILogFileFalseSelected := ""
+ if config.GetCreateSSUILogFile() {
+ createSSUILogFileTrueSelected = "selected"
+ } else {
+ createSSUILogFileFalseSelected = "selected"
+ }
+
+ createGameServerLogFileTrueSelected := ""
+ createGameServerLogFileFalseSelected := ""
+ if config.GetCreateGameServerLogFile() {
+ createGameServerLogFileTrueSelected = "selected"
+ } else {
+ createGameServerLogFileFalseSelected = "selected"
+ }
+
data := ConfigTemplateData{
// Config values
DiscordToken: config.GetDiscordToken(),
@@ -163,6 +179,12 @@ func ServeConfigPage(w http.ResponseWriter, r *http.Request) {
AllowAutoGameServerUpdates: fmt.Sprintf("%v", config.GetAllowAutoGameServerUpdates()),
AllowAutoGameServerUpdatesTrueSelected: autoGameServerUpdatesTrueSelected,
AllowAutoGameServerUpdatesFalseSelected: autoGameServerUpdatesFalseSelected,
+ CreateSSUILogFile: fmt.Sprintf("%v", config.GetCreateSSUILogFile()),
+ CreateSSUILogFileTrueSelected: createSSUILogFileTrueSelected,
+ CreateSSUILogFileFalseSelected: createSSUILogFileFalseSelected,
+ CreateGameServerLogFile: fmt.Sprintf("%v", config.GetCreateGameServerLogFile()),
+ CreateGameServerLogFileTrueSelected: createGameServerLogFileTrueSelected,
+ CreateGameServerLogFileFalseSelected: createGameServerLogFileFalseSelected,
// Localized UI text
UIText_ServerConfig: localization.GetString("UIText_ServerConfig"),
@@ -235,6 +257,10 @@ func ServeConfigPage(w http.ResponseWriter, r *http.Request) {
UIText_AutoStartServerOnStartupInfo: localization.GetString("UIText_AutoStartServerOnStartupInfo"),
UIText_AllowAutoGameServerUpdates: localization.GetString("UIText_AllowAutoGameServerUpdates"),
UIText_AllowAutoGameServerUpdatesInfo: localization.GetString("UIText_AllowAutoGameServerUpdatesInfo"),
+ UIText_CreateSSUILogFile: localization.GetString("UIText_CreateSSUILogFile"),
+ UIText_CreateSSUILogFileInfo: localization.GetString("UIText_CreateSSUILogFileInfo"),
+ UIText_CreateGameServerLogFile: localization.GetString("UIText_CreateGameServerLogFile"),
+ UIText_CreateGameServerLogFileInfo: localization.GetString("UIText_CreateGameServerLogFileInfo"),
UIText_DiscordIntegrationTitle: localization.GetString("UIText_DiscordIntegrationTitle"),
UIText_DiscordBotToken: localization.GetString("UIText_DiscordBotToken"),
diff --git a/src/web/templatevars.go b/src/web/templatevars.go
index 8c0cc2ab..ad5d5a87 100644
--- a/src/web/templatevars.go
+++ b/src/web/templatevars.go
@@ -80,6 +80,12 @@ type ConfigTemplateData struct {
AllowAutoGameServerUpdates string
AllowAutoGameServerUpdatesTrueSelected string
AllowAutoGameServerUpdatesFalseSelected string
+ CreateSSUILogFile string
+ CreateSSUILogFileTrueSelected string
+ CreateSSUILogFileFalseSelected string
+ CreateGameServerLogFile string
+ CreateGameServerLogFileTrueSelected string
+ CreateGameServerLogFileFalseSelected string
UIText_ServerConfig string
UIText_DiscordIntegration string
@@ -153,6 +159,10 @@ type ConfigTemplateData struct {
UIText_AutoStartServerOnStartupInfo string
UIText_AllowAutoGameServerUpdates string
UIText_AllowAutoGameServerUpdatesInfo string
+ UIText_CreateSSUILogFile string
+ UIText_CreateSSUILogFileInfo string
+ UIText_CreateGameServerLogFile string
+ UIText_CreateGameServerLogFileInfo string
UIText_DiscordIntegrationTitle string
UIText_DiscordBotToken string