// Dumper private void workerDumper_DoWork(object sender, DoWorkEventArgs e) { FileStream fs = new FileStream(txtFilename.Text, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReaderX br = new BinaryReaderX(fs, ByteOrder.LittleEndian); // Pointer Tables _pointers = new Dictionary <long, long>(); _workerDumper.ReportProgress(0, "STATUS|Dumping pointers..."); foreach (Bound pointerBound in _kup.PointerTables) { long end = Math.Max(4, pointerBound.EndLong); if (end == 4) { end += pointerBound.StartLong; } br.BaseStream.Seek(pointerBound.StartLong, SeekOrigin.Begin); while (br.BaseStream.Position < end) { uint offset = br.ReadUInt32() - _kup.RamOffsetUInt; if (offset < br.BaseStream.Length) { _pointers.Add(br.BaseStream.Position - sizeof(uint), offset); // AAAHAAAAARRRRRRGGRGGGGHHHHHHH } _workerDumper.ReportProgress((int)(((double)br.BaseStream.Position - pointerBound.StartLong) / ((double)pointerBound.EndLong - pointerBound.StartLong) * prgBottom.Maximum), "BOTTOM"); } } _workerDumper.ReportProgress(0, "STATUS|Found " + _pointers.Count + " pointers..."); _workerDumper.ReportProgress(0, "STATUS|Dumping strings..."); for (int i = 0; i < _kup.StringBounds.Count; i++) { Bound stringBound = _kup.StringBounds[i]; _workerDumper.ReportProgress((int)(((double)i + 1 / (double)_kup.StringBounds.Count) * prgBottom.Maximum), "BOTTOM"); if (stringBound.Dumpable) { List <byte> result = new List <byte>(); long offset = stringBound.StartLong; long jumpBack = 0; br.BaseStream.Seek(stringBound.StartLong, SeekOrigin.Begin); while (br.BaseStream.Position < stringBound.EndLong) { byte[] unichar = br.ReadBytes(2); result.AddRange(unichar); if (stringBound.Injectable) { if (jumpBack == 0 && (_pointers.Values.Contains(br.BaseStream.Position) || br.BaseStream.Position == stringBound.EndLong)) { jumpBack = br.BaseStream.Position; } if ((_pointers.Values.Contains(br.BaseStream.Position) || br.BaseStream.Position == stringBound.EndLong) && (result[result.Count - 1] == 0x00 && result[result.Count - 2] == 0x00)) { if (result[result.Count - 1] == 0x00 && result[result.Count - 2] == 0x00) { result.RemoveAt(result.Count - 1); result.RemoveAt(result.Count - 1); } Entry entry = new Entry(); entry.OffsetLong = offset; // Merging bool matched = false; foreach (Entry ent in _kup.Entries) { if (ent.Offset == entry.Offset) { entry = ent; matched = true; break; } } if (matched) { foreach (long key in _pointers.Keys) { if (_pointers[key] == offset) { entry.AddPointer(key); } } entry.OriginalText = _kup.Encoding.GetString(result.ToArray()); if (entry.EditedText == entry.OriginalText) { entry.EditedText = _kup.Encoding.GetString(result.ToArray()); } } else { foreach (long key in _pointers.Keys) { if (_pointers[key] == offset) { entry.AddPointer(key); } } entry.Relocatable = stringBound.Injectable; entry.Name = Regex.Match(entry.OriginalText, @"\w+", RegexOptions.IgnoreCase).Value; _kup.Entries.Add(entry); } string str = _gameHandler.GetKuriimuString(entry.OriginalText).Replace("\0", "<null>").Replace("\n", "\r\n"); if (Regex.Matches(str, "<null>").Count > 0) { _workerDumper.ReportProgress(0, "STATUS|Found a potentially broken string at " + entry.Offset + ": " + entry.Name + "|" + entry.Offset); } if (jumpBack > 0) { br.BaseStream.Seek(jumpBack, SeekOrigin.Begin); jumpBack = 0; } offset = br.BaseStream.Position; result.Clear(); } } else { if (br.BaseStream.Position == stringBound.EndLong) { if (result.Count >= 2) { if (result[result.Count - 1] == 0x00 && result[result.Count - 2] == 0x00) { result.RemoveAt(result.Count - 1); result.RemoveAt(result.Count - 1); } Entry entry = new Entry(); entry.OffsetLong = stringBound.StartLong; // Merging bool matched = false; foreach (Entry ent in _kup.Entries) { if (ent.Offset == entry.Offset) { entry = ent; matched = true; break; } } if (matched) { entry.OriginalText = _kup.Encoding.GetString(result.ToArray()); if (entry.EditedText == entry.OriginalText) { entry.EditedText = _kup.Encoding.GetString(result.ToArray()); } } else { entry.OriginalText = _kup.Encoding.GetString(result.ToArray()); entry.EditedText = _kup.Encoding.GetString(result.ToArray()); entry.Relocatable = stringBound.Injectable; entry.Name = Regex.Match(entry.OriginalText, @"\w+", RegexOptions.IgnoreCase).Value; entry.MaxLength = entry.EditedText.Length; _kup.Entries.Add(entry); } } result.Clear(); } } _workerDumper.ReportProgress((int)(((double)br.BaseStream.Position - stringBound.StartLong) / ((double)stringBound.EndLong - stringBound.StartLong) * prgTop.Maximum), "TOP"); } } } _workerDumper.ReportProgress(0, "STATUS|Dumped " + _kup.Entries.Count + " strings..."); br.Close(); }