xxscreeps-mod-client 0.3.7 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend.js +40 -8
- package/package.json +2 -2
package/backend.js
CHANGED
|
@@ -90,15 +90,46 @@ function sendFile(ctx, filePath, stat) {
|
|
|
90
90
|
ctx.body = createReadStream(filePath)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
function
|
|
93
|
+
function jsonForScript(value) {
|
|
94
|
+
return JSON.stringify(value).replace(/</g, '\\u003c')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// The client fetches `/api/version` on load (pre-login and again post-connect) to
|
|
98
|
+
// configure itself: welcome text, shards, history settings, and the auth/feature
|
|
99
|
+
// gates. Since the server already has this on hand when it renders index.html, we
|
|
100
|
+
// prefetch it once in-process and inline it as `window.__SCREEPS_BOOTSTRAP__`, so
|
|
101
|
+
// the embedded client is configured from the first frame with zero round-trips.
|
|
102
|
+
// Cached like the client's own 5-min version cache; failures just omit the global
|
|
103
|
+
// and the client falls back to its normal fetch.
|
|
104
|
+
const VERSION_TTL_MS = 5 * 60_000
|
|
105
|
+
let versionCache = null
|
|
106
|
+
|
|
107
|
+
async function bootstrapVersion(ctx) {
|
|
108
|
+
const now = Date.now()
|
|
109
|
+
if (versionCache && now < versionCache.expires) return versionCache.data
|
|
110
|
+
try {
|
|
111
|
+
const origin = `${ctx.protocol}://${ctx.host}`
|
|
112
|
+
const res = await fetch(`${origin}/api/version`)
|
|
113
|
+
if (!res.ok) return null
|
|
114
|
+
const data = await res.json()
|
|
115
|
+
versionCache = { data, expires: now + VERSION_TTL_MS }
|
|
116
|
+
return data
|
|
117
|
+
} catch (err) {
|
|
118
|
+
console.error('[xxscreeps-mod-client] failed to prefetch /api/version for bootstrap:', err)
|
|
119
|
+
return null
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function renderInjectedIndex(filePath, version) {
|
|
94
124
|
const mountDisplay = mountPath === '/' ? '/' : mountPath + '/'
|
|
95
125
|
const baseTag = `<base href="${mountDisplay}">`
|
|
96
|
-
const metadata =
|
|
126
|
+
const metadata = jsonForScript({
|
|
97
127
|
kind: 'xxscreeps-mod',
|
|
98
128
|
packageName: pkg.name,
|
|
99
129
|
version: pkg.version,
|
|
100
|
-
})
|
|
101
|
-
const
|
|
130
|
+
})
|
|
131
|
+
const bootstrap = version ? `;window.__SCREEPS_BOOTSTRAP__=${jsonForScript(version)}` : ''
|
|
132
|
+
const script = `<script>window.__SCREEPS_CLIENT_EMBEDDED__=${metadata}${bootstrap}</script>`
|
|
102
133
|
let html = readFileSync(filePath, 'utf8')
|
|
103
134
|
// Inject base tag first so relative asset URLs resolve from the mount root,
|
|
104
135
|
// not from the current SPA route (e.g. /room/E11N2).
|
|
@@ -106,10 +137,11 @@ function renderInjectedIndex(filePath) {
|
|
|
106
137
|
return html.includes('</head>') ? html.replace('</head>', `${script}</head>`) : html + script
|
|
107
138
|
}
|
|
108
139
|
|
|
109
|
-
function sendInjectedIndex(ctx) {
|
|
140
|
+
async function sendInjectedIndex(ctx) {
|
|
141
|
+
const version = await bootstrapVersion(ctx)
|
|
110
142
|
ctx.type = 'text/html'
|
|
111
143
|
ctx.set('Cache-Control', REVALIDATE_CACHE)
|
|
112
|
-
ctx.body = renderInjectedIndex(indexFile)
|
|
144
|
+
ctx.body = renderInjectedIndex(indexFile, version)
|
|
113
145
|
}
|
|
114
146
|
|
|
115
147
|
// Advertise the server's guest/registration/Steam settings at `/api/version` so
|
|
@@ -156,7 +188,7 @@ hooks.register('middleware', koa => {
|
|
|
156
188
|
}
|
|
157
189
|
|
|
158
190
|
if (relPath === '/' || relPath === '/index.html') {
|
|
159
|
-
sendInjectedIndex(ctx)
|
|
191
|
+
await sendInjectedIndex(ctx)
|
|
160
192
|
return
|
|
161
193
|
}
|
|
162
194
|
|
|
@@ -170,7 +202,7 @@ hooks.register('middleware', koa => {
|
|
|
170
202
|
// Not a real file: claim only the client's own SPA routes (deep links and
|
|
171
203
|
// reloads) with the index shell, and leave every other path to xxscreeps.
|
|
172
204
|
if (isSpaRoute(relPath)) {
|
|
173
|
-
sendInjectedIndex(ctx)
|
|
205
|
+
await sendInjectedIndex(ctx)
|
|
174
206
|
return
|
|
175
207
|
}
|
|
176
208
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xxscreeps-mod-client",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "xxscreeps mod that serves the screeps-client and connects it to the same server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"xxscreeps": true,
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"node": ">=20"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"screeps-client": "^0.
|
|
26
|
+
"screeps-client": "^0.18.0"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"xxscreeps": "*"
|