Files
zkldi_Tachi/database-seeds/scripts/util.js
T

139 lines
3.1 KiB
JavaScript

const fs = require("fs");
const path = require("path");
const DeterministicCollectionSort = require("./deterministic-collection-sort");
const crypto = require("crypto");
const fjsh = require("fast-json-stable-hash");
function IterateCollections(cb) {
for (const collection of fs.readdirSync(COLLECTIONS_DIR)) {
const data = cb(
JSON.parse(fs.readFileSync(path.join(COLLECTIONS_DIR, collection))),
collection
);
fs.writeFileSync(path.join(COLLECTIONS_DIR, collection), JSON.stringify(data, null, "\t"));
}
DeterministicCollectionSort();
}
const COLLECTIONS_DIR = path.join(__dirname, "../collections");
function ReadCollection(name, throwIfNotFound = false) {
const p = path.join(COLLECTIONS_DIR, name);
if (!fs.existsSync(p)) {
if (throwIfNotFound) {
throw new Error(`No collection ${name} exists.`);
}
fs.writeFileSync(p, JSON.stringify([]));
return [];
}
return JSON.parse(fs.readFileSync(p));
}
function WriteCollection(name, data) {
fs.writeFileSync(path.join(COLLECTIONS_DIR, name), JSON.stringify(data, null, "\t"));
DeterministicCollectionSort();
}
function MutateCollection(name, cb) {
const data = cb(ReadCollection(name));
WriteCollection(name, data);
}
function CreateChartID() {
return crypto.randomBytes(20).toString("hex");
}
function CreateFolderID(query, game, playtype) {
return `F${fjsh.hash(Object.assign({ game, playtype }, query), "SHA256")}`;
}
// quick inplace deepmerge hack
// probably doesn't work for arrays, i don't care though.
function EfficientInPlaceDeepmerge(ref, apply) {
for (const key in apply) {
if (typeof apply[key] === "object" && apply[key]) {
EfficientInPlaceDeepmerge(ref[key], apply[key]);
} else {
ref[key] = apply[key];
}
}
}
function AddSupportForBMSTable(header, game, playtype, tableName, tableID, tableDescription) {
const folders = [];
const symbol = header.symbol;
for (const level of header.level_order) {
const f = {
title: `${symbol}${level}`,
playtype,
game,
searchTerms: [],
type: "charts",
data: {
"data¬tableFolders": {
"~elemMatch": {
level: level.toString(),
table: symbol,
},
},
},
inactive: false,
};
const folderID = CreateFolderID(f);
f.folderID = folderID;
folders.push(f);
}
MutateCollection("folders.json", (f) => {
f.push(...folders);
return f;
});
MutateCollection("tables.json", (t) => {
t.push({
folders: folders.map((e) => e.folderID),
game,
playtype,
inactive: false,
description: tableDescription,
title: tableName,
tableID: tableID,
});
return t;
});
}
/**
* Given a game, reads the songs-${game}.json collection, gets the largest song ID, and
* returns a generator that will give an unused songID when called.
*
* Not thread safe.
*/
function GetFreshScoreIDGenerator(game) {
let maxSongID = ReadCollection(`songs-${game}.json`).sort((a, b) => b.id - a.id)[0].id;
return () => ++maxSongID;
}
module.exports = {
IterateCollections,
MutateCollection,
CreateChartID,
CreateFolderID,
ReadCollection,
WriteCollection,
EfficientInPlaceDeepmerge,
AddSupportForBMSTable,
GetFreshScoreIDGenerator,
};