Ejemplo n.º 1
0
        public void SaveAll(object oinfo)
        {
            SaveAllInformation          info = (SaveAllInformation)oinfo;
            IEnumerable <BigFile.Entry> saving;

            if (info.Saving == null)
            {
                saving = info.Archive.Entries;
            }
            else
            {
                saving = info.Saving;
            }

            this.SetStatus("", 0);

            int total   = saving.Count();
            int current = 0;

            byte[] buffer = new byte[0x4000];
            foreach (var entry in saving)
            {
                current++;

                if (entry.Duplicate == true &&
                    info.Settings.SaveFilesWithDuplicateNames == false)
                {
                    this.SetStatus("Skipping...", (int)(((float)current / (float)total) * 100.0f));
                    continue;
                }

                string fileName = null;

                if (info.FileNames.ContainsKey(entry.Name) == true)
                {
                    fileName = info.FileNames[entry.Name];

                    if (entry.Duplicate == true)
                    {
                        string newFileName;

                        newFileName = Path.GetFileNameWithoutExtension(fileName);
                        newFileName = string.Format("{0} (duplicate #{1})", newFileName, current);
                        newFileName = Path.ChangeExtension(newFileName, Path.GetExtension(fileName));
                        fileName    = Path.Combine(Path.GetDirectoryName(fileName), newFileName);
                    }
                }
                else
                {
                    if (info.Settings.SaveOnlyKnownFiles)
                    {
                        this.SetStatus("Skipping...", (int)(((float)current / (float)total) * 100.0f));
                        continue;
                    }

                    fileName = entry.Name.ToString("X8");

                    if (true)
                    {
                        info.Stream.Seek(entry.Offset, SeekOrigin.Begin);
                        byte[] guess = new byte[16];
                        int    read  = info.Stream.Read(guess, 0, guess.Length);

                        if (
                            read >= 4 &&
                            guess[0] == 0x28 &&
                            guess[1] == 0x7B &&
                            guess[2] == 0xBA &&
                            guess[3] == 0x9C)
                        {
                            fileName = Path.ChangeExtension(fileName, ".toc");
                            fileName = Path.Combine("archive", fileName);
                        }
                        else if (
                            read >= 4 &&
                            guess[0] == 0x9C &&
                            guess[1] == 0xBA &&
                            guess[2] == 0x7B &&
                            guess[3] == 0x28)
                        {
                            fileName = Path.ChangeExtension(fileName, ".toc");
                            fileName = Path.Combine("archive", fileName);
                        }
                        else if (
                            read >= 4 &&
                            guess[0] == '3' && // 3
                            guess[1] == 's' && // s
                            guess[2] == 'l' && // l
                            guess[3] == 'o')   // o
                        {
                            fileName = Path.ChangeExtension(fileName, ".str");
                            fileName = Path.Combine("archive", fileName);
                        }
                        else if (
                            read >= 4 &&
                            guess[0] == 'o' && // o
                            guess[1] == 'l' && // l
                            guess[2] == 's' && // s
                            guess[3] == '3')   // 3
                        {
                            fileName = Path.ChangeExtension(fileName, ".str");
                            fileName = Path.Combine("archive", fileName);
                        }
                        else if (
                            read >= 4 &&
                            guess[0] == 'M' &&
                            guess[1] == 'V' &&
                            guess[2] == 'h' &&
                            guess[3] == 'd')
                        {
                            fileName = Path.ChangeExtension(fileName, ".vp6");
                            fileName = Path.Combine("video", fileName);
                        }
                        else if (
                            read >= 4 &&
                            guess[0] == 'S' &&
                            guess[1] == 'C' &&
                            guess[2] == 'H' &&
                            guess[3] == 'l')
                        {
                            fileName = Path.ChangeExtension(fileName, ".vp6");
                            fileName = Path.Combine("audio", fileName);
                        }
                        else if (
                            read >= 3 &&
                            guess[0] == 0x03 &&
                            guess[1] == 0x00 &&
                            guess[2] == 0x00)
                        {
                            fileName = Path.ChangeExtension(fileName, ".exa.snu");
                            fileName = Path.Combine("audio", fileName);
                        }
                        else
                        {
                            //fileName = Path.Combine(Path.Combine("unknown", fileName.Substring(0, 1)), fileName);
                            fileName = Path.Combine("unknown", fileName);
                        }
                    }

                    fileName = Path.Combine("__UNKNOWN", fileName);

                    if (entry.Duplicate == true)
                    {
                        string newFileName;

                        newFileName = Path.GetFileNameWithoutExtension(fileName);
                        newFileName = string.Format("{0} (duplicate #{1})", newFileName, current);
                        newFileName = Path.ChangeExtension(newFileName, Path.GetExtension(fileName));
                        fileName    = Path.Combine(Path.GetDirectoryName(fileName), newFileName);
                    }
                }

                string path = Path.Combine(info.BasePath, fileName);
                if (File.Exists(path) == true &&
                    info.Settings.DontOverwriteFiles == true)
                {
                    this.SetStatus("Skipping...", (int)(((float)current / (float)total) * 100.0f));
                    continue;
                }

                if (info.Settings.DontSaveAudioFiles == true &&
                    Path.GetExtension(path) == ".snu")
                {
                    this.SetStatus("Skipping...", (int)(((float)current / (float)total) * 100.0f));
                    continue;
                }

                this.SetStatus(fileName, (int)(((float)current / (float)total) * 100.0f));

                Directory.CreateDirectory(Path.Combine(info.BasePath, Path.GetDirectoryName(fileName)));

                info.Stream.Seek(entry.Offset, SeekOrigin.Begin);

                using (var output = File.Create(path))
                {
                    int left = (int)entry.Size;
                    while (left > 0)
                    {
                        int read = info.Stream.Read(buffer, 0, Math.Min(left, buffer.Length));
                        if (read == 0)
                        {
                            break;
                        }
                        output.Write(buffer, 0, read);
                        left -= read;
                    }
                }
            }

            this.SaveDone();
        }
