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.

244 lines
8.0 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using IPA.JsonConverters;
  5. using IPA.Utilities;
  6. using Newtonsoft.Json;
  7. using Newtonsoft.Json.Linq;
  8. using SemVer;
  9. using Version = SemVer.Version;
  10. namespace IPA.Updating.BeatMods
  11. {
  12. class ApiEndpoint
  13. {
  14. public const string BeatModBase = "https://beatmods.com";
  15. public const string ApiBase = BeatModBase + "/api/v1/mod";
  16. public const string GetModInfoEndpoint = "?name={0}&version={1}";
  17. public const string GetModsByName = "?name={0}";
  18. class HexArrayConverter : JsonConverter
  19. {
  20. public override bool CanConvert(Type objectType)
  21. {
  22. return objectType == typeof(byte[]);
  23. }
  24. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  25. {
  26. if (reader.TokenType == JsonToken.Null)
  27. {
  28. return null;
  29. }
  30. if (reader.TokenType == JsonToken.String)
  31. {
  32. try
  33. {
  34. return Utils.StringToByteArray((string)reader.Value);
  35. }
  36. catch (Exception ex)
  37. {
  38. throw new Exception($"Error parsing version string: {reader.Value}", ex);
  39. }
  40. }
  41. throw new Exception(
  42. $"Unexpected token or value when parsing hex string. Token: {reader.TokenType}, Value: {reader.Value}");
  43. }
  44. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  45. {
  46. if (value == null)
  47. {
  48. writer.WriteNull();
  49. }
  50. else
  51. {
  52. if (!(value is byte[]))
  53. {
  54. throw new JsonSerializationException("Expected byte[] object value");
  55. }
  56. writer.WriteValue(Utils.ByteArrayToString((byte[]) value));
  57. }
  58. }
  59. }
  60. class ModMultiformatJsonConverter : JsonConverter<Mod>
  61. {
  62. public override Mod ReadJson(JsonReader reader, Type objectType, Mod existingValue, bool hasExistingValue, JsonSerializer serializer)
  63. {
  64. if (reader.TokenType == JsonToken.String)
  65. return new Mod { Id = reader.Value as string, IsIdReference = true };
  66. else
  67. {
  68. if (reader.TokenType != JsonToken.StartObject)
  69. return null;
  70. return serializer.Deserialize<Mod>(reader);
  71. }
  72. }
  73. public override void WriteJson(JsonWriter writer, Mod value, JsonSerializer serializer) => serializer.Serialize(writer, value);
  74. }
  75. [Serializable]
  76. public class Mod
  77. {
  78. #pragma warning disable CS0649
  79. /// <summary>
  80. /// Will be a useless string of characters. Do not use.
  81. /// </summary>
  82. [JsonProperty("_id")]
  83. public string Id;
  84. [JsonIgnore]
  85. public bool IsIdReference = false;
  86. [JsonProperty("required")]
  87. public bool Required;
  88. [JsonProperty("name")]
  89. public string Name;
  90. [JsonProperty("version"),
  91. JsonConverter(typeof(SemverVersionConverter))]
  92. public Version Version;
  93. [Serializable]
  94. public class AuthorType
  95. {
  96. [JsonProperty("username")]
  97. public string Name;
  98. [JsonProperty("_id")]
  99. public string Id;
  100. public override string ToString() => Name;
  101. }
  102. [JsonProperty("author")]
  103. public AuthorType Author;
  104. /*[Serializable]
  105. public class DetailsData
  106. {
  107. [JsonProperty("author")]
  108. public AuthorType Author;
  109. [JsonProperty("title")]
  110. public string Title;
  111. [JsonProperty("description")]
  112. public string Description;
  113. [JsonProperty("published")]
  114. public string Published;
  115. }
  116. [JsonProperty("details")]
  117. public DetailsData Details;*/
  118. [JsonProperty("status")]
  119. public string Status;
  120. public const string ApprovedStatus = "approved";
  121. [JsonProperty("description")]
  122. public string Description;
  123. [JsonProperty("category")]
  124. public string Category;
  125. [JsonProperty("link")]
  126. public Uri Link;
  127. #pragma warning restore CS0649
  128. /*[Serializable]
  129. public class PlatformFile
  130. {
  131. [JsonProperty("hash"),
  132. JsonConverter(typeof(HexArrayConverter))]
  133. public byte[] Hash = new byte[20];
  134. [JsonProperty("files", ItemConverterType = typeof(HexArrayConverter))]
  135. public Dictionary<string, byte[]> FileHashes = new Dictionary<string, byte[]>();
  136. [JsonProperty("url")]
  137. public string DownloadPath;
  138. public override string ToString() =>
  139. $"{Utils.ByteArrayToString(Hash)}@{DownloadPath}({string.Join(",", FileHashes.Select(o => $"\"{o.Key}\":\"{Utils.ByteArrayToString(o.Value)}\""))})";
  140. }
  141. [Serializable]
  142. public class FilesObject
  143. {
  144. [JsonProperty("steam")]
  145. public PlatformFile Steam;
  146. [JsonProperty("oculus")]
  147. public PlatformFile Oculus;
  148. }
  149. [JsonProperty("files")]
  150. public FilesObject Files;*/
  151. [Serializable]
  152. public class DownloadsObject
  153. {
  154. public const string TypeUniversal = "universal";
  155. public const string TypeSteam = "steam";
  156. public const string TypeOculus = "oculus";
  157. [JsonProperty("type")]
  158. public string Type;
  159. [JsonProperty("url")]
  160. public string Path;
  161. [Serializable]
  162. public class HashObject
  163. {
  164. [JsonProperty("hash"), JsonConverter(typeof(HexArrayConverter))]
  165. public byte[] Hash;
  166. [JsonProperty("file")]
  167. public string File;
  168. }
  169. /// <summary>
  170. /// Hashes stored are MD5
  171. /// </summary>
  172. [JsonProperty("hashMd5")]
  173. public HashObject[] Hashes;
  174. }
  175. [JsonProperty("downloads")]
  176. public DownloadsObject[] Downloads;
  177. /*public class Dependency
  178. {
  179. public string Name = null;
  180. public Range VersionRange = null;
  181. }
  182. [Serializable]
  183. public class LinksType
  184. {
  185. [JsonProperty("dependencies", ItemConverterType = typeof(ModSaberDependencyConverter))]
  186. public Dependency[] Dependencies = new Dependency[0];
  187. [JsonProperty("conflicts", ItemConverterType = typeof(ModSaberDependencyConverter))]
  188. public Dependency[] Conflicts = new Dependency[0];
  189. }
  190. [JsonProperty("links")]
  191. public LinksType Links;
  192. [JsonProperty("oldVersions", ItemConverterType = typeof(SemverVersionConverter))]
  193. public Version[] OldVersions = new Version[0];*/
  194. [JsonProperty("dependencies", ItemConverterType = typeof(ModMultiformatJsonConverter))]
  195. public Mod[] Dependencies;
  196. public override string ToString()
  197. {
  198. return $"{{\"{Name}\"v{Version} by {Author} files for {string.Join(", ", Downloads.Select(d => d.Type))}}}";
  199. }
  200. }
  201. }
  202. }