170 lines
4.2 KiB
JavaScript
170 lines
4.2 KiB
JavaScript
class ResourcePack {
|
|
constructor (data) {
|
|
this.name = data.name;
|
|
this.description = data.description;
|
|
|
|
this.meta = data.meta;
|
|
|
|
this.models = data.models || new global.Map();
|
|
this.textures = data.textures || new global.Map();
|
|
this.sounds = new global.Map();
|
|
}
|
|
static loadFromZIP (zipBuffer) {
|
|
if (!zipBuffer) return Promise.reject(new Error("Missing argument zipBuffer. "));
|
|
return new Promise(function (resolve, reject) {
|
|
global.fflate.unzip(new Uint8Array(zipBuffer), {}, function (error, data) {
|
|
if (error) return reject(error);
|
|
if (!data["pack.json"]) return reject(new Error("pack.json not found in zip file. "));
|
|
|
|
let packMeta;
|
|
try {
|
|
packMeta = JSON.parse(global.fflate.strFromU8(data["pack.json"]));
|
|
} catch (err) {
|
|
return reject(err);
|
|
}
|
|
|
|
var packData = readPackMeta(packMeta, data);
|
|
|
|
packData.meta = packMeta;
|
|
|
|
var resourceLoadings = [];
|
|
|
|
resourceLoadings.push(loadU8Textures(packMeta, data).then(function (textureMap) {
|
|
packData.textures = textureMap;
|
|
}).catch(reject));
|
|
|
|
resourceLoadings.push(loadU8Models(packMeta, data).then(function (modelMap) {
|
|
packData.models = modelMap;
|
|
}).catch(reject));
|
|
|
|
Promise.all(resourceLoadings).then(function () {
|
|
var resourcePack = new ResourcePack(packData);
|
|
|
|
global.core.emit("resourcepack-load", resourcePack);
|
|
|
|
resolve(resourcePack);
|
|
}).catch(reject);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
var readPackMeta = function (packMeta, packArchive) {
|
|
var pack = {
|
|
"name": packMeta.name,
|
|
"description": packMeta.description
|
|
};
|
|
|
|
return pack;
|
|
};
|
|
|
|
var loadU8Textures = function (packMeta, packData) {
|
|
return new Promise(function (resolve, reject) {
|
|
var textureMap = new global.Map();
|
|
|
|
var textureLoadings = [];
|
|
|
|
var textureMeta = packMeta.textures;
|
|
|
|
for (var textureName in textureMeta) {
|
|
if (textureMeta.hasOwnProperty(textureName)) {
|
|
var textureData = textureMeta[textureName];
|
|
|
|
if (textureData.path) {
|
|
var splitPath = textureData.path.split(/[\/\.]+/g);
|
|
|
|
var extension = splitPath[splitPath.length - 1].toLowerCase();
|
|
if (extension == "jpg") extension = "jpeg";
|
|
|
|
if ((["png", "jpeg", "webp", "gif", "apng", "avif"]).indexOf(extension) > -1) {
|
|
var type = "image";
|
|
} else if ((["mp4", "mkv", "ogg", "webm"]).indexOf(extension) > -1) {
|
|
var type = "video";
|
|
}
|
|
|
|
var mimeType = type + "/" + extension;
|
|
|
|
if (!packData[textureData.path]) reject(new Error("Texture doesn't exist at " + textureData.path + ". "));
|
|
|
|
var textureBind = {
|
|
"name": textureName
|
|
};
|
|
|
|
textureLoadings.push(new Promise((function(res, rej) {
|
|
var imageData = packData[textureData.path];
|
|
|
|
var imageBlob = new Blob([imageData.buffer], {"type": mimeType});
|
|
|
|
var imageObjectURL = URL.createObjectURL(imageBlob);
|
|
|
|
var texture = new global.three.Texture();
|
|
var image = new global.Image();
|
|
|
|
texture.minFilter = global.three.NearestFilter;
|
|
texture.magFilter = global.three.NearestFilter;
|
|
|
|
image.onload = (function () {
|
|
texture.image = image;
|
|
texture.needsUpdate = true;
|
|
|
|
var data = {
|
|
"map": texture
|
|
};
|
|
|
|
textureMap.set(this.name, data);
|
|
|
|
res(data);
|
|
}).bind(textureBind);
|
|
|
|
image.src = imageObjectURL;
|
|
}).bind(textureBind)));
|
|
} else if (textureData.texture) {
|
|
var data = {
|
|
|
|
};
|
|
|
|
textureMap.set(textureName, data);
|
|
|
|
textureLoadings.push(Promise.resolve(data));
|
|
}
|
|
}
|
|
}
|
|
|
|
Promise.all(textureLoadings).then(function (textures) {
|
|
resolve(textureMap);
|
|
}).catch(reject);
|
|
});
|
|
};
|
|
|
|
var loadU8Models = function (packMeta, packData) {
|
|
return new Promise(function (resolve, reject) {
|
|
var modelMap = new global.Map();
|
|
|
|
var modelLoadings = [];
|
|
|
|
var modelMeta = packMeta.models;
|
|
|
|
for (var modelName in modelMeta) {
|
|
if (modelMeta.hasOwnProperty(modelName)) {
|
|
var modelData = modelMeta[modelName];
|
|
|
|
var modelString = global.fflate.strFromU8(packData[modelData.path]);
|
|
|
|
var modelJSON = JSON.parse(modelString);
|
|
|
|
modelMap.set(modelName, modelJSON);
|
|
|
|
modelLoadings.push(Promise.resolve(modelJSON));
|
|
}
|
|
}
|
|
|
|
Promise.all(modelLoadings).then(function (models) {
|
|
resolve(modelMap);
|
|
}).catch(reject);
|
|
});
|
|
};
|
|
|
|
module.exports = {
|
|
"ResourcePack": ResourcePack
|
|
};
|