• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

BunnyNabbit / node-celaria-server / 21610982938

03 Feb 2026 12:04AM UTC coverage: 13.856% (+0.6%) from 13.217%
21610982938

push

github

web-flow
Merge pull request #25 from BunnyNabbit/format-prettier

Format using Prettier

23 of 167 new or added lines in 11 files covered. (13.77%)

3 existing lines in 3 files now uncovered.

235 of 1696 relevant lines covered (13.86%)

0.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.91
/data/cmapLib.js
1
const smartbuffer = require("smart-buffer").SmartBuffer
6✔
2

6✔
3
function parseCelariaMap(buff) {
×
4
        const map = {}
×
5
        buff = smartbuffer.fromBuffer(buff)
×
6
        const magic = buff.readString(11)
×
7
        if (magic === "celaria_map") {
×
8
                map.version = buff.readUInt8() // Version
×
9

×
10
                map.name = buff.readString(buff.readUInt8())
×
11

×
12
                if (map.version == 0) buff.readInt8() // unused byte
×
13

×
14
                map.mode = buff.readUInt8() // unused byte (is it really? it's used in validation inside the server code but not client)
×
15

×
16
                const numCheckpoints = buff.readInt8()
×
17

×
18
                map.medalTimes = []
×
19

×
20
                for (let i = 0; i < numCheckpoints; i++) {
×
21
                        map.medalTimes.push({
×
22
                                platin: buff.readUInt32LE(),
×
23
                                gold: buff.readUInt32LE(),
×
24
                                silver: buff.readUInt32LE(),
×
NEW
25
                                bronze: buff.readUInt32LE(),
×
26
                        })
×
27
                }
×
28

×
29
                map.sunRotationHorizontal = buff.readFloatLE()
×
30
                map.sunRotationVertical = buff.readFloatLE()
×
31

×
32
                map.previewCamFromX = buff.readDoubleLE()
×
33
                map.previewCamFromY = buff.readDoubleLE()
×
34
                map.previewCamFromZ = buff.readDoubleLE()
×
35

×
36
                map.previewCamToX = buff.readDoubleLE()
×
37
                map.previewCamToY = buff.readDoubleLE()
×
38
                map.previewCamToZ = buff.readDoubleLE()
×
39

×
40
                const instanceCount = buff.readUInt32LE()
×
41

×
42
                map.instances = []
×
43

×
44
                for (var i = 0; i < instanceCount; i++) {
×
45
                        const instance = {}
×
46
                        instance.instanceType = buff.readUInt8()
×
47
                        switch (instance.instanceType) {
×
48
                                case 0: // block
×
49
                                        instance.blockType = buff.readUInt8()
×
50
                                        if (map.version == 0) buff.readUInt8() // unused byte
×
51

×
52
                                        if (map.version <= 1) {
×
53
                                                instance.position = {
×
54
                                                        x: buff.readInt32LE() / 10,
×
55
                                                        y: buff.readInt32LE() / 10,
×
NEW
56
                                                        z: buff.readUInt32LE() / 10,
×
57
                                                }
×
58

×
59
                                                instance.scale = {
×
60
                                                        x: buff.readUInt32LE() / 10,
×
61
                                                        y: buff.readUInt32LE() / 10,
×
NEW
62
                                                        z: buff.readUInt32LE() / 10,
×
63
                                                }
×
64
                                        } else {
×
65
                                                instance.position = {
×
66
                                                        x: buff.readDoubleLE(),
×
67
                                                        y: buff.readDoubleLE(),
×
NEW
68
                                                        z: buff.readDoubleLE(),
×
69
                                                }
×
70

×
71
                                                instance.scale = {
×
72
                                                        x: buff.readDoubleLE(),
×
73
                                                        y: buff.readDoubleLE(),
×
NEW
74
                                                        z: buff.readDoubleLE(),
×
75
                                                }
×
76
                                        }
×
77

×
78
                                        instance.rotation = {
×
79
                                                x: 0,
×
80
                                                y: 0,
×
NEW
81
                                                z: buff.readFloatLE(),
×
82
                                        }
×
83

×
84
                                        if (instance.blockType === 5) instance.checkpointId = buff.readUInt8()
×
85
                                        break
×
86

×
87
                                case 1: // Sphere/gem
×
88
                                        if (map.version <= 1) {
×
89
                                                instance.position = {}
×
90
                                                instance.position.x = buff.readInt32LE() / 10
×
91
                                                instance.position.y = buff.readInt32LE() / 10
×
92
                                                if (map.version == 0) {
×
93
                                                        instance.position.z = buff.readInt32LE() / 10
×
94
                                                } else {
×
95
                                                        instance.position.z = buff.readUInt32LE() / 10
×
96
                                                }
×
97
                                        } else {
×
98
                                                instance.position = {
×
99
                                                        x: buff.readDoubleLE(),
×
100
                                                        y: buff.readDoubleLE(),
×
NEW
101
                                                        z: buff.readDoubleLE(),
×
102
                                                }
×
103
                                        }
×
104
                                        break
×
105
                                case 2: // Player spawn
×
106
                                        buff.readUInt8() // unused byte
×
107

×
108
                                        if (map.version <= 1) {
×
109
                                                instance.position = {}
×
110
                                                instance.position.x = buff.readInt32LE() / 10
×
111
                                                instance.position.y = buff.readInt32LE() / 10
×
112
                                                if (map.version == 0) {
×
113
                                                        instance.position.z = buff.readInt32LE() / 10
×
114
                                                } else {
×
115
                                                        instance.position.z = buff.readUInt32LE() / 10
×
116
                                                }
×
117
                                        } else {
×
118
                                                instance.position = {
×
119
                                                        x: buff.readDoubleLE(),
×
120
                                                        y: buff.readDoubleLE(),
×
NEW
121
                                                        z: buff.readDoubleLE(),
×
122
                                                }
×
123
                                        }
×
124

×
125
                                        instance.rotation = {
×
126
                                                x: 0,
×
127
                                                y: 0,
×
NEW
128
                                                z: buff.readFloatLE(),
×
129
                                        }
×
130
                                        break
×
131

×
132
                                case 3: // Barrier (wall)
×
133
                                        buff.readUInt8() // unused byte
×
134

×
135
                                        if (map.version >= 2) {
×
136
                                                instance.position = {
×
137
                                                        x: buff.readInt32LE() / 10,
×
138
                                                        y: buff.readInt32LE() / 10,
×
NEW
139
                                                        z: buff.readUInt32LE() / 10,
×
140
                                                }
×
141

×
142
                                                instance.scale = {
×
143
                                                        x: buff.readUInt32LE() / 10,
×
144
                                                        y: 0,
×
NEW
145
                                                        z: buff.readUInt32LE() / 10,
×
146
                                                }
×
147
                                        } else {
×
148
                                                instance.position = {
×
149
                                                        x: buff.readDoubleLE(),
×
150
                                                        y: buff.readDoubleLE(),
×
NEW
151
                                                        z: buff.readDoubleLE(),
×
152
                                                }
×
153

×
154
                                                instance.scale = {
×
155
                                                        x: buff.readDoubleLE(),
×
156
                                                        y: 0,
×
NEW
157
                                                        z: buff.readDoubleLE(),
×
158
                                                }
×
159
                                        }
×
160

×
161
                                        instance.rotation = {
×
162
                                                x: 0,
×
163
                                                y: 0,
×
NEW
164
                                                z: buff.readFloatLE(),
×
165
                                        }
×
166
                                        break
×
167
                                case 4: // Barrier (floor)
×
168
                                        buff.readUInt8() // unused byte
×
169

×
170
                                        if (map.version >= 2) {
×
171
                                                instance.position = {
×
172
                                                        x: buff.readInt32LE() / 10,
×
173
                                                        y: buff.readInt32LE() / 10,
×
NEW
174
                                                        z: buff.readUInt32LE() / 10,
×
175
                                                }
×
176

×
177
                                                instance.scale = {
×
178
                                                        x: buff.readUInt32LE() / 10,
×
179
                                                        y: buff.readUInt32LE() / 10,
×
NEW
180
                                                        z: 0,
×
181
                                                }
×
182
                                        } else {
×
183
                                                instance.position = {
×
184
                                                        x: buff.readDoubleLE(),
×
185
                                                        y: buff.readDoubleLE(),
×
NEW
186
                                                        z: buff.readDoubleLE(),
×
187
                                                }
×
188

×
189
                                                instance.scale = {
×
190
                                                        x: buff.readDoubleLE(),
×
191
                                                        y: buff.readDoubleLE(),
×
NEW
192
                                                        z: 0,
×
193
                                                }
×
194
                                        }
×
195

×
196
                                        instance.rotation = {
×
197
                                                x: 0,
×
198
                                                y: 0,
×
NEW
199
                                                z: buff.readFloatLE(),
×
200
                                        }
×
201
                                        break
×
202
                                case 128: // Special
×
203
                                        var id = buff.readUInt8()
×
204

×
205
                                        if (map.version <= 1) {
×
206
                                                var xPos = buff.readInt32LE()
×
207
                                                var yPos = buff.readInt32LE()
×
208
                                                var zPos = buff.readUInt32LE()
×
209

×
210
                                                var xScale = buff.readUInt32LE()
×
211
                                                var yScale = buff.readUInt32LE()
×
212
                                                var zScale = buff.readUInt32LE()
×
213
                                        } else {
×
214
                                                var xPos = buff.readDoubleLE()
×
215
                                                var yPos = buff.readDoubleLE()
×
216
                                                var zPos = buff.readDoubleLE()
×
217

×
218
                                                var xScale = buff.readDoubleLE()
×
219
                                                var yScale = buff.readDoubleLE()
×
220
                                                var zScale = buff.readDoubleLE()
×
221
                                        }
×
222

×
223
                                        var rotation = buff.readFloatLE()
×
224
                                        break
×
225

×
226
                                default:
×
227
                                        break
×
228
                        }
×
229
                        map.instances.push(instance)
×
230
                }
×
231
                return map
×
232
        } else {
×
233
                throw "Map provided wasn't a .ecmap"
×
234
        }
×
235
}
×
236

