@@ -21,6 +21,8 @@ import (
2121
2222// --- Constants ---
2323const (
24+ currentVersion = "v1.5.1"
25+
2426 // API Configuration
2527 epicAPIURL = "https://account-public-service-prod.ak.epicgames.com/account/api"
2628 epicLauncherAuth = "basic MzRhMDJjZjhmNDQxNGUyOWIxNTkyMTg3NmRhMzZmOWE6ZGFhZmJjY2M3Mzc3NDUwMzlkZmZlNTNkOTRmYzc2Y2Y="
@@ -43,6 +45,7 @@ type Config struct {
4345 BakkesModPath string `json:"bakkesmod_path,omitempty"`
4446 BakkesModLaunchDelay int `json:"bakkesmod_launch_delay,omitempty"`
4547 BakkesModSetupDeclined bool `json:"bakkesmod_setup_declined"` // No omitempty, so it defaults to false
48+ LastNotifiedVersion string `json:"last_notified_version,omitempty"`
4649}
4750
4851// LaunchCredentials holds the final codes needed to start the game.
@@ -131,6 +134,96 @@ func main() {
131134 }
132135
133136 log .Println ("Game process started successfully." )
137+
138+ // 5. Check for updates in the background.
139+ // Pass a pointer to cfg so the goroutine can modify it
140+ go checkForUpdates (& cfg )
141+
142+ }
143+
144+ // --- Update Checker ---
145+
146+ // GitHubRelease represents the structure of a release from the GitHub API.
147+ type GitHubRelease struct {
148+ TagName string `json:"tag_name"`
149+ }
150+
151+ // isNewerVersion compares two version strings (e.g., "v1.5.1", "v1.6.0").
152+ // It returns true if the latest version is newer than the current version.
153+ func isNewerVersion (current , latest string ) bool {
154+ // Simple string comparison works for "vX.Y.Z" format
155+ return strings .TrimPrefix (latest , "v" ) > strings .TrimPrefix (current , "v" )
156+ }
157+
158+ // checkForUpdates fetches the latest release from GitHub and notifies the user if it's a new version.
159+ // It runs in a goroutine to avoid blocking the main application flow.
160+ func checkForUpdates (cfg * Config ) {
161+ log .Println ("Checking for application updates..." )
162+ // Use a longer timeout for the update check
163+ client := & http.Client {Timeout : 10 * time .Second }
164+ resp , err := client .Get ("https://api.github.com/repos/jun-eau/Slipstream/releases/latest" )
165+ if err != nil {
166+ log .Printf ("Update check failed (network error): %v" , err )
167+ return
168+ }
169+ defer resp .Body .Close ()
170+
171+ if resp .StatusCode != http .StatusOK {
172+ log .Printf ("Update check failed (status code: %d)" , resp .StatusCode )
173+ return
174+ }
175+
176+ var release GitHubRelease
177+ if err := json .NewDecoder (resp .Body ).Decode (& release ); err != nil {
178+ log .Printf ("Update check failed (JSON parsing error): %v" , err )
179+ return
180+ }
181+
182+ latestVersion := release .TagName
183+ log .Printf ("Current version: %s, Latest version: %s" , currentVersion , latestVersion )
184+
185+ if isNewerVersion (currentVersion , latestVersion ) {
186+ log .Printf ("A new version is available: %s" , latestVersion )
187+ // Check if we've already notified the user about this specific version
188+ if cfg .LastNotifiedVersion != latestVersion {
189+ log .Println ("Notifying user about the new version." )
190+ // Use a separate function to show the dialog to keep this clean
191+ showUpdateNotification (latestVersion )
192+
193+ // Update the config and save it
194+ cfg .LastNotifiedVersion = latestVersion
195+ if err := saveConfig (* cfg ); err != nil {
196+ log .Printf ("Warning: failed to save last notified version: %v" , err )
197+ }
198+ } else {
199+ log .Printf ("Already notified user about version %s. Skipping." , latestVersion )
200+ }
201+ } else {
202+ log .Println ("Application is up to date." )
203+ }
204+ }
205+
206+ // showUpdateNotification displays the update dialog to the user.
207+ func showUpdateNotification (version string ) {
208+ message := fmt .Sprintf (
209+ "A new version of Slipstream is available!\n \n " +
210+ "You are on version: %s\n " +
211+ "The latest version is: %s\n \n " +
212+ "You can download the new version from the releases page." ,
213+ currentVersion , version ,
214+ )
215+ // We use a goroutine for the dialog itself to prevent any potential blocking
216+ // on the main update goroutine, although it's generally not an issue with zenity.
217+ go func () {
218+ err := zenity .Info (message ,
219+ zenity .Title ("Update Available" ),
220+ zenity .ExtraButton ("Open Download Page" ),
221+ zenity .InfoIcon ,
222+ )
223+ if err == zenity .ErrExtraButton {
224+ openBrowser ("https://github.com/jun-eau/Slipstream/releases/latest" )
225+ }
226+ }()
134227}
135228
136229// --- Core Functions ---
0 commit comments