mirror of
https://github.com/araxiaonline/mpq-tools-osx.git
synced 2026-06-13 03:12:25 -04:00
Initial Commit
This commit is contained in:
53
.github/workflows/npm-publish.yml
vendored
Normal file
53
.github/workflows/npm-publish.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: NPM Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate Release Notes
|
||||
id: generate_notes
|
||||
uses: TriPSs/conventional-changelog-action@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
skip-version-file: true
|
||||
skip-commit: true
|
||||
skip-tag: true
|
||||
output-file: false
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
body: ${{ steps.generate_notes.outputs.clean_changelog }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
publish:
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
scope: '@araxiaonline'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
- run: npm run build
|
||||
- run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
node_modules/
|
||||
mpqcli/build/
|
||||
bin/
|
||||
*.log
|
||||
.DS_Store
|
||||
extracted/*
|
||||
103
README.md
Normal file
103
README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# mpq-tools-osx
|
||||
|
||||
A Node.js wrapper for manipulating MPQ archives using mpqcli. This package provides a simple interface to list, extract, and create MPQ archives commonly used in Blizzard games.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js >= 14.0.0
|
||||
- CMake (for building mpqcli)
|
||||
- C++ compiler (for building mpqcli)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install mpq-tools-osx
|
||||
```
|
||||
|
||||
The package will automatically build mpqcli during installation.
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
const MPQTool = require('mpq-tools');
|
||||
const mpq = new MPQTool();
|
||||
|
||||
// List all files in an MPQ archive
|
||||
const files = mpq.listFiles('path/to/archive.mpq');
|
||||
console.log(`Found ${files.length} files`);
|
||||
|
||||
// Search for specific files
|
||||
const swordSounds = mpq.searchFiles('path/to/archive.mpq', 'Sword');
|
||||
console.log(`Found ${swordSounds.length} sword sound files`);
|
||||
|
||||
// Extract a specific file
|
||||
mpq.extractFile('path/to/archive.mpq', 'path/inside/archive.txt', 'output/dir');
|
||||
|
||||
// Extract all files
|
||||
mpq.extractAll('path/to/archive.mpq', 'output/dir');
|
||||
|
||||
// Create a new MPQ archive from a directory
|
||||
mpq.createArchive('directory/to/archive', 2); // version 2 MPQ
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `new MPQTool(options)`
|
||||
|
||||
Create a new MPQTool instance.
|
||||
|
||||
Options:
|
||||
- `mpqcliPath`: Optional path to the mpqcli executable. By default, it uses the bundled version.
|
||||
|
||||
### `listFiles(mpqFile)`
|
||||
|
||||
List all files in an MPQ archive.
|
||||
|
||||
- `mpqFile`: Path to the MPQ file
|
||||
- Returns: Array of file paths in the archive
|
||||
|
||||
### `searchFiles(mpqFile, pattern)`
|
||||
|
||||
Search for files in an MPQ archive using a pattern.
|
||||
|
||||
- `mpqFile`: Path to the MPQ file
|
||||
- `pattern`: Search pattern (case-insensitive)
|
||||
- Returns: Array of matching file paths
|
||||
|
||||
### `extractFile(mpqFile, filePath, outputDir)`
|
||||
|
||||
Extract a specific file from an MPQ archive.
|
||||
|
||||
- `mpqFile`: Path to the MPQ file
|
||||
- `filePath`: Path of the file within the archive to extract
|
||||
- `outputDir`: Optional output directory
|
||||
- Returns: true if successful
|
||||
|
||||
### `extractAll(mpqFile, outputDir)`
|
||||
|
||||
Extract all files from an MPQ archive.
|
||||
|
||||
- `mpqFile`: Path to the MPQ file
|
||||
- `outputDir`: Optional output directory
|
||||
- Returns: true if successful
|
||||
|
||||
### `createArchive(directory, version)`
|
||||
|
||||
Create a new MPQ archive from a directory.
|
||||
|
||||
- `directory`: Directory to create MPQ from
|
||||
- `version`: MPQ version (1 or 2, default: 2)
|
||||
- Returns: true if successful
|
||||
|
||||
### Example command line command
|
||||
```bash
|
||||
$ node -e "const MPQTool = require('./lib'); const mpq = new MPQTool(); mpq.addFile('patch-C.MPQ', 'test.txt', 'custom/test.txt');"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
27
examples/add-files.js
Normal file
27
examples/add-files.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const MPQTool = require('../lib');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const mpq = new MPQTool();
|
||||
|
||||
// Create a test directory structure
|
||||
const testDir = path.join(__dirname, 'test-files');
|
||||
const customPath = path.join(testDir, 'custom', 'path');
|
||||
if (!fs.existsSync(customPath)) {
|
||||
fs.mkdirSync(customPath, { recursive: true });
|
||||
}
|
||||
|
||||
// Create some test files
|
||||
fs.writeFileSync(path.join(customPath, 'test1.txt'), 'Hello World!');
|
||||
fs.writeFileSync(path.join(customPath, 'test2.txt'), 'Another test file');
|
||||
|
||||
// Create an MPQ from our directory
|
||||
const outputMpq = path.join(__dirname, 'test.mpq');
|
||||
console.log('Creating new MPQ archive from directory...');
|
||||
const mpqPath = mpq.createArchive(testDir, 2, outputMpq);
|
||||
console.log(`Created MPQ at: ${mpqPath}`);
|
||||
|
||||
// List files in the archive to verify
|
||||
console.log('\nFiles in the archive:');
|
||||
const files = mpq.listFiles(mpqPath);
|
||||
files.forEach(file => console.log(file));
|
||||
BIN
examples/patch-z.mpq
Normal file
BIN
examples/patch-z.mpq
Normal file
Binary file not shown.
1
examples/test-files/custom/path/test1.txt
Normal file
1
examples/test-files/custom/path/test1.txt
Normal file
@@ -0,0 +1 @@
|
||||
Hello World!
|
||||
1
examples/test-files/custom/path/test2.txt
Normal file
1
examples/test-files/custom/path/test2.txt
Normal file
@@ -0,0 +1 @@
|
||||
Another test file
|
||||
280
lib/index.js
Normal file
280
lib/index.js
Normal file
@@ -0,0 +1,280 @@
|
||||
const { execSync } = require('child_process');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
class MPQTool {
|
||||
constructor(options = {}) {
|
||||
// Get platform-specific information
|
||||
const platform = os.platform();
|
||||
const arch = os.arch();
|
||||
|
||||
// Use the pre-built binary for the current platform
|
||||
const binaryName = platform === 'win32' ? 'mpqcli.exe' : 'mpqcli';
|
||||
const defaultPath = path.join(__dirname, '..', 'bin', `${platform}-${arch}`, binaryName);
|
||||
|
||||
// Allow overriding the mpqcli path
|
||||
this.mpqcliPath = options.mpqcliPath || defaultPath;
|
||||
|
||||
// Verify the binary exists
|
||||
if (!require('fs').existsSync(this.mpqcliPath)) {
|
||||
throw new Error(`mpqcli binary not found at ${this.mpqcliPath}. Make sure to run 'npm run build' first.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List all files in an MPQ archive
|
||||
* @param {string} mpqFile - Path to the MPQ file
|
||||
* @returns {string[]} Array of file paths in the archive
|
||||
*/
|
||||
listFiles(mpqFile) {
|
||||
try {
|
||||
const absolutePath = path.resolve(mpqFile);
|
||||
const cmd = `${this.mpqcliPath} list "${absolutePath}"`;
|
||||
|
||||
const output = execSync(cmd, {
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024 // 10MB buffer
|
||||
});
|
||||
return output.split('\n').filter(line => line.trim());
|
||||
} catch (error) {
|
||||
if (error.stdout) {
|
||||
// Even though it's an error, the command might have output
|
||||
return error.stdout.split('\n').filter(line => line.trim());
|
||||
}
|
||||
throw new Error(`Failed to list files: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all files from an MPQ archive
|
||||
* @param {string} mpqFile - Path to the MPQ file
|
||||
* @param {string} outputDir - Directory to extract files to
|
||||
*/
|
||||
extractAll(mpqFile, outputDir) {
|
||||
try {
|
||||
const fs = require('fs');
|
||||
const absoluteMpqPath = path.resolve(mpqFile);
|
||||
const absoluteOutputDir = path.resolve(outputDir);
|
||||
|
||||
// Create output directory if it doesn't exist
|
||||
fs.mkdirSync(absoluteOutputDir, { recursive: true });
|
||||
|
||||
// Extract files
|
||||
const cmd = `${this.mpqcliPath} extract -o "${absoluteOutputDir}" "${absoluteMpqPath}"`;
|
||||
execSync(cmd, {
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024 // 10MB buffer
|
||||
});
|
||||
|
||||
// Fix path separators in extracted files
|
||||
const files = this.listFiles(mpqFile);
|
||||
files.forEach(file => {
|
||||
const extractedPath = path.join(absoluteOutputDir, file);
|
||||
const normalizedPath = path.join(absoluteOutputDir, file.replace(/\\/g, path.sep));
|
||||
|
||||
// Skip if paths are the same
|
||||
if (extractedPath === normalizedPath) return;
|
||||
|
||||
// Create parent directory
|
||||
fs.mkdirSync(path.dirname(normalizedPath), { recursive: true });
|
||||
|
||||
// Move file to correct location
|
||||
if (fs.existsSync(extractedPath)) {
|
||||
fs.renameSync(extractedPath, normalizedPath);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to extract archive: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract specific files from an MPQ archive
|
||||
* @param {string} mpqFile - Path to the MPQ file
|
||||
* @param {string} filePath - Path of the file within the archive to extract
|
||||
* @param {string} outputDir - Optional output directory
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
extractFile(mpqFile, filePath, outputDir = null) {
|
||||
try {
|
||||
const absolutePath = path.resolve(mpqFile);
|
||||
const cmd = outputDir
|
||||
? `${this.mpqcliPath} extract -o "${path.resolve(outputDir)}" -f "${filePath}" "${absolutePath}"`
|
||||
: `${this.mpqcliPath} extract -f "${filePath}" "${absolutePath}"`;
|
||||
|
||||
execSync(cmd, {
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024 // 10MB buffer
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to extract file: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MPQ archive from a directory
|
||||
* @param {string} directory - Directory to create MPQ from
|
||||
* @param {number} version - MPQ version (1 or 2)
|
||||
* @param {string} [outputPath] - Optional path for the MPQ file. If not provided, creates it next to the directory
|
||||
* @returns {string} Path to the created MPQ file
|
||||
*/
|
||||
createArchive(directory, version = 2, outputPath = null) {
|
||||
try {
|
||||
const absoluteDir = path.resolve(directory);
|
||||
const dirName = path.basename(absoluteDir);
|
||||
const workingDir = path.dirname(absoluteDir);
|
||||
|
||||
// Create the MPQ in the directory's parent
|
||||
const cmd = `${this.mpqcliPath} create -v ${version} "${dirName}"`;
|
||||
execSync(cmd, {
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
||||
cwd: workingDir
|
||||
});
|
||||
|
||||
// MPQ is created as directory.mpq in the working directory
|
||||
const createdMpq = path.join(workingDir, dirName + '.mpq');
|
||||
|
||||
// Move to final destination if specified
|
||||
if (outputPath) {
|
||||
const finalPath = path.resolve(outputPath);
|
||||
const finalDir = path.dirname(finalPath);
|
||||
|
||||
// Create output directory if needed
|
||||
if (!require('fs').existsSync(finalDir)) {
|
||||
require('fs').mkdirSync(finalDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Move the MPQ file
|
||||
require('fs').renameSync(createdMpq, finalPath);
|
||||
return finalPath;
|
||||
}
|
||||
|
||||
return createdMpq;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create archive: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to recursively copy a directory
|
||||
* @private
|
||||
*/
|
||||
_copyDirectory(src, dest) {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Create destination directory
|
||||
fs.mkdirSync(dest, { recursive: true });
|
||||
|
||||
// Read directory contents
|
||||
const entries = fs.readdirSync(src, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const srcPath = path.join(src, entry.name);
|
||||
const destPath = path.join(dest, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
this._copyDirectory(srcPath, destPath);
|
||||
} else {
|
||||
fs.copyFileSync(srcPath, destPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for files in an MPQ archive using a pattern
|
||||
* @param {string} mpqFile - Path to the MPQ file
|
||||
* @param {string} pattern - Search pattern
|
||||
* @returns {string[]} Array of matching file paths
|
||||
*/
|
||||
searchFiles(mpqFile, pattern) {
|
||||
try {
|
||||
const files = this.listFiles(mpqFile);
|
||||
return files.filter(file => file.toLowerCase().includes(pattern.toLowerCase()));
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to search files: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add files or directories to an existing MPQ archive
|
||||
* @param {string} mpqFile - Path to the MPQ file
|
||||
* @param {string} sourcePath - Path to the file or directory to add
|
||||
* @param {string} [targetPath] - Optional path within the MPQ where the file/directory should be placed
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
addToArchive(mpqFile, sourcePath, targetPath = '') {
|
||||
try {
|
||||
const absoluteMpqPath = path.resolve(mpqFile);
|
||||
const absoluteSourcePath = path.resolve(sourcePath);
|
||||
|
||||
let cmd = `${this.mpqcliPath} add "${absoluteMpqPath}" "${absoluteSourcePath}"`;
|
||||
if (targetPath) {
|
||||
cmd += ` -p "${targetPath}"`;
|
||||
}
|
||||
|
||||
execSync(cmd, {
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024 // 10MB buffer
|
||||
});
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to add to archive: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single file to an existing MPQ archive
|
||||
* @param {string} mpqFile - Path to the MPQ file
|
||||
* @param {string} filePath - Path to the file to add
|
||||
* @param {string} [targetPath] - Path within the MPQ where the file should be placed
|
||||
* @returns {boolean} Success status
|
||||
*/
|
||||
addFile(mpqFile, filePath, targetPath = null) {
|
||||
try {
|
||||
const fs = require('fs');
|
||||
const absoluteMpqPath = path.resolve(mpqFile);
|
||||
const absoluteFilePath = path.resolve(filePath);
|
||||
|
||||
// Create a temporary directory
|
||||
const tempDir = path.join(require('os').tmpdir(), 'mpq-tool-' + Date.now());
|
||||
fs.mkdirSync(tempDir, { recursive: true });
|
||||
|
||||
// Extract current MPQ contents
|
||||
console.log('Extracting current MPQ contents...');
|
||||
this.extractAll(absoluteMpqPath, tempDir);
|
||||
|
||||
// Copy new file to temp directory
|
||||
// Normalize path separators for MPQ
|
||||
const finalPath = (targetPath || path.basename(absoluteFilePath))
|
||||
.split(/[/\\]/) // Split on both forward and back slashes
|
||||
.join('\\'); // Join with backslashes
|
||||
const targetFilePath = path.join(tempDir, finalPath);
|
||||
|
||||
// Create parent directories if needed
|
||||
fs.mkdirSync(path.dirname(targetFilePath), { recursive: true });
|
||||
|
||||
// Copy the file
|
||||
fs.copyFileSync(absoluteFilePath, targetFilePath);
|
||||
|
||||
// Create new MPQ with all files
|
||||
console.log('Creating new MPQ with added file...');
|
||||
const tempMpq = path.join(require('os').tmpdir(), 'temp.mpq');
|
||||
this.createArchive(tempDir, 2, tempMpq);
|
||||
|
||||
// Replace original MPQ
|
||||
fs.renameSync(tempMpq, absoluteMpqPath);
|
||||
|
||||
// Clean up
|
||||
fs.rmSync(tempDir, { recursive: true, force: true });
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to add file: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MPQTool;
|
||||
1
mpqcli
Submodule
1
mpqcli
Submodule
Submodule mpqcli added at 2dd551cbdc
88
package-lock.json
generated
Normal file
88
package-lock.json
generated
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"name": "mpq-tool",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mpq-tool",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"stormlib-node": "^1.3.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "11.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
|
||||
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
|
||||
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stormlib-node": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/stormlib-node/-/stormlib-node-1.3.6.tgz",
|
||||
"integrity": "sha512-LBLo1fzTRd+KOAZUmsWhKNHf8gOJ+YEiu7GTXNuXE5jWXk5abdFQOpOz1FYxW+fDXdnq9sD/t2XyQqA9SJiCJw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fs-extra": "^11.1.1",
|
||||
"node-addon-api": "^6.1.0",
|
||||
"typescript": "^5.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.7.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
|
||||
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
package.json
Normal file
46
package.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "@araxiaonline/mpq-tools-osx",
|
||||
"version": "1.0.0",
|
||||
"description": "Node.js wrapper for MPQ archive manipulation for MacOSX using mpqcli",
|
||||
"main": "lib/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "node scripts/build.js",
|
||||
"prepare": "npm run build",
|
||||
"install": "node scripts/build.js",
|
||||
"postinstall": "cd mpqcli && cmake -B build && cmake --build build",
|
||||
"publish": "npm publish --access public"
|
||||
},
|
||||
"keywords": [
|
||||
"mpq",
|
||||
"wow",
|
||||
"warcraft",
|
||||
"archive",
|
||||
"stormlib"
|
||||
],
|
||||
"author": "ben-of-codecraft",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/araxiaonline/mpq-tools-osx"
|
||||
},
|
||||
"files": [
|
||||
"lib/",
|
||||
"bin/",
|
||||
"mpqcli/",
|
||||
"scripts/",
|
||||
"README.md"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"os": [
|
||||
"darwin",
|
||||
"linux",
|
||||
"win32"
|
||||
],
|
||||
"cpu": [
|
||||
"x64",
|
||||
"arm64"
|
||||
]
|
||||
}
|
||||
42
scripts/build.js
Normal file
42
scripts/build.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const { execSync } = require('child_process');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
|
||||
// Get platform-specific information
|
||||
const platform = os.platform();
|
||||
const arch = os.arch();
|
||||
|
||||
// Define the build directory
|
||||
const buildDir = path.join(__dirname, '..', 'bin', `${platform}-${arch}`);
|
||||
|
||||
// Create the build directory if it doesn't exist
|
||||
if (!fs.existsSync(buildDir)) {
|
||||
fs.mkdirSync(buildDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Build mpqcli
|
||||
console.log(`Building mpqcli for ${platform}-${arch}...`);
|
||||
|
||||
try {
|
||||
// Navigate to mpqcli directory
|
||||
const mpqcliDir = path.join(__dirname, '..', 'mpqcli');
|
||||
process.chdir(mpqcliDir);
|
||||
|
||||
// Build using CMake
|
||||
execSync('cmake -B build', { stdio: 'inherit' });
|
||||
execSync('cmake --build build', { stdio: 'inherit' });
|
||||
|
||||
// Copy the binary to the platform-specific directory
|
||||
const binaryName = platform === 'win32' ? 'mpqcli.exe' : 'mpqcli';
|
||||
const binaryPath = path.join('build', 'bin', binaryName);
|
||||
const targetPath = path.join(buildDir, binaryName);
|
||||
|
||||
fs.copyFileSync(binaryPath, targetPath);
|
||||
fs.chmodSync(targetPath, 0o755); // Make executable
|
||||
|
||||
console.log(`Successfully built mpqcli and copied to ${targetPath}`);
|
||||
} catch (error) {
|
||||
console.error('Failed to build mpqcli:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user