Exemple #1
0
        /*
         * Query if p2 obsoletes p1.
         * Will return true if p1 is contained in any obsoleted file list in a pack obsoleted by p2,
         * otherwise false.
         */
        bool Obsoletes(string p1, string p2)
        {
            PFHeader p1Header = nameToHeader[p1];

            if (p1Header.ReplacedPackFileNames.Count == 0)
            {
                return(false);
            }
            bool result = p1Header.ReplacedPackFileNames.Contains(Path.GetFileName(p2));

            if (!result)
            {
                foreach (string name in p1Header.ReplacedPackFileNames)
                {
                    string otherCandidate;
                    if (nameToPath.TryGetValue(name, out otherCandidate))
                    {
                        result = Obsoletes(otherCandidate, p2);
                    }
                    if (result)
                    {
                        break;
                    }
                }
            }
            return(result);
        }
Exemple #2
0
        /*
         * Reads pack header from the given reader.
         */
        public static PFHeader ReadHeader(BinaryReader reader)
        {
            PFHeader header;
            string   packIdentifier = new string (reader.ReadChars(4));

            header = new PFHeader(packIdentifier);
            int packType = reader.ReadInt32();

            header.PrecedenceByte = (byte)packType;
            // header.Type = (PackType)packType;
            header.Version = reader.ReadInt32();
            int replacedPackFilenameLength = reader.ReadInt32();

            reader.BaseStream.Seek(0x10L, SeekOrigin.Begin);
            header.FileCount = reader.ReadUInt32();
            UInt32 indexSize = reader.ReadUInt32();

            header.DataStart = header.Length + indexSize;

            if (header.PackIdentifier == "PFH4" || header.PackIdentifier == "PFH5")
            {
                header.Unknown = reader.ReadUInt32();
            }

            // go to correct position
            reader.BaseStream.Seek(header.Length, SeekOrigin.Begin);
            for (int i = 0; i < header.Version; i++)
            {
                header.ReplacedPackFileNames.Add(IOFunctions.TheadUnsafeReadZeroTerminatedAscii(reader));
            }
            header.DataStart += replacedPackFilenameLength;
            return(header);
        }
Exemple #3
0
 /*
  * Notify pack header having been decoded.
  */
 private void OnHeaderLoaded(PFHeader header)
 {
     if (this.HeaderLoaded != null)
     {
         this.HeaderLoaded(header);
     }
 }
Exemple #4
0
        /*
         * Decode pack file at the given path.
         */
        public PackFile Open(string packFullPath)
        {
            PackFile file;
            long     sizes = 0;

            using (var reader = new BinaryReader(new FileStream(packFullPath, FileMode.Open), Encoding.ASCII)) {
                PFHeader header = ReadHeader(reader);
                file = new PackFile(packFullPath, header);
                OnHeaderLoaded(header);

                long offset = file.Header.DataStart;
                for (int i = 0; i < file.Header.FileCount; i++)
                {
                    uint size = reader.ReadUInt32();
                    sizes += size;
                    if (file.Header.HasAdditionalInfo)
                    {
                        header.AdditionalInfo = reader.ReadInt64();
                    }
                    string packedFileName = IOFunctions.ReadZeroTerminatedAscii(reader);
                    // this is easier because we can use the Path methods
                    // under both Windows and Unix
                    packedFileName = packedFileName.Replace('\\', Path.DirectorySeparatorChar);

                    PackedFile packed = new PackedFile(file.Filepath, packedFileName, offset, size);
                    file.Add(packed);
                    offset += size;
                    this.OnPackedFileLoaded(packed);
                }
            }
            this.OnFinishedLoading(file);
            file.IsModified = false;
            return(file);
        }
 /*
  * Enumerator for pack at given file path.
  */
 public PackFileEnumerator(string path)
 {
     filepath      = path;
     reader        = new BinaryReader(File.OpenRead(path));
     header        = PackFileCodec.ReadHeader(reader);
     startPosition = reader.BaseStream.Position;
     Reset();
 }
Exemple #6
0
 /*
  * Create pack file at the given path with the given header.
  */
 public PackFile(string path, PFHeader h)
 {
     header   = h;
     Filepath = path;
     Root     = new VirtualDirectory()
     {
         Name = Path.GetFileName(path)
     };
     DirAdded(Root);
 }
Exemple #7
0
 public PackLoadOrder(ICollection <string> files)
 {
     foreach (string file in files)
     {
         try {
             PFHeader header = PackFileCodec.ReadHeader(file);
             nameToHeader.Add(file, header);
             nameToPath.Add(Path.GetFileName(file), file);
         } catch { } // couldn't read header probably; just ignore the file
     }
 }
Exemple #8
0
        /*
         * Query if a pack file is provided by CA.
         */
        public static bool IsDbCaPack(string filename)
        {
            foreach (string exclude in EXCLUDE_PREFIXES)
            {
                if (Path.GetFileName(filename).StartsWith(exclude))
                {
                    return(true);
                }
            }
            bool result = false;

            try {
                PFHeader pack = PackFileCodec.ReadHeader(filename);
                result = (pack.Type != PackType.Patch) && (pack.Type != PackType.Release);
            } catch {} // not a valid pack: not a CA pack
            return(result);
        }
Exemple #9
0
        /*
         * Compare the two strings by interpreting them as pack file paths and
         * establishing the load order between those.
         */
        public override int Compare(string p1, string p2)
        {
            // sort by type
            PFHeader p1Header = nameToHeader[p1];
            PFHeader p2Header = nameToHeader[p2];
            int      index1   = p1Header.LoadOrder; // Ordered.IndexOf(p1Header.Type);
            int      index2   = p2Header.LoadOrder; // Ordered.IndexOf(p2Header.Type);
            int      result   = index2 - index1;

            // same type? Check obsoletion path
            if (result == 0)
            {
                if (Obsoletes(p1, p2))
                {
                    result = -1;
                }
                else if (Obsoletes(p2, p1))
                {
                    result = 1;
                }
            }
            return(result);
        }
Exemple #10
0
 /*
  * Create a header from the given one.
  */
 public PFHeader(PFHeader toCopy) : this(toCopy.identifier)
 {
     Type = toCopy.Type;
     ReplacedPackFileNames.AddRange(toCopy.ReplacedPackFileNames);
 }