private void button3_Click(object sender, EventArgs e)
        {
            progressBar1.Minimum = 0;
            progressBar1.Value = 0;

            string openPath = "";
            if (comboBox1.Text.StartsWith("\\"))
            {
                openPath = MadScience.Helpers.findSims3Root() + comboBox1.Text;
            }
            else
            {
                openPath = comboBox1.Text;
            }

            if (openPath == "") return;

            Stream input = File.OpenRead(openPath);

            Database db = new Database(input, true);

            input.Seek(0, SeekOrigin.Begin);

            DatabasePackedFile dbpf = new DatabasePackedFile();
            try
            {
                dbpf.Read(input);
            }
            catch (NotAPackageException)
            {
                MessageBox.Show("bad file: {0}", comboBox1.Text);
                input.Close();
                return;
            }

            this.currentFile = new FileInfo(openPath);

            lookupTypes();
            indexEntries.Clear();
            listView1.Items.Clear();

            txtPkgIndexType.Text = dbpf.IndexType.ToString();
            txtPkgNumChunks.Text = dbpf.Entries.Count.ToString();

            uint searchTypeID = 0;
            if (comboBox2.Text != "") { searchTypeID = Gibbed.Helpers.StringHelpers.ParseHex32(comboBox2.Text); }
            ulong instanceID = 0;
            bool searchInstance = false;
            if (textBox8.Text != "")
            {
                instanceID = Gibbed.Helpers.StringHelpers.ParseHex64(textBox8.Text);
                searchInstance = true;
            }

            string tempChunk = "";
            int count = 0;

            progressBar1.Maximum = dbpf.Entries.Count;

            for (int i = 0; i < dbpf.Entries.Count; i++)
            {
                ListViewItem item = new ListViewItem();
                DatabasePackedFile.Entry entry = dbpf.Entries[i];
                progressBar1.Value++;

                bool searchChunk = false;

                if (entry.Key.TypeId == searchTypeID)
                {
                    if (searchInstance == true)
                    {
                        if (entry.Key.InstanceId == instanceID)
                        {
                            searchChunk = true;
                        }
                    }
                    else
                    {
                        searchChunk = true;
                    }
                }
                else
                {
                    if (searchInstance == true)
                    {
                        if (entry.Key.InstanceId == instanceID)
                        {
                            searchChunk = true;
                        }
                    }
                }
                //if (searchTypeID == 0) { searchChunk = true; }

                if (searchChunk)
                {

                    tempChunk = Encoding.UTF8.GetString(db.GetResource(entry.Key));
                    bool addChunk = false;

                    // If everything is blank we just list... everything
                    if (textBox3.Text == "" && textBox6.Text == "" && textBox7.Text == "")
                    {
                        addChunk = true;
                    }
                    else
                    {

                        if (tempChunk.Contains(textBox3.Text))
                        {
                            if (textBox6.Text != "")
                            {
                                if (tempChunk.Contains(textBox6.Text))
                                {
                                    if (textBox7.Text != "")
                                    {
                                        if (tempChunk.Contains(textBox7.Text))
                                        {
                                            addChunk = true;
                                        }
                                    }
                                    else
                                    {
                                        addChunk = true;
                                    }
                                }
                            }
                            else
                            {
                                addChunk = true;
                            }

                        }

                    }

                    if (addChunk == true)
                    {
                        item.Text = this.lookupList.lookup(entry.Key.TypeId).shortName;
                        item.SubItems.Add(entry.Key.TypeId.ToString("X8"));
                        item.SubItems.Add(entry.Key.GroupId.ToString("X8"));
                        item.SubItems.Add(entry.Key.InstanceId.ToString("X16"));
                        item.SubItems.Add(entry.DecompressedSize.ToString());
                        item.SubItems.Add(count.ToString());
                        listView1.Items.Add(item);
                        indexEntries.Add(entry);
                        count++;
                    }
                }
            }

            input.Close();
        }
        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 1)
            {

                ListViewItem item = listView1.SelectedItems[0];
                DatabasePackedFile.Entry indexEntry = (DatabasePackedFile.Entry)indexEntries[Convert.ToInt32(item.SubItems[5].Text)];

                txtLongName.Text = lookupList.lookup(indexEntry.Key.TypeId).longName;
                txtInstanceID.Text = indexEntry.Key.InstanceId.ToString("X16");
                txtOffset.Text = indexEntry.Offset.ToString();
                txtGroupId.Text = indexEntry.Key.GroupId.ToString("X8");

                textBox25.Text = "key:" + indexEntry.Key.TypeId.ToString("X8") + ":" + txtGroupId.Text + ":" + txtInstanceID.Text;

                Stream input = File.OpenRead(this.currentFile.FullName);

                Database db = new Database(input, true);

                textBox4.Visible = false;
                panel1.Visible = false;
                listView2.Visible = false;

                this.lockImage = true;
                chkShowAlpha.Visible = false;
                chkShowBlue.Visible = false;
                chkShowGreen.Visible = false;
                chkShowRed.Visible = false;
                this.lockImage = false;

                switch (indexEntry.Key.TypeId)
                {
                    case 0x034AEECB: // Cas Part
                        textBox4.Visible = true;
                        textBox4.Text = "";
                        Stream caspStream = db.GetResourceStream(indexEntry.Key);
                        showCaspFile(caspStream);
                        caspStream.Close();
                        break;

                    case 0x01661233: // MODL
                        listView2.Visible = true;
                        listView2.Items.Clear();
                        Stream modlStream = db.GetResourceStream(indexEntry.Key);
                        showModlFile(modlStream);
                        modlStream.Close();
                        break;
                    case 0x067CAA11: // Blend Geometry
                        listView2.Visible = true;
                        listView2.Items.Clear();

                        Stream bgeoStream = db.GetResourceStream(indexEntry.Key);
                        showBlendGeomFile(bgeoStream);
                        bgeoStream.Close();

                        break;

                    case 0x0358B08A: // Face Part File
                        listView2.Visible = true;
                        listView2.Items.Clear();

                        Stream fpartStream = db.GetResourceStream(indexEntry.Key);
                        showFacePartFile(fpartStream);
                        fpartStream.Close();

                        break;

                    case 0xb52f5055: // Facial Blend

                        listView2.Visible = true;
                        listView2.Items.Clear();

                        Stream fblendStream = db.GetResourceStream(indexEntry.Key);
                        showFacialBlendFile(fblendStream);
                        fblendStream.Close();

                        break;

                    case 0x033A1435: // Texture Compositor

                        listView2.Visible = true;
                        listView2.Items.Clear();

                        Stream txtcStream = db.GetResourceStream(indexEntry.Key);
                        showTextureCompositorFile(txtcStream);
                        txtcStream.Close();
                        break;

                    case 0x736884F1: // VPXY

                        listView2.Visible = true;
                        listView2.Items.Clear();

                        Stream vpxyStream = db.GetResourceStream(indexEntry.Key);
                        showVpxyFile(vpxyStream);
                        vpxyStream.Close();

                        break;

                    case 0x0166038C: // Key name

                        listView2.Visible = true;
                        listView2.Items.Clear();

                        Stream keyNameFile = db.GetResourceStream(indexEntry.Key);
                        showKeyNameFile(keyNameFile);
                        keyNameFile.Close();

                        break;

                    case 0x00b2d882: // DDS

                        panel1.Visible = true;

                        ddsFile.Load(db.GetResourceStream(indexEntry.Key));
                        this.lockImage = true;
                        pictureBox1.Image = ddsFile.Image();

                        chkShowAlpha.Visible = true;
                        chkShowBlue.Visible = true;
                        chkShowGreen.Visible = true;
                        chkShowRed.Visible = true;
                        chkShowAlpha.Checked = false;
                        chkShowBlue.Checked = true;
                        chkShowGreen.Checked = true;
                        chkShowRed.Checked = true;
                        this.lockImage = false;

                        break;
                    // XML
                    case 0x73e93eeb:
                    case 0xd4d9fbe5:
                    case 0x0333406c:
                        textBox4.Visible = true;
                        textBox4.Text = Encoding.ASCII.GetString(db.GetResource(indexEntry.Key));
                        break;
                    case 0x015a1849:
                        // GEOM
                        listView2.Visible = true;
                        listView2.Items.Clear();

                        Stream geominput = db.GetResourceStream(indexEntry.Key);
                        showGeomFile(geominput);
                        geominput.Close();

                        break;
                }

                input.Close();

            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
            progressBar1.Minimum = 0;
            progressBar1.Value = 0;

            textBox1.Text = "";

            string firstPath = textBox2.Text;
            FileInfo f1 = new FileInfo(firstPath);
            Stream firstStream = File.OpenRead(firstPath);
            Database firstDb = new Database(firstStream);

            string secondPath = textBox3.Text;
            FileInfo f2 = new FileInfo(secondPath);
            Stream secondStream = File.OpenRead(secondPath);
            Database secondDb = new Database(secondStream);

            textBox1.Text += firstStream.Length.ToString() + " bytes vs " + secondStream.Length.ToString() + " bytes" + Environment.NewLine;
            textBox1.Text += "Comparing " + f1.Name + " to " + f2.Name + Environment.NewLine;

            textBox1.Text += f1.Name + " has " + firstDb.Entries.Count.ToString() + Environment.NewLine;
            textBox1.Text += f2.Name + " has " + secondDb.Entries.Count.ToString() + Environment.NewLine;

            StringBuilder sb = new StringBuilder();

            progressBar1.Maximum = firstDb.Entries.Count;

            int numChanged = 0;
            int identical = 0;

            foreach (KeyValuePair<ResourceKey, Database.Entry> entry in firstDb.Entries)
            {
                progressBar1.Value++;
                if (secondDb.Entries.ContainsKey(entry.Key) == false)
                {
                    numChanged++;
                    sb.AppendLine("Only in " + f1.Name + ": " + entry.Key + " (Size: " + entry.Value.CompressedSize + ")" );
                }
            }

            progressBar1.Value = 0;
            progressBar1.Maximum = secondDb.Entries.Count;

            foreach (KeyValuePair<ResourceKey, Database.Entry> entry in secondDb.Entries)
            {
                progressBar1.Value++;
                if (firstDb.Entries.ContainsKey(entry.Key) == false)
                {
                    numChanged++;
                    sb.AppendLine("Only in " + f2.Name + ": " + entry.Key + " (Size: " + entry.Value.CompressedSize + ")");
                }
            }

            numChanged = 0;

            progressBar1.Value = 0;
            progressBar1.Maximum = firstDb.Entries.Count;

            System.Security.Cryptography.MD5CryptoServiceProvider cryptHandler;
            cryptHandler = new System.Security.Cryptography.MD5CryptoServiceProvider();

            foreach (KeyValuePair<ResourceKey, Database.Entry> entry in firstDb.Entries)
            {
                progressBar1.Value++;
                bool different = false;

                if (secondDb.Entries.ContainsKey(entry.Key) == false)
                {
                    // Check the second file to see if it has a chunk with the same type and group, but a different instance,
                    // but also has the same size and hash etc
                    foreach (KeyValuePair<ResourceKey, Database.Entry> entry2 in secondDb.Entries)
                    {
                        if (entry.Key.TypeId == entry2.Key.TypeId && entry.Key.GroupId == entry2.Key.GroupId && entry.Value.CompressedSize == entry2.Value.CompressedSize && entry.Value.DecompressedSize == entry2.Value.DecompressedSize)
                        {
                            identical++;
                            sb.AppendLine("Chunk " + progressBar1.Value.ToString() + ": Identical chunks: " + entry.Key + " and " + entry2.Key);
                            different = true;
                            break;
                        }
                    }
                    if (!different)
                    {
                        sb.AppendLine("Chunk " + progressBar1.Value.ToString() + ": Does not appear in second package " + entry.Key);
                    }
                    continue;
                }

                ResourceKey key = entry.Key;

                string diffReason = "";

                if (firstDb.Entries[key].DecompressedSize != secondDb.Entries[key].DecompressedSize)
                {
                    diffReason = "Size";
                    different = true;
                }
                else
                {

                    //if (firstDb.Entries[key].

                    byte[] firstData = firstDb.GetResource(key);
                    byte[] secondData = secondDb.GetResource(key);

                    if (firstData.Length != secondData.Length)
                    {
                        diffReason = "Size2";
                        different = true;
                    }
                    else
                    {
                        byte[] hash1 = cryptHandler.ComputeHash(firstData);
                        byte[] hash2 = cryptHandler.ComputeHash(secondData);

                        if (hash1.ToString() != hash2.ToString())
                        {
                            diffReason = "Hash of contents";
                            different = true;
                        }
                    }
                }

                if (different == true)
                {
                    numChanged++;
                    sb.AppendLine("Chunk " + progressBar1.Value.ToString() + ": Differs in " + diffReason + ": " + key);
                }
                else
                {
                    identical++;
                    sb.AppendLine("Chunk " + progressBar1.Value.ToString() + ": Identical chunks: " + key);
                }
            }

            textBox1.Text += sb.ToString();
            textBox1.Text += identical.ToString() + " identical entries" + Environment.NewLine;
            textBox1.Text += numChanged.ToString() + " changed entries" + Environment.NewLine;

            progressBar1.Value = 0;
            secondStream.Close();
            firstStream.Close();
        }