mirror of
https://github.com/sampletext32/ParkanPlayground.git
synced 2025-10-13 23:10:23 +03:00
improvements
This commit is contained in:
@@ -6,7 +6,26 @@ public record CpDatEntry(
|
||||
int Magic1,
|
||||
int Magic2,
|
||||
string Description,
|
||||
int Magic3,
|
||||
DatEntryType Type,
|
||||
int ChildCount, // игра не хранит это число в объекте, но оно есть в файле
|
||||
List<CpDatEntry> Children
|
||||
);
|
||||
);
|
||||
|
||||
// Magic3 seems to be a type
|
||||
// 0 - chassis
|
||||
// 1 - turret (у зданий почему-то дефлектор тоже 1), может быть потому, что дефлектор вращается так же как башня у юнитов
|
||||
// 2 - armour
|
||||
// 3 - part
|
||||
// 4 - cannon
|
||||
// 5 - ammo
|
||||
|
||||
public enum DatEntryType
|
||||
{
|
||||
Unspecified = -1,
|
||||
Chassis = 0,
|
||||
Turret = 1,
|
||||
Armour = 2,
|
||||
Part = 3,
|
||||
Cannon = 4,
|
||||
Ammo = 5,
|
||||
}
|
@@ -6,23 +6,29 @@ public class CpDatParser
|
||||
{
|
||||
public static CpDatParseResult Parse(string filePath)
|
||||
{
|
||||
Span<byte> f0f1 = stackalloc byte[4];
|
||||
|
||||
using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
return Parse(fs);
|
||||
}
|
||||
|
||||
public static CpDatParseResult Parse(Stream fs)
|
||||
{
|
||||
Span<byte> f0f1 = stackalloc byte[4];
|
||||
|
||||
if (fs.Length < 8)
|
||||
return new CpDatParseResult(null, "File too small to be a valid \"cp\" .dat file.");
|
||||
|
||||
fs.ReadExactly(f0f1);
|
||||
|
||||
|
||||
if (f0f1[0] != 0xf1 || f0f1[1] != 0xf0)
|
||||
{
|
||||
return new CpDatParseResult(null, "File does not start with expected header bytes f1_f0");
|
||||
}
|
||||
|
||||
|
||||
var schemeType = (SchemeType)fs.ReadInt32LittleEndian();
|
||||
|
||||
var entryLength = 0x6c + 4; // нам нужно прочитать 0x6c (108) байт - это root, и ещё 4 байта - кол-во вложенных объектов
|
||||
var entryLength =
|
||||
0x6c + 4; // нам нужно прочитать 0x6c (108) байт - это root, и ещё 4 байта - кол-во вложенных объектов
|
||||
if ((fs.Length - 8) % entryLength != 0)
|
||||
{
|
||||
return new CpDatParseResult(null, "File size is not valid according to expected entry length.");
|
||||
@@ -35,7 +41,7 @@ public class CpDatParser
|
||||
return new CpDatParseResult(scheme, null);
|
||||
}
|
||||
|
||||
private static CpDatEntry ReadEntryRecursive(FileStream fs)
|
||||
private static CpDatEntry ReadEntryRecursive(Stream fs)
|
||||
{
|
||||
var str1 = fs.ReadNullTerminatedString();
|
||||
|
||||
@@ -47,22 +53,22 @@ public class CpDatParser
|
||||
var magic1 = fs.ReadInt32LittleEndian();
|
||||
var magic2 = fs.ReadInt32LittleEndian();
|
||||
|
||||
var descriptionString = fs.ReadNullTerminatedString();
|
||||
var descriptionString = fs.ReadNullTerminated1251String();
|
||||
|
||||
fs.Seek(32 - descriptionString.Length - 1, SeekOrigin.Current); // -1 ignore null terminator
|
||||
var magic3 = fs.ReadInt32LittleEndian();
|
||||
var type = (DatEntryType)fs.ReadInt32LittleEndian();
|
||||
|
||||
// игра не читает количество внутрь схемы, вместо этого она сразу рекурсией читает нужно количество вложенных объектов
|
||||
var childCount = fs.ReadInt32LittleEndian();
|
||||
|
||||
|
||||
List<CpDatEntry> children = new List<CpDatEntry>(childCount);
|
||||
|
||||
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
var child = ReadEntryRecursive(fs);
|
||||
children.Add(child);
|
||||
}
|
||||
|
||||
return new CpDatEntry(str1, str2, magic1, magic2, descriptionString, magic3, childCount, Children: children);
|
||||
return new CpDatEntry(str1, str2, magic1, magic2, descriptionString, type, childCount, Children: children);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user