示例#1
0
    private void CopyEntryDataDirect(ZipUpdate update, Stream stream, bool updateCrc, ref long destinationPosition,
                                     ref long sourcePosition)
    {
      var bytesToCopy = update.Entry.CompressedSize;

      // NOTE: Compressed size is updated elsewhere.
      var crc = new Crc32();
      var buffer = GetBuffer();

      var targetBytes = bytesToCopy;
      long totalBytesRead = 0;

      int bytesRead;
      do
      {
        var readSize = buffer.Length;

        if (bytesToCopy < readSize)
        {
          readSize = (int) bytesToCopy;
        }

        stream.Position = sourcePosition;
        bytesRead = stream.Read(buffer, 0, readSize);
        if (bytesRead > 0)
        {
          if (updateCrc)
          {
            crc.Update(buffer, 0, bytesRead);
          }
          stream.Position = destinationPosition;
          stream.Write(buffer, 0, bytesRead);

          destinationPosition += bytesRead;
          sourcePosition += bytesRead;
          bytesToCopy -= bytesRead;
          totalBytesRead += bytesRead;
        }
      }
      while ((bytesRead > 0) && (bytesToCopy > 0));

      if (totalBytesRead != targetBytes)
      {
        throw new ZipException(string.Format("Failed to copy bytes expected {0} read {1}", targetBytes, totalBytesRead));
      }

      if (updateCrc)
      {
        update.OutEntry.Crc = crc.Value;
      }
    }
示例#2
0
    /// <summary>
    ///   Upgrades the installed files log entries.
    /// </summary>
    /// <remarks>
    ///   This analyses the mods and determines, as best as possible, who owns which files, and attempts
    ///   to reconstruct the install order. It populates the overwrites folder with the files that, as far
    ///   as can be determined, belong there. This resulting information is then put in the new install log.
    /// </remarks>
    /// <param name="p_xmlModInstallLog">The current mod install log we are parsing to upgrade.</param>
    /// <param name="p_strModInstallLogPath">The path to the current mod install log.</param>
    /// <param name="p_strModBaseName">The base name of the mod whose install log is being parsed.</param>
    private void UpgradeInstalledFiles(XmlDocument p_xmlModInstallLog, fomod p_fomodMod, string p_strModBaseName)
    {
      var intDataPathStartPos =
        Program.GameMode.PluginsPath.Trim(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar).Length + 1;
      var xnlFiles = p_xmlModInstallLog.SelectNodes("descendant::installedFiles/*");
      foreach (XmlNode xndFile in xnlFiles)
      {
        var strFile = xndFile.InnerText;
        if (!File.Exists(strFile))
        {
          continue;
        }
        var strDataRelativePath = strFile.Substring(intDataPathStartPos);

        var crcDiskFile = new Crc32();
        var crcFomodFile = new Crc32();
        crcDiskFile.Update(File.ReadAllBytes(strFile));
        if (!p_fomodMod.ContainsFile(strDataRelativePath))
        {
          //we don't know if this mod owns the file, so let's assume
          // it doesn't
          //put this mod's file into the overwrites directory.
          // we can't get the original file from the fomod,
          // so we'll use the existing file instead. this isn't
          // strictly correct, but it is inline with the behaviour
          // of the fomm version we are upgrading from
          var strDirectory = Path.GetDirectoryName(strDataRelativePath);
          var strBackupPath = Path.Combine(Program.GameMode.OverwriteDirectory, strDirectory);
          var strModKey = InstallLog.Current.GetModKey(p_strModBaseName);
          if (!Directory.Exists(strBackupPath))
          {
            FileManager.CreateDirectory(strBackupPath);
          }
          strBackupPath = Path.Combine(strBackupPath, strModKey + "_" + Path.GetFileName(strDataRelativePath));
          FileManager.Copy(Path.Combine(Program.GameMode.PluginsPath, strDataRelativePath), strBackupPath, true);
          InstallLog.Current.PrependDataFile(p_strModBaseName, strDataRelativePath);

          //however, it may own the file, so let's make it the default owner for now
          // unless we already know who the owner is
          if (!FileOwnerIsKnown(strDataRelativePath))
          {
            m_dicDefaultFileOwners[strDataRelativePath] = p_strModBaseName;
          }
          continue;
        }
        var bteFomodFile = p_fomodMod.GetFileContents(strDataRelativePath);
        crcFomodFile.Update(bteFomodFile);
        if (!crcDiskFile.Value.Equals(crcFomodFile.Value) || FileOwnerIsKnown(strDataRelativePath))
        {
          //either:
          // 1) another mod owns the file
          // 2) according to the crc we own this file, however we have already found
          //    an owner. this could happen beacue two mods use the same version
          //    of a file, or there is a crc collision.
          //either way, put this mod's file into
          // the overwrites directory
          var strDirectory = Path.GetDirectoryName(strDataRelativePath);
          var strBackupPath = Path.Combine(Program.GameMode.OverwriteDirectory, strDirectory);
          var strModKey = InstallLog.Current.GetModKey(p_strModBaseName);
          if (!Directory.Exists(strBackupPath))
          {
            FileManager.CreateDirectory(strBackupPath);
          }
          strBackupPath = Path.Combine(strBackupPath, strModKey + "_" + Path.GetFileName(strDataRelativePath));
          FileManager.WriteAllBytes(strBackupPath, bteFomodFile);
          InstallLog.Current.PrependDataFile(p_strModBaseName, strDataRelativePath);
        }
        else
        {
          //this mod owns the file, so append it to the list of installing mods
          InstallLog.Current.AddDataFile(p_strModBaseName, strDataRelativePath);

          //we also have to displace the mod that is currently the default owner
          if (m_dicDefaultFileOwners.ContainsKey(strDataRelativePath))
          {
            m_dicDefaultFileOwners.Remove(strDataRelativePath);
          }
        }

        if (ProgressWorker.Cancelled())
        {
          return;
        }
        ProgressWorker.StepItemProgress();
      }
    }
