Ajoutez des fichiers projet.

This commit is contained in:
zenar 2021-10-13 13:25:24 +02:00
parent 6cd06acb9c
commit b6067401f4
6 changed files with 386 additions and 0 deletions

25
PKGTool.sln Normal file
View file

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31727.386
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PKGTool", "PKGTool\PKGTool.csproj", "{C882EC56-0245-481E-B2F2-3C7336B7963A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C882EC56-0245-481E-B2F2-3C7336B7963A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C882EC56-0245-481E-B2F2-3C7336B7963A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C882EC56-0245-481E-B2F2-3C7336B7963A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C882EC56-0245-481E-B2F2-3C7336B7963A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FBC66971-6591-422B-AF47-66D00A35825C}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Dread.FileFormats
{
public class PKG : Misc.Structs.BinaryStruct
{
public List<KeyValuePair<UInt64, MemoryStream>> Files = new List<KeyValuePair<UInt64, MemoryStream>>();
public void Close()
{
foreach (var file in Files)
file.Value.Close();
Files.Clear();
}
Int32[,] GenerateFileOffsets()
{
Int32 i = 0;
Int32[,] offsets = new Int32[Files.Count, 2];
Int32 cursor = 12 + Files.Count * 16;
if ((cursor % 8) != 0) cursor += 8 - (cursor % 8);
foreach (var file in Files)
{
offsets[i, 0] = cursor;
cursor += (Int32)file.Value.Length;
offsets[i, 1] = cursor;
if ((cursor % 8) != 0) cursor += 8 - (cursor % 8);
i++;
}
return offsets;
}
public override int StructSize
{
get
{
int len = 12 + Files.Count * 16;
if ((len % 8) != 0) len += 8 - (len % 8);
foreach (var file in Files)
{
len += (int)file.Value.Length;
if((len % 8) != 0) len += 8 - (len % 8);
}
return len;
}
}
public override void import(Stream stream)
{
Int32 i, data_section_start;
List<UInt64> IDs = new List<UInt64>();
List<Int32[]> Offsets = new List<Int32[]>();
var reader = new BinaryReader(stream);
Int32 header_size = reader.ReadInt32();
Int32 data_section_size = reader.ReadInt32();
Int32 file_count = reader.ReadInt32();
for(i = 0; i< file_count;i++)
{
Files.Add(new KeyValuePair<UInt64, MemoryStream>(reader.ReadUInt64(), new MemoryStream()));
Offsets.Add(new Int32[] { reader.ReadInt32(), reader.ReadInt32() });
}
if (header_size != (Int32)stream.Position)
throw new Exception("Invalid PKG file! (Guessed header size doesn't correspond to the real size)");
// padding
if ((stream.Position % 8) != 0) stream.Position += 8 - (stream.Position % 8);
data_section_start = (Int32)stream.Position;
for (i=0;i<file_count;i++)
{
if (Offsets[i][0] != (int)stream.Position)
throw new Exception("Wrong starting offset!");
Files[i].Value.Write(reader.ReadBytes(Offsets[i][1] - Offsets[i][0]));
Files[i].Value.Position = 0L;
// padding
if ((stream.Position % 8) != 0) stream.Position += 8 - (stream.Position % 8);
}
if (data_section_size != (Int32)stream.Position - data_section_start)
throw new Exception("Invalid PKG file! (Guessed data section size doesn't correspond to the real size)");
}
public override void export(Stream stream)
{
Int32 i, header_size, data_section_start, data_section_size;
Int32[,] offsets = GenerateFileOffsets();
var writer = new BinaryWriter(stream);
stream.Position += 8;
writer.Write(Files.Count);
for(i=0;i<Files.Count;i++)
{
writer.Write(Files[i].Key);
writer.Write(offsets[i, 0]);
writer.Write(offsets[i, 1]);
}
header_size = (Int32)stream.Position;
// padding
while (stream.Position % 8 != 0) writer.Write((byte)0);
data_section_start = (Int32)stream.Position;
for (i = 0; i < Files.Count; i++)
{
Files[i].Value.CopyTo(stream);
Files[i].Value.Position = 0L;
// padding
while (stream.Position % 8 != 0) writer.Write((byte)0);
}
data_section_size = (Int32)stream.Position - data_section_start;
stream.Position = 0L;
writer.Write(header_size);
writer.Write(data_section_size);
}
}
}

View file

@ -0,0 +1,12 @@
using System.IO;
namespace Misc.Structs
{
public abstract class BinaryStruct
{
public BinaryStruct() { }
public abstract void import(Stream stream);
public abstract void export(Stream stream);
public abstract int StructSize { get; }
}
}

8
PKGTool/PKGTool.csproj Normal file
View file

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

203
PKGTool/Program.cs Normal file
View file

