From 637f347169c6911d1da6886d3a911e1eb80a850b Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 14:32:13 +0200 Subject: [PATCH 1/8] removed deprecated ! commands and related intents --- src/discordbot/handleDeprecated.go | 102 ----------------------------- src/discordbot/interface.go | 9 ++- 2 files changed, 4 insertions(+), 107 deletions(-) delete mode 100644 src/discordbot/handleDeprecated.go diff --git a/src/discordbot/handleDeprecated.go b/src/discordbot/handleDeprecated.go deleted file mode 100644 index 845df7e7..00000000 --- a/src/discordbot/handleDeprecated.go +++ /dev/null @@ -1,102 +0,0 @@ -package discordbot - -import ( - "strings" - - "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" - "github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger" - "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/gamemgr" - - "github.com/bwmarrin/discordgo" -) - -// As of v4.5, the ![command] commands are deprecated and will be removed in a future version. - -func handleHelpCommand() { - helpMessage := ` -**Available Commands:** -- ` + "`Attention`" + `: The ![command] commands are deprecated and will be removed in a future version. Please use the slash commands instead. -- ` + "`/help`" + `: Displays the help message for the slash commands.` - - SendMessageToControlChannel(helpMessage) -} - -// DEPRECATED -func handleUpdateCommand() { - SendMessageToControlChannel("🙏 Sorry, this feature has been deprecated. Server Updates are now handled automatically at Software Startup. If you are interested in bringing this feature back, please report it on the GitHub repository. We will be happy to implement it.") -} - -// DEPRECATED -func handleValidateCommand() { - SendMessageToControlChannel(" 🙏Sorry, this feature has been deprecated. Server File Validation is now handled automatically at Software Startup. If you are interested in bringing this feature back, please report it on the GitHub repository. We will be happy to implement it.") -} - -// DEPRECATED -func handleListCommand() { - SendMessageToControlChannel("🙏 Sorry, this feature has been deprecated. The /list command has taken over this functionality. Please use slash (/) commands instead.") -} - -// DEPRECATED -func handleRestoreCommand() { - SendMessageToControlChannel("🙏 Sorry, this feature has been deprecated. The /restore command has taken over this functionality. Please use slash (/) commands instead.") -} - -// DEPRECATED -func handleBanCommand() { - SendMessageToControlChannel("🙏 Sorry, this feature has been deprecated. The /bansteamid command has taken over this functionality. Please use slash (/) commands instead.") -} - -// DEPRECATED -func handleUnbanCommand() { - SendMessageToControlChannel("🙏 Sorry, this feature has been deprecated. The /unbansteamid command has taken over this functionality. Please use slash (/) commands instead.") -} - -// DEPRECATED -func listenToDiscordMessages(s *discordgo.Session, m *discordgo.MessageCreate) { - - if m.Author.ID == s.State.User.ID || m.ChannelID != config.GetControlChannelID() { - logger.Discord.Debug("Ignoring message from " + m.Author.Username) - logger.Discord.Debug("Ignored message: " + m.Content) - logger.Discord.Debug("Message channel: " + m.ChannelID) - - return - } - - // log the message if debug is enabled - logger.Discord.Debug("Ignoring message from " + m.Author.Username) - logger.Discord.Debug("Ignored message: " + m.Content) - logger.Discord.Debug("Message channel: " + m.ChannelID) - - content := strings.TrimSpace(m.Content) - - switch { - case strings.HasPrefix(content, "!start"): - gamemgr.InternalStartServer() - - case strings.HasPrefix(content, "!stop"): - gamemgr.InternalStopServer() - - case strings.HasPrefix(content, "!restore"): - handleRestoreCommand() - - case strings.HasPrefix(content, "!list"): - handleListCommand() - - case strings.HasPrefix(content, "!update"): - handleUpdateCommand() - - case strings.HasPrefix(content, "!help"): - handleHelpCommand() - - case strings.HasPrefix(content, "!ban"): - handleBanCommand() - - case strings.HasPrefix(content, "!unban"): - handleUnbanCommand() - - case strings.HasPrefix(content, "!validate"): - handleValidateCommand() - default: - // Optionally handle unrecognized commands or ignore them - } -} diff --git a/src/discordbot/interface.go b/src/discordbot/interface.go index 10c9a93a..773f8f51 100644 --- a/src/discordbot/interface.go +++ b/src/discordbot/interface.go @@ -30,10 +30,10 @@ func InitializeDiscordBot() { } // Set intents - config.DiscordSession.Identify.Intents = discordgo.IntentsGuilds | discordgo.IntentsGuildMessages | discordgo.IntentsGuildMessageReactions | discordgo.IntentsMessageContent + config.DiscordSession.Identify.Intents = discordgo.IntentsGuildMessageReactions logger.Discord.Info("Starting Discord integration...") - logger.Discord.Debug("Discord token: " + config.GetDiscordToken()) + //logger.Discord.Debug("Discord token: " + config.GetDiscordToken()) logger.Discord.Debug("ControlChannelID: " + config.GetControlChannelID()) logger.Discord.Debug("StatusChannelID: " + config.GetStatusChannelID()) logger.Discord.Debug("ConnectionListChannelID: " + config.GetConnectionListChannelID()) @@ -48,13 +48,12 @@ func InitializeDiscordBot() { } // Register handlers and commands after session is open - config.DiscordSession.AddHandler(listenToDiscordMessages) config.DiscordSession.AddHandler(listenToDiscordReactions) config.DiscordSession.AddHandler(listenToSlashCommands) registerSlashCommands(config.DiscordSession) logger.Discord.Info("Bot is now running.") - SendMessageToStatusChannel("🤖 Bot Version " + config.GetVersion() + " Branch " + config.GetBranch() + " connected to Discord.") + SendMessageToStatusChannel("🤖 SSUI Version " + config.GetVersion() + " connected to Discord.") sendControlPanel() // Send control panel message to Discord UpdateBotStatusWithMessage("StationeersServerUI v" + config.GetVersion()) // Start buffer flush ticker @@ -68,7 +67,7 @@ func InitializeDiscordBot() { select {} // Keep it running } -// Updates the bot status with a string message (unused in 4.3) +// Updates the bot status with a string message func UpdateBotStatusWithMessage(message string) { err := config.DiscordSession.UpdateGameStatus(0, message) if err != nil { From e56785f1fe7713dc7bd8fccf7d29e2ea9a5ce289 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 14:57:15 +0200 Subject: [PATCH 2/8] added /update command to discord integration for gameserver updates --- src/discordbot/handleSlashcommands.go | 24 ++++++++++++++++++++++++ src/discordbot/registerSlashcommands.go | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/src/discordbot/handleSlashcommands.go b/src/discordbot/handleSlashcommands.go index 5cf8b80e..150a6c5b 100644 --- a/src/discordbot/handleSlashcommands.go +++ b/src/discordbot/handleSlashcommands.go @@ -11,6 +11,7 @@ import ( "github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/backupmgr" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/gamemgr" + "github.com/JacksonTheMaster/StationeersServerUI/v5/src/setup" "github.com/bwmarrin/discordgo" ) @@ -27,6 +28,7 @@ var handlers = map[string]commandHandler{ "list": handleList, "bansteamid": handleBan, "unbansteamid": handleUnban, + "update": handleUpdate, } // Check channel and handle initial validation @@ -92,6 +94,27 @@ func handleStatus(s *discordgo.Session, i *discordgo.InteractionCreate, data Emb return respond(s, i, data) } +func handleUpdate(s *discordgo.Session, i *discordgo.InteractionCreate, data EmbedData) error { + data.Title = "🎮 Gameserver Update" + data.Description = "Updating the gameserver via SteamCMD..." + data.Color = 0xFFA500 + if gamemgr.InternalIsServerRunning() { + SendMessageToControlChannel("❗ Server is running, stopping server first...") + gamemgr.InternalStopServer() + time.Sleep(10000 * time.Millisecond) + } + + _, err := setup.InstallAndRunSteamCMD() + + data.Fields = []EmbedField{ + {Name: "Update Status:", Value: map[bool]string{true: "🟢 Success", false: "🔴 Failed"}[err == nil], Inline: true}, + } + if err != nil { + data.Fields = append(data.Fields, EmbedField{Name: "Error:", Value: err.Error(), Inline: true}) + } + return respond(s, i, data) +} + func handleHelp(s *discordgo.Session, i *discordgo.InteractionCreate, data EmbedData) error { data.Title, data.Description, data.Color = "Command Help", "Available Commands:", 0x1E90FF data.Fields = []EmbedField{ @@ -102,6 +125,7 @@ func handleHelp(s *discordgo.Session, i *discordgo.InteractionCreate, data Embed {Name: "/help", Value: "Shows this help"}, {Name: "/bansteamid ", Value: "Bans a player"}, {Name: "/unbansteamid ", Value: "Unbans a player"}, + {Name: "/update", Value: "Updates the gameserver via SteamCMD"}, } return respond(s, i, data) } diff --git a/src/discordbot/registerSlashcommands.go b/src/discordbot/registerSlashcommands.go index f4db1d36..285c4f5f 100644 --- a/src/discordbot/registerSlashcommands.go +++ b/src/discordbot/registerSlashcommands.go @@ -28,6 +28,10 @@ func registerSlashCommands(s *discordgo.Session) { Name: "help", Description: "Show command help", }, + { + Name: "update", + Description: "Update the gameserver via SteamCMD. Feedback will take a while, please be patient.", + }, { Name: "restore", Description: "Restore a backup at the specified index", From c655884922d3d91f33813786c5018a2051d47057 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 15:21:04 +0200 Subject: [PATCH 3/8] added /command [command] to discord, allows running SSCM commands from discord --- src/discordbot/handleSlashcommands.go | 22 ++++++++++++++++++++++ src/discordbot/registerSlashcommands.go | 12 ++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/discordbot/handleSlashcommands.go b/src/discordbot/handleSlashcommands.go index 150a6c5b..fd110b89 100644 --- a/src/discordbot/handleSlashcommands.go +++ b/src/discordbot/handleSlashcommands.go @@ -10,6 +10,7 @@ import ( "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/backupmgr" + "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/commandmgr" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/managers/gamemgr" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/setup" @@ -29,6 +30,7 @@ var handlers = map[string]commandHandler{ "bansteamid": handleBan, "unbansteamid": handleUnban, "update": handleUpdate, + "command": handleCommand, } // Check channel and handle initial validation @@ -234,3 +236,23 @@ func handleBanUnban(s *discordgo.Session, i *discordgo.InteractionCreate, data E data.Fields = []EmbedField{{Name: "Status", Value: "✅ Completed", Inline: true}} return respond(s, i, data) } + +func handleCommand(s *discordgo.Session, i *discordgo.InteractionCreate, data EmbedData) error { + data.Title, data.Description, data.Color = "Server Control", "Sending a command to the gameserver console...", 0x00FF00 + data.Fields = []EmbedField{{Name: "Status", Value: "❌ Failed, is the server running and SSCM enabled?", Inline: true}} + data.Color = 0xFF0000 + if gamemgr.InternalIsServerRunning() { + data.Color = 0x00FF00 + err := commandmgr.WriteCommand(i.ApplicationCommandData().Options[0].StringValue()) + if err != nil { + data.Fields = []EmbedField{{Name: "Error", Value: err.Error(), Inline: true}} + return respond(s, i, data) + } + data.Fields = []EmbedField{{Name: "Status", Value: "✅ Gameserver recieved command", Inline: true}} + } + + if err := respond(s, i, data); err != nil { + return err + } + return nil +} diff --git a/src/discordbot/registerSlashcommands.go b/src/discordbot/registerSlashcommands.go index 285c4f5f..8756d3ce 100644 --- a/src/discordbot/registerSlashcommands.go +++ b/src/discordbot/registerSlashcommands.go @@ -32,6 +32,18 @@ func registerSlashCommands(s *discordgo.Session) { Name: "update", Description: "Update the gameserver via SteamCMD. Feedback will take a while, please be patient.", }, + { + Name: "command", + Description: "send a console command to the gameserver via SSCM", + Options: []*discordgo.ApplicationCommandOption{ + { + Type: discordgo.ApplicationCommandOptionString, + Name: "command", + Description: "Console Command to send to the gameserver. Has NO command syntax validation!", + Required: true, + }, + }, + }, { Name: "restore", Description: "Restore a backup at the specified index", From 1ecb0c1d9513908daabaf378c92d1bbb42578fc4 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 15:23:22 +0200 Subject: [PATCH 4/8] removed unused config.CustomDetection struct (spotted by @mitoskalandiel) --- src/config/config.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/config/config.go b/src/config/config.go index 0a84dd8c..a6fcccd6 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -78,14 +78,6 @@ type JsonConfig struct { SSUIWebPort string `json:"SSUIWebPort"` } -type CustomDetection struct { - ID string `json:"id"` - Type string `json:"type"` - Pattern string `json:"pattern"` - EventType string `json:"eventType"` - Message string `json:"message"` -} - // LoadConfig loads and initializes the configuration func LoadConfig() (*JsonConfig, error) { ConfigMu.Lock() From 979285e04cb36f20e69da1908e26f45f0032987f Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:20:47 +0200 Subject: [PATCH 5/8] added some missing translations --- UIMod/onboard_bundled/localization/de-DE.json | 11 +++++++---- UIMod/onboard_bundled/localization/sv-SE.json | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/UIMod/onboard_bundled/localization/de-DE.json b/UIMod/onboard_bundled/localization/de-DE.json index 2c992566..311c62dd 100644 --- a/UIMod/onboard_bundled/localization/de-DE.json +++ b/UIMod/onboard_bundled/localization/de-DE.json @@ -7,7 +7,9 @@ "UIText_Update_SteamCMD": "Server Updaten", "UIText_Console": "Konsole", "UIText_Detection_Events": "Ereignisse", + "UIText_Backend_Log": "Backend Konsole", "UIText_Backup_Manager": "Spielstands-Manager", + "UIText_Connected_PlayersHeader": "Verbundene Spieler", "UIText_Discord_Info": "Tritt dem Discord bei und hilf uns SSUI besser zu machen oder Support anzufragen!", "UIText_API_Info": "API-Endpunktdokumentation", "UIText_Copyright": "Urheberrecht", @@ -284,6 +286,7 @@ "UIText_Finalize_SubmitButton": "Zurück zum Start", "UIText_Finalize_SkipButton": "Authentifizierung Überspringen", "UIText_Login_Title": "Stationeers Server UI", + "UIText_Login_HeaderTitle": "Login", "UIText_Login_PrimaryLabel": "Benutzername", "UIText_Login_SecondaryLabel": "Passwort", "UIText_Login_PrimaryPlaceholder": "Benutzername eingeben", @@ -298,10 +301,10 @@ } }, "BackendText": { - "top1": {}, - "nest1": { - "nestINnest1": {}, - "nestINnest2": {} + "gamemgr": { + "BackendText_ServerStarted": "Server gestartet.", + "BackendText_ServerNotRunningOrAlreadyStopped": "Server war nicht gestartet oder wurde bereits gestoppt", + "BackendText_ServerStopped": "Server gestoppt." } } } \ No newline at end of file diff --git a/UIMod/onboard_bundled/localization/sv-SE.json b/UIMod/onboard_bundled/localization/sv-SE.json index 1baf27f8..8ec17c98 100644 --- a/UIMod/onboard_bundled/localization/sv-SE.json +++ b/UIMod/onboard_bundled/localization/sv-SE.json @@ -7,7 +7,9 @@ "UIText_Update_SteamCMD": "Uppdatera server", "UIText_Console": "Konsol", "UIText_Detection_Events": "Detekteringshändelser", + "UIText_Backend_Log": "Backend Konsol", "UIText_Backup_Manager": "Backup-hanterare", + "UIText_Connected_PlayersHeader": "Konnekterade spelare", "UIText_Discord_Info": "Gå med i Discord och hjälp till att förbättra SSUI eller få support!", "UIText_API_Info": "API-slutpunktsreferens", "UIText_Copyright": "Upphovsrätt", @@ -284,6 +286,7 @@ "UIText_Finalize_SubmitButton": "Gå tillbaka till start", "UIText_Finalize_SkipButton": "Hoppa över autentisering", "UIText_Login_Title": "Stationeers Server UI", + "UIText_Login_HeaderTitle": "Logga in", "UIText_Login_PrimaryLabel": "Användarnamn", "UIText_Login_SecondaryLabel": "Lösenord", "UIText_Login_PrimaryPlaceholder": "Ange användarnamn", @@ -298,10 +301,10 @@ } }, "BackendText": { - "top1": {}, - "nest1": { - "nestINnest1": {}, - "nestINnest2": {} + "gamemgr": { + "BackendText_ServerStarted": "Server startad.", + "BackendText_ServerNotRunningOrAlreadyStopped": "Servern kördes inte eller var redan stoppad", + "BackendText_ServerStopped": "Server stoppad." } } } \ No newline at end of file From cdb059635e5525840162feca6cda1bd260918a24 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:21:37 +0200 Subject: [PATCH 6/8] added a small helper ui to identify missing translations --- build/loc-ui.go | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 build/loc-ui.go diff --git a/build/loc-ui.go b/build/loc-ui.go new file mode 100644 index 00000000..064e2153 --- /dev/null +++ b/build/loc-ui.go @@ -0,0 +1,146 @@ +package main + +import ( + "encoding/json" + "fmt" + "html/template" + "log" + "net/http" + "os" + "path/filepath" +) + +type Translation struct { + Key string + Value string +} + +type LanguageData struct { + Language string + MissingKeys []Translation +} + +func flattenJSON(prefix string, data map[string]interface{}, result map[string]string, orderedKeys *[]string) { + for key, value := range data { + newKey := key + if prefix != "" { + newKey = prefix + "." + key + } + *orderedKeys = append(*orderedKeys, newKey) + switch v := value.(type) { + case map[string]interface{}: + flattenJSON(newKey, v, result, orderedKeys) + case string: + result[newKey] = v + } + } +} + +func loadJSONFile(filename string) (map[string]interface{}, map[string]string, []string, error) { + data, err := os.ReadFile(filename) + if err != nil { + if os.IsNotExist(err) { + return make(map[string]interface{}), make(map[string]string), []string{}, nil + } + return nil, nil, nil, err + } + var jsonData map[string]interface{} + if err := json.Unmarshal(data, &jsonData); err != nil { + return nil, nil, nil, err + } + flatData := make(map[string]string) + orderedKeys := []string{} + flattenJSON("", jsonData, flatData, &orderedKeys) + return jsonData, flatData, orderedKeys, nil +} + +func main() { + localizationDir := "./UIMod/onboard_bundled/localization/" + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // Load en-US.json + _, enFlat, enOrderedKeys, err := loadJSONFile(filepath.Join(localizationDir, "en-US.json")) + if err != nil { + http.Error(w, fmt.Sprintf("Error loading en-US.json: %v", err), http.StatusInternalServerError) + return + } + + // Load de-DE.json and sv-SE.json + languages := []string{"de-DE", "sv-SE"} + data := make([]LanguageData, 0, len(languages)) + for _, lang := range languages { + _, langFlat, _, err := loadJSONFile(filepath.Join(localizationDir, lang+".json")) + if err != nil { + http.Error(w, fmt.Sprintf("Error loading %s.json: %v", lang, err), http.StatusInternalServerError) + return + } + missing := []Translation{} + for _, key := range enOrderedKeys { + if _, exists := langFlat[key]; !exists { + if enVal, exists := enFlat[key]; exists { + missing = append(missing, Translation{Key: key, Value: enVal}) + } + } + } + data = append(data, LanguageData{ + Language: lang, + MissingKeys: missing, + }) + } + + // Parse and execute template + tmpl, err := template.New("index").Parse(` + + + + + + Translation Manager + + + +

