5 Commits

7 changed files with 180 additions and 79 deletions
Split View
  1. +16
    -0
      Hack.Xenosaga/Common/Extension.cs
  2. +1
    -43
      Hack.Xenosaga/Common/Functions.cs
  3. +6
    -1
      Hack.Xenosaga/Common/Variables.cs
  4. +4
    -2
      Hack.Xenosaga/Process/JavaClass.cs
  5. +134
    -17
      Hack.Xenosaga/Process/Scripts.cs
  6. +16
    -15
      Hack.Xenosaga/Process/Unpack.cs
  7. +3
    -1
      Hack.Xenosaga/Xenosaga.cs

+ 16
- 0
Hack.Xenosaga/Common/Extension.cs View File

@ -40,5 +40,21 @@ namespace Hack.Xenosaga.Common
return value;
}
/// <summary>
/// Pad a MemoryStream with a byte
/// </summary>
/// <param name="modulo">Modulo to use for the padding (default: 4)</param>
/// <param name="value">Value of the byte (default: 0)</param>
public static void Padding(this MemoryStream ms, int modulo = 4, byte value = 0)
{
long size = ms.Length;
while (size % modulo != 0)
{
ms.WriteByte(value);
size++;
}
}
}
}

+ 1
- 43
Hack.Xenosaga/Common/Functions.cs View File

@ -16,7 +16,7 @@ namespace Hack.Xenosaga.Common
Trace.WriteLine(" -p = Pack files from index");
Trace.WriteLine(" -e = Extract text from file");
Trace.WriteLine(" -i = Insert text from file");
Trace.WriteLine(" file : Index file (the first one of each decade : xenosaga.00, xenosaga.10, xenosaga.20...)");
Trace.WriteLine(" file : File to process (-l, -p, -u=Index file (the first one of each decade : xenosaga.00, xenosaga.10, xenosaga.20...) ; -e, -i : filename)");
Trace.WriteLine(" encode : (-e) Encoding of the output/input file (ANSI( default), ASCII, UTF8, UNICODE)");
Trace.WriteLine(" regroup : (-p) true to pack all files in only one (ex: 11, 12, 13 in 11) ; false or empty (default) to keep the same system of increment files");
}
@ -89,47 +89,5 @@ namespace Hack.Xenosaga.Common
return true;
}
public static void ManageListener(bool consoleTrace, bool fileTrace = false, StreamWriter sw = null)
{
string traceFileName = "TraceFile";
string traceConsoleName = "TraceConsole";
for (int i = 0; i < Trace.Listeners.Count; i++)
{
TraceListener trace = Trace.Listeners[i];
if (trace.Name == "Default" || (trace.Name == traceConsoleName && !consoleTrace) || (trace.Name == traceFileName && !fileTrace))
{
Trace.Listeners.Remove(trace);
trace.Dispose();
}
}
if (consoleTrace)
{
ConsoleTraceListener traceConsole = new ConsoleTraceListener();
traceConsole.Name = traceConsoleName;
Trace.Listeners.Add(traceConsole);
}
if (fileTrace)
{
TextWriterTraceListener traceFile = new TextWriterTraceListener(sw);
traceFile.Name = traceFileName;
Trace.Listeners.Add(traceFile);
}
}
public static void Padding(MemoryStream ms)
{
long size = ms.Length;
while (size % 4 != 0)
{
ms.WriteByte(0);
size++;
}
}
}
}

+ 6
- 1
Hack.Xenosaga/Common/Variables.cs View File

@ -1,4 +1,5 @@
using System.Text;
using Hack.Tools.TraceLog;
namespace Hack.Xenosaga.Common
{
@ -12,6 +13,8 @@ namespace Hack.Xenosaga.Common
public bool regroup;
}
public static TraceLog traceLog;
public const string dirUnpack = "01-UNPACK/";
public const string dirExtract = "02-EXTRACT/";
public const string dirInsert = "03-INSERT/";
@ -19,6 +22,8 @@ namespace Hack.Xenosaga.Common
public const string dirFinal = "05-FINAL/";
public const string tblCard = "TABLES/card_ANSI.tbl";
public const string tblEvt = "TABLES/evt_ANSI.tbl";
public const string tblEvtBox = "TABLES/evt_box_ANSI.tbl";
public const string tblEvtVideo = "TABLES/evt_video_ANSI.tbl";
public const string tblEvtItem = "TABLES/evtitem_ANSI.tbl";
}
}

