Merge branch 'main' into translations-system

This commit is contained in:
⍚~Nex
2024-06-09 01:38:14 +02:00
32 changed files with 224 additions and 125 deletions
@@ -89,7 +89,7 @@ class ModsFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
return __getFiles(folder, false);
public function __getFiles(folder:String, folders:Bool = false) {
if (!folder.endsWith("/")) folder = folder + "/";
if (!folder.endsWith("/")) folder += "/";
if (!__parseAsset(folder)) return [];
var path = getAssetPath();
try {
+2 -2
View File
@@ -173,7 +173,7 @@ class Paths
public static function getFrames(key:String, assetsPath:Bool = false, ?library:String) {
if (tempFramesCache.exists(key)) {
var frames = tempFramesCache[key];
if (frames.parent != null && frames.parent.bitmap != null && frames.parent.bitmap.readable)
if (frames != null && frames.parent != null && frames.parent.bitmap != null && frames.parent.bitmap.readable)
return frames;
else
tempFramesCache.remove(key);
@@ -271,4 +271,4 @@ class ScriptPathInfo {
this.file = file;
this.library = library;
}
}
}
@@ -20,6 +20,8 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
public var zip:SysZip;
public var assets:Map<String, SysZipEntry> = [];
public var lowerCaseAssets:Map<String, SysZipEntry> = [];
public var nameMap:Map<String, String> = [];
public function new(basePath:String, libName:String, ?modName:String) {
this.libName = libName;
@@ -33,8 +35,10 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
zip = SysZip.openFromFile(basePath);
zip.read();
for(entry in zip.entries)
assets[entry.fileName.toLowerCase()] = entry;
for(entry in zip.entries) {
lowerCaseAssets[entry.fileName.toLowerCase()] = assets[entry.fileName.toLowerCase()] = assets[entry.fileName] = entry;
nameMap.set(entry.fileName.toLowerCase(), entry.fileName);
}
super();
}
@@ -86,6 +90,8 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
}
_parsedAsset = _parsedAsset.toLowerCase();
if(nameMap.exists(_parsedAsset))
_parsedAsset = nameMap.get(_parsedAsset);
return true;
}
@@ -105,35 +111,45 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
return '[ZIP]$basePath/$_parsedAsset';
}
// TODO: rewrite this to 1 function, like ModsFolderLibrary
public function getFiles(folder:String):Array<String> {
var content:Array<String> = [];
if (!folder.endsWith("/")) folder = folder + "/";
if (!folder.endsWith("/")) folder += "/";
if (!__parseAsset(folder)) return [];
var content:Array<String> = [];
var checkPath = _parsedAsset.toLowerCase();
@:privateAccess
for(k=>e in assets) {
if (k.toLowerCase().startsWith(_parsedAsset)) {
for(k=>e in lowerCaseAssets) {
if (k.toLowerCase().startsWith(checkPath)) {
if(nameMap.exists(k))
k = nameMap.get(k);
var fileName = k.substr(_parsedAsset.length);
if (!fileName.contains("/"))
content.push(fileName);
if (!fileName.contains("/") && fileName.length > 0)
content.pushOnce(fileName);
}
}
return content;
}
public function getFolders(folder:String):Array<String> {
var content:Array<String> = [];
if (!folder.endsWith("/")) folder = folder + "/";
if (!folder.endsWith("/")) folder += "/";
if (!__parseAsset(folder)) return [];
var content:Array<String> = [];
var checkPath = _parsedAsset.toLowerCase();
@:privateAccess
for(k=>e in assets) {
if (k.toLowerCase().startsWith(_parsedAsset)) {
for(k=>e in lowerCaseAssets) {
if (k.toLowerCase().startsWith(checkPath)) {
if(nameMap.exists(k))
k = nameMap.get(k);
var fileName = k.substr(_parsedAsset.length);
if (fileName.contains("/")) {
var s = fileName.split("/")[0];
var index = fileName.indexOf("/");
if (index != -1 && fileName.length > 0) {
var s = fileName.substr(0, index);
content.pushOnce(s);
}
}
-1
View File
@@ -56,7 +56,6 @@ class Chart {
data.setFieldDefault("name", songName);
data.setFieldDefault("beatsPerMeasure", 4);
data.setFieldDefault("stepsPerBeat", 4);
data.setFieldDefault("needsVoices", true);
data.setFieldDefault("icon", "face");
data.setFieldDefault("difficulties", []);
data.setFieldDefault("coopAllowed", false);
-1
View File
@@ -20,7 +20,6 @@ typedef ChartMetaData = {
public var ?displayName:String;
public var ?beatsPerMeasure:Float;
public var ?stepsPerBeat:Float;
public var ?needsVoices:Bool;
public var ?icon:String;
public var ?color:Dynamic;
public var ?difficulties:Array<String>;
+1 -1
View File
@@ -48,7 +48,7 @@ class EventsData {
}
],
"Alt Animation Toggle" => [{name: "Enable On Sing Poses", type: TBool, defValue: true}, {name: "Enable On Idle", type: TBool, defValue: true}, {name: "Strumline", type: TStrumLine, defValue: 0}],
"Play Animation" => [{name: "Character", type: TStrumLine, defValue: 0}, {name: "Animation", type: TString, defValue: "animation"}],
"Play Animation" => [{name: "Character", type: TStrumLine, defValue: 0}, {name: "Animation", type: TString, defValue: "animation"}, {name: "Is forced?", type: TBool, defValue: true}],
];
public static var eventsList:Array<String> = defaultEventsList.copy();
@@ -41,7 +41,6 @@ class FNFLegacyParser {
}
result.meta.bpm = data.bpm;
result.meta.needsVoices = data.needsVoices.getDefault(true);
var camFocusedBF:Bool = false;
var altAnims:Bool = false;
@@ -132,7 +131,7 @@ class FNFLegacyParser {
if ((swagSection.mustHitSection && strumLine.type == OPPONENT) ||
(!swagSection.mustHitSection && strumLine.type == PLAYER))
sectionNote[1] += 4;
swagSection.sectionNotes.push(note);
swagSection.sectionNotes.push(sectionNote);
}
}
@@ -145,7 +144,6 @@ class FNFLegacyParser {
song: chart.meta.name,
notes: null,
bpm: chart.meta.bpm,
needsVoices: chart.meta.needsVoices,
speed: chart.scrollSpeed,
player1: null,
@@ -206,7 +204,6 @@ typedef SwagSong =
var song:String;
var notes:Array<SwagSection>;
var bpm:Float;
var needsVoices:Bool;
var speed:Float;
var ?stage:String;
var ?noteTypes:Array<String>;
+7 -1
View File
@@ -64,7 +64,13 @@ class HScript extends Script {
}
private function importFailedCallback(cl:Array<String>):Bool {
var assetsPath = 'assets/source/${cl.join("/")}';
if(_importFailedCallback(cl, "") || _importFailedCallback(cl, "source/")) {
return true;
}
return false;
}
private function _importFailedCallback(cl:Array<String>, prefix:String):Bool {
var assetsPath = 'assets/$prefix${cl.join("/")}';
for(hxExt in ["hx", "hscript", "hsc", "hxs"]) {
var p = '$assetsPath.$hxExt';
if (__importedPaths.contains(p))
+7 -2
View File
@@ -428,13 +428,18 @@ class Controls extends FlxActionSet
return byName[name].check();
}
public function getKeyName(control:Control):String
{
return getDialogueName(getActionFromControl(control));
}
public function getDialogueName(action:FlxActionDigital):String
{
var input = action.inputs[0];
return switch input.device
{
case KEYBOARD: return '[${(input.inputID : FlxKey)}]';
case GAMEPAD: return '(${(input.inputID : FlxGamepadInputID)})';
case KEYBOARD: return '${(input.inputID : FlxKey)}';
case GAMEPAD: return '${(input.inputID : FlxGamepadInputID)}';
case device: throw 'unhandled device: $device';
}
}
+1 -6
View File
@@ -68,11 +68,6 @@ class MainState extends FlxState {
betaWarningShown = true;
}
#if sys
sys.FileSystem.createDirectory('./.temp/');
#if windows
try new funkin.backend.utils.native.HiddenProcess("attrib +h .temp")
catch(e) Logs.warn('Failed to set hidden attribute on .temp folder');
#end #end
CoolUtil.safeSetAttribute('./.temp/', HIDDEN);
}
}
+27 -12
View File
@@ -1,5 +1,8 @@
package funkin.backend.utils;
#if sys
import sys.FileSystem;
#end
import flixel.animation.FlxAnimation;
import flixel.input.keyboard.FlxKey;
import flixel.sound.FlxSound;
@@ -62,18 +65,15 @@ class CoolUtil
*/
@:noUsing public static function deleteFolder(delete:String) {
#if sys
if (!sys.FileSystem.exists(delete)) return;
var files:Array<String> = sys.FileSystem.readDirectory(delete);
if (!FileSystem.exists(delete)) return;
var files:Array<String> = FileSystem.readDirectory(delete);
for(file in files) {
if (sys.FileSystem.isDirectory(delete + "/" + file)) {
if (FileSystem.isDirectory(delete + "/" + file)) {
deleteFolder(delete + "/" + file);
sys.FileSystem.deleteDirectory(delete + "/" + file);
FileSystem.deleteDirectory(delete + "/" + file);
} else {
try {
sys.FileSystem.deleteFile(delete + "/" + file);
} catch(e) {
Logs.warn("Could not delete " + delete + "/" + file);
}
try FileSystem.deleteFile(delete + "/" + file)
catch(e) Logs.warn("Could not delete " + delete + "/" + file);
}
}
#end
@@ -98,6 +98,22 @@ class CoolUtil
#end
}
/**
* 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).
* @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 safeSetAttribute(path:String, attrib:NativeAPI.FileAttribute, useAbsol:Bool = true) {
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);
return result;
}
/**
* Creates eventual missing folders to the specified `path`
*
@@ -113,9 +129,8 @@ class CoolUtil
for (folder in folders) {
currentPath += folder + "/";
if (!sys.FileSystem.exists(currentPath)) {
sys.FileSystem.createDirectory(currentPath);
}
if (!FileSystem.exists(currentPath))
FileSystem.createDirectory(currentPath);
}
#end
return path;
@@ -41,7 +41,9 @@ class FunkinParentDisabler extends FlxBasic {
}
}
public override function update(elapsed:Float) {}
public override function update(elapsed:Float) {
@:privateAccess for(c in __cameras) c.updateFlashSpritePosition();
}
public override function draw() {}
public function reset() {
+45 -3
View File
@@ -29,6 +29,30 @@ class NativeAPI {
#end
}
/**
* Gets the specified file's (or folder) attribute.
*/
public static function getFileAttribute(path:String, useAbsol:Bool = true):FileAttribute {
#if windows
if(useAbsol) path = sys.FileSystem.absolutePath(path);
return Windows.getFileAttribute(path);
#else
return NORMAL;
#end
}
/**
* Sets the specified file's (or folder) attribute. If it fails, the return value is `0`.
*/
public static function setFileAttribute(path:String, attrib:FileAttribute, useAbsol:Bool = true):Int {
#if windows
if(useAbsol) path = sys.FileSystem.absolutePath(path);
return Windows.setFileAttribute(path, attrib);
#else
return 0;
#end
}
public static function setDarkMode(title:String, enable:Bool) {
#if windows
Windows.setDarkMode(title, enable);
@@ -61,15 +85,13 @@ class NativeAPI {
var fg = cast(foregroundColor, Int);
var bg = cast(backgroundColor, Int);
Windows.setConsoleColors((bg * 16) + fg);
#else
#if sys
#elseif sys
Sys.print("\x1b[0m");
if(foregroundColor != NONE)
Sys.print("\x1b[" + Std.int(consoleColorToANSI(foregroundColor)) + "m");
if(backgroundColor != NONE)
Sys.print("\x1b[" + Std.int(consoleColorToANSI(backgroundColor) + 10) + "m");
#end
#end
}
public static function consoleColorToANSI(color:ConsoleColor) {
@@ -115,6 +137,26 @@ class NativeAPI {
}
}
enum abstract FileAttribute(Int) {
// Settables
var ARCHIVE = 0x20;
var HIDDEN = 0x2;
var NORMAL = 0x80;
var NOT_CONTENT_INDEXED = 0x2000;
var OFFLINE = 0x1000;
var READONLY = 0x1;
var SYSTEM = 0x4;
var TEMPORARY = 0x100;
// Non Settables
var COMPRESSED = 0x800;
var DEVICE = 0x40;
var DIRECTORY = 0x10;
var ENCRYPTED = 0x4000;
var REPARSE_POINT = 0x400;
var SPARSE_FILE = 0x200;
}
enum abstract ConsoleColor(Int) {
var BLACK = 0;
var DARKBLUE = 1;
@@ -1,6 +1,7 @@
package funkin.backend.utils.native;
#if windows
import funkin.backend.utils.NativeAPI.FileAttribute;
import funkin.backend.utils.NativeAPI.MessageBoxIcon;
@:buildXml('
<target id="haxe">
@@ -153,6 +154,22 @@ class Windows {
public static function allocConsole() {
}
@:functionCode('
return GetFileAttributes(path);
')
public static function getFileAttribute(path:String):FileAttribute
{
return NORMAL;
}
@:functionCode('
return SetFileAttributes(path, attrib);
')
public static function setFileAttribute(path:String, attrib:FileAttribute):Int
{
return 0;
}
@:functionCode('
HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);