Skip to content

Commit 1a1fff4

Browse files
committed
[GameSettings] Reload RegistryRoot when detecting error during GetValue
1 parent e6a698a commit 1a1fff4

25 files changed

+139
-54
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using Hi3Helper;
2+
using Microsoft.Win32;
3+
using System;
4+
using static Hi3Helper.Logger;
5+
6+
namespace CollapseLauncher.Extension;
7+
8+
public static class RegistryExtension
9+
{
10+
#nullable enable
11+
12+
/// <summary>
13+
/// Attempts to retrieve a value from the specified registry key. If an exception occurs,
14+
/// the provided reload function is invoked to reload the registry key, and the value is
15+
/// retrieved from the reloaded key.
16+
/// </summary>
17+
/// <param name="key">The <see cref="RegistryKey"/> to retrieve the value from. This string is not case-sensitive.</param>
18+
/// <param name="name">The name of the value to retrieve.</param>
19+
/// <param name="defaultValue">The value to return if name does not exist.</param>
20+
/// <param name="reloadFunction">
21+
/// A function that reloads the registry key in case of an error. This function should return
22+
/// a new <see cref="RegistryKey"/> instance or null if the reload fails.
23+
/// </param>
24+
/// <returns>
25+
/// The value associated with the specified name, or null if the value does not exist or
26+
/// the reload function fails.
27+
/// </returns>
28+
/// <remarks>
29+
/// This method logs an error message if an exception occurs while attempting to retrieve
30+
/// the value from the registry key.
31+
/// </remarks>
32+
public static object? TryGetValue(this RegistryKey? key, string name, object? defaultValue, Func<RegistryKey?> reloadFunction)
33+
{
34+
try
35+
{
36+
if (key != null) return key.GetValue(name, defaultValue);
37+
38+
LogWriteLine($"[RegistryExtension::TryGetValue] The provided RegistryKey is null. Cannot retrieve value {name}.", LogType.Error, true);
39+
return null;
40+
}
41+
catch (Exception ex)
42+
{
43+
LogWriteLine($"[RegistryExtension::TryGetValue] Failed to get registry value {name} from {key?.Name ?? "null"}\r\n{ex}" +
44+
$"\r\n\t Attempting to reload the registry key after running function {reloadFunction.Method.Name}",
45+
LogType.Error, true);
46+
var reloadedKey = reloadFunction();
47+
if (reloadedKey != null) return reloadedKey?.GetValue(name, defaultValue);
48+
49+
LogWriteLine($"[RegistryExtension::TryGetValue] Reload function {reloadFunction.Method.Name} returned null. Cannot retrieve value {name}.", LogType.Error, true);
50+
return null;
51+
}
52+
}
53+
}

CollapseLauncher/Classes/GameManagement/GameSettings/BaseClass/SettingsBase.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ internal static string? RegistryPath
2222
Path.Combine($"Software\\{GameVersionManager.VendorTypeProp.VendorType}", GameVersionManager.GamePreset.InternalGameNameInConfig);
2323
}
2424

25+
private static RegistryKey? _registryRoot;
2526
internal static RegistryKey? RegistryRoot
2627
{
2728
get
@@ -30,15 +31,23 @@ internal static RegistryKey? RegistryRoot
3031
if (RegistryPath == null) return null;
3132

3233
// Try to open the registry path
33-
field = Registry.CurrentUser.OpenSubKey(RegistryPath, true);
34+
_registryRoot = Registry.CurrentUser.OpenSubKey(RegistryPath, true);
3435

3536
// If it's still empty, then create a new one
36-
field ??= Registry.CurrentUser.CreateSubKey(RegistryPath, true, RegistryOptions.None);
37+
_registryRoot ??= Registry.CurrentUser.CreateSubKey(RegistryPath, true, RegistryOptions.None);
3738

38-
return field;
39+
return _registryRoot;
3940
}
4041
}
4142

43+
internal static RegistryKey? RefreshRegistryRoot()
44+
{
45+
_registryRoot?.Close();
46+
_registryRoot?.Dispose();
47+
_registryRoot = null;
48+
return RegistryRoot;
49+
}
50+
4251
protected SettingsBase(IGameVersion gameVersionManager) => GameVersionManager = gameVersionManager;
4352

4453
public static IGameSettings CreateBaseFrom(IGameVersion gameVersionManager, bool isEnableResizableWindow = false)

CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GeneralData.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using CollapseLauncher.Extension;
12
using CollapseLauncher.GameSettings.Genshin.Context;
23
using Hi3Helper;
34
using Hi3Helper.EncTool;
@@ -349,8 +350,8 @@ public static GeneralData Load()
349350
try
350351
{
351352
if (RegistryRoot == null) throw new ArgumentNullException($"Cannot load {ValueName} since RegistryKey is unexpectedly not initialized!");
352-
object value = RegistryRoot.GetValue(ValueName) ?? throw new ArgumentNullException($"Cannot find registry key {ValueName}");
353-
353+
object value = RegistryRoot.TryGetValue(ValueName, null, RefreshRegistryRoot) ?? throw new ArgumentNullException($"Cannot find registry key {ValueName}");
354+
354355
ReadOnlySpan<byte> byteStr = (byte[])value;
355356
#if DUMPGIJSON
356357
// Dump GeneralData as raw string

CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/ScreenManager.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using CollapseLauncher.Extension;
12
using CollapseLauncher.GameSettings.Base;
23
using CollapseLauncher.Interfaces;
34
using Hi3Helper;
@@ -109,9 +110,9 @@ public static ScreenManager Load()
109110
{
110111
if (RegistryRoot == null) throw new NullReferenceException("Cannot load Genshin Screen Manager settings as RegistryKey is unexpectedly not initialized!");
111112

112-
object? valueWidth = RegistryRoot.GetValue(ValueNameScreenManagerWidth, null);
113-
object? valueHeight = RegistryRoot.GetValue(ValueNameScreenManagerHeight, null);
114-
object? valueFullscreen = RegistryRoot.GetValue(ValueNameScreenManagerFullscreen, null);
113+
object? valueWidth = RegistryRoot.TryGetValue(ValueNameScreenManagerWidth, null, RefreshRegistryRoot);
114+
object? valueHeight = RegistryRoot.TryGetValue(ValueNameScreenManagerHeight, null, RefreshRegistryRoot);
115+
object? valueFullscreen = RegistryRoot.TryGetValue(ValueNameScreenManagerFullscreen, null, RefreshRegistryRoot);
115116
if (valueWidth != null && valueHeight != null && valueFullscreen != null)
116117
{
117118
int width = (int)valueWidth;

CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/VisibleBackground.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Hi3Helper;
1+
using CollapseLauncher.Extension;
2+
using Hi3Helper;
23
using Hi3Helper.EncTool;
34
using Hi3Helper.SentryHelper;
45
using Microsoft.Win32;
@@ -41,7 +42,7 @@ public static VisibleBackground Load()
4142
{
4243
if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {ValueName} since RegistryRoot is unexpectedly not initialized!");
4344

44-
object? value = RegistryRoot.GetValue(ValueName, null);
45+
object? value = RegistryRoot.TryGetValue(ValueName, null, RefreshRegistryRoot);
4546
if (value != null)
4647
{
4748
int borderless = (int)value;

CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/WindowsHDR.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using Hi3Helper;
1+
using CollapseLauncher.Extension;
2+
using Hi3Helper;
23
using Hi3Helper.EncTool;
34
using Hi3Helper.SentryHelper;
45
using Microsoft.Win32;
@@ -41,7 +42,7 @@ public static WindowsHDR Load()
4142
{
4243
if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {ValueName} since RegistryRoot is unexpectedly not initialized!");
4344

44-
object? value = RegistryRoot.GetValue(ValueName, null);
45+
object? value = RegistryRoot.TryGetValue(ValueName, null, RefreshRegistryRoot);
4546
if (value != null)
4647
{
4748
int hdr = (int)value;

CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/GraphicsGrade.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using CollapseLauncher.Interfaces;
1+
using CollapseLauncher.Extension;
2+
using CollapseLauncher.Interfaces;
23
using Hi3Helper;
34
using Hi3Helper.SentryHelper;
45
using Microsoft.Win32;
@@ -40,7 +41,7 @@ public static GraphicsGrade Load()
4041
{
4142
if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {ValueName} RegistryKey is unexpectedly not initialized!");
4243

43-
object? value = RegistryRoot.GetValue(ValueName, null);
44+
object? value = RegistryRoot.TryGetValue(ValueName, null, RefreshRegistryRoot);
4445
if (value != null)
4546
{
4647
SelectGraphicsGrade graphicsGrade = (SelectGraphicsGrade)value;

CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/PersonalAudioSetting.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using CollapseLauncher.GameSettings.Honkai.Context;
1+
using CollapseLauncher.Extension;
2+
using CollapseLauncher.GameSettings.Honkai.Context;
23
using CollapseLauncher.Interfaces;
34
using Hi3Helper;
45
using Hi3Helper.EncTool;
@@ -177,7 +178,7 @@ public static PersonalAudioSetting Load()
177178
{
178179
if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {ValueName} RegistryKey is unexpectedly not initialized!");
179180

180-
object? value = RegistryRoot.GetValue(ValueName, null);
181+
object? value = RegistryRoot.TryGetValue(ValueName, null, RefreshRegistryRoot);
181182

182183
if (value != null)
183184
{

CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/PersonalAudioSettingVolume.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using CollapseLauncher.GameSettings.Honkai.Context;
1+
using CollapseLauncher.Extension;
2+
using CollapseLauncher.GameSettings.Honkai.Context;
23
using CollapseLauncher.Interfaces;
34
using Hi3Helper;
45
using Hi3Helper.EncTool;
@@ -80,7 +81,7 @@ public static PersonalAudioSettingVolume Load()
8081
{
8182
if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {ValueName} RegistryKey is unexpectedly not initialized!");
8283

83-
object? value = RegistryRoot.GetValue(ValueName, null);
84+
object? value = RegistryRoot.TryGetValue(ValueName, null, RefreshRegistryRoot);
8485

8586
if (value != null)
8687
{

CollapseLauncher/Classes/GameManagement/GameSettings/Honkai/RegistryClass/PersonalGraphicsSettingV2.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using CollapseLauncher.GameSettings.Honkai.Context;
1+
using CollapseLauncher.Extension;
2+
using CollapseLauncher.GameSettings.Honkai.Context;
23
using CollapseLauncher.GameSettings.Honkai.Enums;
34
using CollapseLauncher.Interfaces;
45
using Hi3Helper;
@@ -186,7 +187,7 @@ public static PersonalGraphicsSettingV2 Load()
186187
{
187188
if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {ValueName} RegistryKey is unexpectedly not initialized!");
188189

189-
object? value = RegistryRoot.GetValue(ValueName, null);
190+
object? value = RegistryRoot.TryGetValue(ValueName, null, RefreshRegistryRoot);
190191

191192
if (value != null)
192193
{

0 commit comments

Comments
 (0)