/// <summary> /// Applies translations to content.ggpk /// </summary> public void ApplyTranslations() { StringBuilder outputBuffer = new StringBuilder(); foreach (var datTranslation in AllDatTranslations) { // Map of originalText -> Translation containing all translations to apply Dictionary<string, Translation> translationsToApply = (from n in datTranslation.Value.Translations where n.Status == Translation.TranslationStatus.NeedToApply select n).ToDictionary(k => k.OriginalText); if (translationsToApply.Count == 0) { continue; } // Record we will be translating with data from translationTable FileRecord datRecord = fileRecordMap[datTranslation.Value.DatName]; // Raw bytes of the .dat file we will be translating byte[] datBytes = datRecord.ReadData(ggpkPath); // Dat parser for changing the actual strings DatContainer dc = new DatContainer(new MemoryStream(datBytes), datTranslation.Value.DatName); // Replace the actual strings foreach (var item in dc.DataEntries) { UnicodeString currentDatString = (item.Value as UnicodeString); if (currentDatString == null || !currentDatString.IsUserString) { continue; } if (!translationsToApply.ContainsKey(currentDatString.Data)) { continue; } Translation translationBeingApplied = translationsToApply[currentDatString.Data]; currentDatString.NewData = translationBeingApplied.TranslatedText; outputBuffer.AppendLine(string.Format(Settings.Strings["ApplyTranslations_TextReplaced"], translationBeingApplied.ShortNameCurrent, translationBeingApplied.ShortNameTranslated)); translationBeingApplied.Status = Translation.TranslationStatus.AlreadyApplied; } // dc.GetBytes() will return the new data for this .dat file after replacing the original strings with whatever's in 'NewData' datRecord.ReplaceContents(ggpkPath, dc.GetBytes(), content.FreeRoot); } if (outputBuffer.Length > 0) { Output(outputBuffer.ToString()); } }
private void ParseDatFile(Stream inStream) { Dat = new DatContainer(inStream, datName); try { var containerData = DataEntries.ToList(); foreach (var keyValuePair in containerData) { if (keyValuePair.Value is UnicodeString) { Strings.Add((UnicodeString)keyValuePair.Value); } else if (keyValuePair.Value is UInt64List) { UInt64List ul = (UInt64List)keyValuePair.Value; Strings.Add((UnicodeString)new UnicodeString(ul.Offset, ul.dataTableOffset, ul.ToString())); } else if (keyValuePair.Value is UInt32List) { UInt32List ul = (UInt32List)keyValuePair.Value; Strings.Add((UnicodeString)new UnicodeString(ul.Offset, ul.dataTableOffset, ul.ToString())); } else if (keyValuePair.Value is Int32List) { Int32List ul = (Int32List)keyValuePair.Value; Strings.Add((UnicodeString)new UnicodeString(ul.Offset, ul.dataTableOffset, ul.ToString())); } } } catch (Exception ex) { throw new Exception(string.Format(Settings.Strings["DatWrapper_ParseDatFile_Failed"], ex.Message), ex); } }
/// <summary> /// Gets a list of all translatable strings in specified record. Record must be a FileRecord of a valid dat file. /// </summary> /// <param name="record">Dat File Record to extract translatable strings from</param> /// <returns>List of translatable strings contained in specified dat file</returns> private List<string> GetTranslatableStringsFromDatFile(FileRecord record) { // Map of all strings that can be safely translated (not used as ID's, paths, etc) stored by their hash HashSet<string> currentStrings = new HashSet<string>(); byte[] datBytes = record.ReadData(ggpkPath); using (MemoryStream datStream = new MemoryStream(datBytes)) { DatContainer container = new DatContainer(datStream, record.Name); // Any properties with the UserStringIndex attribute are translatable foreach (var propInfo in container.DatType.GetProperties()) { if (!propInfo.GetCustomAttributes(false).Any(n => n is UserStringIndex)) { continue; } foreach (var entry in container.Entries) { int stringIndex = (int)propInfo.GetValue(entry, null); string stringValue = container.DataEntries[stringIndex].ToString(); if (string.IsNullOrWhiteSpace(stringValue)) { continue; } if (!currentStrings.Contains(stringValue)) { currentStrings.Add(stringValue); } } } } return currentStrings.ToList(); }