protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); var dictionary = new Dictionary <string, bool>(); string text = System.IO.File.ReadAllText(Path, FileEncoding); text = text.Replace("\n", "\\n"); string[] items = text.Split('■'); for (int i = 0; i < items.Length - 1; i++) { var data = items[i].Split('◆'); if (!dictionary.ContainsKey(data[0])) { var subtitle = new SubtitleWithId { Id = data[0], Offset = 0, Text = data[1], Loaded = data[1], Translation = data[1] }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); dictionary.Add(data[0], true); } } LoadChanges(result); return(result); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); using (var fs = new FileStream(Path, FileMode.Open)) using (var input = new ExtendedBinaryReader(fs, FileEncoding)) { int arraySize = input.ReadInt32(); for (int i = 0; i < arraySize; i++) { string focusObj = input.ReadStringSerialized(0x04); string text = input.ReadStringSerialized(0x04); var subtitle = new SubtitleWithId { Id = focusObj, Offset = 0, Text = text, Loaded = text, Translation = text }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } LoadChanges(result); return(result); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); using (var fs = new FileStream(Path, FileMode.Open)) using (var input = new ExtendedBinaryReader(fs, FileEncoding)) { var count = input.ReadInt32(); for (int i = 0; i < count; i++) { // UILabel input.Skip(0x04); input.Skip(0x08); var strJap = input.ReadStringSerialized(0x04); var strEng = input.ReadStringSerialized(0x04); var subtitle = new SubtitleWithId { Id = (i + 1).ToString(), Offset = 0, Text = strEng, Loaded = strEng, Translation = strEng }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } LoadChanges(result); return(result); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); using (var fs = new FileStream(Path, FileMode.Open)) using (var input = new ExtendedBinaryReader(fs, FileEncoding)) { // Material input.Skip(0x04); input.Skip(0x08); // ColorRGBA input.Skip(4 * 0x04); // RaycastTarget input.Skip(0x04); // CullStateChangedEvent int persistentCallCount = input.ReadInt32(); for (int i = 0; i < persistentCallCount; i++) { // PersistentCall } // FontData input.Skip(0x04); input.Skip(0x08); input.Skip(0x04); // Font size input.Skip(0x04); // Font style input.Skip(0x04); // Best Fit input.Skip(0x04); // Min size input.Skip(0x04); // Max size input.Skip(0x04); // Alignment input.Skip(0x04); // Align by geometry input.Skip(0x04); // Rich Text input.Skip(0x04); // Horizontal Overflow input.Skip(0x04); // Vertical Overflow input.Skip(0x04); // Line spacing string sub = input.ReadStringSerialized(0x04); var subtitle = new SubtitleWithId { Id = sub, Offset = 0, Text = sub, Loaded = sub, Translation = sub }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } LoadChanges(result); return(result); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); using (var fs = new FileStream(Path, FileMode.Open)) using (var input = new ExtendedBinaryReader(fs, FileEncoding)) { input.Skip(0x0C); int termCount = input.ReadInt32(); for (int termIndex = 0; termIndex < termCount; termIndex++) { string term = input.ReadStringSerialized(0x04); int termType = input.ReadInt32(); string description = input.ReadStringSerialized(0x04); int languageCount = input.ReadInt32(); for (int i = 0; i < languageCount; i++) { string sub = input.ReadStringSerialized(0x04); if (i == LanguageIndex && !string.IsNullOrEmpty(sub)) { var subtitle = new SubtitleWithId { Id = term, Offset = 0, Text = sub, Loaded = sub, Translation = sub }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } int flagCount = input.ReadInt32(); input.Skip(flagCount); input.SkipPadding(0x04); int languageTouchCount = input.ReadInt32(); for (int i = 0; i < languageTouchCount; i++) { input.ReadStringSerialized(0x04); } } } LoadChanges(result); return(result); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); using (var fs = new FileStream(Path, FileMode.Open)) using (var input = new ExtendedBinaryReader(fs, FileEncoding)) { // AnchorPoints for (int i = 0; i < 4; i++) { input.Skip(0x0C); input.Skip(0x08); } input.Skip(0x04); // updateAnchors input.Skip(4 * 0x04); // Color input.Skip(0x04); // pivot input.Skip(0x04); // width input.Skip(0x04); // height input.Skip(0x04); // depth input.Skip(0x04); // autoresizeBoxCollider input.Skip(0x04); // hideIfOffScreen input.Skip(0x04); // keepAspectRatio input.Skip(0x04); // aspectRatio input.Skip(0x04); // keepCrispWhenShrunk input.Skip(0x0C); // truetypefont input.Skip(0x0C); // font var str = input.ReadStringSerialized(0x04); var subtitle = new SubtitleWithId { Id = str, Offset = 0, Text = str, Loaded = str, Translation = str }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } LoadChanges(result); return(result); }
protected override IList <Subtitle> GetSubtitles() { var tempFile = System.IO.Path.GetTempFileName(); UnderRailTool.Run("r", Path, tempFile, string.Empty); var result = new List <Subtitle>(); if (System.IO.File.Exists(tempFile)) { var lines = System.IO.File.ReadAllLines(tempFile); System.IO.File.Delete(tempFile); if (lines.Length > 0) { var dictionary = lines.Select(line => line.Split(new[] { "<Split>" }, StringSplitOptions.None)) .ToDictionary(split => split[0], split => split[1]); foreach (var pair in dictionary) { var sub = new SubtitleWithId { Id = pair.Key, Text = pair.Value, Loaded = pair.Value, Translation = pair.Value, Offset = 0, }; sub.PropertyChanged += SubtitlePropertyChanged; result.Add(sub); } LoadChanges(result); } } return(result); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); ModuleDefMD module = ModuleDefMD.Load(Path); foreach (TypeDef t in module.Types) { foreach (MethodDef m in t.Methods) { if (!m.HasBody) { continue; } foreach (Instruction instr in m.Body.Instructions) { if (instr.OpCode != OpCodes.Ldstr) { continue; } string str = (string)instr.Operand; var subtitle = new SubtitleWithId { Text = str, Loaded = str, Translation = str, Id = $"{t.Name}/{m.Name}/{m.RVA.ToString()}/{instr.Offset}" }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } result.Sort(); LoadChanges(result); return(result); }
protected override IList <Subtitle> GetSubtitles() { var result = new List <Subtitle>(); var module = ModuleDefMD.Load(Path); foreach (var t in module.Types) { foreach (var a in t.CustomAttributes) { for (var i = a.ConstructorArguments.Count - 1; i >= 0; i--) { var arg = a.ConstructorArguments[i]; if (arg.Type.FullName == "System.String") { var str = ((UTF8String)arg.Value).String.Replace("\r\n", "\\r\\n"); var id = $"{t.Name}_attr_{a.TypeFullName}_arg_{i}"; var subtitle = new SubtitleWithId { Id = id, Text = str, Loaded = str, Translation = str, Offset = 0 }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } foreach (var f in t.Fields) { var str = string.Empty; if (f.HasConstant && f.FieldType.FullName == "System.String") { str = ((string)f.Constant.Value).Replace("\r\n", "\\r\\n"); } else if (f.HasConstant && translatableEnums.Contains(f.FieldType.FullName)) { str = f.Name.String; } if (!string.IsNullOrEmpty(str)) { var id = $"{t.Name}_field_{f.Name.String}"; var subtitle = new SubtitleWithId { Id = id, Text = str, Loaded = str, Translation = str, Offset = 0 }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } foreach (var m in t.Methods) { if (!m.HasBody) { continue; } foreach (var instr in m.Body.Instructions) { if (instr.OpCode != OpCodes.Ldstr) { continue; } var str = ((string)(instr.Operand)).Replace("\r\n", "\\r\\n"); var id = $"{t.Name}_method_{m.Name}_rva_{m.RVA}_{instr.Offset}"; var subtitle = new SubtitleWithId { Id = id, Text = str, Loaded = str, Translation = str, Offset = 0 }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } result.Sort(); LoadChanges(result); return(result); }
protected void Rebuild(ExtendedBinaryReader input, ExtendedBinaryWriter output, Dictionary <string, SubtitleWithId> dictionary) { string version = input.ReadStringSerialized(0x04); output.WriteStringSerialized(version, 0x04); string author = input.ReadStringSerialized(0x04); output.WriteStringSerialized(author, 0x04); string description = input.ReadStringSerialized(0x04); output.WriteStringSerialized(description, 0x04); string globalUserScript = input.ReadStringSerialized(0x04); output.WriteStringSerialized(globalUserScript, 0x04); int emphasisSettingCount = input.ReadInt32(); output.Write(emphasisSettingCount); output.Write(input.ReadBytes(emphasisSettingCount * 0x04 * 0x07)); int actorCount = input.ReadInt32(); output.Write(actorCount); for (int i = 0; i < actorCount; i++) { int id = input.ReadInt32(); output.Write(id); int fieldCount = input.ReadInt32(); output.Write(fieldCount); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Name", "LongDescription", "short_description" }; foreach (KeyValuePair <string, Field> kvp in fields) { output.WriteStringSerialized(kvp.Value.Title, 0x04); if (translatableFields.Contains(kvp.Value.Title) && !string.IsNullOrEmpty(kvp.Value.Value)) { string key = $"Actor_{id}_{kvp.Value.Title}"; SubtitleWithId subtitle = dictionary[key]; output.WriteStringSerialized(subtitle.Translation, 0x04); } else { output.WriteStringSerialized(kvp.Value.Value, 0x04); } output.Write(kvp.Value.Type); output.WriteStringSerialized(kvp.Value.TypeString, 0x04); } output.Write(input.ReadBytes(0x0C)); // portrait output.Write(input.ReadBytes(0x0C)); // spritePortrait output.Write(input.ReadBytes(0x04)); // alternatePortraits output.Write(input.ReadBytes(0x04)); // spritePortraits } int itemCount = input.ReadInt32(); output.Write(itemCount); for (int i = 0; i < itemCount; i++) { int id = input.ReadInt32(); output.Write(id); int fieldCount = input.ReadInt32(); output.Write(fieldCount); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Description", "displayname", "description", "fixtureBonus", "requirement", "bonus", "fixtureDescription" }; foreach (KeyValuePair <string, Field> kvp in fields) { output.WriteStringSerialized(kvp.Value.Title, 0x04); if (translatableFields.Contains(kvp.Value.Title) && !string.IsNullOrEmpty(kvp.Value.Value)) { string key = $"Item_{id}_{kvp.Value.Title}"; SubtitleWithId subtitle = dictionary[key]; output.WriteStringSerialized(subtitle.Translation, 0x04); } else { output.WriteStringSerialized(kvp.Value.Value, 0x04); } output.Write(kvp.Value.Type); output.WriteStringSerialized(kvp.Value.TypeString, 0x04); } } int locationCount = input.ReadInt32(); output.Write(locationCount); for (int i = 0; i < locationCount; i++) { int id = input.ReadInt32(); output.Write(id); int fieldCount = input.ReadInt32(); output.Write(fieldCount); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Name" }; foreach (KeyValuePair <string, Field> kvp in fields) { output.WriteStringSerialized(kvp.Value.Title, 0x04); if (translatableFields.Contains(kvp.Value.Title) && !string.IsNullOrEmpty(kvp.Value.Value)) { string key = $"Location_{id}_{kvp.Value.Title}"; SubtitleWithId subtitle = dictionary[key]; output.WriteStringSerialized(subtitle.Translation, 0x04); } else { output.WriteStringSerialized(kvp.Value.Value, 0x04); } output.Write(kvp.Value.Type); output.WriteStringSerialized(kvp.Value.TypeString, 0x04); } } int variableCount = input.ReadInt32(); output.Write(variableCount); for (int i = 0; i < variableCount; i++) { int id = input.ReadInt32(); output.Write(id); int fieldCount = input.ReadInt32(); output.Write(fieldCount); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Description" }; foreach (KeyValuePair <string, Field> kvp in fields) { output.WriteStringSerialized(kvp.Value.Title, 0x04); if (translatableFields.Contains(kvp.Value.Title) && !string.IsNullOrEmpty(kvp.Value.Value)) { string key = $"Variable_{id}_{kvp.Value.Title}"; SubtitleWithId subtitle = dictionary[key]; output.WriteStringSerialized(subtitle.Translation, 0x04); } else { output.WriteStringSerialized(kvp.Value.Value, 0x04); } output.Write(kvp.Value.Type); output.WriteStringSerialized(kvp.Value.TypeString, 0x04); } } int conversationCount = input.ReadInt32(); output.Write(conversationCount); for (int i = 0; i < conversationCount; i++) { int id = input.ReadInt32(); output.Write(id); int fieldCount = input.ReadInt32(); output.Write(fieldCount); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Title", "Description", "subtask_title_01", "subtask_title_02", "subtask_title_03", "subtask_title_04", "subtask_title_05", "subtask_title_06", "subtask_title_07", "subtask_title_08", "subtask_title_09", "subtask_title_10", }; foreach (KeyValuePair <string, Field> kvp in fields) { output.WriteStringSerialized(kvp.Value.Title, 0x04); if (translatableFields.Contains(kvp.Value.Title) && !string.IsNullOrEmpty(kvp.Value.Value)) { string key = $"Conversation_{id}_{kvp.Value.Title}"; SubtitleWithId subtitle = dictionary[key]; output.WriteStringSerialized(subtitle.Translation, 0x04); } else { output.WriteStringSerialized(kvp.Value.Value, 0x04); } output.Write(kvp.Value.Type); output.WriteStringSerialized(kvp.Value.TypeString, 0x04); } // ConversationOverrideDisplaySettings output.Write(input.ReadBytes(0x28)); for (int j = 0; j < 3; j++) { output.WriteStringSerialized(input.ReadStringSerialized(0x04), 0x04); } output.Write(input.ReadBytes(0x10)); output.WriteStringSerialized(input.ReadStringSerialized(0x04), 0x04); // nodeColor // DialogueEntry int dialogueEntryCount = input.ReadInt32(); output.Write(dialogueEntryCount); for (int j = 0; j < dialogueEntryCount; j++) { int dialogueEntryId = input.ReadInt32(); output.Write(dialogueEntryId); int fieldCount2 = input.ReadInt32(); output.Write(fieldCount2); var fields2 = new Dictionary <string, Field>(fieldCount2); for (int k = 0; k < fieldCount2; k++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields2.Add($"{field.Title}", field); } var translatableFields2 = new string[] { "Dialogue Text", "Alternate1", "Alternate2", "Alternate3", "Alternate4", "tooltip1", "tooltip2", "tooltip3", "tooltip4", "tooltip5", "tooltip6", "tooltip7", "tooltip8", "tooltip9", "tooltip10" }; foreach (KeyValuePair <string, Field> kvp in fields2) { output.WriteStringSerialized(kvp.Value.Title, 0x04); if (translatableFields2.Contains(kvp.Value.Title) && !string.IsNullOrEmpty(kvp.Value.Value)) { string key = $"Conversation_{id}_Entry_{dialogueEntryId}_{kvp.Value.Title}"; SubtitleWithId subtitle = dictionary[key]; output.WriteStringSerialized(subtitle.Translation, 0x04); } else { output.WriteStringSerialized(kvp.Value.Value, 0x04); } output.Write(kvp.Value.Type); output.WriteStringSerialized(kvp.Value.TypeString, 0x04); } output.Write(input.ReadBytes(0x0C)); output.WriteStringSerialized(input.ReadStringSerialized(0x04), 0x04); // nodeColor output.Write(input.ReadBytes(0x04)); output.WriteStringSerialized(input.ReadStringSerialized(0x04), 0x04); // falseConditionAction output.Write(input.ReadBytes(0x04)); int outgoingLinksCount = input.ReadInt32(); output.Write(outgoingLinksCount); output.Write(input.ReadBytes(outgoingLinksCount * 0x04 * 0x06)); output.WriteStringSerialized(input.ReadStringSerialized(0x04), 0x04); // conditionsString string userScript = input.ReadStringSerialized(0x04); // userScript if (userScript.StartsWith("NewspaperEndgame(")) { var regex = new Regex(@"NewspaperEndgame\(""(?<Id>[^""]+)"",""(?<Headline>[^""]+)"",""(?<Text>[^""\\]*(?:\\.[^""\\]*)*)""\)"); Match match = regex.Match(userScript); while (match.Success) { string endId = match.Groups["Id"].Value; string headlineKey = $"Conversation_{id}_Entry_{dialogueEntryId}_EndHeadline"; string textKey = $"Conversation_{id}_Entry_{dialogueEntryId}_EndText"; if (!dictionary.ContainsKey(headlineKey) || !dictionary.ContainsKey(textKey)) { output.WriteStringSerialized(userScript, 0x04); } else { SubtitleWithId headline = dictionary[headlineKey]; SubtitleWithId text = dictionary[textKey]; string escapedText = text.Translation.Replace("\"", "\\\"").Replace("\\n", "<NewLine>"); output.WriteStringSerialized($@"NewspaperEndgame(""{endId}"",""{headline}"",""{escapedText}"")", 0x04); } match = match.NextMatch(); } } else { output.WriteStringSerialized(userScript, 0x04); } // onExecute output.Write(input.ReadBytes(0x04)); output.Write(input.ReadBytes(0x10)); // Canvas rect } output.Write(input.ReadBytes(0x08)); // canvasScrollPosition output.Write(input.ReadBytes(0x04)); // canvasZoom } int remainderLength = (int)(input.Length - input.Position); byte[] remainder = input.ReadBytes(remainderLength); output.Write(remainder); }
protected IList <Subtitle> GetSubtitles(ExtendedBinaryReader input) { var result = new List <Subtitle>(); string version = input.ReadStringSerialized(0x04); string author = input.ReadStringSerialized(0x04); string description = input.ReadStringSerialized(0x04); string globalUserScript = input.ReadStringSerialized(0x04); int emphasisSettingCount = input.ReadInt32(); input.Skip(emphasisSettingCount * 0x04 * 0x07); int actorCount = input.ReadInt32(); for (int i = 0; i < actorCount; i++) { int id = input.ReadInt32(); int fieldCount = input.ReadInt32(); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Name", "LongDescription", "short_description" }; foreach (string translatableField in translatableFields) { if (fields.TryGetValue(translatableField, out Field field)) { if (!string.IsNullOrEmpty(field.Value)) { var subtitle = new SubtitleWithId { Id = $"Actor_{id}_{translatableField}", Offset = 0, Text = field.Value, Loaded = field.Value, Translation = field.Value }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } input.Skip(0x0C); // portrait input.Skip(0x0C); // spritePortrait input.Skip(0x04); // alternatePortraits input.Skip(0x04); // spritePortraits } int itemCount = input.ReadInt32(); for (int i = 0; i < itemCount; i++) { int id = input.ReadInt32(); int fieldCount = input.ReadInt32(); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Description", "displayname", "description", "fixtureBonus", "requirement", "bonus", "fixtureDescription" }; foreach (string translatableField in translatableFields) { if (fields.TryGetValue(translatableField, out Field field)) { if (!string.IsNullOrEmpty(field.Value)) { var subtitle = new SubtitleWithId { Id = $"Item_{id}_{translatableField}", Offset = 0, Text = field.Value, Loaded = field.Value, Translation = field.Value }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } } int locationCount = input.ReadInt32(); for (int i = 0; i < locationCount; i++) { int id = input.ReadInt32(); int fieldCount = input.ReadInt32(); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Name" }; foreach (string translatableField in translatableFields) { if (fields.TryGetValue(translatableField, out Field field)) { if (!string.IsNullOrEmpty(field.Value)) { var subtitle = new SubtitleWithId { Id = $"Location_{id}_{translatableField}", Offset = 0, Text = field.Value, Loaded = field.Value, Translation = field.Value }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } } int variableCount = input.ReadInt32(); for (int i = 0; i < variableCount; i++) { int id = input.ReadInt32(); int fieldCount = input.ReadInt32(); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Description" }; foreach (string translatableField in translatableFields) { if (fields.TryGetValue(translatableField, out Field field)) { if (!string.IsNullOrEmpty(field.Value)) { var subtitle = new SubtitleWithId { Id = $"Variable_{id}_{translatableField}", Offset = 0, Text = field.Value, Loaded = field.Value, Translation = field.Value }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } } int conversationCount = input.ReadInt32(); for (int i = 0; i < conversationCount; i++) { int id = input.ReadInt32(); int fieldCount = input.ReadInt32(); var fields = new Dictionary <string, Field>(fieldCount); for (int j = 0; j < fieldCount; j++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields.Add(field.Title, field); } var translatableFields = new string[] { "Title", "Description", "subtask_title_01", "subtask_title_02", "subtask_title_03", "subtask_title_04", "subtask_title_05", "subtask_title_06", "subtask_title_07", "subtask_title_08", "subtask_title_09", "subtask_title_10", }; foreach (string translatableField in translatableFields) { if (fields.TryGetValue(translatableField, out Field field)) { if (!string.IsNullOrEmpty(field.Value)) { var subtitle = new SubtitleWithId { Id = $"Conversation_{id}_{translatableField}", Offset = 0, Text = field.Value, Loaded = field.Value, Translation = field.Value }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } // ConversationOverrideDisplaySettings input.Skip(0x28); for (int j = 0; j < 3; j++) { input.ReadStringSerialized(0x04); } input.Skip(0x10); input.ReadStringSerialized(0x04); // nodeColor // DialogueEntry int dialogueEntryCount = input.ReadInt32(); for (int j = 0; j < dialogueEntryCount; j++) { int dialogueEntryId = input.ReadInt32(); int fieldCount2 = input.ReadInt32(); var fields2 = new Dictionary <string, Field>(fieldCount2); for (int k = 0; k < fieldCount2; k++) { var field = new Field(); field.Title = input.ReadStringSerialized(0x04); field.Value = input.ReadStringSerialized(0x04); field.Type = input.ReadInt32(); field.TypeString = input.ReadStringSerialized(0x04); fields2.Add($"{field.Title}", field); } var translatableFields2 = new string[] { "Dialogue Text", "Alternate1", "Alternate2", "Alternate3", "Alternate4", "tooltip1", "tooltip2", "tooltip3", "tooltip4", "tooltip5", "tooltip6", "tooltip7", "tooltip8", "tooltip9", "tooltip10" }; foreach (string translatableField in translatableFields2) { if (fields2.TryGetValue(translatableField, out Field field)) { if (!string.IsNullOrEmpty(field.Value)) { var subtitle = new SubtitleWithId { Id = $"Conversation_{id}_Entry_{dialogueEntryId}_{translatableField}", Offset = 0, Text = field.Value, Loaded = field.Value, Translation = field.Value }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); } } } input.Skip(0x0C); input.ReadStringSerialized(0x04); // nodeColor input.Skip(0x04); input.ReadStringSerialized(0x04); // falseConditionAction input.Skip(0x04); int outgoingLinksCount = input.ReadInt32(); input.Skip(outgoingLinksCount * 0x04 * 0x06); input.ReadStringSerialized(0x04); // conditionsString string userScript = input.ReadStringSerialized(0x04); // userScript if (userScript.StartsWith("NewspaperEndgame(")) { var regex = new Regex(@"NewspaperEndgame\(""(?<Id>[^""]+)"",""(?<Headline>[^""]+)"",""(?<Text>[^""\\]*(?:\\.[^""\\]*)*)""\)"); Match match = regex.Match(userScript); while (match.Success) { string endId = match.Groups["Id"].Value; string headline = match.Groups["Headline"].Value; string text = match.Groups["Text"].Value; var subtitle = new SubtitleWithId { Id = $"Conversation_{id}_Entry_{dialogueEntryId}_EndHeadline", Offset = 0, Text = headline, Loaded = headline, Translation = headline }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); text = text.Replace("<NewLine>", "\\n").Replace("\\\"", "\""); subtitle = new SubtitleWithId { Id = $"Conversation_{id}_Entry_{dialogueEntryId}_EndText", Offset = 0, Text = text, Loaded = text, Translation = text }; subtitle.PropertyChanged += SubtitlePropertyChanged; result.Add(subtitle); match = match.NextMatch(); } } // onExecute input.Skip(0x04); input.Skip(0x10); // Canvas rect } input.Skip(0x08); // canvasScrollPosition input.Skip(0x04); // canvasZoom } LoadChanges(result); return(result); }