11package funkin .backend .assets ;
22
3+ import funkin .backend .system .Flags ;
4+
35import haxe .io .Path ;
46import lime .graphics .Image ;
57import lime .media .AudioBuffer ;
68import lime .text .Font ;
79import lime .utils .Bytes ;
810import openfl .utils .AssetLibrary ;
11+ import sys .io .File ;
912
1013#if MOD_SUPPORT
1114import funkin .backend .utils .SysZip .SysZipEntry ;
@@ -15,40 +18,76 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
1518 public var basePath : String ;
1619 public var modName : String ;
1720 public var libName : String ;
18- public var useImageCache : Bool = false ;
1921 public var prefix = ' assets/' ;
20-
22+
2123 public var zip : SysZip ;
2224 public var assets : Map <String , SysZipEntry > = [];
2325 public var lowerCaseAssets : Map <String , SysZipEntry > = [];
2426 public var nameMap : Map <String , String > = [];
2527
26- public function new (basePath : String , libName : String , ? modName : String ) {
28+ public var PRELOAD_VIDEOS : Bool = true ;
29+
30+ public function new (basePath : String , libName : String , ? modName : String , ? preloadVideos : Bool = true ) {
2731 this .libName = libName ;
2832
2933 this .basePath = basePath ;
3034
3135 this .modName = (modName == null ) ? libName : modName ;
3236
3337 zip = SysZip .openFromFile (basePath );
34- zip .read ();
3538 for (entry in zip .entries ) {
36- if (entry .fileName .length < 0 || entry .fileName .endsWith (" /" ))
37- continue ;
39+ if (entry .fileName .length < 0 || entry .fileName .endsWith (" /" )) continue ;
3840
39- lowerCaseAssets [entry .fileName .toLowerCase ()] = assets [entry .fileName .toLowerCase ()] = assets [entry .fileName ] = entry ;
40- nameMap .set (entry .fileName .toLowerCase (), entry .fileName );
41+ var name : String = entry .fileName .toLowerCase (); // calling .toLowerCase a million times is never the solution
42+ lowerCaseAssets [name ] = assets [name ] = assets [entry .fileName ] = entry ;
43+ nameMap .set (name , entry .fileName );
4144 }
4245
4346 super ();
47+
48+ isCompressed = true ;
49+
50+ // don't override default value of true if the file exists.
51+ // by default `PRELOAD_VIDEOS` is true so you will never need to add this file, but in the case of it being false this is a backup method.
52+ PRELOAD_VIDEOS = (! PRELOAD_VIDEOS ) ? exists (" assets/data/PRECACHE_VIDEOS" , " TEXT" ) : PRELOAD_VIDEOS ;
53+
54+ // if (PRELOAD_VIDEOS) precacheVideos(); // we do this in `MainState` now to handle for `Flags.VIDEO_EXT` :)
55+ }
56+
57+ public function precacheVideos () {
58+ _videoExtensions = [Flags .VIDEO_EXT ];
59+
60+ videoCacheRemap = [];
61+ for (entry in zip .entries ) {
62+ var name = entry .fileName .toLowerCase ();
63+ if (_videoExtensions .contains (Path .extension (name ))) getPath (prefix + name );
64+ }
65+
66+ var count : Int = 0 ;
67+ for (_ in videoCacheRemap .keys ()) count ++ ;
68+ if (count <= 0 ) return ;
69+ trace (' Precached $count video ${(count == 1 ) ? " " : " s" }' );
70+ }
71+
72+ // Now we have supports for videos in ZIP!!
73+ public var _videoExtensions : Array <String > = [Flags .VIDEO_EXT ];
74+ public var videoCacheRemap : Map <String , String > = [];
75+ public function getVideoRemap (originalPath : String ): String {
76+ if (! _videoExtensions .contains (Path .extension (_parsedAsset ))) return originalPath ;
77+ if (videoCacheRemap .exists (originalPath )) return videoCacheRemap .get (originalPath );
78+
79+ // We adding the length of the string to counteract folder in folder naming duplicates.
80+ var newPath = ' ./.temp/ ${_parsedAsset .length }-zipvideo- ${_parsedAsset .split (" /" ).pop ()}' ;
81+ File .saveBytes (newPath , unzip (assets [_parsedAsset ]));
82+ videoCacheRemap .set (originalPath , newPath );
83+ return newPath ;
4484 }
4585
4686 function toString (): String {
47- return ' (ZipFolderLibrary: $libName / $modName )' ;
87+ return ' (ZipFolderLibrary: $libName / $modName | ${ zip . entries . length } entries | Detected Video Extensions: ${ _videoExtensions . join ( " , " )} )' ;
4888 }
4989
5090 public var _parsedAsset : String ;
51-
5291 public override function getAudioBuffer (id : String ): AudioBuffer {
5392 __parseAsset (id );
5493 return AudioBuffer .fromBytes (unzip (assets [_parsedAsset ]));
@@ -71,15 +110,12 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
71110 return getAssetPath ();
72111 }
73112
74-
75-
76- public inline function unzip (f : SysZipEntry )
77- return f == null ? null : zip .unzipEntry (f );
113+ public inline function unzip (f : SysZipEntry ) return (f == null ) ? null : zip .unzipEntry (f );
78114
79115 public function __parseAsset (asset : String ): Bool {
80116 if (! asset .startsWith (prefix )) return false ;
81117 _parsedAsset = asset .substr (prefix .length );
82- if (ModsFolder .useLibFile ) {
118+ if (ModsFolder .useLibFile ) {
83119 var file = new haxe.io. Path (_parsedAsset );
84120 if (file .file .startsWith (" LIB_" )) {
85121 var library = file .file .substr (4 );
@@ -90,8 +126,7 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
90126 }
91127
92128 _parsedAsset = _parsedAsset .toLowerCase ();
93- if (nameMap .exists (_parsedAsset ))
94- _parsedAsset = nameMap .get (_parsedAsset );
129+ if (nameMap .exists (_parsedAsset )) _parsedAsset = nameMap .get (_parsedAsset );
95130 return true ;
96131 }
97132
@@ -106,9 +141,8 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
106141 return assets [_parsedAsset ] != null ;
107142 }
108143
109- private function getAssetPath () {
110- trace (' [ZIP] $basePath / $_parsedAsset ' );
111- return ' [ZIP] $basePath / $_parsedAsset ' ;
144+ private inline function getAssetPath () {
145+ return getVideoRemap (' $basePath / $_parsedAsset ' );
112146 }
113147
114148 // TODO: rewrite this to 1 function, like ModsFolderLibrary
@@ -157,18 +191,6 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
157191 return content ;
158192 }
159193
160- public override function list (type : String ): Array <String > {
161- return [for (k => e in nameMap ) ' $prefix $e ' ];
162- }
163-
164- // Backwards compat
165-
166- @:noCompletion public var zipPath (get , set ): String ;
167- @:noCompletion private inline function get_zipPath (): String {
168- return basePath ;
169- }
170- @:noCompletion private inline function set_zipPath (value : String ): String {
171- return basePath = value ;
172- }
194+ public override function list (type : String ): Array <String > { return [for (k => e in nameMap ) ' $prefix $e ' ]; }
173195}
174196#end
0 commit comments