mirror of
https://github.com/kwsch/pk3DS.git
synced 2026-10-03 06:16:55 -05:00
Relative offset fix
FileOffset is relative to the entire DARC file, not the data array. Also extracted the insertFile method
This commit is contained in:
@@ -212,8 +212,18 @@ internal static DARC getDARC(string folderName)
|
||||
// Fix the First two folders to specify the number of files
|
||||
darc.Entries[0].DataLength = (uint)darcFileCount;
|
||||
darc.Entries[1].DataLength = (uint)darcFileCount;
|
||||
|
||||
// Fix the Data Offset of the files to point to actual destination
|
||||
foreach (FileTableEntry f in darc.Entries.Where(x => !x.IsFolder))
|
||||
f.DataOffset += darc.Header.FileDataOffset;
|
||||
return darc;
|
||||
}
|
||||
|
||||
internal static bool darc2files(string path, string folderName)
|
||||
{
|
||||
try { return darc2files(File.ReadAllBytes(path), folderName); }
|
||||
catch (Exception) { return false; }
|
||||
}
|
||||
internal static bool darc2files(byte[] darc, string folderName)
|
||||
{
|
||||
// Save all contents of a DARC to a folder, assuming there's only 1 layer of folders.
|
||||
@@ -243,7 +253,7 @@ internal static bool darc2files(byte[] darc, string folderName)
|
||||
string fileName = DARC.FileNameTable[i].FileName;
|
||||
int offset = (int)DARC.Entries[i].DataOffset;
|
||||
int length = (int)DARC.Entries[i].DataLength;
|
||||
byte[] data = DARC.Data.Skip(offset).Take(length).ToArray();
|
||||
byte[] data = DARC.Data.Skip((int)(offset - DARC.Header.FileDataOffset)).Take(length).ToArray();
|
||||
|
||||
string outPath = Path.Combine(root, parentName, fileName);
|
||||
File.WriteAllBytes(outPath, data);
|
||||
@@ -304,6 +314,35 @@ internal static int getDARCposition(byte[] data)
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
internal static bool insertFile(DARC orig, int index, string path)
|
||||
{
|
||||
try { return insertFile(orig, index, File.ReadAllBytes(path)); }
|
||||
catch (Exception) { return false; }
|
||||
}
|
||||
internal static bool insertFile(DARC orig, int index, byte[] data)
|
||||
{
|
||||
if (index < 0) return false;
|
||||
|
||||
try
|
||||
{
|
||||
uint oldLength = orig.Entries[index].DataLength;
|
||||
uint offset = orig.Entries[index].DataOffset;
|
||||
int diff = (int) (data.Length - oldLength);
|
||||
|
||||
// Insert into Data Block
|
||||
byte[] pre = orig.Data.Take((int) offset).ToArray();
|
||||
byte[] post = orig.Data.Skip((int) (offset + oldLength)).ToArray();
|
||||
|
||||
// Reassemble data
|
||||
orig.Data = pre.Concat(data).Concat(post).ToArray();
|
||||
|
||||
// Fix Offset references of other files
|
||||
foreach (var x in orig.Entries.Where(x => x.DataOffset >= offset + oldLength))
|
||||
x.DataOffset += (uint) diff;
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { return false; }
|
||||
}
|
||||
internal static DARC insertFiles(DARC orig, string folderName)
|
||||
{
|
||||
string[] fileNames = new string[orig.Entries.Count()];
|
||||
@@ -318,28 +357,13 @@ internal static DARC insertFiles(DARC orig, string folderName)
|
||||
{
|
||||
FileInfo fi = new FileInfo(file);
|
||||
string FileName = fi.Name;
|
||||
int length = (int)fi.Length;
|
||||
|
||||
// Get Index of file
|
||||
int index = Array.IndexOf(fileNames, FileName);
|
||||
if (orig.Entries[index].IsFolder)
|
||||
throw new Exception(file + " is not a valid file to reinsert!");
|
||||
if (index < 0) continue;
|
||||
uint oldLength = orig.Entries[index].DataLength;
|
||||
uint offset = orig.Entries[index].DataOffset;
|
||||
int diff = (int)(length - oldLength);
|
||||
|
||||
// Insert into Data Block
|
||||
byte[] pre = orig.Data.Take((int)offset).ToArray();
|
||||
byte[] data = File.ReadAllBytes(file);
|
||||
byte[] post = orig.Data.Skip((int)(offset + oldLength)).ToArray();
|
||||
|
||||
// Reassemble data
|
||||
orig.Data = pre.Concat(data).Concat(post).ToArray();
|
||||
|
||||
// Fix Offset references of other files
|
||||
foreach (var x in orig.Entries.Where(x => x.DataOffset >= offset + oldLength))
|
||||
x.DataOffset += (uint)diff;
|
||||
insertFile(orig, index, file);
|
||||
}
|
||||
}
|
||||
// Fix Data layout
|
||||
|
||||
Reference in New Issue
Block a user