198 lines
7.5 KiB
JavaScript
198 lines
7.5 KiB
JavaScript
import {dest, series, src} from 'gulp';
|
|
import process from 'node:process';
|
|
import replace from 'gulp-replace';
|
|
import jsonModify from 'gulp-json-modify';
|
|
import {subtle} from 'node:crypto';
|
|
import * as dartSass from 'sass';
|
|
import gulpSass from 'gulp-sass';
|
|
import {deleteAsync} from 'del';
|
|
import {readdirSync, readFileSync, writeFileSync, rmdirSync, existsSync, mkdirSync, statSync} from "fs";
|
|
import {join} from 'node:path';
|
|
|
|
import {compilePack} from '@foundryvtt/foundryvtt-cli';
|
|
|
|
const sass = gulpSass(dartSass);
|
|
|
|
|
|
/**
|
|
* Generate a random alphanumeric string ID of a given requested length using `crypto.getRandomValues()`.
|
|
* @param {string} reference The reference which should be used to generate a semi random ID
|
|
* @param {number} length The length of the random string to generate, which must be at most 16384.
|
|
* @returns {string} A string containing random letters (A-Z, a-z) and numbers (0-9).
|
|
*/
|
|
function randomID(reference = "", length = 16) {
|
|
const encoder = new TextEncoder();
|
|
const data = encoder.encode(reference);
|
|
return subtle.digest('SHA-256', data).then(hashBuffer => {
|
|
// Step 2: Convert the hash to a Base62 string
|
|
const base62Chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
const hashArray = new Uint8Array(hashBuffer);
|
|
let num = BigInt(0);
|
|
|
|
// Convert hash buffer to a BigInt
|
|
for (let byte of hashArray) {
|
|
num = (num << BigInt(8)) | BigInt(byte);
|
|
}
|
|
|
|
let base62Id = '';
|
|
while (num > 0) {
|
|
const remainder = num % BigInt(62);
|
|
base62Id = base62Chars[Number(remainder)] + base62Id;
|
|
num = num / BigInt(62);
|
|
}
|
|
|
|
// Step 3: Return the first 16 characters
|
|
return base62Id.slice(-length);
|
|
});
|
|
}
|
|
|
|
const convert = async function (from, to, ofType, overwrite = true) {
|
|
|
|
const SOURCE = from;
|
|
const DEST = to;
|
|
const TYPE = ofType;
|
|
|
|
if (overwrite) {
|
|
try {
|
|
rmdirSync(DEST, {force: true, recursive: true})
|
|
} catch (e) {
|
|
}
|
|
mkdirSync(DEST)
|
|
}
|
|
|
|
const filewalker = async (source) => {
|
|
console.debug("entering directory", source);
|
|
for (let file of readdirSync(source)) {
|
|
if (statSync(join(source, file)).isDirectory()) {
|
|
await filewalker(join(source, file));
|
|
} else {
|
|
console.debug("processing file", join(source, file))
|
|
let originalSource = JSON.parse(readFileSync(join(source, file), {encoding: "utf8"}));
|
|
let id = await randomID("DSA_4-1" + TYPE + originalSource.name.trim())
|
|
|
|
let targetSource = {
|
|
_id: id,
|
|
_key: "!items!" + id,
|
|
type: TYPE,
|
|
img: originalSource.image,
|
|
name: originalSource.name.trim(),
|
|
system: {...originalSource},
|
|
}
|
|
delete targetSource.system.image;
|
|
let target = JSON.stringify(targetSource, null, 2);
|
|
let newFileName = "./" + join(DEST, id + ".json");
|
|
writeFileSync(newFileName, target, {encoding: "utf8"});
|
|
}
|
|
}
|
|
}
|
|
|
|
return await filewalker(SOURCE)
|
|
}
|
|
|
|
function cleanDist() {
|
|
return deleteAsync(['dist/**']);
|
|
}
|
|
|
|
function buildStyles() {
|
|
return src('src/style/**/*.scss')
|
|
.pipe(sass().on('error', sass.logError))
|
|
.pipe(dest('dist/style/'))
|
|
}
|
|
|
|
function copySource() {
|
|
return src(['src/**/*', '!src/assets/**/*', '!src/style/**/*.scss', '!src/packs/**/*'])
|
|
.pipe(dest('dist/'));
|
|
}
|
|
|
|
function copyAssets() {
|
|
return src(['src/assets/**/*'], {encoding: false})
|
|
.pipe(dest('dist/assets/'))
|
|
}
|
|
|
|
function updateManifestFile() {
|
|
return src('src/system.json')
|
|
.pipe(
|
|
jsonModify({
|
|
key: "version",
|
|
value: process.env.VERSION
|
|
})
|
|
)
|
|
.pipe(
|
|
jsonModify({
|
|
key: "download",
|
|
value: "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/{{VERSION}}/release.zip".replace("{{VERSION}}", process.env.VERSION)
|
|
})
|
|
)
|
|
.pipe(dest('src/'))
|
|
}
|
|
|
|
async function prepareDB() {
|
|
|
|
try {
|
|
if (!existsSync("./src/packs/__source")) {
|
|
mkdirSync("./src/packs/__source");
|
|
}
|
|
|
|
convert("./src/packs/_source/talente", "./src/packs/__source/talente", "Skill");
|
|
convert("./src/packs/_source/zauber", "./src/packs/__source/zauber", "Spell");
|
|
convert("./src/packs/_source/vorteile", "./src/packs/__source/vorteile", "Advantage");
|
|
convert("./src/packs/_source/nachteile", "./src/packs/__source/vorteile", "Advantage", false);
|
|
convert("./src/packs/_source/sonderfertigkeiten", "./src/packs/__source/sonderfertigkeiten", "SpecialAbility");
|
|
convert("./src/packs/_source/waehrungen", "./src/packs/__source/waehrungen", "Equipment");
|
|
convert("./src/packs/_source/Gegenstaende/Waffen", "./src/packs/__source/Waffen", "Equipment");
|
|
convert("./src/packs/_source/Gegenstaende/Munition", "./src/packs/__source/Munition", "Equipment");
|
|
convert("./src/packs/_source/Gegenstaende/Ruestzeug", "./src/packs/__source/Ruestzeug", "Equipment");
|
|
convert("./src/packs/_source/Gegenstaende/Behaelter", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/Gegenstaende/Bekleidung", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/Gegenstaende/Beleuchtung", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/Gegenstaende/Buecher", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/Gegenstaende/Essutensilien", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/Gegenstaende/Sonstiges", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/Gegenstaende/Werkzeug", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/Gegenstaende/Seile", "./src/packs/__source/Gegenstaende", "Equipment", false);
|
|
convert("./src/packs/_source/liturgien-und-segnungen", "./src/packs/__source/liturgien", "Liturgy");
|
|
convert("./src/packs/_source/wunden", "./src/packs/__source/wunden", "ActiveEffect");
|
|
|
|
convert("./src/packs/_source/kulturen", "./src/packs/__source/kulturen", "Culture");
|
|
convert("./src/packs/_source/spezien", "./src/packs/__source/spezien", "Species");
|
|
convert("./src/packs/_source/professionen", "./src/packs/__source/professionen", "Profession");
|
|
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
}
|
|
|
|
function buildDB() {
|
|
// Determine which source folders to process
|
|
|
|
const PACK_SRC = "src/packs/__source"
|
|
const PACK_DEST = "dist/packs/"
|
|
|
|
return new Promise(async (resolve, reject) => {
|
|
const folders = readdirSync(PACK_SRC, {withFileTypes: true}).filter(file =>
|
|
file.isDirectory()
|
|
);
|
|
|
|
for (const folder of folders) {
|
|
const src = join(PACK_SRC, folder.name);
|
|
const dest = join(PACK_DEST, folder.name);
|
|
console.info(`Compiling pack ${folder.name}`);
|
|
await compilePack(src, dest, {recursive: true, nedb: false});
|
|
|
|
}
|
|
resolve()
|
|
})
|
|
}
|
|
|
|
|
|
export default series(
|
|
cleanDist,
|
|
updateManifestFile,
|
|
copySource,
|
|
copyAssets,
|
|
buildStyles,
|
|
prepareDB,
|
|
buildDB
|
|
)
|