version.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package config
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "goseg/defaults"
  6. "goseg/structs"
  7. "io/ioutil"
  8. "net/http"
  9. "os"
  10. "path/filepath"
  11. "time"
  12. )
  13. var (
  14. VersionServerReady = false
  15. VersionInfo structs.Channel
  16. )
  17. // check the version server and return struct
  18. func CheckVersion() (structs.Channel, bool) {
  19. versMutex.Lock()
  20. defer versMutex.Unlock()
  21. conf := Conf()
  22. releaseChannel := conf.UpdateBranch
  23. const retries = 10
  24. const delay = time.Second
  25. url := globalConfig.UpdateUrl
  26. var fetchedVersion structs.Version
  27. for i := 0; i < retries; i++ {
  28. req, err := http.NewRequest("GET", url, nil)
  29. if err != nil {
  30. }
  31. userAgent := "NativePlanet.GroundSeg-" + conf.GsVersion
  32. req.Header.Set("User-Agent", userAgent)
  33. resp, err := http.DefaultClient.Do(req)
  34. if err != nil {
  35. errmsg := fmt.Sprintf("Unable to connect to update server: %v", err)
  36. Logger.Warn(errmsg)
  37. if i < retries-1 {
  38. time.Sleep(delay)
  39. continue
  40. } else {
  41. VersionServerReady = false
  42. return VersionInfo, false
  43. }
  44. }
  45. // read the body bytes
  46. body, err := ioutil.ReadAll(resp.Body)
  47. resp.Body.Close()
  48. if err != nil {
  49. errmsg := fmt.Sprintf("Error reading version info: %v", err)
  50. Logger.Warn(errmsg)
  51. if i < retries-1 {
  52. time.Sleep(delay)
  53. continue
  54. } else {
  55. VersionServerReady = false
  56. return VersionInfo, false
  57. }
  58. }
  59. // unmarshal values into Version struct
  60. err = json.Unmarshal(body, &fetchedVersion)
  61. if err != nil {
  62. errmsg := fmt.Sprintf("Error unmarshalling JSON: %v", err)
  63. Logger.Warn(errmsg)
  64. if i < retries-1 {
  65. time.Sleep(delay)
  66. continue
  67. } else {
  68. VersionServerReady = false
  69. return VersionInfo, false
  70. }
  71. }
  72. VersionInfo = fetchedVersion.Groundseg[releaseChannel]
  73. // debug: re-marshal and write the entire fetched version to disk
  74. confPath := filepath.Join(BasePath, "settings", "version_info.json")
  75. file, err := os.Create(confPath)
  76. if err != nil {
  77. errmsg := fmt.Sprintf("Failed to create file: %v", err)
  78. Logger.Error(errmsg)
  79. VersionServerReady = false
  80. return VersionInfo, false
  81. }
  82. defer file.Close()
  83. encoder := json.NewEncoder(file)
  84. encoder.SetIndent("", " ")
  85. if err := encoder.Encode(&fetchedVersion); err != nil {
  86. errmsg := fmt.Sprintf("Failed to write JSON: %v", err)
  87. Logger.Error(errmsg)
  88. }
  89. VersionServerReady = true
  90. return VersionInfo, true
  91. }
  92. VersionServerReady = false
  93. return VersionInfo, false
  94. }
  95. func CheckVersionLoop() {
  96. ticker := time.NewTicker(checkInterval)
  97. conf := Conf()
  98. releaseChannel := conf.UpdateBranch
  99. for {
  100. select {
  101. case <-ticker.C:
  102. latestVersion, _ := CheckVersion()
  103. currentChannelVersion := VersionInfo
  104. latestChannelVersion := latestVersion
  105. if latestChannelVersion != currentChannelVersion {
  106. fmt.Printf("New version available in %s channel! Current: %+v, Latest: %+v\n", releaseChannel, currentChannelVersion, latestChannelVersion)
  107. VersionInfo = latestVersion
  108. // Handle the update logic here
  109. }
  110. }
  111. }
  112. }
  113. // write the defaults.VersionInfo value to disk
  114. func CreateDefaultVersion() error {
  115. var versionInfo structs.Version
  116. err := json.Unmarshal([]byte(defaults.DefaultVersionText), &versionInfo)
  117. if err != nil {
  118. return err
  119. }
  120. prettyJSON, err := json.MarshalIndent(versionInfo, "", " ")
  121. if err != nil {
  122. return err
  123. }
  124. filePath := filepath.Join(BasePath, "settings", "version_info.json")
  125. err = ioutil.WriteFile(filePath, prettyJSON, 0644)
  126. if err != nil {
  127. return err
  128. }
  129. return nil
  130. }
  131. // return the existing local version info or create default
  132. func LocalVersion() structs.Version {
  133. confPath := filepath.Join(BasePath, "settings", "version_info.json")
  134. _, err := os.Open(confPath)
  135. if err != nil {
  136. // create a default if it doesn't exist
  137. err = CreateDefaultVersion()
  138. if err != nil {
  139. // panic if we can't create it
  140. errmsg := fmt.Sprintf("Unable to write version info! %v", err)
  141. Logger.Error(errmsg)
  142. panic(errmsg)
  143. }
  144. }
  145. file, err := ioutil.ReadFile(confPath)
  146. if err != nil {
  147. errmsg := fmt.Sprintf("Unable to load version info: %v", err)
  148. panic(errmsg)
  149. }
  150. var versionStruct structs.Version
  151. if err := json.Unmarshal(file, &versionStruct); err != nil {
  152. errmsg := fmt.Sprintf("Error decoding version JSON: %v", err)
  153. panic(errmsg)
  154. }
  155. return versionStruct
  156. }