From f153df4630d3c65a20700a47eee0314c9136be3c Mon Sep 17 00:00:00 2001 From: Anairkoen Schno Date: Tue, 16 Jul 2019 18:43:34 -0500 Subject: [PATCH] Added some framework stuff for early gameversion detection --- Doorstop | 2 +- IPA.Injector/GameVersionEarly.cs | 48 +++++++++++++++++++++++++++++++ IPA.Injector/IPA.Injector.csproj | 1 + IPA.Injector/Injector.cs | 5 ++++ IPA.Loader/Loader/PluginLoader.cs | 1 + IPA.Loader/Utilities/BeatSaber.cs | 15 ++++++++++ appveyor.yml | 29 +++++++++++++++++-- 7 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 IPA.Injector/GameVersionEarly.cs diff --git a/Doorstop b/Doorstop index 17449269..02647aa4 160000 --- a/Doorstop +++ b/Doorstop @@ -1 +1 @@ -Subproject commit 17449269e7c39a652cad597396540fd6e9663bab +Subproject commit 02647aa40bdde4e5027eb596082a6787497b92e9 diff --git a/IPA.Injector/GameVersionEarly.cs b/IPA.Injector/GameVersionEarly.cs new file mode 100644 index 00000000..7b251157 --- /dev/null +++ b/IPA.Injector/GameVersionEarly.cs @@ -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()); + } +} diff --git a/IPA.Injector/IPA.Injector.csproj b/IPA.Injector/IPA.Injector.csproj index 46fd7b6a..c79a4514 100644 --- a/IPA.Injector/IPA.Injector.csproj +++ b/IPA.Injector/IPA.Injector.csproj @@ -55,6 +55,7 @@ + diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs index a0ce06d6..5c247c31 100644 --- a/IPA.Injector/Injector.cs +++ b/IPA.Injector/Injector.cs @@ -8,6 +8,7 @@ using System; using System.IO; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; using System.Threading.Tasks; using UnityEngine; using static IPA.Logging.Logger; @@ -59,12 +60,16 @@ namespace IPA.Injector loader.Debug("Prepping bootstrapper"); + // updates backup InstallBootstrapPatch(); Updates.InstallPendingUpdates(); LibLoader.SetupAssemblyFilenames(true); + // causes mono to hate itself + //GameVersionEarly.Load(); + pluginAsyncLoadTask = PluginLoader.LoadTask(); permissionFixTask = PermissionFix.FixPermissions(new DirectoryInfo(Environment.CurrentDirectory)); } diff --git a/IPA.Loader/Loader/PluginLoader.cs b/IPA.Loader/Loader/PluginLoader.cs index 1277fb46..e3e75ea2 100644 --- a/IPA.Loader/Loader/PluginLoader.cs +++ b/IPA.Loader/Loader/PluginLoader.cs @@ -21,6 +21,7 @@ namespace IPA.Loader { internal static Task LoadTask() => Task.Run(() => { + LoadMetadata(); Resolve(); ComputeLoadOrder(); diff --git a/IPA.Loader/Utilities/BeatSaber.cs b/IPA.Loader/Utilities/BeatSaber.cs index 0cdfeefc..3629d4f5 100644 --- a/IPA.Loader/Utilities/BeatSaber.cs +++ b/IPA.Loader/Utilities/BeatSaber.cs @@ -18,6 +18,21 @@ namespace IPA.Utilities /// the SemVer version of the game public static Version GameVersion => _gameVersion ?? (_gameVersion = new Version(Application.version, true)); + internal static void SetEarlyGameVersion(Version ver) + { + _gameVersion = ver; + Logging.Logger.log.Debug($"GameVersion set early to {ver}"); + } + internal static void EnsureRuntimeGameVersion() + { + var rtVer = new Version(Application.version, true); + if (rtVer != _gameVersion) + { + Logging.Logger.log.Warn($"Early version {_gameVersion} parsed from game files doesn't match runtime version {rtVer}!"); + _gameVersion = rtVer; + } + } + /// /// The different types of releases of the game. /// diff --git a/appveyor.yml b/appveyor.yml index 4c4c1d52..44ffedfd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,10 +1,14 @@ version: 'BSIPA-{branch}-{build}' + environment: bsipa_version: '3.12.23' gh_token: secure: E42gl/yepETuoLSwbJZ1GmEIPK6cCJu6zkd59NA21XiICtEV6COOLW7aehi1tcVU + BUILD_DOCS: 'no' + pull_requests: do_not_increment_build_number: true + install: - git submodule update --init --recursive - nuget restore @@ -14,26 +18,43 @@ install: #git checkout $env:APPVEYOR_REPO_BRANCH -q choco install docfx -y } -image: Visual Studio 2019 Preview + +image: Visual Studio 2019 + configuration: - Release platform: - - x86 - x64 + #- x86 + +for: +- + matrix: + only: + - configuration: Release + platform: x64 + environment: + BUILD_DOCS: 'yes' + branches: except: - gh-pages + cache: - '%LocalAppData%\NuGet\v3-cache' # NuGet v3 + artifacts: - path: IPA/bin/$(configuration) name: BSIPA - path: BSIPA-ModList/bin/$(configuration) name: ModList + build: verbosity: normal project: BSIPA.sln + skip_tags: false + deploy: - provider: GitHub release: BSIPA $(bsipa_version)-draft @@ -51,6 +72,7 @@ deploy: on: branch: master APPVEYOR_REPO_TAG: false + - provider: GitHub release: -ignore- tag: create_tag @@ -63,9 +85,10 @@ deploy: on: branch: master APPVEYOR_REPO_TAG: true + before_deploy: - ps: | - if ($env:APPVEYOR_REPO_BRANCH -eq 'master') + if ($env:APPVEYOR_REPO_BRANCH -eq 'master' -and $env:BUILD_DOCS -eq 'yes') { cd docs