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());