Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions UIMod/onboard_bundled/twoboxform/twoboxform.css
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,6 @@ footer {
display: none !important;
}
}
@media (max-height: 1050px) {
.progress-bar {
display: none !important;
}
}

.progress-bar {
display: flex;
Expand Down
6 changes: 6 additions & 0 deletions src/cli/runtimecommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

Expand Down Expand Up @@ -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")
Expand Down
7 changes: 7 additions & 0 deletions src/core/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -23,6 +24,7 @@ func InitBackend(wg *sync.WaitGroup) {
ReloadSSCM()
ReloadBackupManager()
ReloadLocalizer()
ReloadAppInfoPoller()
ReloadDiscordBot()
InitDetector()
}
Expand All @@ -35,6 +37,7 @@ func ReloadBackend() {
ReloadSSCM()
ReloadBackupManager()
ReloadLocalizer()
ReloadAppInfoPoller()
PrintConfigDetails()
logger.Core.Info("Backend reload done!")
}
Expand Down Expand Up @@ -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)
Expand Down
18 changes: 16 additions & 2 deletions src/steamcmd/getappinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +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 {
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 after SteamCMD AppInfo...")
steamcmddir := SteamCMDLinuxDir
executable := "steamcmd.sh"
appid := config.GetGameServerAppID()
Expand Down Expand Up @@ -109,7 +120,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 {
Expand All @@ -133,12 +144,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)
Expand Down
27 changes: 26 additions & 1 deletion src/steamcmd/steamcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import (
"path/filepath"
"runtime"
"strings"
"sync"

"github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger"
"github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/gamemgr"

"github.com/JacksonTheMaster/StationeersServerUI/v5/src/config"
)

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.
type ExtractorFunc func(io.ReaderAt, int64, string) error
Expand All @@ -30,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...")
Expand All @@ -54,6 +68,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) {
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 after SteamCMD execution...")
currentDir, err := os.Getwd()
if err != nil {
logger.Install.Error("❌ Error getting current working directory: " + err.Error() + "\n")
Expand Down Expand Up @@ -99,7 +124,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" {
Expand Down
11 changes: 0 additions & 11 deletions src/web/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"net/http"
"os"
"strings"
"time"

"github.com/JacksonTheMaster/StationeersServerUI/v5/src/config"
"github.com/JacksonTheMaster/StationeersServerUI/v5/src/localization"
Expand Down Expand Up @@ -118,30 +117,20 @@ 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 {
http.Error(w, "Only GET requests are allowed", http.StatusMethodNotAllowed)
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)
Expand Down
Loading