-
-
Notifications
You must be signed in to change notification settings - Fork 321
Expand file tree
/
Copy pathZipFolderLibrary.hx
More file actions
193 lines (159 loc) · 5.73 KB
/
ZipFolderLibrary.hx
File metadata and controls
193 lines (159 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
package funkin.backend.assets;
import funkin.backend.system.Flags;
import haxe.io.Path;
import lime.graphics.Image;
import lime.media.AudioBuffer;
import lime.text.Font;
import lime.utils.Bytes;
import openfl.utils.AssetLibrary;
import sys.io.File;
#if MOD_SUPPORT
import funkin.backend.utils.SysZip.SysZipEntry;
import funkin.backend.utils.SysZip;
class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
public var basePath:String;
public var modName:String;
public var libName:String;
// public var useImageCache:Bool = false;
public var prefix = 'assets/';
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, ?preloadVideos:Bool = true) {
CoolUtil.debugTimeStamp();
this.libName = libName;
this.basePath = basePath;
this.modName = (modName == null) ? libName : modName;
zip = SysZip.openFromFile(basePath);
for(entry in zip.entries) {
var name = entry.fileName.toLowerCase();
lowerCaseAssets[name] = assets[name] = assets[entry.fileName] = entry;
nameMap.set(name, entry.fileName);
}
super();
isCompressed = true;
precacheVideos();
CoolUtil.debugTimeStamp("ZipFolderLibrary");
}
public function precacheVideos() {
videoCacheRemap = [];
for (entry in zip.entries) {
var name = entry.fileName.toLowerCase();
if (_videoExtensions.contains(Path.extension(name))) getPath(prefix+name);
}
var count = 0;
for (_ in videoCacheRemap.keys()) count++;
trace('Precached $count video${count == 1 ? "" : "s"}');
}
// Now we have supports for videos in ZIP!!
public var _videoExtensions:Array<String> = [Flags.VIDEO_EXT];
public var videoCacheRemap:Map<String, String> = [];
public function getVideoRemap(originalPath:String):String {
if (!_videoExtensions.contains(Path.extension(_parsedAsset))) return originalPath;
if (videoCacheRemap.exists(originalPath)) return videoCacheRemap.get(originalPath);
// We adding the length of the string to counteract folder in folder naming duplicates.
var newPath = './.temp/${assets[_parsedAsset].fileName.length}-zipvideo-${_parsedAsset.split("/").pop()}';
File.saveBytes(newPath, unzip(assets[_parsedAsset]));
videoCacheRemap.set(originalPath, newPath);
return newPath;
}
function toString():String {
return '(ZipFolderLibrary: $libName/$modName | ${zip.entries.length} entries | Detected Video Extensions: ${_videoExtensions.join(", ")})';
}
public var _parsedAsset:String;
public override function getAudioBuffer(id:String):AudioBuffer {
__parseAsset(id);
return AudioBuffer.fromBytes(unzip(assets[_parsedAsset]));
}
public override function getBytes(id:String):Bytes {
__parseAsset(id);
return Bytes.fromBytes(unzip(assets[_parsedAsset]));
}
public override function getFont(id:String):Font {
__parseAsset(id);
return ModsFolder.registerFont(Font.fromBytes(unzip(assets[_parsedAsset])));
}
public override function getImage(id:String):Image {
__parseAsset(id);
return Image.fromBytes(unzip(assets[_parsedAsset]));
}
public override function getPath(id:String):String {
if (!__parseAsset(id)) return null;
return getAssetPath();
}
public inline function unzip(f:SysZipEntry) return (f == null) ? null : zip.unzipEntry(f);
public function __parseAsset(asset:String):Bool {
if (!asset.startsWith(prefix)) return false;
_parsedAsset = asset.substr(prefix.length);
if (ModsFolder.useLibFile) {
var file = new haxe.io.Path(_parsedAsset);
if(file.file.startsWith("LIB_")) {
var library = file.file.substr(4);
if(library != modName) return false;
_parsedAsset = file.dir + "." + file.ext;
}
}
_parsedAsset = _parsedAsset.toLowerCase();
if (nameMap.exists(_parsedAsset)) _parsedAsset = nameMap.get(_parsedAsset);
return true;
}
public function __isCacheValid(cache:Map<String, Dynamic>, asset:String, isLocal:Bool = false) {
if (cache.exists(isLocal ? '$libName:$asset': asset)) return true;
return false;
}
public override function exists(asset:String, type:String):Bool {
if(!__parseAsset(asset)) return false;
return assets[_parsedAsset] != null;
}
private function getAssetPath() {
return getVideoRemap('$basePath/$_parsedAsset');
}
// TODO: rewrite this to 1 function, like ModsFolderLibrary
public function getFiles(folder:String):Array<String> {
if (!folder.endsWith("/")) folder += "/";
if (!__parseAsset(folder)) return [];
var content:Array<String> = [];
var checkPath = _parsedAsset.toLowerCase();
@:privateAccess
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("/") && fileName.length > 0)
content.pushOnce(fileName);
}
}
return content;
}
public function getFolders(folder:String):Array<String> {
if (!folder.endsWith("/")) folder += "/";
if (!__parseAsset(folder)) return [];
var content:Array<String> = [];
var checkPath = _parsedAsset.toLowerCase();
@:privateAccess
for(k=>e in lowerCaseAssets) {
if (k.toLowerCase().startsWith(checkPath)) {
if(nameMap.exists(k))
k = nameMap.get(k);
var fileName = k.substr(_parsedAsset.length);
var index = fileName.indexOf("/");
if (index != -1 && fileName.length > 0) {
var s = fileName.substr(0, index);
content.pushOnce(s);
}
}
}
return content;
}
// Backwards compat
@:noCompletion public var zipPath(get, set):String;
@:noCompletion private inline function get_zipPath():String {
return basePath;
}
@:noCompletion private inline function set_zipPath(value:String):String {
return basePath = value;
}
}
#end