From a6c5b4d6e81d1c5d2012388e69a906b7287599b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=8D=9A=7ENex?= <87421482+NexIsDumb@users.noreply.github.com> Date: Tue, 18 Jun 2024 00:04:26 +0200 Subject: [PATCH] fixin some stuff about file attribs Co-Authored-By: Ne_Eo --- source/funkin/backend/utils/CoolUtil.hx | 35 ++- .../backend/utils/FileAttributeWrapper.hx | 292 ++++++++++++++++++ source/funkin/backend/utils/NativeAPI.hx | 30 +- 3 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 source/funkin/backend/utils/FileAttributeWrapper.hx diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx index 9448b05a8..979662e04 100644 --- a/source/funkin/backend/utils/CoolUtil.hx +++ b/source/funkin/backend/utils/CoolUtil.hx @@ -100,7 +100,7 @@ class CoolUtil /** * Sets an attribute to a file or a folder adding eventual missing folders in the path - * (WARNING: Only works on `windows`. On other platforms the return code it's always going to be `0` but still creates eventual missing folders if the platforms allows it to). + * (WARNING: Only works on `windows` for now. On other platforms the return code it's always going to be `0` but still creates eventual missing folders if the platforms allows it to). * @param path Path to the file or folder * @param attrib The attribute to set (WARNING: There are some non settable attributes, such as the `COMPRESSED` one) * @param useAbsol If it should use the absolute path (By default it's `true` but if it's `false` you can use files outside from this program's directory for example) @@ -114,6 +114,39 @@ class CoolUtil return result; } + /** + * Sets file attributes to a file or a folder adding eventual missing folders in the path + * (WARNING: Only works on `windows` for now. On other platforms the return code it's always going to be `0` but still creates eventual missing folders if the platforms allows it to). + * @param path Path to the file or folder + * @param attrib The attribute to set (WARNING: There are some non settable attributes, such as the `COMPRESSED` one) + * @param useAbsol If it should use the absolute path (By default it's `true` but if it's `false` you can use files outside from this program's directory for example) + * @return The result code: 0 means that it failed setting + */ + @:noUsing public static inline function safeSetAttributes(path:String, attrib:OneOfTwo, useAbsol:Bool = true) { + addMissingFolders(Path.directory(path)); + + var result = NativeAPI.setFileAttributes(path, attrib, useAbsol); + if(result == 0) Logs.trace('Failed to set attributes to $path with a code of: $result', WARNING); + return result; + } + + /** + * Gets the attributes of a file or a folder adding eventual missing folders in the path + * (WARNING: Only works on `windows` for now. On other platforms the return code it's always going to be `0` but still creates eventual missing folders if the platforms allows it to). + * @param path Path to the file or folder + * @param useAbsol If it should use the absolute path (By default it's `true` but if it's `false` you can use files outside from this program's directory for example) + * @return The result code: 0 means that it failed setting + */ + // uncomment if it crashes when using it normall + /*@:noUsing public static inline function safeGetAttribute(path:String, useAbsol:Bool = true) { + addMissingFolders(Path.directory(path)); + + var result = NativeAPI.getFileAttribute(path, useAbsol); + if(result == 0) Logs.trace('Failed to get attribute to $path with a code of: $result', WARNING); + return result; + }*/ + + /** * Creates eventual missing folders to the specified `path` * diff --git a/source/funkin/backend/utils/FileAttributeWrapper.hx b/source/funkin/backend/utils/FileAttributeWrapper.hx new file mode 100644 index 000000000..0b5262230 --- /dev/null +++ b/source/funkin/backend/utils/FileAttributeWrapper.hx @@ -0,0 +1,292 @@ +package funkin.backend.utils; + +import funkin.backend.utils.NativeAPI.FileAttribute; + +/** + * Currently only for Windows, but planned to work on other platforms later. + */ +class FileAttributeWrapper +{ + public var flags:Int; + + public function new(flags:Int) + { + this.flags = flags; + } + + public var isArchived(get, set):Bool; + + private function get_isArchived():Bool + { + #if windows + return (flags & FileAttribute.ARCHIVE) != 0; + #else + return false; + #end + } + + private function set_isArchived(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.ARCHIVE; + else + flags &= ~FileAttribute.ARCHIVE; + return value; + #else + return false; + #end + } + + public var isHidden(get, set):Bool; + + private function get_isHidden():Bool + { + #if windows + return (flags & FileAttribute.HIDDEN) != 0; + #else + return false; + #end + } + + private function set_isHidden(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.HIDDEN; + else + flags &= ~FileAttribute.HIDDEN; + return value; + #else + return false; + #end + } + + public var isNormal(get, set):Bool; + + private function get_isNormal():Bool + { + #if windows + return (flags & FileAttribute.NORMAL) != 0; + #else + return false; + #end + } + + private function set_isNormal(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.NORMAL; + else + flags &= ~FileAttribute.NORMAL; + return value; + #else + return false; + #end + } + + public var isNotContentIndexed(get, set):Bool; + + private function get_isNotContentIndexed():Bool + { + #if windows + return (flags & FileAttribute.NOT_CONTENT_INDEXED) != 0; + #else + return false; + #end + } + + private function set_isNotContentIndexed(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.NOT_CONTENT_INDEXED; + else + flags &= ~FileAttribute.NOT_CONTENT_INDEXED; + return value; + #else + return false; + #end + } + + public var isOffline(get, set):Bool; + + private function get_isOffline():Bool + { + #if windows + return (flags & FileAttribute.OFFLINE) != 0; + #else + return false; + #end + } + + private function set_isOffline(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.OFFLINE; + else + flags &= ~FileAttribute.OFFLINE; + return value; + #else + return false; + #end + } + + public var isReadOnly(get, set):Bool; + + private function get_isReadOnly():Bool + { + #if windows + return (flags & FileAttribute.READONLY) != 0; + #else + return false; + #end + } + + private function set_isReadOnly(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.READONLY; + else + flags &= ~FileAttribute.READONLY; + return value; + #else + return false; + #end + } + + public var isSystem(get, set):Bool; + + private function get_isSystem():Bool + { + #if windows + return (flags & FileAttribute.SYSTEM) != 0; + #else + return false; + #end + } + + private function set_isSystem(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.SYSTEM; + else + flags &= ~FileAttribute.SYSTEM; + return value; + #else + return false; + #end + } + + public var isTemporary(get, set):Bool; + + private function get_isTemporary():Bool + { + #if windows + return (flags & FileAttribute.TEMPORARY) != 0; + #else + return false; + #end + } + + private function set_isTemporary(value:Bool):Bool + { + #if windows + if (value) + flags |= FileAttribute.TEMPORARY; + else + flags &= ~FileAttribute.TEMPORARY; + return value; + #else + return false; + #end + } + + // Non Settables + public var isCompressed(get, never):Bool; + + private function get_isCompressed():Bool + { + #if windows + return (flags & FileAttribute.COMPRESSED) != 0; + #else + return false; + #end + } + + public var isDevice(get, never):Bool; + + private function get_isDevice():Bool + { + #if windows + return (flags & FileAttribute.DEVICE) != 0; + #else + return false; + #end + } + + public var isDirectory(get, never):Bool; + + private function get_isDirectory():Bool + { + #if windows + return (flags & FileAttribute.DIRECTORY) != 0; + #else + return false; + #end + } + + public var isEncrypted(get, never):Bool; + + private function get_isEncrypted():Bool + { + #if windows + return (flags & FileAttribute.ENCRYPTED) != 0; + #else + return false; + #end + } + + public var isReparsePoint(get, never):Bool; + + private function get_isReparsePoint():Bool + { + #if windows + return (flags & FileAttribute.REPARSE_POINT) != 0; + #else + return false; + #end + } + + public var isSparseFile(get, never):Bool; + + private function get_isSparseFile():Bool + { + #if windows + return (flags & FileAttribute.SPARSE_FILE) != 0; + #else + return false; + #end + } + + // For checking (mainly) + public var isNothing(get, never):Bool; + + private function get_isNothing():Bool + { + #if windows + return (flags & FileAttribute.NOTHING) == 0; + #else + return false; + #end + } + + public function getValue():Int + { + return flags; + } +} diff --git a/source/funkin/backend/utils/NativeAPI.hx b/source/funkin/backend/utils/NativeAPI.hx index 495403dcb..d7bd60303 100644 --- a/source/funkin/backend/utils/NativeAPI.hx +++ b/source/funkin/backend/utils/NativeAPI.hx @@ -1,6 +1,7 @@ package funkin.backend.utils; import funkin.backend.utils.native.*; +import flixel.util.typeLimit.OneOfTwo; /** * Class for functions that talk to a lower level than haxe, such as message boxes, and more. @@ -32,7 +33,7 @@ class NativeAPI { /** * Gets the specified file's (or folder) attribute. */ - public static function getFileAttribute(path:String, useAbsol:Bool = true):FileAttribute { + public static function getFileAttributeRaw(path:String, useAbsol:Bool = true):Int { #if windows if(useAbsol) path = sys.FileSystem.absolutePath(path); return Windows.getFileAttribute(path); @@ -41,6 +42,13 @@ class NativeAPI { #end } + /** + * Gets the specified file's (or folder) attribute. + */ + public static function getFileAttribute(path:String, useAbsol:Bool = true):FileAttributeWrapper { + return new FileAttributeWrapper(getFileAttributeRaw(path, useAbsol)); + } + /** * Sets the specified file's (or folder) attribute. If it fails, the return value is `0`. */ @@ -53,6 +61,21 @@ class NativeAPI { #end } + /** + * Sets the specified file's (or folder) attribute. If it fails, the return value is `0`. + */ + public static function setFileAttributes(path:String, attrib:OneOfTwo, useAbsol:Bool = true):Int { + #if windows + if(useAbsol) path = sys.FileSystem.absolutePath(path); + if(attrib is FileAttributeWrapper) + return Windows.setFileAttribute(path, cast(attrib, FileAttributeWrapper).flags); + else + return Windows.setFileAttribute(path, cast(attrib, Int)); + #else + return 0; + #end + } + public static function setDarkMode(title:String, enable:Bool) { #if windows Windows.setDarkMode(title, enable); @@ -137,7 +160,7 @@ class NativeAPI { } } -enum abstract FileAttribute(Int) { +enum abstract FileAttribute(Int) from Int to Int { // Settables var ARCHIVE = 0x20; var HIDDEN = 0x2; @@ -155,6 +178,9 @@ enum abstract FileAttribute(Int) { var ENCRYPTED = 0x4000; var REPARSE_POINT = 0x400; var SPARSE_FILE = 0x200; + + // For checking (mainly) + var NOTHING = -1; } enum abstract ConsoleColor(Int) {