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.

98 lines
4.0 KiB

  1. using SimpleJSON;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Runtime.Serialization;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace IllusionInjector.Updating
  9. {
  10. /** // JSON format
  11. * {
  12. * "_updateScript": "0.1", // version
  13. * "<pluginName>": { // an entry for your plugin, using its annotated name
  14. * "version": "<version>", // required, should be in .NET Version class format
  15. * // note: only required if neither newName nor newScript is specified
  16. * "newName": "<newName>", // optional, defines a new name for the plugin (gets saved under this name)
  17. * // (updater will also check this file for this name to get latest)
  18. * "newScript": "<newScript>", // optional, defines a new location for the update script
  19. * // updater will look here for latest version too
  20. * // note: if both newName and newScript are defined, the updater will only look in newScript
  21. * // for newName, and not any other combination
  22. * "download": "<url>", // required, defines URL to use for downloading new version
  23. * // note: only required if neither newName nor newScript is specified
  24. * },
  25. * ...
  26. * }
  27. */
  28. class UpdateScript
  29. {
  30. static readonly Version ScriptVersion = new Version(0, 1);
  31. public Version Version { get; private set; }
  32. private Dictionary<string, PluginVersionInfo> info = new Dictionary<string, PluginVersionInfo>();
  33. public IReadOnlyDictionary<string, PluginVersionInfo> Info { get => info; }
  34. public class PluginVersionInfo
  35. {
  36. public Version Version { get; protected internal set; }
  37. public string NewName { get; protected internal set; }
  38. public Uri NewScript { get; protected internal set; }
  39. public Uri Download { get; protected internal set; }
  40. }
  41. public static UpdateScript Parse(JSONObject jscript)
  42. {
  43. var script = new UpdateScript
  44. {
  45. Version = Version.Parse(jscript["_updateScript"].Value)
  46. };
  47. if (script.Version != ScriptVersion)
  48. throw new UpdateScriptParseException("Script version mismatch");
  49. jscript.Remove("_updateScript");
  50. foreach (var kvp in jscript)
  51. {
  52. var obj = kvp.Value.AsObject;
  53. var pvi = new PluginVersionInfo
  54. {
  55. Version = obj.Linq.Any(p => p.Key == "version") ? Version.Parse(obj["version"].Value) : null,
  56. Download = obj.Linq.Any(p => p.Key == "download") ? new Uri(obj["download"].Value) : null,
  57. NewName = obj.Linq.Any(p => p.Key == "newName") ? obj["newName"] : null,
  58. NewScript = obj.Linq.Any(p => p.Key == "newScript") ? new Uri(obj["newScript"]) : null
  59. };
  60. if (pvi.NewName == null && pvi.NewScript == null && (pvi.Version == null || pvi.Download == null))
  61. throw new UpdateScriptParseException($"Required fields missing from object {kvp.Key}");
  62. script.info.Add(kvp.Key, pvi);
  63. }
  64. return script;
  65. }
  66. [Serializable]
  67. private class UpdateScriptParseException : Exception
  68. {
  69. public UpdateScriptParseException()
  70. {
  71. }
  72. public UpdateScriptParseException(string message) : base(message)
  73. {
  74. }
  75. public UpdateScriptParseException(string message, Exception innerException) : base(message, innerException)
  76. {
  77. }
  78. protected UpdateScriptParseException(SerializationInfo info, StreamingContext context) : base(info, context)
  79. {
  80. }
  81. }
  82. }
  83. }