Compares hashes before marking game saves as updated

This commit is contained in:
Riley Testut 2019-03-26 00:55:52 -07:00
parent bf2752496a
commit 3ecee031be
3 changed files with 72 additions and 13 deletions

View File

@ -152,6 +152,7 @@
BFFA4C091E8A24D600D87934 /* GameTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA4C081E8A24D600D87934 /* GameTableViewCell.swift */; };
BFFA71DD1AAC406100EE9DD1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */; };
BFFA71E21AAC406100EE9DD1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFFA71E01AAC406100EE9DD1 /* Main.storyboard */; };
BFFBD3D9224A0756002EFC79 /* URL+ExtendedAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFBD3D8224A0756002EFC79 /* URL+ExtendedAttributes.swift */; };
BFFC461E1D59823500AF2CC6 /* GamesPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC461B1D59823500AF2CC6 /* GamesPresentationController.swift */; };
BFFC461F1D59823500AF2CC6 /* GamesStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC461C1D59823500AF2CC6 /* GamesStoryboardSegue.swift */; };
BFFC46201D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFC461D1D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift */; };
@ -319,6 +320,7 @@
BFFA71DB1AAC406100EE9DD1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BFFA71DC1AAC406100EE9DD1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
BFFA71E11AAC406100EE9DD1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
BFFBD3D8224A0756002EFC79 /* URL+ExtendedAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+ExtendedAttributes.swift"; sourceTree = "<group>"; };
BFFC461B1D59823500AF2CC6 /* GamesPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesPresentationController.swift; sourceTree = "<group>"; };
BFFC461C1D59823500AF2CC6 /* GamesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GamesStoryboardSegue.swift; sourceTree = "<group>"; };
BFFC461D1D59823500AF2CC6 /* InitialGamesStoryboardSegue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitialGamesStoryboardSegue.swift; sourceTree = "<group>"; };
@ -370,6 +372,7 @@
BF6424841F5CBDC900D6AB44 /* UIView+ParentViewController.swift */,
BFC3627F21ADE2BA00EF2BE6 /* UIAlertController+Error.swift */,
BF1F45AC21AF57BA00EF9895 /* HarmonyMetadataKey+Keys.swift */,
BFFBD3D8224A0756002EFC79 /* URL+ExtendedAttributes.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -1073,6 +1076,7 @@
BF4828861F9028F500028B97 /* System.swift in Sources */,
BF13A7561D5D29B0000BB055 /* PreviewGameViewController.swift in Sources */,
BF6866171DCAC8B900BF2D06 /* ControllerSkin+Configuring.swift in Sources */,
BFFBD3D9224A0756002EFC79 /* URL+ExtendedAttributes.swift in Sources */,
BF713C0822499ED4004A1A2B /* PreviousHarmony.xcdatamodeld in Sources */,
BF59427D1E09BC830051894B /* ControllerSkin.swift in Sources */,
BFAB9F7D219A43380080EC7D /* SyncManager.swift in Sources */,

View File

@ -527,22 +527,32 @@ private extension GameViewController
guard let game = self.game as? Game else { return }
DatabaseManager.shared.performBackgroundTask { (context) in
let game = context.object(with: game.objectID) as! Game
if let gameSave = game.gameSave
{
gameSave.modifiedDate = Date()
}
else
{
let gameSave = GameSave(context: context)
gameSave.identifier = game.identifier
game.gameSave = gameSave
}
do
{
let game = context.object(with: game.objectID) as! Game
let hash = try RSTHasher.sha1HashOfFile(at: game.gameSaveURL)
let previousHash = game.gameSaveURL.extendedAttribute(name: "com.rileytestut.delta.sha1Hash")
guard hash != previousHash else { return }
if let gameSave = game.gameSave
{
gameSave.modifiedDate = Date()
}
else
{
let gameSave = GameSave(context: context)
gameSave.identifier = game.identifier
game.gameSave = gameSave
}
try context.save()
try game.gameSaveURL.setExtendedAttribute(name: "com.rileytestut.delta.sha1Hash", value: hash)
}
catch CocoaError.fileNoSuchFile
{
// Ignore
}
catch
{

View File

@ -0,0 +1,45 @@
//
// URL+ExtendedAttributes.swift
// Delta
//
// Created by Riley Testut on 3/26/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import Foundation
extension URL
{
func setExtendedAttribute(name: String, value: String) throws
{
try self.withUnsafeFileSystemRepresentation { (path) in
let data = value.data(using: .utf8)
let result = data?.withUnsafeBytes { (buffer) in
setxattr(path, name, buffer.baseAddress, buffer.count, 0, 0)
}
if let result = result, result < 0
{
throw POSIXError(POSIXErrorCode(rawValue: errno) ?? .ENOENT)
}
}
}
func extendedAttribute(name: String) -> String?
{
let value = self.withUnsafeFileSystemRepresentation { (path) -> String? in
let size = getxattr(path, name, nil, 0, 0, 0)
guard size >= 0 else { return nil }
var data = Data(count: size)
let result = data.withUnsafeMutableBytes { getxattr(path, name, $0.baseAddress, $0.count, 0, 0) }
guard result >= 0 else { return nil }
let value = String(data: data, encoding: .utf8)!
return value
}
return value
}
}