Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Assets/Editor/Tests/LocalMetaDataTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void CreateMetaDataFile()

var localMetaData = new LocalMetaData(_filePath, _deprecatedFilePath);

localMetaData.RegisterEntry("test", 1);
localMetaData.RegisterEntry("test", 1, 0, true);

Assert.True(File.Exists(_filePath));
}
Expand All @@ -41,8 +41,8 @@ public void SaveValidFileSinglePass()
{
var localMetaData = new LocalMetaData(_filePath, _deprecatedFilePath);

localMetaData.RegisterEntry("a", 1);
localMetaData.RegisterEntry("b", 2);
localMetaData.RegisterEntry("a", 1, 0 , true);
localMetaData.RegisterEntry("b", 2, 0 , true);

var localMetaData2 = new LocalMetaData(_filePath, _deprecatedFilePath);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ public interface ILocalMetaData
/// </summary>
/// <param name="entryName">Name of the entry.</param>
/// <param name="versionId">The version id.</param>
void RegisterEntry(string entryName, int versionId);
/// <param name="entrySize">Size of entry.</param>
/// <param name="isLastEntry">If set to true, it is last entry.</param>
void RegisterEntry(string entryName, int versionId, long entrySize, bool isLastEntry);

/// <summary>
/// Unregisters the entry.
Expand Down
35 changes: 30 additions & 5 deletions Assets/PatchKit Patcher/Scripts/AppData/Local/LocalMetaData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ namespace PatchKit.Unity.Patcher.AppData.Local
public class LocalMetaData : ILocalMetaData
{
private readonly ILogger _logger;
private long _unsavedEntriesSize = 0;
private const string DeprecatedCachePatchKitKey = "patchkit-key";
private const long UnsavedEntriesSizeLimit = 104857600; //100MiB

/// <summary>
/// Data structure stored in file.
Expand Down Expand Up @@ -79,7 +81,7 @@ public string[] GetRegisteredEntries()
return _data.FileVersionIds.Select(pair => pair.Key).ToArray();
}

public void RegisterEntry([NotNull] string entryName, int versionId)
public void RegisterEntry([NotNull] string entryName, int versionId, long entrySize, bool isLastEntry)
{
if (entryName == null)
{
Expand All @@ -103,7 +105,10 @@ public void RegisterEntry([NotNull] string entryName, int versionId)

_data.FileVersionIds[entryName] = versionId;

SaveData();
if (ShouldSaveEntry(entrySize, isLastEntry))
{
SaveData();
}

_logger.LogDebug("Entry registered.");
}
Expand All @@ -114,6 +119,22 @@ public void RegisterEntry([NotNull] string entryName, int versionId)
}
}

private bool ShouldSaveEntry(long entrySize, bool isLastEntry)
{
if (isLastEntry)
{
return true;
}

_unsavedEntriesSize += entrySize;
if (_unsavedEntriesSize > UnsavedEntriesSizeLimit)
{
_unsavedEntriesSize = 0;
return true;
}
return false;
}