Ejemplo n.º 2
0
        public void SaveAll(object oinfo)
        {
            SaveAllInformation info = (SaveAllInformation)oinfo;

            XmlTextWriter writer = new XmlTextWriter(Path.Combine(info.BasePath, "files.xml"), Encoding.UTF8);

            writer.Formatting = Formatting.Indented;

            writer.WriteStartDocument();
            writer.WriteStartElement("files");

            for (int i = 0; i < info.Files.Length; i++)
            {
                DatabasePackedFile.Entry index = info.Files[i];

                string fileName  = null;
                string groupName = null;

                if (Lookup.Files.ContainsKey(index.Key.InstanceId))
                {
                    fileName = Lookup.Files[index.Key.InstanceId];

                    char[] invalids = Path.GetInvalidFileNameChars();
                    for (int j = 0; j < invalids.Length; j++)
                    {
                        fileName = fileName.Replace(invalids[j].ToString(), "");
                    }
                }
                else
                {
                    fileName = "#" + index.Key.InstanceId.ToString("X16");
                }

                if (Lookup.Groups.ContainsKey(index.Key.GroupId))
                {
                    groupName = Lookup.Groups[index.Key.GroupId];
                }
                else
                {
                    groupName = "#" + index.Key.GroupId.ToString("X8");
                }

                string fragmentPath;

                if (Lookup.Types.ContainsKey(index.Key.TypeId) == true)
                {
                    TypeLookup type = Lookup.Types[index.Key.TypeId];
                    fragmentPath = Path.Combine(type.Category, type.Directory);
                    fragmentPath = Path.Combine(fragmentPath, groupName);
                    fileName    += "." + Lookup.Types[index.Key.TypeId].Extension;
                }
                else
                {
                    fragmentPath = Path.Combine("unknown", "#" + index.Key.TypeId.ToString("X8"));
                    fragmentPath = Path.Combine(fragmentPath, groupName);
                }

                Directory.CreateDirectory(Path.Combine(info.BasePath, fragmentPath));

                string path = Path.Combine(fragmentPath, fileName);

                this.SetStatus(path, i);

                writer.WriteStartElement("file");
                writer.WriteAttributeString("groupid", "0x" + index.Key.GroupId.ToString("X8"));
                writer.WriteAttributeString("instanceid", "0x" + index.Key.InstanceId.ToString("X16"));
                writer.WriteAttributeString("typeid", "0x" + index.Key.TypeId.ToString("X8"));
                writer.WriteValue(path);
                writer.WriteEndElement();

                path = Path.Combine(info.BasePath, path);

                if (index.Compressed)
                {
                    info.Archive.Seek(index.Offset, SeekOrigin.Begin);
                    byte[]     d      = info.Archive.RefPackDecompress();
                    FileStream output = new FileStream(path, FileMode.Create);
                    output.Write(d, 0, d.Length);
                    output.Close();
                }
                else
                {
                    info.Archive.Seek(index.Offset, SeekOrigin.Begin);
                    byte[] d = new byte[index.DecompressedSize];
                    info.Archive.Read(d, 0, d.Length);
                    FileStream output = new FileStream(path, FileMode.Create);
                    output.Write(d, 0, d.Length);
                    output.Close();
                }
            }

            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
            writer.Close();
            this.SaveDone();
        }
