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.

57 lines
2.0 KiB

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