public void UnregisterEntry([NotNull] string entryName)
{
if (entryName == null)
Expand Down Expand Up @@ -183,10 +204,14 @@ public string GetProductKey()

public void SetMainExecutableAndArgs(string mainExecutable, string mainExecutableArgs)
{
_data.MainExecutable = mainExecutable;
_data.MainExecutableArgs = mainExecutableArgs;
if (_data.MainExecutable != mainExecutable ||
_data.MainExecutableArgs != mainExecutableArgs)
{
_data.MainExecutable = mainExecutable;
_data.MainExecutableArgs = mainExecutableArgs;

SaveData();
SaveData();
}
}

public string GetMainExecutable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ ICheckVersionIntegrityCommand checkVersionIntegrityCommand

var contentSummary = _context.App.RemoteMetaData.GetContentSummary(installedVersionId, cancellationToken);

foreach (var invalidVersionIdFile in filesIntegrity.Where(x =>
x.Status == FileIntegrityStatus.InvalidVersion).ToArray())
var filesIntegrityWithInvalidVersion = filesIntegrity.Where(x =>
x.Status == FileIntegrityStatus.InvalidVersion).ToArray();
for (int i = 0; i < filesIntegrityWithInvalidVersion.Length; i++)
{
var fileName = invalidVersionIdFile.FileName;
var fileName = filesIntegrityWithInvalidVersion[i].FileName;
var file = contentSummary.Files.First(x => x.Path == fileName);

var localPath = _context.App.LocalDirectory.Path.PathCombine(file.Path);
Expand All @@ -96,13 +97,15 @@ ICheckVersionIntegrityCommand checkVersionIntegrityCommand
if (actualFileHash != file.Hash)
{
FileOperations.Delete(localPath, cancellationToken);
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId);
invalidVersionIdFile.Status = FileIntegrityStatus.MissingData;
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId, file.Size,
i == filesIntegrityWithInvalidVersion.Length - 1);
filesIntegrityWithInvalidVersion[i].Status = FileIntegrityStatus.MissingData;
}
else
{
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId);
invalidVersionIdFile.Status = FileIntegrityStatus.Ok;
_context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId, file.Size,
i == filesIntegrityWithInvalidVersion.Length - 1);
filesIntegrityWithInvalidVersion[i].Status = FileIntegrityStatus.Ok;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,12 @@ public override void Execute(CancellationToken cancellationToken)
for (int i = 0; i < _versionContentSummary.Files.Length; i++)
{
cancellationToken.ThrowIfCancellationRequested();

string filePath = _versionContentSummary.Files[i].Path;
string nameHash;
if (mapHashExtractedFiles.TryGetHash(filePath, out nameHash))
{
var sourceFile = new SourceFile(filePath, packageDir.Path, usedSuffix, nameHash);
var sourceFile = new SourceFile(filePath, packageDir.Path, usedSuffix, nameHash, _versionContentSummary.Size);

if (unarchiver.HasErrors && !sourceFile.Exists()) // allow unexistent file only if does not have errors
{
Expand All @@ -152,7 +153,7 @@ public override void Execute(CancellationToken cancellationToken)
}
else
{
InstallFile(sourceFile, cancellationToken);
InstallFile(sourceFile, cancellationToken, i == _versionContentSummary.Files.Length - 1);
}
}
else
Expand Down Expand Up @@ -185,7 +186,7 @@ private IUnarchiver CreateUnrachiver(string destinationDir, MapHashExtractedFile
}
}

private void InstallFile(SourceFile sourceFile, CancellationToken cancellationToken)
private void InstallFile(SourceFile sourceFile, CancellationToken cancellationToken, bool isLastEntry)
{
DebugLogger.Log(string.Format("Installing file {0}", sourceFile.Name));

Expand All @@ -202,33 +203,36 @@ private void InstallFile(SourceFile sourceFile, CancellationToken cancellationTo
DebugLogger.LogFormat("Destination file {0} already exists, removing it.", destinationFilePath);
FileOperations.Delete(destinationFilePath, cancellationToken);
}

#if UNITY_STANDALONE_WIN
if (destinationFilePath.Length > 259)
{
throw new FilePathTooLongException(string.Format("Cannot install file {0}, the destination path length has exceeded Windows path length limit (260).", destinationFilePath));
}
#endif
FileOperations.Move(sourceFile.FullHashPath, destinationFilePath, cancellationToken);
_localMetaData.RegisterEntry(sourceFile.Name, _versionId);
_localMetaData.RegisterEntry(sourceFile.Name, _versionId, sourceFile.Size, isLastEntry);
}

