From a64507ee15132320bfc34f0125de2730c407d92d Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sat, 20 Dec 2025 22:57:29 +0100 Subject: [PATCH 01/34] bump version to 5.9.2 --- src/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/config.go b/src/config/config.go index 57d23568..f0e4be51 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -11,7 +11,7 @@ import ( var ( // All configuration variables can be found in vars.go - Version = "5.9.1" + Version = "5.9.2" Branch = "release" ) From 114b81e4340b86d7847915c9e7f3c62664fdc16e Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sat, 20 Dec 2025 22:57:43 +0100 Subject: [PATCH 02/34] Update localization messages for Local IP Address guidance in de-DE, en-US, and sv-SE files --- UIMod/onboard_bundled/localization/de-DE.json | 2 +- UIMod/onboard_bundled/localization/en-US.json | 2 +- UIMod/onboard_bundled/localization/sv-SE.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/UIMod/onboard_bundled/localization/de-DE.json b/UIMod/onboard_bundled/localization/de-DE.json index 3cd789de..6c8d5d66 100644 --- a/UIMod/onboard_bundled/localization/de-DE.json +++ b/UIMod/onboard_bundled/localization/de-DE.json @@ -219,7 +219,7 @@ "UIText_UPnPEnabled_SkipButton": "Überspringen", "UIText_LocalIPAddress_Title": "Stationeers Server UI", "UIText_LocalIPAddress_HeaderTitle": "Netzwerk (4/4)", - "UIText_LocalIPAddress_StepMessage": "Lokale IP-Adresse des Servers im Format 0.0.0.0 eingeben (keine CIDR Notation)", + "UIText_LocalIPAddress_StepMessage": "Gib die IP-Adresse ein, auf der der Server auf eine Verbindung hören soll - In den meisten fällen kann man den Wert auf 0.0.0.0 belassen", "UIText_LocalIPAddress_PrimaryPlaceholder": "0.0.0.0", "UIText_LocalIPAddress_PrimaryLabel": "Lokale IP-Adresse", "UIText_LocalIPAddress_SubmitButton": "Speichern & Weiter", diff --git a/UIMod/onboard_bundled/localization/en-US.json b/UIMod/onboard_bundled/localization/en-US.json index adbbd138..af044ca5 100644 --- a/UIMod/onboard_bundled/localization/en-US.json +++ b/UIMod/onboard_bundled/localization/en-US.json @@ -226,7 +226,7 @@ "UIText_UPnPEnabled_SkipButton": "Skip", "UIText_LocalIPAddress_Title": "Stationeers Server UI", "UIText_LocalIPAddress_HeaderTitle": "Network (4/4)", - "UIText_LocalIPAddress_StepMessage": "Enter server's local IP address in format 0.0.0.0 (no CIDR notation)", + "UIText_LocalIPAddress_StepMessage": "Enter the IP address to bind to. Recommended to leave at 0.0.0.0 unless you really know what you're doing.", "UIText_LocalIPAddress_PrimaryPlaceholder": "0.0.0.0", "UIText_LocalIPAddress_PrimaryLabel": "Local IP Address", "UIText_LocalIPAddress_SubmitButton": "Save & Continue", diff --git a/UIMod/onboard_bundled/localization/sv-SE.json b/UIMod/onboard_bundled/localization/sv-SE.json index c54d5890..334f4c0c 100644 --- a/UIMod/onboard_bundled/localization/sv-SE.json +++ b/UIMod/onboard_bundled/localization/sv-SE.json @@ -217,7 +217,7 @@ "UIText_UPnPEnabled_SkipButton": "Hoppa över", "UIText_LocalIPAddress_Title": "Stationeers Server UI", "UIText_LocalIPAddress_HeaderTitle": "Nätverk (4/4)", - "UIText_LocalIPAddress_StepMessage": "Ange serverns lokala IP-adress i formatet 0.0.0.0 (ingen CIDR-notation)", + "UIText_LocalIPAddress_StepMessage": "Ange den IP-adress som servern ska lyssna på - I de flesta fall kan du lämna värdet på 0.0.0.0.", "UIText_LocalIPAddress_PrimaryPlaceholder": "0.0.0.0", "UIText_LocalIPAddress_PrimaryLabel": "Lokal IP-adress", "UIText_LocalIPAddress_SubmitButton": "Spara & fortsätt", From e526f7c09d03cdf22a2f2cb7d5e1dd4034b9aa8c Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sat, 20 Dec 2025 23:10:15 +0100 Subject: [PATCH 03/34] Added missing localization on setup finalize button, fixed setup info text showing on login state of 2bxform. Fixes #121 "Missing localization in setup track" --- UIMod/onboard_bundled/localization/de-DE.json | 3 ++- UIMod/onboard_bundled/localization/en-US.json | 3 ++- UIMod/onboard_bundled/localization/sv-SE.json | 3 ++- UIMod/onboard_bundled/twoboxform/twoboxform.html | 5 +++-- src/web/TwoBoxForm.go | 12 +++++++----- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/UIMod/onboard_bundled/localization/de-DE.json b/UIMod/onboard_bundled/localization/de-DE.json index 6c8d5d66..02110e42 100644 --- a/UIMod/onboard_bundled/localization/de-DE.json +++ b/UIMod/onboard_bundled/localization/de-DE.json @@ -265,7 +265,8 @@ "UIText_WorldID_SecondaryLabel": "Wähle aus dem Dropdown-Menü unten aus", "UIText_WorldID_SecondaryPlaceholder": "Wähle eine Karte aus", "UIText_WorldID_SubmitButton": "Speichern & Weiter", - "UIText_WorldID_SkipButton": "Überspringen" + "UIText_WorldID_SkipButton": "Überspringen", + "UIText_FinalizeSubmitButtonText": "Setup abschließen" } }, "BackendText": { diff --git a/UIMod/onboard_bundled/localization/en-US.json b/UIMod/onboard_bundled/localization/en-US.json index af044ca5..225368ae 100644 --- a/UIMod/onboard_bundled/localization/en-US.json +++ b/UIMod/onboard_bundled/localization/en-US.json @@ -257,7 +257,8 @@ "UIText_ChangeUser_PrimaryLabel": "Username to Add/Update", "UIText_ChangeUser_SecondaryLabel": "New Password", "UIText_ChangeUser_SecondaryPlaceholder": "Password", - "UIText_ChangeUser_SubmitButton": "Add/Update User" + "UIText_ChangeUser_SubmitButton": "Add/Update User", + "UIText_FinalizeSubmitButtonText": "Finalize Setup" } }, "BackendText": { diff --git a/UIMod/onboard_bundled/localization/sv-SE.json b/UIMod/onboard_bundled/localization/sv-SE.json index 334f4c0c..4e4a847f 100644 --- a/UIMod/onboard_bundled/localization/sv-SE.json +++ b/UIMod/onboard_bundled/localization/sv-SE.json @@ -263,7 +263,8 @@ "UIText_WorldID_SecondaryLabel": "Välj från rullgardinsmenyn nedan", "UIText_WorldID_SecondaryPlaceholder": "Välj en karta", "UIText_WorldID_SubmitButton": "Spara & fortsätt", - "UIText_WorldID_SkipButton": "Hoppa över" + "UIText_WorldID_SkipButton": "Hoppa över", + "UIText_FinalizeSubmitButtonText": "Slutför konfiguration" } }, "BackendText": { diff --git a/UIMod/onboard_bundled/twoboxform/twoboxform.html b/UIMod/onboard_bundled/twoboxform/twoboxform.html index 984c9c0f..54d2fde9 100644 --- a/UIMod/onboard_bundled/twoboxform/twoboxform.html +++ b/UIMod/onboard_bundled/twoboxform/twoboxform.html @@ -47,9 +47,8 @@

{{.HeaderTitle}}

-

Your server is ready to be launched!

- +
{{end}} @@ -119,8 +118,10 @@

{{.HeaderTitle}}

+ {{if eq .Path "/setup"}}

{{.FooterTextInfo}}


+ {{end}}

{{.FooterText}}

diff --git a/src/web/TwoBoxForm.go b/src/web/TwoBoxForm.go index c5b88773..17bfe149 100644 --- a/src/web/TwoBoxForm.go +++ b/src/web/TwoBoxForm.go @@ -50,6 +50,7 @@ func ServeTwoBoxFormTemplate(w http.ResponseWriter, r *http.Request) { ShowExtraButtons bool FooterText string FooterTextInfo string + FinalizeSubmitButtonText string Step string ConfigField string NextStep string @@ -316,11 +317,12 @@ func ServeTwoBoxFormTemplate(w http.ResponseWriter, r *http.Request) { } data := TemplateData{ - IsFirstTimeSetup: config.GetIsFirstTimeSetup(), - Path: path, - Step: stepID, - FooterText: localization.GetString("UIText_FooterText"), - FooterTextInfo: localization.GetString("UIText_FooterTextInfo"), + IsFirstTimeSetup: config.GetIsFirstTimeSetup(), + Path: path, + Step: stepID, + FooterText: localization.GetString("UIText_FooterText"), + FooterTextInfo: localization.GetString("UIText_FooterTextInfo"), + FinalizeSubmitButtonText: localization.GetString("UIText_FinalizeSubmitButtonText"), } switch { From e4620dc19e43a0ba041b5395f7892c40a3b5ea1c Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sat, 20 Dec 2025 23:35:56 +0100 Subject: [PATCH 04/34] improved annoucements to show multiple if needed --- .../assets/js/dynamic-announcement.js | 145 ++++++++++-------- UIMod/onboard_bundled/ui/index.html | 18 +-- 2 files changed, 86 insertions(+), 77 deletions(-) diff --git a/UIMod/onboard_bundled/assets/js/dynamic-announcement.js b/UIMod/onboard_bundled/assets/js/dynamic-announcement.js index 73b75665..477e1755 100644 --- a/UIMod/onboard_bundled/assets/js/dynamic-announcement.js +++ b/UIMod/onboard_bundled/assets/js/dynamic-announcement.js @@ -1,21 +1,18 @@ // dynamic-announcement.js (function () { - // Configuration - change only these values if needed - const ANNOUNCEMENT_ID = 'dynamic-announcement'; - const JSON_URL = 'https://steamserverui.github.io/StationeersServerUI/dynamic-announcement.json'; + // Configuration + const CONTAINER_ID = 'dynamic-announcement-list'; + const JSON_URL = 'https://steamserverui.github.io/StationeersServerUI/dynamic-announcement-list.json'; const FETCH_TIMEOUT = 8000; // ms - // Find the announcement container - const container = document.getElementById(ANNOUNCEMENT_ID); + const container = document.getElementById(CONTAINER_ID); if (!container) { - console.warn(`[Dynamic Announcement] Element #${ANNOUNCEMENT_ID} not found on page.`); + console.warn(`[Dynamic Announcement] Container #${CONTAINER_ID} not found on page.`); return; } - // Hide it initially (in case CSS shows it by default) - container.style.display = 'none'; + container.innerHTML = ''; - // Helper: simple timeout for fetch const fetchWithTimeout = (url, options = {}, timeout = FETCH_TIMEOUT) => { return Promise.race([ fetch(url, options), @@ -25,12 +22,24 @@ ]); }; - // Main logic + function attachCollapsibleHandlers() { + document.querySelectorAll('.info-notice h3').forEach(header => { + // Avoid adding multiple listeners if called repeatedly + header.removeEventListener('click', handleClick); + header.addEventListener('click', handleClick); + }); + } + + function handleClick(event) { + const notice = event.currentTarget.parentElement; + notice.classList.toggle('open'); + } + fetchWithTimeout(JSON_URL, { method: 'GET', cache: 'no-cache' }) .then(response => { if (!response.ok) { if (response.status === 404) { - console.info('[Dynamic Announcement] No announcement (404) - staying hidden.'); + console.info('[Dynamic Announcement] No announcement file (404).'); return null; } throw new Error(`HTTP ${response.status}`); @@ -38,73 +47,87 @@ return response.json(); }) .then(data => { - if (!data) return; // 404 or empty - - // Validate required fields - if (!data.headline || !data.bodyHtml) { - console.warn('[Dynamic Announcement] JSON is missing required fields.'); + if (!data || (Array.isArray(data) && data.length === 0)) { + console.info('[Dynamic Announcement] No announcements defined.'); return; } - // Optional date range check + const announcements = Array.isArray(data) ? data : [data]; + const now = Date.now(); - const start = data.validFrom ? new Date(data.validFrom).getTime() : null; - const end = data.validUntil ? new Date(data.validUntil).getTime() : null; + const validAnnouncements = announcements.filter(ann => { + if (!ann.headline || !ann.bodyHtml) return false; - if ((start !== null && now < start) || (end !== null && now > end)) { - console.info('[Dynamic Announcement] Current date is outside the valid range.'); + const start = ann.validFrom ? new Date(ann.validFrom).getTime() : null; + const end = ann.validUntil ? new Date(ann.validUntil).getTime() : null; + + if ((start !== null && now < start) || (end !== null && now > end)) { + return false; + } + + return true; + }); + + if (validAnnouncements.length === 0) { + console.info('[Dynamic Announcement] No currently valid announcements.'); return; } - // Fill the template - const headerElement = container.querySelector('h3'); - if (headerElement) { - headerElement.innerHTML = ` - 📢 - ${escapeHtml(data.headline)} - `; - } + validAnnouncements.sort((a, b) => { + const timeA = a.validFrom ? new Date(a.validFrom).getTime() : 0; + const timeB = b.validFrom ? new Date(b.validFrom).getTime() : 0; + return timeB - timeA; + }); - const contentDiv = container.querySelector('.collapsible-content'); + // Clear container + container.innerHTML = ''; - // Short description (optional) - let shortHtml = ''; - if (data.shortDescription) { - shortHtml = `

${escapeHtml(data.shortDescription)}

`; - } + validAnnouncements.forEach(ann => { + const notice = document.createElement('div'); + notice.className = 'info-notice'; - // Warning (optional) - let warningHtml = ''; - if (data.warningHtml) { - warningHtml = `

${data.warningHtml}

`; - } + // Build inner HTML + let contentHTML = ''; - // Signature (optional) - let signatureHtml = ''; - if (data.author || data.authorRole) { - const author = data.author ? escapeHtml(data.author) : ''; - const role = data.authorRole ? escapeHtml(data.authorRole) : ''; - signatureHtml = `

${author}${author && role ? ' - ' : ''}${role}

`; - } + if (ann.shortDescription) { + contentHTML += `

${escapeHtml(ann.shortDescription)}

`; + } + + contentHTML += `

${ann.bodyHtml}

`; + + if (ann.warningHtml) { + contentHTML += `

${ann.warningHtml}

`; + } + + contentHTML += `

`; // spacer + + if (ann.author || ann.authorRole) { + const author = ann.author ? escapeHtml(ann.author) : ''; + const role = ann.authorRole ? escapeHtml(ann.authorRole) : ''; + contentHTML += `

${author}${author && role ? ' - ' : ''}${role}

`; + } + + notice.innerHTML = ` +

+ 📢 + ${escapeHtml(ann.headline)} +

+
+ ${contentHTML} +
+ `; + + container.appendChild(notice); + }); + + attachCollapsibleHandlers(); - contentDiv.innerHTML = ` - ${shortHtml} -

${data.bodyHtml}

- ${warningHtml} -

- ${signatureHtml} - `; - - // Show the announcement - container.style.display = ''; // revert to CSS default (usually block) - console.info('[Dynamic Announcement] Announcement loaded and displayed.'); + console.info(`[Dynamic Announcement] ${validAnnouncements.length} announcement(s) loaded and collapsible handlers attached.`); }) .catch(err => { - // On any error (network, timeout, JSON parse, etc.) just keep it hidden - console.info('[Dynamic Announcement] Failed to load announcement:', err.message); + console.info('[Dynamic Announcement] Failed to load announcements:', err.message); }); - // Simple HTML escape utility (prevents XSS if you trust the JSON source) function escapeHtml(text) { if (typeof text !== 'string') return text; const div = document.createElement('div'); diff --git a/UIMod/onboard_bundled/ui/index.html b/UIMod/onboard_bundled/ui/index.html index 71339142..377c7b6f 100644 --- a/UIMod/onboard_bundled/ui/index.html +++ b/UIMod/onboard_bundled/ui/index.html @@ -63,22 +63,8 @@

Stationeers Server UI v{{.Version}}{{.SSUIIdentifier}}

- + + + +
+
+ +
+ +

A new version of SSUI is ready to install and will be installed the next time you restart the application.

+ + +
+ + +
+ + +
+ ⏳ Installing update, please wait... +
+
+ ✗ Update failed. Please try again later. +
+
+
+
+ title="Save GPU Power by disabling background Animations. Persistent until toggled off. Options: Focus (Default), Always, Disabled. If unsure, check developer tools -> Application -> Local Storage -> animationState"> +
+

Stationeers Server UI v{{.Version}}{{.SSUIIdentifier}}

@@ -170,6 +198,7 @@

+ \ No newline at end of file From 67a4a7cc2615ed77a85ae08876de6217cedf432f Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sun, 21 Dec 2025 09:49:52 +0100 Subject: [PATCH 12/34] add localization for update modal messages --- UIMod/onboard_bundled/localization/de-DE.json | 7 ++++++- UIMod/onboard_bundled/localization/en-US.json | 7 ++++++- UIMod/onboard_bundled/localization/sv-SE.json | 7 ++++++- UIMod/onboard_bundled/ui/index.html | 10 +++++----- src/web/indexpage.go | 5 +++++ src/web/templatevars.go | 5 +++++ 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/UIMod/onboard_bundled/localization/de-DE.json b/UIMod/onboard_bundled/localization/de-DE.json index 02110e42..10499954 100644 --- a/UIMod/onboard_bundled/localization/de-DE.json +++ b/UIMod/onboard_bundled/localization/de-DE.json @@ -14,7 +14,12 @@ "UIText_API_Info": "API-Endpunktdokumentation", "UIText_Copyright": "Urheberrecht", "UIText_Copyright1": "Lizenziert unter", - "UIText_Copyright2": "Proprietärer Lizenz" + "UIText_Copyright2": "Proprietärer Lizenz", + "UIText_UpdateAvailable": "Eine neue Version von SSUI ist bereit zu installieren und wird beim nächsten Neustart installiert.", + "UIText_UpdateLater": "Später", + "UIText_UpdateNow": "Jetzt aktualisieren", + "UIText_UpdateInstalling": "Aktualisierung wird installiert, bitte warten...", + "UIText_UpdateFailed": "Aktualisierung fehlgeschlagen. Bitte versuche es später erneut." }, "config": { "UIText_ServerConfig": "Server Konfiguration", diff --git a/UIMod/onboard_bundled/localization/en-US.json b/UIMod/onboard_bundled/localization/en-US.json index 225368ae..9fae31d7 100644 --- a/UIMod/onboard_bundled/localization/en-US.json +++ b/UIMod/onboard_bundled/localization/en-US.json @@ -14,7 +14,12 @@ "UIText_API_Info": "API Endpoint Reference", "UIText_Copyright": "Copyright", "UIText_Copyright1": "Licensed under", - "UIText_Copyright2": "Proprietary License" + "UIText_Copyright2": "Proprietary License", + "UIText_UpdateAvailable": "A new version of SSUI is ready to install and will be installed the next time you restart the application.", + "UIText_UpdateLater": "Later", + "UIText_UpdateNow": "Update Now", + "UIText_UpdateInstalling": "Installing update, please wait...", + "UIText_UpdateFailed": "Update failed. Please try again later." }, "config": { "UIText_ServerConfig": "Server Configuration", diff --git a/UIMod/onboard_bundled/localization/sv-SE.json b/UIMod/onboard_bundled/localization/sv-SE.json index 4e4a847f..f3e100ac 100644 --- a/UIMod/onboard_bundled/localization/sv-SE.json +++ b/UIMod/onboard_bundled/localization/sv-SE.json @@ -14,7 +14,12 @@ "UIText_API_Info": "API-slutpunktsreferens", "UIText_Copyright": "Upphovsrätt", "UIText_Copyright1": "Licensierad under", - "UIText_Copyright2": "Proprietär licens" + "UIText_Copyright2": "Proprietär licens", + "UIText_UpdateAvailable": "En ny version av SSUI är redo att installera och kommer att installeras nästa gång du startar applikationen.", + "UIText_UpdateLater": "Senare", + "UIText_UpdateNow": "Uppdatera nu", + "UIText_UpdateInstalling": "Uppdatering installeras, vänligen vänta...", + "UIText_UpdateFailed": "Uppdateringen installeras, vänligen vänta..." }, "config": { "UIText_ServerConfig": "Konfiguration", diff --git a/UIMod/onboard_bundled/ui/index.html b/UIMod/onboard_bundled/ui/index.html index b3649ff2..8226c741 100644 --- a/UIMod/onboard_bundled/ui/index.html +++ b/UIMod/onboard_bundled/ui/index.html @@ -36,20 +36,20 @@

-

A new version of SSUI is ready to install and will be installed the next time you restart the application.

+

{{.UIText_UpdateAvailable}}

- - + +
- ⏳ Installing update, please wait... + ⏳ {{.UIText_UpdateInstalling}}
- ✗ Update failed. Please try again later. + ✗ {{.UIText_UpdateFailed}}

diff --git a/src/web/indexpage.go b/src/web/indexpage.go index 81d72180..f702d8c6 100644 --- a/src/web/indexpage.go +++ b/src/web/indexpage.go @@ -33,6 +33,11 @@ func ServeIndex(w http.ResponseWriter, r *http.Request) { } data := IndexTemplateData{ + UIText_UpdateAvailable: localization.GetString("UIText_UpdateAvailable"), + UIText_UpdateLater: localization.GetString("UIText_UpdateLater"), + UIText_UpdateNow: localization.GetString("UIText_UpdateNow"), + UIText_UpdateInstalling: localization.GetString("UIText_UpdateInstalling"), + UIText_UpdateFailed: localization.GetString("UIText_UpdateFailed"), Version: config.GetVersion(), Branch: config.GetBranch(), SSUIIdentifier: Identifier, diff --git a/src/web/templatevars.go b/src/web/templatevars.go index ad5d5a87..311e1eab 100644 --- a/src/web/templatevars.go +++ b/src/web/templatevars.go @@ -2,6 +2,11 @@ package web // TemplateData holds data to be passed to templates type IndexTemplateData struct { + UIText_UpdateAvailable string + UIText_UpdateLater string + UIText_UpdateNow string + UIText_UpdateInstalling string + UIText_UpdateFailed string Version string Branch string SSUIIdentifier string From 0e11cd3e45468708244e72475a3ee4f68530ead9 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sun, 21 Dec 2025 18:41:54 +0100 Subject: [PATCH 13/34] fixed removed button icons on config page --- UIMod/onboard_bundled/assets/css/config.css | 21 ++++++++++++++++----- src/setup/install.go | 7 +++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/UIMod/onboard_bundled/assets/css/config.css b/UIMod/onboard_bundled/assets/css/config.css index 9262c3cd..7ad344ba 100644 --- a/UIMod/onboard_bundled/assets/css/config.css +++ b/UIMod/onboard_bundled/assets/css/config.css @@ -54,7 +54,7 @@ width: 24px; height: 24px; margin-right: 10px; - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 64 64' id='wizard' xmlns='http://www.w3.org/2000/svg' fill='%23000000'%3E%3C!-- SVG content unchanged, but stroke/fill colours are part of the icon design --%3E%3C/svg%3E"); + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 64 64' id='wizard' xmlns='http://www.w3.org/2000/svg' fill='%23000000'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Ctitle%3Ewizard%3C/title%3E%3Ccircle cx='33' cy='23' r='23' style='fill:%23edebdc'%3E%3C/circle%3E%3Cline x1='7' y1='17' x2='7' y2='19' style='fill:none;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/line%3E%3Cline x1='7' y1='23' x2='7' y2='25' style='fill:none;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/line%3E%3Cpath d='M21.778,47H47.222A8.778,8.778,0,0,1,56,55.778V61a0,0,0,0,1,0,0H13a0,0,0,0,1,0,0V55.778A8.778,8.778,0,0,1,21.778,47Z' style='fill:%239dc1e4;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/path%3E%3Cpolygon points='32 61 28 61 34 49 38 49 32 61' style='fill:%23ffffff;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/polygon%3E%3Cpath d='M59,39H11v4.236A5.763,5.763,0,0,0,16.764,49L34,55l19.236-6A5.763,5.763,0,0,0,59,43.236Z' style='fill:%239dc1e4;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/path%3E%3Cline x1='3' y1='21' x2='5' y2='21' style='fill:none;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/line%3E%3Cline x1='9' y1='21' x2='11' y2='21' style='fill:none;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/line%3E%3Ccircle cx='55.5' cy='6.5' r='2.5' style='fill:none;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/circle%3E%3Ccircle cx='13.984' cy='6.603' r='1.069' style='fill:%234c241d'%3E%3C/circle%3E%3Cellipse cx='35' cy='39' rx='24' ry='6' style='fill:%236b4f5b;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/ellipse%3E%3Ccircle cx='5.984' cy='30.603' r='1.069' style='fill:%234c241d'%3E%3C/circle%3E%3Cpath d='M48,13V10.143A6.143,6.143,0,0,0,41.857,4H27.143A6.143,6.143,0,0,0,21,10.143V13' style='fill:%239dc1e4;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/path%3E%3Crect x='20' y='17.81' width='29' height='14.19' style='fill:%23ffe8dc;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/rect%3E%3Cpath d='M41.972,13H48a4,4,0,0,1,4,4h0a4,4,0,0,1-4,4H21a4,4,0,0,1-4-4h0a4,4,0,0,1,4-4H37' style='fill:%23ffffff;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/path%3E%3Ccircle cx='39.5' cy='25.5' r='1.136' style='fill:%234c241d'%3E%3C/circle%3E%3Ccircle cx='29.5' cy='25.5' r='1.136' style='fill:%234c241d'%3E%3C/circle%3E%3Cpath d='M43.875,32a6.472,6.472,0,0,0-5.219-2.2A5.2,5.2,0,0,0,35,31.974,5.2,5.2,0,0,0,31.344,29.8,6.472,6.472,0,0,0,26.125,32H20v4.5a14.5,14.5,0,0,0,29,0V32Z' style='fill:%23ffffff;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/path%3E%3Cline x1='33' y1='36' x2='37' y2='36' style='fill:none;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/line%3E%3Crect x='32' y='10' width='5' height='5' transform='translate(1.266 28.056) rotate(-45)' style='fill:%23bd53b5;stroke:%234c241d;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px'%3E%3C/rect%3E%3C/g%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center; } @@ -121,22 +121,33 @@ display: inline-block; width: 24px; height: 24px; + padding: 2px; margin-right: 10px; vertical-align: middle; } -/* Icons – colours are baked in as white; keep as-is */ -.server-icon, -.discord-icon, -.detection-icon { +/* Server Icon - gear/cog icon */ +.server-icon { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: center; } +/* Discord Icon */ .discord-icon { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 127.14 96.36' fill='%23ffffff'%3E%3Cpath d='M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center; background-size: 20px 20px; } +/* Detection Manager Icon - radar/search icon */ +.detection-icon { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z'/%3E%3Cpath d='M12 8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-1 5h2v2h-2v-2zm0-2h2v1h-2v-1zm0-1h2v1h-2v-1z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center; +} + .tab-button { display: flex; align-items: center; diff --git a/src/setup/install.go b/src/setup/install.go index 5343f60c..1d81e6de 100644 --- a/src/setup/install.go +++ b/src/setup/install.go @@ -16,7 +16,6 @@ import ( "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger" - "github.com/JacksonTheMaster/StationeersServerUI/v5/src/setup/update" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/steamcmd" ) @@ -28,9 +27,9 @@ func Install(wg *sync.WaitGroup) { defer wg.Done() // Signal that installation is complete // Step 0: Check for updates - if err, _ := update.Update(true); err != nil { - logger.Install.Error("❌Update check went sideways: " + err.Error()) - } + //if err, _ := update.Update(true); err != nil { + // logger.Install.Error("❌Update check went sideways: " + err.Error()) + //} // Step 1: Check and download the UIMod folder contents logger.Install.Debug("🔄Checking UIMod folder...") From 212b8c16a12c8e80c84ebe799654ae1a2e58f4c9 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sun, 21 Dec 2025 19:57:37 +0100 Subject: [PATCH 14/34] fixed config page mobile style --- UIMod/onboard_bundled/assets/css/config.css | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/UIMod/onboard_bundled/assets/css/config.css b/UIMod/onboard_bundled/assets/css/config.css index 7ad344ba..10ce0f45 100644 --- a/UIMod/onboard_bundled/assets/css/config.css +++ b/UIMod/onboard_bundled/assets/css/config.css @@ -322,9 +322,26 @@ select option { background-color: rgba(0, 0, 0, 0.4); } -/* Responsive & Animation unchanged */ @media (max-width: 768px) { - /* ... unchanged ... */ + .section-navigation { + flex-wrap: wrap; + justify-content: flex-start; + } + + .section-nav-button { + padding: 8px 12px; + font-size: 0.85em; + } + + .wizard-button { + width: 100%; + justify-content: center; + padding: 10px 15px; + } + + .section-title { + font-size: 0.9rem; + } } @keyframes fadeIn { From 31b0a550ae20b39f580188a672854ab98d7c0921 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Sun, 21 Dec 2025 19:59:05 +0100 Subject: [PATCH 15/34] updated config page tab design and prepared for SLP tab --- UIMod/onboard_bundled/assets/css/config.css | 19 ++++++++++++++---- .../onboard_bundled/assets/icons/discord.webp | Bin 0 -> 1244 bytes .../assets/icons/launchpad.webp | Bin 0 -> 1142 bytes UIMod/onboard_bundled/ui/config.html | 17 ++++++++++++---- 4 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 UIMod/onboard_bundled/assets/icons/discord.webp create mode 100644 UIMod/onboard_bundled/assets/icons/launchpad.webp diff --git a/UIMod/onboard_bundled/assets/css/config.css b/UIMod/onboard_bundled/assets/css/config.css index 10ce0f45..716bc0ba 100644 --- a/UIMod/onboard_bundled/assets/css/config.css +++ b/UIMod/onboard_bundled/assets/css/config.css @@ -122,8 +122,8 @@ width: 24px; height: 24px; padding: 2px; - margin-right: 10px; vertical-align: middle; + background-size: contain; } /* Server Icon - gear/cog icon */ @@ -135,10 +135,9 @@ /* Discord Icon */ .discord-icon { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 127.14 96.36' fill='%23ffffff'%3E%3Cpath d='M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z'/%3E%3C/svg%3E"); + background-image: url("/static/icons/discord.webp"); background-repeat: no-repeat; background-position: center; - background-size: 20px 20px; } /* Detection Manager Icon - radar/search icon */ @@ -147,17 +146,29 @@ background-repeat: no-repeat; background-position: center; } +.slp-icon { + background-image: url("/static/icons/launchpad.webp"); + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; +} .tab-button { display: flex; align-items: center; - justify-content: center; + justify-content: space-evenly; + flex-direction: column; } .tab-button.active .icon { filter: brightness(1.2); } +.config-tabs{ + display: flex; + flex-direction: column; +} + .fill-hint-wraper { background-color: var(--danger); border-radius: 8px; diff --git a/UIMod/onboard_bundled/assets/icons/discord.webp b/UIMod/onboard_bundled/assets/icons/discord.webp new file mode 100644 index 0000000000000000000000000000000000000000..587be942c1ab631da9dec513f1200b99d4033b33 GIT binary patch literal 1244 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 I%DVsn03`f6t^fc4 literal 0 HcmV?d00001 diff --git a/UIMod/onboard_bundled/ui/config.html b/UIMod/onboard_bundled/ui/config.html index 5672510b..e0fa874a 100644 --- a/UIMod/onboard_bundled/ui/config.html +++ b/UIMod/onboard_bundled/ui/config.html @@ -30,15 +30,22 @@

{{.UIText_ServerConfig}}

-
+
+
@@ -418,6 +425,8 @@

{{.UIText_DiscordIntegrationBenefits}}

target="_blank">GitHub repository

+
+
- + {{if eq .IsNewTerrainAndSaveSystemTrueSelected "selected"}} - + {{end}} - - + +
@@ -95,7 +99,7 @@

{{.UIText_BasicServerSettings}}

{{.UIText_WorldIDInfo}}
- +
{{.UIText_BasicServerSettings}}
{{.UIText_ServerPasswordInfo}}
- +
{{.UIText_AdvancedConfiguration}}
- +
{{.UIText_AdminPasswordInfo}}
@@ -241,8 +245,7 @@

{{.UIText_AdvancedConfiguration}}

- +
{{.UIText_GameBranchInfo}}
@@ -256,10 +259,12 @@

{{.UIText_AdvancedConfiguration}}

- +
{{.UIText_AllowAutoGameServerUpdatesInfo}}
@@ -281,7 +286,7 @@

{{.UIText_AdvancedConfiguration}}

{{.UIText_CreateGameServerLogFileInfo}}
- + @@ -291,16 +296,16 @@

{{.UIText_TerrainSettingsHeader}}


-
+
{{.UIText_WorldIDInfo}}
-
+
- +
✅{{.UIText_DifficultyInfo}}
@@ -318,7 +323,8 @@

{{.UIText_TerrainSettingsHeader}}

✅{{.UIText_StartLocationInfo}}
- @@ -328,7 +334,7 @@

{{.UIText_TerrainSettingsHeader}}

- + @@ -421,8 +427,9 @@

{{.UIText_DiscordIntegrationBenefits}}

  • {{.UIText_DiscordBenefit4}}
  • {{.UIText_DiscordBenefit5}}
  • -

    {{.UIText_DiscordSetupInstructions}} GitHub repository

    +

    {{.UIText_DiscordSetupInstructions}} GitHub + repository

    @@ -430,22 +437,31 @@

    {{.UIText_DiscordIntegrationBenefits}}

    - + \ No newline at end of file diff --git a/src/web/configpage.go b/src/web/configpage.go index a03598fb..839f3fdd 100644 --- a/src/web/configpage.go +++ b/src/web/configpage.go @@ -189,6 +189,7 @@ func ServeConfigPage(w http.ResponseWriter, r *http.Request) { // Localized UI text UIText_ServerConfig: localization.GetString("UIText_ServerConfig"), UIText_DiscordIntegration: localization.GetString("UIText_DiscordIntegration"), + UIText_SLPModIntegration: localization.GetString("UIText_SLPModIntegration"), UIText_DetectionManager: localization.GetString("UIText_DetectionManager"), UIText_ConfigurationWizard: localization.GetString("UIText_ConfigurationWizard"), UIText_PleaseSelectSection: localization.GetString("UIText_PleaseSelectSection"), diff --git a/src/web/templatevars.go b/src/web/templatevars.go index 311e1eab..c61e94b8 100644 --- a/src/web/templatevars.go +++ b/src/web/templatevars.go @@ -94,6 +94,7 @@ type ConfigTemplateData struct { UIText_ServerConfig string UIText_DiscordIntegration string + UIText_SLPModIntegration string UIText_DetectionManager string UIText_ConfigurationWizard string UIText_PleaseSelectSection string From 81626039bc694787812db922c617598b24655d3c Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Wed, 24 Dec 2025 09:57:15 +0100 Subject: [PATCH 18/34] moved detection manager to tab style on config page --- .../assets/css/detectionmanager.css | 6 +- .../assets/js/detectionmanager.js | 18 +-- .../detectionmanager/detectionmanager.html | 119 ------------------ UIMod/onboard_bundled/ui/config.html | 97 +++++++++++++- 4 files changed, 100 insertions(+), 140 deletions(-) delete mode 100644 UIMod/onboard_bundled/detectionmanager/detectionmanager.html diff --git a/UIMod/onboard_bundled/assets/css/detectionmanager.css b/UIMod/onboard_bundled/assets/css/detectionmanager.css index 2bbd84dd..6bf80a88 100644 --- a/UIMod/onboard_bundled/assets/css/detectionmanager.css +++ b/UIMod/onboard_bundled/assets/css/detectionmanager.css @@ -1,6 +1,6 @@ @import '/static/css/variables.css'; -#detection-list-tab { +#detection-list-container { background: rgba(114, 137, 218, 0.1); } @@ -190,6 +190,10 @@ input:checked+.slider:before { margin-top: 10px; } +#add-detection-container { + margin-top: 2rem; +} + /* Responsive design */ @media (max-width: 768px) { .detection-list-header, diff --git a/UIMod/onboard_bundled/assets/js/detectionmanager.js b/UIMod/onboard_bundled/assets/js/detectionmanager.js index 9d1a3702..c13430f7 100644 --- a/UIMod/onboard_bundled/assets/js/detectionmanager.js +++ b/UIMod/onboard_bundled/assets/js/detectionmanager.js @@ -1,16 +1,3 @@ -// Show active tab -function showTab(tabId) { - document.querySelectorAll('.tab-content').forEach(tab => tab.classList.remove('active')); - document.querySelectorAll('.tab-button').forEach(button => button.classList.remove('active')); - - document.getElementById(tabId).classList.add('active'); - document.querySelector(`.tab-button[data-tab="${tabId}"]`).classList.add('active'); - - if (tabId === 'detection-list-tab') { - loadDetections(); - } -} - // Toggle detection type function setupDetectionTypeToggle() { const toggle = document.getElementById('detection-type-toggle'); @@ -50,7 +37,7 @@ function loadDetections() { loader.style.display = 'none'; if (detections.length === 0) { - detectionItems.innerHTML = '
    No custom detections found. Add one to get started.
    '; + detectionItems.innerHTML = '
    No custom detections found. Add one below to get started.
    '; return; } @@ -163,8 +150,5 @@ function escapeHtml(unsafe) { document.addEventListener('DOMContentLoaded', () => { loadDetections(); setupDetectionTypeToggle(); - document.querySelectorAll('.tab-button').forEach(button => { - button.addEventListener('click', () => showTab(button.getAttribute('data-tab'))); - }); document.querySelector('.add-button').addEventListener('click', submitDetection); }); \ No newline at end of file diff --git a/UIMod/onboard_bundled/detectionmanager/detectionmanager.html b/UIMod/onboard_bundled/detectionmanager/detectionmanager.html deleted file mode 100644 index e298d02e..00000000 --- a/UIMod/onboard_bundled/detectionmanager/detectionmanager.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - Custom Detection Manager - - - - - - - - - - -
    -
    - -
    -
    -

    Custom Detection Manager

    -
    -
    - - - -
    -
    - -
    -
    -
    -
    -
    Type
    -
    Pattern
    -
    Message
    -
    Actions
    -
    -
    -
    No custom detections found. Add one to get started.
    -
    -
    -
    - -
    -
    -
    -
    - Change Detection Mode - - Keyword -
    - -
    - - -
    Text to match exactly (case-sensitive)
    -
    - -
    - - -
    Message to display when pattern is detected
    -
    - - - -
    -
    - -
    -
    -
    - -
    -

    Custom Detection Patterns

    -

    Custom detections allow you to create custom patterns for detection. These patterns can be used to detect specific events in the server logs.

    -

    To create a custom detection, you can use the "Add Detection Tab" to define a regex pattern or alternatively a simple string match ("keyword") and a message that will be logged in the Events and if enabled in Discord when the pattern is detected. It is not possible to create patterns that have faulty regex.

    -
    -

    Creating Effective Detections

    -
    -
    -

    Keyword Detection:

    -

    For example, to detect the "Unsupported shader" message that unity logs when a shader is not supported, you would use the following pattern:

    - Pattern: "Unsupported shader" - Message: "Unity detected an unsupported shader. This may cause unexpected behavior." -
    -
    -

    Regex Detection:

    -

    For example, to detect (fictional) the "Player (.+) has reached level (\d+)" message that is logged when a player reaches a certain level in an elevator, you would use the following pattern:

    - Pattern: "Player (.+) has reached level (\d+)" - Message: "Player {1} has reached level {2}" -

    The AI of your choise will be more than happy to help you create effective detections. You can also use the Regex101 tool to test your patterns.

    -
    -
    -

    For more information, visit the GitHub Wiki

    -
    -
    - -
    - -
    - -
    -
    - - - - - - - \ No newline at end of file diff --git a/UIMod/onboard_bundled/ui/config.html b/UIMod/onboard_bundled/ui/config.html index 5342ccc3..78c44809 100644 --- a/UIMod/onboard_bundled/ui/config.html +++ b/UIMod/onboard_bundled/ui/config.html @@ -12,6 +12,7 @@ + @@ -43,7 +44,7 @@

    {{.UIText_ServerConfig}}

    {{.UIText_SLPModIntegration}} - @@ -53,7 +54,7 @@

    {{.UIText_ServerConfig}}

    - @@ -432,8 +433,97 @@

    {{.UIText_DiscordIntegrationBenefits}}

    repository

    +
    + +
    +

    Custom Detection Manager

    +

    Custom detections allow you to create custom patterns for event detection. These patterns can be used to + detect specific events in the server log and send alerts to the "Status" channel in Discord and will be shown in the Events tab on the main dashboard.

    +

    To create a custom detection, you can either define a regex pattern or + alternatively a simple string match ("keyword") and a message that will be broadcasted to Discord and the Events log

    + +
    +
    +
    +
    +
    Type
    +
    Pattern
    +
    Message
    +
    Actions
    +
    +
    +
    No custom detections found. Add one to get started.
    +
    +
    +
    + +
    +
    +
    +
    + Change Detection Mode + + Keyword +
    + +
    + + +
    Text to match exactly (case-sensitive)
    +
    + +
    + + +
    Message to display when pattern is detected
    +
    + + + +
    + +
    +
    +
    +
    + +
    +
    +

    Creating Effective Detections

    +
    +
    +

    Keyword Detection:

    +

    For example, to detect the "Unsupported shader" message that unity logs when a shader + is not supported, you would use the following pattern:

    + Pattern: "Unsupported shader" + Message: "Unity detected an unsupported shader. This may cause unexpected behavior." +
    +
    +

    Regex Detection:

    +

    For example, to detect (fictional) the "Player (.+) has reached level (\d+)" message + that is logged when a player reaches a certain level in an elevator, you would use the + following pattern:

    + Pattern: "Player (.+) has reached level (\d+)" + Message: "Player {1} has reached level {2}" +

    The AI of your choise will be more than happy to help you create effective detections. + You can also use the Regex101 tool to + test your patterns.

    +
    +
    +

    For more information, visit the GitHub Wiki

    +
    +
    + +
    +
    +
    +
    @@ -221,27 +223,6 @@

    {{.UIText_NetworkConfiguration}}

    {{.UIText_AdvancedConfiguration}}

    -
    - - -
    {{.UIText_AdminPasswordInfo}}
    -
    - -
    - - -
    {{.UIText_ServerExePathInfo}}
    -
    {{.UIText_ServerExePathInfo2}}
    -
    - -
    - - -
    {{.UIText_AdditionalParamsInfo}}
    -
    -
    {{.UIText_AdvancedConfiguration}}
    {{.UIText_AutoRestartServerTimerInfo}}
    -
    - - -
    {{.UIText_GameBranchInfo}}
    -
    -
    +
    {{.UIText_GameBranchInfo}}
    +
    + +
    + + +
    {{.UIText_ServerExePathInfo}}
    +
    {{.UIText_ServerExePathInfo2}}
    +
    + +
    + + +
    {{.UIText_AdminPasswordInfo}}
    +
    + +
    + + +
    {{.UIText_AdditionalParamsInfo}}
    +
    + + +
    From fab88a10910add1db8a97e0ce55c69a9046b66dc Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Wed, 24 Dec 2025 10:27:23 +0100 Subject: [PATCH 22/34] added more error handling for exit status 8 in runSteamCMD, providing guidance for users to restart and report issues (Thx for the hint Seneram) --- src/steamcmd/steamcmd.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/steamcmd/steamcmd.go b/src/steamcmd/steamcmd.go index 7312e714..73c68108 100644 --- a/src/steamcmd/steamcmd.go +++ b/src/steamcmd/steamcmd.go @@ -131,6 +131,10 @@ func runSteamCMD(steamCMDDir string) (int, error) { if err != nil { if exitErr, ok := err.(*exec.ExitError); ok { logger.Install.Error("❌ SteamCMD exited unsuccessfully: " + err.Error() + "\n") + if err.Error() == "exit status 8" { + logger.Install.Error(" ⚠️ Exit status 8 after the first install is a known issue. Please restart SSUI and try again. If the issue persists, feel free to ask for help on the SSUI Discord server or GitHub issues page.") + logger.Install.Error(" ⚠️ Please restart SSUI and try again. If the issue persists, please report it on the SSUI Discord server or GitHub issues page.") + } return exitErr.ExitCode(), err } logger.Install.Error("❌ Error running SteamCMD: " + err.Error() + "\n") From 9e56a891d4c1656773fd8da063207369157b8f6e Mon Sep 17 00:00:00 2001 From: JacksonTheMaster Date: Wed, 24 Dec 2025 10:27:43 +0100 Subject: [PATCH 23/34] improved main dashboard --- UIMod/onboard_bundled/ui/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIMod/onboard_bundled/ui/index.html b/UIMod/onboard_bundled/ui/index.html index 8226c741..a19911cf 100644 --- a/UIMod/onboard_bundled/ui/index.html +++ b/UIMod/onboard_bundled/ui/index.html @@ -55,7 +55,7 @@

    - +