Ejemplo n.º 3
0
        public void SaveAll(object oinfo)
        {
            SaveAllInformation      info = (SaveAllInformation)oinfo;
            IEnumerable <ERF.Entry> saving;

            if (info.Saving == null)
            {
                saving = info.Archive.Entries;
            }
            else
            {
                saving = info.Saving;
            }

            this.SetStatus("", 0);

            int total   = saving.Count();
            int current = 0;

            var buffer = new byte[0x100000];

            foreach (var entry in saving)
            {
                current++;

                string fileName = null;

                if (entry.Name != null)
                {
                    fileName = entry.Name;
                }
                else
                {
                    if (info.FileNames.Contains(entry.NameHash) == true)
                    {
                        fileName = info.FileNames[entry.NameHash];
                    }
                    else
                    {
                        if (info.Settings.SaveOnlyKnownFiles)
                        {
                            this.SetStatus("Skipping...", (int)(((float)current / (float)total) * 100.0f));
                            continue;
                        }

                        if (info.TypeNames != null &&
                            info.TypeNames.Contains(entry.TypeHash) == true)
                        {
                            fileName =
                                entry.NameHash.ToString("X16") + "." +
                                info.TypeNames[entry.TypeHash];
                            fileName = Path.Combine(info.TypeNames[entry.TypeHash], fileName);
                        }
                        else
                        {
                            fileName =
                                entry.NameHash.ToString("X16") + "." +
                                entry.TypeHash.ToString("X8");
                        }

                        fileName = Path.Combine("__UNKNOWN", fileName);
                    }
                }

                string path = Path.Combine(info.BasePath, fileName);
                if (File.Exists(path) == true &&
                    info.Settings.DontOverwriteFiles == true)
                {
                    this.SetStatus("Skipping...", (int)(((float)current / (float)total) * 100.0f));
                    continue;
                }

                this.SetStatus(fileName, (int)(((float)current / (float)total) * 100.0f));

                Directory.CreateDirectory(Path.Combine(info.BasePath, Path.GetDirectoryName(fileName)));

                info.Stream.Seek(entry.Offset, SeekOrigin.Begin);

                using (var output = File.Create(path))
                {
                    Stream data = info.Stream;

                    switch (info.Archive.Encryption)
                    {
                    case ERF.EncryptionScheme.None:
                    {
                        //data = data;
                        break;
                    }

                    default:
                    {
                        throw new NotSupportedException("unsupported encryption scheme");
                    }
                    }

                    switch (info.Archive.Compression)
                    {
                    case ERF.CompressionScheme.BiowareZlib:
                    {
                        /* Bioware's zlib has a custom header of 1 byte
                         * rather than the normal two-byte zlib header.
                         *
                         * The upper 4 bits are the window bits.
                         *
                         * The uppermost bit must always be set to 1,
                         * since a valid window bits size must be from
                         * 8 to 15.
                         *
                         * Don't know what the lower 4 bits are for yet.
                         *
                         * So for now, we'll ignore it their header.
                         */
                        data.Seek(1, SeekOrigin.Current);
                        data = new InflaterInputStream(
                            data, new Inflater(true));
                        break;
                    }

                    case ERF.CompressionScheme.HeaderlessZlib:
                    {
                        data = new InflaterInputStream(
                            data, new Inflater(true));
                        break;
                    }

                    case ERF.CompressionScheme.None:
                    {
                        //data = data;
                        break;
                    }

                    default:
                    {
                        throw new NotSupportedException("unsupported compression scheme");
                    }
                    }

                    long left = entry.UncompressedSize;
                    while (left > 0)
                    {
                        int block = (int)(Math.Min(left, buffer.Length));
                        int read  = data.Read(buffer, 0, block);
                        output.Write(buffer, 0, read);
                        left -= read;
                    }
                }
            }

            this.SaveDone();
        }