/// <summary>
        /// Merges two archives into a single archive.
        /// </summary>
        public static void Merge(string ar, string merge)
        {
            GensArchive arc    = new GensArchive();
            GensArchive tmpArc = new GensArchive();
            string      arl    = Paths.ReplaceFilename(ar, $"{Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(ar))}.arl");

            CreateBackup(ar);
            Decompress.DecompressBySystem(ar);
            Decompress.DecompressBySystem(arl);
            CreateBackup(arl);

            foreach (string split in arc.GetSplitArchivesList(ar))
            {
                CreateBackup(split);
                Decompress.DecompressBySystem(split);
            }

            foreach (string split in arc.GetSplitArchivesList(ar))
            {
                arc.Load(split);
            }

            tmpArc.Load(merge);

            foreach (var entry in tmpArc.Data)
            {
                arc.Data.Remove(arc.Data.Find(x => x.Name.Equals(entry.Name)));
                arc.Data.Add(entry);
            }

            arc.Save(ar, true, 99999999);
        }
Exemplo n.º 2
0
        // Methods
        /// <summary>
        /// Packs a PFD and generates a PFI.
        /// </summary>
        /// <param name="input">The directory to pack into a PFD</param>
        /// <param name="output">The directory to output PFD and PFI files.
        /// Auto-detected if none is given.</param>
        /// <param name="pfdPadding">How much padding the generated PFD should have.</param>
        public static void PackPFD(string input, string output = null,
                                   uint pfdPadding             = 2048)
        {
            // Get output Directory
            var info = new DirectoryInfo(input);

            if (string.IsNullOrEmpty(output))
            {
                output = info.Parent.FullName;
            }

            Directory.CreateDirectory(output);

            // Pack PFD
            var    pfd     = new GensArchive();
            string pfdPath = Path.Combine(output,
                                          info.Name + GensArchive.PFDExtension);

            pfd.Padding = pfdPadding;
            pfd.AddDirectory(input);
            pfd.Save(pfdPath, overwrite: true);

            // Generate PFI
            var    pfi     = new GensPFI(pfd);
            string pfiPath = Path.Combine(output,
                                          info.Name + Extension);

            pfi.Save(pfiPath, true);
        }
Exemplo n.º 3
0
        public GensPFI(GensArchive pfd)
        {
            // Generate a PFI from a PFD archive
            var  files  = pfd.GetFiles(false);
            uint offset = 0x10;

            for (int i = 0; i < files.Count; ++i)
            {
                var file = files[i];
                offset += (GensArchive.MinFileEntrySize + (uint)file.Name.Length);

                while (offset % pfd.Padding != 0)
                {
                    ++offset;
                }

                uint dataLen = (uint)file.Data.LongLength;
                Entries.Add(new AREntry()
                {
                    Name      = file.Name,
                    PFDOffset = offset,
                    Size      = dataLen
                });

                offset += dataLen;
            }
        }
Exemplo n.º 4
0
        public static void Repack(string path, string inDir, string hashID = null,
                                  bool includeSubDirs = false, bool generateList = false,
                                  uint?splitCount     = 0xA00000)
        {
            // Figure out what type of archive to use
            Archive arc = null;

            switch (Types.CurrentDataType)
            {
            case Types.DataTypes.Forces:
                arc = new ForcesArchive();
                break;

            // TODO: Add LW Support
            case Types.DataTypes.LW:
                throw new NotImplementedException(
                          "Could not repack, LW archives are not yet supported!");

            case Types.DataTypes.Gens:
            case Types.DataTypes.SU:
                arc = new GensArchive();
                break;

            case Types.DataTypes.Storybook:
                arc = new SBArchive();
                break;

            // TODO: Add Colors Support
            case Types.DataTypes.Colors:
                throw new NotImplementedException(
                          "Could not repack, Colors archives are not yet supported!");

            // TODO: Add 06 Support
            case Types.DataTypes.S06:
                throw new NotImplementedException(
                          "Could not repack, '06 archives are not yet supported!");

            case Types.DataTypes.Shadow:
            case Types.DataTypes.Heroes:
                arc = new ONEArchive();
                break;

            // TODO: Add SA2 Support
            case Types.DataTypes.SA2:
                throw new NotImplementedException(
                          "Could not repack, SA2 archives are not yet supported!");

            default:
                throw new Exception(
                          "Could not repack, game type has not been set!");
            }

            // Generate the archive
            arc.AddDirectory(inDir, includeSubDirs);

            if (arc is GensArchive gensArc)
            {
                gensArc.Save(path, generateList, splitCount);
            }
            else if (arc is ForcesArchive forcesArc)
            {
                forcesArc.Save(path, splitCount);
            }
            else
            {
                arc.Save(path, true);
            }

            // Hashes
            if (!string.IsNullOrEmpty(hashID) && Stage.EditorCache != null)
            {
                // Get splits list
                var arcSplits = new List <string>();
                try
                {
                    var arcFileList = arc.GetSplitArchivesList(path);
                    arcSplits.AddRange(arcFileList);
                }
                catch
                {
                    arcSplits.Add(path);
                }

                // Get new hashes
                for (int i = 0; i < arcSplits.Count; ++i)
                {
                    arcSplits[i] = Helpers.GetFileHash(arcSplits[i]);
                }

                // Update editor cache hashes
                if (Stage.EditorCache.ArcHashes.ContainsKey(hashID))
                {
                    Stage.EditorCache.ArcHashes[hashID] = arcSplits;
                }
                else
                {
                    Stage.EditorCache.ArcHashes.Add(hashID, arcSplits);
                }
            }

            LuaTerminal.Log((string.IsNullOrEmpty(hashID)) ?
                            "Successfully repacked!" :
                            $"Successfully repacked \"{hashID}\"!");
        }
