From dcf287825ca50d707929d3bc1b4a4d4d98b0917b Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Fri, 12 Sep 2025 19:39:40 +0200 Subject: [PATCH 1/6] removed (max-height: 1050px) check from 2bxform for progress bar since 1080p screens exist --- UIMod/onboard_bundled/twoboxform/twoboxform.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/UIMod/onboard_bundled/twoboxform/twoboxform.css b/UIMod/onboard_bundled/twoboxform/twoboxform.css index 5a5d7795..5d505a44 100644 --- a/UIMod/onboard_bundled/twoboxform/twoboxform.css +++ b/UIMod/onboard_bundled/twoboxform/twoboxform.css @@ -489,11 +489,6 @@ footer { display: none !important; } } -@media (max-height: 1050px) { - .progress-bar { - display: none !important; - } -} .progress-bar { display: flex; From dba1849ed090c4c911ec45fa1b0e9fe29d3b6336 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:39:22 +0200 Subject: [PATCH 2/6] added setdummybuildid command for testing, fixed AppInfoPoller init from loader, added wasRunning check to AutoUpdateCheck --- src/cli/runtimecommands.go | 6 ++++++ src/core/loader/loader.go | 7 +++++++ src/steamcmd/getappinfo.go | 7 +++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/cli/runtimecommands.go b/src/cli/runtimecommands.go index f495a287..9207d780 100644 --- a/src/cli/runtimecommands.go +++ b/src/cli/runtimecommands.go @@ -161,6 +161,7 @@ func init() { RegisterCommand("supportmode", WrapNoReturn(supportMode), "sm") RegisterCommand("supportpackage", WrapNoReturn(supportPackage), "sp") RegisterCommand("getbuildid", WrapNoReturn(getBuildID), "gbid") + RegisterCommand("setdummybuildid", WrapNoReturn(setDummyBuildID), "sdbid") RegisterCommand("printconfig", WrapNoReturn(printConfig), "pc") } @@ -209,6 +210,11 @@ func getBuildID() { logger.Core.Info("Build ID: " + buildID) } +func setDummyBuildID() { + config.SetCurrentBranchBuildID("dummy") + logger.Core.Info("Dummy build ID set") +} + func testLocalization() { currentLanguageSetting := config.GetLanguageSetting() s := localization.GetString("UIText_StartButton") diff --git a/src/core/loader/loader.go b/src/core/loader/loader.go index 78e1a1e6..72830a12 100644 --- a/src/core/loader/loader.go +++ b/src/core/loader/loader.go @@ -13,6 +13,7 @@ import ( "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/detectionmgr" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/setup" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/setup/update" + "github.com/JacksonTheMaster/StationeersServerUI/v5/src/steamcmd" ) // only call this once at startup @@ -23,6 +24,7 @@ func InitBackend(wg *sync.WaitGroup) { ReloadSSCM() ReloadBackupManager() ReloadLocalizer() + ReloadAppInfoPoller() ReloadDiscordBot() InitDetector() } @@ -35,6 +37,7 @@ func ReloadBackend() { ReloadSSCM() ReloadBackupManager() ReloadLocalizer() + ReloadAppInfoPoller() PrintConfigDetails() logger.Core.Info("Backend reload done!") } @@ -87,6 +90,10 @@ func ReloadLocalizer() { localization.ReloadLocalizer() } +func ReloadAppInfoPoller() { + steamcmd.AppInfoPoller() +} + // InitBundler initialized the onboard bundled assets for the web UI func InitVirtFS(v1uiFS embed.FS) { config.SetV1UIFS(v1uiFS) diff --git a/src/steamcmd/getappinfo.go b/src/steamcmd/getappinfo.go index d693693d..c7c7d69b 100644 --- a/src/steamcmd/getappinfo.go +++ b/src/steamcmd/getappinfo.go @@ -109,7 +109,7 @@ func getAppInfo() error { branchesLock.Lock() maps.Copy(branches, newBranches) branchesLock.Unlock() - + wasRunning := false currentBranch := config.GetGameBranch() if buildID, ok := branches[currentBranch]; ok { if config.GetCurrentBranchBuildID() != "" && config.GetCurrentBranchBuildID() != buildID { @@ -133,12 +133,15 @@ func getAppInfo() error { commandmgr.WriteCommand("say Update found, stopping server in 10 seconds...") time.Sleep(10 * time.Second) gamemgr.InternalStopServer() + wasRunning = true } _, err := InstallAndRunSteamCMD() if err != nil { logger.Install.Error("❌ Failed to update gameserver: " + err.Error() + "\n") } - gamemgr.InternalStartServer() + if wasRunning { + gamemgr.InternalStartServer() + } } } config.SetCurrentBranchBuildID(buildID) From 416ff26a3214aaedb89a0adcad9a69ff26b03437 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:39:47 +0200 Subject: [PATCH 3/6] fixed printing wrong branch (ssui branch instead of game branch) in steamcmd command builder --- src/steamcmd/steamcmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/steamcmd/steamcmd.go b/src/steamcmd/steamcmd.go index e6dbb0fc..74c33172 100644 --- a/src/steamcmd/steamcmd.go +++ b/src/steamcmd/steamcmd.go @@ -99,7 +99,7 @@ func runSteamCMD(steamCMDDir string) (int, error) { // buildSteamCMDCommand constructs the SteamCMD command based on the OS. func buildSteamCMDCommand(steamCMDDir, currentDir string) *exec.Cmd { //print the config.GameBranch and config.GameServerAppID - logger.Install.Info("🔍 Game Branch: " + config.GetBranch()) + logger.Install.Info("🔍 Game Branch: " + config.GetGameBranch()) logger.Install.Debug("🔍 Game Server App ID: " + config.GetGameServerAppID()) if runtime.GOOS == "windows" { From 370912a8103a09a54b7909468696b5280b84db89 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Fri, 12 Sep 2025 23:47:33 +0200 Subject: [PATCH 4/6] added a SteamMu "just in case" --- src/steamcmd/getappinfo.go | 4 ++++ src/steamcmd/steamcmd.go | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/steamcmd/getappinfo.go b/src/steamcmd/getappinfo.go index c7c7d69b..e4183692 100644 --- a/src/steamcmd/getappinfo.go +++ b/src/steamcmd/getappinfo.go @@ -64,6 +64,10 @@ func AppInfoPoller() { // getAppInfo fetches the branches and their build IDs for the specified app ID using SteamCMD // and stores them in the package-level branches map. func getAppInfo() error { + steamMu.Lock() + logger.Core.Debug("🔄 Locking SteamMu...") + defer steamMu.Unlock() + defer logger.Core.Debug("🔄 Unlocking SteamMu...") steamcmddir := SteamCMDLinuxDir executable := "steamcmd.sh" appid := config.GetGameServerAppID() diff --git a/src/steamcmd/steamcmd.go b/src/steamcmd/steamcmd.go index 74c33172..39bf0dff 100644 --- a/src/steamcmd/steamcmd.go +++ b/src/steamcmd/steamcmd.go @@ -8,6 +8,7 @@ import ( "path/filepath" "runtime" "strings" + "sync" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/gamemgr" @@ -15,6 +16,8 @@ import ( "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" ) +var steamMu sync.Mutex + // ExtractorFunc is a type that represents a function for extracting archives. // It takes an io.ReaderAt, the size of the content, and the destination directory. type ExtractorFunc func(io.ReaderAt, int64, string) error @@ -54,6 +57,10 @@ func InstallAndRunSteamCMD() (int, error) { // runSteamCMD runs the SteamCMD command to update the game and returns its exit status and any error. func runSteamCMD(steamCMDDir string) (int, error) { + steamMu.Lock() + logger.Core.Debug("🔄 Locking SteamMu...") + defer steamMu.Unlock() + defer logger.Core.Debug("🔄 Unlocking SteamMu...") currentDir, err := os.Getwd() if err != nil { logger.Install.Error("❌ Error getting current working directory: " + err.Error() + "\n") From a7bc1920f264b10da6842c4dd1720acfbe0a758b Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sat, 13 Sep 2025 00:12:30 +0200 Subject: [PATCH 5/6] added Warn logging if ssui tries to use steamcmd concurrently - one function blocks and waits for the other instead --- src/steamcmd/getappinfo.go | 13 ++++++++++--- src/steamcmd/steamcmd.go | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/steamcmd/getappinfo.go b/src/steamcmd/getappinfo.go index e4183692..0d592c7d 100644 --- a/src/steamcmd/getappinfo.go +++ b/src/steamcmd/getappinfo.go @@ -64,10 +64,17 @@ func AppInfoPoller() { // getAppInfo fetches the branches and their build IDs for the specified app ID using SteamCMD // and stores them in the package-level branches map. func getAppInfo() error { - steamMu.Lock() - logger.Core.Debug("🔄 Locking SteamMu...") + if steamMu.TryLock() { + // Successfully acquired the lock; no other func holds it + logger.Core.Debug("🔄 Locking SteamMu for SteamCMD AppInfo...") + } else { + // Another goroutine holds the lock; log and wait. + logger.Core.Warn("🔄 SteamMu is currently locked, waiting for it to be unlocked and then continuing...") + steamMu.Lock() // Block until steamMu becomes available, then snack it and lock it again + logger.Core.Debug("🔄 Locking SteamMu for SteamCMD AppInfo...") + } defer steamMu.Unlock() - defer logger.Core.Debug("🔄 Unlocking SteamMu...") + defer logger.Core.Debug("🔄 Unlocking SteamMu after SteamCMD AppInfo...") steamcmddir := SteamCMDLinuxDir executable := "steamcmd.sh" appid := config.GetGameServerAppID() diff --git a/src/steamcmd/steamcmd.go b/src/steamcmd/steamcmd.go index 39bf0dff..5dd66387 100644 --- a/src/steamcmd/steamcmd.go +++ b/src/steamcmd/steamcmd.go @@ -57,10 +57,17 @@ func InstallAndRunSteamCMD() (int, error) { // runSteamCMD runs the SteamCMD command to update the game and returns its exit status and any error. func runSteamCMD(steamCMDDir string) (int, error) { - steamMu.Lock() - logger.Core.Debug("🔄 Locking SteamMu...") + if steamMu.TryLock() { + // Successfully acquired the lock; no other func holds it + logger.Core.Debug("🔄 Locking SteamMu for SteamCMD execution...") + } else { + // Another goroutine holds the lock; log and wait. + logger.Core.Warn("🔄 SteamMu is currently locked, waiting for it to be unlocked and then continuing...") + steamMu.Lock() // Block until steamMu becomes available, then snack it and lock it again + logger.Core.Debug("🔄 Locking SteamMu for SteamCMD execution..") + } defer steamMu.Unlock() - defer logger.Core.Debug("🔄 Unlocking SteamMu...") + defer logger.Core.Debug("🔄 Unlocking SteamMu after SteamCMD execution...") currentDir, err := os.Getwd() if err != nil { logger.Install.Error("❌ Error getting current working directory: " + err.Error() + "\n") From f36ddbae9cd9c0bb97a8c56a3a988d281d0de93b Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sat, 13 Sep 2025 01:05:29 +0200 Subject: [PATCH 6/6] further imporved steamcmd with isUpdatingMu and checks --- src/steamcmd/steamcmd.go | 11 +++++++++++ src/web/http.go | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/steamcmd/steamcmd.go b/src/steamcmd/steamcmd.go index 5dd66387..292ed1ce 100644 --- a/src/steamcmd/steamcmd.go +++ b/src/steamcmd/steamcmd.go @@ -17,6 +17,7 @@ import ( ) var steamMu sync.Mutex +var isUpdatingMu sync.Mutex // ExtractorFunc is a type that represents a function for extracting archives. // It takes an io.ReaderAt, the size of the content, and the destination directory. @@ -33,6 +34,16 @@ const ( // InstallAndRunSteamCMD installs and runs SteamCMD based on the platform (Windows/Linux). // It returns the exit status of the SteamCMD execution and any error encountered. func InstallAndRunSteamCMD() (int, error) { + if isUpdatingMu.TryLock() { + // Successfully acquired the lock; we are not updating currently + logger.Core.Debug("🔄 Locking isUpdatingMu for SteamCMD Update run...") + } else { + // already updating, return + logger.Core.Warn("🔄 isUpdatingMu is currently locked, cannot update server using SteamCMD right now...") + return -1, fmt.Errorf("already updating") + } + defer isUpdatingMu.Unlock() + defer logger.Core.Debug("🔄 Unlocking isUpdatingMu after SteamCMD Update run...") if gamemgr.InternalIsServerRunning() { logger.Core.Warn("Server is running, stopping server first...") diff --git a/src/web/http.go b/src/web/http.go index 5f99f9fe..fd010f65 100644 --- a/src/web/http.go +++ b/src/web/http.go @@ -7,7 +7,6 @@ import ( "net/http" "os" "strings" - "time" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/localization" @@ -118,12 +117,9 @@ func HandleIsSSCMEnabled(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -var lastSteamCMDExecution time.Time // last time SteamCMD was executed via API. - // run SteamCMD from API, but only allow once every 5 minutes to "kinda" prevent concurrent executions although that woluldnt hurn. // If the user has a 5mbit connection, I cannot help them anyways. func HandleRunSteamCMD(w http.ResponseWriter, r *http.Request) { - const rateLimitDuration = 30 * time.Second // Only allow GET requests if r.Method != http.MethodGet { @@ -131,17 +127,10 @@ func HandleRunSteamCMD(w http.ResponseWriter, r *http.Request) { return } - // Check rate limit - if time.Since(lastSteamCMDExecution) < rateLimitDuration { - json.NewEncoder(w).Encode(map[string]string{"statuscode": "200", "status": "Rejected", "message": "Slow down, you just called SteamCMD.", "advanced": "Use SSUICLI or restart SSUI to run SteamCMD repeatedly without limit."}) - return - } - logger.Core.Info("Running SteamCMD") _, err := steamcmd.InstallAndRunSteamCMD() // Update last execution time - lastSteamCMDExecution = time.Now() // Success: return 202 Accepted and JSON w.WriteHeader(http.StatusOK)