+ 4
- 2
Hack.Xenosaga/Process/JavaClass.cs View File

@ -530,7 +530,9 @@ namespace Hack.Xenosaga.Process
{
bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2);
bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 4), 0, 4);
bw.Write(attribut.Value.info);
if (attribut.Value.info != null)
bw.Write(attribut.Value.info);
}
}
}
@ -1745,8 +1747,8 @@ namespace Hack.Xenosaga.Process
CONSTANT_Utf8_info stUTF8 = (CONSTANT_Utf8_info)constant_pool[id];
stUTF8.bytes = new byte[bytes.Length];
stUTF8.length = (short)(bytes.Length);
Array.Copy(bytes, 0, stUTF8.bytes, 0, bytes.Length);
//stUTF8.bytes[bytes.Length] = 0;
}
}
}


+ 134
- 17
Hack.Xenosaga/Process/Scripts.cs View File

@ -65,7 +65,7 @@ namespace Hack.Xenosaga.Process
br.ReadUInt32();
}
using (StreamWriter sw = new StreamWriter(Variables.dirExtract + filename + ".txt", false, encode))
using (StreamWriter sw = new StreamWriter(Variables.dirExtract + Path.GetFileName(filename) + ".txt", false, encode))
{
// Extracting text from pointers
foreach (Pointers pt in tblPt.ListPointers)
@ -188,9 +188,108 @@ namespace Hack.Xenosaga.Process
#endregion
#region evtitem.dat
public static bool extractEvtitem(string filename, Encoding encode)
{
int numBloc = 0;
int sizeBloc = 128;
long pos = 0;
try
{
Trace.Write("Extract evtitem.dat : ");
Directory.CreateDirectory(Variables.dirExtract);
Directory.CreateDirectory(Variables.dirInsert);
using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)))
{
Table tbl = new Table(encode);
tbl.Load(Variables.tblEvtItem);
using (StreamWriter sw = new StreamWriter(Variables.dirExtract + Path.GetFileName(filename) + ".txt", false, encode))
{
while (br.PeekChar() != 0)
{
sw.Write(string.Format("[{0:d4}]\n", numBloc));
// Read object name
sw.Write(tbl.BytesToString(br));
// Read object description
sw.Write(tbl.BytesToString(br));
pos += sizeBloc;
numBloc++;
br.BaseStream.Position = pos;
}
}
}
Trace.WriteLine("OK");
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
return false;
}
return true;
}
private static bool insertEvtitem(string filename, Encoding encode)
{
string name = Path.GetFileName(filename);
int sizeBloc = 128;
try
{
Trace.Write("Insert evtitem.dat : ");
using (BinaryReader brOriginalDatFile = new BinaryReader(File.Open(filename, FileMode.Open)))
using (MemoryStream ms = new MemoryStream())
{
cTblPointers tblPt = new cTblPointers();
Table tbl = loadTable(Variables.tblEvtItem, encode);
Dictionary<string, byte[]> bytes = tbl.StringToBytesArray(Variables.dirInsert + name + ".txt", new Regex(@"\[(.{4})\]\n"));
foreach (KeyValuePair<string, byte[]> b in bytes)
{
if (b.Value.Length > sizeBloc)
throw new Exception(string.Format("Bloc [{0}] too long : {1}/{2}!", b.Key, b.Value.Length, sizeBloc));
ms.Write(b.Value, 0, b.Value.Length);
ms.Padding(sizeBloc);
}
Directory.CreateDirectory(Variables.dirPack);
using (FileStream fs = new FileStream(Variables.dirPack + name, FileMode.Create))
{
ms.Position = 0;
ms.CopyTo(fs);
}
}
Trace.WriteLine("OK");
return true;
}
catch (Exception ex)
{
Trace.WriteLine(string.Format("ERROR : {0}", ex.Message));
return false;
}
}
#endregion
#region *.evt
private static bool decompilEvt(string nameFile, MemoryStream ms)
private static bool decompilEvt(string nameFile, MemoryStream ms, string nameTable)
{
Encoding encode = new UTF8Encoding(false);
@ -200,18 +299,13 @@ namespace Hack.Xenosaga.Process
jc.load(br);
//using (StreamWriter sw = new StreamWriter("ST0210_constantes.txt"))
//{
// jc.writeConstants(sw);
//}
Dictionary<int, byte[]> dictBytes = jc.getConstantsBytes();
if (dictBytes.Count > 0)
{
using (StreamWriter sw = new StreamWriter(Variables.dirExtract + nameFile + ".txt", false, encode))
{
Table tbl = loadTable(Variables.tblEvt, Encoding.Default);
Table tbl = loadTable(nameTable, Encoding.Default);
foreach (KeyValuePair<int, byte[]> bytes in dictBytes)
{
@ -235,6 +329,10 @@ namespace Hack.Xenosaga.Process
evtClass evtFile = new evtClass(pathName);
string nameTable = Variables.tblEvtBox;
if (Path.GetFileName(pathName).Substring(0, 3).ToUpper() == "SCE")
nameTable = Variables.tblEvtVideo;
Directory.CreateDirectory(Variables.dirExtract);
Directory.CreateDirectory(Variables.dirInsert);
@ -245,7 +343,7 @@ namespace Hack.Xenosaga.Process
ms.Write(file.file, 0, (int)file.fileLength);
ms.Position = 0;
decompilEvt(file.name, ms);
decompilEvt(file.name, ms, nameTable);
}
}
@ -264,13 +362,17 @@ namespace Hack.Xenosaga.Process
{
try
{
Trace.WriteLine(string.Format("Insert {0} : ", pathName));
Trace.Write(string.Format("Insert {0} : ", pathName));
using (BinaryReader br = new BinaryReader(File.Open(pathName, FileMode.Open)))
{
evtClass origEvt = new evtClass(br);
Table tbl = loadTable(Variables.tblEvt, Encoding.Default);
Table tbl;
if (Path.GetFileName(pathName).Substring(0, 3).ToUpper() == "SCE")
tbl = loadTable(Variables.tblEvtVideo, Encoding.Default);
else
tbl = loadTable(Variables.tblEvtBox, Encoding.Default);
using (MemoryStream destEvt = new MemoryStream())
{
@ -323,9 +425,14 @@ namespace Hack.Xenosaga.Process
foreach (KeyValuePair<int, byte[]> bytes in dictBytes)
{
pt = string.Format("{0:X4}", bytes.Key);
if (dictBytes.ContainsKey(Convert.ToInt32(pt, 16)) && list[pt] != null)
{
if (list[pt].Length >= 255)
throw new Exception("Line too long (254 characters max)!");
jc.setConstantsBytes(bytes.Key, list[pt]);
}
}
}
@ -340,7 +447,7 @@ namespace Hack.Xenosaga.Process
destEvt.Write(classFile.file, 0, (int)classFile.fileLength);
}
Functions.Padding(destEvt);
destEvt.Padding();
}
long posName = destEvt.Position;
@ -401,6 +508,9 @@ namespace Hack.Xenosaga.Process
if (Path.GetFileName(pathName) == "card.dat")
result = extractCard(pathName, encode);
if (Path.GetFileName(pathName) == "evtitem.dat")
result = extractEvtitem(pathName, encode);
if (Path.GetExtension(pathName) == ".evt")
result = extractEvt(pathName, encode);
}
@ -415,6 +525,8 @@ namespace Hack.Xenosaga.Process
{
if (Path.GetFileName(file) == "card.dat")
result = extractCard(file.ToLower(), encode);
else if (Path.GetFileName(file) == "evtitem.dat")
result = extractEvtitem(file.ToLower(), encode);
else if (Path.GetExtension(file) == ".evt")
result = extractEvt(file.ToLower(), encode);
}
@ -429,10 +541,13 @@ namespace Hack.Xenosaga.Process
if (File.Exists(pathName))
{
if (Path.GetFileName(pathName) == "card.dat")
if (Path.GetFileName(pathName).ToLower() == "card.dat")
result = insertCard(pathName, encode);
if (Path.GetExtension(pathName) == ".evt")
if (Path.GetFileName(pathName).ToLower() == "evtitem.dat")
result = insertEvtitem(pathName, encode);
if (Path.GetExtension(pathName).ToLower() == ".evt")
result = insertEvt(pathName, encode);
}
else if (Directory.Exists(pathName))
@ -444,9 +559,11 @@ namespace Hack.Xenosaga.Process
foreach (string file in listFiles)
{
if (Path.GetFileName(file) == "card.dat")
if (Path.GetFileName(file).ToLower() == "card.dat")
result = insertCard(file.ToLower(), encode);
else if (Path.GetExtension(file) == ".evt")
else if (Path.GetFileName(file).ToLower() == "evtitem.dat")
result = insertEvtitem(file.ToLower(), encode);
else if (Path.GetExtension(file).ToLower() == ".evt")
result = insertEvt(file.ToLower(), encode);
}
}


+ 16
- 15
Hack.Xenosaga/Process/Unpack.cs View File

@ -3,6 +3,7 @@ using System.IO;
using System.Diagnostics;
using System.Text;
using Hack.Xenosaga.Common;
using Hack.Tools.TraceLog;
namespace Hack.Xenosaga.Process
{
@ -506,28 +507,28 @@ namespace Hack.Xenosaga.Process
Directory.CreateDirectory(Variables.dirUnpack);
outputName = string.Format("{0}{1}{2}", Variables.dirUnpack, indexName, _listExtension);
using (StreamWriter sw = new StreamWriter(outputName))
{
Functions.ManageListener(false, true, sw);
Variables.traceLog.Off(typeTraceListeners.CONSOLE);
Variables.traceLog.On(typeTraceListeners.FILE, outputName);
bIndexNbSector = readIndex(indexName, index);
index.SortBySector();
iIndexSize = bIndexNbSector * _sectorSize;
bIndexNbSector = readIndex(indexName, index);
index.SortBySector();
iIndexSize = bIndexNbSector * _sectorSize;
foreach (pathElement entryPath in index.getEntries())
foreach (pathElement entryPath in index.getEntries())
{
if (!entryPath.IsDirectory)
{
if (!entryPath.IsDirectory)
{
double d = (entryPath.Position - iIndexSize) / _maxSizeFile;
int id = (int)Math.Floor(d) + 1;
double d = (entryPath.Position - iIndexSize) / _maxSizeFile;
int id = (int)Math.Floor(d) + 1;
Trace.WriteLine(string.Format("{0,-36}Sector={1,-15}SizeIn={2,-15}SizeOut={3,-15}File=xenosaga.{4:D2}", entryPath.FullPath, entryPath.Sector, entryPath.SizeIn, entryPath.SizeOut, id + numFile));
}
Trace.WriteLine(string.Format("{0,-36}Sector={1,-15}SizeIn={2,-15}SizeOut={3,-15}File=xenosaga.{4:D2}", entryPath.FullPath, entryPath.Sector, entryPath.SizeIn, entryPath.SizeOut, id + numFile));
}
Functions.ManageListener(true, false);
}
Variables.traceLog.On(typeTraceListeners.CONSOLE);
Variables.traceLog.Off(typeTraceListeners.FILE, outputName);
Variables.traceLog.Close(outputName);
Trace.WriteLine("OK");
}
catch (Exception ex)


+ 3
- 1
Hack.Xenosaga/Xenosaga.cs View File

@ -1,6 +1,7 @@
using System.Diagnostics;
using Hack.Xenosaga.Common;
using Hack.Xenosaga.Process;
using Hack.Tools.TraceLog;
namespace Hack.Xenosaga
{
@ -9,7 +10,8 @@ namespace Hack.Xenosaga
public static void Main(string[] args)
{
Variables.stArgs listArgs;
Functions.ManageListener(true);
Variables.traceLog = new TraceLog();
Variables.traceLog.On(typeTraceListeners.CONSOLE);
Trace.WriteLine("Hack.Xenosaga - (c) 2016 BahaBulle\n");


Loading…
Cancel
Save