public void Access(string Path, Action Action, int RecompressVersion = -1) { if (Path.Contains('/')) { var Parts = Path.Split(new[] { '/' }, 2); Access(Parts[0], () => { Access(Parts[1], Action); }); return; } GetFile(Path, (CompressedStream) => { DecompressAndRecompressIfRequired(CompressedStream, (UncompressedStream) => { var Magic = UncompressedStream.Slice().ReadBytesUpTo(0x100); if (FPS4.IsValid(Magic)) { LanguageUtils.LocalSet(ref this.FileSystem, new FPS4FileSystem(UncompressedStream), Action); } else if (TO8SCEL.IsValid(Magic)) { LanguageUtils.LocalSet(ref this.FileSystem, new TO8SCELFileSystem(UncompressedStream), Action); } else { throw (new InvalidOperationException(String.Format("Can't access '{0}'", Path))); } }, RecompressVersion); }, RecompressVersion); }
protected void ExtractSvo(string SvoPath) { //try //{ using (var _SvoStream = File.OpenRead(SvoPath)) { Stream SvoStream = _SvoStream; int Compressed = TalesCompression.DetectVersion(SvoStream.Slice().ReadBytes(16), SvoStream.Length); if (Compressed >= 0) { SvoStream = TalesCompression.DecompressStream(SvoStream); } if (SvoStream.SliceWithLength().ReadString(7) == "TO8SCEL") { var TO8SCEL = new TO8SCEL(SvoStream); foreach (var Entry in TO8SCEL) { Console.WriteLine("{0} ... Start: {1}, End: {2}, Length: {3}", Entry.Index, Entry.EntryStruct.Offset, Entry.EntryStruct.Offset + Entry.EntryStruct.LengthCompressed, Entry.EntryStruct.LengthCompressed); } } else { var FPS4 = new FPS4(SvoStream); Console.WriteLine("{0}", FPS4); foreach (var Entry in FPS4) { Console.WriteLine("{0} ... Start: {1}, End: {2}, Length: {3}", Entry.Name, Entry.EntryStruct.Offset, Entry.EntryStruct.Offset + Entry.EntryStruct.LengthReal, Entry.EntryStruct.LengthReal); } } } }
/// <summary> /// /// </summary> /// <param name="DatPath"></param> /// <param name="DavPath"></param> /// <param name="OutputDirectory"></param> protected void ExtractSvo2(string DatPath, string DavPath, string OutputDirectory = null) { if (DavPath == null) { DavPath = DatPath; } if (OutputDirectory == null) { OutputDirectory = DatPath + ".d"; } Console.WriteLine("Loading {0}...", DatPath); //try //{ using (var _Stream1 = File.OpenRead(DatPath)) using (var Stream2 = File.OpenRead(DavPath)) { var Stream1 = (Stream)_Stream1; try { Directory.CreateDirectory(OutputDirectory); } catch { } int Compressed = TalesCompression.DetectVersion(Stream1.Slice().ReadBytes(16), Stream1.Length); if (Compressed >= 0) { Stream1 = TalesCompression.DecompressStream(Stream1); } if (Stream1.SliceWithLength().ReadString(7) == "TO8SCEL") { var TO8SCEL = new TO8SCEL(Stream1); foreach (var Entry in TO8SCEL) { _ExtractFile(OutputDirectory + "/" + Entry.Index, () => Entry.UncompressedStream, (int)(uint)Entry.EntryStruct.Offset, (int)(uint)Entry.EntryStruct.LengthCompressed); } } else { var FPS4 = new FPS4(Stream1, Stream2); Console.WriteLine("{0}", FPS4); foreach (var Entry in FPS4) { _ExtractFile(OutputDirectory + "/" + Entry.Name, () => Entry.Open(), (int)(uint)Entry.EntryStruct.Offset, (int)(uint)Entry.EntryStruct.LengthReal); } } } //} //catch (Exception Exception) //{ // Console.Error.WriteLine("{0}", Exception); //} }
private void CompressRooms() { if (Patcher.TempFS.Exists("scenario_es.dat")) { return; } this.Patcher.ProgressHandler.AddProgressLevel("Comprimiendo habitaciones", RoomCount, () => { var NewTO8SCEL = new TO8SCEL(); Patcher.ParallelForeach("Compressing Room", Iterators.IntRange(0, RoomCount - 1), (RoomId) => RoomId.ToString(), (RoomId) => { this.Patcher.ProgressHandler.IncrementLevelProgress(); var ScenarioTempFileName = ScenarioTempFileNamePrep + RoomId; var ScenarioTempFileCompressedName = ScenarioTempFileName + ".c"; if (Patcher.TempFS.Exists(ScenarioTempFileName)) { if (!Patcher.TempFS.Exists(ScenarioTempFileCompressedName)) { var UncompressedBytes = Patcher.TempFS.ReadAllBytes(ScenarioTempFileName); var CompressedBytes = TalesCompression.CreateFromVersion(Patcher.CompressionVersion, Patcher.CompressionVersion).EncodeBytes(UncompressedBytes); Patcher.TempFS.WriteAllBytes(ScenarioTempFileCompressedName, CompressedBytes); } NewTO8SCEL.CreateEntry( RoomId, Patcher.TempFS.OpenFileRead(ScenarioTempFileCompressedName), Patcher.TempFS.OpenFileRead(ScenarioTempFileName) ); } else { NewTO8SCEL.CreateEntry( RoomId, new MemoryStream(), new MemoryStream() ); } }); Patcher.TempFS.OpenFileCreateScope("scenario_es.dat", (Stream) => { NewTO8SCEL.SaveTo(Stream); Stream.Position = 0; }); }); }
public TO8SCELFileSystem(TO8SCEL TO8SCEL) { this.TO8SCEL = TO8SCEL; }
public TO8SCELFileSystem(Stream Stream) { this.TO8SCEL = new TO8SCEL(Stream); }
public void Initialize() { to8scel = new TO8SCEL(); }
private void TranslateRooms() { if (Patcher.TempFS.Exists("scenario_es.dat")) { return; } var PasswordString = Patcher.PatcherDataFS.ReadAllBytes("Text/password.txt").GetString(Encoding.UTF8).Trim(); //Console.WriteLine(PasswordString); //Console.ReadKey(); this.Patcher.ProgressHandler.AddProgressLevel("Traduciendo habitaciones", RoomCount, () => { FileSystem.CopyFile(Patcher.GameFileSystem, "language/scenario_uk.dat", Patcher.TempFS, "scenario_uk.dat"); var TO8SCEL = new TO8SCEL(Patcher.TempFS.OpenFileRW("scenario_uk.dat")); //TO8SCEL.Save(new MemoryStream()); //Patcher.GameAccessPath("language/scenario_uk.dat", () => Patcher.TempFS.CreateDirectory("SCENARIO_ES", 0777, false); Patcher.ParallelForeach //Patcher.Foreach ("Translating Room", Iterators.IntRange(0, RoomCount - 1), (RoomId) => RoomId.ToString(), (RoomId) => { var ScenarioTempFileName = ScenarioTempFileNamePrep + RoomId; if (!Patcher.TempFS.Exists(ScenarioTempFileName)) { if (TO8SCEL.Entries[RoomId].CompressedStream.Length > 0) { var Stream = TO8SCEL.Entries[RoomId].UncompressedStream; var RoomPath = String.Format("scenario/{0:D4}", RoomId); var Tss = new TSS().Load(Stream); Tss.TranslateTexts((Entry) => { var TextId = String.Format("{0:X8}", Entry.Id); if (Patcher.EntriesByRoom.ContainsKey(RoomPath)) { var TranslationRoom = Patcher.EntriesByRoom[RoomPath]; if (TranslationRoom.ContainsKey(TextId)) { var TranslationEntry = TranslationRoom[TextId]; Entry.TranslateWithTranslationEntry(TranslationEntry); } else { Console.Error.WriteLine("Missing Translation {0} : {1:X8} : {2:X8} : {3:X8}", RoomPath, Entry.Id, Entry.Id2, Entry.Id3); } } else { Console.Error.WriteLine("Missing Room"); } }, (Text) => { if (RoomId == 192) { //Console.WriteLine("{0}", Text); if (Text == "sun") { return(PasswordString); } } if (RoomId == 31 || RoomId == 35) { //Console.WriteLine("{0}", Text); if (Text == "1st") { return("1ª"); } if (Text == "2nd") { return("2ª"); } if (Text == "Last") { return("Última"); } if (Text == "%s Battle") { return("%s batalla"); } if (Text == "%s?\n") { return("¿%s?\n"); } } if (RoomId == 1256 || RoomId == 1257 || RoomId == 1258 || RoomId == 1259 || RoomId == 1260 || RoomId == 1271 || RoomId == 1272 || RoomId == 1273) { if (Text == "SELECT") { return("Selección"); } } //Los siguientes textos no se pueden arreglar con este método, ya que ni si quiera se cargan (Text nunca será "1st Battle", etc.) //Investigando cómo van los TSS, he visto que la mayoría (o todos) los textos se cargan con un Opcode.PUSH_ARRAY //Por lo visto el programa solamente procesa por ahora las entradas que tienen 6 elementos. (TSS.HandleTexts()) //En este caso, también se gestiona con un PUSH_ARRAY, pero distinto. Para empezar, los textos ya no son ValueType.String (0xC), //si no 0x2C. ¿Otro tipo de strings? Y contienen 3 elementos. He intentado apañar el asunto, y aunque he conseguido leer esos textos, //no me veo capaz de meterme en semejante inmensidad de código ajeno sin romper nada. Así que por ahora prefiero hacer un método //cutre que no implique modificar nada existente. Este método está en la función FixTexts() /*if (RoomId == 344 || RoomId == 1331) * { * if (Text == "1st Battle") return "Ronda 1"; * if (Text == "2st Battle") return "Ronda 2"; //Sí, en inglés hay una errata. * if (Text == "Last Battle") return "Última ronda"; * }*/ return(null); }); //if (RoomId == 192) Console.ReadKey(); Patcher.TempFS.WriteAllBytes(ScenarioTempFileName, Tss.Save().ToArray()); } else { //Console.WriteLine("CompressedStream.Length = 0"); } } this.Patcher.ProgressHandler.IncrementLevelProgress(); }); //FileSystem.CopyFile(Patcher.TempFS, "scenario_es.dat", Patcher.TempFS, "scenario_es.dat.finished"); }); }
protected void Expand(string FilePath) { if (FilePath.Contains('*') || FilePath.Contains('?')) { var BasePath = Path.GetDirectoryName(FilePath); var Recursive = false; if (BasePath == "") { BasePath = "."; } foreach (var FileName in Directory.EnumerateFiles(BasePath, Path.GetFileName(FilePath), Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { Expand(FileName); } return; } var ListToExpand = new List <string>(); //Console.WriteLine("Expanding '{0}'...", FilePath); using (var _FileStream = File.OpenRead(FilePath)) { if (_FileStream.Length == 0) { //Console.WriteLine("EMPTY: {0}", FilePath); return; } var FileStream = DecompressIfCompressedStream(_FileStream); var MagicData = FileStream.Slice().ReadBytesUpTo(0x100); if (false) { } else if (TO8SCEL.IsValid(MagicData)) { try { var To8Scel = new TO8SCEL(FileStream); foreach (var Entry in To8Scel) { var EntryFilePath = FilePath + ".d/" + Entry.Index; if (Overwrite || !File.Exists(EntryFilePath)) { Console.WriteLine("{0}", EntryFilePath); try { var EntryStream = DecompressIfCompressedStream(Entry.CompressedStream); if (EntryStream.Length > 0) { EntryStream.CopyToFile(EntryFilePath); } } catch (Exception Exception) { ShowException(Exception); } } if (File.Exists(EntryFilePath)) { ListToExpand.Add(EntryFilePath); } } } catch (Exception Exception) { ShowException(Exception); } } else if (FPS4.IsValid(MagicData)) { //Console.WriteLine("FPS4"); try { var Fps4 = new FPS4(FileStream); foreach (var Entry in Fps4) { var EntryFilePath = FilePath + ".d/" + Entry.Name; if (Overwrite || !File.Exists(EntryFilePath)) { Console.WriteLine("{0}", EntryFilePath); try { var EntryStream = DecompressIfCompressedStream(Entry.Open()); if (EntryStream.Length > 0) { EntryStream.CopyToFile(EntryFilePath); } } catch (Exception Exception) { ShowException(Exception); } } if (File.Exists(EntryFilePath)) { ListToExpand.Add(EntryFilePath); } } } catch (Exception Exception) { ShowException(Exception); } } else if (TSS.IsValid(MagicData)) { int RoomId = 0; try { RoomId = int.Parse(Path.GetFileNameWithoutExtension(FilePath)); } catch { } var TxtFile = FilePath + ".txt"; Console.WriteLine("{0}", TxtFile); if (Overwrite || !File.Exists(TxtFile)) { var Tss = new TSS().Load(FileStream.Slice()); using (var TxtStream = File.Open(TxtFile, FileMode.Create, FileAccess.Write)) using (var TextWriter = new StreamWriter(TxtStream)) { try { Tss.DumpTexts(TextWriter); } catch (Exception Exception) { ShowException(Exception); } } } var ScrFile = FilePath + ".scr"; Console.WriteLine("{0}", ScrFile); if (Overwrite || !File.Exists(ScrFile)) { var Tss = new TSS().Load(FileStream.Slice()); using (var TxtStream = File.Open(ScrFile, FileMode.Create, FileAccess.Write)) using (var TextWriter = new StreamWriter(TxtStream)) { try { var ErrorString = ConsoleUtils.CaptureError(() => { Tss.DumpScript(TextWriter); }); } catch (Exception Exception) { ShowException(Exception); } } } } else if (TO8CHTX.IsValid(MagicData)) { var Chtx = new TO8CHTX(FileStream); var TxtFile = FilePath + ".txt"; Console.WriteLine("{0}", TxtFile); if (Overwrite || !File.Exists(TxtFile)) { using (var TxtStream = File.Open(TxtFile, FileMode.Create, FileAccess.Write)) using (var TextWriter = new StreamWriter(TxtStream)) { foreach (var Entry in Chtx.Entries) { TextWriter.WriteLine("{0}", Entry.Title); TextWriter.WriteLine("{0}", Entry.TextOriginal); TextWriter.WriteLine("{0}", Entry.TextTranslated); TextWriter.WriteLine(""); } } //Chtx.Entries[0].Title //Console.WriteLine("CHAT!"); } } else if (SE3.IsValid(MagicData)) { var Se3 = new SE3().Load(FileStream); foreach (var Entry in Se3.Entries) { var EntryFullNameXma = FilePath + "." + Entry.Name + ".xma"; var EntryFullNameWav = FilePath + "." + Entry.Name + ".wav"; Console.WriteLine("{0}", EntryFullNameXma); if (Overwrite || !File.Exists(EntryFullNameXma)) { Entry.ToXmaWav().CopyToFile(EntryFullNameXma); } if (Overwrite || !File.Exists(EntryFullNameWav)) { using (var WavOut = File.Open(EntryFullNameWav, FileMode.Create, FileAccess.Write)) { Entry.ToWav(WavOut); } } } } else if (TXM.IsValid(MagicData)) { string BasePath; string TxmPath; string TxvPath; if (Path.GetExtension(FilePath).ToLower() == ".txm") { BasePath = Path.GetDirectoryName(FilePath) + "/" + Path.GetFileNameWithoutExtension(FilePath); TxmPath = BasePath + ".txm"; TxvPath = BasePath + ".txv"; } else { var DirectoryPath = Path.GetDirectoryName(FilePath); TxmPath = DirectoryPath + "/" + Path.GetFileName(FilePath); TxvPath = DirectoryPath + "/" + (int.Parse(Path.GetFileName(TxmPath)) + 1); BasePath = TxmPath; } var Txm = TXM.FromTxmTxv(File.OpenRead(TxmPath), File.OpenRead(TxvPath)); /* * if (Txm.Surface2DEntries.Length > 0 && Txm.Surface3DEntries.Length > 0) * { * // 3D and 2D surfaces * //Console.WriteLine("ERROR 3D and 2D SURFACES! (2D: {0}, 3D: {1})", Txm.Surface2DEntries.Length, Txm.Surface3DEntries.Length); * } * else if (Txm.Surface2DEntries.Length > 0) * { * // 2D Surfaces * //Console.WriteLine("2D SURFACES! {0}", Txm.Surface2DEntries.Length); * } * else if (Txm.Surface3DEntries.Length > 0) * { * // 3D Surfaces * //Console.WriteLine("3D SURFACES! {0}", Txm.Surface3DEntries.Length); * } */ foreach (var Entry in Txm.Surface2DEntries) { var ImagePath = BasePath + "." + Entry.Name + ".png"; if (Overwrite || !File.Exists(ImagePath)) { try { Entry.Bitmap.Save(ImagePath); } catch (Exception Exception) { ShowException(Exception); } } } foreach (var Entry in Txm.Surface3DEntries) { var ImagePath0 = BasePath + "." + Entry.Name + "." + 0 + ".png"; if (Overwrite || !File.Exists(ImagePath0)) { try { var n = 0; foreach (var Bitmap in Entry.Bitmaps.Bitmaps) { var ImagePath = BasePath + "." + Entry.Name + "." + n + ".png"; Console.WriteLine("{0}", ImagePath); if (Overwrite || !File.Exists(ImagePath)) { Bitmap.Save(ImagePath); } n++; } } catch (Exception Exception) { ShowException(Exception); } } } } else { } } // Expand all the queued stuff foreach (var Item in ListToExpand) { try { Expand(Item); } catch (Exception Exception) { Console.WriteLine(" ERROR: {0}", Verbose ? Exception.ToString() : Exception.Message.ToString()); } } }