diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f33c8f..372c8b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.3.6 + +**Additions**: +- Added support for V67 +- Added startup functionality that fetches game versions from a remote resource, allowing easier LCVR compatibility updates with less downtime + # 1.3.5 **Additions**: diff --git a/LCVR.csproj b/LCVR.csproj index f414707..bd66b01 100644 --- a/LCVR.csproj +++ b/LCVR.csproj @@ -4,7 +4,7 @@ netstandard2.1 LCVR Collecting Scrap in VR - 1.3.5 + 1.3.6 DaXcess true 12.0 diff --git a/Source/Plugin.cs b/Source/Plugin.cs index e0cd5c3..b7b9e1d 100644 --- a/Source/Plugin.cs +++ b/Source/Plugin.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Net; using System.Reflection; using UnityEngine; using UnityEngine.InputSystem; @@ -25,7 +26,7 @@ public class Plugin : BaseUnityPlugin { public const string PLUGIN_GUID = "io.daxcess.lcvr"; public const string PLUGIN_NAME = "LCVR"; - public const string PLUGIN_VERSION = "1.3.5"; + public const string PLUGIN_VERSION = "1.3.6"; #if DEBUG private const string SKIP_CHECKSUM_VAR = $"--lcvr-skip-checksum={PLUGIN_VERSION}-dev"; @@ -33,11 +34,14 @@ public class Plugin : BaseUnityPlugin private const string SKIP_CHECKSUM_VAR = $"--lcvr-skip-checksum={PLUGIN_VERSION}"; #endif + private const string HASHES_OVERRIDE_URL = "https://gist.githubusercontent.com/DaXcess/72c4fbac0f18c76ebc99e6b769f19389/raw/LCVR%2520Game%2520Hashes"; + private readonly string[] GAME_ASSEMBLY_HASHES = [ "BFF45683C267F402429049EF7D8095C078D5CD534E5300E56317ACB6056D70FB", // V64 "A6BDE2EB39028B36CB1667DCFB4ED10F688FB3FF72E71491AC25C5CB47A7EF6C", // V64.1 "B0BC7D3392FDAD3BB6515C0769363A51FF3599E67325FAE153948E0B82EB7596", // V66 + "B644AD19F3CE1E82071AC5F45D1E96D76B9FC06C11763381E1979BCDC5889607", // V67 ]; public new static Config Config { get; private set; } @@ -113,7 +117,7 @@ private void Awake() } } - if (!LoadEarlyRuntimeDependencies()) + if (!PreloadRuntimeDependencies()) { Logger.LogError("Disabling mod because required runtime dependencies could not be loaded!"); return; @@ -163,10 +167,39 @@ private bool VerifyGameVersion() var location = Path.Combine(Paths.ManagedPath, "Assembly-CSharp.dll"); var hash = BitConverter.ToString(Utils.ComputeHash(File.ReadAllBytes(location))).Replace("-", ""); - return GAME_ASSEMBLY_HASHES.Contains(hash); + // Attempt local lookup first + if (GAME_ASSEMBLY_HASHES.Contains(hash)) + { + Logger.LogInfo("Game version verified using local hashes"); + + return true; + } + + Logger.LogWarning("Failed to verify game version using local hashes, checking remotely for updated hashes..."); + + // Attempt to fetch a gist with known working assembly hashes + // This allows me to keep LCVR up and running if the game updates, without code changes + try + { + var contents = new WebClient().DownloadString(HASHES_OVERRIDE_URL); + var hashes = Utils.ParseConfig(contents); + + if (!hashes.Contains(hash)) + return false; + + Logger.LogInfo("Game version verified using remote hashes"); + + return true; + } + catch (Exception ex) + { + Logger.LogWarning($"Failed to verify using remote hashes: {ex.Message}"); + + return false; + } } - private bool LoadEarlyRuntimeDependencies() + private bool PreloadRuntimeDependencies() { try { @@ -180,7 +213,7 @@ private bool LoadEarlyRuntimeDependencies() if (filename is "UnityOpenXR.dll" or "openxr_loader.dll") continue; - Logger.LogDebug($"Early loading {filename}"); + Logger.LogDebug($"Preloading '{filename}'..."); try { @@ -188,14 +221,14 @@ private bool LoadEarlyRuntimeDependencies() } catch (Exception ex) { - Logger.LogWarning($"Failed to early load {filename}: {ex.Message}"); + Logger.LogWarning($"Failed to preload '{filename}': {ex.Message}"); } } } catch (Exception ex) { Logger.LogError( - $"Unexpected error occured while loading early runtime dependencies (incorrect folder structure?): {ex.Message}"); + $"Unexpected error occured while preloading runtime dependencies (incorrect folder structure?): {ex.Message}"); return false; } diff --git a/Source/Utils.cs b/Source/Utils.cs index 437b909..1a9719e 100644 --- a/Source/Utils.cs +++ b/Source/Utils.cs @@ -10,6 +10,7 @@ using System.Text; using System; using System.Collections; +using System.Linq; using GameNetcodeStuff; namespace LCVR; @@ -31,6 +32,19 @@ public static byte[] ComputeHash(byte[] input) return sha.ComputeHash(input); } + public static string[] ParseConfig(string content) + { + var lines = content.Split("\n", StringSplitOptions.RemoveEmptyEntries); + + return (from line in lines + where !line.TrimStart().StartsWith("#") + let commentIndex = line.IndexOf('#') + select commentIndex >= 0 ? line[..commentIndex].Trim() : line.Trim() + into parsedLine + where !string.IsNullOrEmpty(parsedLine) + select parsedLine).ToArray(); + } + public static string FormatPascalAndAcronym(string input) { var builder = new StringBuilder(input[0].ToString());