Translation Manager - Missing Keys

+ {{range .}} +
+

{{.Language}}

+ {{if .MissingKeys}} + + + + + + {{range .MissingKeys}} + + + + + {{end}} +
Keyen-US Value
{{.Key}}{{.Value}}
+ {{else}} +

No missing translations for {{.Language}}.

+ {{end}} +
+ {{end}} + + +`) + if err != nil { + http.Error(w, fmt.Sprintf("Error parsing template: %v", err), http.StatusInternalServerError) + return + } + if err := tmpl.Execute(w, data); err != nil { + http.Error(w, fmt.Sprintf("Error executing template: %v", err), http.StatusInternalServerError) + } + }) + + fmt.Println("Server starting on http://localhost:8080") + log.Fatal(http.ListenAndServe(":8080", nil)) +} From c8346eb2c289ae7a157827a58b4faf63ee92903d Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:29:59 +0200 Subject: [PATCH 7/8] added 30 more seconds of warn messages to AutoRestart (requested by @NAM) --- src/managers/gamemgr/autorestart.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/managers/gamemgr/autorestart.go b/src/managers/gamemgr/autorestart.go index d1b1725a..3bec7653 100644 --- a/src/managers/gamemgr/autorestart.go +++ b/src/managers/gamemgr/autorestart.go @@ -57,6 +57,12 @@ func startAutoRestart(schedule string, done chan struct{}) { mu.Unlock() if config.GetIsSSCMEnabled() { + commandmgr.WriteCommand("say Attention, server is restarting in 60 seconds!") + time.Sleep(10 * time.Second) + commandmgr.WriteCommand("say Attention, server is restarting in 50 seconds!") + time.Sleep(10 * time.Second) + commandmgr.WriteCommand("say Attention, server is restarting in 40 seconds!") + time.Sleep(10 * time.Second) commandmgr.WriteCommand("say Attention, server is restarting in 30 seconds!") time.Sleep(10 * time.Second) commandmgr.WriteCommand("say Attention, server is restarting in 20 seconds!") From 8e6c5571b54155fe242562b28591c03d4c68b826 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Tue, 9 Sep 2025 18:49:33 +0200 Subject: [PATCH 8/8] added language swtichers to setup and config page optimized banner image to use webp --- UIMod/onboard_bundled/assets/apiinfo.html | 2 +- UIMod/onboard_bundled/assets/css/flags.css | 56 ++++++++++++++++++ UIMod/onboard_bundled/assets/flags/de.webp | Bin 0 -> 732 bytes UIMod/onboard_bundled/assets/flags/en.webp | Bin 0 -> 1596 bytes UIMod/onboard_bundled/assets/flags/sv.webp | Bin 0 -> 956 bytes UIMod/onboard_bundled/assets/js/main.js | 23 +++++++ UIMod/onboard_bundled/assets/stationeers.png | Bin 52205 -> 0 bytes UIMod/onboard_bundled/assets/stationeers.webp | Bin 0 -> 5716 bytes .../detectionmanager/detectionmanager.html | 2 +- .../twoboxform/twoboxform.html | 20 ++++++- .../onboard_bundled/twoboxform/twoboxform.js | 28 +++++++++ UIMod/onboard_bundled/ui/config.html | 8 ++- UIMod/onboard_bundled/ui/index.html | 2 +- 13 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 UIMod/onboard_bundled/assets/css/flags.css create mode 100644 UIMod/onboard_bundled/assets/flags/de.webp create mode 100644 UIMod/onboard_bundled/assets/flags/en.webp create mode 100644 UIMod/onboard_bundled/assets/flags/sv.webp delete mode 100644 UIMod/onboard_bundled/assets/stationeers.png create mode 100644 UIMod/onboard_bundled/assets/stationeers.webp diff --git a/UIMod/onboard_bundled/assets/apiinfo.html b/UIMod/onboard_bundled/assets/apiinfo.html index 36d9e1e7..fdcdf826 100644 --- a/UIMod/onboard_bundled/assets/apiinfo.html +++ b/UIMod/onboard_bundled/assets/apiinfo.html @@ -16,7 +16,7 @@
- +

About the Server API (Incomplete)

diff --git a/UIMod/onboard_bundled/assets/css/flags.css b/UIMod/onboard_bundled/assets/css/flags.css new file mode 100644 index 00000000..ca7807f6 --- /dev/null +++ b/UIMod/onboard_bundled/assets/css/flags.css @@ -0,0 +1,56 @@ + +#language-flags { + position: absolute; + top: 15px; + right: 10px; + display: flex; + gap: 10px; +} + +#welcome-flags { + display: flex; + gap: 10px; + justify-content: space-evenly; + margin-top: 15px +} + +#language-flags img, #welcome-flags img{ + width: 30px; + height: 20px; + cursor: pointer; + transition: transform 0.5s ease; +} + +#language-flags img { + opacity: 0.7; +} + +#language-flags img:hover, #welcome-flags img:hover { + scale: 1.1; + animation: wave 3s infinite; + opacity: 1; +} + +@keyframes wave { + 0% { + transform: perspective(200px) rotateY(0deg) scaleX(1); + } + 25% { + transform: perspective(200px) rotateY(10deg) scaleX(0.95); + } + 50% { + transform: perspective(200px) rotateY(0deg) scaleX(1); + } + 75% { + transform: perspective(200px) rotateY(-10deg) scaleX(0.95); + } + 100% { + transform: perspective(200px) rotateY(0deg) scaleX(1); + } +} + +@media (max-width: 767px) { + #language-flags, #welcome-flags { + display: none; + } +} \ No newline at end of file diff --git a/UIMod/onboard_bundled/assets/flags/de.webp b/UIMod/onboard_bundled/assets/flags/de.webp new file mode 100644 index 0000000000000000000000000000000000000000..7ebd48e18b8e8d784d1905defae46c8b99efec07 GIT binary patch literal 732 zcmV<20weuWNk&H00ssJ4MM6+kP&il$0000G0000#001ih06|PpNZ9}Y00Dp-0f3@t z2ZxZ5xeyDfz}+Qst-xIxV2FqqVwdm=c=!JjY~yzqTz3ojiHHfHEOL#-=E3#z@96g# zUXk^rl~2JJ0CD+jG}-+9s1^`X0FJJM3Br3aE9IbKOpt#cRh>M_)`>hsw-gTZMuGx1 zq)C!HqY2i}XWdHFXVogT_DH^Q@H+Wd;OjvnAF*qdTB|Qw>7G5~HQGr^Xp~I}V}1xR zfq4RKo#(6`eWPPg5Obti@*c&33*bl*25Lv|TNs^{#QJXA)z|Cm;jIu32Xqt5CDa5zi9*tI$U0RH}l?YFq3j&_HqOVtr)?F`{#{H{ActLLZ;)cc#z z@<(okh&ADzw<)uoA8!}4^okBcvrM>H`KJ;@a8WuC)0k0bkU&&Hzs-Hth*Q1B*{_F1 z*(rYSI&TSO(hIcz4(#Q%eI!bw!TX)n8c9q-xqagtWQ(xUuc7b#qe)WKp_;TBeo>Zr%{$@E7lu*`CDVkU_P69 z5!3EgL9PI{yiHA^f~1Rk#TkQ9XVta9*5U5RS+U`aM!If}n+_nUK-j_o;*NR^{2$d+ z#U0LWa2q)nnZHS&8W1Itd-b2~lypH%8$J6pIWlc}@d&!O-Rk(X#+3gXxm9ejF^^yf zXRaYsI`kvTe+@DUGYh`h`2B>xaA?^4;v)1+h}>?s+yBPK2fi^8XhUJbeaFFb4H4V_ O&cwFjqsZ{HDI@@*U|)~` literal 0 HcmV?d00001 diff --git a/UIMod/onboard_bundled/assets/flags/en.webp b/UIMod/onboard_bundled/assets/flags/en.webp new file mode 100644 index 0000000000000000000000000000000000000000..be397edfe610e65588cbf1b2b44bc19e27ad6d88 GIT binary patch literal 1596 zcmV-C2E+MMNk&FA1^@t8MM6+kP&il$0000G0000#001Tc06|PpNZtSd00Dp-+qUZF z&iN3FBgL!&m{kQsFJN0#gqbT~$BHzH&CJXeL=R%mM1+~PZQ`#4HViZdU!k$yJ%0Qi zd_SM}x2CI=uni;%47ugo0gKCxR?edmK)n0>`+&#mUMJ%KpX5M*`;A7%rxOc3+Snfm z^VwUjR?;4e3L-$a`*V{U&jTr*uP?7(2mjQ(USD3zy2TrlIlo;8Ku|57bfvo7`xMuH zBdUXi?#nbb?nRUY*IxujrnC3T)%!dNpn7txjZ3C(mvaUJ5yb4aaHTrE)jxm!9(+F@ zch?&QA3y|FP&gnk1pojL766?ADnI}y06vj6mq(?dq9HIEs;ICM32XqTM)r+Qwcdu= zzwaKPIi>%E{dD&M;z9aX@2jRY&yDQq`tSQQ?CEn8z@Hpmsf^vi^sD{@z`uQ;%=sDJ zSmXcBzruI!|5fM*gO3TH&<`&{(0v!@)95ezKH`6@yY!-4~33DhA(^TOqtlSl9S zprp5NfaMo0INv}JZRNfjf2Dj209|~+DN?Io*^GIx0P6&005iRn#cUaX0RHLL&Za%JXJ;`<|$0oR0XJE1ZS$$5-PGN(l z!}W8r{n=3f>1h+imVww}j)b?ctkjGoL?S9{>fZRXCkhxtc9`e5v$b>AmG%Uihh&z2 zxz&A%t41TWnnT`}kl%4eUOHN07jr*=oYA+t_WzDnG>jpp5+nl0`hr8>kVkEw#MUH7p>}@)iyg8<%(WMrF@W|h6 zI0JtK#NQh6_vnz+kgPS|XSpvVtZqPsa_8s{mgMyxPBaG5qvFqDcb45EveWb$X8OsCW1G|8uA9MDJx^{IK}*fOZ2M zwNJS(wyNzdqOZ{q$801;hF!?IZlku7)<`jehe?4mG9Ye|HxOetLe98$PKK1}BBltO zibrLy>56y`OCNJNjwy(AM%EvsUTA*z#d;r7vF% zPkVpN{Oh))?w;D>@lZcgl6chjJm zxiWC<5l5I?R$Kpr5#NK7We)ay(iM&J9@gCM~ynR(yND{gztQq^$qSDdo zj0OSRruu@Z;N8Iv=lU=I#P8JKyG1Atv6)HixNthJWgtGD#^3zjP8Ai$7stw=a)qoV uUvtbgT7Sbp{Bb3Mw7D3-!;d5eYf|Mb8sAj0zHjjM$p9aw|LV6NZ~y>={Ua;@ literal 0 HcmV?d00001 diff --git a/UIMod/onboard_bundled/assets/flags/sv.webp b/UIMod/onboard_bundled/assets/flags/sv.webp new file mode 100644 index 0000000000000000000000000000000000000000..df0dcffbb28d95393dbd07d6680759ad2d4f8a64 GIT binary patch literal 956 zcmV;t14H~$Nk&Gr0{{S5MM6+kP&il$0000G0000#001oj06|PpNY?-W00DqHZNIAM z%r|F9?k6Qm3r1OifYQ6e% zQ(9jek61yt1s`K+sJ9ePm|+ zjgRv*B_oF?BVDlrbEjA+GpH5?cHP>*8FR2*}Y5 z09H^qAhrSk0MHQtodGI904@MNkvf)0C8HuCEmm!?uo4Mu0G&B_+P(q&&+)_9?x6ka z@1{{7Mn8)Ds{Vo6JH&6y1J!?+57V#N4}bqaAM|}dKk@oT|7qU9_B;K({hjuR%sGAp z;tJe+0IC@kv-GW{+Opo!dcPjSww*1%`;KCC{@QU%XC#TSDCU>zoZ9z~b;V3zl;hIW z=?ln!0RFS;T@Ov6K~=Da{IwUq4OIZlA|KIu3sv&4@qqDwYa_n`fAmP|q5T1m@T`CB zB;K^}#2&wsgQF(=4IUVS)y}FU?!o1zumA0xs?Ff-oC{B7r4Rhs7wbmb(b96)(oL^9 zC<-z{-yulm4Eatwin8J+{u;S<;NQQ^wrIF}PDZd@QAW9$4e*CrLDQr7uHl#L#Q-a- zyd&YE{}8GW>EEW92iZ)usLrGCFLCVN_Tg@b2}B1R`6932Io_+<)t7>{6nCWG&Ho{w zhxCo);i?Yzu}I}Z6e9W;Dv^s@cqX%--s5%fTOHMG&MXIS?Mc-9?p+&~FII?M$GjYQ z`CK^1enJ*E%lHs-qFm+3{+Ud-I<35=z({k^gp(NN>XZ%$-l@KZb$jgVEAu!m->0v) z_mtQ10D8$YY47k^oVM!S;aw8{83Q1IqloHhbcUKfsV2XIZALuJ7%T;S0}8HdB_Div z5SL=n=!4|M?4r=+dsmZg5|;OcI0=VU;mkXPuM#R ef7W`K8HbSaLr-3L`TKTaK94{=f6GCtfB*nn#^fLX literal 0 HcmV?d00001 diff --git a/UIMod/onboard_bundled/assets/js/main.js b/UIMod/onboard_bundled/assets/js/main.js index 2726a9dc..ab8acda6 100644 --- a/UIMod/onboard_bundled/assets/js/main.js +++ b/UIMod/onboard_bundled/assets/js/main.js @@ -35,6 +35,29 @@ document.addEventListener('DOMContentLoaded', () => { } console.warn("If you see errors for sscm.js or sscm.css, you may want to enable SSCM."); } + // Language flag selection + const languageFlags = document.querySelectorAll('#language-flags img'); + languageFlags.forEach(flag => { + flag.addEventListener('click', async () => { + const lang = flag.dataset.lang; + try { + const response = await fetch('/api/v2/saveconfig', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ LanguageSetting: lang }) + }); + const data = await response.json(); + if (response.ok) { + window.location.reload(); + } else { + console.error(data.error); + } + } catch (error) { + console.error('Language setting error:', error); + } + + }); + }); }); // Global references to EventSource objects diff --git a/UIMod/onboard_bundled/assets/stationeers.png b/UIMod/onboard_bundled/assets/stationeers.png deleted file mode 100644 index c3153afa1365cb172313a862e663aa0c8eb87f81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52205 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 g#i(urNksJj04ldE##nP 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
- +

