Browse Source

Added a soft AlmostVersion for GameVersion operations

pull/32/head
Anairkoen Schno 5 years ago
parent
commit
2f38769b5e
8 changed files with 169 additions and 12 deletions
  1. +2
    -0
      IPA.Loader/IPA.Loader.csproj
  2. +22
    -0
      IPA.Loader/JsonConverters/AlmostVersionConverter.cs
  3. +2
    -2
      IPA.Loader/Loader/PluginManager.cs
  4. +3
    -2
      IPA.Loader/Loader/PluginManifest.cs
  5. +2
    -2
      IPA.Loader/Updating/BeatMods/ApiEndpoint.cs
  6. +1
    -1
      IPA.Loader/Updating/BeatMods/Updater.cs
  7. +132
    -0
      IPA.Loader/Utilities/AlmostVersion.cs
  8. +5
    -5
      IPA.Loader/Utilities/BeatSaber.cs

+ 2
- 0
IPA.Loader/IPA.Loader.csproj View File

@ -62,6 +62,7 @@
<Compile Include="Config\ConfigProviders\JsonConfigProvider.cs" /> <Compile Include="Config\ConfigProviders\JsonConfigProvider.cs" />
<Compile Include="Config\IConfigProvider.cs" /> <Compile Include="Config\IConfigProvider.cs" />
<Compile Include="Config\SelfConfig.cs" /> <Compile Include="Config\SelfConfig.cs" />
<Compile Include="JsonConverters\AlmostVersionConverter.cs" />
<Compile Include="JsonConverters\MultilineStringConverter.cs" /> <Compile Include="JsonConverters\MultilineStringConverter.cs" />
<Compile Include="Loader\Composite\CompositeBSPlugin.cs" /> <Compile Include="Loader\Composite\CompositeBSPlugin.cs" />
<Compile Include="Loader\DisabledConfig.cs" /> <Compile Include="Loader\DisabledConfig.cs" />
@ -93,6 +94,7 @@
<Compile Include="JsonConverters\SemverRangeConverter.cs" /> <Compile Include="JsonConverters\SemverRangeConverter.cs" />
<Compile Include="JsonConverters\SemverVersionConverter.cs" /> <Compile Include="JsonConverters\SemverVersionConverter.cs" />
<Compile Include="Utilities\BeatSaber.cs" /> <Compile Include="Utilities\BeatSaber.cs" />
<Compile Include="Utilities\AlmostVersion.cs" />
<Compile Include="Utilities\Ref.cs" /> <Compile Include="Utilities\Ref.cs" />
<Compile Include="Utilities\ReflectionUtil.cs" /> <Compile Include="Utilities\ReflectionUtil.cs" />
<Compile Include="Loader\Composite\CompositeIPAPlugin.cs" /> <Compile Include="Loader\Composite\CompositeIPAPlugin.cs" />


+ 22
- 0
IPA.Loader/JsonConverters/AlmostVersionConverter.cs View File

@ -0,0 +1,22 @@
using IPA.Utilities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IPA.JsonConverters
{
internal class AlmostVersionConverter : JsonConverter<AlmostVersion>
{
public override AlmostVersion ReadJson(JsonReader reader, Type objectType, AlmostVersion existingValue, bool hasExistingValue, JsonSerializer serializer) =>
reader.Value == null ? null : new AlmostVersion(reader.Value as string);
public override void WriteJson(JsonWriter writer, AlmostVersion value, JsonSerializer serializer)
{
if (value == null) writer.WriteNull();
else writer.WriteValue(value.ToString());
}
}
}

+ 2
- 2
IPA.Loader/Loader/PluginManager.cs View File

