Merge branch 'main' into translations-system
This commit is contained in:
@@ -3,6 +3,21 @@ package funkin.backend.utils;
|
||||
#if sys
|
||||
import sys.FileSystem;
|
||||
#end
|
||||
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;
|
||||
import funkin.backend.system.Conductor;
|
||||
import flixel.sound.FlxSoundGroup;
|
||||
import haxe.Json;
|
||||
import haxe.io.Path;
|
||||
import haxe.io.Bytes;
|
||||
import haxe.xml.Access;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
import lime.utils.Assets;
|
||||
import flixel.animation.FlxAnimation;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
import flixel.sound.FlxSound;
|
||||
@@ -110,18 +125,66 @@ 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).
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(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
|
||||
*/
|
||||
@:noUsing public static inline function safeSetAttributes(path:String, attrib:OneOfThree<NativeAPI.FileAttribute, FileAttributeWrapper, Int>, 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);
|
||||
if(result == 0) Logs.trace('Failed to set attributes to $path with a code of: $result', WARNING);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@:noUsing public static inline function safeAddAttributes(path:String, attrib:OneOfTwo<NativeAPI.FileAttribute, Int>, useAbsol:Bool = true):Int {
|
||||
addMissingFolders(Path.directory(path));
|
||||
|
||||
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<NativeAPI.FileAttribute, Int>, 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;
|
||||
}
|
||||
|
||||
@@ -775,6 +838,16 @@ class CoolUtil
|
||||
r.add(str);
|
||||
return r.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the filename of a path, without the extension.
|
||||
* @param path Path to get the filename from
|
||||
* @return Filename
|
||||
*/
|
||||
@:noUsing public static inline function getFilename(file:String) {
|
||||
var file = new haxe.io.Path(file);
|
||||
return file.file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
package funkin.backend.utils;
|
||||
|
||||
import flixel.util.FlxStringUtil;
|
||||
import funkin.backend.utils.NativeAPI.FileAttribute;
|
||||
|
||||
/**
|
||||
* Currently only for Windows, but planned to work on other platforms later.
|
||||
*/
|
||||
class FileAttributeWrapper
|
||||
{
|
||||
private var flags:Int;
|
||||
inline public function getValue():Int
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
public function new(flags:Int)
|
||||
{
|
||||
this.flags = flags == -1 ? 0 : flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
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
|
||||
public var isNothing(get, never):Bool;
|
||||
private function get_isNothing():Bool
|
||||
{
|
||||
#if windows
|
||||
return flags == 0;
|
||||
#else
|
||||
return true;
|
||||
#end
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
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.
|
||||
@@ -30,24 +32,53 @@ class NativeAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified file's (or folder) attribute.
|
||||
* Gets the specified file's (or folder) attributes.
|
||||
*/
|
||||
public static function getFileAttribute(path:String, useAbsol:Bool = true):FileAttribute {
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified file's (or folder) attribute. If it fails, the return value is `0`.
|
||||
* Gets the specified file's (or folder) attributes and passes it to `FileAttributeWrapper`.
|
||||
*/
|
||||
public static function setFileAttribute(path:String, attrib:FileAttribute, useAbsol:Bool = true):Int {
|
||||
public static function getFileAttributes(path:String, useAbsol:Bool = true):FileAttributeWrapper {
|
||||
return new FileAttributeWrapper(getFileAttributesRaw(path, useAbsol));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified file's (or folder) attributes. If it fails, the return value is `0`.
|
||||
*/
|
||||
public static function setFileAttributes(path:String, attrib:OneOfThree<NativeAPI.FileAttribute, FileAttributeWrapper, Int>, 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from the specified file's (or folder) one (or more) specific attribute.
|
||||
*/
|
||||
public static function addFileAttributes(path:String, attrib:OneOfTwo<NativeAPI.FileAttribute, Int>, useAbsol:Bool = true):Int {
|
||||
#if windows
|
||||
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<NativeAPI.FileAttribute, Int>, useAbsol:Bool = true):Int {
|
||||
#if windows
|
||||
return setFileAttributes(path, getFileAttributesRaw(path, useAbsol) & ~cast(attrib, Int), useAbsol);
|
||||
#else
|
||||
return 0;
|
||||
#end
|
||||
@@ -137,7 +168,7 @@ class NativeAPI {
|
||||
}
|
||||
}
|
||||
|
||||
enum abstract FileAttribute(Int) {
|
||||
enum abstract FileAttribute(Int) from Int to Int {
|
||||
// Settables
|
||||
var ARCHIVE = 0x20;
|
||||
var HIDDEN = 0x2;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user