generated from metaversecloud-com/sdk-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhandleLoadGameState.js
More file actions
111 lines (97 loc) · 3.23 KB
/
handleLoadGameState.js
File metadata and controls
111 lines (97 loc) · 3.23 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
import {
World,
errorHandler,
formatLeaderboard,
getCredentials,
getInventoryItems,
getVisitor,
} from "../utils/index.js";
import { TRACKS } from "../constants.js";
export const handleLoadGameState = async (req, res) => {
try {
const credentials = getCredentials(req.query);
const { profileId, urlSlug, sceneDropId } = credentials;
const now = Date.now();
const world = await World.create(urlSlug, { credentials });
await world.fetchDataObject();
let sceneData = world.dataObject?.[sceneDropId];
let shouldUpdateWorldDataObject = false;
if (!sceneData) {
const checkpointAssets = await world.fetchDroppedAssetsWithUniqueName({
uniqueName: "race-track-checkpoint",
isPartial: true,
});
let count = 0;
for (const asset of checkpointAssets) {
if (asset.sceneDropId === sceneDropId) count++;
}
sceneData = {
numberOfCheckpoints: count,
leaderboard: {},
};
shouldUpdateWorldDataObject = true;
} else if (sceneData.profiles) {
// Migrate old leaderboard format to new format
let leaderboard = {};
for (const profileId in sceneData.profiles) {
const { username, highscore } = sceneData.profiles[profileId];
leaderboard[profileId] = `${username}|${highscore}`;
}
sceneData.leaderboard = leaderboard;
delete sceneData.profiles;
shouldUpdateWorldDataObject = true;
}
const lockId = `${sceneDropId}-${new Date(Math.round(new Date().getTime() / 60000) * 60000)}`;
if (!world.dataObject || Object.keys(world.dataObject).length === 0) {
await world.setDataObject(
{
[sceneDropId]: sceneData,
},
{ lock: { lockId, releaseLock: true } },
);
} else if (shouldUpdateWorldDataObject) {
await world.updateDataObject(
{
[sceneDropId]: sceneData,
},
{ lock: { lockId, releaseLock: true } },
);
}
const { leaderboardArray, highScore } = await formatLeaderboard(sceneData.leaderboard, profileId);
const { visitor, visitorProgress, visitorInventory } = await getVisitor(credentials, true);
let { checkpoints, startTimestamp } = visitorProgress;
const { badges } = await getInventoryItems(credentials);
return res.json({
checkpointsCompleted: checkpoints,
elapsedTimeInSeconds: startTimestamp ? Math.floor((now - startTimestamp) / 1000) : 0,
highScore,
isAdmin: visitor.isAdmin,
leaderboard: leaderboardArray,
numberOfCheckpoints: sceneData.numberOfCheckpoints,
startTimestamp,
success: true,
tracks: parseEnvJson(process.env.TRACKS) || TRACKS,
visitorInventory,
badges,
lastRaceStartedDate: sceneData.lastRaceStartedDate || null,
});
} catch (error) {
return errorHandler({
error,
functionName: "handleLoadGameState",
message: "Error loading game state",
req,
res,
});
}
};
const parseEnvJson = (envVar) => {
try {
if (!envVar) throw new Error("Environment variable is undefined");
const unescapedJson = envVar.replace(/\\"/g, '"');
return JSON.parse(unescapedJson);
} catch (error) {
console.error("Error parsing JSON:", error);
throw error;
}
};