@shockpkg/dir-projector
Version:
Package for creating Shockwave Director projectors
222 lines (175 loc) • 4.23 kB
JavaScript
import { join as pathJoin, dirname } from 'path';
import fse from 'fs-extra';
import { PathType } from "@shockpkg/archive-files/module.mjs";
import { pathRelativeBase, pathRelativeBaseMatch } from "../util.mjs";
import { peResourceReplace } from "../util/windows.mjs";
import { Projector } from "../projector.mjs";
/**
* ProjectorWindows constructor.
*
* @param path Output path.
*/
export class ProjectorWindows extends Projector {
/**
* Icon file.
*/
/**
* Icon data.
*/
/**
* Version strings.
*/
constructor(path) {
super(path);
this.iconFile = null;
this.iconData = null;
this.versionStrings = null;
}
/**
* Projector file extension.
*
* @returns File extension.
*/
get extension() {
return '.exe';
}
/**
* Config file newline characters.
*
* @returns Newline characters.
*/
get configNewline() {
return '\r\n';
}
/**
* Lingo file newline characters.
*
* @returns Newline characters.
*/
get lingoNewline() {
return '\r\n';
}
/**
* Splash image file extension.
*
* @returns File extension.
*/
get splashImageExtension() {
return '.BMP';
}
/**
* Get the SKL name.
*
* @returns File name.
*/
get sklName() {
return 'Projec32.skl';
}
/**
* Get icon data if any specified, from data or file.
*
* @returns Icon data or null.
*/
async getIconData() {
const {
iconData,
iconFile
} = this;
return iconData || (iconFile ? fse.readFile(iconFile) : null);
}
/**
* Write the projector skeleton from archive.
*
* @param skeleton Skeleton path.
*/
async _writeSkeleton(skeleton) {
const {
path,
shockwave,
sklName,
xtrasName,
xtrasPath
} = this;
const xtrasMappings = this.getIncludeXtrasMappings();
let foundProjectorSkl = false;
let foundXtras = false;
const xtrasHandler = async entry => {
// Check if Xtras path.
const xtrasRel = pathRelativeBase(entry.volumePath, xtrasName, true);
if (xtrasRel === null) {
return false;
}
foundXtras = true; // Find output path if being included, else skip.
const dest = this.includeXtrasMappingsDest(xtrasMappings, xtrasRel);
if (!dest) {
return true;
}
await entry.extract(pathJoin(xtrasPath, dest));
return true;
};
const projectorSklHandler = async entry => {
const entryPath = entry.volumePath; // Should not be in sub directory.
if (entryPath.includes('/')) {
return false;
} // Check if skl path.
if (!pathRelativeBaseMatch(entryPath, sklName, true)) {
return false;
}
foundProjectorSkl = true;
await entry.extract(path);
return true;
};
const projectorDllHandler = async entry => {
const entryPath = entry.volumePath; // Should not be in sub directory.
if (entryPath.includes('/')) {
return false;
} // Check if dll path.
if (!/\.dll$/i.test(entryPath)) {
return false;
} // Exclude if shockwave projector.
if (shockwave) {
return true;
}
await entry.extract(pathJoin(dirname(path), entryPath));
return true;
};
const archive = await this.getSkeletonArchive(skeleton);
await archive.read(async entry => {
if (entry.type === PathType.RESOURCE_FORK) {
return;
}
if (await xtrasHandler(entry)) {
return;
}
if (await projectorSklHandler(entry)) {
return;
}
if (await projectorDllHandler(entry)) {
return;
}
});
if (!foundProjectorSkl) {
throw new Error(`Failed to locate: ${sklName}`);
}
if (!foundXtras) {
throw new Error(`Failed to locate: ${xtrasName}`);
}
}
/**
* Modify the projector skeleton.
*/
async _modifySkeleton() {
const iconData = await this.getIconData();
const {
versionStrings
} = this;
if (!(iconData || versionStrings)) {
return;
}
await peResourceReplace(this.path, {
iconData,
versionStrings
});
}
}
//# sourceMappingURL=windows.mjs.map