public void TestSaveScriptAsOriginal() { var BytesOriginal = File.ReadAllBytes(Utils.TestInputPath + "/BTL_EP_210_090"); var Tss = new TSS().Load(new MemoryStream(BytesOriginal)); var BytesTranslated = Tss.Save().ToArray(); CollectionAssert.AreEqual(BytesOriginal, BytesTranslated); }
public void TestTranslateScript() { string TssFileName = "BTL_EP_210_090"; int ExpectedTextCount = 4; var ExpectedStrings = new Queue <String>(); var Tss = new TSS().Load(File.OpenRead(Utils.TestInputPath + "/" + TssFileName)); int mm = 0; Tss.TranslateTexts((Text) => { for (int n = 0; n < Text.Translated.Length; n++) { Text.Original[n].Text = "Original" + mm++; Text.Translated[n].Text = "Translated" + mm++; } }, (String) => { try { //Console.WriteLine(String); if (String == "VB36_1402") { return(String = "**VB36_1403**"); } return(null); } finally { ExpectedStrings.Enqueue(String); } }); Assert.AreEqual(ExpectedTextCount * 2 * 2, mm); mm = 0; var Tss2 = new TSS().Load(Tss.Save()); var TranslatedTexts = Tss2.ExtractTexts(); Assert.AreEqual(ExpectedTextCount, TranslatedTexts.Count); foreach (var Text in TranslatedTexts) { for (int n = 0; n < Text.Translated.Length; n++) { Assert.AreEqual("Original" + mm++, Text.Original[n].Text); Assert.AreEqual("Translated" + mm++, Text.Translated[n].Text); } } var TranslatedStrings = Tss2.ExtractStrings(); foreach (var StringInfo in TranslatedStrings) { //Assert.AreEqual("Original" + mm++, Text.Original[n].Text); Assert.AreEqual(ExpectedStrings.Dequeue(), StringInfo.Text); } Assert.AreEqual(ExpectedTextCount * 2 * 2, mm); //File.WriteAllBytes(Utils.TestOutputPath + "/BTL_EP_210_090.translated", Tss.Save().ToArray()); }
private void Handle2() { if (!Patcher.TempFS.Exists("string_dic_es.so")) { var TotalCount = Patcher.EntriesByRoom.Where(Room => Room.Key.StartsWith("misc/")).Sum(Item => Item.Value.Count); this.Patcher.ProgressHandler.AddProgressLevel("Traduciendo String.dic", TotalCount, () => { long OriginalLength = Patcher.TempFS.GetFileInfo("string_dic_uk.so").Size; long TranslatedLength = OriginalLength; Patcher.TempFS.OpenFileRWScope("string_dic_es.so.temp", (TssStream) => { var Tss = new TSS().Load(TssStream); Tss.TranslateTexts((TextEntry) => { this.Patcher.ProgressHandler.IncrementLevelProgress(); var RoomPath = String.Format("misc/{0}", (TextEntry.Id / 1000) * 1000); var TextId = String.Format("{0:D8}", TextEntry.Id); var TranslationRoom = Patcher.EntriesByRoom[RoomPath]; var TranslationEntry = TranslationRoom[TextId]; TextEntry.TranslateWithTranslationEntry(TranslationEntry); }, (String) => { return(null); }, HandleType1: true, AddAdditionalSpace: true); var TssTranslatedStream = Tss.Save(); OriginalLength = TssStream.Length; TranslatedLength = TssTranslatedStream.Length; TssStream.Position = 0; TssStream.WriteStream(TssTranslatedStream.Slice()).WriteByteRepeatedTo(0x00, TssStream.Length); }); Console.WriteLine("Old: {0}", OriginalLength); Console.WriteLine("New: {0}", TranslatedLength); if (TranslatedLength > OriginalLength) { throw (new Exception(String.Format("Translated string_dic is bigger than the original one. {0} > {1}", TranslatedLength, OriginalLength))); } Patcher.TempFS.MoveFile("string_dic_es.so.temp", "string_dic_es.so", true); }); } }
public void HandleBattlePackDialogs(Stream OldStream, Stream NewStream) { FPS4 OldFps4; FPS4 NewFps4; OldFps4 = new FPS4(OldStream.Slice()); NewFps4 = new FPS4(OldStream.Slice()); // Intended OldStream var TranslatedFiles = new ConcurrentDictionary <string, MemoryStream>(); var Names = new[] { "BTL_EP_0070_010", "BTL_EP_030_040", "BTL_EP_030_080", "BTL_EP_0950_010", "BTL_EP_0960_020", "BTL_EP_1040_020", "BTL_EP_150_170", "BTL_EP_170_050", "BTL_EP_210_090", "BTL_EP_270_110", "BTL_EP_270_110_1", "BTL_EP_340_070", "BTL_EP_370_050", "BTL_EP_420_080", "BTL_EP_440_040", "BTL_EP_470_030", "BTL_EP_490_060_0", "BTL_EP_490_060_1", "BTL_EP_510_050", "BTL_EP_510_080", "BTL_EP_640_050", "BTL_EP_650_030", "BTL_EP_650_050", "BTL_LL_MONSTER", "MA_VAL_A_05", }; Patcher.Action("Translating Battle Scripts", () => { Patcher.ProgressHandler.AddProgressLevel("Traduciendo scripts de batalla...", Names.Length, () => { Patcher.ParallelForeach("Translating", Names, (Name) => Name, (Name) => { using (var CompressedTssStream = OldFps4[Name].Open()) { using (var TssStream = TalesCompression.DecompressStream(CompressedTssStream)) { var TssName = Name; var Tss = new TSS().Load(TssStream); Tss.TranslateTexts((Entry) => { //if (Entry == null) return; var TranslationEntry = Patcher.EntriesByRoom["battle/" + TssName][String.Format("{0:X8}", Entry.Id2)]; int TextCount = Entry.Original.Length; Entry.TranslateWithTranslationEntry(TranslationEntry); //Console.WriteLine("{0} : {1}", Entry.Translated[1], TranslationEntry.texts.es[1]); }, (String) => { return(null); }); var TranslatedCompressedStream = TalesCompression.CreateFromVersion(Patcher.CompressionVersion, Patcher.CompressionFallback).EncodeFile(Tss.Save()); TranslatedFiles[Name] = TranslatedCompressedStream; } } Patcher.ProgressHandler.IncrementLevelProgress(); }); }); }); Patcher.Action("Reconstructing Battle Scripts Package", () => { NewFps4.ClearAllEntries(); foreach (var Entry in OldFps4.Entries.Values) { var EntryName = Entry.Name; if (TranslatedFiles.ContainsKey(EntryName)) { NewFps4.CreateEntry(EntryName, TranslatedFiles[EntryName]); } else { NewFps4.CreateEntry(EntryName, Entry.Open()); } } NewFps4.SaveTo(NewStream, DoAlign: false); }); }
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"); }); }