diff --git a/IPA.Loader/Updating/ModSaber/ApiEndpoint.cs b/IPA.Loader/Updating/ModSaber/ApiEndpoint.cs index b35b1970..cb3c9535 100644 --- a/IPA.Loader/Updating/ModSaber/ApiEndpoint.cs +++ b/IPA.Loader/Updating/ModSaber/ApiEndpoint.cs @@ -13,7 +13,7 @@ namespace IPA.Updating.ModSaber { public const string ApiBase = "https://www.modsaber.org/"; public const string GetModInfoEndpoint = "registry/{0}/{1}"; - public const string GetModsWithSemver = "api/v1.0/mods/semver/{0}/{1}"; + public const string GetModsWithSemver = "api/v1.1/mods/semver/{0}/{1}"; class HexArrayConverter : JsonConverter { @@ -36,10 +36,11 @@ namespace IPA.Updating.ModSaber } catch (Exception ex) { - throw new Exception(string.Format("Error parsing version string: {0}", reader.Value), ex); + throw new Exception($"Error parsing version string: {reader.Value}", ex); } } - throw new Exception(string.Format("Unexpected token or value when parsing hex string. Token: {0}, Value: {1}", reader.TokenType, reader.Value)); + throw new Exception( + $"Unexpected token or value when parsing hex string. Token: {reader.TokenType}, Value: {reader.Value}"); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) @@ -54,7 +55,7 @@ namespace IPA.Updating.ModSaber { throw new JsonSerializationException("Expected byte[] object value"); } - writer.WriteValue(LoneFunctions.ByteArrayToString(value as byte[])); + writer.WriteValue(LoneFunctions.ByteArrayToString((byte[]) value)); } } } @@ -70,18 +71,58 @@ namespace IPA.Updating.ModSaber JsonConverter(typeof(SemverVersionConverter))] public Version Version; - [JsonProperty("approved")] - public bool Approved; + [Serializable] + public class AuthorType + { + [JsonProperty("name")] + public string Name; + [JsonProperty("id")] + public string Id; + + public override string ToString() => Name; + } + + [Serializable] + public class DetailsData + { + [JsonProperty("author")] + public AuthorType Author; + [JsonProperty("title")] + public string Title; + [JsonProperty("description")] + public string Description; + [JsonProperty("published")] + public string Published; + } + + [JsonProperty("details")] + public DetailsData Details; + + [Serializable] + public class ApprovalStatus + { + [JsonProperty("status")] + public bool Status; + [JsonProperty("modified")] + public string LastModified; + } - [JsonProperty("title")] - public string Title; + [JsonProperty("approval")] + public ApprovalStatus Approval; + + [Serializable] + public class GameVersionType + { + [JsonProperty("value"), + JsonConverter(typeof(SemverVersionConverter))] + public Version Version; + [JsonProperty("manifest")] + public string Manifest; + } [JsonProperty("gameVersion"), JsonConverter(typeof(SemverVersionConverter))] - public Version GameVersion; - - [JsonProperty("author")] - public string Author; + public GameVersionType GameVersion; #pragma warning restore CS0649 [Serializable] @@ -97,10 +138,8 @@ namespace IPA.Updating.ModSaber [JsonProperty("url")] public string DownloadPath; - public override string ToString() - { - return $"{LoneFunctions.ByteArrayToString(Hash)}@{DownloadPath}({string.Join(",",FileHashes.Select(o=>$"\"{o.Key}\":\"{LoneFunctions.ByteArrayToString(o.Value)}\""))})"; - } + public override string ToString() => + $"{LoneFunctions.ByteArrayToString(Hash)}@{DownloadPath}({string.Join(",", FileHashes.Select(o => $"\"{o.Key}\":\"{LoneFunctions.ByteArrayToString(o.Value)}\""))})"; } [Serializable] @@ -122,18 +161,25 @@ namespace IPA.Updating.ModSaber public Range VersionRange = null; } - [JsonProperty("dependsOn", ItemConverterType = typeof(ModSaberDependencyConverter))] - public Dependency[] Dependencies = new Dependency[0]; + [Serializable] + public class LinksType + { + [JsonProperty("dependencies", ItemConverterType = typeof(ModSaberDependencyConverter))] + public Dependency[] Dependencies = new Dependency[0]; + + [JsonProperty("conflicts", ItemConverterType = typeof(ModSaberDependencyConverter))] + public Dependency[] Conflicts = new Dependency[0]; + } - [JsonProperty("conflictsWith", ItemConverterType = typeof(ModSaberDependencyConverter))] - public Dependency[] Conflicts = new Dependency[0]; + [JsonProperty("links")] + public LinksType Links; [JsonProperty("oldVersions", ItemConverterType = typeof(SemverVersionConverter))] public Version[] OldVersions = new Version[0]; public override string ToString() { - return $"{{\"{Title} ({Name})\"v{Version} for {GameVersion} by {Author} with \"{Files.Steam}\" and \"{Files.Oculus}\"}}"; + return $"{{\"{Details.Title} ({Name})\"v{Version} for {GameVersion.Version} by {Details.Author} with \"{Files.Steam}\" and \"{Files.Oculus}\"}}"; } } diff --git a/IPA.Loader/Updating/ModSaber/Updater.cs b/IPA.Loader/Updating/ModSaber/Updater.cs index 0a3ef53c..26307c36 100644 --- a/IPA.Loader/Updating/ModSaber/Updater.cs +++ b/IPA.Loader/Updating/ModSaber/Updater.cs @@ -218,8 +218,8 @@ namespace IPA.Updating.ModSaber continue; } - list.Value.AddRange(mod.Value.Dependencies.Select(d => new DependencyObject { Name = d.Name, Requirement = d.VersionRange, Consumers = new HashSet { dep.Name } })); - list.Value.AddRange(mod.Value.Conflicts.Select(d => new DependencyObject { Name = d.Name, Conflicts = d.VersionRange, Consumers = new HashSet { dep.Name } })); + list.Value.AddRange(mod.Value.Links.Dependencies.Select(d => new DependencyObject { Name = d.Name, Requirement = d.VersionRange, Consumers = new HashSet { dep.Name } })); + list.Value.AddRange(mod.Value.Links.Conflicts.Select(d => new DependencyObject { Name = d.Name, Conflicts = d.VersionRange, Consumers = new HashSet { dep.Name } })); } var depNames = new HashSet(); @@ -278,7 +278,7 @@ namespace IPA.Updating.ModSaber } var ver = modsMatching.Value.Where(nullCheck => nullCheck != null) - .Where(versionCheck => versionCheck.GameVersion == BeatSaber.GameVersion && versionCheck.Approved) + .Where(versionCheck => versionCheck.GameVersion.Version == BeatSaber.GameVersion && versionCheck.Approval.Status) .Where(conflictsCheck => dep.Conflicts == null || !dep.Conflicts.IsSatisfied(conflictsCheck.Version)) .Select(mod => mod.Version).Max(); // (2.1) // ReSharper disable once AssignmentInConditionalExpression diff --git a/IPA.Loader/Updating/SelfPlugin.cs b/IPA.Loader/Updating/SelfPlugin.cs index 18eac7f2..88cfde26 100644 --- a/IPA.Loader/Updating/SelfPlugin.cs +++ b/IPA.Loader/Updating/SelfPlugin.cs @@ -5,7 +5,7 @@ namespace IPA.Updating internal class SelfPlugin : IBeatSaberPlugin { internal const string IPA_Name = "Beat Saber IPA"; - internal const string IPA_Version = "3.11.5-b2"; + internal const string IPA_Version = "3.11.5"; public static SelfPlugin Instance { get; set; } = new SelfPlugin(); diff --git a/appveyor.yml b/appveyor.yml index f2fca7d3..74ef74ef 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: 'BSIPA-{branch}-{build}' environment: - bsipa_version: '3.11.5-b2' + bsipa_version: '3.11.5' pull_requests: do_not_increment_build_number: true install: