Skip to content
Draft
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace moddingSuite.Test
{
Expand All @@ -13,5 +8,6 @@ public abstract class BaseTests
protected string RedDragonGameDataPath => TestContext.Properties["reddragonData"] as string;
protected string AirLandGameDataPath => TestContext.Properties["airlandData"] as string;
protected string AirLandUserDataPath => TestContext.Properties["airlandUserPath"] as string;
protected string RedDragonLinuxGameDataPath => TestContext.Properties["linuxReddragonData"] as string;
}
}
Original file line number Diff line number Diff line change
@@ -1,63 +1,65 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using moddingSuite.BL;
using System.IO;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using moddingSuite.BL;
using moddingSuite.Model.Edata;
using System.IO;
using System.Linq;

namespace moddingSuite.Test
{
[TestClass]
public class EdataManagerTest: BaseTests
{

namespace moddingSuite.Test
{
[TestClass]
public class EdataManagerTest: BaseTests
{
[DataTestMethod]
[DataRow("/48574/Data")]
[DataRow("/48574/DataMap")]
[DataRow("/48574/NDF_NotFinal")]
[DataRow("/48574/NDF_Win")]
[DataRow("/48574/ZZ_1")]
[DataRow("/48574/ZZ_2")]
[DataRow("/48574/ZZ_3a")]
[DataRow("/48574/ZZ_3b")]
[DataRow("/48574/ZZ_4")]
[DataRow("/48574/ZZ_NotFinal")]
[DataRow("/48574/ZZ_Win")]
[DataRow("/49125/NDF_Win")]
[DataRow("/49964/NDF_Win")]
public void CanParseRedDragonHeader(string path)
{
var sut = new EdataManager($"{RedDragonGameDataPath}{path}.dat");
sut.ParseEdataFile();
sut.Files.Should().NotBeEmpty();
[DataRow("/48574/NDF_NotFinal")]
[DataRow("/48574/NDF_Win")]
[DataRow("/48574/ZZ_1")]
[DataRow("/48574/ZZ_2")]
[DataRow("/48574/ZZ_3a")]
[DataRow("/48574/ZZ_3b")]
[DataRow("/48574/ZZ_4")]
[DataRow("/48574/ZZ_NotFinal")]
[DataRow("/48574/ZZ_Win")]
[DataRow("/49125/NDF_Win")]
[DataRow("/49964/NDF_Win")]
public void CanParseRedDragonHeader(string path)
{
var sut = new EdataManager($"{RedDragonGameDataPath}{path}.dat");
sut.ParseEdataFile();
sut.Files.Should().NotBeEmpty();
}

[DataTestMethod]
[DataRow("/49125/NDF_Win")]
[DataRow("/49964/NDF_Win")]
[DataRow("/48574/NDF_Win")]
public void CanReadRawData(string path)
{
var manager = new EdataManager($"{RedDragonGameDataPath}{path}.dat");
manager.ParseEdataFile();

var config = manager.Files.First(f => f.Path == @"pc\ndf\nonpatchable\config.ndfbin");
var bytes = manager.GetRawData(config);
bytes.Should().NotBeEmpty();
[DataRow("/49125/NDF_Win")]
[DataRow("/49964/NDF_Win")]
[DataRow("/48574/NDF_Win")]
public void CanReadRawData(string path)
{
var manager = new EdataManager($"{RedDragonGameDataPath}{path}.dat");
manager.ParseEdataFile();

var config = manager.Files.First(f => f.Path == EdataManager.KnownLocation.Config);
config.FileType.Should().Be(EdataFileType.Ndfbin);
var bytes = manager.GetRawData(config);
bytes.Should().NotBeEmpty();
}

[TestMethod]
public void CanParseAirLandBattleHeader()
{
var files = Directory.EnumerateFiles(AirLandGameDataPath, "*.dat", SearchOption.AllDirectories);
var count = 0;
public void CanParseAirLandBattleHeader()
{
var files = Directory.EnumerateFiles(AirLandGameDataPath, "*.dat", SearchOption.AllDirectories);
var count = 0;
foreach(var file in files)
{
var sut = new EdataManager(file);
sut.ParseEdataFile();
sut.Header.Magic.Should().BeGreaterThan(0);
count++;
}
count.Should().BeGreaterThan(0);
}
}
}
}
count.Should().BeGreaterThan(0);
}
}
}
49 changes: 49 additions & 0 deletions moddingSuite.BL.Test/TradManagerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using moddingSuite.BL;
using moddingSuite.Model.Edata;
using System.IO;
using System.Linq;

namespace moddingSuite.Test
{
[TestClass]
public class TradManagerTest: BaseTests
{
[DataTestMethod]
[DataRow("/48574/ZZ_Win")]
public void CanParseWindowsReadRawData(string path)
{
var manager = new EdataManager($"{RedDragonGameDataPath}{path}.dat");
AssertAntiRadar(manager, StringType.Default);
}

private static void AssertAntiRadar(EdataManager manager, StringType stringType)
{
AssertUnites("DC02000000000000", "Anti-Radar", manager, stringType);
}

private static void AssertUnites(string hashView, string content, EdataManager manager, StringType stringType)
{
manager.ParseEdataFile();

var unites = manager.Files.First(f => f.Path == EdataManager.KnownLocation.Unites);
unites.FileType.Should().Be(EdataFileType.Dictionary);
var bytes = manager.GetRawData(unites);
bytes.Should().NotBeEmpty();

var tradManager = new TradManager(bytes, stringType);
tradManager.Entries.Should().NotBeEmpty();
var antiRadar = tradManager.Entries.First(t => t.HashView == hashView);
antiRadar.Content.Should().Be(content);
}

[DataTestMethod]
[DataRow("/430000319/ZZ_Linux")]
public void CanParseLinuxReadRawData(string path)
{
var manager = new EdataManager($"{RedDragonLinuxGameDataPath}{path}.dat");
AssertAntiRadar(manager, StringType.Utf32);
}
}
}
21 changes: 21 additions & 0 deletions moddingSuite.BL.Test/UtilsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using moddingSuite.BL.Utils;

namespace moddingSuite.BL.Test
{
[TestClass]
public class UtilsTests
{

[DataTestMethod]
[DataRow("K4", "4505000000000000")]
public void TestHash(string name, string expectedHashView)
{
var hash = StdUtils.CreateLocalisationHash(name, name.Length);

var newHashView = StdUtils.ByteArrayToBigEndianHexByteString(hash);
newHashView.Should().Be(expectedHashView);
}
}
}
24 changes: 24 additions & 0 deletions moddingSuite.BL.Test/moddingSuite.BL.Test.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;net5.0</TargetFrameworks>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.4" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.4" />
<PackageReference Include="coverlet.collector" Version="3.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\moddingSuite.BL\moddingSuite.BL.csproj" />
</ItemGroup>

</Project>
57 changes: 43 additions & 14 deletions moddingSuite/BL/EdataManager.cs → moddingSuite.BL/EdataManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,56 @@
using System.Security.Cryptography;
using System.Text;
using moddingSuite.Model.Edata;
using moddingSuite.Util;
using System.Runtime.InteropServices;
using moddingSuite.ViewModel.Base;
using BLUtils = moddingSuite.BL.Utils.StdUtils;

namespace moddingSuite.BL
{
{

public enum OSPlatform
{
Generic,
Windows,
Linux
}

/// <summary>
/// Thanks to Giovanni Condello. He created the "WargameEE DAT unpacker" which is the base for my EdataManager.
/// TODO: implement virtual packages.
/// </summary>
public class EdataManager : ViewModelBase
{
{

public static class KnownLocation
{

public const string Unites = @"pc\localisation\us\localisation\unites.dic";
public const string Config = @"pc\ndf\nonpatchable\config.ndfbin";

}

public static readonly byte[] EdataMagic = { 0x65, 0x64, 0x61, 0x74 };

public OSPlatform Platform { get; private set; }

/// <summary>
/// Creates a new Instance of a EdataManager.
/// </summary>
/// <param name="filePath">The package file which is to be managed.</param>
public EdataManager(string filePath)
{
FilePath = filePath;
Platform = DetectOSSpecificString(FilePath);
}

private static OSPlatform DetectOSSpecificString(string filePath)
{
var name = Path.GetFileNameWithoutExtension(filePath);
if (name == "ZZ_Linux") return OSPlatform.Linux;
else if (name == "ZZ_Win") return OSPlatform.Windows;
else return OSPlatform.Generic;

}

static EdataManager()
Expand Down Expand Up @@ -123,7 +152,7 @@ protected EdataHeader ReadEdataHeader()
using (var fs = File.Open(FilePath, FileMode.Open))
fs.Read(buffer, 0, buffer.Length);

header = Utils.ByteArrayToStructure<EdataHeader>(buffer);
header = Utils.StdUtils.ByteArrayToStructure<EdataHeader>(buffer);

if (header.Version > 2)
throw new NotSupportedException(string.Format("Edata version {0} not supported", header.Version));
Expand Down Expand Up @@ -171,7 +200,7 @@ protected ObservableCollection<EdataContentFile> ReadEdatV2Dictionary()
fileStream.Read(checkSum, 0, checkSum.Length);
file.Checksum = checkSum;

file.Name = Utils.ReadString(fileStream);
file.Name = BLUtils.ReadString(fileStream);
file.Path = MergePath(dirs, file.Name);

if (file.Name.Length % 2 == 0)
Expand Down Expand Up @@ -202,7 +231,7 @@ protected ObservableCollection<EdataContentFile> ReadEdatV2Dictionary()
else if (endings.Count > 0)
endings.Add(endings.Last());

dir.Name = Utils.ReadString(fileStream);
dir.Name = BLUtils.ReadString(fileStream);

if (dir.Name.Length % 2 == 0)
fileStream.Seek(1, SeekOrigin.Current);
Expand Down Expand Up @@ -251,7 +280,7 @@ protected ObservableCollection<EdataContentFile> ReadEdatV1Dictionary()
//file.Checksum = checkSum;
fileStream.Seek(1, SeekOrigin.Current); //instead, skip 1 byte - as in WEE DAT unpacker

file.Name = Utils.ReadString(fileStream);
file.Name = Utils.StdUtils.ReadString(fileStream);
file.Path = MergePath(dirs, file.Name);

if ((file.Name.Length + 1) % 2 == 0)
Expand Down Expand Up @@ -282,7 +311,7 @@ protected ObservableCollection<EdataContentFile> ReadEdatV1Dictionary()
else if (endings.Count > 0)
endings.Add(endings.Last());

dir.Name = Utils.ReadString(fileStream);
dir.Name = BLUtils.ReadString(fileStream);

if ((dir.Name.Length + 1) % 2 == 1)
fileStream.Seek(1, SeekOrigin.Current);
Expand Down Expand Up @@ -397,7 +426,7 @@ protected string ReplaceRebuildV2(EdataContentFile oldFile, byte[] newContent)
byte[] checkSum = curFile.Checksum;
newFile.Write(checkSum, 0, checkSum.Length);

string name = Utils.ReadString(newFile);
string name = BLUtils.ReadString(newFile);

if ((name.Length + 1) % 2 == 1)
newFile.Seek(1, SeekOrigin.Current);
Expand All @@ -407,7 +436,7 @@ protected string ReplaceRebuildV2(EdataContentFile oldFile, byte[] newContent)
else if (fileGroupId > 0)
{
newFile.Seek(4, SeekOrigin.Current);
string name = Utils.ReadString(newFile);
string name = BLUtils.ReadString(newFile);

if ((name.Length + 1) % 2 == 1)
newFile.Seek(1, SeekOrigin.Current);
Expand Down Expand Up @@ -501,7 +530,7 @@ protected string ReplaceRebuildV1(EdataContentFile oldFile, byte[] newContent)

newFile.Seek(1, SeekOrigin.Current);

string name = Utils.ReadString(newFile);
string name = BLUtils.ReadString(newFile);

if ((name.Length + 1) % 2 == 0)
newFile.Seek(1, SeekOrigin.Current);
Expand All @@ -511,7 +540,7 @@ protected string ReplaceRebuildV1(EdataContentFile oldFile, byte[] newContent)
else if (fileGroupId > 0)
{
newFile.Seek(4, SeekOrigin.Current);
string name = Utils.ReadString(newFile);
string name = BLUtils.ReadString(newFile);

if ((name.Length + 1) % 2 == 1)
newFile.Seek(1, SeekOrigin.Current);
Expand Down Expand Up @@ -604,11 +633,11 @@ public static EdataFileType GetFileTypeFromHeaderData(byte[] headerData)
Array.Copy(headerData, tmp, knownHeader.Value.Length);
//headerData = tmp;

if (Utils.ByteArrayCompare(tmp, knownHeader.Value))
if (BLUtils.ByteArrayCompare(tmp, knownHeader.Value))
return knownHeader.Key;
}
else
if (Utils.ByteArrayCompare(headerData, knownHeader.Value))
if (BLUtils.ByteArrayCompare(headerData, knownHeader.Value))
return knownHeader.Key;
}

Expand Down
Loading