Exemplo n.º 5
0
        // Methods
        public static void Extract(string path, string outDir, string hashID = null)
        {
            // Figure out what type of archive to use
            Archive arc = null;

            switch (Types.CurrentDataType)
            {
            case Types.DataTypes.Forces:
                arc = new ForcesArchive();
                break;

            // TODO: Add LW Support
            case Types.DataTypes.LW:
                throw new NotImplementedException(
                          "Could not unpack, LW archives are not yet supported!");

            case Types.DataTypes.Gens:
            case Types.DataTypes.SU:
                arc = new GensArchive();
                break;

            case Types.DataTypes.Storybook:
                arc = new SBArchive();
                break;

            // TODO: Add Colors Support
            case Types.DataTypes.Colors:
                throw new NotImplementedException(
                          "Could not unpack, Colors archives are not yet supported!");

            case Types.DataTypes.S06:
                arc = new S06Archive();
                break;

            case Types.DataTypes.Shadow:
            case Types.DataTypes.Heroes:
                arc = new ONEArchive();
                break;

            // TODO: Add SA2 Support
            case Types.DataTypes.SA2:
                throw new NotImplementedException(
                          "Could not unpack, SA2 archives are not yet supported!");

            default:
                throw new Exception(
                          "Could not unpack, game type has not been set!");
            }

            // Hashes
            bool hashesMatch = false;

            if (!string.IsNullOrEmpty(hashID) && Stage.EditorCache != null)
            {
                var editorCache = Stage.EditorCache;

                // Get splits list
                var arcSplits = new List <string>();
                hashesMatch = true;

                try
                {
                    var arcFileList = arc.GetSplitArchivesList(path);
                    arcSplits.AddRange(arcFileList);
                }
                catch
                {
                    arcSplits.Add(path);
                }

                // Check hashes
                var splitHashes      = new List <string>();
                var splitCacheHashes = (editorCache.ArcHashes.ContainsKey(
                                            hashID)) ? editorCache.ArcHashes[hashID] : null;

                if (splitCacheHashes != null &&
                    splitCacheHashes.Count != arcSplits.Count)
                {
                    hashesMatch = false;
                }

                for (int i = 0; i < arcSplits.Count; ++i)
                {
                    string file    = arcSplits[i];
                    string arcHash = Helpers.GetFileHash(file);
                    splitHashes.Add(arcHash);

                    if (hashesMatch && (splitCacheHashes == null ||
                                        splitCacheHashes[i] != arcHash))
                    {
                        hashesMatch = false;
                    }
                }

                // Update editor cache hashes
                if (splitCacheHashes == null)
                {
                    Stage.EditorCache.ArcHashes.Add(
                        hashID, splitHashes);
                }
                else if (!hashesMatch)
                {
                    Stage.EditorCache.ArcHashes[
                        hashID] = splitHashes;
                }

                if (hashesMatch)
                {
                    LuaTerminal.LogWarning(string.Format(
                                               "{0} \"{1}\", as it hasn't changed since it was last unpacked.",
                                               "WARNING: Skipped", hashID));
                }
                else
                {
                    LuaTerminal.Log($"Extracting \"{hashID}\"...");
                }
            }

            // Extract the archive
            if (!hashesMatch)
            {
                if (Directory.Exists(outDir))
                {
                    Directory.Delete(outDir, true);
                }

                arc.Load(path);
                arc.Extract(outDir);

                LuaTerminal.Log((string.IsNullOrEmpty(hashID)) ?
                                "Successfully unpacked!" :
                                $"Successfully unpacked \"{hashID}\"!");
            }
        }
Exemplo n.º 6
0
        public static Archive LoadArchive(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            Archive  arc      = null;

            // Checks if the file even exist.
            if (!File.Exists(fileInfo.FullName))
            {
                throw new FileNotFoundException("The given archive does not exist.");
            }

            // Checks if the file is not empty.
            if (fileInfo.Length == 0)
            {
                throw new Exception("The given file is empty.");
            }

            // Addons
            foreach (var addon in Addon.Addons)
            {
                foreach (var archive in addon.Archives)
                {
                    if (archive.FileExtensions.Contains(fileInfo.Extension))
                    {
                        arc = Activator.CreateInstance(archive.ArchiveType) as Archive;
                        arc.Load(filePath);
                        return(arc);
                    }
                }
            }

            // TODO: Add support for other types of archive.
            if (fileInfo.Extension == GensArchive.Extension ||
                fileInfo.Extension == GensArchive.SplitExtension ||
                fileInfo.Extension == GensArchive.PFDExtension ||
                fileInfo.Extension == GensArchive.ListExtension)
            {
                arc = new GensArchive();
            }
            else if (fileInfo.Extension == ForcesArchive.Extension)
            {
                arc = new ForcesArchive();
            }
            else if (fileInfo.Extension == ONEArchive.Extension)
            {
                // I know This is a horrible way of checking between archives.
                if (File.ReadAllBytes(fileInfo.FullName)[3] == 0x00)
                {
                    arc = new ONEArchive();
                }
                else
                {
                    arc = new SBArchive();
                }
            }
            else
            {
                throw new Exception("The given archive has an unknown extension.");
            }

            arc.Load(filePath);
            return(arc);
        }