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.

187 lines
6.1 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using IPA.Updating.Converters;
  5. using IPA.Utilities;
  6. using Newtonsoft.Json;
  7. using SemVer;
  8. using Version = SemVer.Version;
  9. namespace IPA.Updating.ModSaber
  10. {
  11. class ApiEndpoint
  12. {
  13. public const string ApiBase = "https://www.modsaber.org/";
  14. public const string GetModInfoEndpoint = "registry/{0}/{1}";
  15. public const string GetModsWithSemver = "api/v1.1/mods/semver/{0}/{1}";
  16. class HexArrayConverter : JsonConverter
  17. {
  18. public override bool CanConvert(Type objectType)
  19. {
  20. return objectType == typeof(byte[]);
  21. }
  22. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  23. {
  24. if (reader.TokenType == JsonToken.Null)
  25. {
  26. return null;
  27. }
  28. if (reader.TokenType == JsonToken.String)
  29. {
  30. try
  31. {
  32. return LoneFunctions.StringToByteArray((string)reader.Value);
  33. }
  34. catch (Exception ex)
  35. {
  36. throw new Exception($"Error parsing version string: {reader.Value}", ex);
  37. }
  38. }
  39. throw new Exception(
  40. $"Unexpected token or value when parsing hex string. Token: {reader.TokenType}, Value: {reader.Value}");
  41. }
  42. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  43. {
  44. if (value == null)
  45. {
  46. writer.WriteNull();
  47. }
  48. else
  49. {
  50. if (!(value is byte[]))
  51. {
  52. throw new JsonSerializationException("Expected byte[] object value");
  53. }
  54. writer.WriteValue(LoneFunctions.ByteArrayToString((byte[]) value));
  55. }
  56. }
  57. }
  58. [Serializable]
  59. public class Mod
  60. {
  61. #pragma warning disable CS0649
  62. [JsonProperty("name")]
  63. public string Name;
  64. [JsonProperty("version"),
  65. JsonConverter(typeof(SemverVersionConverter))]
  66. public Version Version;
  67. [Serializable]
  68. public class AuthorType
  69. {
  70. [JsonProperty("name")]
  71. public string Name;
  72. [JsonProperty("id")]
  73. public string Id;
  74. public override string ToString() => Name;
  75. }
  76. [Serializable]
  77. public class DetailsData
  78. {
  79. [JsonProperty("author")]
  80. public AuthorType Author;
  81. [JsonProperty("title")]
  82. public string Title;
  83. [JsonProperty("description")]
  84. public string Description;
  85. [JsonProperty("published")]
  86. public string Published;
  87. }
  88. [JsonProperty("details")]
  89. public DetailsData Details;
  90. [Serializable]
  91. public class ApprovalStatus
  92. {
  93. [JsonProperty("status")]
  94. public bool Status;
  95. [JsonProperty("modified")]
  96. public string LastModified;
  97. }
  98. [JsonProperty("approval")]
  99. public ApprovalStatus Approval;
  100. [Serializable]
  101. public class GameVersionType
  102. {
  103. [JsonProperty("value"),
  104. JsonConverter(typeof(SemverVersionConverter))]
  105. public Version Version;
  106. [JsonProperty("manifest")]
  107. public string Manifest;
  108. }
  109. [JsonProperty("gameVersion"),
  110. JsonConverter(typeof(SemverVersionConverter))]
  111. public GameVersionType GameVersion;
  112. #pragma warning restore CS0649
  113. [Serializable]
  114. public class PlatformFile
  115. {
  116. [JsonProperty("hash"),
  117. JsonConverter(typeof(HexArrayConverter))]
  118. public byte[] Hash = new byte[20];
  119. [JsonProperty("files", ItemConverterType = typeof(HexArrayConverter))]
  120. public Dictionary<string, byte[]> FileHashes = new Dictionary<string, byte[]>();
  121. [JsonProperty("url")]
  122. public string DownloadPath;
  123. public override string ToString() =>
  124. $"{LoneFunctions.ByteArrayToString(Hash)}@{DownloadPath}({string.Join(",", FileHashes.Select(o => $"\"{o.Key}\":\"{LoneFunctions.ByteArrayToString(o.Value)}\""))})";
  125. }
  126. [Serializable]
  127. public class FilesObject
  128. {
  129. [JsonProperty("steam")]
  130. public PlatformFile Steam;
  131. [JsonProperty("oculus")]
  132. public PlatformFile Oculus;
  133. }
  134. [JsonProperty("files")]
  135. public FilesObject Files;
  136. public class Dependency
  137. {
  138. public string Name = null;
  139. public Range VersionRange = null;
  140. }
  141. [Serializable]
  142. public class LinksType
  143. {
  144. [JsonProperty("dependencies", ItemConverterType = typeof(ModSaberDependencyConverter))]
  145. public Dependency[] Dependencies = new Dependency[0];
  146. [JsonProperty("conflicts", ItemConverterType = typeof(ModSaberDependencyConverter))]
  147. public Dependency[] Conflicts = new Dependency[0];
  148. }
  149. [JsonProperty("links")]
  150. public LinksType Links;
  151. [JsonProperty("oldVersions", ItemConverterType = typeof(SemverVersionConverter))]
  152. public Version[] OldVersions = new Version[0];
  153. public override string ToString()
  154. {
  155. return $"{{\"{Details.Title} ({Name})\"v{Version} for {GameVersion.Version} by {Details.Author} with \"{Files.Steam}\" and \"{Files.Oculus}\"}}";
  156. }
  157. }
  158. }
  159. }