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.

48 lines
1.7 KiB

  1. using IPA.Utilities;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. namespace IPA.Injector
  7. {
  8. internal static class GameVersionEarly
  9. {
  10. private static string ResolveDataPath(string installDir) =>
  11. Path.Combine(Directory.EnumerateDirectories(installDir, "*_Data").First(), "globalgamemanagers");
  12. internal static string GetGameVersion()
  13. {
  14. var mgr = ResolveDataPath(BeatSaber.InstallPath);
  15. using (var stream = File.OpenRead(mgr))
  16. using (var reader = new BinaryReader(stream, Encoding.UTF8))
  17. {
  18. const string key = "public.app-category.games";
  19. int pos = 0;
  20. while (stream.Position < stream.Length && pos < key.Length)
  21. {
  22. if (reader.ReadByte() == key[pos]) pos++;
  23. else pos = 0;
  24. }
  25. if (stream.Position == stream.Length) // we went through the entire stream without finding the key
  26. throw new KeyNotFoundException("Could not find key '" + key + "' in " + mgr);
  27. // otherwise pos == key.Length, which means we found it
  28. int offset = 136 - key.Length - sizeof(int);
  29. stream.Seek(offset, SeekOrigin.Current); // advance past junk to beginning of string
  30. int strlen = reader.ReadInt32(); // assumes LE
  31. var strbytes = reader.ReadBytes(strlen);
  32. return Encoding.UTF8.GetString(strbytes);
  33. }
  34. }
  35. internal static SemVer.Version SafeParseVersion() => new SemVer.Version(GetGameVersion(), true);
  36. internal static void Load() => BeatSaber.SetEarlyGameVersion(SafeParseVersion());
  37. }
  38. }