fix:修复bug
This commit is contained in:
93
server.js
93
server.js
@@ -30,6 +30,90 @@ async function writeDb(list) {
|
||||
await fs.writeFile(DB_PATH, JSON.stringify(list, null, 2), "utf8");
|
||||
}
|
||||
|
||||
function extractFunctionSection(code) {
|
||||
const endMarker = code.indexOf("void ANGLE__0_main");
|
||||
const end = endMarker >= 0 ? endMarker : code.length;
|
||||
const firstFn = code.search(
|
||||
/(metal::float[234](x2)?|float|void)\s+[A-Za-z_][A-Za-z0-9_]*\s*\([^)]*\)\s*\{/m
|
||||
);
|
||||
if (firstFn < 0 || firstFn >= end) return "";
|
||||
return code.slice(firstFn, end);
|
||||
}
|
||||
|
||||
function convertAngleMetalToGlsl(code) {
|
||||
let section = extractFunctionSection(code);
|
||||
if (!section || !section.includes("_umainImage")) return "";
|
||||
|
||||
section = section
|
||||
.replace(
|
||||
/void _umainImage\s*\(\s*constant ANGLE_UserUniforms\s*&\s*ANGLE_userUniforms\s*,\s*thread metal::float4\s*&\s*([A-Za-z0-9_]+)\s*,\s*metal::float2\s*([A-Za-z0-9_]+)\s*\)/g,
|
||||
"void _umainImage(out vec4 $1, vec2 $2)"
|
||||
)
|
||||
.replace(
|
||||
/float _umap\s*\(\s*constant ANGLE_UserUniforms\s*&\s*ANGLE_userUniforms\s*,\s*metal::float3\s*([A-Za-z0-9_]+)\s*\)/g,
|
||||
"float _umap(vec3 $1)"
|
||||
)
|
||||
.replace(
|
||||
/metal::float4 _urm\s*\(\s*constant ANGLE_UserUniforms\s*&\s*ANGLE_userUniforms\s*,\s*metal::float3\s*([A-Za-z0-9_]+)\s*,\s*metal::float3\s*([A-Za-z0-9_]+)\s*\)/g,
|
||||
"vec4 _urm(vec3 $1, vec3 $2)"
|
||||
)
|
||||
.replace(/_umap\s*\(\s*ANGLE_userUniforms\s*,/g, "_umap(")
|
||||
.replace(/_urm\s*\(\s*ANGLE_userUniforms\s*,/g, "_urm(")
|
||||
.replace(/ANGLE_userUniforms\._uiResolution/g, "iResolution")
|
||||
.replace(/ANGLE_userUniforms\._uiTime/g, "iTime")
|
||||
.replace(/metal::fast::normalize/g, "normalize")
|
||||
.replace(/metal::/g, "")
|
||||
.replace(/\bthread\b/g, "")
|
||||
.replace(/\bconstant\b/g, "")
|
||||
.replace(/\buint32_t\b/g, "uint")
|
||||
.replace(/;\s*;/g, ";");
|
||||
|
||||
const cleaned = [
|
||||
"void ANGLE_loopForwardProgress() {}",
|
||||
section,
|
||||
"void mainImage(out vec4 fragColor, in vec2 fragCoord) { _umainImage(fragColor, fragCoord); }",
|
||||
].join("\n");
|
||||
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
function normalizeIncomingCode(code) {
|
||||
if (!code || typeof code !== "string") return { error: "code 不能为空", normalized: "" };
|
||||
if (code.includes("metal::") || code.includes("[[function_constant")) {
|
||||
const converted = convertAngleMetalToGlsl(code);
|
||||
if (!converted) {
|
||||
return { error: "自动解构失败:请检查粘贴内容是否完整。", normalized: "" };
|
||||
}
|
||||
return { error: "", normalized: converted };
|
||||
}
|
||||
if (!code.includes("mainImage")) {
|
||||
return { error: "code 必须包含 mainImage", normalized: "" };
|
||||
}
|
||||
return { error: "", normalized: code };
|
||||
}
|
||||
|
||||
async function autoNormalizeStoredShaders() {
|
||||
const shaders = await readDb();
|
||||
let changed = false;
|
||||
const next = shaders.map((item) => {
|
||||
const code = String(item.code || "");
|
||||
if (code.includes("metal::") || code.includes("[[function_constant")) {
|
||||
const { error, normalized } = normalizeIncomingCode(code);
|
||||
if (!error && normalized) {
|
||||
changed = true;
|
||||
return {
|
||||
...item,
|
||||
code: normalized,
|
||||
updatedAt: new Date().toISOString(),
|
||||
sourceFormat: "angle-metal-auto-converted",
|
||||
};
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
if (changed) await writeDb(next);
|
||||
}
|
||||
|
||||
app.get("/api/shaders", async (_req, res) => {
|
||||
try {
|
||||
const shaders = await readDb();
|
||||
@@ -44,8 +128,9 @@ app.post("/api/shaders", async (req, res) => {
|
||||
if (!name || typeof name !== "string") {
|
||||
return res.status(400).json({ error: "name 必填" });
|
||||
}
|
||||
if (!code || typeof code !== "string" || !code.includes("mainImage")) {
|
||||
return res.status(400).json({ error: "code 必须包含 mainImage" });
|
||||
const { error: parseError, normalized } = normalizeIncomingCode(code);
|
||||
if (parseError) {
|
||||
return res.status(400).json({ error: parseError });
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -54,10 +139,11 @@ app.post("/api/shaders", async (req, res) => {
|
||||
id: crypto.randomUUID(),
|
||||
name: name.trim(),
|
||||
author: String(author || "unknown").trim() || "unknown",
|
||||
code,
|
||||
code: normalized,
|
||||
views: Math.floor(3000 + Math.random() * 22000),
|
||||
likes: Math.floor(40 + Math.random() * 700),
|
||||
createdAt: new Date().toISOString(),
|
||||
sourceFormat: code.includes("metal::") ? "angle-metal-auto-converted" : "glsl",
|
||||
};
|
||||
shaders.unshift(item);
|
||||
await writeDb(shaders);
|
||||
@@ -82,6 +168,7 @@ app.delete("/api/shaders/:id", async (req, res) => {
|
||||
});
|
||||
|
||||
ensureDb().then(() => {
|
||||
autoNormalizeStoredShaders().catch(() => {});
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server running: http://localhost:${PORT}`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user