示例#3
0
    private void CopyBytes(ZipUpdate update, Stream destination, Stream source,
                           long bytesToCopy, bool updateCrc)
    {
      if (destination == source)
      {
        throw new InvalidOperationException("Destination and source are the same");
      }

      // NOTE: Compressed size is updated elsewhere.
      var crc = new Crc32();
      var buffer = GetBuffer();

      var targetBytes = bytesToCopy;
      long totalBytesRead = 0;

      int bytesRead;
      do
      {
        var readSize = buffer.Length;

        if (bytesToCopy < readSize)
        {
          readSize = (int) bytesToCopy;
        }

        bytesRead = source.Read(buffer, 0, readSize);
        if (bytesRead > 0)
        {
          if (updateCrc)
          {
            crc.Update(buffer, 0, bytesRead);
          }
          destination.Write(buffer, 0, bytesRead);
          bytesToCopy -= bytesRead;
          totalBytesRead += bytesRead;
        }
      }
      while ((bytesRead > 0) && (bytesToCopy > 0));

      if (totalBytesRead != targetBytes)
      {
        throw new ZipException(string.Format("Failed to copy bytes expected {0} read {1}", targetBytes, totalBytesRead));
      }

      if (updateCrc)
      {
        update.OutEntry.Crc = crc.Value;
      }
    }
示例#4
0
    private static bool ReplaceShader(string file, string shader, byte[] newdata, out byte[] OldData, uint crc)
    {
      var tempshader = Path.Combine(Program.tmpPath, "tempshader");

      var timeStamp = File.GetLastWriteTime(file);
      File.Delete(tempshader);
      File.Move(file, tempshader);
      var br = new BinaryReader(File.OpenRead(tempshader), Encoding.Default);
      var bw = new BinaryWriter(File.Create(file), Encoding.Default);
      bw.Write(br.ReadInt32());
      var num = br.ReadInt32();
      bw.Write(num);
      var sizeoffset = br.BaseStream.Position;
      bw.Write(br.ReadInt32());
      var found = false;
      OldData = null;
      for (var i = 0; i < num; i++)
      {
        var name = br.ReadChars(0x100);
        var size = br.ReadInt32();
        var data = br.ReadBytes(size);

        bw.Write(name);
        var sname = "";
        for (var i2 = 0; i2 < 100; i2++)
        {
          if (name[i2] == '\0')
          {
            break;
          }
          sname += name[i2];
        }
        if (!found && sname == shader)
        {
          var ccrc = new Crc32();
          ccrc.Update(data);
          if (crc == 0 || ccrc.Value == crc)
          {
            bw.Write(newdata.Length);
            bw.Write(newdata);
            found = true;
            OldData = data;
          }
          else
          {
            bw.Write(size);
            bw.Write(data);
          }
        }
        else
        {
          bw.Write(size);
          bw.Write(data);
        }
      }
      bw.BaseStream.Position = sizeoffset;
      bw.Write((int) (bw.BaseStream.Length - 12));
      br.Close();
      bw.Close();
      File.Delete(tempshader);
      File.SetLastWriteTime(file, timeStamp);
      return found;
    }