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))