using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("MageArenaVR.Preload")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MageArenaVR.Preload")] [assembly: AssemblyTitle("MageArenaVR.Preload")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MageArenaVR.Preload { public static class Preload { private static readonly ManualLogSource Logger = Logger.CreateLogSource("MageArenaVR.Preload"); private const string NativeName = "openvr_api.dll"; public static IEnumerable TargetDLLs { get; } = Array.Empty(); public static void Patch(AssemblyDefinition assembly) { } [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern IntPtr LoadLibraryW(string path); public static void Initialize() { try { string text = FindShippedNative(); if (text == null) { Logger.LogError((object)"openvr_api.dll was not found in the mod folders. VR cannot start without it. Reinstall the mod - the file ships alongside the patcher."); return; } string text2 = DeployNative(text); DeployBesideExe(text); RemoveOldOpenXRFiles(); if (text2 == null) { text2 = text; } string text3 = text2; if (LoadLibraryW(text3) == IntPtr.Zero) { Logger.LogWarning((object)($"LoadLibrary failed for '{text3}' (error {Marshal.GetLastWin32Error()}). " + "VR may still work if the file is already in the game's native plugin folder.")); } else { Logger.LogInfo((object)("OpenVR runtime loaded from '" + text3 + "'.")); } } catch (Exception arg) { Logger.LogError((object)$"Preload failed: {arg}"); } } private static void RemoveOldOpenXRFiles() { try { string text = Directory.GetParent(Paths.ManagedPath)?.FullName; if (string.IsNullOrEmpty(text) || !Directory.Exists(text)) { return; } int num = 0; string[] array = new string[4] { "Plugins\\UnityOpenXR.dll", "Plugins\\openxr_loader.dll", "Plugins\\x86_64\\UnityOpenXR.dll", "Plugins\\x86_64\\openxr_loader.dll" }; foreach (string path in array) { string path2 = Path.Combine(text, path); if (File.Exists(path2)) { try { File.Delete(path2); num++; } catch { } } } string path3 = Path.Combine(Path.Combine(text, "UnitySubsystems"), "UnityOpenXR"); if (Directory.Exists(path3)) { try { Directory.Delete(path3, recursive: true); num++; } catch { } } if (num > 0) { Logger.LogInfo((object)$"Removed {num} leftover OpenXR file(s) from an older install - this mod uses OpenVR and a stale OpenXR display would only conflict."); } } catch { } } private static string FindShippedNative() { List list = new List(); try { string directoryName = Path.GetDirectoryName(typeof(Preload).Assembly.Location); if (!string.IsNullOrEmpty(directoryName)) { list.Add(Path.Combine(directoryName, "openvr_api.dll")); } } catch { } string[] array = new string[2] { Paths.PatcherPluginPath, Paths.PluginPath }; foreach (string text in array) { if (string.IsNullOrEmpty(text) || !Directory.Exists(text)) { continue; } try { string[] files = Directory.GetFiles(text, "openvr_api.dll", SearchOption.AllDirectories); foreach (string item in files) { list.Add(item); } } catch { } } foreach (string item2 in list) { if (!string.IsNullOrEmpty(item2) && File.Exists(item2)) { return item2; } } return null; } private static string DeployNative(string source) { try { string text = Directory.GetParent(Paths.ManagedPath)?.FullName; if (string.IsNullOrEmpty(text) || !Directory.Exists(text)) { Logger.LogWarning((object)"Could not locate the game data folder; skipping native deployment."); return null; } string text2 = Path.Combine(Path.Combine(text, "Plugins"), "x86_64"); string text3 = Path.Combine(text2, "openvr_api.dll"); if (File.Exists(text3) && new FileInfo(text3).Length == new FileInfo(source).Length) { Logger.LogInfo((object)("openvr_api.dll already in place at '" + text2 + "'.")); return text3; } Directory.CreateDirectory(text2); File.Copy(source, text3, overwrite: true); return text3; } catch (Exception ex) { Logger.LogWarning((object)("Could not copy openvr_api.dll into the game folder (" + ex.Message + "). Loading it directly from the mod folder instead.")); return null; } } private static void DeployBesideExe(string source) { try { string gameRootPath = Paths.GameRootPath; if (!string.IsNullOrEmpty(gameRootPath) && Directory.Exists(gameRootPath)) { string text = Path.Combine(gameRootPath, "openvr_api.dll"); if (!File.Exists(text) || new FileInfo(text).Length != new FileInfo(source).Length) { File.Copy(source, text, overwrite: true); Logger.LogInfo((object)"Also placed openvr_api.dll in the game root as a fallback."); } } } catch { } } } }