Beispiel #1
0
        // 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();
        }