예제 #1
0
파일: IrosArc.cs 프로젝트: professorlust/7h
 public static void Create(IrosArc original, IrosArc updated, System.IO.Stream patchOutput, CompressType compress, Action<double, string> onProgress) {
     string[] deleted = original.AllFileNames()
         .Except(updated.AllFileNames(), StringComparer.InvariantCultureIgnoreCase)
         .ToArray();
     List<IrosArc.ArchiveCreateEntry> pentries = new List<IrosArc.ArchiveCreateEntry>();
     if (deleted.Any()) {
         onProgress(0, "Adding deleted entries");
         byte[] deldata = System.Text.Encoding.Unicode.GetBytes(String.Join("\n", deleted));
         pentries.Add(new IrosArc.ArchiveCreateEntry() {
             Filename = "%IrosPatch:Deleted",
             GetData = () => deldata
         });
     }
     foreach (string newFile in updated.AllFileNames().Except(original.AllFileNames(), StringComparer.InvariantCultureIgnoreCase)) {
         onProgress(0, "Adding new entries");
         string fn = newFile;
         pentries.Add(new IrosArc.ArchiveCreateEntry() {
             Filename = fn,
             GetData = () => updated.GetBytes(fn)
         });
     }
     foreach (string check in original.AllFileNames().Intersect(updated.AllFileNames())) {
         onProgress(0, "Checking " + check);
         if (!Same(original.GetBytes(check), updated.GetBytes(check))) {
             string fn = check;
             pentries.Add(new IrosArc.ArchiveCreateEntry() {
                 Filename = fn,
                 GetData = () => updated.GetBytes(fn)
             });
         }
     }
     IrosArc.Create(patchOutput, pentries, ArchiveFlags.Patch, compress, onProgress);
 }
예제 #2
0
 private IEnumerable <string> GetDlls(IEnumerable <string> dlls, bool loadaside)
 {
     if (_archive == null)
     {
         return(dlls.Select(s => System.IO.Path.Combine(BaseFolder, s)));
     }
     else
     {
         string appPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
         string libpath = System.IO.Path.Combine(appPath, "7thWorkshop", "LoadLibTemp");
         System.IO.Directory.CreateDirectory(libpath);
         List <string> saved = new List <string>();
         if (loadaside)
         {
             foreach (string path in dlls.Select(s => System.IO.Path.GetDirectoryName(s)).Distinct(StringComparer.InvariantCultureIgnoreCase))
             {
                 foreach (string dll in _archive
                          .AllFileNames()
                          .Where(s => System.IO.Path.GetDirectoryName(s).Equals(path, StringComparison.InvariantCultureIgnoreCase))
                          .Where(s => s.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase))
                          )
                 {
                     string loc = System.IO.Path.Combine(libpath, dll);
                     WriteIfNecessary(loc, _archive.GetBytes(dll));
                     if (dlls.Contains(dll, StringComparer.InvariantCultureIgnoreCase))
                     {
                         saved.Add(loc);
                     }
                 }
             }
         }
         else
         {
             foreach (string LL in dlls)
             {
                 string path = System.IO.Path.Combine(libpath, LL);
                 WriteIfNecessary(path, _archive.GetBytes(LL));
                 saved.Add(path);
             }
         }
         return(saved);
     }
 }
예제 #3
0
파일: IrosArc.cs 프로젝트: rodriada000/7h
        public void ApplyPatch(IrosArc patch, Action <double, string> onProgress)
        {
            int currentDirSize = _entries.Sum(e => e.GetSize());

            byte[] deldata = patch.GetBytes("%IrosPatch:Deleted");
            if (deldata != null)
            {
                string[] delfile = System.Text.Encoding.Unicode.GetString(deldata).Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string del in delfile)
                {
                    RuntimeLog.Write("Removing file {0} from archive", del);
                    _entries.RemoveAll(e => e.Filename.Equals(del, StringComparison.InvariantCultureIgnoreCase));
                }
                onProgress(0, "Removed " + delfile.Length + " deleted files");
            }
            int count = 0;
            var files = patch.AllFileNames().Where(s => !s.StartsWith("%")).ToArray();

            foreach (string file in files)
            {
                var    patchEntry = patch._lookup[file];
                byte[] data       = new byte[patchEntry.Length];
                patch._data.Position = patchEntry.Offset;
                patch._data.Read(data, 0, data.Length);
                if (HasFile(file))   //update existing
                {
                    RuntimeLog.Write("File {0} is already in archive...", file);
                    DirectoryEntry exist = _lookup[file];
                    if (exist.Length >= data.Length)   //put data in same position, woo
                    {
                        RuntimeLog.Write("...updating in place");
                        _data.Position = exist.Offset;
                    }
                    else     //stick at end of file
                    {
                        _data.Position = _data.Length;
                        exist.Offset   = _data.Position;
                        RuntimeLog.Write("...size increase: writing to end of file");
                    }
                    _data.Write(data, 0, data.Length);
                    exist.Length = data.Length;
                    exist.Flags  = patchEntry.Flags;
                }
                else     //new file, just append
                {
                    RuntimeLog.Write("File {0} is new, appending", file);
                    DirectoryEntry de = new DirectoryEntry()
                    {
                        Filename = file,
                        Flags    = patchEntry.Flags,
                        Length   = patchEntry.Length,
                        Offset   = _data.Length
                    };
                    _data.Position = de.Offset;
                    _data.Write(data, 0, data.Length);
                    _entries.Add(de);
                    _lookup[file] = de;
                }

                count++;
                onProgress(1.0 * count / files.Length, "Processed " + file);
            }
            int newDirSize = _entries.Sum(e => e.GetSize());

            if (newDirSize <= currentDirSize)
            {
                RuntimeLog.Write("Directory will fit in existing location");
                _data.Position = _header.Directory;
            }
            else
            {
                RuntimeLog.Write("Directory size increase, appending");
                if (_data.Length >= int.MaxValue)   //write forwarder
                {
                    _data.Position = _header.Directory;
                    _data.WriteInt(-1);
                    _data.WriteLong(_data.Length);
                    _data.Position = _data.Length;
                }
                else     //write direct location
                {
                    _header.Directory = (int)_data.Length;
                    _data.Position    = _header.Directory;
                }
            }
            _data.WriteInt(_entries.Count);
            foreach (var e in _entries)
            {
                e.Save(_data);
            }
            _header.Version = MAX_VERSION;
            _data.Position  = 0;
            _header.Save(_data);
            onProgress(1.0, "Wrote directory");
        } //TODO: track blank spaces in file and reuse where possible...