using CodeWalker.GameFiles; using System; using System.Buffers.Binary; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Xml.Linq; using Xunit; using Xunit.Abstractions; namespace CodeWalker.Test { public static class TestData { public const string ReferenceDataBytes = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAADWA9YDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAATABMAAAAAAAAAAAAAAAAACgAAAAAAAADZAdkBAAAAAAYAAAAAAAAAogGiAQAAAAABAAAAAAAAADsAOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3///8mAAAANgAAAEkAAAAAAAAAAAAAAAAAAAAAAAAAAACAQgAAgEIAAAAAAAAAAAAAAAAIQDQAAAAAAEgDSAMAAAAABwAAAAAAAAAGAAYAAAAAAAgAAAAAAAAANwA3AAAAAAAIwA0AAAAAAB4AHgAAAAAACEAVAAAAAAAOAA4AAAAAAAjAGAAAAAAACQAJAAAAAAAIABsAAAAAAAIAAgAAAAAACIAbAAAAAAABAAEAAAAAAA=="; public static CScenarioPointRegion ReferenceData => new CScenarioPointRegion { AccelGrid = new rage__spdGrid2D { CellDimX = 64, CellDimY = 64, MaxCellX = 38, MaxCellY = 73, MinCellX = -3, MinCellY = 54, }, ChainingGraph = new CodeWalker.GameFiles.CScenarioChainingGraph { Chains = new CodeWalker.GameFiles.Array_Structure { Count1 = 59, Count2 = 59, Pointer = 1, }, Edges = new CodeWalker.GameFiles.Array_Structure { Count1 = 418, Count2 = 418, Pointer = 6, }, Nodes = new CodeWalker.GameFiles.Array_Structure { Count1 = 473, Count2 = 473, Pointer = 10, } }, Clusters = new CodeWalker.GameFiles.Array_Structure { Count1 = 6, Count2 = 6, Pointer = 7, }, EntityOverrides = new CodeWalker.GameFiles.Array_Structure { Count1 = 19, Count2 = 19, Pointer = 2, }, LookUps = new CodeWalker.GameFiles.CScenarioPointLookUps { GroupNames = new CodeWalker.GameFiles.Array_uint { Count1 = 9, Count2 = 9, Pointer = 1622024, }, InteriorNames = new CodeWalker.GameFiles.Array_uint { Count1 = 2, Count2 = 2, Pointer = 1769480, }, PedModelSetNames = new CodeWalker.GameFiles.Array_uint { Count1 = 30, Count2 = 30, Pointer = 901128, }, RequiredIMapNames = new CodeWalker.GameFiles.Array_uint { Count1 = 1, Count2 = 1, Pointer = 1802248, }, TypeNames = new CodeWalker.GameFiles.Array_uint { Count1 = 55, Count2 = 55, Pointer = 8, }, VehicleModelSetNames = new CodeWalker.GameFiles.Array_uint { Count1 = 14, Count2 = 14, Pointer = 1392648, }, }, Points = new CodeWalker.GameFiles.CScenarioPointContainer { LoadSavePoints = new CodeWalker.GameFiles.Array_Structure { PointerDataIndex = 4294967295, }, MyPoints = new CodeWalker.GameFiles.Array_Structure { Count1 = 982, Count2 = 982, Pointer = 3, } }, Unk_3844724227 = new CodeWalker.GameFiles.Array_ushort { Count1 = 840, Count2 = 840, Pointer = 3424264, } }; } public class PsoTypesTests { private readonly ITestOutputHelper _output; public PsoTypesTests(ITestOutputHelper testOutputHelper) { _output = testOutputHelper; } private const string ExpectedResult = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTAraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTEraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTMraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTQraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTUraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTYraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWw3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsNytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWw4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsOCtoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWw5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsOStoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3QzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0MytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NCtoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NStoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NitoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0OCtoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; private const string InputData = "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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTAraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTEraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTMraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTQraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTUraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwxNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMTYraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWwzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsMytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWw3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsNytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWw4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsOCtoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N0d2hlZWw5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdHdoZWVsOStoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3QzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0MytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NCtoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NStoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NitoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0NytoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pyMzUwX3N1c3Q4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6cjM1MF9zdXN0OCtoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; [Fact] public void TestConvertData() { var data = Convert.FromBase64String(InputData); var result = PsoTypes.ConvertDataArrayRaw(data, 0, 43); Assert.Equal(43, result.Length); var firstResult = result[0]; Assert.Equal(768, firstResult.Unused02); Assert.Equal("zr350_dash1+hifr", firstResult.HDTxd.ToString()); Assert.Equal("zr350_dash1", firstResult.targetAsset.ToString()); var outputData = Convert.ToBase64String(MemoryMarshal.AsBytes(result.AsSpan())); Assert.Equal(ExpectedResult, outputData); Assert.Equal(InputData, outputData); } private const string InputDataWithOffset = "UFNJTgAAAXhwcHBwcHBwcAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANnYl9idW1mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ2JfYnVtZitoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANnYl9idW1yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ2JfYnVtcitoaWZyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="; [Fact] public void TestConvertDataWithOffset() { var data = Convert.FromBase64String(InputDataWithOffset); var result = PsoTypes.ConvertDataArrayRaw(data, 112, 2); Assert.Equal(2, result.Length); var firstResult = result[0]; Assert.Equal(768, firstResult.Unused02); Assert.Equal("gb_bumf+hifr", firstResult.HDTxd.ToString()); Assert.Equal("gb_bumf", firstResult.targetAsset.ToString()); var secondResult = result[1]; Assert.Equal(768, secondResult.Unused02); Assert.Equal("gb_bumr+hifr", secondResult.HDTxd.ToString()); Assert.Equal("gb_bumr", secondResult.targetAsset.ToString()); data = Convert.FromBase64String("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"); var result2 = PsoTypes.ConvertDataArrayRaw(data, 144, 160); Assert.Equal(160, result2.Length); var firstResult2 = result2[0]; Assert.Equal(0, firstResult2.Unused0); Assert.Equal(1254242044u, firstResult2.imapName.Hash); Assert.Equal(256, firstResult2.itypDepArray.Count1); Assert.Equal(256, firstResult2.itypDepArray.Count2); Assert.Equal(50331648ul, firstResult2.itypDepArray.Pointer); var lastResult = result2[159]; Assert.Equal(0, lastResult.Unused0); Assert.Equal(2255575624, lastResult.imapName.Hash); Assert.Equal(256, lastResult.itypDepArray.Count1); Assert.Equal(256, lastResult.itypDepArray.Count2); Assert.Equal(54542593ul, lastResult.itypDepArray.Pointer); } [Fact] public void TestStringConversion() { var arr = new byte[64]; for (int i = 0; i <= 'j' - 'a'; i++) { arr[i] = (byte)('a' + i); } MemoryMarshal.TryRead(arr, out var str1); MemoryMarshal.TryRead(arr, out var str2); Assert.Equal("abcdefghij", str1.ToString()); Assert.Equal("abcdefghij", str2.ToString()); for (int i = 0; i <= 'Z' - 'A'; i++) { arr[i] = (byte)('A' + i); } MemoryMarshal.TryRead(arr, out str1); MemoryMarshal.TryRead(arr, out str2); Assert.Equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ", str1.ToString()); Assert.Equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ", str2.ToString()); } [Fact] public void StringConversionShouldRespectNullTerminators() { var arr = new byte[64]; for (int i = 0; i <= 'Z' - 'A'; i++) { arr[i] = (byte)('A' + i); } arr[15] = (byte)'\0'; MemoryMarshal.TryRead(arr, out var str1); Assert.Equal("ABCDEFGHIJKLMNO", str1.ToString()); MemoryMarshal.TryRead(arr, out var str2); Assert.Equal("ABCDEFGHIJKLMNO", str2.ToString()); } [Fact] public void TestGetItem() { var data = Convert.FromBase64String("UFNJTgAAAoBwcHBwcHBwcAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN6aGFiX2Noc3NfMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAemhhYl9jaHNzXzMraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN6aGFiX2ZlbmRfMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAemhhYl9mZW5kXzIraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN6aGFiX21pcnJfMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAemhhYl9taXJyXzEraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN6aGFiX21pcnJfMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAemhhYl9taXJyXzIraGlmcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); var result = PsoTypes.ConvertData(data, 16); Assert.Equal(4, result._HDTxdBindingArray.Count1); Assert.Equal(4, result._HDTxdBindingArray.Count2); Assert.Equal(2ul, result._HDTxdBindingArray.Pointer); Assert.Equal(0, result._Interiors.Count1); Assert.Equal(0, result._Interiors.Count2); Assert.Equal(0ul, result._Interiors.Pointer); Assert.Equal(0, result._MapDataGroups.Count1); Assert.Equal(0, result._MapDataGroups.Count2); Assert.Equal(0ul, result._MapDataGroups.Pointer); Assert.Equal(0, result._imapDependencies.Count1); Assert.Equal(0, result._imapDependencies.Count2); Assert.Equal(0ul, result._imapDependencies.Pointer); Assert.Equal(0, result._imapDependencies_2.Count1); Assert.Equal(0, result._imapDependencies_2.Count2); Assert.Equal(0ul, result._imapDependencies_2.Pointer); Assert.Equal(0, result._itypDependencies_2.Count1); Assert.Equal(0, result._itypDependencies_2.Count2); Assert.Equal(0ul, result._itypDependencies_2.Pointer); } } public class MetaTypesTests { private readonly ITestOutputHelper _output; public MetaTypesTests(ITestOutputHelper testOutputHelper) { _output = testOutputHelper; } [Fact] public void TestConvertData() { var data = BitConverter.GetBytes((uint)1234); var number = MetaTypes.ConvertData(data); Assert.Equal(1234U, number); } [Fact] public void Test_Convert_Data_From_Bytes() { var bytes = Convert.FromBase64String(TestData.ReferenceDataBytes); var newData = MetaTypes.ConvertData(bytes); Assert.Equivalent(TestData.ReferenceData, newData); } [Fact] public void Test_Convert_Data_From_Bytes_Offset() { var bytes = Convert.FromBase64String(TestData.ReferenceDataBytes); bytes = new byte[4].Concat(bytes).ToArray(); var newData = MetaTypes.ConvertData(bytes, 4); Assert.Equivalent(TestData.ReferenceData, newData); MetaTypes.TryConvertData(bytes, 4, out newData); Assert.Equivalent(TestData.ReferenceData, newData); } [Fact] public void Test_Convert_To_Bytes() { var bytes = MetaTypes.ConvertToBytes(TestData.ReferenceData); var bytesBase64 = Convert.ToBase64String(bytes); Assert.Equivalent(TestData.ReferenceDataBytes, bytesBase64); } [Fact] public void Test_Convert_Data_From_And_To_Bytes() { var bytes = MetaTypes.ConvertToBytes(TestData.ReferenceData); var newData = MetaTypes.ConvertData(bytes); Assert.Equivalent(TestData.ReferenceData, newData); } private readonly SharpDX.Vector3[] referenceArray = new SharpDX.Vector3[] { new SharpDX.Vector3(12.5f, 23.0f, 65.0f), new SharpDX.Vector3(1234.234f, 17896.22f, 9845.12f), new SharpDX.Vector3(-12.3f, -82349.123f, 1234.9f), new SharpDX.Vector3(-23412.4f, 1289.2f, 948.0f) }; private readonly string referenceArrayBytes = "AABIQQAAuEEAAIJCfUeaRHHQi0Z71BlGzcxEwZDWoMfNXJpEzei2xmYmoUQAAG1E"; [Fact] public void Test_Convert_Array_To_Bytes() { var bytes = MetaTypes.ConvertArrayToBytes(referenceArray); var base64 = Convert.ToBase64String(bytes); Assert.Equal(referenceArrayBytes, base64); } [Fact] public void Test_Convert_Bytes_To_Array() { var bytes = Convert.FromBase64String(referenceArrayBytes); var arr = MetaTypes.ConvertDataArray(bytes, 0, referenceArray.Length).ToArray(); Assert.Equal(referenceArray, arr); var newBytes = MetaTypes.ConvertArrayToBytes(arr); var base64 = Convert.ToBase64String(newBytes); Assert.Equal(referenceArrayBytes, base64); } [Fact] public void TestSwapBytes() { ushort testValue = (ushort)12345u; ushort result = MetaTypes.SwapBytes(testValue); Assert.Equal(14640, result); Assert.Equal(testValue, MetaTypes.SwapBytes(result)); uint testValueUInt = 12345u; uint resultUInt = MetaTypes.SwapBytes(testValueUInt); Assert.Equal(959447040u, resultUInt); Assert.Equal(testValueUInt, MetaTypes.SwapBytes(resultUInt)); int testValueInt = 12345; int resultInt = MetaTypes.SwapBytes(testValueInt); Assert.Equal(959447040, resultInt); Assert.Equal(testValueInt, MetaTypes.SwapBytes(resultInt)); short testValueShort = (short)12345; short resultShort = MetaTypes.SwapBytes(testValueShort); Assert.Equal(14640, resultShort); Assert.Equal(testValueShort, MetaTypes.SwapBytes(resultShort)); ulong testValueUlong = 0x123456789ABCDEFFUL; ulong resultUlong = MetaTypes.SwapBytes(testValueUlong); Assert.Equal(0x78563412FFDEBC9AUL, resultUlong); Assert.Equal(testValueUlong, MetaTypes.SwapBytes(resultUlong)); float testValueFloat = 12345.12345f; float resultFloat = MetaTypes.SwapBytes(testValueFloat); Assert.Equal(1.5169885490328965E+38, resultFloat); Assert.Equal(testValueFloat, MetaTypes.SwapBytes(resultFloat)); } } public class TestResourceData { [Fact] public void Test_Write_Struct() { using var systemStream = new MemoryStream(); using var graphicsStream = new MemoryStream(); using var dataWriter = new ResourceDataWriter(systemStream, graphicsStream); dataWriter.Position = 0x50000000; dataWriter.WriteStruct(TestData.ReferenceData); var buffer = systemStream.ToArray(); var base64 = Convert.ToBase64String(buffer); Assert.Equal(TestData.ReferenceDataBytes, base64); } [Fact] public void Test_Read_Struct() { var buffer = Convert.FromBase64String(TestData.ReferenceDataBytes); using var systemStream = new MemoryStream(buffer); using var graphicsStream = new MemoryStream(); using var dataReader = new ResourceDataReader(systemStream, graphicsStream); var region = dataReader.ReadStruct(); Assert.Equal(TestData.ReferenceData, region); } [Fact] public void Test_Write_Single() { using var systemStream = new MemoryStream(); using var graphicsStream = new MemoryStream(); using var dataWriter = new ResourceDataWriter(systemStream, graphicsStream); dataWriter.Position = 0x50000000; dataWriter.Write(20.0f); var buffer = systemStream.ToArray(); var result = BitConverter.ToSingle(buffer, 0); Assert.Equal(20.0f, result); } [Fact] public void Test_Write_Single_Big_Endian() { using var systemStream = new MemoryStream(); using var graphicsStream = new MemoryStream(); using var dataWriter = new ResourceDataWriter(systemStream, graphicsStream, Endianess.BigEndian); dataWriter.Position = 0x50000000; dataWriter.Write(20.0f); var buffer = systemStream.ToArray(); var valueInt = BinaryPrimitives.ReadInt32BigEndian(buffer); var valueFloat = Unsafe.ReadUnaligned(ref Unsafe.As(ref valueInt)); //BinaryPrimitives.ReverseEndianness(20.0f) Assert.Equal(20.0f, valueFloat); dataWriter.Position = 0x50000000; dataWriter.Write(double.MaxValue); buffer = systemStream.ToArray(); var valueLong = BinaryPrimitives.ReadInt64BigEndian(buffer); var valueDouble = Unsafe.ReadUnaligned(ref Unsafe.As(ref valueLong)); Assert.Equal(double.MaxValue, valueDouble); } [Fact] public void Test_Write_Multiple_Structs() { using var systemStream = new MemoryStream(); using var graphicsStream = new MemoryStream(); using var dataWriter = new ResourceDataWriter(systemStream, graphicsStream); dataWriter.Position = 0x50000000; dataWriter.WriteStructs(new[] { TestData.ReferenceData, TestData.ReferenceData, TestData.ReferenceData, TestData.ReferenceData }); var buffer = systemStream.ToArray(); var structs = MemoryMarshal.Cast(buffer); Assert.Equal(4, structs.Length); foreach (var scenarioRegion in structs) { Assert.Equal(TestData.ReferenceData, scenarioRegion); } } [Fact] public void Test_Read_Multiple_Structs() { using var systemStream = new MemoryStream(); using var graphicsStream = new MemoryStream(); using var dataWriter = new ResourceDataWriter(systemStream, graphicsStream); dataWriter.Position = 0x50000000; dataWriter.WriteStructs(new[] { TestData.ReferenceData, TestData.ReferenceData, TestData.ReferenceData, TestData.ReferenceData }); var buffer = systemStream.ToArray(); systemStream.Position = 0; var dataReader = new ResourceDataReader(systemStream, graphicsStream); var structs = dataReader.ReadStructs(4); Assert.Equal(4, structs.Length); foreach (var scenarioRegion in structs) { Assert.Equal(TestData.ReferenceData, scenarioRegion); } structs = dataReader.ReadStructsAt(0 | 0x50000000, 4); foreach (var scenarioRegion in structs) { Assert.Equal(TestData.ReferenceData, scenarioRegion); } systemStream.Position = 0; dataWriter.Position = 0x50000000; dataWriter.Write(new byte[] { 0, 0, 0, 0 }); dataWriter.WriteStructs(new[] { TestData.ReferenceData, TestData.ReferenceData, TestData.ReferenceData, TestData.ReferenceData }); structs = dataReader.ReadStructsAt(4 | 0x50000000, 4); foreach (var scenarioRegion in structs) { Assert.Equal(TestData.ReferenceData, scenarioRegion); } } //[Fact] //public void Test() //{ // var attachedObjects = MetaTypes.GetUintArray(meta, _Data.attachedObjects); //} private const string ArchetypeData = "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"; private readonly CBaseArchetypeDef referenceArchetype = new CBaseArchetypeDef { assetName = new MetaHash((uint)0x1d0b5555), assetType = rage__fwArchetypeDef__eAssetType.ASSET_TYPE_DRAWABLE, bbMax = new SharpDX.Vector3(3.617807f, 4.9E-05f, 0.447415f), bbMin = new SharpDX.Vector3(-3.617834f, -5.1E-05f, -0.447416f), bsCentre = new SharpDX.Vector3(-1.3589859E-05f, -1.00000034E-06f, -5.066395E-07f), bsRadius = 3.645381f, hdTextureDist = 5, lodDist = 100, Unused05 = float.NaN, Unused06 = float.NaN, Unused07 = float.NaN, name = new MetaHash((uint)0x1d0b5555), textureDictionary = new MetaHash((uint)0x5e0cce25), flags = 0x00002000, }; [Fact] public void TestConvertDataRaw() { var data = Convert.FromBase64String(ArchetypeData); var basearch = PsoTypes.ConvertDataRawOld(data, 0); Assert.Equivalent(referenceArchetype, basearch); var basearch2 = PsoTypes.ConvertDataRaw(data, 0); Assert.Equivalent(basearch, basearch2); var random = new Random(); var length = random.Next(100); var newData = Enumerable.Empty().Concat(new byte[length]).Concat(data).ToArray(); basearch = PsoTypes.ConvertDataRawOld(newData, length); Assert.Equivalent(basearch, referenceArchetype); basearch2 = PsoTypes.ConvertDataRaw(newData, length); Assert.Equivalent(basearch, basearch2); //a.Extensions = MetaTypes.GetExtensions(Meta, basearch.extensions); } } public class TestConvertDataArray { private readonly ITestOutputHelper _output; public TestConvertDataArray(ITestOutputHelper output) { _output = output; } private static string GetFilePath(string filename) { // Directory we're looking for. var dirToFind = Path.Combine(@"CodeWalker.Test", "Files"); // Search up directory tree starting at assembly path looking for 'Images' dir. var searchPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); while (true) { var testPath = Path.Combine(searchPath, dirToFind); if (Directory.Exists(testPath)) { // Found it! return Path.Combine(testPath, filename); } // Move up one directory. var newSearchPath = Path.GetFullPath(Path.Combine(searchPath, "..")); if (newSearchPath == searchPath) { // Didn't move up, so we're at the root. throw new FileNotFoundException($"Could not find '{dirToFind}' directory."); } searchPath = newSearchPath; } } public string TestData = "AAAAAAAAAAAFAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAKDAAACgwAAAAMAAAAAAAACgQAAAoEAAAABAAAAAAAAAgD9kViJCAAAAAGAAAAABAAAAAAAAAP////8AAAAABgAAAAAAAAABAAEAAAAAAAAAAAAAAAAABWAAAAAAAAAKAAoAAAAAAAAAAAAAAAAAgPEnwiB/QcIAcFzBAAAAAADgDsL9ke/BHKgswQAAAAAAAIA/yyTUkwAAAABgAAAAAQAAAAEAAAD/////AAAAAAYAAQAAAAAALgAuAAAAAAA="; [Fact] public void ConvertDataArrayShouldReturnSameAsConvertData() { var data = Convert.FromBase64String(TestData); var referenceData = MetaTypes.ConvertData(data); var arrayData = MetaTypes.ConvertDataArray(data, 0, 2); var path = GetFilePath("anwblokaal.ytyp"); var bytes = File.ReadAllBytes(path); var entry = RpfFile.CreateFileEntry("anwblokaal.ytyp", path, ref bytes); var ytypFile = RpfFile.GetFile(entry, bytes); var rooms = ytypFile.AllArchetypes .Where(p => p is MloArchetype) .Select(p => p as MloArchetype) .SelectMany(p => p.rooms) .Select(p => p.Data); var secondRoom = rooms.Last(); var arr = new byte[Marshal.SizeOf() * rooms.Count()]; //MemoryMarshal.Write(arr.AsSpan(), ref rooms); _output.WriteLine(Convert.ToBase64String(MemoryMarshal.AsBytes(rooms.ToArray().AsSpan()))); // I know the bbMax values don't really make sense here, seems to be a weird ytyp, but it's mostly about testing the serialization, not about using a 100% correct ytyp // And didn't want to include a ytyp from Rockstar Games since that could cause some legal issues down the road // Another possible solution would be to do abest attempt to find the GTA V installed on the user's computer running the tests and use files from there, but this would add complexity and links which could break tests // However this would be more in the scope of implementation testing as it tests the whole chain including encryption which is not wanted here Assert.Equivalent(new SharpDX.Vector3(-41.98584f, -48.3741455f, -13.7773438f), secondRoom.bbMin); Assert.Equivalent(new SharpDX.Vector3(-35.71875f, -29.9462833f, -10.7910423f), secondRoom.bbMax); Assert.Equivalent(new Array_uint(65542, 46), secondRoom.attachedObjects); Assert.Equal(96u, secondRoom.flags); Assert.Equal(1, secondRoom.floorId); Assert.Equivalent(new CharPointer() { Count1 = 10, Count2 = 10, Pointer = 24581 }, secondRoom.name); Assert.Equal(1u, secondRoom.portalCount); Assert.Equal(2480153803, secondRoom.timecycleName.Hash); // First room is limbo, so this check isn't that useful, but just make sure, and the following check will compare the entire array anyways Assert.Equivalent(referenceData, rooms.First()); Assert.Equivalent(arrayData.ToArray(), rooms); } } }