@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace PKGTool
{
class Program
{
static void Usage()
{
Console.WriteLine("PKG Tool");
Console.WriteLine("-----------------------");
Console.WriteLine();
Console.WriteLine("Extract : PKGTool -x <input path> [-o <output path>");
Console.WriteLine("Create : PKGTool -c <input path> [-o <output path>");
}
static String GenerateFileName(UInt64 ID, MemoryStream File)
{
String fn = String.Empty;
BinaryReader reader = new BinaryReader(File);
String magic = Encoding.UTF8.GetString(reader.ReadBytes(4), 0, 4);
switch(magic)
{
case "\x1BLua":
fn = $"{ID:X16}.lc";
break;
case "\x6F\x7F\xF3\x73":
fn = $"{ID:X16}.bapd";
break;
case "BTXT":
fn = $"{ID:X16}.txt";
break;
case "CWAV":
fn = $"{ID:X16}.bcwav";
break;
case "FGRP":
fn = $"{ID:X16}.bfgrp";
break;
case "FSAR":
fn = $"{ID:X16}.bfsar";
break;
case "LSND":
fn = $"{ID:X16}.blsnd";
break;
case "LUT\x01":
fn = $"{ID:X16}.blut";
break;
case "MANM":
fn = $"{ID:X16}.bcskla";
break;
case "MFNT":
fn = $"{ID:X16}.bfont";
break;
case "MMDL":
fn = $"{ID:X16}.bcmdl";
break;
case "MNAV":
fn = $"{ID:X16}.bmnav";
break;
case "MPSI":
fn = $"{ID:X16}.bpsi";
break;
case "MSAD":
fn = $"{ID:X16}.bmsad";
break;
case "MSAS":
fn = $"{ID:X16}.bmsas";
break;
case "MSHD":
fn = $"{ID:X16}.bshdat";
break;
case "MSUR":
fn = $"{ID:X16}.bsmat";
break;
case "MTXT":
fn = $"{ID:X16}.bctex";
break;
case "MUCT":
fn = $"{ID:X16}.buct";
break;
default:
fn = $"{ID:X16}.bin";
break;
}
File.Position = 0;
return fn;
}
static void Main(string[] args)
{
FileStream tmp = null;
String fn = String.Empty;
String outPath = String.Empty;
Dread.FileFormats.PKG pkg = new Dread.FileFormats.PKG();
try
{
if (args.Length >= 2)
{
if (args[0] == "-x")
{
if (!File.Exists(args[1]))
throw new FileNotFoundException($"Couldn't find the file {args[1]}");
pkg.import(File.OpenRead(args[1]));
if (args.Length == 4)
{
if (args[2] == "-o")
outPath = args[2];
else
{
Usage();
return;
}
}
else if (args.Length == 2)
outPath = String.Join(Path.DirectorySeparatorChar, Directory.GetCurrentDirectory(), Path.GetFileNameWithoutExtension(args[1]));
else
{
Usage();
return;
}
if (!Directory.Exists(outPath))
Directory.CreateDirectory(outPath);
using(var list = new StreamWriter(String.Join(Path.DirectorySeparatorChar, outPath, "files.list")))
{
foreach (var file in pkg.Files)
{
fn = GenerateFileName(file.Key, file.Value);
Console.WriteLine($"Extracting {fn}...");
tmp = File.Open(String.Join(Path.DirectorySeparatorChar, outPath, fn), FileMode.Create, FileAccess.Write);
file.Value.CopyTo(tmp);
file.Value.Position = 0L;
tmp.Close();
list.WriteLine(fn);
}
}
pkg.Close();
}
else if (args[0] == "-c")
{
if (!Directory.Exists(args[1]))
throw new FileNotFoundException($"Couldn't find the folder {args[1]}");
if (!File.Exists(String.Join(Path.DirectorySeparatorChar, args[1], "files.list")))
throw new FileNotFoundException($"Couldn't find the file files.list");
if (args.Length == 4)
{
if (args[2] == "-o")
outPath = args[2];
else
{
Usage();
return;
}
}
else if (args.Length == 2)
outPath = String.Join(Path.DirectorySeparatorChar, Directory.GetCurrentDirectory(), Path.GetFileNameWithoutExtension(args[1]));
else
{
Usage();
return;
}
if (Path.GetExtension(outPath) == String.Empty)
outPath += ".pkg";
else if (Path.GetExtension(outPath).ToLower() != ".pkg")
outPath = Path.ChangeExtension(outPath, ".pkg");
using (var list = new StreamReader(String.Join(Path.DirectorySeparatorChar, args[1], "files.list")))
{
while (!list.EndOfStream)
{
fn = list.ReadLine().TrimEnd('\r', '\n');
Console.WriteLine($"Adding {fn}...");
pkg.Files.Add(new KeyValuePair<UInt64, MemoryStream>(Convert.ToUInt64("0x" + Path.GetFileNameWithoutExtension(fn), 16), new MemoryStream(File.ReadAllBytes(String.Join(Path.DirectorySeparatorChar, args[1], fn)))));
}
}
tmp = File.Open(outPath, FileMode.Create, FileAccess.Write);
pkg.export(tmp);
tmp.Close();
pkg.Close();
}
}
else
Usage();
} catch (Exception ex) {
Console.WriteLine("An error occured!");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
Console.WriteLine();
Console.WriteLine();
}
}
}
}

View file

@ -0,0 +1,8 @@
{
"profiles": {
"PKGTool": {
"commandName": "Project",
"commandLineArgs": "-c \"D:\\Projects\\PKGTool\\PKGTool\\bin\\Debug\\net5.0\\s010_cave\""
}
}
}