| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- "use strict";
- var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.ensureDir = ensureDir;
- exports.parseDetailUrl = parseDetailUrl;
- exports.downloadFile = downloadFile;
- exports.xorDecryptBuffer = xorDecryptBuffer;
- exports.getCreativeAssetsDir = getCreativeAssetsDir;
- exports.getBuildOutputDir = getBuildOutputDir;
- exports.scanAssetFiles = scanAssetFiles;
- const fs_1 = __importDefault(require("fs"));
- const path_1 = __importDefault(require("path"));
- const https_1 = __importDefault(require("https"));
- const http_1 = __importDefault(require("http"));
- function ensureDir(dir) {
- if (!fs_1.default.existsSync(dir)) {
- fs_1.default.mkdirSync(dir, { recursive: true });
- }
- }
- /**
- * 从填色详情页 URL 中提取素材 ID 并拼接 zip 下载地址。
- *
- * 输入:https://color2.jccytech.cn/app/zh/pages/detail/6a154397957ac783bac98e10
- * 输出:https://color2.jccytech.cn/zips/v2/number_mini/1501/6a154397957ac783bac98e10.zip
- */
- function parseDetailUrl(detailUrl) {
- try {
- const url = new URL(detailUrl);
- // 取路径最后一段作为 ID
- const segments = url.pathname.split("/").filter(Boolean);
- const id = segments[segments.length - 1];
- if (!id || id.length < 20)
- return null;
- const zipUrl = `https://color2.jccytech.cn/zips/v2/number_mini/1501/${id}.zip`;
- return { id, zipUrl };
- }
- catch {
- return null;
- }
- }
- /**
- * 下载远程文件到 Buffer
- */
- function downloadFile(url) {
- return new Promise((resolve, reject) => {
- const client = url.startsWith("https") ? https_1.default : http_1.default;
- client.get(url, (res) => {
- if (res.statusCode !== 200) {
- reject(new Error(`Download failed: HTTP ${res.statusCode}`));
- return;
- }
- const chunks = [];
- res.on("data", (chunk) => chunks.push(chunk));
- res.on("end", () => resolve(Buffer.concat(chunks)));
- res.on("error", reject);
- }).on("error", reject);
- });
- }
- /**
- * XOR 解密 zip 文件。
- *
- * 密钥 = 文件名(不含扩展名),即素材 ID。
- * 对整个文件逐字节异或解密,密钥循环使用。
- */
- function xorDecryptBuffer(encrypted, key) {
- const keyBuf = Buffer.from(key);
- const keyLen = keyBuf.length;
- const decrypted = Buffer.alloc(encrypted.length);
- for (let i = 0; i < encrypted.length; i++) {
- decrypted[i] = encrypted[i] ^ keyBuf[i % keyLen];
- }
- return decrypted;
- }
- function getCreativeAssetsDir(storageDir, creativeId) {
- const dir = path_1.default.join(storageDir, "creatives", creativeId, "assets");
- return dir;
- }
- function getBuildOutputDir(storageDir, creativeId, buildId) {
- const dir = path_1.default.join(storageDir, "creatives", creativeId, "builds", buildId);
- ensureDir(dir);
- return dir;
- }
- function scanAssetFiles(assetsDir) {
- const result = { config: false, page: false, map: false, special: null };
- if (!fs_1.default.existsSync(assetsDir))
- return result;
- const files = fs_1.default.readdirSync(assetsDir);
- for (const file of files) {
- const lower = file.toLowerCase();
- if (lower === "config.json")
- result.config = true;
- else if (lower === "page.png" || lower === "page.jpg" || lower === "page.jpeg")
- result.page = true;
- else if (lower === "map.png")
- result.map = true;
- else if (lower.startsWith("special."))
- result.special = file;
- }
- return result;
- }
- //# sourceMappingURL=storageService.js.map
|