struct SourceFile
{
public string Name { get; private set; }
public long Size { get; private set; }
public string HashName { get; private set; }
private string _suffix;
private string _root;

public string FullHashPath { get { return Path.Combine(_root, HashName + _suffix); } }

public SourceFile(string name, string root, string suffix, string hashName)
public SourceFile(string name, string root, string suffix, string hashName, long size)
{
Assert.IsNotNull(name);
Assert.IsNotNull(root);
Assert.IsNotNull(suffix);
Assert.IsNotNull(hashName);

Name = name;
Size = size;
_root = root;
_suffix = suffix;
HashName = hashName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ private void ProcessAddedFiles(string packageDirPath, string suffix,
}
else
{
AddFile(entryName, packageDirPath, suffix, cancellationToken);
AddFile(entryName, packageDirPath, suffix, cancellationToken, i);
}

_addFilesStatusReporter.Progress.Value = (i + 1) / (double) _diffSummary.AddedFiles.Length;
Expand All @@ -459,7 +459,8 @@ private void AddDirectory(string dirName, CancellationToken cancellationToken)
_logger.LogDebug("Add directory entry processed.");
}

private void AddFile(string fileName, string packageDirPath, string suffix, CancellationToken cancellationToken)
private void AddFile(string fileName, string packageDirPath, string suffix, CancellationToken cancellationToken,
int fileIndex)
{
_logger.LogDebug(string.Format("Processing add file entry {0}", fileName));

Expand All @@ -482,7 +483,7 @@ private void AddFile(string fileName, string packageDirPath, string suffix, Canc
throw new MissingFileFromPackageException(string.Format("Cannot find file {0} in diff package.",
fileName));
}

_logger.LogDebug("Creating file parent directories in local data...");
var fileParentDirPath = Path.GetDirectoryName(filePath);
_logger.LogTrace("fileParentDirPath = " + fileParentDirPath);
Expand All @@ -495,7 +496,9 @@ private void AddFile(string fileName, string packageDirPath, string suffix, Canc
FileOperations.Copy(sourceFilePath, filePath, true, cancellationToken);
_logger.LogDebug("File copied to local data.");

_localMetaData.RegisterEntry(fileName, _versionId);
_localMetaData.RegisterEntry(fileName, _versionId,
_contentSummary.Files.First(x => x.Path == fileName).Size,
fileIndex == _diffSummary.AddedFiles.Length - 1);

_logger.LogDebug("Add file entry processed.");
}
Expand All @@ -521,7 +524,7 @@ private void ProcessModifiedFiles(string packageDirPath, string suffix, Temporar

if (!entryName.EndsWith("/"))
{
PatchFile(entryName, packageDirPath, suffix, tempDiffDir, cancellationToken);
PatchFile(entryName, packageDirPath, suffix, tempDiffDir, cancellationToken, i);
}

_modifiedFilesStatusReporter.Progress.Value = (i + 1) / (double) _diffSummary.ModifiedFiles.Length;
Expand All @@ -537,7 +540,7 @@ private void ProcessModifiedFiles(string packageDirPath, string suffix, Temporar

private void PatchFile(
string fileName, string packageDirPath, string suffix,
TemporaryDirectory tempDiffDir, CancellationToken cancellationToken)
TemporaryDirectory tempDiffDir, CancellationToken cancellationToken, int fileIndex)
{
_logger.LogDebug(string.Format("Processing patch file entry {0}", fileName));

Expand Down Expand Up @@ -592,8 +595,10 @@ private void PatchFile(
{
_logger.LogDebug("Patching is not necessary. File content is the same as in previous version.");
}

_localMetaData.RegisterEntry(fileName, _versionId);

_localMetaData.RegisterEntry(fileName, _versionId,
_contentSummary.Files.First(x => x.Path == fileName).Size,
fileIndex == _diffSummary.ModifiedFiles.Length - 1);

_logger.LogDebug("Patch file entry processed.");
}
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Checking path length on Windows
- Support for HDPI

### Changed
- Speed up the installation/patching process due to less frequent meta data saving

### Fixed
- Paths too long when unpacking (#2156)

Expand Down