You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
8.2 KiB

  1. using IllusionInjector.Logging;
  2. using SimpleJSON;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Collections;
  6. using System.Diagnostics;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Runtime.Serialization;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using UnityEngine.Networking;
  13. using UnityEngine;
  14. using IllusionPlugin;
  15. using System.Text.RegularExpressions;
  16. using Logger = IllusionInjector.Logging.Logger;
  17. namespace IllusionInjector.Updating
  18. {
  19. #if OLD_UPDATER
  20. class ModUpdater : MonoBehaviour
  21. {
  22. public ModUpdater instance;
  23. public void Awake()
  24. {
  25. instance = this;
  26. CheckForUpdates();
  27. }
  28. public void CheckForUpdates()
  29. {
  30. StartCoroutine(CheckForUpdatesCoroutine());
  31. }
  32. struct UpdateCheckQueueItem
  33. {
  34. public PluginManager.BSPluginMeta Plugin;
  35. public Uri UpdateUri;
  36. public string Name;
  37. }
  38. struct UpdateQueueItem
  39. {
  40. public PluginManager.BSPluginMeta Plugin;
  41. public Uri DownloadUri;
  42. public string Name;
  43. public Version NewVersion;
  44. }
  45. private Regex commentRegex = new Regex(@"(?: \/\/.+)?$", RegexOptions.Compiled | RegexOptions.Multiline);
  46. private Dictionary<Uri, UpdateScript> cachedRequests = new Dictionary<Uri, UpdateScript>();
  47. IEnumerator CheckForUpdatesCoroutine()
  48. {
  49. Logger.log.Info("Checking for mod updates...");
  50. var toUpdate = new List<UpdateQueueItem>();
  51. var plugins = new Queue<UpdateCheckQueueItem>(PluginManager.BSMetas.Select(p => new UpdateCheckQueueItem { Plugin = p, UpdateUri = p.Plugin.UpdateUri, Name = p.Plugin.Name }));
  52. for (; plugins.Count > 0;)
  53. {
  54. var plugin = plugins.Dequeue();
  55. Logger.log.Debug($"Checking for updates for {plugin.Name}");
  56. if (plugin.UpdateUri != null)
  57. {
  58. if (!cachedRequests.ContainsKey(plugin.UpdateUri))
  59. using (var request = UnityWebRequest.Get(plugin.UpdateUri))
  60. {
  61. yield return request.SendWebRequest();
  62. if (request.isNetworkError)
  63. {
  64. Logger.log.Error("Network error while trying to update mods");
  65. Logger.log.Error(request.error);
  66. break;
  67. }
  68. if (request.isHttpError)
  69. {
  70. Logger.log.Error($"Server returned an error code while trying to update mod {plugin.Name}");
  71. Logger.log.Error(request.error);
  72. }
  73. var json = request.downloadHandler.text;
  74. json = commentRegex.Replace(json, "");
  75. JSONObject obj = null;
  76. try
  77. {
  78. obj = JSON.Parse(json).AsObject;
  79. }
  80. catch (InvalidCastException)
  81. {
  82. Logger.log.Error($"Parse error while trying to update mod {plugin.Name}");
  83. Logger.log.Error($"Response doesn't seem to be a JSON object");
  84. continue;
  85. }
  86. catch (Exception e)
  87. {
  88. Logger.log.Error($"Parse error while trying to update mod {plugin.Name}");
  89. Logger.log.Error(e);
  90. continue;
  91. }
  92. UpdateScript ss;
  93. try
  94. {
  95. ss = UpdateScript.Parse(obj);
  96. }
  97. catch (Exception e)
  98. {
  99. Logger.log.Error($"Parse error while trying to update mod {plugin.Name}");
  100. Logger.log.Error($"Script at {plugin.UpdateUri} doesn't seem to be a valid update script");
  101. Logger.log.Debug(e);
  102. continue;
  103. }
  104. cachedRequests.Add(plugin.UpdateUri, ss);
  105. }
  106. var script = cachedRequests[plugin.UpdateUri];
  107. if (script.Info.TryGetValue(plugin.Name, out UpdateScript.PluginVersionInfo info))
  108. {
  109. Logger.log.Debug($"Checking version info for {plugin.Name} ({plugin.Plugin.Plugin.Name})");
  110. if (info.NewName != null || info.NewScript != null)
  111. plugins.Enqueue(new UpdateCheckQueueItem
  112. {
  113. Plugin = plugin.Plugin,
  114. Name = info.NewName ?? plugin.Name,
  115. UpdateUri = info.NewScript ?? plugin.UpdateUri
  116. });
  117. else
  118. {
  119. Logger.log.Debug($"New version: {info.Version}, Current version: {plugin.Plugin.Plugin.Version}");
  120. if (info.Version > plugin.Plugin.Plugin.Version)
  121. { // we should update plugin
  122. Logger.log.Debug($"Queueing update for {plugin.Name} ({plugin.Plugin.Plugin.Name})");
  123. toUpdate.Add(new UpdateQueueItem
  124. {
  125. Plugin = plugin.Plugin,
  126. DownloadUri = info.Download,
  127. Name = plugin.Name,
  128. NewVersion = info.Version
  129. });
  130. }
  131. }
  132. }
  133. else
  134. {
  135. Logger.log.Error($"Script defined for plugin {plugin.Name} doesn't define information for {plugin.Name}");
  136. continue;
  137. }
  138. }
  139. }
  140. Logger.log.Info($"{toUpdate.Count} mods need updating");
  141. if (toUpdate.Count == 0) yield break;
  142. string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + Path.GetRandomFileName());
  143. Directory.CreateDirectory(tempDirectory);
  144. Logger.log.Debug($"Created temp download dirtectory {tempDirectory}");
  145. foreach (var item in toUpdate)
  146. {
  147. StartCoroutine(DownloadPluginCoroutine(tempDirectory, item));
  148. }
  149. }
  150. IEnumerator DownloadPluginCoroutine(string tempdir, UpdateQueueItem item)
  151. {
  152. var file = Path.Combine(tempdir, item.Name + ".dll");
  153. using (var req = UnityWebRequest.Get(item.DownloadUri))
  154. {
  155. req.downloadHandler = new DownloadHandlerFile(file);
  156. yield return req.SendWebRequest();
  157. if (req.isNetworkError)
  158. {
  159. Logger.log.Error($"Network error while trying to download update for {item.Plugin.Plugin.Name}");
  160. Logger.log.Error(req.error);
  161. yield break;
  162. }
  163. if (req.isHttpError)
  164. {
  165. Logger.log.Error($"Server returned an error code while trying to download update for {item.Plugin.Plugin.Name}");
  166. Logger.log.Error(req.error);
  167. yield break;
  168. }
  169. }
  170. var pluginDir = Path.GetDirectoryName(item.Plugin.Filename);
  171. var newFile = Path.Combine(pluginDir, item.Name + ".dll");
  172. File.Delete(item.Plugin.Filename);
  173. if (File.Exists(newFile))
  174. File.Delete(newFile);
  175. File.Move(file, newFile);
  176. Logger.log.Info($"{item.Plugin.Plugin.Name} updated to {item.NewVersion}");
  177. }
  178. }
  179. #endif
  180. }