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.
 
 
 
 

92 lines
3.4 KiB

using IPA.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
#if NET3
using Net3_Proxy;
using Path = Net3_Proxy.Path;
using File = Net3_Proxy.File;
using Directory = Net3_Proxy.Directory;
#endif
namespace IPA.Injector
{
internal static class GameVersionEarly
{
internal static string ResolveDataPath(string installDir) =>
Directory.EnumerateDirectories(installDir, "*_Data").First();
internal static string GlobalGameManagers(string installDir) =>
Path.Combine(ResolveDataPath(installDir), "globalgamemanagers");
internal static string GetGameVersion()
{
var mgr = GlobalGameManagers(UnityGame.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);
long startPos = 0;
long length = 0;
while (stream.Position < stream.Length)
{
char current = reader.ReadChar();
if (startPos == 0 && current >= '0' && current <= '9')
startPos = stream.Position - 1;
else if (startPos > 0 && IllegalCharacters.Contains(current))
{
length = stream.Position - startPos - 1;
break;
}
}
if (startPos <= 0 || length <= 0)
throw new KeyNotFoundException("Could not parse version from " + mgr);
stream.Seek(startPos, SeekOrigin.Begin);
var strbytes = reader.ReadBytes((int)length);
return Encoding.UTF8.GetString(strbytes);
}
}
internal static SemVer.Version SafeParseVersion() => new SemVer.Version(GetGameVersion(), true);
private static void _Load()
{
UnityGame.SetEarlyGameVersion(SafeParseVersion());
UnityGame.CheckGameVersionBoundary();
}
internal static void Load()
{
// This exists for the same reason the wierdness in Injector.Main does
_ = Type.GetType("SemVer.Version, SemVer", false);
_Load();
}
internal static readonly char[] IllegalCharacters = new char[]
{
'<', '>', ':', '/', '\\', '|', '?', '*', '"',
'\u0000', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u0007',
'\u0008', '\u0009', '\u000a', '\u000b', '\u000c', '\u000d', '\u000e', '\u000d',
'\u000f', '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016',
'\u0017', '\u0018', '\u0019', '\u001a', '\u001b', '\u001c', '\u001d', '\u001f',
};
}
}