From 9f74a5aaa321fec09b56ca286003bd5518889acd Mon Sep 17 00:00:00 2001 From: Nuclearist Date: Wed, 24 Jan 2024 09:57:49 +0300 Subject: [PATCH] Switched to Enum.HasFlag; Made AppManager.WriteNewData() apply file flags --- protos/manifest/payload.proto | 1 - src/AppManager.cs | 25 ++++++++++++++++++++----- src/Manifest/DepotManifest.cs | 12 ++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/protos/manifest/payload.proto b/protos/manifest/payload.proto index 8ea1379..384a6d9 100644 --- a/protos/manifest/payload.proto +++ b/protos/manifest/payload.proto @@ -9,7 +9,6 @@ message Payload { enum FileFlag { - NONE = 0; READONLY = 8; HIDDEN = 16; EXECUTABLE = 32; diff --git a/src/AppManager.cs b/src/AppManager.cs index 5a8fdee..07ea6c1 100644 --- a/src/AppManager.cs +++ b/src/AppManager.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; using TEKSteamClient.CM; using TEKSteamClient.Manifest; @@ -48,7 +49,7 @@ public AppManager(uint appId, string installationPath, [Optional]string? worksho if (!Directory.Exists(WorkshopContentPath)) Directory.CreateDirectory(WorkshopContentPath); var attributes = File.GetAttributes(_scDataPath); - if ((attributes & FileAttributes.ReadOnly) is not FileAttributes.None) + if (attributes.HasFlag(FileAttributes.ReadOnly)) File.SetAttributes(_scDataPath, attributes & ~FileAttributes.ReadOnly); } /// Path to SCData directory. @@ -117,7 +118,7 @@ void processDir(in DirectoryEntry dir, in DirectoryEntry.AuxiliaryEntry auxiliar var file = dir.Files[auxiliaryFile.Index]; string filePath = Path.Combine(path, file.Name); var attributes = File.GetAttributes(filePath); - if ((attributes & FileAttributes.ReadOnly) is not FileAttributes.None) + if (attributes.HasFlag(FileAttributes.ReadOnly)) File.SetAttributes(filePath, attributes & ~FileAttributes.ReadOnly); using var fileHandle = File.OpenHandle(filePath, access: FileAccess.ReadWrite, options: FileOptions.RandomAccess); long fileSize = RandomAccess.GetLength(fileHandle); @@ -395,7 +396,6 @@ static long countTotalDirSize(in DirectoryEntry dir) foreach (var subdir in dir.Subdirectories) result += countTotalDirSize(in subdir); return result; - } if (acquisitionDir.IsNew) { @@ -423,7 +423,22 @@ static long countTotalDirSize(in DirectoryEntry dir) var file = dir.Files[acquisitonFile.Index]; if (acquisitonFile.Chunks.Count is 0) { - File.Move(Path.Combine(downloadPath, file.Name), Path.Combine(localPath, file.Name), true); + string destinationFile = Path.Combine(localPath, file.Name); + if (File.Exists(destinationFile)) + File.Delete(destinationFile); + File.Move(Path.Combine(downloadPath, file.Name), destinationFile); + if (file.Flags is not 0) + { + var attributes = (FileAttributes)0; + if (file.Flags.HasFlag(FileEntry.Flag.ReadOnly)) + attributes = FileAttributes.ReadOnly; + if (file.Flags.HasFlag(FileEntry.Flag.Hidden)) + attributes |= FileAttributes.Hidden; + if (attributes is not 0) + File.SetAttributes(destinationFile, attributes); + if (file.Flags.HasFlag(FileEntry.Flag.Executable) && !OperatingSystem.IsWindows()) + File.SetUnixFileMode(destinationFile, File.GetUnixFileMode(destinationFile) | UnixFileMode.UserExecute | UnixFileMode.GroupExecute | UnixFileMode.OtherExecute); + } state.DisplayProgress += file.Size; ProgressUpdated?.Invoke(state.DisplayProgress); } @@ -440,7 +455,7 @@ static long countTotalDirSize(in DirectoryEntry dir) } string filePath = Path.Combine(localPath, file.Name); var attributes = File.GetAttributes(filePath); - if ((attributes & FileAttributes.ReadOnly) is not FileAttributes.None) + if (attributes.HasFlag(FileAttributes.ReadOnly)) File.SetAttributes(filePath, attributes & ~FileAttributes.ReadOnly); using var fileHandle = File.OpenHandle(filePath, access: FileAccess.Write, options: FileOptions.RandomAccess); for (; chunkIndex < acquisitonFile.Chunks.Count; chunkIndex++) diff --git a/src/Manifest/DepotManifest.cs b/src/Manifest/DepotManifest.cs index 6dfcd04..368cec8 100644 --- a/src/Manifest/DepotManifest.cs +++ b/src/Manifest/DepotManifest.cs @@ -71,7 +71,7 @@ internal DepotManifest(byte[] compressedData, ItemIdentifier item) foreach (var file in files) { _nameBufferSize += Encoding.UTF8.GetByteCount(Path.GetFileName(file.Name)); - if ((file.Flags & FileFlag.Directory) is not 0) + if (file.Flags.HasFlag(FileFlag.Directory)) numDirs++; else { @@ -111,7 +111,7 @@ void loadDirectory(int index, int payloadEntryIndex) int numSepChars = file.Name.AsSpan().Count(Path.DirectorySeparatorChar); if (numSepChars - dirNumSepChars is not 1 || numSepChars > 0 && file.Name[path.Length] != Path.DirectorySeparatorChar) continue; - if ((file.Flags & FileFlag.Directory) is not 0) + if (file.Flags.HasFlag(FileFlag.Directory)) { dirOffset++; continue; @@ -129,11 +129,11 @@ void loadDirectory(int index, int payloadEntryIndex) }; new Span(ChunkBuffer, chunkStartOffset, numChunks).Sort(); FileEntry.Flag flags = 0; - if ((file.Flags & FileFlag.Readonly) is not FileFlag.None) + if (file.Flags.HasFlag(FileFlag.Readonly)) flags = FileEntry.Flag.ReadOnly; - if ((file.Flags & FileFlag.Hidden) is not FileFlag.None) + if (file.Flags.HasFlag(FileFlag.Hidden)) flags |= FileEntry.Flag.Hidden; - if ((file.Flags & FileFlag.Executable) is not FileFlag.None) + if (file.Flags.HasFlag(FileFlag.Executable)) flags |= FileEntry.Flag.Executable; FileBuffer[fileOffset++] = new() { @@ -149,7 +149,7 @@ void loadDirectory(int index, int payloadEntryIndex) for (int i = startIndex; i < endIndex; i++) { var file = files[i]; - if ((file.Flags & FileFlag.Directory) is not 0) + if (file.Flags.HasFlag(FileFlag.Directory)) { int numSepChars = file.Name.AsSpan().Count(Path.DirectorySeparatorChar); if (numSepChars - dirNumSepChars is 1 && (numSepChars < 1 || file.Name[path.Length] == Path.DirectorySeparatorChar))