-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpatch-node-modules.cjs
More file actions
134 lines (118 loc) · 6.3 KB
/
Copy pathpatch-node-modules.cjs
File metadata and controls
134 lines (118 loc) · 6.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env node
// Patches node_modules after npm install.
// Re-run automatically via the "postinstall" script in package.json.
//
// Patches applied:
// 1. @dcl/hammurabi-server — replace all require("@babylonjs/*") with
// globalThis.__BABYLON_*__ so ESM babylon can be preloaded via hammurabi.mjs
// 2. @dcl/sdk-commands — replace npx spawn with local hammurabi.mjs spawn
// so the preloader is always used when running `npm start`
const fs = require('fs')
const path = require('path')
const root = __dirname
// ── 1. Patch hammurabi-server dist files ─────────────────────────────────────
const hamDir = path.join(root, 'node_modules/@dcl/hammurabi-server/dist')
const replacements = [
[/require\(["']@babylonjs\/core["']\)/g, 'globalThis.__BABYLON_CORE__'],
[/require\(["']@babylonjs\/gui["']\)/g, 'globalThis.__BABYLON_GUI__'],
[/require\(["']@babylonjs\/materials["']\)/g, 'globalThis.__BABYLON_MATERIALS__'],
// Must be the full module (not {}), GLTFFileLoader instanceof checks depend on it
[/require\(["']@babylonjs\/loaders.*?["']\)/g,'globalThis.__BABYLON_GLTF__'],
]
function patchDir(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name)
if (entry.isDirectory()) { patchDir(full); continue }
if (!entry.name.endsWith('.js')) continue
let src = fs.readFileSync(full, 'utf8')
let changed = false
for (const [pattern, replacement] of replacements) {
const next = src.replace(pattern, replacement)
if (next !== src) { src = next; changed = true }
}
if (changed) {
fs.writeFileSync(full, src)
console.log(' patched:', path.relative(root, full))
}
}
}
if (fs.existsSync(hamDir)) {
console.log('[postinstall] Patching @dcl/hammurabi-server ...')
patchDir(hamDir)
// ── 1b. Patch colliders.js — fix NullEngine transparent-pass crash ──────────
// colliders.js creates a GridMaterial with opacity=0 for all _collider meshes.
// In Babylon.js, opacity<1 sets needAlphaBlending()=true which puts the mesh
// into the transparent sorted render pass. NullEngine never compiles shaders
// so the material effect is always undefined → setMatrix() crash every frame.
//
// Fix: remove the opacity=0 line — disableColorWrite=true (already set below it)
// achieves the same visual result (invisible mesh) without triggering the
// transparent render path.
const collidersFile = path.join(hamDir, 'lib/babylon/scene/logic/colliders.js')
if (fs.existsSync(collidersFile)) {
let src = fs.readFileSync(collidersFile, 'utf8')
// Match exactly the opacity=0 assignment inside colliderMaterial
if (src.includes('m.opacity = 0;')) {
src = src.replace('m.opacity = 0;', '// m.opacity = 0; // patched: keep opaque so mesh stays out of transparent render pass (NullEngine crash fix)')
fs.writeFileSync(collidersFile, src)
console.log(' patched: colliders.js — removed opacity=0 to prevent NullEngine transparent-pass crash')
} else {
console.log(' colliders.js — opacity=0 line not found (already patched or changed)')
}
} else {
console.warn(' colliders.js not found — skipping collider opacity patch')
}
// Wrap render loop in try/catch so NullEngine _effect=null crash is swallowed.
// NullEngine never compiles shaders so _effect is always null, but the render
// loop still runs (activeCamera is set). _RenderSorted has no isReady() guard
// so it crashes on every opaque mesh render → setMatrix on null effect.
const babylonIndexFile = path.join(hamDir, 'lib/babylon/index.js')
if (fs.existsSync(babylonIndexFile)) {
let src = fs.readFileSync(babylonIndexFile, 'utf8')
if (src.includes('scene.render();') && !src.includes('try {')) {
src = src.replace(
'function renderLoop() {\n if (scene.activeCamera) {\n scene.render();\n }\n }',
'function renderLoop() {\n if (scene.activeCamera) {\n try {\n scene.render();\n } catch (_) {\n // NullEngine: _effect null, swallow setMatrix crash\n }\n }\n }'
)
fs.writeFileSync(babylonIndexFile, src)
console.log(' patched: babylon/index.js — wrapped render loop in try/catch')
} else {
console.log(' babylon/index.js — render loop already patched or changed')
}
}
console.log('[postinstall] hammurabi-server patch done.')
} else {
console.warn('[postinstall] @dcl/hammurabi-server not found — skipping.')
}
// ── 2. Patch sdk-commands hammurabi-server.js ─────────────────────────────────
const sdkCmdFile = path.join(
root,
'node_modules/@dcl/sdk-commands/dist/commands/start/hammurabi-server.js'
)
if (fs.existsSync(sdkCmdFile)) {
console.log('[postinstall] Patching @dcl/sdk-commands ...')
let src = fs.readFileSync(sdkCmdFile, 'utf8')
// Only patch if still in original npx form
if (src.includes("'--yes'") && !src.includes('hammurabi.mjs')) {
// Add path require if missing
if (!src.includes("require(\"path\")") && !src.includes("require('path')")) {
src = src.replace(
"const child_process_1 = require(\"child_process\");",
"const child_process_1 = require(\"child_process\");\nconst path_1 = require(\"path\");"
)
}
// Replace npx spawn block with local hammurabi.mjs spawn
src = src.replace(
/const npxArgs = \[.*?\];[\s\S]*?const hammurabiProcess = npxCliJs[\s\S]*?\);/,
`const env = (0, utils_1.isElectronEnvironment)() ? { ...(0, utils_1.getSpawnEnv)(), npm_config_prefix: workingDir } : (0, utils_1.getSpawnEnv)();
const preloaderPath = (0, path_1.join)(workingDir, 'hammurabi.mjs');
const hammurabiProcess = (0, child_process_1.spawn)(process.execPath, [preloaderPath, \`--realm=\${realm}\`, '--production'], { cwd: workingDir, shell: false, stdio: 'inherit', env });`
)
fs.writeFileSync(sdkCmdFile, src)
console.log('[postinstall] sdk-commands patch done.')
} else {
console.log('[postinstall] sdk-commands already patched — skipping.')
}
} else {
console.warn('[postinstall] @dcl/sdk-commands hammurabi-server.js not found — skipping.')
}