forked from phenom/healer-man
Release Healer Man 0.1.29
This commit is contained in:
1 parent
8c9809d3e0
commit
544c1bee91
120 files changed
+4363
-1036
No files matched your search
@@ -1,7 +1,5 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import {
|
||||
constants,
|
||||
copyFile,
|
||||
mkdir,
|
||||
readFile,
|
||||
readdir,
|
||||
@@ -11,6 +9,7 @@ import {
|
||||
} from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { prepareContentObjects } from "./content-objects.mjs";
|
||||
|
||||
const SCRIPT_DIRECTORY = path.dirname(fileURLToPath(import.meta.url));
|
||||
export const PROJECT_ROOT = path.resolve(SCRIPT_DIRECTORY, "../..");
|
||||
@@ -190,7 +189,7 @@ export async function scanContentSources(sources = DEFAULT_CONTENT_SOURCES) {
|
||||
|
||||
function contentVersion(files, packs) {
|
||||
const digest = createHash("sha256");
|
||||
for (const file of files) digest.update(`${file.logicalPath}\0${file.sha256}\0${file.bytes}\n`);
|
||||
for (const file of files) digest.update(`${file.logicalPath}\0${file.sha256}\0${file.bytes}\0${JSON.stringify(file.download ?? null)}\n`);
|
||||
for (const pack of packs) {
|
||||
digest.update(`pack\0${pack.id}\0${pack.label}\0${pack.bundledOnAndroid}\0${pack.dependencies.join(",")}\n`);
|
||||
}
|
||||
@@ -305,6 +304,7 @@ export function createContentManifest(files, options = {}) {
|
||||
url: `${baseUrl}/${encodeUrlPath(objectName)}`,
|
||||
sha256: file.sha256,
|
||||
bytes: file.bytes,
|
||||
...(file.download ? { download: file.download } : {}),
|
||||
};
|
||||
const pack = packs.get(file.packId) ?? {
|
||||
id: file.packId,
|
||||
@@ -351,6 +351,11 @@ export function createContentManifest(files, options = {}) {
|
||||
}
|
||||
|
||||
const sortedPacks = [...packs.values()].sort((left, right) => left.id.localeCompare(right.id));
|
||||
for (const pack of sortedPacks) {
|
||||
const objects = new Map(files.filter((file) => file.packId === pack.id)
|
||||
.map((file) => [file.sha256, file.download?.bytes ?? file.bytes]));
|
||||
pack.downloadBytes = [...objects.values()].reduce((sum, bytes) => sum + bytes, 0);
|
||||
}
|
||||
const version = options.version ?? contentVersion(files, sortedPacks);
|
||||
|
||||
return {
|
||||
@@ -420,24 +425,6 @@ export function assertCampaignDungeonManifest(manifest, definitions) {
|
||||
}
|
||||
}
|
||||
|
||||
async function copyObjectIfMissing(file, objectDirectory) {
|
||||
const objectName = `${file.sha256}${file.extension}`;
|
||||
const destination = path.join(objectDirectory, objectName);
|
||||
try {
|
||||
const destinationStats = await stat(destination);
|
||||
if (destinationStats.size !== file.bytes) throw new Error(`Published object has the wrong size: ${destination}`);
|
||||
return false;
|
||||
} catch (error) {
|
||||
if (error?.code !== "ENOENT") throw error;
|
||||
}
|
||||
try {
|
||||
await copyFile(file.sourcePath, destination, constants.COPYFILE_EXCL);
|
||||
} catch (error) {
|
||||
if (error?.code !== "EEXIST") throw error;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function replaceJsonAtomically(destination, value) {
|
||||
const temporary = `${destination}.${process.pid}.${Date.now()}.tmp`;
|
||||
await writeFile(temporary, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
||||
@@ -456,22 +443,24 @@ export async function publishContent(options = {}) {
|
||||
...campaignPackDefinitions,
|
||||
...(options.packDefinitions ?? []),
|
||||
];
|
||||
const manifest = createContentManifest(files, { ...options, packDefinitions });
|
||||
if (campaignDefinitions) assertCampaignDungeonManifest(manifest, campaignDefinitions);
|
||||
if (campaignDefinitions) assertCampaignDungeonManifest(createContentManifest(files, { ...options, packDefinitions }), campaignDefinitions);
|
||||
|
||||
const objectDirectory = path.join(contentDirectory, "objects");
|
||||
const manifestDirectory = path.join(contentDirectory, "manifests");
|
||||
await mkdir(objectDirectory, { recursive: true });
|
||||
await mkdir(manifestDirectory, { recursive: true });
|
||||
let copiedObjects = 0;
|
||||
for (const file of files) {
|
||||
if (await copyObjectIfMissing(file, objectDirectory)) copiedObjects += 1;
|
||||
}
|
||||
const prepared = await prepareContentObjects(files, {
|
||||
directory: objectDirectory,
|
||||
baseUrl: String(options.baseUrl ?? "/content/objects").replace(/\/+$/, ""),
|
||||
keepOriginal: true,
|
||||
});
|
||||
const manifest = createContentManifest(prepared.files, { ...options, packDefinitions });
|
||||
await replaceJsonAtomically(path.join(manifestDirectory, `${manifest.version}.json`), manifest);
|
||||
await replaceJsonAtomically(path.join(contentDirectory, "manifest.json"), manifest);
|
||||
return {
|
||||
contentDirectory,
|
||||
copiedObjects,
|
||||
copiedObjects: prepared.writtenObjects,
|
||||
storage: { logicalBytes: prepared.logicalBytes, uniqueBytes: prepared.uniqueBytes, storedBytes: prepared.storedBytes },
|
||||
manifest,
|
||||
campaignDungeonPackCount: campaignDefinitions?.length ?? 0,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user