Custom Detection Manager

diff --git a/UIMod/onboard_bundled/twoboxform/twoboxform.html b/UIMod/onboard_bundled/twoboxform/twoboxform.html index df6ba9ed..abd09bc1 100644 --- a/UIMod/onboard_bundled/twoboxform/twoboxform.html +++ b/UIMod/onboard_bundled/twoboxform/twoboxform.html @@ -6,6 +6,7 @@ {{.Title}} +
@@ -19,7 +20,13 @@

Preparing...

Preparing {{.Title}}

- + {{if ne .Step "welcome"}} +
+ English + German + Swedish +
+ {{end}}

{{.Title}}

@@ -32,7 +39,7 @@

{{.HeaderTitle}}

{{.StepMessage}}

{{end}} - + {{if eq .Step "finalize"}}
@@ -88,6 +95,15 @@

{{.HeaderTitle}}

+ + {{if eq .Step "welcome"}} +
+ English + German + Swedish +
+ {{end}} +
diff --git a/UIMod/onboard_bundled/twoboxform/twoboxform.js b/UIMod/onboard_bundled/twoboxform/twoboxform.js index 1de9baa1..d329e72b 100644 --- a/UIMod/onboard_bundled/twoboxform/twoboxform.js +++ b/UIMod/onboard_bundled/twoboxform/twoboxform.js @@ -255,4 +255,32 @@ document.addEventListener('DOMContentLoaded', () => { } } }); + + // Language flag selection + const languageFlags = document.querySelectorAll('#language-flags img, #welcome-flags img'); + languageFlags.forEach(flag => { + flag.addEventListener('click', async () => { + const lang = flag.dataset.lang; + try { + showPreloader(); + const response = await fetch('/api/v2/saveconfig', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ LanguageSetting: lang }) + }); + const data = await response.json(); + if (response.ok) { + showNotification(`Language set to ${lang}`, 'success'); + } else { + showNotification(data.error || 'Failed to set language', 'error'); + } + } catch (error) { + console.error('Language setting error:', error); + showNotification('Error setting language!', 'error'); + } finally { + hidePreloader(); + } + window.location.reload(); + }); + }); }); \ No newline at end of file diff --git a/UIMod/onboard_bundled/ui/config.html b/UIMod/onboard_bundled/ui/config.html index 8367bf57..3a36a9f3 100644 --- a/UIMod/onboard_bundled/ui/config.html +++ b/UIMod/onboard_bundled/ui/config.html @@ -12,13 +12,19 @@ +
- + +
+ English + German + Swedish +

{{.UIText_ServerConfig}}

diff --git a/UIMod/onboard_bundled/ui/index.html b/UIMod/onboard_bundled/ui/index.html index 75c0e631..0a753410 100644 --- a/UIMod/onboard_bundled/ui/index.html +++ b/UIMod/onboard_bundled/ui/index.html @@ -29,7 +29,7 @@

- +