|
|
@ -0,0 +1,48 @@ |
|
|
|
using IPA.Utilities; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.IO; |
|
|
|
using System.Linq; |
|
|
|
using System.Text; |
|
|
|
|
|
|
|
namespace IPA.Injector |
|
|
|
{ |
|
|
|
internal static class GameVersionEarly |
|
|
|
{ |
|
|
|
private static string ResolveDataPath(string installDir) => |
|
|
|
Path.Combine(Directory.EnumerateDirectories(installDir, "*_Data").First(), "globalgamemanagers"); |
|
|
|
|
|
|
|
internal static string GetGameVersion() |
|
|
|
{ |
|
|
|
var mgr = ResolveDataPath(BeatSaber.InstallPath); |
|
|
|
|
|
|
|
using (var stream = File.OpenRead(mgr)) |
|
|
|
using (var reader = new BinaryReader(stream, Encoding.UTF8)) |
|
|
|
{ |
|
|
|
const string key = "public.app-category.games"; |
|
|
|
int pos = 0; |
|
|
|
|
|
|
|
while (stream.Position < stream.Length && pos < key.Length) |
|
|
|
{ |
|
|
|
if (reader.ReadByte() == key[pos]) pos++; |
|
|
|
else pos = 0; |
|
|
|
} |
|
|
|
|
|
|
|
if (stream.Position == stream.Length) // we went through the entire stream without finding the key
|
|
|
|
throw new KeyNotFoundException("Could not find key '" + key + "' in " + mgr); |
|
|
|
|
|
|
|
// otherwise pos == key.Length, which means we found it
|
|
|
|
int offset = 136 - key.Length - sizeof(int); |
|
|
|
stream.Seek(offset, SeekOrigin.Current); // advance past junk to beginning of string
|
|
|
|
|
|
|
|
int strlen = reader.ReadInt32(); // assumes LE
|
|
|
|
var strbytes = reader.ReadBytes(strlen); |
|
|
|
|
|
|
|
return Encoding.UTF8.GetString(strbytes); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal static SemVer.Version SafeParseVersion() => new SemVer.Version(GetGameVersion(), true); |
|
|
|
|
|
|
|
internal static void Load() => BeatSaber.SetEarlyGameVersion(SafeParseVersion()); |
|
|
|
} |
|
|
|
} |