From 6715e2b1ccec52ef82be92362a90e18a1b2ad7da 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 04:54:59 +0200 Subject: [PATCH] even cooler stuff for file attributes --- source/funkin/backend/system/MainState.hx | 2 +- source/funkin/backend/utils/CoolUtil.hx | 50 ++++++++++------ .../backend/utils/FileAttributeWrapper.hx | 57 ++++++++----------- source/funkin/backend/utils/NativeAPI.hx | 45 ++++++++------- source/funkin/backend/utils/native/Windows.hx | 4 +- 5 files changed, 85 insertions(+), 73 deletions(-) diff --git a/source/funkin/backend/system/MainState.hx b/source/funkin/backend/system/MainState.hx index d7238eece..14c40aff8 100644 --- a/source/funkin/backend/system/MainState.hx +++ b/source/funkin/backend/system/MainState.hx @@ -66,6 +66,6 @@ class MainState extends FlxState { betaWarningShown = true; } - CoolUtil.safeSetAttribute('./.temp/', HIDDEN); + CoolUtil.safeAddAttributes('./.temp/', NativeAPI.FileAttribute.HIDDEN); } } \ No newline at end of file diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx index 979662e04..63a910b1c 100644 --- a/source/funkin/backend/utils/CoolUtil.hx +++ b/source/funkin/backend/utils/CoolUtil.hx @@ -6,6 +6,7 @@ import sys.FileSystem; import flixel.text.FlxText; import funkin.backend.utils.XMLUtil.TextFormat; import flixel.util.typeLimit.OneOfTwo; +import flixel.util.typeLimit.OneOfThree; import flixel.tweens.FlxTween; import flixel.system.frontEnds.SoundFrontEnd; import flixel.sound.FlxSound; @@ -99,18 +100,17 @@ class CoolUtil } /** - * Sets an attribute 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). + * Gets file attributes from a file or a folder adding eventual missing folders in the path + * (WARNING: Only works on `windows` for now. On other platforms the attributes' value it's always going to be `0` -thanks to the wrapper you can also use `isNothing` for checking- 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 + * @return The attributes through the `FileAttributeWrapper` */ - @:noUsing public static inline function safeSetAttribute(path:String, attrib:NativeAPI.FileAttribute, useAbsol:Bool = true) { + @:noUsing public static inline function safeGetAttributes(path:String, useAbsol:Bool = true):FileAttributeWrapper { addMissingFolders(Path.directory(path)); - var result = NativeAPI.setFileAttribute(path, attrib, useAbsol); - if(result == 0) Logs.trace('Failed to set attribute to $path with a code of: $result', WARNING); + var result = NativeAPI.getFileAttributes(path, useAbsol); + if(result.isNothing) Logs.trace('The file where it has been tried to get the attributes from, might be corrupted or inexistent (code: ${result.getValue()})', WARNING); return result; } @@ -118,11 +118,12 @@ class CoolUtil * 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 attrib The attribute(s) 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 + * @return The result code: `0` means that it failed setting */ - @:noUsing public static inline function safeSetAttributes(path:String, attrib:OneOfTwo, useAbsol:Bool = true) { + @:noUsing public static inline function safeSetAttributes(path:String, attrib:OneOfThree, useAbsol:Bool = true):Int { + // yes, i'm aware that FileAttribute is also an Int so need to include it too, but at least like this we don't have to make cast sometimes while passing the arguments - Nex addMissingFolders(Path.directory(path)); var result = NativeAPI.setFileAttributes(path, attrib, useAbsol); @@ -131,21 +132,36 @@ class CoolUtil } /** - * Gets the attributes of a file or a folder adding eventual missing folders in the path + * Adds one (or more) 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(s) to add (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 + * @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) { + @:noUsing public static inline function safeAddAttributes(path:String, attrib:OneOfTwo, useAbsol:Bool = true):Int { 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); + var result = NativeAPI.addFileAttributes(path, attrib, useAbsol); + if(result == 0) Logs.trace('Failed to add attributes to $path with a code of: $result', WARNING); return result; - }*/ + } + /** + * Removes one (or more) 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(s) to remove (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 safeRemoveAttributes(path:String, attrib:OneOfTwo, useAbsol:Bool = true):Int { + addMissingFolders(Path.directory(path)); + + var result = NativeAPI.removeFileAttributes(path, attrib, useAbsol); + if(result == 0) Logs.trace('Failed to remove attributes 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 index 0b5262230..7d7e26f4b 100644 --- a/source/funkin/backend/utils/FileAttributeWrapper.hx +++ b/source/funkin/backend/utils/FileAttributeWrapper.hx @@ -1,5 +1,6 @@ package funkin.backend.utils; +import flixel.util.FlxStringUtil; import funkin.backend.utils.NativeAPI.FileAttribute; /** @@ -7,15 +8,32 @@ import funkin.backend.utils.NativeAPI.FileAttribute; */ class FileAttributeWrapper { - public var flags:Int; + private var flags:Int; + inline public function getValue():Int + { + return flags; + } public function new(flags:Int) { - this.flags = flags; + this.flags = flags == -1 ? 0 : flags; } - public var isArchived(get, set):Bool; + /** + * Returns a string representation of the attributes. + */ + inline public function toString():String + { + return FlxStringUtil.getDebugString([ + for (field in Reflect.fields(this)) + { + LabelValuePair.weak(field, Reflect.getProperty(this, field)); + } + ]); + } + // Settables + public var isArchived(get, set):Bool; private function get_isArchived():Bool { #if windows @@ -24,7 +42,6 @@ class FileAttributeWrapper return false; #end } - private function set_isArchived(value:Bool):Bool { #if windows @@ -39,7 +56,6 @@ class FileAttributeWrapper } public var isHidden(get, set):Bool; - private function get_isHidden():Bool { #if windows @@ -48,7 +64,6 @@ class FileAttributeWrapper return false; #end } - private function set_isHidden(value:Bool):Bool { #if windows @@ -63,7 +78,6 @@ class FileAttributeWrapper } public var isNormal(get, set):Bool; - private function get_isNormal():Bool { #if windows @@ -72,7 +86,6 @@ class FileAttributeWrapper return false; #end } - private function set_isNormal(value:Bool):Bool { #if windows @@ -87,7 +100,6 @@ class FileAttributeWrapper } public var isNotContentIndexed(get, set):Bool; - private function get_isNotContentIndexed():Bool { #if windows @@ -96,7 +108,6 @@ class FileAttributeWrapper return false; #end } - private function set_isNotContentIndexed(value:Bool):Bool { #if windows @@ -111,7 +122,6 @@ class FileAttributeWrapper } public var isOffline(get, set):Bool; - private function get_isOffline():Bool { #if windows @@ -120,7 +130,6 @@ class FileAttributeWrapper return false; #end } - private function set_isOffline(value:Bool):Bool { #if windows @@ -135,7 +144,6 @@ class FileAttributeWrapper } public var isReadOnly(get, set):Bool; - private function get_isReadOnly():Bool { #if windows @@ -144,7 +152,6 @@ class FileAttributeWrapper return false; #end } - private function set_isReadOnly(value:Bool):Bool { #if windows @@ -159,7 +166,6 @@ class FileAttributeWrapper } public var isSystem(get, set):Bool; - private function get_isSystem():Bool { #if windows @@ -168,7 +174,6 @@ class FileAttributeWrapper return false; #end } - private function set_isSystem(value:Bool):Bool { #if windows @@ -183,7 +188,6 @@ class FileAttributeWrapper } public var isTemporary(get, set):Bool; - private function get_isTemporary():Bool { #if windows @@ -192,7 +196,6 @@ class FileAttributeWrapper return false; #end } - private function set_isTemporary(value:Bool):Bool { #if windows @@ -208,7 +211,6 @@ class FileAttributeWrapper // Non Settables public var isCompressed(get, never):Bool; - private function get_isCompressed():Bool { #if windows @@ -219,7 +221,6 @@ class FileAttributeWrapper } public var isDevice(get, never):Bool; - private function get_isDevice():Bool { #if windows @@ -230,7 +231,6 @@ class FileAttributeWrapper } public var isDirectory(get, never):Bool; - private function get_isDirectory():Bool { #if windows @@ -241,7 +241,6 @@ class FileAttributeWrapper } public var isEncrypted(get, never):Bool; - private function get_isEncrypted():Bool { #if windows @@ -252,7 +251,6 @@ class FileAttributeWrapper } public var isReparsePoint(get, never):Bool; - private function get_isReparsePoint():Bool { #if windows @@ -263,7 +261,6 @@ class FileAttributeWrapper } public var isSparseFile(get, never):Bool; - private function get_isSparseFile():Bool { #if windows @@ -273,20 +270,14 @@ class FileAttributeWrapper #end } - // For checking (mainly) + // For checking public var isNothing(get, never):Bool; - private function get_isNothing():Bool { #if windows - return (flags & FileAttribute.NOTHING) == 0; + return flags == 0; #else - return false; + return true; #end } - - public function getValue():Int - { - return flags; - } } diff --git a/source/funkin/backend/utils/NativeAPI.hx b/source/funkin/backend/utils/NativeAPI.hx index d7bd60303..78f0b38de 100644 --- a/source/funkin/backend/utils/NativeAPI.hx +++ b/source/funkin/backend/utils/NativeAPI.hx @@ -2,6 +2,7 @@ package funkin.backend.utils; import funkin.backend.utils.native.*; import flixel.util.typeLimit.OneOfTwo; +import flixel.util.typeLimit.OneOfThree; /** * Class for functions that talk to a lower level than haxe, such as message boxes, and more. @@ -31,46 +32,53 @@ class NativeAPI { } /** - * Gets the specified file's (or folder) attribute. + * Gets the specified file's (or folder) attributes. */ - public static function getFileAttributeRaw(path:String, useAbsol:Bool = true):Int { + public static function getFileAttributesRaw(path:String, useAbsol:Bool = true):Int { #if windows if(useAbsol) path = sys.FileSystem.absolutePath(path); - return Windows.getFileAttribute(path); + return Windows.getFileAttributes(path); #else - return NORMAL; + return -1; #end } /** - * Gets the specified file's (or folder) attribute. + * Gets the specified file's (or folder) attributes and passes it to `FileAttributeWrapper`. */ - public static function getFileAttribute(path:String, useAbsol:Bool = true):FileAttributeWrapper { - return new FileAttributeWrapper(getFileAttributeRaw(path, useAbsol)); + public static function getFileAttributes(path:String, useAbsol:Bool = true):FileAttributeWrapper { + return new FileAttributeWrapper(getFileAttributesRaw(path, useAbsol)); } /** - * Sets the specified file's (or folder) attribute. If it fails, the return value is `0`. + * Sets the specified file's (or folder) attributes. If it fails, the return value is `0`. */ - public static function setFileAttribute(path:String, attrib:FileAttribute, useAbsol:Bool = true):Int { + public static function setFileAttributes(path:String, attrib:OneOfThree, useAbsol:Bool = true):Int { #if windows if(useAbsol) path = sys.FileSystem.absolutePath(path); - return Windows.setFileAttribute(path, attrib); + return Windows.setFileAttributes(path, attrib is FileAttributeWrapper ? cast(attrib, FileAttributeWrapper).getValue() : cast(attrib, Int)); #else return 0; #end } /** - * Sets the specified file's (or folder) attribute. If it fails, the return value is `0`. + * Removes from the specified file's (or folder) one (or more) specific attribute. */ - public static function setFileAttributes(path:String, attrib:OneOfTwo, useAbsol:Bool = true):Int { + public static function addFileAttributes(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)); + return setFileAttributes(path, getFileAttributesRaw(path, useAbsol) | cast(attrib, Int), useAbsol); + #else + return 0; + #end + } + + /** + * Removes from the specified file's (or folder) one (or more) specific attribute. + */ + public static function removeFileAttributes(path:String, attrib:OneOfTwo, useAbsol:Bool = true):Int { + #if windows + return setFileAttributes(path, getFileAttributesRaw(path, useAbsol) & ~cast(attrib, Int), useAbsol); #else return 0; #end @@ -178,9 +186,6 @@ enum abstract FileAttribute(Int) from Int to Int { var ENCRYPTED = 0x4000; var REPARSE_POINT = 0x400; var SPARSE_FILE = 0x200; - - // For checking (mainly) - var NOTHING = -1; } enum abstract ConsoleColor(Int) { diff --git a/source/funkin/backend/utils/native/Windows.hx b/source/funkin/backend/utils/native/Windows.hx index 5b03b9042..a536c75f8 100644 --- a/source/funkin/backend/utils/native/Windows.hx +++ b/source/funkin/backend/utils/native/Windows.hx @@ -157,7 +157,7 @@ class Windows { @:functionCode(' return GetFileAttributes(path); ') - public static function getFileAttribute(path:String):FileAttribute + public static function getFileAttributes(path:String):FileAttribute { return NORMAL; } @@ -165,7 +165,7 @@ class Windows { @:functionCode(' return SetFileAttributes(path, attrib); ') - public static function setFileAttribute(path:String, attrib:FileAttribute):Int + public static function setFileAttributes(path:String, attrib:FileAttribute):Int { return 0; }