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 00000000..7ebd48e1 Binary files /dev/null and b/UIMod/onboard_bundled/assets/flags/de.webp differ diff --git a/UIMod/onboard_bundled/assets/flags/en.webp b/UIMod/onboard_bundled/assets/flags/en.webp new file mode 100644 index 00000000..be397edf Binary files /dev/null and b/UIMod/onboard_bundled/assets/flags/en.webp differ diff --git a/UIMod/onboard_bundled/assets/flags/sv.webp b/UIMod/onboard_bundled/assets/flags/sv.webp new file mode 100644 index 00000000..df0dcffb Binary files /dev/null and b/UIMod/onboard_bundled/assets/flags/sv.webp differ 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 c3153afa..00000000 Binary files a/UIMod/onboard_bundled/assets/stationeers.png and /dev/null differ diff --git a/UIMod/onboard_bundled/assets/stationeers.webp b/UIMod/onboard_bundled/assets/stationeers.webp new file mode 100644 index 00000000..c3aa78f3 Binary files /dev/null and b/UIMod/onboard_bundled/assets/stationeers.webp differ diff --git a/UIMod/onboard_bundled/detectionmanager/detectionmanager.html b/UIMod/onboard_bundled/detectionmanager/detectionmanager.html index f848d514..e298d02e 100644 --- a/UIMod/onboard_bundled/detectionmanager/detectionmanager.html +++ b/UIMod/onboard_bundled/detectionmanager/detectionmanager.html @@ -17,7 +17,7 @@
- +

Custom Detection Manager

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 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 @@

- + 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)) +} 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() 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/handleSlashcommands.go b/src/discordbot/handleSlashcommands.go index 5cf8b80e..fd110b89 100644 --- a/src/discordbot/handleSlashcommands.go +++ b/src/discordbot/handleSlashcommands.go @@ -10,7 +10,9 @@ 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" "github.com/bwmarrin/discordgo" ) @@ -27,6 +29,8 @@ var handlers = map[string]commandHandler{ "list": handleList, "bansteamid": handleBan, "unbansteamid": handleUnban, + "update": handleUpdate, + "command": handleCommand, } // Check channel and handle initial validation @@ -92,6 +96,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 +127,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) } @@ -210,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/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 { diff --git a/src/discordbot/registerSlashcommands.go b/src/discordbot/registerSlashcommands.go index f4db1d36..8756d3ce 100644 --- a/src/discordbot/registerSlashcommands.go +++ b/src/discordbot/registerSlashcommands.go @@ -28,6 +28,22 @@ 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: "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", 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!")