/// <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(); }
public void SerializeRecords(string pathToBin, Action<string> output) { if (output != null) { output(Environment.NewLine); output("Serializing... "); } var Serialized = File.Create(pathToBin); var s = new BinaryWriter(Serialized); foreach (var record in RecordOffsets) { s.Write(record.Key); var baseRecord = record.Value; if (baseRecord is FileRecord) { s.Write((byte)1); FileRecord fr = (FileRecord)baseRecord; s.Write(fr.RecordBegin); s.Write(fr.Length); s.Write(fr.Hash); s.Write(fr.Name); s.Write(fr.DataBegin); s.Write(fr.DataLength); } else if (baseRecord is GgpkRecord) { s.Write((byte)2); GgpkRecord gr = (GgpkRecord)baseRecord; s.Write(gr.RecordBegin); s.Write(gr.Length); s.Write(gr.RecordOffsets.Length); foreach (long l in gr.RecordOffsets) { s.Write(l); } } else if (baseRecord is FreeRecord) { s.Write((byte)3); FreeRecord fr = (FreeRecord)baseRecord; s.Write(fr.RecordBegin); s.Write(fr.Length); s.Write(fr.NextFreeOffset); } else if (baseRecord is DirectoryRecord) { s.Write((byte)4); DirectoryRecord dr = (DirectoryRecord)baseRecord; s.Write(dr.RecordBegin); s.Write(dr.Length); s.Write(dr.Hash); s.Write(dr.Name); s.Write(dr.EntriesBegin); s.Write(dr.Entries.Count); foreach (var directoryEntry in dr.Entries) { s.Write(directoryEntry.EntryNameHash); s.Write(directoryEntry.Offset); } } } Serialized.Flush(); Serialized.Close(); output?.Invoke("Done!" + Environment.NewLine); }
public void DeleteFileRecord(FileRecord file) { var parent = file.ContainingDirectory; parent.RemoveFile(file); }
/// <summary> /// Attempts to display the specified record on the gui /// </summary> /// <param name="selectedRecord">Record to view</param> private void ViewFileRecord(FileRecord selectedRecord) { string extractedFileName; try { extractedFileName = selectedRecord.ExtractTempFile(ggpkPath); // If we're dealing with .dat files then just create a human readable CSV and view that instead if (Path.GetExtension(selectedRecord.Name).ToLower() == ".dat") { string extractedCSV = Path.GetTempFileName(); File.Move(extractedCSV, extractedCSV + ".csv"); extractedCSV = extractedCSV + ".csv"; using (FileStream inStream = File.Open(extractedFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { DatWrapper tempWrapper = new DatWrapper(inStream, selectedRecord.Name); File.WriteAllText(extractedCSV, tempWrapper.Dat.GetCSV()); } File.Delete(extractedFileName); extractedFileName = extractedCSV; } } catch (Exception ex) { MessageBox.Show(string.Format(Settings.Strings["ViewSelectedItem_Failed"], ex.Message), Settings.Strings["Error_Caption"], MessageBoxButton.OK, MessageBoxImage.Error); return; } Process fileViewerProcess = new Process(); fileViewerProcess.StartInfo = new ProcessStartInfo(extractedFileName); fileViewerProcess.EnableRaisingEvents = true; fileViewerProcess.Exited += fileViewerProcess_Exited; fileViewerProcess.Start(); }
/// <summary> /// Displays the contents of a FileRecord in the TextBox as Ascii text /// </summary> /// <param name="selectedRecord">FileRecord to display</param> private void DisplayAscii(FileRecord selectedRecord) { byte[] buffer = selectedRecord.ReadData(ggpkPath); textBoxOutput.Visibility = System.Windows.Visibility.Visible; textBoxOutput.Text = Encoding.ASCII.GetString(buffer); }
/// <summary> /// Exports the specified FileRecord to disk /// </summary> /// <param name="selectedRecord">FileRecord to export</param> private void ExportFileRecord(FileRecord selectedRecord) { try { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FileName = selectedRecord.Name; if (saveFileDialog.ShowDialog() == true) { selectedRecord.ExtractFile(ggpkPath, saveFileDialog.FileName); MessageBox.Show(string.Format(Settings.Strings["ExportSelectedItem_Successful"], selectedRecord.DataLength), Settings.Strings["ExportAllItemsInDirectory_Successful_Caption"], MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { MessageBox.Show(string.Format(Settings.Strings["ExportSelectedItem_Failed"], ex.Message), Settings.Strings["Error_Caption"], MessageBoxButton.OK, MessageBoxImage.Error); return; } }
/// <summary> /// Replaces selected file with file user selects via MessageBox /// </summary> /// <param name="recordToReplace"></param> private void ReplaceItem(FileRecord recordToReplace) { if (content.IsReadOnly) { MessageBox.Show(Settings.Strings["ReplaceItem_Readonly"], Settings.Strings["ReplaceItem_ReadonlyCaption"]); return; } try { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.FileName = ""; openFileDialog.CheckFileExists = true; openFileDialog.CheckPathExists = true; if (openFileDialog.ShowDialog() == true) { long previousOffset = recordToReplace.RecordBegin; recordToReplace.ReplaceContents(ggpkPath, openFileDialog.FileName, content.FreeRoot); MessageBox.Show(String.Format(Settings.Strings["ReplaceItem_Successful"], recordToReplace.Name, recordToReplace.RecordBegin.ToString("X")), Settings.Strings["ReplaceItem_Successful_Caption"], MessageBoxButton.OK, MessageBoxImage.Information); UpdateDisplayPanel(); } } catch (Exception ex) { MessageBox.Show(string.Format(Settings.Strings["ReplaceItem_Failed"], ex.Message), Settings.Strings["Error_Caption"], MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// Displays the contents of a FileRecord in the RichTextBox /// </summary> /// <param name="selectedRecord">FileRecord to display</param> private void DisplayRichText(FileRecord selectedRecord) { byte[] buffer = selectedRecord.ReadData(ggpkPath); richTextOutput.Visibility = System.Windows.Visibility.Visible; using (MemoryStream ms = new MemoryStream(buffer)) { richTextOutput.Selection.Load(ms, DataFormats.Rtf); } }
/// <summary> /// Displays the contents of a FileRecord in the ImageBox /// </summary> /// <param name="selectedRecord">FileRecord to display</param> private void DisplayImage(FileRecord selectedRecord) { byte[] buffer = selectedRecord.ReadData(ggpkPath); imageOutput.Visibility = System.Windows.Visibility.Visible; using (MemoryStream ms = new MemoryStream(buffer)) { BitmapImage bmp = new BitmapImage(); bmp.BeginInit(); bmp.CacheOption = BitmapCacheOption.OnLoad; bmp.StreamSource = ms; bmp.EndInit(); imageOutput.Source = bmp; } }
/// <summary> /// Displays the contents of a FileRecord in the ImageBox (DDS Texture mode) /// </summary> /// <param name="selectedRecord">FileRecord to display</param> private void DisplayDDS(FileRecord selectedRecord) { byte[] buffer = selectedRecord.ReadData(ggpkPath); imageOutput.Visibility = System.Windows.Visibility.Visible; DDSImage dds = new DDSImage(buffer); using (MemoryStream ms = new MemoryStream()) { dds.images[0].Save(ms, ImageFormat.Png); BitmapImage bmp = new BitmapImage(); bmp.BeginInit(); bmp.CacheOption = BitmapCacheOption.OnLoad; bmp.StreamSource = ms; bmp.EndInit(); imageOutput.Source = bmp; } }
/// <summary> /// Displays the contents of a FileRecord in the DatViewer /// </summary> /// <param name="selectedRecord">FileRecord to display</param> private void DisplayDat(FileRecord selectedRecord) { byte[] data = selectedRecord.ReadData(ggpkPath); datViewerOutput.Visibility = System.Windows.Visibility.Visible; using (MemoryStream ms = new MemoryStream(data)) { datViewerOutput.Reset(selectedRecord.Name, ms); } }
public void ReplaceFile(FileRecord fileRecord, string path) { ReplaceFile(fileRecord, File.ReadAllBytes(path)); }