new assets system
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
1340
|
||||
1354
|
||||
@@ -186,7 +186,7 @@ class FreeplayState extends MusicBeatState
|
||||
curDifficulty = FlxMath.wrap(curDifficulty + change, 0, curSong.difficulties.length-1);
|
||||
|
||||
#if !switch
|
||||
intendedScore = Highscore.getScore(songs[curSelected].songName, songs[curSelected].difficulties[curDifficulty]).score;
|
||||
intendedScore = Highscore.getScore(curSong.songName, curSong.difficulties[curDifficulty]).score;
|
||||
#end
|
||||
|
||||
|
||||
|
||||
@@ -9,14 +9,18 @@ class ModdableAssetsFolder extends ModsFolderLibrary {
|
||||
public var oldLibrary:AssetLibrary;
|
||||
|
||||
public override function exists(id:String, type:String) {
|
||||
if (!id.startsWith("assets/"))
|
||||
if (!id.startsWith("assets/") && !exists('assets/$id', type))
|
||||
return oldLibrary.exists(id, type);
|
||||
return super.exists(id, type);
|
||||
}
|
||||
|
||||
public override function getAsset(id:String, type:String) {
|
||||
if (!id.startsWith("assets/"))
|
||||
if (!id.startsWith("assets/")) {
|
||||
var possibleReplacement = getAsset('assets/$id', type);
|
||||
if (possibleReplacement != null)
|
||||
return possibleReplacement;
|
||||
return oldLibrary.getAsset(id, type);
|
||||
}
|
||||
return super.getAsset(id, type);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import sys.FileSystem;
|
||||
using StringTools;
|
||||
|
||||
interface ModsAssetLibrary {
|
||||
public var prefix:String;
|
||||
|
||||
#if MOD_SUPPORT
|
||||
public var _parsedAsset:String;
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@ class ModsFolder {
|
||||
*/
|
||||
public static var currentModFolder:String = null;
|
||||
/**
|
||||
* Array of all loaded mods' folder names.
|
||||
* Map all loaded mods' folder libraries.
|
||||
*/
|
||||
public static var loadedMods:Array<String> = [];
|
||||
public static var loadedMods:Map<String, lime.utils.AssetLibrary> = [];
|
||||
/**
|
||||
* Path to the `mods` folder.
|
||||
*/
|
||||
@@ -54,15 +54,11 @@ class ModsFolder {
|
||||
#if MOD_SUPPORT
|
||||
if (mod == null) return null; // may be loading base game
|
||||
|
||||
if (FileSystem.exists('${modsPath}$mod.zip')) {
|
||||
var e = loadLibraryFromZip('mods/$mod'.toLowerCase(), '${modsPath}$mod.zip', force);
|
||||
loadedMods.push(mod);
|
||||
return e;
|
||||
} else {
|
||||
var e = loadLibraryFromFolder('mods/$mod'.toLowerCase(), '${modsPath}$mod', force);
|
||||
loadedMods.push(mod);
|
||||
return e;
|
||||
}
|
||||
if (FileSystem.exists('${modsPath}$mod.zip'))
|
||||
return loadedMods[mod] = loadLibraryFromZip('mods/$mod'.toLowerCase(), '${modsPath}$mod.zip', force);
|
||||
else
|
||||
return loadedMods[mod] = loadLibraryFromFolder('mods/$mod'.toLowerCase(), '${modsPath}$mod', force);
|
||||
|
||||
#else
|
||||
return null;
|
||||
#end
|
||||
@@ -73,16 +69,17 @@ class ModsFolder {
|
||||
* @param libName
|
||||
*/
|
||||
public static function switchMod(mod:String) {
|
||||
for(m in loadedMods)
|
||||
unloadMod(m);
|
||||
|
||||
loadMod(ModsFolder.currentModFolder = mod);
|
||||
unloadMod(ModsFolder.currentModFolder);
|
||||
Paths.assetsTree.addLibrary(loadMod(ModsFolder.currentModFolder = mod));
|
||||
|
||||
Main.refreshAssets();
|
||||
onModSwitch.dispatch(ModsFolder.currentModFolder);
|
||||
FlxG.resetState();
|
||||
}
|
||||
|
||||
public static function unloadMod(mod:String) {
|
||||
if (mod == null) return;
|
||||
Paths.assetsTree.removeLibrary(loadedMods[mod]);
|
||||
Assets.unloadLibrary('mods/$mod'.toLowerCase());
|
||||
}
|
||||
|
||||
@@ -103,64 +100,20 @@ class ModsFolder {
|
||||
return AssetLibrary.fromManifest(assets);
|
||||
}
|
||||
|
||||
public static function prepareModLibrary(libName:String, lib:ModsAssetLibrary, force:Bool = false) {
|
||||
var openLib = prepareLibrary(libName, force);
|
||||
lib.prefix = 'assets/';
|
||||
@:privateAccess
|
||||
openLib.__proxy = cast(lib, lime.utils.AssetLibrary);
|
||||
Assets.registerLibrary(libName, openLib);
|
||||
return openLib;
|
||||
}
|
||||
|
||||
public static function loadLibraryFromFolder(libName:String, folder:String, force:Bool = false) {
|
||||
return prepareModLibrary(libName, new ModsFolderLibrary(folder, libName), force);
|
||||
}
|
||||
|
||||
public static function loadLibraryFromZip(libName:String, zipPath:String, force:Bool = false) {
|
||||
var lib = prepareLibrary(libName, force);
|
||||
@:privateAccess
|
||||
lib.__proxy = new ZipFolderLibrary(zipPath, libName);
|
||||
Assets.registerLibrary(libName, lib);
|
||||
return lib;
|
||||
}
|
||||
|
||||
public static function loadLibraryFromFolder(libName:String, folder:String, force:Bool = false, useOldWhenMissing:Bool = false) {
|
||||
var oldLib = useOldWhenMissing ? Assets.getLibrary(libName) : null;
|
||||
var lib = prepareLibrary(libName, force);
|
||||
@:privateAccess
|
||||
lib.__proxy = useOldWhenMissing ? new ModdableAssetsFolder(folder, libName, oldLib) : new ModsFolderLibrary(folder, libName);
|
||||
Assets.registerLibrary(libName, lib);
|
||||
return lib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all assets in folders and put them in the `assets` array.
|
||||
* @param assets Array of assets
|
||||
* @param rootPath Root path
|
||||
* @param path Path inside of the rootPath (ex: `root path/path/path2/`)
|
||||
* @param libraryName Name of the library (ex: `mods/my mod/`)
|
||||
* @param prefix Prefix for the asset names (ex: `assets/mods/my mod/`)
|
||||
* @param addRoot Whenever the root should be added to the paths. Defaults to false
|
||||
*/
|
||||
public static function getAssetFiles(assets:Array<Dynamic>, rootPath:String, path:String, libraryName:String, prefix:String = "", addRoot:Bool = false) {
|
||||
#if sys
|
||||
for(f in FileSystem.readDirectory('$rootPath$path')) {
|
||||
if (FileSystem.isDirectory('$rootPath$path$f')) {
|
||||
// fuck you git
|
||||
if (f.toLowerCase() != ".git")
|
||||
getAssetFiles(assets, rootPath, '$path$f/', libraryName);
|
||||
} else {
|
||||
var type = "BINARY";
|
||||
var useExt:Bool = true;
|
||||
switch(Path.extension(f).toLowerCase()) {
|
||||
case "txt" | "xml" | "json" | "hx" | "hscript" | "hsc" | "lua" | "frag" | "vert":
|
||||
type = "TEXT";
|
||||
case "png":
|
||||
type = "IMAGE";
|
||||
case "ogg":
|
||||
type = path.toLowerCase().startsWith("music") ? "MUSIC" : "SOUND";
|
||||
case "ttf":
|
||||
type = "FONT";
|
||||
useExt = false;
|
||||
|
||||
}
|
||||
var stat = FileSystem.stat('$rootPath$path$f');
|
||||
assets.push({
|
||||
type: type,
|
||||
id: ('assets/$libraryName/$prefix$path${useExt ? f : Path.withoutExtension(f)}').toLowerCase(), // for case sensitive shit & correct linux support
|
||||
path: (addRoot ? rootPath : '') + '$path$f',
|
||||
size: stat.size,
|
||||
edited: stat.mtime.getTime() / 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
#end
|
||||
return prepareModLibrary(libName, new ZipFolderLibrary(zipPath, libName), force);
|
||||
}
|
||||
}
|
||||
@@ -27,10 +27,12 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
public var folderPath:String;
|
||||
public var libName:String;
|
||||
public var useImageCache:Bool = true;
|
||||
public var prefix = 'assets/';
|
||||
|
||||
public function new(folderPath:String, libName:String) {
|
||||
this.folderPath = folderPath;
|
||||
this.libName = libName;
|
||||
this.prefix = 'assets/$libName/';
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -48,10 +50,8 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
return LimeAssets.cache.audio.get('$libName:$id');
|
||||
}
|
||||
else {
|
||||
if (!exists(id, "SOUND")) {
|
||||
Log.error('ModsAssetLibrary: Audio Buffer at $id does not exist.');
|
||||
if (!exists(id, "SOUND"))
|
||||
return null;
|
||||
}
|
||||
var path = getAssetPath();
|
||||
editedTimes[id] = FileSystem.stat(path).mtime.getTime();
|
||||
var e = AudioBuffer.fromFile(path);
|
||||
@@ -64,10 +64,8 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
if (__isCacheValid(cachedBytes, id, true))
|
||||
return cachedBytes.get(id);
|
||||
else {
|
||||
if (!exists(id, "BINARY")) {
|
||||
Log.error('ModsAssetLibrary: Bytes at $id does not exist.');
|
||||
if (!exists(id, "BINARY"))
|
||||
return null;
|
||||
}
|
||||
var path = getAssetPath();
|
||||
editedTimes[id] = FileSystem.stat(path).mtime.getTime();
|
||||
var e = Bytes.fromFile(path);
|
||||
@@ -80,10 +78,8 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
if (__isCacheValid(LimeAssets.cache.font, id))
|
||||
return LimeAssets.cache.font.get(id);
|
||||
else {
|
||||
if (!exists(id, "FONT")) {
|
||||
Log.error('ModsAssetLibrary: Font at $id does not exist.');
|
||||
if (!exists(id, "FONT"))
|
||||
return null;
|
||||
}
|
||||
var path = getAssetPath();
|
||||
editedTimes[id] = FileSystem.stat(path).mtime.getTime();
|
||||
var e = Font.fromFile(path);
|
||||
@@ -95,10 +91,8 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
if (useImageCache && __isCacheValid(LimeAssets.cache.image, id))
|
||||
return LimeAssets.cache.image.get('$libName:$id');
|
||||
else {
|
||||
if (!exists(id, "IMAGE")) {
|
||||
Log.error('ModsAssetLibrary: Image at $id does not exist.');
|
||||
if (!exists(id, "IMAGE"))
|
||||
return null;
|
||||
}
|
||||
var path = getAssetPath();
|
||||
editedTimes[id] = FileSystem.stat(path).mtime.getTime();
|
||||
|
||||
@@ -150,7 +144,6 @@ class ModsFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
}
|
||||
|
||||
private function __parseAsset(asset:String):Bool {
|
||||
var prefix = 'assets/$libName/';
|
||||
if (!asset.startsWith(prefix)) return false;
|
||||
_parsedAsset = asset.substr(prefix.length);
|
||||
return true;
|
||||
|
||||
@@ -29,6 +29,7 @@ class ZipFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
public var zipPath:String;
|
||||
public var libName:String;
|
||||
public var useImageCache:Bool = false;
|
||||
public var prefix = 'assets/';
|
||||
|
||||
#if MOD_SUPPORT
|
||||
public var zip:Reader;
|
||||
@@ -38,6 +39,7 @@ class ZipFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
public function new(zipPath:String, libName:String) {
|
||||
this.zipPath = zipPath;
|
||||
this.libName = libName;
|
||||
this.prefix = 'assets/$libName/';
|
||||
|
||||
#if MOD_SUPPORT
|
||||
zip = new Reader(File.read(zipPath, true));
|
||||
@@ -124,7 +126,6 @@ class ZipFolderLibrary extends AssetLibrary implements ModsAssetLibrary {
|
||||
}
|
||||
|
||||
public function __parseAsset(asset:String):Bool {
|
||||
var prefix = 'assets/$libName/';
|
||||
if (!asset.startsWith(prefix)) return false;
|
||||
_parsedAsset = asset.substr(prefix.length).toLowerCase();
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package funkin.system;
|
||||
|
||||
import funkin.mods.ModsAssetLibrary;
|
||||
import openfl.utils.Assets;
|
||||
import lime.utils.AssetLibrary;
|
||||
|
||||
class AssetsLibraryList extends AssetLibrary {
|
||||
public var libraries:Array<AssetLibrary> = [];
|
||||
public var base:AssetLibrary;
|
||||
|
||||
public function removeLibrary(lib:AssetLibrary) {
|
||||
if (lib == null) return lib;
|
||||
libraries.remove(lib);
|
||||
return lib;
|
||||
}
|
||||
public override function exists(id:String, type:String) {
|
||||
if (!id.startsWith("assets/") && exists('assets/$id', type))
|
||||
return true;
|
||||
for(e in libraries)
|
||||
if (e.exists(id, type))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override function getPath(id:String) {
|
||||
for(e in libraries) {
|
||||
var path = e.getPath(id);
|
||||
if (path != null)
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getFiles(folder:String):Array<String> {
|
||||
var content:Array<String> = [];
|
||||
for(e in libraries) {
|
||||
var l = e;
|
||||
|
||||
if (l is openfl.utils.AssetLibrary) {
|
||||
@:privateAccess
|
||||
l = cast(l, openfl.utils.AssetLibrary).__proxy;
|
||||
}
|
||||
|
||||
// TODO: do base folder scanning
|
||||
if (l is ModsAssetLibrary) {
|
||||
var lib = cast(l, ModsAssetLibrary);
|
||||
for(e in lib.getFiles(folder))
|
||||
content.push(e);
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
public override function getAsset(id:String, type:String) {
|
||||
if (!id.startsWith("assets/")) {
|
||||
var ass = getAsset('assets/$id', type);
|
||||
if (ass != null)
|
||||
return ass;
|
||||
}
|
||||
for(e in libraries) {
|
||||
var asset = e.getAsset(id, type);
|
||||
if (asset != null)
|
||||
return asset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function new(?base:AssetLibrary) {
|
||||
super();
|
||||
if (base == null)
|
||||
base = Assets.getLibrary("default");
|
||||
addLibrary(this.base = base);
|
||||
}
|
||||
|
||||
public function addLibrary(lib:AssetLibrary) {
|
||||
libraries.insert(0, lib);
|
||||
return lib;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package funkin.system;
|
||||
|
||||
import openfl.utils.AssetLibrary;
|
||||
import openfl.utils.AssetCache;
|
||||
import openfl.text.TextFormat;
|
||||
import flixel.system.ui.FlxSoundTray;
|
||||
@@ -111,6 +112,8 @@ class Main extends Sprite
|
||||
|
||||
|
||||
public function loadGameSettings() {
|
||||
Paths.assetsTree = new AssetsLibraryList();
|
||||
|
||||
Logs.init();
|
||||
|
||||
// TODO: Mod switching
|
||||
@@ -127,7 +130,9 @@ class Main extends Sprite
|
||||
if (Sys.args().contains("-livereload")) {
|
||||
#if USE_SOURCE_ASSETS
|
||||
trace("Used lime test windows. Switching into source assets.");
|
||||
ModsFolder.loadLibraryFromFolder('default', './../../../../assets/', true, true);
|
||||
Paths.assetsTree.addLibrary(ModsFolder.loadLibraryFromFolder('assets', './../../../../assets/', true));
|
||||
#else
|
||||
Assets.registerLibrary('assets', Paths.assetsTree.base);
|
||||
#end
|
||||
|
||||
var buildNum:Int = Std.parseInt(File.getContent("./../../../../buildnumber.txt"));
|
||||
@@ -135,11 +140,21 @@ class Main extends Sprite
|
||||
File.saveContent("./../../../../buildnumber.txt", Std.string(buildNum));
|
||||
} else {
|
||||
#if USE_ADAPTED_ASSETS
|
||||
ModsFolder.loadLibraryFromFolder('default', './assets/', true, true);
|
||||
Paths.assetsTree.addLibrary(ModsFolder.loadLibraryFromFolder('assets', './assets/', true));
|
||||
#else
|
||||
Assets.registerLibrary('assets', Paths.assetsTree.base);
|
||||
#end
|
||||
}
|
||||
#else
|
||||
Assets.registerLibrary('assets', Paths.assetsTree.base);
|
||||
#end
|
||||
|
||||
|
||||
var lib = new AssetLibrary();
|
||||
@:privateAccess
|
||||
lib.__proxy = Paths.assetsTree;
|
||||
Assets.registerLibrary('default', lib);
|
||||
|
||||
funkin.options.PlayerSettings.init();
|
||||
FlxG.save.bind('Save');
|
||||
Options.load();
|
||||
|
||||
@@ -19,19 +19,14 @@ class Paths
|
||||
*/
|
||||
inline public static var SOUND_EXT = #if web "mp3" #else "ogg" #end;
|
||||
|
||||
public static var assetsTree:AssetsLibraryList;
|
||||
|
||||
public static function getPath(file:String, type:AssetType, library:Null<String>, skipModsVerification:Bool = false)
|
||||
{
|
||||
if (library != null && library.startsWith("mods/")) {
|
||||
library = library.toLowerCase();
|
||||
} else if (!skipModsVerification && ModsFolder.currentModFolder != null) {
|
||||
var modPath = getPath(file, type, 'mods/${ModsFolder.currentModFolder}');
|
||||
if (OpenFlAssets.exists(modPath)) return modPath;
|
||||
}
|
||||
|
||||
if (library != null)
|
||||
return getLibraryPath(file, library);
|
||||
|
||||
return getAssetsPath(file);
|
||||
return skipModsVerification ? 'assets:${getAssetsPath(file)}' : getAssetsPath(file);
|
||||
}
|
||||
|
||||
static public function video(key:String) {
|
||||
@@ -188,13 +183,20 @@ class Paths
|
||||
|
||||
static public function getFolderContent(key:String, includeSource:Bool = true, addPath:Bool = false, scanSource:Bool = false):Array<String> {
|
||||
// designed to work both on windows and web
|
||||
|
||||
if (!key.endsWith("/")) key += "/";
|
||||
var content = assetsTree.getFiles('assets/$key');
|
||||
if (addPath) {
|
||||
for(k=>e in content)
|
||||
content[k] = '$key$e';
|
||||
}
|
||||
return content;
|
||||
/*
|
||||
if (!key.endsWith("/")) key = key + "/";
|
||||
|
||||
if (ModsFolder.currentModFolder == null && !scanSource)
|
||||
return getFolderContent(key, false, addPath, true);
|
||||
|
||||
var folderPath:String = scanSource ? getPreloadPath(key) : getLibraryPathForce(key, 'mods/${ModsFolder.currentModFolder}');
|
||||
var folderPath:String = scanSource ? getAssetsPath(key) : getLibraryPathForce(key, 'mods/${ModsFolder.currentModFolder}');
|
||||
var libThing = new LimeLibrarySymbol(folderPath);
|
||||
var library = libThing.library;
|
||||
|
||||
@@ -239,5 +241,6 @@ class Paths
|
||||
}
|
||||
|
||||
return content;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user