@ -294,9 +294,9 @@ namespace IPA.Loader
string pluginDir = BeatSaber.PluginsPath; string pluginDir = BeatSaber.PluginsPath;
var gameVer = BeatSaber.GameVersion; var gameVer = BeatSaber.GameVersion;
var lastVerS = SelfConfig.SelfConfigRef.Value.LastGameVersion; var lastVerS = SelfConfig.SelfConfigRef.Value.LastGameVersion;
var lastVer = lastVerS != null ? new SemVer.Version(lastVerS, true) : null;
var lastVer = lastVerS != null ? new AlmostVersion(lastVerS, gameVer) : null;
if (lastVer != null && Utils.VersionCompareNoPrerelease(gameVer, lastVer) != 0)
if (lastVer != null && gameVer != lastVer)
{ {
var oldPluginsName = Path.Combine(BeatSaber.InstallPath, $"Old {lastVer} Plugins"); var oldPluginsName = Path.Combine(BeatSaber.InstallPath, $"Old {lastVer} Plugins");
var newPluginsName = Path.Combine(BeatSaber.InstallPath, $"Old {gameVer} Plugins"); var newPluginsName = Path.Combine(BeatSaber.InstallPath, $"Old {gameVer} Plugins");


+ 3
- 2
IPA.Loader/Loader/PluginManifest.cs View File

@ -1,4 +1,5 @@
using IPA.JsonConverters; using IPA.JsonConverters;
using IPA.Utilities;
using Newtonsoft.Json; using Newtonsoft.Json;
using SemVer; using SemVer;
using System; using System;
@ -21,8 +22,8 @@ namespace IPA.Loader
[JsonProperty("version", Required = Required.Always), JsonConverter(typeof(SemverVersionConverter))] [JsonProperty("version", Required = Required.Always), JsonConverter(typeof(SemverVersionConverter))]
public Version Version; public Version Version;
[JsonProperty("gameVersion", Required = Required.Always), JsonConverter(typeof(SemverVersionConverter))]
public Version GameVersion;
[JsonProperty("gameVersion", Required = Required.Always), JsonConverter(typeof(AlmostVersionConverter))]
public AlmostVersion GameVersion;
[JsonProperty("author", Required = Required.Always)] [JsonProperty("author", Required = Required.Always)]
public string Author; public string Author;


+ 2
- 2
IPA.Loader/Updating/BeatMods/ApiEndpoint.cs View File

@ -103,8 +103,8 @@ namespace IPA.Updating.BeatMods
public Version Version; public Version Version;
[JsonProperty("gameVersion"), [JsonProperty("gameVersion"),
JsonConverter(typeof(SemverVersionConverter))]
public Version GameVersion;
JsonConverter(typeof(AlmostVersionConverter))]
public AlmostVersion GameVersion;
[Serializable] [Serializable]
public class AuthorType public class AuthorType


+ 1
- 1
IPA.Loader/Updating/BeatMods/Updater.cs View File

@ -389,7 +389,7 @@ namespace IPA.Updating.BeatMods
var ver = modsMatching.Value var ver = modsMatching.Value
.Where(nullCheck => nullCheck != null) // entry is not null .Where(nullCheck => nullCheck != null) // entry is not null
.Where(versionCheck => Utils.VersionCompareNoPrerelease(versionCheck.GameVersion, BeatSaber.GameVersion) == 0) // game version matches
.Where(versionCheck => versionCheck.GameVersion == BeatSaber.GameVersion) // game version matches
.Where(approvalCheck => approvalCheck.Status == ApiEndpoint.Mod.ApprovedStatus) // version approved .Where(approvalCheck => approvalCheck.Status == ApiEndpoint.Mod.ApprovedStatus) // version approved
// TODO: fix; it seems wrong somehow // TODO: fix; it seems wrong somehow
.Where(conflictsCheck => dep.Conflicts == null || !dep.Conflicts.IsSatisfied(conflictsCheck.Version)) // not a conflicting version .Where(conflictsCheck => dep.Conflicts == null || !dep.Conflicts.IsSatisfied(conflictsCheck.Version)) // not a conflicting version


+ 132
- 0
IPA.Loader/Utilities/AlmostVersion.cs View File

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SemVer;
using Version = SemVer.Version;
namespace IPA.Utilities
{
public class AlmostVersion : IComparable<AlmostVersion>, IComparable<Version>
{
private Version semverForm = null;
private string strForm = null;
private StoredAs storedAs;
public enum StoredAs
{
SemVer,
String
}
public AlmostVersion(string vertext)
{
if (!TryParseFrom(vertext, StoredAs.SemVer))
TryParseFrom(vertext, StoredAs.String);
}
public AlmostVersion(Version ver)
{
semverForm = ver;
storedAs = StoredAs.SemVer;
}
public AlmostVersion(string vertext, StoredAs mode)
{
if (!TryParseFrom(vertext, mode))
throw new ArgumentException($"{nameof(vertext)} could not be stored as {mode}!");
}
public AlmostVersion(string vertext, AlmostVersion copyMode)
{
if (copyMode == null)
throw new ArgumentNullException(nameof(copyMode));
if (!TryParseFrom(vertext, copyMode.storedAs))
throw new ArgumentException($"{nameof(vertext)} could not be stored the same way as {copyMode}!");
}
private bool TryParseFrom(string str, StoredAs mode)
{
if (mode == StoredAs.SemVer)
try
{
semverForm = new Version(str, true);
storedAs = StoredAs.SemVer;
return true;
}
catch
{
return false;
}
else
{
strForm = str;
storedAs = StoredAs.String;
return true;
}
}
public string StringValue => strForm;
public Version SemverValue => semverForm;
public override string ToString() =>
storedAs == StoredAs.SemVer ? semverForm.ToString() : strForm;
public int CompareTo(AlmostVersion other)
{
if (other == null) return -1;
if (storedAs != other.storedAs)
throw new InvalidOperationException("Cannot compare AlmostVersions with different stores!");
if (storedAs == StoredAs.SemVer)
return semverForm.CompareTo(other.semverForm);
else
return strForm.CompareTo(other.strForm);
}
public int CompareTo(Version other)
{
if (storedAs != StoredAs.SemVer)
throw new InvalidOperationException("Cannot compare a SemVer version with an AlmostVersion stored as a string!");
return semverForm.CompareTo(other);
}
public override bool Equals(object obj)
{
return obj is AlmostVersion version &&
semverForm == version.semverForm &&
strForm == version.strForm &&
storedAs == version.storedAs;
}
public override int GetHashCode()
{
var hashCode = -126402897;
hashCode = hashCode * -1521134295 + EqualityComparer<Version>.Default.GetHashCode(semverForm);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(strForm);
hashCode = hashCode * -1521134295 + storedAs.GetHashCode();
return hashCode;
}
public static bool operator==(AlmostVersion l, AlmostVersion r)
{
if (l.storedAs != r.storedAs) return false;
if (l.storedAs == StoredAs.SemVer)
return Utils.VersionCompareNoPrerelease(l.semverForm, r.semverForm) == 0;
else
return l.strForm == r.strForm;
}
public static bool operator!=(AlmostVersion l, AlmostVersion r) => !(l == r);
// implicitly convertible from Version
public static implicit operator AlmostVersion(Version ver) => new AlmostVersion(ver);
// implicitly convertible to Version
public static implicit operator Version(AlmostVersion av) => av.SemverValue;
}
}

+ 5
- 5
IPA.Loader/Utilities/BeatSaber.cs View File

@ -11,22 +11,22 @@ namespace IPA.Utilities
/// </summary> /// </summary>
public static class BeatSaber public static class BeatSaber
{ {
private static Version _gameVersion;
private static AlmostVersion _gameVersion;
/// <summary> /// <summary>
/// Provides the current game version. /// Provides the current game version.
/// </summary> /// </summary>
/// <value>the SemVer version of the game</value> /// <value>the SemVer version of the game</value>
public static Version GameVersion => _gameVersion ?? (_gameVersion = new Version(Application.version, true));
public static AlmostVersion GameVersion => _gameVersion ?? (_gameVersion = new AlmostVersion(Application.version));
internal static void SetEarlyGameVersion(Version ver)
internal static void SetEarlyGameVersion(AlmostVersion ver)
{ {
_gameVersion = ver; _gameVersion = ver;
Logging.Logger.log.Debug($"GameVersion set early to {ver}"); Logging.Logger.log.Debug($"GameVersion set early to {ver}");
} }
internal static void EnsureRuntimeGameVersion() internal static void EnsureRuntimeGameVersion()
{ {
var rtVer = new Version(Application.version, true);
if (rtVer != _gameVersion)
var rtVer = new AlmostVersion(Application.version);
if (!rtVer.Equals(_gameVersion)) // this actually uses stricter equality than == for AlmostVersion
{ {
Logging.Logger.log.Warn($"Early version {_gameVersion} parsed from game files doesn't match runtime version {rtVer}!"); Logging.Logger.log.Warn($"Early version {_gameVersion} parsed from game files doesn't match runtime version {rtVer}!");
_gameVersion = rtVer; _gameVersion = rtVer;


Loading…
Cancel
Save