Harden keyboard and camera routing, inventory and vendor interactions, chat/emotes, relog portal flow, and paperdoll rendering. Add retail research, connected gate coverage, and release-gate validation.
113 lines
4.9 KiB
C#
113 lines
4.9 KiB
C#
using AcDream.App.Input;
|
|
using AcDream.UI.Abstractions.Input;
|
|
using Silk.NET.Input;
|
|
|
|
namespace AcDream.App.Tests.Input;
|
|
|
|
public sealed class RetailKeymapFileTests
|
|
{
|
|
[Fact]
|
|
public void Parse_CommittedRetailFile_ReproducesEveryUserBindableDefault()
|
|
{
|
|
string text = File.ReadAllText(Path.Combine(
|
|
FindRepoRoot(), "docs", "research", "named-retail",
|
|
"retail-default.keymap.txt"));
|
|
KeyBindings expected = KeyBindings.RetailDefaults();
|
|
KeyBindings actual = RetailKeymapFile.Parse(text, expected);
|
|
|
|
Assert.Equal(
|
|
expected.ForAction(InputAction.MovementForward).ToArray(),
|
|
actual.ForAction(InputAction.MovementForward).ToArray());
|
|
Assert.Equal(
|
|
expected.ForAction(InputAction.MovementWalkMode).ToArray(),
|
|
actual.ForAction(InputAction.MovementWalkMode).ToArray());
|
|
Assert.Equal(
|
|
expected.ForAction(InputAction.ToggleInventoryPanel).ToArray(),
|
|
actual.ForAction(InputAction.ToggleInventoryPanel).ToArray());
|
|
Assert.Equal(
|
|
expected.ForAction(InputAction.CameraAlternateRotateLeft).ToArray(),
|
|
actual.ForAction(InputAction.CameraAlternateRotateLeft).ToArray());
|
|
// The user's captured retail file omits slots 10-13; omission means
|
|
// unbound rather than "inherit a compiled default".
|
|
Assert.Empty(actual.ForAction(InputAction.UseQuickSlot_10));
|
|
|
|
// Host-only actions are outside retail's fourteen editable maps and survive.
|
|
Assert.Equal(
|
|
expected.ForAction(InputAction.AcdreamToggleAudioMute).ToArray(),
|
|
actual.ForAction(InputAction.AcdreamToggleAudioMute).ToArray());
|
|
}
|
|
|
|
[Fact]
|
|
public void WriteThenParse_RoundTripsAll306RetailActionIdentities()
|
|
{
|
|
var source = new KeyBindings();
|
|
foreach (((uint inputMapId, uint actionId), InputAction action) in
|
|
RetailActionIdentityTable.Map)
|
|
{
|
|
source.Add(new Binding(
|
|
new KeyChord(
|
|
Key.SuperRight,
|
|
ModifierMask.Shift | ModifierMask.Ctrl | ModifierMask.Win),
|
|
action,
|
|
RetailActionIdentityTable.ActivationFor(inputMapId, actionId),
|
|
RetailActionIdentityTable.ScopeForInputMap(inputMapId)));
|
|
}
|
|
|
|
string text = RetailKeymapFile.Write(source);
|
|
KeyBindings loaded = RetailKeymapFile.Parse(text, new KeyBindings());
|
|
|
|
Assert.Equal(306, loaded.All.Count);
|
|
foreach (Binding expected in source.All)
|
|
Assert.Contains(expected, loaded.All);
|
|
Assert.Contains("CharacterOptionCommands", text, StringComparison.Ordinal);
|
|
Assert.Contains("AutoRepeatAttacks", text, StringComparison.Ordinal);
|
|
Assert.Contains("AFKState", text, StringComparison.Ordinal);
|
|
Assert.Contains("DIK_RWIN", text, StringComparison.Ordinal);
|
|
Assert.Contains("EscapeKey [ \"\" [ 0 DIK_ESCAPE ] ]", text, StringComparison.Ordinal);
|
|
Assert.Contains("TargetedUsage", text, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public void ProfileStore_SaveAsSelectsProfile_AndLoadReplacesRetailRows()
|
|
{
|
|
string root = Path.Combine(Path.GetTempPath(), "acdream-keymap-" + Guid.NewGuid().ToString("N"));
|
|
string config = Path.Combine(root, "config");
|
|
string documents = Path.Combine(root, "documents", "Asheron's Call");
|
|
string json = Path.Combine(config, "keybinds.json");
|
|
try
|
|
{
|
|
var source = KeyBindings.RetailDefaults();
|
|
var store = new RetailKeymapProfileStore(json, documents);
|
|
RetailKeymapSaveResult saved = store.Save("friends", source, overwrite: false);
|
|
|
|
Assert.Equal(RetailKeymapSaveStatus.Saved, saved.Status);
|
|
Assert.Equal("friends.keymap", store.CurrentFileName);
|
|
Assert.Equal(new[] { "friends.keymap" }, store.ListFiles());
|
|
Assert.True(store.TryLoad(
|
|
"friends.keymap", new KeyBindings(), out KeyBindings loaded, out string? error),
|
|
error);
|
|
Assert.Equal(
|
|
source.ForAction(InputAction.MovementForward).ToArray(),
|
|
loaded.ForAction(InputAction.MovementForward).ToArray());
|
|
Assert.Equal(
|
|
RetailKeymapSaveStatus.Exists,
|
|
store.Save("friends", source, overwrite: false).Status);
|
|
}
|
|
finally
|
|
{
|
|
if (Directory.Exists(root)) Directory.Delete(root, recursive: true);
|
|
}
|
|
}
|
|
|
|
private static string FindRepoRoot()
|
|
{
|
|
string? directory = AppContext.BaseDirectory;
|
|
while (directory is not null)
|
|
{
|
|
if (File.Exists(Path.Combine(directory, "AcDream.slnx")))
|
|
return directory;
|
|
directory = Directory.GetParent(directory)?.FullName;
|
|
}
|
|
throw new DirectoryNotFoundException("Could not locate acdream.sln.");
|
|
}
|
|
}
|