Skip to content

Commit

Permalink
WIP on configuration library
Browse files Browse the repository at this point in the history
  • Loading branch information
LogicAndTrick committed Dec 27, 2024
1 parent f4b0ef4 commit f1d34f0
Show file tree
Hide file tree
Showing 31 changed files with 1,646 additions and 18 deletions.
6 changes: 3 additions & 3 deletions Sledge.Formats.Bsp.Tests/Sledge.Formats.Bsp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.5.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.5.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.7.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.7.0" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Sledge.Formats.Configuration.Tests/MSTestSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
56 changes: 56 additions & 0 deletions Sledge.Formats.Configuration.Tests/RegistryUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Diagnostics;
using Microsoft.Win32;
using Sledge.Formats.Configuration.Registry;

namespace Sledge.Formats.Configuration.Tests;

#pragma warning disable CA1416 // platform warning
public static class RegistryUtil
{
/// <summary>
/// Very rough .reg file parser
/// </summary>
public static InMemoryRegistry CreateRegistryFromRegString(string regString)
{
var reg = new InMemoryRegistry();

var spl = regString.Split('\n').Select(x => x.Trim()).ToList();

if (spl[0] != "Windows Registry Editor Version 5.00") throw new NotSupportedException($"Unknown registry type: {spl[0]}");

var currentHive = RegistryHive.CurrentUser;
string? currentKey = null;

foreach (var line in spl.Skip(1))
{
if (string.IsNullOrWhiteSpace(line)) continue;
if (line[0] == '[')
{
var keyPath = line.Trim('[', ']').Split('\\');
var hiveStr = keyPath[0][4..].Replace("_", "");
currentHive = Enum.Parse<RegistryHive>(hiveStr, true);
currentKey = string.Join('\\', keyPath.Skip(1));
}
else if (currentKey != null)
{
var kv = line.Split('=', 2);
var key = kv[0].Trim('"');
var val = kv[1];
if (val.StartsWith('"'))
{
reg.OpenBaseKey(currentHive, RegistryView.Default).CreateSubKey(currentKey).SetValue(key, val.Trim('"').Replace(@"\\", @"\"), RegistryValueKind.String);
}
else if (val.StartsWith("dword:"))
{
reg.OpenBaseKey(currentHive, RegistryView.Default).CreateSubKey(currentKey).SetValue(key, Convert.ToInt32(val[6..], 16), RegistryValueKind.DWord);
}
else
{
throw new NotSupportedException($"Unknown value type: {val}");
}
}
}

return reg;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="MSTest.Sdk/3.6.1">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UseVSTest>true</UseVSTest>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Sledge.Formats.Configuration\Sledge.Formats.Configuration.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.12.0" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="MSTest.Analyzers" Version="3.7.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<PackageReference Update="MSTest.TestAdapter" Version="3.7.0" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="MSTest.TestFramework" Version="3.7.0" />
</ItemGroup>

</Project>
111 changes: 111 additions & 0 deletions Sledge.Formats.Configuration.Tests/TestWorldcraftConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using Microsoft.Win32;
using Sledge.Formats.Configuration.Worldcraft;

namespace Sledge.Formats.Configuration.Tests;

#pragma warning disable CA1416

[TestClass]
public sealed class TestWorldcraftConfiguration
{
/// <summary>
/// If you don't have worldcraft settings in your registry, this test will fail
/// </summary>
[TestMethod]
public void TestLoadSettingsFromLocalComputer()
{
var config = WorldcraftConfiguration.LoadFromRegistry(WorldcraftConfigurationLoadSettings.Default);
Console.WriteLine("Undo levels: " + config.General.UndoLevels);
Console.WriteLine("Textures: " + string.Join("; ", config.TextureDirectories));
}

[TestMethod]
public void TestLoadSettings()
{
var reg = RegistryUtil.CreateRegistryFromRegString(Worldcraft33RegString);
var config = WorldcraftConfiguration.LoadFromRegistry(new WorldcraftConfigurationLoadSettings
{
LoadGameConfigurations = false,
AutodetectRegistryLocation = false,
RegistryLocation = reg.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default).OpenSubKey(@"Software\Valve\Worldcraft")
});

Assert.AreEqual(@"C:\Users\WDAGUtilityAccount\Desktop\Worldcraft 3.3", config.General.InstallDirectory, StringComparer.InvariantCultureIgnoreCase);
Assert.AreEqual(true, config.General.UseIndependentWindowConfigurations);
Assert.AreEqual(false, config.General.LoadDefaultWindowPositionsWithMaps);
Assert.AreEqual(0x32, config.General.UndoLevels);
Assert.AreEqual(true, config.General.AllowGroupingWhileIgnoreGroupsChecked);
Assert.AreEqual(false, config.General.StretchArchesToFitOriginalBoundingRectangle);

CollectionAssert.AreEqual(new[] { @"c:\users\wdagutilityaccount\desktop\zhlt.wad" }, config.TextureDirectories, StringComparer.InvariantCultureIgnoreCase);
}

private const string Worldcraft33RegString = """
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Valve]
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft]
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft\2D Views]
"Crosshairs"=dword:00000001
"GroupCarve"=dword:00000001
"Scrollbars"=dword:00000000
"RotateConstrain"=dword:00000001
"Draw Vertices"=dword:00000000
"Default Grid"=dword:00000020
"WhiteOnBlack"=dword:00000000
"GridHigh10"=dword:00000000
"GridIntensity"=dword:00000042
"HideSmallGrid"=dword:00000000
"Nudge"=dword:00000001
"OrientPrimitives"=dword:00000001
"AutoSelect"=dword:00000001
"SelectByHandles"=dword:00000001
"GridHighSpec"=dword:00000008
"KeepCloneGroup"=dword:00000000
"Gridhigh64"=dword:00000001
"GridDots"=dword:00000000
"Centeroncamera"=dword:00000001
"Usegroupcolors"=dword:00000000
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft\3D Views]
"Hardware"=dword:00000000
"Reverse Y"=dword:00000001
"BackPlane"=dword:00001ef9
"UseMouseLook"=dword:00000000
"ModelDistance"=dword:00000190
"AnimateModels"=dword:00000001
"ForwardSpeedMax"=dword:00000b0d
"TimeToMaxSpeed"=dword:00000783
"FilterTextures"=dword:00000000
"ReverseSelection"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft\Configured]
"Installed"=dword:6767bfdf
"Configured"=dword:00000002
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft\Custom2DColors]
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft\General]
"Directory"="C:\\Users\\WDAGUtilityAccount\\Desktop\\Worldcraft 3.3"
"TextureFileCount"=dword:00000001
"TextureFile0"="c:\\users\\wdagutilityaccount\\desktop\\zhlt.wad"
"Brightness"=dword:0000000a
"Undo Levels"=dword:00000032
"Locking Textures"=dword:00000000
"Texture Alignment"=dword:00000000
"Independent Windows"=dword:00000001
"Load Default Positions"=dword:00000000
"GroupWhileIgnore"=dword:00000001
"StretchArches"=dword:00000000
"NewBars"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft\Recent File List]
"File1"="C:\\Users\\WDAGUtilityAccount\\Desktop\\Worldcraft 3.3\\123"
[HKEY_CURRENT_USER\SOFTWARE\Valve\Worldcraft\Settings]
""";
}
21 changes: 21 additions & 0 deletions Sledge.Formats.Configuration/Registry/IRegistry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.Win32;

namespace Sledge.Formats.Configuration.Registry
{
/// <summary>
/// An interface for any type which can provide access to the registry. In most circumstances, the implementation
/// will be <see cref="WindowsRegistry"/>. This service exists to support effective testing of registry access.
/// </summary>
public interface IRegistry
{
/// <summary>Opens a new <see cref="IRegistryKey"/> that represents the requested key on the local machine with the specified view.</summary>
/// <returns>The requested registry key.</returns>
/// <param name="hKey">The HKEY to open.</param>
/// <param name="view">The registry view to use.</param>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="hKey" /> or <paramref name="view" /> is invalid.</exception>
/// <exception cref="T:System.UnauthorizedAccessException">The user does not have the necessary registry rights.</exception>
/// <exception cref="T:System.Security.SecurityException">The user does not have the permissions required to perform this action.</exception>
IRegistryKey OpenBaseKey(RegistryHive hKey, RegistryView view);
}
}
Loading

0 comments on commit f1d34f0

Please sign in to comment.