Skip to content

Instantly share code, notes, and snippets.

@linuxgemini
Created May 14, 2018 17:31
Show Gist options
  • Select an option

  • Save linuxgemini/75dde1ec3c134bcfee817f4f86d20b47 to your computer and use it in GitHub Desktop.

Select an option

Save linuxgemini/75dde1ec3c134bcfee817f4f86d20b47 to your computer and use it in GitHub Desktop.
Export files from the proprietary BLK format.
/*--------------------------------------------------------------
* Copyright (c) linuxgemini. All rights reserved.
* Licensed under the MIT License.
*
* Original ActionScript code written by JrMasterModelBuilder (c) 2011
*-------------------------------------------------------------*/
"use strict";
/*
import fs from "fs";
import path from "path";
*/
const fs = require("fs");
const path = require("path");
class BLKextractor {
constructor() {
/**
* @type {Buffer}
*/
this.archiveFileData = null;
/**
* @type {Array}
*/
this.archiveFileList = null;
/**
* @type {Buffer}
*/
this.blankByte = Buffer.from([0x00]);
/**
* @type {String}
*/
this.folderMemory = null;
/**
* @type {String}
*/
this.fileName = null;
}
_erase() {
this.archiveFileData = null;
this.archiveFileList = null;
}
/**
* Read and extract a BLK file.
* @param {String} filePath Relative or absolute path of the BLK file.
*/
extractFile(filePath) {
return new Promise((resolve, reject) => {
try {
this._erase();
if (!filePath) throw new Error("File is not supplied!");
if (!path.isAbsolute(filePath)) filePath = path.resolve(filePath);
this.folderMemory = path.dirname(filePath);
this.fileName = path.parse(filePath).name;
this.archiveFileData = fs.readFileSync(filePath);
if (this.archiveFileData.length < 1) throw new Error("File is empty.");
let checkBLK = Buffer.compare(this.archiveFileData, Buffer.from([0x42, 0x4c, 0x4b, 0x46]));
if (checkBLK !== 1) throw new Error("File is not a BLK file.");
this.archiveFileList = this._listFiles(12, this._findNumber(8));
let savePath = path.resolve(this.folderMemory, `${this.fileName}-extracted`);
if (fs.existsSync(savePath)) throw new Error("This file has already been extracted!");
this._saveFiles(savePath) && resolve(true);
} catch (error) {
reject(error);
}
});
}
/**
* List all files.
* @param {Number} int1
* @param {Number} int2
* @returns {Array}
*/
_listFiles(int1, int2) {
/**
* @type {String}
*/
let _loc5_ = null;
let _loc6_ = 0;
let _loc3_ = new Array(3);
_loc3_[0] = new Array(int2);
_loc3_[1] = new Array(int2);
_loc3_[2] = new Array(int2);
let _loc4_ = 0;
while (_loc4_ < int2) {
_loc5_ = "";
_loc6_ = 0;
while (_loc6_ < 40) {
if (this.archiveFileData[int1 + _loc6_] != 0) {
_loc5_ = _loc5_ + this._char(this.archiveFileData[int1 + _loc6_]);
}
_loc6_++;
}
_loc3_[0][_loc4_] = _loc5_;
_loc3_[1][_loc4_] = this._findNumber(int1 + 52);
_loc3_[2][_loc4_] = this._findNumber(int1 + 40);
int1 = int1 + 56;
_loc4_++;
}
return _loc3_;
}
/**
* String.fromCharCode(int);
* @param {Number} int1
*/
_char(int1) {
return String.fromCharCode(int1);
}
/**
* Finds number.
* @param {Number} int1
*/
_findNumber(int1) {
return this.archiveFileData[int1] + this.archiveFileData[int1 + 1] * 256 + this.archiveFileData[int1 + 2] * 65536 + this.archiveFileData[int1 + 3] * 16777216;
}
/**
* Extract a BLK file.
* @param {String} savePath Absolute path of the file extraction folder.
*/
_saveFiles(savePath) {
fs.mkdirSync(savePath);
let _loc3_ = null;
let _loc4_ = null;
let _loc2_ = 0;
while (_loc2_ < this.archiveFileList[0].length) {
_loc3_ = path.resolve(savePath, this.archiveFileList[0][_loc2_]);
_loc4_ = fs.openSync(_loc3_, "wx");
if (this.archiveFileList[1][_loc2_] == 0 || this.archiveFileList[2][_loc2_] == 0) {
fs.writeSync(_loc4_, this.blankByte);
} else {
fs.writeSync(_loc4_, this.archiveFileData, this.archiveFileList[1][_loc2_], this.archiveFileList[2][_loc2_]);
}
_loc2_++;
}
return true;
}
}
// export default BLKextractor;
module.exports = BLKextractor;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment