Files
cc-3-8-x-mcp/cli/src/id.js
T
furao 14c5b00f14 Initial public release: cc-3-8-x-mcp
Cocos Creator 3.8.x MCP bridge extension with a built-in offline CLI.

Components:
- Editor extension: in-process MCP server exposing scene / asset-db /
  preview / local / editor-process-control tools
- stdio router: aggregates multiple editor instances on one machine,
  with shortName dedup
- offline CLI (cocos-mcp-cli): headless prefab read/write + a wrapper
  around the Cocos CLI build

Pure Node.js, zero third-party dependencies. Licensed under Apache-2.0.
2026-06-06 11:33:19 +08:00

98 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// 确定性 UUID / fileId 生成器(纯 CJS,零三方依赖)
// 与 tools/fgui2cc3/src/utils/DeterministicId.ts byte-for-byte 对齐
// ============================================================
'use strict';
const { createHash } = require('node:crypto');
/**
* 基于种子字符串生成确定性 UUID v4 格式
* 使用 SHA-256 哈希前 16 字节,设置 version=4 和 variant=RFC4122
* @param {string} seed
* @returns {string}
*/
function deterministicUUID(seed) {
const hash = createHash('sha256').update(seed).digest();
// 设置 version (4) 和 variant (RFC 4122)
hash[6] = (hash[6] & 0x0f) | 0x40;
hash[8] = (hash[8] & 0x3f) | 0x80;
const hex = hash.subarray(0, 16).toString('hex');
return [
hex.slice(0, 8),
hex.slice(8, 12),
hex.slice(12, 16),
hex.slice(16, 20),
hex.slice(20, 32),
].join('-');
}
/**
* 基于种子字符串生成确定性 fileId(CC3 使用 base64 编码的 16 字节)
* @param {string} seed
* @returns {string}
*/
function deterministicFileId(seed) {
const hash = createHash('sha256').update(seed).digest();
return hash.subarray(0, 16).toString('base64').replace(/=+$/, '');
}
/**
* 创建一个带自增计数器的 fileId 生成器
* 同一组件内每个节点/组件使用递增的序号保证唯一性和稳定性
* @param {string} baseSeed
* @returns {() => string}
*/
function createFileIdGenerator(baseSeed) {
let counter = 0;
return () => deterministicFileId(`${baseSeed}#fid#${counter++}`);
}
// ============================================================
// Cocos Creator 压缩 classId 编解码
// 标准 base64A-Z a-z 0-9 + /),前 5 hex 保留,每 3 hex → 2 base64
// 产物格式:23 字符 = 5 hex + 18 base64
// ============================================================
const _BASE64_STD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
/**
* 把 32/36 位 uuid 压缩为 Cocos ccclass id23 字符)。
*
* @param {string} uuid 标准 uuid(含或不含 dash
* @returns {string} 23 字符压缩 classId
*/
function compressUuid(uuid) {
if (typeof uuid !== 'string') {
throw new Error(`compressUuid: uuid 必须是字符串,收到 ${typeof uuid}`);
}
const hex = uuid.replace(/-/g, '').toLowerCase();
if (!/^[0-9a-f]{32}$/.test(hex)) {
throw new Error(`compressUuid: 输入不是合法 uuid${uuid}`);
}
let out = hex.slice(0, 5);
for (let i = 5; i < 32; i += 3) {
const code = parseInt(hex.substr(i, 3), 16);
out += _BASE64_STD[(code >> 6) & 0x3f];
out += _BASE64_STD[code & 0x3f];
}
return out;
}
/**
* 判断字符串是否是 Cocos 压缩 classId 格式(23 字符,前 5 hex + 后 18 base64)。
* 不做语义合法性校验(不查 classId 是否对应真实类)。
*/
function isCompressedClassId(str) {
return typeof str === 'string' && /^[0-9a-f]{5}[A-Za-z0-9+/]{18}$/.test(str);
}
module.exports = {
deterministicUUID,
deterministicFileId,
createFileIdGenerator,
compressUuid,
isCompressedClassId,
};