Add unit test for item injection validation

Check the other bind list too

don't bother checking that a bound index actually exists in the item pocket
This commit is contained in:
Kurt 2020-04-26 18:58:13 -07:00
parent f28a544604
commit 839e1a3f14
6 changed files with 54 additions and 2 deletions

View File

@ -21,7 +21,7 @@ public PocketInjector(IReadOnlyList<Item> items, IRAMReadWriter bot)
}
private const int pocket = Item.SIZE * 20;
private const int size = (pocket * 2) + 0x18;
private const int size = (pocket + 0x18) * 2;
private const int shift = -0x18 - (Item.SIZE * 20);
private uint DataOffset => (uint)(WriteOffset + shift);
@ -90,23 +90,44 @@ public bool Validate(byte[] data)
if (!ValidateEnabled)
return true;
return ValidateItemBinary(data);
}
public static bool ValidateItemBinary(byte[] data)
{
// Check the unlocked slot count -- expect 0,10,20
var bagCount = BitConverter.ToUInt32(data, pocket);
if (bagCount > 20 || bagCount % 10 != 0) // pouch21-39 count
return false;
var pocketCount = BitConverter.ToUInt32(data, pocket + 0x18 + pocket);
if (pocketCount != 20) // pouch0-19 count should be 20.
return false;
// Check the item wheel binding -- expect -1 or [0,7]
// Disallow duplicate binds!
// Don't bother checking that bind[i] (when ! -1) is not NONE at items[i]. We don't need to check everything!
var bound = new List<byte>();
if (!ValidateBindList(data, pocket + 4, bound))
return false;
if (!ValidateBindList(data, pocket + 4 + (pocket + 0x18), bound))
return false;
return true;
}
private static bool ValidateBindList(byte[] data, int bindStart, ICollection<byte> bound)
{
for (int i = 0; i < 20; i++)
{
var bind = data[pocket + 4 + i];
var bind = data[bindStart + i];
if (bind == 0xFF)
continue;
if (bind > 7)
return false;
if (bound.Contains(bind))
return false;
bound.Add(bind);
}

View File

@ -0,0 +1,17 @@
using FluentAssertions;
using NHSE.Injection;
using Xunit;
namespace NHSE.Tests
{
public static class InjectionTests
{
[Fact]
public static void VerifyItemBinary()
{
var data = Properties.Resources.itempacket;
bool result = PocketInjector.ValidateItemBinary(data);
result.Should().BeTrue();
}
}
}

View File

@ -18,6 +18,7 @@
<ItemGroup>
<ProjectReference Include="..\NHSE.Core\NHSE.Core.csproj" />
<ProjectReference Include="..\NHSE.Injection\NHSE.Injection.csproj" />
<ProjectReference Include="..\NHSE.Parsing\NHSE.Parsing.csproj" />
</ItemGroup>

View File

@ -60,6 +60,16 @@ internal class Resources {
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] itempacket {
get {
object obj = ResourceManager.GetObject("itempacket", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>

View File

@ -118,6 +118,9 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="itempacket" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\itempacket.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="STR_ItemName_41_Turnip" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\STR_ItemName_41_Turnip.msbt;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>

Binary file not shown.