6✔
237
// TODO: Many of the map data to write should be optional and have default values for everything to "just work" if the map alone has no checkpoint data, sun or name and just the map blocks.
6✔
238
function writeCelariaMap(map, version = 3) {
×
239
        // this can modify the original object
×
NEW
240
        if (!map.instances)
×
NEW
241
                map.instances = [
×
NEW
242
                        {
×
NEW
243
                                instanceType: 2,
×
NEW
244
                                position: { x: 0, y: 0, z: 0 },
×
NEW
245
                                rotation: { z: 0 },
×
NEW
246
                        },
×
NEW
247
                ]
×
248

×
249
        output = new smartbuffer()
×
250
        output.writeString("celaria_map")
×
251
        output.writeUInt8(version) // Version
×
252

×
253
        // Might be a temp file on someone's computer never to be normally seen again
×
254
        const mapName = "DELETE_ME" //map.name ?? "DELETE_ME"
×
255
        output.writeUInt8(mapName.length)
×
256
        output.writeString(mapName)
×
257

×
258
        if (version == 0) output.writeUInt8(0) // unused byte
×
259
        output.writeUInt8(1) // Mode byte: Must be 1 for Celaria server (Java) to work. Otherwise doesn't matter
×
260

×
NEW
261
        const numCheckpoints = map.instances.filter((instance) => instance.instanceType === 0 && (instance.blockType === 5 || instance.blockType === 1)).length
×
262
        output.writeUInt8(numCheckpoints)
×
263
        for (let i = 0; i < numCheckpoints; i++) {
×
264
                // Purposefully have impossible to beat times for maps written by cmapLib.js
×
265
                output.writeUInt32LE(1)
×
266
                output.writeUInt32LE(2)
×
267
                output.writeUInt32LE(3)
×
268
                output.writeUInt32LE(4)
×
269
        }
×
270

×
271
        output.writeFloatLE(map.sunRotationHorizontal ?? 40)
×
272
        output.writeFloatLE(map.sunRotationVertical ?? 60)
×
273

×
274
        output.writeDoubleLE(map.previewCamFromX ?? 20)
×
275
        output.writeDoubleLE(map.previewCamFromY ?? 30)
×
276
        output.writeDoubleLE(map.previewCamFromZ ?? 40)
×
277

×
278
        output.writeDoubleLE(map.previewCamToX ?? 200)
×
279
        output.writeDoubleLE(map.previewCamToY ?? 300)
×
280
        output.writeDoubleLE(map.previewCamToZ ?? 200)
×
281

×
282
        output.writeUInt32LE(map.instances.length)
×
283

×
284
        // write data
×
NEW
285
        map.instances.forEach((instance) => {
×
286
                if (!instanceTypeIsSupported(instance.instanceType, version)) return
×
287
                output.writeUInt8(instance.instanceType)
×
288
                switch (instance.instanceType) {
×
289
                        case 0: // block
×
290
                                output.writeUInt8(instance.blockType)
×
291
                                if (version == 0) output.writeUInt8(0) // unused byte
×
292

×
293
                                if (version <= 1) {
×
294
                                        output.writeInt32LE(instance.position.x * 10)
×
295
                                        output.writeInt32LE(instance.position.y * 10)
×
296
                                        output.writeUInt32LE(instance.position.z * 10)
×
297

×
298
                                        output.writeUInt32LE(instance.scale.x * 10)
×
299
                                        output.writeUInt32LE(instance.scale.y * 10)
×
300
                                        output.writeUInt32LE(instance.scale.z * 10)
×
301
                                } else {
×
302
                                        output.writeDoubleLE(instance.position.x)
×
303
                                        output.writeDoubleLE(instance.position.y)
×
304
                                        output.writeDoubleLE(instance.position.z)
×
305

×
306
                                        output.writeDoubleLE(instance.scale.x)
×
307
                                        output.writeDoubleLE(instance.scale.y)
×
308
                                        output.writeDoubleLE(instance.scale.z)
×
309
                                }
×
310

×
311
                                output.writeFloatLE(instance.rotation.z)
×
312

×
313
                                if (instance.blockType === 5) output.writeUInt8(instance.checkpointId)
×
314
                                break
×
315

×
316
                        case 1: // Sphere/gem/collectible/schmilblick
×
317
                                if (version <= 1) {
×
318
                                        output.writeInt32LE(instance.position.x * 10)
×
319
                                        output.writeInt32LE(instance.position.y * 10)
×
320
                                        if (version == 0) {
×
321
                                                output.writeInt32LE(instance.position.z * 10)
×
322
                                        } else {
×
323
                                                output.writeUInt32LE(instance.position.z * 10)
×
324
                                        }
×
325
                                } else {
×
326
                                        output.writeDoubleLE(instance.position.x)
×
327
                                        output.writeDoubleLE(instance.position.y)
×
328
                                        output.writeDoubleLE(instance.position.z)
×
329
                                }
×
330
                                break
×
331
                        case 2: // Player spawn
×
332
                                output.writeUInt8(0) // unused byte
×
333

×
334
                                if (version <= 1) {
×
335
                                        output.writeInt32LE(instance.position.x * 10)
×
336
                                        output.writeInt32LE(instance.position.y * 10)
×
337
                                        if (version == 0) {
×
338
                                                output.writeInt32LE(instance.position.z * 10)
×
339
                                        } else {
×
340
                                                output.writeUInt32LE(instance.position.z * 10)
×
341
                                        }
×
342
                                } else {
×
343
                                        output.writeDoubleLE(instance.position.x)
×
344
                                        output.writeDoubleLE(instance.position.y)
×
345
                                        output.writeDoubleLE(instance.position.z)
×
346
                                }
×
347

×
348
                                output.writeFloatLE(instance.rotation.z)
×
349
                                break
×
350

×
351
                        case 3: // Barrier (wall)
×
352
                                output.writeUInt8(0) // unused byte
×
353

×
354
                                if (version === 3) {
×
355
                                        output.writeInt32LE(instance.position * 10)
×
356
                                        output.writeInt32LE(instance.position * 10)
×
357
                                        output.writeUInt32LE(instance.position * 10)
×
358

×
359
                                        output.writeUInt32LE(instance.scale.x * 10)
×
360
                                        output.writeUInt32LE(instance.scale.z * 10)
×
361
                                } else {
×
362
                                        output.writeDoubleLE(instance.position.x)
×
363
                                        output.writeDoubleLE(instance.position.y)
×
364
                                        output.writeDoubleLE(instance.position.z)
×
365

×
366
                                        output.writeDoubleLE(instance.scale.x)
×
367
                                        output.writeDoubleLE(instance.scale.z)
×
368
                                }
×
369

×
370
                                output.writeFloatLE(instance.rotation.z)
×
371
                                break
×
372
                        case 4: // Barrier (floor)
×
373
                                output.writeUInt8(0) // unused byte
×
374

×
375
                                if (version === 3) {
×
376
                                        output.writeInt32LE(instance.position * 10)
×
377
                                        output.writeInt32LE(instance.position * 10)
×
378
                                        output.writeUInt32LE(instance.position * 10)
×
379

×
380
                                        output.writeUInt32LE(instance.scale.x * 10)
×
381
                                        output.writeUInt32LE(instance.scale.y * 10)
×
382
                                } else {
×
383
                                        output.writeDoubleLE(instance.position.x)
×
384
                                        output.writeDoubleLE(instance.position.y)
×
385
                                        output.writeDoubleLE(instance.position.z)
×
386

×
387
                                        output.writeDoubleLE(instance.scale.x)
×
388
                                        output.writeDoubleLE(instance.scale.y)
×
389
                                }
×
390

×
391
                                output.writeFloatLE(instance.rotation.z)
×
392
                                break
×
393
                        default:
×
394
                                break
×
395
                }
×
396
        })
×
397

×
398
        return output.toBuffer()
×
399
}
×
400

6✔
401
// TODO: Again, this uses the .ecmap versions (0 - 4)
6✔
UNCOV
402
function instanceTypeIsSupported(instanceType, version) {
×
403
        switch (instanceType) {
×
404
                case 3:
×
405
                        if (version < 3) return false
×
406
                        break
×
407
                case 4:
×
408
                        if (version < 3) return false
×
409
                        break
×
410

×
411
                default:
×
412
                        break
×
413
        }
×
414

×
415
        return true
×
416
}
×
417

6✔
418
module.exports = { parseCelariaMap, writeCelariaMap }
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc