@series-inc/venus-sdk 3.1.2 → 3.2.1-beta.0
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/dist/{AdsApi-CNGRf6j0.d.mts → AdsApi-or6zfdzM.d.mts} +499 -293
- package/dist/{AdsApi-CNGRf6j0.d.ts → AdsApi-or6zfdzM.d.ts} +499 -293
- package/dist/chunk-NSSMTXJJ.mjs +7 -0
- package/dist/chunk-NSSMTXJJ.mjs.map +1 -0
- package/dist/{chunk-W7IPHM67.mjs → chunk-QABXMFND.mjs} +3 -26
- package/dist/chunk-QABXMFND.mjs.map +1 -0
- package/dist/chunk-UXY5CKKG.mjs +12 -0
- package/dist/chunk-UXY5CKKG.mjs.map +1 -0
- package/dist/{chunk-PXWCNWJ6.mjs → chunk-YOBDYPKZ.mjs} +1528 -1577
- package/dist/chunk-YOBDYPKZ.mjs.map +1 -0
- package/dist/core-62LWDHN7.mjs +4 -0
- package/dist/{core-R3FHW62G.mjs.map → core-62LWDHN7.mjs.map} +1 -1
- package/dist/index.cjs +1556 -1585
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +290 -92
- package/dist/index.d.ts +290 -92
- package/dist/index.mjs +4 -6
- package/dist/index.mjs.map +1 -1
- package/dist/venus-api/index.cjs +1613 -2008
- package/dist/venus-api/index.cjs.map +1 -1
- package/dist/venus-api/index.d.mts +2 -2
- package/dist/venus-api/index.d.ts +2 -2
- package/dist/venus-api/index.mjs +92 -391
- package/dist/venus-api/index.mjs.map +1 -1
- package/dist/vite/index.cjs +534 -0
- package/dist/vite/index.cjs.map +1 -0
- package/dist/vite/index.mjs +527 -0
- package/dist/vite/index.mjs.map +1 -0
- package/dist/webview/index.cjs +15 -0
- package/dist/webview/index.cjs.map +1 -0
- package/dist/webview/index.d.mts +15 -0
- package/dist/webview/index.d.ts +15 -0
- package/dist/webview/index.mjs +4 -0
- package/dist/webview/index.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-PXWCNWJ6.mjs.map +0 -1
- package/dist/chunk-W7IPHM67.mjs.map +0 -1
- package/dist/core-R3FHW62G.mjs +0 -3
package/dist/index.cjs
CHANGED
|
@@ -1,243 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
4
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __esm = (fn, res) => function __init() {
|
|
9
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
-
};
|
|
11
|
-
var __export = (target, all) => {
|
|
12
|
-
for (var name in all)
|
|
13
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
-
};
|
|
15
|
-
var __copyProps = (to, from, except, desc) => {
|
|
16
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
-
for (let key of __getOwnPropNames(from))
|
|
18
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
5
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
25
6
|
|
|
26
|
-
// src/rooms/RoomsApi.ts
|
|
27
|
-
var init_RoomsApi = __esm({
|
|
28
|
-
"src/rooms/RoomsApi.ts"() {
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// src/rooms/VenusRoom.ts
|
|
33
|
-
exports.VenusRoom = void 0;
|
|
34
|
-
var init_VenusRoom = __esm({
|
|
35
|
-
"src/rooms/VenusRoom.ts"() {
|
|
36
|
-
exports.VenusRoom = class {
|
|
37
|
-
constructor(roomData) {
|
|
38
|
-
__publicField(this, "id");
|
|
39
|
-
__publicField(this, "name");
|
|
40
|
-
__publicField(this, "players");
|
|
41
|
-
__publicField(this, "maxPlayers");
|
|
42
|
-
__publicField(this, "gameType");
|
|
43
|
-
__publicField(this, "appId");
|
|
44
|
-
__publicField(this, "type");
|
|
45
|
-
__publicField(this, "createdBy");
|
|
46
|
-
__publicField(this, "createdAt");
|
|
47
|
-
__publicField(this, "updatedAt");
|
|
48
|
-
__publicField(this, "isPrivate");
|
|
49
|
-
__publicField(this, "currentPlayers");
|
|
50
|
-
__publicField(this, "status");
|
|
51
|
-
__publicField(this, "customMetadata");
|
|
52
|
-
__publicField(this, "admins");
|
|
53
|
-
__publicField(this, "roomCode");
|
|
54
|
-
__publicField(this, "description");
|
|
55
|
-
__publicField(this, "data");
|
|
56
|
-
__publicField(this, "version");
|
|
57
|
-
__publicField(this, "_subscriptions", /* @__PURE__ */ new Map());
|
|
58
|
-
this.id = roomData.id;
|
|
59
|
-
this.name = roomData.name;
|
|
60
|
-
this.players = roomData.currentPlayers || [];
|
|
61
|
-
this.maxPlayers = roomData.maxPlayers;
|
|
62
|
-
this.gameType = roomData.gameType;
|
|
63
|
-
this.appId = roomData.appId;
|
|
64
|
-
this.type = roomData.type;
|
|
65
|
-
this.createdBy = roomData.createdBy;
|
|
66
|
-
this.createdAt = roomData.createdAt;
|
|
67
|
-
this.updatedAt = roomData.updatedAt;
|
|
68
|
-
this.isPrivate = roomData.isPrivate;
|
|
69
|
-
this.currentPlayers = roomData.currentPlayers || [];
|
|
70
|
-
this.status = roomData.status;
|
|
71
|
-
this.customMetadata = roomData.customMetadata || {};
|
|
72
|
-
this.admins = roomData.admins || [];
|
|
73
|
-
this.roomCode = roomData.roomCode;
|
|
74
|
-
this.description = roomData.description;
|
|
75
|
-
this.data = roomData.data || {};
|
|
76
|
-
this.version = roomData.version;
|
|
77
|
-
console.log(`VenusRoom: Created room object for ${this.id}`, {
|
|
78
|
-
hasCustomMetadata: !!this.customMetadata,
|
|
79
|
-
hasGameState: !!this.customMetadata?.rules?.gameState,
|
|
80
|
-
gamePhase: this.customMetadata?.rules?.gameState?.phase,
|
|
81
|
-
currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
updateFromRoomData(newRoomData) {
|
|
85
|
-
if (newRoomData.id === this.id) {
|
|
86
|
-
this.name = newRoomData.name || this.name;
|
|
87
|
-
this.players = newRoomData.currentPlayers || this.players;
|
|
88
|
-
this.maxPlayers = newRoomData.maxPlayers || this.maxPlayers;
|
|
89
|
-
this.gameType = newRoomData.gameType || this.gameType;
|
|
90
|
-
this.currentPlayers = newRoomData.currentPlayers || this.currentPlayers;
|
|
91
|
-
this.customMetadata = newRoomData.customMetadata || this.customMetadata;
|
|
92
|
-
this.data = newRoomData.data || this.data;
|
|
93
|
-
this.status = newRoomData.status || this.status;
|
|
94
|
-
this.updatedAt = newRoomData.updatedAt || this.updatedAt;
|
|
95
|
-
console.log(`VenusRoom: Updated room object ${this.id} with fresh data`, {
|
|
96
|
-
hasCustomMetadata: !!this.customMetadata,
|
|
97
|
-
hasGameState: !!this.customMetadata?.rules?.gameState,
|
|
98
|
-
gamePhase: this.customMetadata?.rules?.gameState?.phase,
|
|
99
|
-
currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// src/rooms/index.ts
|
|
108
|
-
var rooms_exports = {};
|
|
109
|
-
__export(rooms_exports, {
|
|
110
|
-
VenusRoom: () => exports.VenusRoom,
|
|
111
|
-
initializeRoomsApi: () => initializeRoomsApi,
|
|
112
|
-
setupRoomNotifications: () => setupRoomNotifications
|
|
113
|
-
});
|
|
114
|
-
function bindMethod(target, targetKey, source, sourceKey) {
|
|
115
|
-
const key = sourceKey ?? targetKey;
|
|
116
|
-
const fn = source?.[key];
|
|
117
|
-
if (typeof fn === "function") {
|
|
118
|
-
target[targetKey] = fn.bind(source);
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
function setupRoomNotifications(transport, getSubscriptions) {
|
|
124
|
-
console.log("[Venus Rooms] Setting up room notification listeners");
|
|
125
|
-
return transport.onVenusMessage((message) => {
|
|
126
|
-
const subscriptions = getSubscriptions();
|
|
127
|
-
if (!subscriptions) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
if (message.type === "H5_ROOM_DATA_UPDATED") {
|
|
131
|
-
const messageData = message.data;
|
|
132
|
-
const { roomId, roomData } = messageData;
|
|
133
|
-
if (!roomId) return;
|
|
134
|
-
const callbacks = subscriptions.data?.[roomId] || [];
|
|
135
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
136
|
-
console.log(`[Venus Rooms] \u{1F514} Room data updated for ${roomId}, notifying ${callbacks.length} callbacks`, roomData);
|
|
137
|
-
callbacks.forEach((callback) => {
|
|
138
|
-
try {
|
|
139
|
-
callback(roomData);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
console.error("[Venus Rooms] Error in room data callback:", error);
|
|
142
|
-
throw error;
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
allEventsCallbacks.forEach((callback) => {
|
|
146
|
-
try {
|
|
147
|
-
callback({ type: message.type, ...messageData });
|
|
148
|
-
} catch (error) {
|
|
149
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
150
|
-
throw error;
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
|
|
155
|
-
const messageData = message.data;
|
|
156
|
-
const { roomId } = messageData;
|
|
157
|
-
if (!roomId) return;
|
|
158
|
-
const callbacks = subscriptions.messages?.[roomId] || [];
|
|
159
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
160
|
-
console.log(`[Venus Rooms] \u{1F514} Room message event for ${roomId}, notifying ${callbacks.length} callbacks`);
|
|
161
|
-
callbacks.forEach((callback) => {
|
|
162
|
-
try {
|
|
163
|
-
callback(messageData);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error("[Venus Rooms] Error in room message callback:", error);
|
|
166
|
-
throw error;
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
allEventsCallbacks.forEach((callback) => {
|
|
170
|
-
try {
|
|
171
|
-
callback({ type: message.type, ...messageData });
|
|
172
|
-
} catch (error) {
|
|
173
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
174
|
-
throw error;
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
if (message.type === "app:h5:proposedMoveValidationUpdated") {
|
|
179
|
-
const messageData = message.data;
|
|
180
|
-
const { roomId } = messageData;
|
|
181
|
-
if (!roomId) return;
|
|
182
|
-
const callbacks = subscriptions.gameEvents?.[roomId] || [];
|
|
183
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
184
|
-
console.log(`[Venus Rooms] \u{1F514} Proposed move validation updated for ${roomId}, notifying ${callbacks.length} callbacks`);
|
|
185
|
-
callbacks.forEach((callback) => {
|
|
186
|
-
try {
|
|
187
|
-
callback(messageData);
|
|
188
|
-
} catch (error) {
|
|
189
|
-
console.error("[Venus Rooms] Error in game event callback:", error);
|
|
190
|
-
throw error;
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
allEventsCallbacks.forEach((callback) => {
|
|
194
|
-
try {
|
|
195
|
-
callback({ type: message.type, ...messageData });
|
|
196
|
-
} catch (error) {
|
|
197
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
198
|
-
throw error;
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
function initializeRoomsApi(venusApi, host) {
|
|
205
|
-
const roomsApi = host?.rooms;
|
|
206
|
-
if (!roomsApi) {
|
|
207
|
-
console.warn(
|
|
208
|
-
"[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
|
|
209
|
-
);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
const venus = venusApi;
|
|
213
|
-
const existingNamespace = venus.rooms || {};
|
|
214
|
-
const roomsNamespace = Object.assign({}, existingNamespace);
|
|
215
|
-
const namespaceBindings = [
|
|
216
|
-
["create", "createRoom"],
|
|
217
|
-
["joinOrCreate", "joinOrCreateRoom"],
|
|
218
|
-
["joinByCode", "joinRoomByCode"],
|
|
219
|
-
["list", "getUserRooms"],
|
|
220
|
-
["subscribeToRoom", "subscribe"],
|
|
221
|
-
["updateRoomData", "updateData"],
|
|
222
|
-
["getRoomData", "getData"],
|
|
223
|
-
["sendRoomMessage", "sendMessage"],
|
|
224
|
-
["leaveRoom", "leave"],
|
|
225
|
-
["startRoomGame", "startGame"],
|
|
226
|
-
["proposeMove"],
|
|
227
|
-
["validateMove"]
|
|
228
|
-
];
|
|
229
|
-
namespaceBindings.forEach(([targetKey, sourceKey]) => {
|
|
230
|
-
bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
|
|
231
|
-
});
|
|
232
|
-
venus.rooms = roomsNamespace;
|
|
233
|
-
}
|
|
234
|
-
var init_rooms = __esm({
|
|
235
|
-
"src/rooms/index.ts"() {
|
|
236
|
-
init_RoomsApi();
|
|
237
|
-
init_VenusRoom();
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
|
|
241
7
|
// src/VenusMessageId.ts
|
|
242
8
|
var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
243
9
|
VenusMessageId2["H5_RESPONSE"] = "H5_RESPONSE";
|
|
@@ -284,10 +50,6 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
|
284
50
|
VenusMessageId2["CONFIRM_DIALOG"] = "H5_CONFIRM_DIALOG";
|
|
285
51
|
VenusMessageId2["ACTION_SHEET_SHOW"] = "H5_ACTION_SHEET_SHOW";
|
|
286
52
|
VenusMessageId2["REQUEST_SERVER_TIME"] = "H5_REQUEST_SERVER_TIME";
|
|
287
|
-
VenusMessageId2["GET_POST_INTERACTIONS"] = "H5_GET_POST_INTERACTIONS";
|
|
288
|
-
VenusMessageId2["TOGGLE_LIKE"] = "H5_TOGGLE_LIKE";
|
|
289
|
-
VenusMessageId2["OPEN_COMMENTS"] = "H5_OPEN_COMMENTS";
|
|
290
|
-
VenusMessageId2["TOGGLE_FOLLOW"] = "H5_TOGGLE_FOLLOW";
|
|
291
53
|
VenusMessageId2["SHARE_LINK"] = "H5_SHARE_LINK";
|
|
292
54
|
VenusMessageId2["CREATE_SHARE_QRCODE"] = "H5_CREATE_SHARE_QRCODE";
|
|
293
55
|
VenusMessageId2["AI_CHAT_COMPLETION"] = "H5_AI_CHAT_COMPLETION";
|
|
@@ -329,11 +91,14 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
|
329
91
|
VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
|
|
330
92
|
VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
|
|
331
93
|
VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
|
|
332
|
-
VenusMessageId2["
|
|
94
|
+
VenusMessageId2["H5_SIMULATION_SUBSCRIBE"] = "H5_SIMULATION_SUBSCRIBE";
|
|
95
|
+
VenusMessageId2["H5_SIMULATION_UNSUBSCRIBE"] = "H5_SIMULATION_UNSUBSCRIBE";
|
|
96
|
+
VenusMessageId2["H5_SIMULATION_UPDATE"] = "H5_SIMULATION_UPDATE";
|
|
97
|
+
VenusMessageId2["H5_LEADERBOARD_CREATE_SCORE_TOKEN"] = "H5_LEADERBOARD_CREATE_SCORE_TOKEN";
|
|
333
98
|
VenusMessageId2["H5_LEADERBOARD_SUBMIT_SCORE"] = "H5_LEADERBOARD_SUBMIT_SCORE";
|
|
334
|
-
VenusMessageId2["
|
|
335
|
-
VenusMessageId2["
|
|
336
|
-
VenusMessageId2["
|
|
99
|
+
VenusMessageId2["H5_LEADERBOARD_GET_PAGED_SCORES"] = "H5_LEADERBOARD_GET_PAGED_SCORES";
|
|
100
|
+
VenusMessageId2["H5_LEADERBOARD_GET_PODIUM_SCORES"] = "H5_LEADERBOARD_GET_PODIUM_SCORES";
|
|
101
|
+
VenusMessageId2["H5_LEADERBOARD_GET_MY_RANK"] = "H5_LEADERBOARD_GET_MY_RANK";
|
|
337
102
|
VenusMessageId2["H5_ROOM_CREATE"] = "H5_ROOM_CREATE";
|
|
338
103
|
VenusMessageId2["H5_ROOM_JOIN"] = "H5_ROOM_JOIN";
|
|
339
104
|
VenusMessageId2["H5_ROOM_JOIN_OR_CREATE"] = "H5_ROOM_JOIN_OR_CREATE";
|
|
@@ -588,7 +353,7 @@ var MockAvatarApi = class {
|
|
|
588
353
|
async deleteAvatar() {
|
|
589
354
|
console.log(`[Venus Mock] Deleting avatar3d config`);
|
|
590
355
|
const venusApi = this._venusApi;
|
|
591
|
-
const currentProfile = venusApi.
|
|
356
|
+
const currentProfile = venusApi.getProfile();
|
|
592
357
|
const profileId = currentProfile?.id || "default_profile";
|
|
593
358
|
localStorage.removeItem(`venus-mock-avatar3d-${profileId}`);
|
|
594
359
|
console.log(
|
|
@@ -603,7 +368,7 @@ var MockAvatarApi = class {
|
|
|
603
368
|
console.log(`[Venus Mock] Loading shared avatar3d by ID: ${avatar3dId}`);
|
|
604
369
|
config = await this.selectAvatarConfig(avatar3dId, false);
|
|
605
370
|
} else {
|
|
606
|
-
const currentProfile = venusApi.
|
|
371
|
+
const currentProfile = venusApi.getProfile();
|
|
607
372
|
const profileId = currentProfile?.id || "default_profile";
|
|
608
373
|
console.log(`[Venus Mock] Loading avatar3d for profile: ${profileId}`);
|
|
609
374
|
console.log(
|
|
@@ -620,7 +385,7 @@ var MockAvatarApi = class {
|
|
|
620
385
|
async saveAvatar(config) {
|
|
621
386
|
console.log(`[Venus Mock] Saving avatar3d config:`, config);
|
|
622
387
|
const venusApi = this._venusApi;
|
|
623
|
-
const currentProfile = venusApi.
|
|
388
|
+
const currentProfile = venusApi.getProfile();
|
|
624
389
|
const profileId = currentProfile?.id || "default_profile";
|
|
625
390
|
localStorage.setItem(
|
|
626
391
|
`venus-mock-avatar3d-${profileId}`,
|
|
@@ -1136,7 +901,8 @@ var HostCdnApi = class {
|
|
|
1136
901
|
return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
|
|
1137
902
|
});
|
|
1138
903
|
const encodedSubPath = encodedParts.join("/");
|
|
1139
|
-
const
|
|
904
|
+
const cacheBust = Date.now();
|
|
905
|
+
const fullUrl = this.baseUrl + "/" + encodedSubPath + `?cacheBust=${cacheBust}`;
|
|
1140
906
|
return fullUrl;
|
|
1141
907
|
}
|
|
1142
908
|
resolveAvatarAssetUrl(subPath) {
|
|
@@ -1151,9 +917,15 @@ var HostCdnApi = class {
|
|
|
1151
917
|
|
|
1152
918
|
// src/cdn/MockCdnApi.ts
|
|
1153
919
|
var MockCdnApi = class {
|
|
1154
|
-
constructor() {
|
|
1155
|
-
__publicField(this, "
|
|
1156
|
-
this.
|
|
920
|
+
constructor(venusApi) {
|
|
921
|
+
__publicField(this, "venusApi");
|
|
922
|
+
this.venusApi = venusApi;
|
|
923
|
+
}
|
|
924
|
+
get baseUrl() {
|
|
925
|
+
return this.venusApi._mock?.cdnBaseUrl ?? "https://venus-static-01293ak.web.app/";
|
|
926
|
+
}
|
|
927
|
+
get forceRemoteCdn() {
|
|
928
|
+
return this.venusApi._mock?.cdnForceRemote ?? false;
|
|
1157
929
|
}
|
|
1158
930
|
async fetchBlob(path, options) {
|
|
1159
931
|
const controller = new AbortController();
|
|
@@ -1190,6 +962,10 @@ var MockCdnApi = class {
|
|
|
1190
962
|
return subPath;
|
|
1191
963
|
}
|
|
1192
964
|
const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
|
|
965
|
+
const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
|
|
966
|
+
if (isLocalhost && !this.forceRemoteCdn) {
|
|
967
|
+
return `/${cleanSubPath}`;
|
|
968
|
+
}
|
|
1193
969
|
const pathParts = cleanSubPath.split("/");
|
|
1194
970
|
const encodedParts = pathParts.map((part, index) => {
|
|
1195
971
|
return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
|
|
@@ -1311,6 +1087,212 @@ function initializeCdn(venusApi, host) {
|
|
|
1311
1087
|
venusApi.cdn = host.cdn;
|
|
1312
1088
|
}
|
|
1313
1089
|
|
|
1090
|
+
// src/device/HostDeviceApi.ts
|
|
1091
|
+
var HostDeviceApi = class {
|
|
1092
|
+
constructor(venusApi) {
|
|
1093
|
+
__publicField(this, "venusApi");
|
|
1094
|
+
this.venusApi = venusApi;
|
|
1095
|
+
}
|
|
1096
|
+
getDevice() {
|
|
1097
|
+
const device = this.venusApi._deviceData;
|
|
1098
|
+
if (!device) {
|
|
1099
|
+
throw new Error(
|
|
1100
|
+
"[Venus SDK] Device info not available. You must await VenusAPI.initializeAsync() before calling getDevice(). INIT_SDK has not completed."
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
return device;
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
|
|
1107
|
+
// src/device/MockDeviceApi.ts
|
|
1108
|
+
var MockDeviceApi = class {
|
|
1109
|
+
constructor(venusApi) {
|
|
1110
|
+
__publicField(this, "venusApi");
|
|
1111
|
+
this.venusApi = venusApi;
|
|
1112
|
+
}
|
|
1113
|
+
getDevice() {
|
|
1114
|
+
const width = typeof window !== "undefined" ? window.innerWidth : 400;
|
|
1115
|
+
const height = typeof window !== "undefined" ? window.innerHeight : 800;
|
|
1116
|
+
return {
|
|
1117
|
+
screenSize: { width, height },
|
|
1118
|
+
viewportSize: {
|
|
1119
|
+
width: width - 20,
|
|
1120
|
+
// account for safe area
|
|
1121
|
+
height: height - 20
|
|
1122
|
+
},
|
|
1123
|
+
orientation: width > height ? "landscape" : "portrait",
|
|
1124
|
+
pixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
|
|
1125
|
+
fontScale: 1,
|
|
1126
|
+
deviceType: width > 768 ? "tablet" : "phone",
|
|
1127
|
+
hapticsEnabled: false,
|
|
1128
|
+
haptics: { supported: false, enabled: false }
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
};
|
|
1132
|
+
|
|
1133
|
+
// src/environment/HostEnvironmentApi.ts
|
|
1134
|
+
var HostEnvironmentApi = class {
|
|
1135
|
+
constructor(venusApi) {
|
|
1136
|
+
__publicField(this, "venusApi");
|
|
1137
|
+
this.venusApi = venusApi;
|
|
1138
|
+
}
|
|
1139
|
+
getEnvironment() {
|
|
1140
|
+
const environment = this.venusApi._environmentData;
|
|
1141
|
+
if (!environment) {
|
|
1142
|
+
throw new Error(
|
|
1143
|
+
"[Venus SDK] Environment info not available. You must await VenusAPI.initializeAsync() before calling getEnvironment(). INIT_SDK has not completed."
|
|
1144
|
+
);
|
|
1145
|
+
}
|
|
1146
|
+
return environment;
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
|
|
1150
|
+
// src/environment/MockEnvironmentApi.ts
|
|
1151
|
+
var MockEnvironmentApi = class {
|
|
1152
|
+
constructor(venusApi) {
|
|
1153
|
+
__publicField(this, "venusApi");
|
|
1154
|
+
this.venusApi = venusApi;
|
|
1155
|
+
}
|
|
1156
|
+
getEnvironment() {
|
|
1157
|
+
const getBrowser = () => {
|
|
1158
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1159
|
+
const userAgent = navigator.userAgent;
|
|
1160
|
+
if (/chrome|chromium|crios/i.test(userAgent)) return "chrome";
|
|
1161
|
+
if (/firefox|fxios/i.test(userAgent)) return "firefox";
|
|
1162
|
+
if (/safari/i.test(userAgent)) return "safari";
|
|
1163
|
+
if (/edg/i.test(userAgent)) return "edge";
|
|
1164
|
+
if (/opera|opr/i.test(userAgent)) return "opera";
|
|
1165
|
+
return "unknown";
|
|
1166
|
+
};
|
|
1167
|
+
return {
|
|
1168
|
+
isDevelopment: true,
|
|
1169
|
+
platform: "web",
|
|
1170
|
+
platformVersion: "mock-1.0",
|
|
1171
|
+
browserInfo: {
|
|
1172
|
+
browser: getBrowser(),
|
|
1173
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "mock-agent",
|
|
1174
|
+
isMobile: typeof navigator !== "undefined" ? /Mobi|Android/i.test(navigator.userAgent) : false,
|
|
1175
|
+
isTablet: typeof navigator !== "undefined" ? /iPad|Tablet|Pad/i.test(navigator.userAgent) : false,
|
|
1176
|
+
language: typeof navigator !== "undefined" ? navigator.language || "en-US" : "en-US"
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
// src/system/HostSystemApi.ts
|
|
1183
|
+
var HostSystemApi = class {
|
|
1184
|
+
constructor(deviceApi, environmentApi, venusApi) {
|
|
1185
|
+
__publicField(this, "deviceApi");
|
|
1186
|
+
__publicField(this, "environmentApi");
|
|
1187
|
+
__publicField(this, "venusApi");
|
|
1188
|
+
this.deviceApi = deviceApi;
|
|
1189
|
+
this.environmentApi = environmentApi;
|
|
1190
|
+
this.venusApi = venusApi;
|
|
1191
|
+
}
|
|
1192
|
+
getDevice() {
|
|
1193
|
+
return this.deviceApi.getDevice();
|
|
1194
|
+
}
|
|
1195
|
+
getEnvironment() {
|
|
1196
|
+
return this.environmentApi.getEnvironment();
|
|
1197
|
+
}
|
|
1198
|
+
getSafeArea() {
|
|
1199
|
+
const safeArea = this.venusApi._safeAreaData;
|
|
1200
|
+
if (!safeArea) {
|
|
1201
|
+
throw new Error(
|
|
1202
|
+
"[Venus SDK] getSafeArea() called before initialization. Call VenusAPI.initializeAsync() first."
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
return { ...safeArea };
|
|
1206
|
+
}
|
|
1207
|
+
isMobile() {
|
|
1208
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1209
|
+
if (environment.platform === "ios" || environment.platform === "android") {
|
|
1210
|
+
return true;
|
|
1211
|
+
}
|
|
1212
|
+
if (environment.browserInfo) {
|
|
1213
|
+
return environment.browserInfo.isMobile;
|
|
1214
|
+
}
|
|
1215
|
+
return true;
|
|
1216
|
+
}
|
|
1217
|
+
isWeb() {
|
|
1218
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1219
|
+
if (environment.platform === "web") {
|
|
1220
|
+
return true;
|
|
1221
|
+
}
|
|
1222
|
+
if (environment.browserInfo && !environment.browserInfo.isMobile) {
|
|
1223
|
+
return true;
|
|
1224
|
+
}
|
|
1225
|
+
return false;
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1229
|
+
// src/system/MockSystemApi.ts
|
|
1230
|
+
var MockSystemApi = class {
|
|
1231
|
+
constructor(deviceApi, environmentApi, venusApi) {
|
|
1232
|
+
__publicField(this, "deviceApi");
|
|
1233
|
+
__publicField(this, "environmentApi");
|
|
1234
|
+
__publicField(this, "venusApi");
|
|
1235
|
+
this.deviceApi = deviceApi;
|
|
1236
|
+
this.environmentApi = environmentApi;
|
|
1237
|
+
this.venusApi = venusApi;
|
|
1238
|
+
}
|
|
1239
|
+
getDevice() {
|
|
1240
|
+
return this.deviceApi.getDevice();
|
|
1241
|
+
}
|
|
1242
|
+
getEnvironment() {
|
|
1243
|
+
return this.environmentApi.getEnvironment();
|
|
1244
|
+
}
|
|
1245
|
+
getSafeArea() {
|
|
1246
|
+
const safeArea = this.venusApi._safeAreaData;
|
|
1247
|
+
if (!safeArea) {
|
|
1248
|
+
return {
|
|
1249
|
+
top: 0,
|
|
1250
|
+
right: 0,
|
|
1251
|
+
bottom: 34,
|
|
1252
|
+
left: 0
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
return { ...safeArea };
|
|
1256
|
+
}
|
|
1257
|
+
isMobile() {
|
|
1258
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1259
|
+
if (environment.platform === "ios" || environment.platform === "android") {
|
|
1260
|
+
return true;
|
|
1261
|
+
}
|
|
1262
|
+
if (environment.browserInfo) {
|
|
1263
|
+
return environment.browserInfo.isMobile;
|
|
1264
|
+
}
|
|
1265
|
+
return true;
|
|
1266
|
+
}
|
|
1267
|
+
isWeb() {
|
|
1268
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1269
|
+
if (environment.platform === "web") {
|
|
1270
|
+
return true;
|
|
1271
|
+
}
|
|
1272
|
+
if (environment.browserInfo && !environment.browserInfo.isMobile) {
|
|
1273
|
+
return true;
|
|
1274
|
+
}
|
|
1275
|
+
return false;
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
// src/system/index.ts
|
|
1280
|
+
function initializeSystem(venusApi, host) {
|
|
1281
|
+
venusApi.system = host.system;
|
|
1282
|
+
venusApi.isMobile = () => {
|
|
1283
|
+
console.warn(
|
|
1284
|
+
"[Venus SDK] DEPRECATED: VenusAPI.isMobile() is deprecated. Use VenusAPI.system.isMobile() instead."
|
|
1285
|
+
);
|
|
1286
|
+
return host.system.isMobile();
|
|
1287
|
+
};
|
|
1288
|
+
venusApi.isWeb = () => {
|
|
1289
|
+
console.warn(
|
|
1290
|
+
"[Venus SDK] DEPRECATED: VenusAPI.isWeb() is deprecated. Use VenusAPI.system.isWeb() instead."
|
|
1291
|
+
);
|
|
1292
|
+
return host.system.isWeb();
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1314
1296
|
// src/features/RpcFeaturesApi.ts
|
|
1315
1297
|
var RpcFeaturesApi = class {
|
|
1316
1298
|
constructor(rcpClient) {
|
|
@@ -1793,13 +1775,8 @@ var MockNotificationsApi = class {
|
|
|
1793
1775
|
async cancelNotification(notificationId) {
|
|
1794
1776
|
const venusApi = this.venusApi;
|
|
1795
1777
|
if (isWebPlatform()) {
|
|
1796
|
-
console.log(
|
|
1797
|
-
"[Venus Mock] Cancel notification on web platform (simulated):",
|
|
1798
|
-
notificationId
|
|
1799
|
-
);
|
|
1800
1778
|
return true;
|
|
1801
1779
|
}
|
|
1802
|
-
console.log("[Venus Mock] Cancel local notification:", notificationId);
|
|
1803
1780
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1804
1781
|
if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
|
|
1805
1782
|
delete venusApi._mock.scheduledNotifications[notificationId];
|
|
@@ -1809,12 +1786,8 @@ var MockNotificationsApi = class {
|
|
|
1809
1786
|
}
|
|
1810
1787
|
async getAllScheduledLocalNotifications() {
|
|
1811
1788
|
if (isWebPlatform()) {
|
|
1812
|
-
console.log(
|
|
1813
|
-
"[Venus Mock] Get notifications on web platform (returning empty list)"
|
|
1814
|
-
);
|
|
1815
1789
|
return [];
|
|
1816
1790
|
}
|
|
1817
|
-
console.log("[Venus Mock] Get all scheduled local notifications");
|
|
1818
1791
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1819
1792
|
const venusApi = this.venusApi;
|
|
1820
1793
|
const notifications = venusApi._mock.scheduledNotifications || {};
|
|
@@ -1822,10 +1795,8 @@ var MockNotificationsApi = class {
|
|
|
1822
1795
|
}
|
|
1823
1796
|
async isLocalNotificationsEnabled() {
|
|
1824
1797
|
if (isWebPlatform()) {
|
|
1825
|
-
console.log("[Venus Mock] Notifications not available on web platform");
|
|
1826
1798
|
return false;
|
|
1827
1799
|
}
|
|
1828
|
-
console.log("[Venus Mock] Check if local notifications are enabled");
|
|
1829
1800
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1830
1801
|
const venusApi = this.venusApi;
|
|
1831
1802
|
const isEnabled = venusApi._mock.notificationsEnabled !== false;
|
|
@@ -1834,9 +1805,6 @@ var MockNotificationsApi = class {
|
|
|
1834
1805
|
async scheduleAsync(title, body, seconds, notificationId, options) {
|
|
1835
1806
|
const { priority = 50, groupId, payload } = options || {};
|
|
1836
1807
|
if (isWebPlatform()) {
|
|
1837
|
-
console.log(
|
|
1838
|
-
"[Venus Mock] Notifications not supported on web platform, simulating success"
|
|
1839
|
-
);
|
|
1840
1808
|
console.info(
|
|
1841
1809
|
"\u{1F514} [Venus Mock] Notification would be scheduled:",
|
|
1842
1810
|
title || "Untitled",
|
|
@@ -1847,14 +1815,11 @@ var MockNotificationsApi = class {
|
|
|
1847
1815
|
const mockId = `mock-web-notification-${Date.now()}`;
|
|
1848
1816
|
return mockId;
|
|
1849
1817
|
}
|
|
1850
|
-
console.log("[Venus Mock] Schedule local notification:", { title, body, seconds, options });
|
|
1851
1818
|
const venusApi = this.venusApi;
|
|
1852
1819
|
if (!venusApi._mock.pendingRequests) {
|
|
1853
|
-
console.log("[Venus Mock] Initializing pendingRequests");
|
|
1854
1820
|
venusApi._mock.pendingRequests = {};
|
|
1855
1821
|
}
|
|
1856
1822
|
const requestId = Date.now().toString();
|
|
1857
|
-
console.log("[Venus Mock] Creating request with ID:", requestId);
|
|
1858
1823
|
return new Promise((resolve) => {
|
|
1859
1824
|
venusApi._mock.pendingRequests[requestId] = { resolve };
|
|
1860
1825
|
const id = notificationId || `mock-notification-${Date.now()}`;
|
|
@@ -1876,13 +1841,8 @@ var MockNotificationsApi = class {
|
|
|
1876
1841
|
async setLocalNotificationsEnabled(enabled) {
|
|
1877
1842
|
const venusApi = this.venusApi;
|
|
1878
1843
|
if (isWebPlatform()) {
|
|
1879
|
-
console.log(
|
|
1880
|
-
"[Venus Mock] Set notifications enabled on web platform (simulated):",
|
|
1881
|
-
enabled
|
|
1882
|
-
);
|
|
1883
1844
|
return true;
|
|
1884
1845
|
}
|
|
1885
|
-
console.log("[Venus Mock] Set local notifications enabled:", enabled);
|
|
1886
1846
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1887
1847
|
venusApi._mock.notificationsEnabled = enabled;
|
|
1888
1848
|
return enabled;
|
|
@@ -2107,16 +2067,20 @@ function initializePopups(venusApi, host) {
|
|
|
2107
2067
|
|
|
2108
2068
|
// src/profile/HostProfileApi.ts
|
|
2109
2069
|
var HostProfileApi = class {
|
|
2070
|
+
constructor(venusApi) {
|
|
2071
|
+
__publicField(this, "venusApi");
|
|
2072
|
+
this.venusApi = venusApi;
|
|
2073
|
+
}
|
|
2110
2074
|
getCurrentProfile() {
|
|
2111
|
-
const profile =
|
|
2075
|
+
const profile = this.venusApi._profileData;
|
|
2112
2076
|
if (!profile) {
|
|
2113
2077
|
throw new Error(
|
|
2114
|
-
"[Venus SDK]
|
|
2078
|
+
"[Venus SDK] Profile not available. You must await VenusAPI.initializeAsync() before calling getProfile(). INIT_SDK has not completed."
|
|
2115
2079
|
);
|
|
2116
2080
|
}
|
|
2117
2081
|
if (!profile.id || !profile.username) {
|
|
2118
2082
|
throw new Error(
|
|
2119
|
-
"[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply
|
|
2083
|
+
"[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply valid profile data."
|
|
2120
2084
|
);
|
|
2121
2085
|
}
|
|
2122
2086
|
return {
|
|
@@ -2130,6 +2094,10 @@ var HostProfileApi = class {
|
|
|
2130
2094
|
|
|
2131
2095
|
// src/profile/MockProfileApi.ts
|
|
2132
2096
|
var MockProfileApi = class {
|
|
2097
|
+
constructor(venusApi) {
|
|
2098
|
+
__publicField(this, "venusApi");
|
|
2099
|
+
this.venusApi = venusApi;
|
|
2100
|
+
}
|
|
2133
2101
|
getCurrentProfile() {
|
|
2134
2102
|
return {
|
|
2135
2103
|
id: "mock_profile_123",
|
|
@@ -2142,11 +2110,22 @@ var MockProfileApi = class {
|
|
|
2142
2110
|
|
|
2143
2111
|
// src/profile/index.ts
|
|
2144
2112
|
function initializeProfile(venusApi, host) {
|
|
2113
|
+
venusApi.getProfile = () => {
|
|
2114
|
+
return host.profile.getCurrentProfile();
|
|
2115
|
+
};
|
|
2145
2116
|
venusApi.getCurrentProfile = () => {
|
|
2117
|
+
console.warn(
|
|
2118
|
+
"[Venus SDK] DEPRECATED: VenusAPI.getCurrentProfile() is deprecated. Use VenusAPI.getProfile() instead. See migration guide: https://docs.venus.com/migration/profile-api"
|
|
2119
|
+
);
|
|
2146
2120
|
return host.profile.getCurrentProfile();
|
|
2147
2121
|
};
|
|
2148
2122
|
}
|
|
2149
2123
|
|
|
2124
|
+
// src/utils/idGenerator.ts
|
|
2125
|
+
function generateId() {
|
|
2126
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2150
2129
|
// src/rpc/RpcClient.ts
|
|
2151
2130
|
var RpcClient = class {
|
|
2152
2131
|
constructor() {
|
|
@@ -2189,7 +2168,7 @@ var RpcClient = class {
|
|
|
2189
2168
|
}
|
|
2190
2169
|
async call(method, args, timeout = 5e3) {
|
|
2191
2170
|
return new Promise((resolve, reject) => {
|
|
2192
|
-
const id =
|
|
2171
|
+
const id = generateId();
|
|
2193
2172
|
this.addPendingCall(id, resolve, reject);
|
|
2194
2173
|
const request = {
|
|
2195
2174
|
type: "rpc-request",
|
|
@@ -2226,9 +2205,6 @@ var RpcClient = class {
|
|
|
2226
2205
|
getPendingCall(id) {
|
|
2227
2206
|
return this.pendingCalls.get(id);
|
|
2228
2207
|
}
|
|
2229
|
-
generateId() {
|
|
2230
|
-
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2231
|
-
}
|
|
2232
2208
|
handleRpcResponse(response) {
|
|
2233
2209
|
const pending = this.getPendingCall(response.id);
|
|
2234
2210
|
if (!pending) {
|
|
@@ -2250,60 +2226,488 @@ var RpcClient = class {
|
|
|
2250
2226
|
}
|
|
2251
2227
|
};
|
|
2252
2228
|
|
|
2253
|
-
// src/
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
this.
|
|
2285
|
-
this.
|
|
2229
|
+
// src/rooms/VenusRoom.ts
|
|
2230
|
+
var VenusRoom = class {
|
|
2231
|
+
constructor(roomData) {
|
|
2232
|
+
__publicField(this, "id");
|
|
2233
|
+
__publicField(this, "name");
|
|
2234
|
+
__publicField(this, "players");
|
|
2235
|
+
__publicField(this, "maxPlayers");
|
|
2236
|
+
__publicField(this, "gameType");
|
|
2237
|
+
__publicField(this, "appId");
|
|
2238
|
+
__publicField(this, "type");
|
|
2239
|
+
__publicField(this, "createdBy");
|
|
2240
|
+
__publicField(this, "createdAt");
|
|
2241
|
+
__publicField(this, "updatedAt");
|
|
2242
|
+
__publicField(this, "isPrivate");
|
|
2243
|
+
__publicField(this, "status");
|
|
2244
|
+
__publicField(this, "customMetadata");
|
|
2245
|
+
__publicField(this, "admins");
|
|
2246
|
+
__publicField(this, "roomCode");
|
|
2247
|
+
__publicField(this, "description");
|
|
2248
|
+
__publicField(this, "data");
|
|
2249
|
+
__publicField(this, "version");
|
|
2250
|
+
this.id = roomData.id;
|
|
2251
|
+
this.name = roomData.name;
|
|
2252
|
+
this.players = Array.isArray(roomData.currentPlayers) ? [...roomData.currentPlayers] : [];
|
|
2253
|
+
this.maxPlayers = roomData.maxPlayers;
|
|
2254
|
+
this.gameType = roomData.gameType;
|
|
2255
|
+
this.appId = roomData.appId;
|
|
2256
|
+
this.type = roomData.type;
|
|
2257
|
+
this.createdBy = roomData.createdBy;
|
|
2258
|
+
this.createdAt = roomData.createdAt;
|
|
2259
|
+
this.updatedAt = roomData.updatedAt;
|
|
2260
|
+
this.isPrivate = roomData.isPrivate;
|
|
2261
|
+
this.status = roomData.status;
|
|
2262
|
+
this.customMetadata = roomData.customMetadata || {};
|
|
2263
|
+
this.admins = Array.isArray(roomData.admins) ? [...roomData.admins] : [];
|
|
2264
|
+
this.roomCode = roomData.roomCode;
|
|
2265
|
+
this.description = roomData.description;
|
|
2266
|
+
this.data = roomData.data || {};
|
|
2267
|
+
this.version = roomData.version;
|
|
2286
2268
|
}
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2269
|
+
};
|
|
2270
|
+
|
|
2271
|
+
// src/rooms/setupRoomNotifications.ts
|
|
2272
|
+
function invokeCallbacks(callbacks, event, context) {
|
|
2273
|
+
callbacks.forEach((callback) => {
|
|
2274
|
+
try {
|
|
2275
|
+
callback(event);
|
|
2276
|
+
} catch (error) {
|
|
2277
|
+
console.error(`[Venus SDK] Error in ${context} callback:`, error);
|
|
2278
|
+
throw error;
|
|
2294
2279
|
}
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
const
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
function setupRoomNotifications(transport, getSubscriptions) {
|
|
2283
|
+
return transport.onVenusMessage((message) => {
|
|
2284
|
+
const subscriptions = getSubscriptions();
|
|
2285
|
+
if (!subscriptions) {
|
|
2286
|
+
return;
|
|
2287
|
+
}
|
|
2288
|
+
if (message.type === "H5_ROOM_DATA_UPDATED") {
|
|
2289
|
+
const messageData = message.data;
|
|
2290
|
+
const { roomId, roomData } = messageData;
|
|
2291
|
+
if (!roomId) return;
|
|
2292
|
+
const callbacks = subscriptions.data[roomId] || [];
|
|
2293
|
+
const event = {
|
|
2294
|
+
type: "H5_ROOM_DATA_UPDATED",
|
|
2295
|
+
roomId,
|
|
2296
|
+
roomData,
|
|
2297
|
+
timestamp: messageData.timestamp
|
|
2298
|
+
};
|
|
2299
|
+
invokeCallbacks(callbacks, event, "room data");
|
|
2300
|
+
}
|
|
2301
|
+
if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
|
|
2302
|
+
const messageData = message.data;
|
|
2303
|
+
const { roomId } = messageData;
|
|
2304
|
+
if (!roomId) return;
|
|
2305
|
+
const callbacks = subscriptions.messages[roomId] || [];
|
|
2306
|
+
const event = {
|
|
2307
|
+
type: message.type,
|
|
2308
|
+
roomId,
|
|
2309
|
+
message: messageData.message,
|
|
2310
|
+
timestamp: messageData.timestamp
|
|
2311
|
+
};
|
|
2312
|
+
invokeCallbacks(callbacks, event, "room message");
|
|
2313
|
+
}
|
|
2314
|
+
if (message.type === "app:h5:proposedMoveValidationUpdated") {
|
|
2315
|
+
const messageData = message.data;
|
|
2316
|
+
const { roomId } = messageData;
|
|
2317
|
+
if (!roomId) return;
|
|
2318
|
+
const callbacks = subscriptions.gameEvents[roomId] || [];
|
|
2319
|
+
const event = {
|
|
2320
|
+
type: "app:h5:proposedMoveValidationUpdated",
|
|
2321
|
+
roomId,
|
|
2322
|
+
proposedMoveData: messageData.proposedMoveData,
|
|
2323
|
+
proposedMoveId: messageData.proposedMoveId,
|
|
2324
|
+
changeType: messageData.changeType,
|
|
2325
|
+
timestamp: messageData.timestamp
|
|
2326
|
+
};
|
|
2327
|
+
invokeCallbacks(callbacks, event, "game event");
|
|
2328
|
+
}
|
|
2329
|
+
});
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
// src/rooms/RpcRoomsApi.ts
|
|
2333
|
+
var RpcRoomsApi = class {
|
|
2334
|
+
constructor(rpcClient) {
|
|
2335
|
+
__publicField(this, "rpcClient");
|
|
2336
|
+
__publicField(this, "subscriptions");
|
|
2337
|
+
this.rpcClient = rpcClient;
|
|
2338
|
+
this.subscriptions = {
|
|
2339
|
+
data: {},
|
|
2340
|
+
messages: {},
|
|
2341
|
+
gameEvents: {}
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2344
|
+
/**
|
|
2345
|
+
* Get the subscription state for external access (used by setupRoomNotifications)
|
|
2346
|
+
*/
|
|
2347
|
+
getSubscriptions() {
|
|
2348
|
+
return this.subscriptions;
|
|
2349
|
+
}
|
|
2350
|
+
/**
|
|
2351
|
+
* Set up room notification routing from the transport
|
|
2352
|
+
*/
|
|
2353
|
+
setupNotifications(transport) {
|
|
2354
|
+
setupRoomNotifications(transport, () => this.getSubscriptions());
|
|
2355
|
+
}
|
|
2356
|
+
async createRoomAsync(options) {
|
|
2357
|
+
const response = await this.rpcClient.call(
|
|
2358
|
+
"H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
|
|
2359
|
+
{
|
|
2360
|
+
options
|
|
2361
|
+
}
|
|
2362
|
+
);
|
|
2363
|
+
if (response.success === false) {
|
|
2364
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to create room";
|
|
2365
|
+
throw new Error(errorMessage);
|
|
2366
|
+
}
|
|
2367
|
+
const room = new VenusRoom(response.roomData);
|
|
2368
|
+
return room;
|
|
2369
|
+
}
|
|
2370
|
+
async joinOrCreateRoomAsync(options) {
|
|
2371
|
+
const response = await this.rpcClient.call(
|
|
2372
|
+
"H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
|
|
2373
|
+
{
|
|
2374
|
+
options
|
|
2375
|
+
}
|
|
2376
|
+
);
|
|
2377
|
+
if (response.success === false) {
|
|
2378
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to join or create room";
|
|
2379
|
+
throw new Error(errorMessage);
|
|
2380
|
+
}
|
|
2381
|
+
const room = new VenusRoom(response.value.roomData);
|
|
2382
|
+
return {
|
|
2383
|
+
action: response.value.action,
|
|
2384
|
+
room,
|
|
2385
|
+
playersJoined: response.value.playersJoined
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2388
|
+
async joinRoomByCodeAsync(roomCode) {
|
|
2389
|
+
const response = await this.rpcClient.call(
|
|
2390
|
+
"H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
|
|
2391
|
+
{
|
|
2392
|
+
roomCode
|
|
2393
|
+
}
|
|
2394
|
+
);
|
|
2395
|
+
if (response?.success === false) {
|
|
2396
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to join room by code";
|
|
2397
|
+
throw new Error(errorMessage);
|
|
2398
|
+
}
|
|
2399
|
+
const room = new VenusRoom(response.roomData);
|
|
2400
|
+
return room;
|
|
2401
|
+
}
|
|
2402
|
+
// Get user's rooms with optional filtering
|
|
2403
|
+
async getUserRoomsAsync(options = {}) {
|
|
2404
|
+
const response = await this.rpcClient.call(
|
|
2405
|
+
"H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
|
|
2406
|
+
{
|
|
2407
|
+
includeArchived: options.includeArchived ?? false
|
|
2408
|
+
}
|
|
2409
|
+
);
|
|
2410
|
+
if (response?.success === false) {
|
|
2411
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to get user rooms";
|
|
2412
|
+
throw new Error(errorMessage);
|
|
2413
|
+
}
|
|
2414
|
+
const venusRooms = [];
|
|
2415
|
+
for (const roomData of response.rooms) {
|
|
2416
|
+
if (!roomData.id) {
|
|
2417
|
+
console.warn("[Venus SDK] getUserRooms: Skipping room with missing ID:", roomData);
|
|
2418
|
+
continue;
|
|
2419
|
+
}
|
|
2420
|
+
try {
|
|
2421
|
+
const venusRoom = new VenusRoom(roomData);
|
|
2422
|
+
venusRooms.push(venusRoom);
|
|
2423
|
+
} catch (error) {
|
|
2424
|
+
console.warn(
|
|
2425
|
+
"[Venus SDK] getUserRooms: Failed to create VenusRoom object:",
|
|
2426
|
+
error,
|
|
2427
|
+
roomData
|
|
2428
|
+
);
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
return venusRooms;
|
|
2432
|
+
}
|
|
2433
|
+
async updateRoomDataAsync(room, updates, options = {}) {
|
|
2434
|
+
const response = await this.rpcClient.call(
|
|
2435
|
+
"H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
|
|
2436
|
+
{
|
|
2437
|
+
roomId: room.id,
|
|
2438
|
+
updates,
|
|
2439
|
+
merge: options.merge ?? true
|
|
2440
|
+
}
|
|
2441
|
+
);
|
|
2442
|
+
if (response?.success === false) {
|
|
2443
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to update room data";
|
|
2444
|
+
throw new Error(errorMessage);
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
async getRoomDataAsync(room) {
|
|
2448
|
+
const response = await this.rpcClient.call(
|
|
2449
|
+
"H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
|
|
2450
|
+
{
|
|
2451
|
+
roomId: room.id
|
|
2452
|
+
}
|
|
2453
|
+
);
|
|
2454
|
+
if (response?.success === false) {
|
|
2455
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to get room data";
|
|
2456
|
+
throw new Error(errorMessage);
|
|
2457
|
+
}
|
|
2458
|
+
return response.data;
|
|
2459
|
+
}
|
|
2460
|
+
async sendRoomMessageAsync(venusRoom, request) {
|
|
2461
|
+
const response = await this.rpcClient.call(
|
|
2462
|
+
"H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
|
|
2463
|
+
{
|
|
2464
|
+
roomId: venusRoom.id,
|
|
2465
|
+
message: request.message,
|
|
2466
|
+
metadata: request.metadata
|
|
2467
|
+
}
|
|
2468
|
+
);
|
|
2469
|
+
if (response?.success === false) {
|
|
2470
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to send message";
|
|
2471
|
+
throw new Error(errorMessage);
|
|
2472
|
+
}
|
|
2473
|
+
return response.messageId;
|
|
2474
|
+
}
|
|
2475
|
+
async leaveRoomAsync(room) {
|
|
2476
|
+
const response = await this.rpcClient.call(
|
|
2477
|
+
"H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
|
|
2478
|
+
{
|
|
2479
|
+
roomId: room.id
|
|
2480
|
+
}
|
|
2481
|
+
);
|
|
2482
|
+
if (response?.success === false) {
|
|
2483
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to leave room";
|
|
2484
|
+
throw new Error(errorMessage);
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
async startRoomGameAsync(room, options = {}) {
|
|
2488
|
+
const response = await this.rpcClient.call(
|
|
2489
|
+
"H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
|
|
2490
|
+
{
|
|
2491
|
+
roomId: room.id,
|
|
2492
|
+
gameConfig: options.gameConfig ?? {},
|
|
2493
|
+
turnOrder: options.turnOrder ?? null
|
|
2494
|
+
}
|
|
2495
|
+
);
|
|
2496
|
+
if (response?.success === false) {
|
|
2497
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to start game";
|
|
2498
|
+
throw new Error(errorMessage);
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
async proposeMoveAsync(room, proposalPayload) {
|
|
2502
|
+
const response = await this.rpcClient.call(
|
|
2503
|
+
"h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
|
|
2504
|
+
{
|
|
2505
|
+
roomId: room.id,
|
|
2506
|
+
gameSpecificState: proposalPayload.gameSpecificState,
|
|
2507
|
+
moveType: proposalPayload.moveType,
|
|
2508
|
+
clientContext: proposalPayload.clientContext,
|
|
2509
|
+
clientProposalId: proposalPayload.clientProposalId
|
|
2510
|
+
}
|
|
2511
|
+
);
|
|
2512
|
+
if (response?.success === false) {
|
|
2513
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to propose move";
|
|
2514
|
+
throw new Error(errorMessage);
|
|
2515
|
+
}
|
|
2516
|
+
return response.data;
|
|
2517
|
+
}
|
|
2518
|
+
async validateMoveAsync(_room, moveId, verdict) {
|
|
2519
|
+
return {
|
|
2520
|
+
success: true,
|
|
2521
|
+
moveId,
|
|
2522
|
+
isValid: verdict.isValid,
|
|
2523
|
+
reason: verdict.reason
|
|
2524
|
+
};
|
|
2525
|
+
}
|
|
2526
|
+
async subscribeAsync(room, options = {}) {
|
|
2527
|
+
const roomId = room.id;
|
|
2528
|
+
const existingData = this.subscriptions.data[roomId];
|
|
2529
|
+
const existingMessages = this.subscriptions.messages[roomId];
|
|
2530
|
+
const existingGameEvents = this.subscriptions.gameEvents[roomId];
|
|
2531
|
+
const subscribeToData = Boolean(options.onData) && (existingData?.length ?? 0) === 0;
|
|
2532
|
+
const subscribeToMessages = Boolean(options.onMessages) && (existingMessages?.length ?? 0) === 0;
|
|
2533
|
+
const subscribeToProposedMoves = Boolean(options.onGameEvents) && (existingGameEvents?.length ?? 0) === 0;
|
|
2534
|
+
if (subscribeToData || subscribeToMessages || subscribeToProposedMoves) {
|
|
2535
|
+
try {
|
|
2536
|
+
await this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
|
|
2537
|
+
roomId,
|
|
2538
|
+
subscribeToData,
|
|
2539
|
+
subscribeToMessages,
|
|
2540
|
+
subscribeToProposedMoves
|
|
2541
|
+
});
|
|
2542
|
+
} catch (error) {
|
|
2543
|
+
console.error("[Venus SDK] Failed to set up room subscription:", error);
|
|
2544
|
+
throw error;
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
if (options.onData) {
|
|
2548
|
+
if (!this.subscriptions.data[roomId]) {
|
|
2549
|
+
this.subscriptions.data[roomId] = [];
|
|
2550
|
+
}
|
|
2551
|
+
this.subscriptions.data[roomId].push(options.onData);
|
|
2552
|
+
}
|
|
2553
|
+
if (options.onMessages) {
|
|
2554
|
+
if (!this.subscriptions.messages[roomId]) {
|
|
2555
|
+
this.subscriptions.messages[roomId] = [];
|
|
2556
|
+
}
|
|
2557
|
+
this.subscriptions.messages[roomId].push(options.onMessages);
|
|
2558
|
+
}
|
|
2559
|
+
if (options.onGameEvents) {
|
|
2560
|
+
if (!this.subscriptions.gameEvents[roomId]) {
|
|
2561
|
+
this.subscriptions.gameEvents[roomId] = [];
|
|
2562
|
+
}
|
|
2563
|
+
this.subscriptions.gameEvents[roomId].push(options.onGameEvents);
|
|
2564
|
+
}
|
|
2565
|
+
let disposed = false;
|
|
2566
|
+
return () => {
|
|
2567
|
+
if (disposed) return;
|
|
2568
|
+
disposed = true;
|
|
2569
|
+
if (options.onData) {
|
|
2570
|
+
const callbacks = this.subscriptions.data[roomId];
|
|
2571
|
+
if (callbacks) {
|
|
2572
|
+
const index = callbacks.indexOf(options.onData);
|
|
2573
|
+
if (index > -1) {
|
|
2574
|
+
callbacks.splice(index, 1);
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
if (options.onMessages) {
|
|
2579
|
+
const callbacks = this.subscriptions.messages[roomId];
|
|
2580
|
+
if (callbacks) {
|
|
2581
|
+
const index = callbacks.indexOf(options.onMessages);
|
|
2582
|
+
if (index > -1) {
|
|
2583
|
+
callbacks.splice(index, 1);
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
if (options.onGameEvents) {
|
|
2588
|
+
const callbacks = this.subscriptions.gameEvents[roomId];
|
|
2589
|
+
if (callbacks) {
|
|
2590
|
+
const index = callbacks.indexOf(options.onGameEvents);
|
|
2591
|
+
if (index > -1) {
|
|
2592
|
+
callbacks.splice(index, 1);
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
const hasAnySubscriptions = (this.subscriptions.data[roomId]?.length ?? 0) > 0 || (this.subscriptions.messages[roomId]?.length ?? 0) > 0 || (this.subscriptions.gameEvents[roomId]?.length ?? 0) > 0;
|
|
2597
|
+
if (!hasAnySubscriptions) {
|
|
2598
|
+
this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
|
|
2599
|
+
roomId
|
|
2600
|
+
}).catch((error) => {
|
|
2601
|
+
console.error("[Venus SDK] Failed to clean up room subscription:", error);
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
};
|
|
2607
|
+
|
|
2608
|
+
// src/rooms/index.ts
|
|
2609
|
+
function bindMethod(target, targetKey, source, sourceKey) {
|
|
2610
|
+
const key = sourceKey ?? targetKey;
|
|
2611
|
+
const fn = source?.[key];
|
|
2612
|
+
if (typeof fn === "function") {
|
|
2613
|
+
target[targetKey] = fn.bind(source);
|
|
2614
|
+
return true;
|
|
2615
|
+
}
|
|
2616
|
+
return false;
|
|
2617
|
+
}
|
|
2618
|
+
function initializeRoomsApi(venusApi, host) {
|
|
2619
|
+
const roomsApi = host?.rooms;
|
|
2620
|
+
if (!roomsApi) {
|
|
2621
|
+
console.warn(
|
|
2622
|
+
"[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
|
|
2623
|
+
);
|
|
2624
|
+
return;
|
|
2625
|
+
}
|
|
2626
|
+
const venus = venusApi;
|
|
2627
|
+
const existingNamespace = venus.rooms || {};
|
|
2628
|
+
const roomsNamespace = Object.assign({}, existingNamespace);
|
|
2629
|
+
const namespaceBindings = [
|
|
2630
|
+
["createRoomAsync"],
|
|
2631
|
+
["joinOrCreateRoomAsync"],
|
|
2632
|
+
["joinRoomByCodeAsync"],
|
|
2633
|
+
["getUserRoomsAsync"],
|
|
2634
|
+
["subscribeAsync"],
|
|
2635
|
+
["updateRoomDataAsync"],
|
|
2636
|
+
["getRoomDataAsync"],
|
|
2637
|
+
["sendRoomMessageAsync"],
|
|
2638
|
+
["leaveRoomAsync"],
|
|
2639
|
+
["startRoomGameAsync"],
|
|
2640
|
+
["proposeMoveAsync"],
|
|
2641
|
+
["validateMoveAsync"]
|
|
2642
|
+
];
|
|
2643
|
+
namespaceBindings.forEach(([targetKey, sourceKey]) => {
|
|
2644
|
+
bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
|
|
2645
|
+
});
|
|
2646
|
+
venus.rooms = roomsNamespace;
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2649
|
+
// src/storage/MockStorageApi.ts
|
|
2650
|
+
var STORAGE_PREFIXES = {
|
|
2651
|
+
globalStorage: "venus:global",
|
|
2652
|
+
deviceCache: "venus:deviceCache",
|
|
2653
|
+
appStorage: "venus:appStorage"
|
|
2654
|
+
};
|
|
2655
|
+
function createMockStorageApi(storageType, appUrl) {
|
|
2656
|
+
const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
|
|
2657
|
+
let prefix = STORAGE_PREFIXES[storageType];
|
|
2658
|
+
let syncDelay = 0;
|
|
2659
|
+
switch (storageType) {
|
|
2660
|
+
case "deviceCache":
|
|
2661
|
+
syncDelay = 0;
|
|
2662
|
+
break;
|
|
2663
|
+
case "appStorage":
|
|
2664
|
+
syncDelay = 100;
|
|
2665
|
+
break;
|
|
2666
|
+
case "globalStorage":
|
|
2667
|
+
syncDelay = 100;
|
|
2668
|
+
break;
|
|
2669
|
+
default:
|
|
2670
|
+
throw new Error(`Unknown storage type: ${storageType}`);
|
|
2671
|
+
}
|
|
2672
|
+
prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
|
|
2673
|
+
return new MockStorageApi(prefix, syncDelay);
|
|
2674
|
+
}
|
|
2675
|
+
var MockStorageApi = class {
|
|
2676
|
+
constructor(prefix, syncDelay) {
|
|
2677
|
+
__publicField(this, "prefix");
|
|
2678
|
+
__publicField(this, "syncDelay");
|
|
2679
|
+
__publicField(this, "orderStorageKey");
|
|
2680
|
+
this.prefix = prefix;
|
|
2681
|
+
this.syncDelay = syncDelay;
|
|
2682
|
+
this.orderStorageKey = `${prefix}__order__`;
|
|
2683
|
+
}
|
|
2684
|
+
async clear() {
|
|
2685
|
+
const keysToRemove = [];
|
|
2686
|
+
const fullLength = localStorage.length;
|
|
2300
2687
|
for (let i = 0; i < fullLength; i++) {
|
|
2301
2688
|
const fullKey = localStorage.key(i);
|
|
2302
|
-
if (fullKey
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2689
|
+
if (!fullKey || fullKey === this.orderStorageKey) {
|
|
2690
|
+
continue;
|
|
2691
|
+
}
|
|
2692
|
+
if (fullKey.startsWith(this.prefix)) {
|
|
2693
|
+
keysToRemove.push(fullKey);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
for (const key of keysToRemove) {
|
|
2697
|
+
localStorage.removeItem(key);
|
|
2698
|
+
}
|
|
2699
|
+
this.clearOrder();
|
|
2700
|
+
await this.simulateSyncDelay();
|
|
2701
|
+
}
|
|
2702
|
+
async getAllItems() {
|
|
2703
|
+
const items = new Array();
|
|
2704
|
+
const orderedKeys = this.keys();
|
|
2705
|
+
for (const key of orderedKeys) {
|
|
2706
|
+
const value = localStorage.getItem(this.buildKey(key));
|
|
2707
|
+
if (value !== null) {
|
|
2708
|
+
items.push(value);
|
|
2709
|
+
} else {
|
|
2710
|
+
this.removeFromOrder(key);
|
|
2307
2711
|
}
|
|
2308
2712
|
}
|
|
2309
2713
|
return items;
|
|
@@ -2328,11 +2732,13 @@ var MockStorageApi = class {
|
|
|
2328
2732
|
const fullKey = this.buildKey(key);
|
|
2329
2733
|
await this.simulateSyncDelay();
|
|
2330
2734
|
localStorage.removeItem(fullKey);
|
|
2735
|
+
this.removeFromOrder(key);
|
|
2331
2736
|
}
|
|
2332
2737
|
async setItem(key, item) {
|
|
2333
2738
|
const fullKey = this.buildKey(key);
|
|
2334
2739
|
await this.simulateSyncDelay();
|
|
2335
2740
|
localStorage.setItem(fullKey, item);
|
|
2741
|
+
this.upsertOrder(key);
|
|
2336
2742
|
}
|
|
2337
2743
|
async setMultipleItems(entries) {
|
|
2338
2744
|
for (const entry of entries) {
|
|
@@ -2340,6 +2746,7 @@ var MockStorageApi = class {
|
|
|
2340
2746
|
localStorage.setItem(fullKey, entry.value);
|
|
2341
2747
|
}
|
|
2342
2748
|
await this.simulateSyncDelay();
|
|
2749
|
+
this.bulkUpsertOrder(entries.map((entry) => entry.key));
|
|
2343
2750
|
}
|
|
2344
2751
|
async removeMultipleItems(keys) {
|
|
2345
2752
|
for (const key of keys) {
|
|
@@ -2347,6 +2754,7 @@ var MockStorageApi = class {
|
|
|
2347
2754
|
localStorage.removeItem(fullKey);
|
|
2348
2755
|
}
|
|
2349
2756
|
await this.simulateSyncDelay();
|
|
2757
|
+
this.bulkRemoveFromOrder(keys);
|
|
2350
2758
|
}
|
|
2351
2759
|
buildKey(key) {
|
|
2352
2760
|
const prefix = this.prefix;
|
|
@@ -2357,17 +2765,8 @@ var MockStorageApi = class {
|
|
|
2357
2765
|
return fullKey.substring(prefix.length);
|
|
2358
2766
|
}
|
|
2359
2767
|
keys() {
|
|
2360
|
-
const
|
|
2361
|
-
|
|
2362
|
-
for (let i = 0; i < length; i++) {
|
|
2363
|
-
const fullKey = localStorage.key(i);
|
|
2364
|
-
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
2365
|
-
length++;
|
|
2366
|
-
const key = this.extractKey(fullKey);
|
|
2367
|
-
keys.push(key);
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
return keys;
|
|
2768
|
+
const order = this.readOrder();
|
|
2769
|
+
return [...order];
|
|
2371
2770
|
}
|
|
2372
2771
|
async simulateSyncDelay() {
|
|
2373
2772
|
const syncDelay = this.syncDelay;
|
|
@@ -2375,6 +2774,127 @@ var MockStorageApi = class {
|
|
|
2375
2774
|
await new Promise((resolve) => setTimeout(resolve, syncDelay));
|
|
2376
2775
|
}
|
|
2377
2776
|
}
|
|
2777
|
+
readOrder() {
|
|
2778
|
+
const raw = localStorage.getItem(this.orderStorageKey);
|
|
2779
|
+
if (!raw) {
|
|
2780
|
+
return this.rebuildOrderFromStorage();
|
|
2781
|
+
}
|
|
2782
|
+
try {
|
|
2783
|
+
const parsed = JSON.parse(raw);
|
|
2784
|
+
if (Array.isArray(parsed)) {
|
|
2785
|
+
return this.normalizeOrder(parsed);
|
|
2786
|
+
}
|
|
2787
|
+
} catch {
|
|
2788
|
+
}
|
|
2789
|
+
return this.rebuildOrderFromStorage();
|
|
2790
|
+
}
|
|
2791
|
+
normalizeOrder(order) {
|
|
2792
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2793
|
+
const normalized = [];
|
|
2794
|
+
let changed = false;
|
|
2795
|
+
for (const entry of order) {
|
|
2796
|
+
if (typeof entry !== "string") {
|
|
2797
|
+
changed = true;
|
|
2798
|
+
continue;
|
|
2799
|
+
}
|
|
2800
|
+
if (seen.has(entry)) {
|
|
2801
|
+
changed = true;
|
|
2802
|
+
continue;
|
|
2803
|
+
}
|
|
2804
|
+
const fullKey = this.buildKey(entry);
|
|
2805
|
+
if (localStorage.getItem(fullKey) === null) {
|
|
2806
|
+
changed = true;
|
|
2807
|
+
continue;
|
|
2808
|
+
}
|
|
2809
|
+
seen.add(entry);
|
|
2810
|
+
normalized.push(entry);
|
|
2811
|
+
}
|
|
2812
|
+
if (changed) {
|
|
2813
|
+
this.writeOrder(normalized);
|
|
2814
|
+
}
|
|
2815
|
+
return normalized;
|
|
2816
|
+
}
|
|
2817
|
+
rebuildOrderFromStorage() {
|
|
2818
|
+
const keys = [];
|
|
2819
|
+
const total = localStorage.length;
|
|
2820
|
+
for (let i = 0; i < total; i++) {
|
|
2821
|
+
const fullKey = localStorage.key(i);
|
|
2822
|
+
if (!fullKey) continue;
|
|
2823
|
+
if (fullKey === this.orderStorageKey) continue;
|
|
2824
|
+
if (fullKey.startsWith(this.prefix)) {
|
|
2825
|
+
keys.push(this.extractKey(fullKey));
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
this.writeOrder(keys);
|
|
2829
|
+
return keys;
|
|
2830
|
+
}
|
|
2831
|
+
upsertOrder(key) {
|
|
2832
|
+
const order = this.readOrder();
|
|
2833
|
+
const index = order.indexOf(key);
|
|
2834
|
+
if (index !== -1) {
|
|
2835
|
+
order.splice(index, 1);
|
|
2836
|
+
}
|
|
2837
|
+
order.push(key);
|
|
2838
|
+
this.writeOrder(order);
|
|
2839
|
+
}
|
|
2840
|
+
bulkUpsertOrder(keys) {
|
|
2841
|
+
const dedupedKeys = this.dedupeKeys(keys);
|
|
2842
|
+
if (dedupedKeys.length === 0) {
|
|
2843
|
+
return;
|
|
2844
|
+
}
|
|
2845
|
+
const order = this.readOrder();
|
|
2846
|
+
const keysSet = new Set(dedupedKeys);
|
|
2847
|
+
const filtered = order.filter((entry) => !keysSet.has(entry));
|
|
2848
|
+
for (const key of dedupedKeys) {
|
|
2849
|
+
filtered.push(key);
|
|
2850
|
+
}
|
|
2851
|
+
this.writeOrder(filtered);
|
|
2852
|
+
}
|
|
2853
|
+
removeFromOrder(key) {
|
|
2854
|
+
const order = this.readOrder();
|
|
2855
|
+
const index = order.indexOf(key);
|
|
2856
|
+
if (index !== -1) {
|
|
2857
|
+
order.splice(index, 1);
|
|
2858
|
+
this.writeOrder(order);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
bulkRemoveFromOrder(keys) {
|
|
2862
|
+
const dedupedKeys = this.dedupeKeys(keys);
|
|
2863
|
+
if (dedupedKeys.length === 0) {
|
|
2864
|
+
return;
|
|
2865
|
+
}
|
|
2866
|
+
const order = this.readOrder();
|
|
2867
|
+
const keysSet = new Set(dedupedKeys);
|
|
2868
|
+
const filtered = order.filter((entry) => !keysSet.has(entry));
|
|
2869
|
+
if (filtered.length !== order.length) {
|
|
2870
|
+
this.writeOrder(filtered);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
writeOrder(order) {
|
|
2874
|
+
if (order.length === 0) {
|
|
2875
|
+
localStorage.removeItem(this.orderStorageKey);
|
|
2876
|
+
return;
|
|
2877
|
+
}
|
|
2878
|
+
localStorage.setItem(this.orderStorageKey, JSON.stringify(order));
|
|
2879
|
+
}
|
|
2880
|
+
clearOrder() {
|
|
2881
|
+
localStorage.removeItem(this.orderStorageKey);
|
|
2882
|
+
}
|
|
2883
|
+
dedupeKeys(keys) {
|
|
2884
|
+
const result = [];
|
|
2885
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2886
|
+
for (const key of keys) {
|
|
2887
|
+
if (typeof key !== "string") {
|
|
2888
|
+
continue;
|
|
2889
|
+
}
|
|
2890
|
+
if (seen.has(key)) {
|
|
2891
|
+
continue;
|
|
2892
|
+
}
|
|
2893
|
+
seen.add(key);
|
|
2894
|
+
result.push(key);
|
|
2895
|
+
}
|
|
2896
|
+
return result;
|
|
2897
|
+
}
|
|
2378
2898
|
};
|
|
2379
2899
|
function generateAppIdentifier(appUrl) {
|
|
2380
2900
|
if (!appUrl) appUrl = "";
|
|
@@ -2486,24 +3006,20 @@ function initializeStorage(venusApiInstance, host) {
|
|
|
2486
3006
|
venusApiInstance.globalStorage = host.globalStorage;
|
|
2487
3007
|
}
|
|
2488
3008
|
|
|
2489
|
-
// src/simulation/utils.ts
|
|
2490
|
-
function sumContributions(contributions) {
|
|
2491
|
-
const totals = {};
|
|
2492
|
-
for (const profileId in contributions) {
|
|
2493
|
-
for (const entityId in contributions[profileId]) {
|
|
2494
|
-
const amount = contributions[profileId][entityId] || 0;
|
|
2495
|
-
totals[entityId] = (totals[entityId] || 0) + amount;
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
return totals;
|
|
2499
|
-
}
|
|
2500
|
-
|
|
2501
3009
|
// src/simulation/RpcSimulationApi.ts
|
|
2502
3010
|
var RpcSimulationApi = class {
|
|
2503
3011
|
constructor(rpcClient) {
|
|
2504
3012
|
__publicField(this, "rpcClient");
|
|
2505
3013
|
__publicField(this, "_simulationConfig", null);
|
|
3014
|
+
__publicField(this, "subscriptionCallbacks", /* @__PURE__ */ new Map());
|
|
2506
3015
|
this.rpcClient = rpcClient;
|
|
3016
|
+
this.rpcClient.onNotification(
|
|
3017
|
+
"H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */,
|
|
3018
|
+
this.handleSimulationUpdate.bind(this)
|
|
3019
|
+
);
|
|
3020
|
+
}
|
|
3021
|
+
isEnabled() {
|
|
3022
|
+
return true;
|
|
2507
3023
|
}
|
|
2508
3024
|
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2509
3025
|
return this.rpcClient.call(
|
|
@@ -2515,14 +3031,47 @@ var RpcSimulationApi = class {
|
|
|
2515
3031
|
}
|
|
2516
3032
|
);
|
|
2517
3033
|
}
|
|
2518
|
-
|
|
2519
|
-
|
|
3034
|
+
async subscribeAsync(options) {
|
|
3035
|
+
this.ensureValidSubscribeOptions(options);
|
|
3036
|
+
const subscriptionId = generateId();
|
|
3037
|
+
this.subscriptionCallbacks.set(subscriptionId, options.onUpdate);
|
|
3038
|
+
try {
|
|
3039
|
+
await this.rpcClient.call("H5_SIMULATION_SUBSCRIBE" /* H5_SIMULATION_SUBSCRIBE */, {
|
|
3040
|
+
subscriptionId,
|
|
3041
|
+
entities: options.entities,
|
|
3042
|
+
tags: options.tags,
|
|
3043
|
+
activeRuns: options.activeRuns,
|
|
3044
|
+
roomId: options.roomId
|
|
3045
|
+
});
|
|
3046
|
+
} catch (error) {
|
|
3047
|
+
this.subscriptionCallbacks.delete(subscriptionId);
|
|
3048
|
+
throw error;
|
|
3049
|
+
}
|
|
3050
|
+
let unsubscribed = false;
|
|
3051
|
+
return () => {
|
|
3052
|
+
if (unsubscribed) {
|
|
3053
|
+
return;
|
|
3054
|
+
}
|
|
3055
|
+
unsubscribed = true;
|
|
3056
|
+
this.subscriptionCallbacks.delete(subscriptionId);
|
|
3057
|
+
void this.rpcClient.call("H5_SIMULATION_UNSUBSCRIBE" /* H5_SIMULATION_UNSUBSCRIBE */, {
|
|
3058
|
+
subscriptionId
|
|
3059
|
+
}).catch((error) => {
|
|
3060
|
+
console.error(
|
|
3061
|
+
"[Venus SDK] Failed to unsubscribe simulation listener",
|
|
3062
|
+
error
|
|
3063
|
+
);
|
|
3064
|
+
});
|
|
3065
|
+
};
|
|
2520
3066
|
}
|
|
2521
3067
|
executeBatchOperationsAsync(operations, validateOnly) {
|
|
2522
|
-
return this.rpcClient.call(
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
3068
|
+
return this.rpcClient.call(
|
|
3069
|
+
"H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */,
|
|
3070
|
+
{
|
|
3071
|
+
operations,
|
|
3072
|
+
validateOnly
|
|
3073
|
+
}
|
|
3074
|
+
);
|
|
2526
3075
|
}
|
|
2527
3076
|
async getAvailableItemsAsync(containerId, slotId) {
|
|
2528
3077
|
const response = await this.rpcClient.call(
|
|
@@ -2545,17 +3094,23 @@ var RpcSimulationApi = class {
|
|
|
2545
3094
|
);
|
|
2546
3095
|
}
|
|
2547
3096
|
assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
2548
|
-
return this.rpcClient.call(
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
3097
|
+
return this.rpcClient.call(
|
|
3098
|
+
"H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */,
|
|
3099
|
+
{
|
|
3100
|
+
containerId,
|
|
3101
|
+
slotId,
|
|
3102
|
+
itemId
|
|
3103
|
+
}
|
|
3104
|
+
);
|
|
2553
3105
|
}
|
|
2554
3106
|
removeItemFromSlotAsync(containerId, slotId) {
|
|
2555
|
-
return this.rpcClient.call(
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
3107
|
+
return this.rpcClient.call(
|
|
3108
|
+
"H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */,
|
|
3109
|
+
{
|
|
3110
|
+
containerId,
|
|
3111
|
+
slotId
|
|
3112
|
+
}
|
|
3113
|
+
);
|
|
2559
3114
|
}
|
|
2560
3115
|
async getSlotContainersAsync() {
|
|
2561
3116
|
const response = await this.rpcClient.call(
|
|
@@ -2580,7 +3135,6 @@ var RpcSimulationApi = class {
|
|
|
2580
3135
|
roomId
|
|
2581
3136
|
}
|
|
2582
3137
|
);
|
|
2583
|
-
console.log("[Venus SDK] getStateAsync", response);
|
|
2584
3138
|
if (response.configuration) {
|
|
2585
3139
|
this._simulationConfig = response.configuration;
|
|
2586
3140
|
}
|
|
@@ -2592,9 +3146,10 @@ var RpcSimulationApi = class {
|
|
|
2592
3146
|
}
|
|
2593
3147
|
const config = await this.rpcClient.call(
|
|
2594
3148
|
"H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
|
|
2595
|
-
{
|
|
3149
|
+
{
|
|
3150
|
+
roomId
|
|
3151
|
+
}
|
|
2596
3152
|
);
|
|
2597
|
-
console.log("[Venus SDK] getConfigAsync", config);
|
|
2598
3153
|
if (config) {
|
|
2599
3154
|
this._simulationConfig = config;
|
|
2600
3155
|
return config;
|
|
@@ -2602,14 +3157,17 @@ var RpcSimulationApi = class {
|
|
|
2602
3157
|
throw new Error("No simulation configuration available");
|
|
2603
3158
|
}
|
|
2604
3159
|
executeRecipeAsync(recipeId, inputs, options) {
|
|
2605
|
-
return this.rpcClient.call(
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
3160
|
+
return this.rpcClient.call(
|
|
3161
|
+
"H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */,
|
|
3162
|
+
{
|
|
3163
|
+
recipeId,
|
|
3164
|
+
inputs,
|
|
3165
|
+
roomId: options?.roomId,
|
|
3166
|
+
batchAmount: options?.batchAmount,
|
|
3167
|
+
allowPartialBatch: options?.allowPartialBatch,
|
|
3168
|
+
entity: options?.entity
|
|
3169
|
+
}
|
|
3170
|
+
);
|
|
2613
3171
|
}
|
|
2614
3172
|
collectRecipeAsync(runId) {
|
|
2615
3173
|
return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
|
|
@@ -2617,9 +3175,12 @@ var RpcSimulationApi = class {
|
|
|
2617
3175
|
});
|
|
2618
3176
|
}
|
|
2619
3177
|
getActiveRunsAsync(options) {
|
|
2620
|
-
return this.rpcClient.call(
|
|
2621
|
-
|
|
2622
|
-
|
|
3178
|
+
return this.rpcClient.call(
|
|
3179
|
+
"H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */,
|
|
3180
|
+
{
|
|
3181
|
+
roomId: options?.roomId
|
|
3182
|
+
}
|
|
3183
|
+
);
|
|
2623
3184
|
}
|
|
2624
3185
|
executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2625
3186
|
return this.rpcClient.call(
|
|
@@ -2671,601 +3232,70 @@ var RpcSimulationApi = class {
|
|
|
2671
3232
|
);
|
|
2672
3233
|
}
|
|
2673
3234
|
getEntityMetadataAsync(entityId) {
|
|
2674
|
-
return this.rpcClient.call(
|
|
2675
|
-
"H5_SIMULATION_GET_ENTITY_METADATA" /* H5_SIMULATION_GET_ENTITY_METADATA */,
|
|
2676
|
-
{
|
|
2677
|
-
entityId
|
|
2678
|
-
}
|
|
2679
|
-
);
|
|
2680
|
-
}
|
|
2681
|
-
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
2682
|
-
const response = await this.rpcClient.call(
|
|
2683
|
-
"H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
|
|
2684
|
-
{
|
|
2685
|
-
entityId,
|
|
2686
|
-
fieldPath,
|
|
2687
|
-
entity
|
|
2688
|
-
}
|
|
2689
|
-
);
|
|
2690
|
-
return response.value;
|
|
2691
|
-
}
|
|
2692
|
-
};
|
|
2693
|
-
|
|
2694
|
-
// src/simulation/MockSimulationApi.ts
|
|
2695
|
-
function generateAppIdentifier2() {
|
|
2696
|
-
if (typeof window === "undefined") return "unknown-app";
|
|
2697
|
-
const url = window.location.href;
|
|
2698
|
-
const match = url.match(/\/H5\/([^\/]+)/);
|
|
2699
|
-
return match ? match[1] : "unknown-app";
|
|
2700
|
-
}
|
|
2701
|
-
var MockSimulationApi = class {
|
|
2702
|
-
constructor(simulationConfig = null) {
|
|
2703
|
-
__publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
|
|
2704
|
-
// appIdentifier -> config
|
|
2705
|
-
__publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
|
|
2706
|
-
// appIdentifier -> config
|
|
2707
|
-
__publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
|
|
2708
|
-
// appIdentifier -> timers[]
|
|
2709
|
-
__publicField(this, "appId");
|
|
2710
|
-
__publicField(this, "providedSimulationConfig");
|
|
2711
|
-
this.appId = generateAppIdentifier2();
|
|
2712
|
-
this.providedSimulationConfig = simulationConfig;
|
|
2713
|
-
}
|
|
2714
|
-
sumContributions(contributions) {
|
|
2715
|
-
return sumContributions(contributions);
|
|
2716
|
-
}
|
|
2717
|
-
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2718
|
-
this.log("validateSlotAssignmentAsync called:", {
|
|
2719
|
-
containerId,
|
|
2720
|
-
slotId,
|
|
2721
|
-
itemId
|
|
2722
|
-
});
|
|
2723
|
-
return { valid: true, message: "Mock validation successful" };
|
|
2724
|
-
}
|
|
2725
|
-
async executeBatchOperationsAsync(operations, validateOnly) {
|
|
2726
|
-
this.log("executeBatchOperationsAsync called:", {
|
|
2727
|
-
operations,
|
|
2728
|
-
validateOnly
|
|
2729
|
-
});
|
|
2730
|
-
return {
|
|
2731
|
-
success: true,
|
|
2732
|
-
results: operations.map(() => ({ success: true }))
|
|
2733
|
-
};
|
|
2734
|
-
}
|
|
2735
|
-
async getAvailableItemsAsync(containerId, slotId) {
|
|
2736
|
-
console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
|
|
2737
|
-
containerId,
|
|
2738
|
-
slotId
|
|
2739
|
-
});
|
|
2740
|
-
const appIdentifier = generateAppIdentifier2();
|
|
2741
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2742
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2743
|
-
entities: {}
|
|
2744
|
-
};
|
|
2745
|
-
const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
|
|
2746
|
-
entityId,
|
|
2747
|
-
quantity: 1,
|
|
2748
|
-
metadata: entity.metadata,
|
|
2749
|
-
powerPreview: 100
|
|
2750
|
-
// Mock power value
|
|
2751
|
-
}));
|
|
2752
|
-
return availableItems;
|
|
2753
|
-
}
|
|
2754
|
-
async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
|
|
2755
|
-
this.log("calculatePowerPreviewAsync called:", {
|
|
2756
|
-
containerId,
|
|
2757
|
-
slotId,
|
|
2758
|
-
candidateItemId
|
|
2759
|
-
});
|
|
2760
|
-
return {
|
|
2761
|
-
currentPower: 1e3,
|
|
2762
|
-
previewPower: 1200,
|
|
2763
|
-
powerDelta: 200,
|
|
2764
|
-
breakdown: { base: 800, weapon: 200, armor: 200 }
|
|
2765
|
-
};
|
|
2766
|
-
}
|
|
2767
|
-
async getSlotContainersAsync() {
|
|
2768
|
-
this.log("getSlotContainersAsync called");
|
|
2769
|
-
const appIdentifier = this.appId;
|
|
2770
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2771
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2772
|
-
entities: {}
|
|
2773
|
-
};
|
|
2774
|
-
const containers = Object.entries(config.entities).filter(([_, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
|
|
2775
|
-
entityId,
|
|
2776
|
-
slots: entity.metadata?.slots,
|
|
2777
|
-
isOwned: true
|
|
2778
|
-
// Mock: assume all containers are owned
|
|
2779
|
-
}));
|
|
2780
|
-
return containers;
|
|
2781
|
-
}
|
|
2782
|
-
async getSlotAssignmentsAsync(containerId) {
|
|
2783
|
-
this.log("getSlotAssignmentsAsync called for:", containerId);
|
|
2784
|
-
return [];
|
|
2785
|
-
}
|
|
2786
|
-
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
2787
|
-
this.log("resolveFieldValueAsync called:", {
|
|
2788
|
-
entityId,
|
|
2789
|
-
fieldPath,
|
|
2790
|
-
entity
|
|
2791
|
-
});
|
|
2792
|
-
const mockValues = {
|
|
2793
|
-
basePower: 850,
|
|
2794
|
-
weaponPower: 300,
|
|
2795
|
-
armorPower: 150,
|
|
2796
|
-
total_power: 1300,
|
|
2797
|
-
total_defense_power: 5e3
|
|
2798
|
-
};
|
|
2799
|
-
return mockValues[fieldPath] || 100;
|
|
2800
|
-
}
|
|
2801
|
-
async getEntityMetadataAsync(entityId) {
|
|
2802
|
-
this.log("getEntityMetadataAsync called for:", entityId);
|
|
2803
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2804
|
-
const appIdentifier = this.appId;
|
|
2805
|
-
const config = mockSimulationConfigs.get(
|
|
2806
|
-
appIdentifier
|
|
2807
|
-
) || {
|
|
2808
|
-
entities: {}};
|
|
2809
|
-
const entity = config.entities[entityId];
|
|
2810
|
-
return entity?.metadata || {};
|
|
2811
|
-
}
|
|
2812
|
-
async collectRecipeAsync(runId) {
|
|
2813
|
-
this.log("collectRecipeAsync called:", { runId });
|
|
2814
|
-
const mockRewards = {
|
|
2815
|
-
cash: Math.floor(Math.random() * 1e3) + 500,
|
|
2816
|
-
experience: Math.floor(Math.random() * 50) + 25
|
|
2817
|
-
};
|
|
2818
|
-
return {
|
|
2819
|
-
success: true,
|
|
2820
|
-
runId,
|
|
2821
|
-
rewards: mockRewards,
|
|
2822
|
-
message: "Rewards collected successfully"
|
|
2823
|
-
};
|
|
2824
|
-
}
|
|
2825
|
-
executeRecipeAsync(recipeId, inputs, options) {
|
|
2826
|
-
this.log("executeRecipeAsync called:", {
|
|
2827
|
-
recipeId,
|
|
2828
|
-
inputs,
|
|
2829
|
-
options
|
|
2830
|
-
});
|
|
2831
|
-
const appIdentifier = this.appId;
|
|
2832
|
-
return this.executeRecipe(appIdentifier, recipeId, inputs);
|
|
2833
|
-
}
|
|
2834
|
-
async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2835
|
-
this.log("executeScopedRecipeAsync called:", {
|
|
2836
|
-
recipeId,
|
|
2837
|
-
entity,
|
|
2838
|
-
inputs,
|
|
2839
|
-
roomId: options?.roomId,
|
|
2840
|
-
options
|
|
2841
|
-
});
|
|
2842
|
-
return {
|
|
2843
|
-
success: true,
|
|
2844
|
-
message: "Mock scoped recipe execution successful"
|
|
2845
|
-
};
|
|
2846
|
-
}
|
|
2847
|
-
async getActiveRunsAsync(options) {
|
|
2848
|
-
this.log("getActiveRunsAsync called:", options);
|
|
2849
|
-
const appIdentifier = this.appId;
|
|
2850
|
-
let state = this.mockSimulationStates.get(appIdentifier);
|
|
2851
|
-
if (!state) {
|
|
2852
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
2853
|
-
}
|
|
2854
|
-
return state.activeRuns || [];
|
|
2855
|
-
}
|
|
2856
|
-
async getAvailableRecipesAsync(options) {
|
|
2857
|
-
this.log("getAvailableRecipesAsync called:", options);
|
|
2858
|
-
const baseRecipes = [
|
|
2859
|
-
{ id: "collect_resources", scope: "player", clientViewable: true },
|
|
2860
|
-
{ id: "upgrade_equipment", scope: "player", clientViewable: true }
|
|
2861
|
-
];
|
|
2862
|
-
if (options?.roomId) {
|
|
2863
|
-
baseRecipes.push(
|
|
2864
|
-
{ id: "room_upgrade", scope: "room", clientViewable: true },
|
|
2865
|
-
{ id: "cooperative_project", scope: "room", clientViewable: true }
|
|
2866
|
-
);
|
|
2867
|
-
}
|
|
2868
|
-
if (options?.includeActorRecipes && options?.roomId) {
|
|
2869
|
-
baseRecipes.push(
|
|
2870
|
-
{ id: "trade_with_npc", scope: "actor", clientViewable: true },
|
|
2871
|
-
{ id: "attack_monster", scope: "actor", clientViewable: true }
|
|
2872
|
-
);
|
|
2873
|
-
}
|
|
2874
|
-
return { success: true, recipes: baseRecipes };
|
|
2875
|
-
}
|
|
2876
|
-
async getBatchRecipeRequirementsAsync(recipes) {
|
|
2877
|
-
this.log("getBatchRecipeRequirementsAsync called:", {
|
|
2878
|
-
count: recipes?.length
|
|
2879
|
-
});
|
|
2880
|
-
const results = (recipes || []).map((q) => ({
|
|
2881
|
-
recipeId: q.recipeId,
|
|
2882
|
-
entity: q.entity || null,
|
|
2883
|
-
amount: q.batchAmount || 1,
|
|
2884
|
-
inputs: { cash: "BE:0" },
|
|
2885
|
-
canAfford: true,
|
|
2886
|
-
disabled: false
|
|
2887
|
-
}));
|
|
2888
|
-
return { success: true, results };
|
|
2889
|
-
}
|
|
2890
|
-
async getRecipeRequirementsAsync(recipe) {
|
|
2891
|
-
this.log("getRecipeRequirementsAsync called:", recipe);
|
|
2892
|
-
return {
|
|
2893
|
-
recipeId: recipe.recipeId,
|
|
2894
|
-
entity: recipe.entity || null,
|
|
2895
|
-
amount: recipe.batchAmount,
|
|
2896
|
-
inputs: { cash: "BE:0" },
|
|
2897
|
-
canAfford: true,
|
|
2898
|
-
disabled: false
|
|
2899
|
-
};
|
|
2900
|
-
}
|
|
2901
|
-
async triggerRecipeChainAsync(recipeId, options) {
|
|
2902
|
-
this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
|
|
2903
|
-
return {
|
|
2904
|
-
success: true,
|
|
2905
|
-
message: "Mock recipe chain triggered successfully"
|
|
2906
|
-
};
|
|
2907
|
-
}
|
|
2908
|
-
log(message, ...args) {
|
|
2909
|
-
console.log(`[Venus Sim Mock] ${message}`, args);
|
|
2910
|
-
}
|
|
2911
|
-
async executeRecipe(appIdentifier, recipeId, inputs) {
|
|
2912
|
-
this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
|
|
2913
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2914
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
2915
|
-
let config = mockSimulationConfigs.get(appIdentifier);
|
|
2916
|
-
let state = mockSimulationStates.get(appIdentifier);
|
|
2917
|
-
if (!config || !state) {
|
|
2918
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
2919
|
-
config = mockSimulationConfigs.get(appIdentifier);
|
|
2920
|
-
if (!config) {
|
|
2921
|
-
throw new Error("Failed to initialize simulation config");
|
|
2922
|
-
}
|
|
2923
|
-
}
|
|
2924
|
-
const recipe = config.recipes?.[recipeId];
|
|
2925
|
-
if (!recipe) {
|
|
2926
|
-
throw new Error(`Recipe ${recipeId} not found`);
|
|
2927
|
-
}
|
|
2928
|
-
if (state.disabledRecipes?.includes(recipeId)) {
|
|
2929
|
-
throw new Error(`Recipe ${recipeId} is disabled`);
|
|
2930
|
-
}
|
|
2931
|
-
if (recipe.inputs) {
|
|
2932
|
-
for (const [entityId, required] of Object.entries(recipe.inputs)) {
|
|
2933
|
-
const available = state.inventory[entityId] || 0;
|
|
2934
|
-
if (available < required) {
|
|
2935
|
-
throw new Error(
|
|
2936
|
-
`Insufficient ${entityId}: required ${required}, available ${available}`
|
|
2937
|
-
);
|
|
2938
|
-
}
|
|
3235
|
+
return this.rpcClient.call(
|
|
3236
|
+
"H5_SIMULATION_GET_ENTITY_METADATA" /* H5_SIMULATION_GET_ENTITY_METADATA */,
|
|
3237
|
+
{
|
|
3238
|
+
entityId
|
|
2939
3239
|
}
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
3240
|
+
);
|
|
3241
|
+
}
|
|
3242
|
+
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
3243
|
+
const response = await this.rpcClient.call(
|
|
3244
|
+
"H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
|
|
3245
|
+
{
|
|
3246
|
+
entityId,
|
|
3247
|
+
fieldPath,
|
|
3248
|
+
entity
|
|
2947
3249
|
}
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
this.applyEffects(state, recipe.beginEffects);
|
|
2951
|
-
}
|
|
2952
|
-
const runId = this.generateRunId();
|
|
2953
|
-
const now = Date.now();
|
|
2954
|
-
const expiresAt = now + (recipe.duration || 0);
|
|
2955
|
-
const run = {
|
|
2956
|
-
id: runId,
|
|
2957
|
-
recipeId,
|
|
2958
|
-
status: "running",
|
|
2959
|
-
startTime: now,
|
|
2960
|
-
expiresAt,
|
|
2961
|
-
inputs: recipe.inputs || {}
|
|
2962
|
-
};
|
|
2963
|
-
state.activeRuns.push(run);
|
|
2964
|
-
if (recipe.duration === 0) {
|
|
2965
|
-
this.completeRun(appIdentifier, runId);
|
|
2966
|
-
return { status: "completed", runId };
|
|
2967
|
-
} else {
|
|
2968
|
-
const mockActiveTimers = this.mockActiveTimers;
|
|
2969
|
-
const timer = setTimeout(() => {
|
|
2970
|
-
this.completeRun(appIdentifier, runId);
|
|
2971
|
-
}, recipe.duration);
|
|
2972
|
-
const timers = mockActiveTimers.get(appIdentifier) || [];
|
|
2973
|
-
timers.push(timer);
|
|
2974
|
-
mockActiveTimers.set(appIdentifier, timers);
|
|
2975
|
-
return {
|
|
2976
|
-
status: "running",
|
|
2977
|
-
runId,
|
|
2978
|
-
expiresAt: new Date(expiresAt).toISOString()
|
|
2979
|
-
};
|
|
2980
|
-
}
|
|
3250
|
+
);
|
|
3251
|
+
return response.value;
|
|
2981
3252
|
}
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
2987
|
-
const mockActiveTimers = this.mockActiveTimers;
|
|
2988
|
-
const config = providedSimulationConfig || {
|
|
2989
|
-
version: "1.0",
|
|
2990
|
-
entities: {},
|
|
2991
|
-
recipes: {}
|
|
2992
|
-
};
|
|
2993
|
-
mockSimulationConfigs.set(appIdentifier, config);
|
|
2994
|
-
const initialInventory = {};
|
|
2995
|
-
if (providedSimulationConfig && config.entities) {
|
|
2996
|
-
Object.keys(config.entities).forEach((entityId) => {
|
|
2997
|
-
initialInventory[entityId] = 0;
|
|
2998
|
-
});
|
|
2999
|
-
}
|
|
3000
|
-
const state = {
|
|
3001
|
-
inventory: initialInventory,
|
|
3002
|
-
activeRuns: [],
|
|
3003
|
-
disabledRecipes: new Array()
|
|
3004
|
-
};
|
|
3005
|
-
if (config.recipes) {
|
|
3006
|
-
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
3007
|
-
if (recipe.metadata?.startsDisabled) {
|
|
3008
|
-
state.disabledRecipes.push(recipeId);
|
|
3009
|
-
}
|
|
3010
|
-
});
|
|
3253
|
+
handleSimulationUpdate(notification) {
|
|
3254
|
+
if (!notification || !notification.subscriptionId) {
|
|
3255
|
+
console.warn("[Venus SDK] Received malformed simulation update");
|
|
3256
|
+
return;
|
|
3011
3257
|
}
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
3020
|
-
const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
|
|
3021
|
-
if (isAutoRestart && recipe.outputs) {
|
|
3022
|
-
this.log(`Found auto-restart recipe: ${recipeId}`, {
|
|
3023
|
-
topLevelAutoRestart: recipe.autoRestart,
|
|
3024
|
-
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
3025
|
-
hasOutputs: !!recipe.outputs,
|
|
3026
|
-
duration: recipe.duration
|
|
3027
|
-
});
|
|
3028
|
-
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
3029
|
-
if (condition && condition.entity) {
|
|
3030
|
-
const currentAmount = initialInventory[condition.entity] || 0;
|
|
3031
|
-
if (currentAmount < condition.maxValue) {
|
|
3032
|
-
console.log(
|
|
3033
|
-
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
|
|
3034
|
-
{
|
|
3035
|
-
currentAmount,
|
|
3036
|
-
maxValue: condition.maxValue,
|
|
3037
|
-
entity: condition.entity
|
|
3038
|
-
}
|
|
3039
|
-
);
|
|
3040
|
-
setTimeout(() => {
|
|
3041
|
-
this.executeRecipe(appIdentifier, recipeId, {});
|
|
3042
|
-
}, 1e3);
|
|
3043
|
-
}
|
|
3044
|
-
} else {
|
|
3045
|
-
console.log(
|
|
3046
|
-
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
|
|
3047
|
-
);
|
|
3048
|
-
setTimeout(() => {
|
|
3049
|
-
this.executeRecipe(appIdentifier, recipeId, {});
|
|
3050
|
-
}, 1e3);
|
|
3051
|
-
}
|
|
3052
|
-
}
|
|
3053
|
-
});
|
|
3258
|
+
const callback = this.subscriptionCallbacks.get(notification.subscriptionId);
|
|
3259
|
+
if (!callback) {
|
|
3260
|
+
console.warn(
|
|
3261
|
+
"[Venus SDK] Received update for unknown subscription:",
|
|
3262
|
+
notification.subscriptionId
|
|
3263
|
+
);
|
|
3264
|
+
return;
|
|
3054
3265
|
}
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
}
|
|
3060
|
-
completeRun(appIdentifier, runId) {
|
|
3061
|
-
this.log(`Completing run ${runId} for ${appIdentifier}`);
|
|
3062
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3063
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
3064
|
-
const config = mockSimulationConfigs.get(appIdentifier);
|
|
3065
|
-
const state = mockSimulationStates.get(appIdentifier);
|
|
3066
|
-
if (!config || !state) return;
|
|
3067
|
-
const runIndex = state.activeRuns.findIndex((r) => r.id === runId);
|
|
3068
|
-
if (runIndex === -1) return;
|
|
3069
|
-
const run = state.activeRuns[runIndex];
|
|
3070
|
-
const recipe = config.recipes?.[run.recipeId];
|
|
3071
|
-
if (!recipe) return;
|
|
3072
|
-
const outputs = {};
|
|
3073
|
-
const rng = this.createSeededRandom(runId);
|
|
3074
|
-
if (recipe.outputs) {
|
|
3075
|
-
for (const [entityId, value] of Object.entries(recipe.outputs)) {
|
|
3076
|
-
if (typeof value === "number") {
|
|
3077
|
-
outputs[entityId] = value;
|
|
3078
|
-
} else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
|
|
3079
|
-
outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
3266
|
+
try {
|
|
3267
|
+
callback(notification.updates);
|
|
3268
|
+
} catch (error) {
|
|
3269
|
+
console.error("[Venus SDK] Error in simulation subscription callback", error);
|
|
3082
3270
|
}
|
|
3083
|
-
|
|
3084
|
-
|
|
3271
|
+
}
|
|
3272
|
+
ensureValidSubscribeOptions(options) {
|
|
3273
|
+
if (typeof options !== "object" || options === null) {
|
|
3274
|
+
throw new Error("Simulation subscribe requires an options object");
|
|
3085
3275
|
}
|
|
3086
|
-
|
|
3087
|
-
|
|
3276
|
+
const opts = options;
|
|
3277
|
+
if (typeof opts.onUpdate !== "function") {
|
|
3278
|
+
throw new Error("Simulation subscribe requires an onUpdate callback");
|
|
3088
3279
|
}
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
if (isAutoRestart) {
|
|
3094
|
-
console.log(
|
|
3095
|
-
`[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
|
|
3096
|
-
{
|
|
3097
|
-
topLevelAutoRestart: recipe.autoRestart,
|
|
3098
|
-
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
3099
|
-
hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
|
|
3100
|
-
}
|
|
3280
|
+
const hasFilter = Array.isArray(opts.entities) && opts.entities.length > 0 || Array.isArray(opts.tags) && opts.tags.length > 0 || Boolean(opts.activeRuns);
|
|
3281
|
+
if (!hasFilter) {
|
|
3282
|
+
throw new Error(
|
|
3283
|
+
"Simulation subscribe requires at least one filter (entities, tags, activeRuns)"
|
|
3101
3284
|
);
|
|
3102
|
-
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
3103
|
-
if (condition) {
|
|
3104
|
-
const currentAmount = state.inventory[condition.entity] || 0;
|
|
3105
|
-
if (currentAmount < condition.maxValue) {
|
|
3106
|
-
console.log(
|
|
3107
|
-
`[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
|
|
3108
|
-
{
|
|
3109
|
-
currentAmount,
|
|
3110
|
-
maxValue: condition.maxValue,
|
|
3111
|
-
entity: condition.entity
|
|
3112
|
-
}
|
|
3113
|
-
);
|
|
3114
|
-
setTimeout(() => {
|
|
3115
|
-
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
3116
|
-
}, 1e3);
|
|
3117
|
-
}
|
|
3118
|
-
} else {
|
|
3119
|
-
console.log(
|
|
3120
|
-
`[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
|
|
3121
|
-
);
|
|
3122
|
-
setTimeout(() => {
|
|
3123
|
-
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
3124
|
-
}, 1e3);
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3127
|
-
console.log(
|
|
3128
|
-
`[Venus Simulation Mock] Completed run ${runId}, outputs:`,
|
|
3129
|
-
outputs
|
|
3130
|
-
);
|
|
3131
|
-
}
|
|
3132
|
-
createSeededRandom(seed) {
|
|
3133
|
-
let hash = 0;
|
|
3134
|
-
for (let i = 0; i < seed.length; i++) {
|
|
3135
|
-
const char = seed.charCodeAt(i);
|
|
3136
|
-
hash = (hash << 5) - hash + char;
|
|
3137
|
-
hash = hash & hash;
|
|
3138
3285
|
}
|
|
3139
|
-
return () => {
|
|
3140
|
-
hash = (hash * 9301 + 49297) % 233280;
|
|
3141
|
-
return hash / 233280;
|
|
3142
|
-
};
|
|
3143
|
-
}
|
|
3144
|
-
applyEffects(state, effects) {
|
|
3145
|
-
if (!effects || !Array.isArray(effects)) return;
|
|
3146
|
-
for (const effect of effects) {
|
|
3147
|
-
switch (effect.type) {
|
|
3148
|
-
case "set":
|
|
3149
|
-
state.inventory[effect.target] = effect.value;
|
|
3150
|
-
console.log(
|
|
3151
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
|
|
3152
|
-
);
|
|
3153
|
-
break;
|
|
3154
|
-
case "add":
|
|
3155
|
-
state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
|
|
3156
|
-
console.log(
|
|
3157
|
-
`[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
|
|
3158
|
-
);
|
|
3159
|
-
break;
|
|
3160
|
-
case "multiply":
|
|
3161
|
-
state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
|
|
3162
|
-
console.log(
|
|
3163
|
-
`[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3164
|
-
);
|
|
3165
|
-
break;
|
|
3166
|
-
case "min":
|
|
3167
|
-
state.inventory[effect.target] = Math.max(
|
|
3168
|
-
state.inventory[effect.target] || 0,
|
|
3169
|
-
effect.value
|
|
3170
|
-
);
|
|
3171
|
-
console.log(
|
|
3172
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3173
|
-
);
|
|
3174
|
-
break;
|
|
3175
|
-
case "max":
|
|
3176
|
-
state.inventory[effect.target] = Math.min(
|
|
3177
|
-
state.inventory[effect.target] || 0,
|
|
3178
|
-
effect.value
|
|
3179
|
-
);
|
|
3180
|
-
console.log(
|
|
3181
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3182
|
-
);
|
|
3183
|
-
break;
|
|
3184
|
-
case "enable_recipe":
|
|
3185
|
-
if (state.disabledRecipes?.includes(effect.target)) {
|
|
3186
|
-
state.disabledRecipes = state.disabledRecipes.filter(
|
|
3187
|
-
(r) => r !== effect.target
|
|
3188
|
-
);
|
|
3189
|
-
console.log(
|
|
3190
|
-
`[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
|
|
3191
|
-
);
|
|
3192
|
-
}
|
|
3193
|
-
break;
|
|
3194
|
-
case "disable_recipe":
|
|
3195
|
-
if (!state.disabledRecipes) state.disabledRecipes = [];
|
|
3196
|
-
if (!state.disabledRecipes.includes(effect.target)) {
|
|
3197
|
-
state.disabledRecipes.push(effect.target);
|
|
3198
|
-
console.log(
|
|
3199
|
-
`[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
|
|
3200
|
-
);
|
|
3201
|
-
}
|
|
3202
|
-
break;
|
|
3203
|
-
case "trigger_recipe":
|
|
3204
|
-
console.log(
|
|
3205
|
-
`[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
|
|
3206
|
-
);
|
|
3207
|
-
break;
|
|
3208
|
-
default:
|
|
3209
|
-
console.warn(
|
|
3210
|
-
`[Venus Simulation Mock] Unknown effect type: ${effect.type}`
|
|
3211
|
-
);
|
|
3212
|
-
}
|
|
3213
|
-
}
|
|
3214
|
-
}
|
|
3215
|
-
async getConfigAsync() {
|
|
3216
|
-
console.log("[Venus Simulation Mock] getConfigAsync called");
|
|
3217
|
-
const appIdentifier = this.appId;
|
|
3218
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3219
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
3220
|
-
version: "1.0",
|
|
3221
|
-
entities: {},
|
|
3222
|
-
recipes: {}
|
|
3223
|
-
};
|
|
3224
|
-
return config;
|
|
3225
|
-
}
|
|
3226
|
-
async getStateAsync(roomId) {
|
|
3227
|
-
this.log("getStateAsync called:", roomId);
|
|
3228
|
-
const appIdentifier = this.appId;
|
|
3229
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
3230
|
-
let state = mockSimulationStates.get(appIdentifier);
|
|
3231
|
-
if (!state) {
|
|
3232
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
3233
|
-
}
|
|
3234
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3235
|
-
return {
|
|
3236
|
-
...state,
|
|
3237
|
-
roomId,
|
|
3238
|
-
configuration: mockSimulationConfigs.get(appIdentifier)
|
|
3239
|
-
};
|
|
3240
|
-
}
|
|
3241
|
-
async assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
3242
|
-
this.log("assignItemToSlotAsync called:", {
|
|
3243
|
-
containerId,
|
|
3244
|
-
slotId,
|
|
3245
|
-
itemId
|
|
3246
|
-
});
|
|
3247
|
-
return { success: true, message: "Mock assignment successful" };
|
|
3248
|
-
}
|
|
3249
|
-
async removeItemFromSlotAsync(containerId, slotId) {
|
|
3250
|
-
this.log("removeItemFromSlotAsync called:", {
|
|
3251
|
-
containerId,
|
|
3252
|
-
slotId
|
|
3253
|
-
});
|
|
3254
|
-
return { success: true, message: "Mock removal successful" };
|
|
3255
3286
|
}
|
|
3256
3287
|
};
|
|
3257
3288
|
|
|
3258
3289
|
// src/simulation/index.ts
|
|
3259
3290
|
function initializeSimulation(venusApi, host) {
|
|
3260
|
-
console.log("[Venus SDK] Initializing new Simulation Api");
|
|
3261
3291
|
venusApi.simulation = {
|
|
3262
3292
|
isEnabled: () => true
|
|
3263
3293
|
};
|
|
3264
3294
|
venusApi.simulation.getConfigAsync = () => {
|
|
3265
3295
|
return host.simulation.getConfigAsync();
|
|
3266
3296
|
};
|
|
3267
|
-
venusApi.simulation.getStateAsync = (
|
|
3268
|
-
return host.simulation.getStateAsync(
|
|
3297
|
+
venusApi.simulation.getStateAsync = (roomId) => {
|
|
3298
|
+
return host.simulation.getStateAsync(roomId);
|
|
3269
3299
|
};
|
|
3270
3300
|
venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
|
|
3271
3301
|
return host.simulation.executeRecipeAsync(recipeId, inputs, options);
|
|
@@ -3276,31 +3306,17 @@ function initializeSimulation(venusApi, host) {
|
|
|
3276
3306
|
venusApi.simulation.collectRecipeAsync = (runId) => {
|
|
3277
3307
|
return host.simulation.collectRecipeAsync(runId);
|
|
3278
3308
|
};
|
|
3279
|
-
venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs,
|
|
3280
|
-
return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs,
|
|
3281
|
-
roomId,
|
|
3282
|
-
...options
|
|
3283
|
-
});
|
|
3309
|
+
venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, options) => {
|
|
3310
|
+
return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, options);
|
|
3284
3311
|
};
|
|
3285
|
-
venusApi.simulation.triggerRecipeChainAsync = (recipeId,
|
|
3286
|
-
return host.simulation.triggerRecipeChainAsync(recipeId,
|
|
3287
|
-
context,
|
|
3288
|
-
roomId
|
|
3289
|
-
});
|
|
3312
|
+
venusApi.simulation.triggerRecipeChainAsync = (recipeId, options) => {
|
|
3313
|
+
return host.simulation.triggerRecipeChainAsync(recipeId, options);
|
|
3290
3314
|
};
|
|
3291
|
-
venusApi.simulation.getAvailableRecipesAsync = async (
|
|
3292
|
-
|
|
3293
|
-
roomId,
|
|
3294
|
-
includeActorRecipes
|
|
3295
|
-
});
|
|
3296
|
-
return result.recipes;
|
|
3315
|
+
venusApi.simulation.getAvailableRecipesAsync = async (options) => {
|
|
3316
|
+
return host.simulation.getAvailableRecipesAsync(options);
|
|
3297
3317
|
};
|
|
3298
|
-
venusApi.simulation.getRecipeRequirementsAsync = (
|
|
3299
|
-
return host.simulation.getRecipeRequirementsAsync(
|
|
3300
|
-
recipeId,
|
|
3301
|
-
entity,
|
|
3302
|
-
batchAmount: amount
|
|
3303
|
-
});
|
|
3318
|
+
venusApi.simulation.getRecipeRequirementsAsync = (recipe) => {
|
|
3319
|
+
return host.simulation.getRecipeRequirementsAsync(recipe);
|
|
3304
3320
|
};
|
|
3305
3321
|
venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
|
|
3306
3322
|
return host.simulation.getBatchRecipeRequirementsAsync(recipes);
|
|
@@ -3343,9 +3359,6 @@ function initializeSimulation(venusApi, host) {
|
|
|
3343
3359
|
itemId
|
|
3344
3360
|
);
|
|
3345
3361
|
};
|
|
3346
|
-
venusApi.simulation.sumContributions = (contributions) => {
|
|
3347
|
-
return host.simulation.sumContributions(contributions);
|
|
3348
|
-
};
|
|
3349
3362
|
}
|
|
3350
3363
|
|
|
3351
3364
|
// src/time/utils.ts
|
|
@@ -3364,9 +3377,11 @@ function isPacificDaylightTime(date) {
|
|
|
3364
3377
|
|
|
3365
3378
|
// src/time/HostTimeApi.ts
|
|
3366
3379
|
var HostTimeApi = class {
|
|
3367
|
-
constructor(rpcClient) {
|
|
3380
|
+
constructor(rpcClient, venusApi) {
|
|
3368
3381
|
__publicField(this, "rpcClient");
|
|
3382
|
+
__publicField(this, "venusApi");
|
|
3369
3383
|
this.rpcClient = rpcClient;
|
|
3384
|
+
this.venusApi = venusApi;
|
|
3370
3385
|
}
|
|
3371
3386
|
async requestTimeAsync() {
|
|
3372
3387
|
const response = await this.rpcClient.call(
|
|
@@ -3376,13 +3391,7 @@ var HostTimeApi = class {
|
|
|
3376
3391
|
return response;
|
|
3377
3392
|
}
|
|
3378
3393
|
formatTime(timestamp, options) {
|
|
3379
|
-
|
|
3380
|
-
const windowVenus = window.venus;
|
|
3381
|
-
if (windowVenus._config.locale) {
|
|
3382
|
-
locale = windowVenus._config.locale;
|
|
3383
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3384
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
3385
|
-
}
|
|
3394
|
+
const locale = this.venusApi.getLocale();
|
|
3386
3395
|
const date = new Date(timestamp);
|
|
3387
3396
|
const dateTimeOptions = {
|
|
3388
3397
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -3394,13 +3403,7 @@ var HostTimeApi = class {
|
|
|
3394
3403
|
}
|
|
3395
3404
|
formatNumber(value, options) {
|
|
3396
3405
|
try {
|
|
3397
|
-
|
|
3398
|
-
const windowVenus = window.venus;
|
|
3399
|
-
if (windowVenus._config.locale) {
|
|
3400
|
-
locale = windowVenus._config.locale;
|
|
3401
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3402
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
3403
|
-
}
|
|
3406
|
+
const locale = this.venusApi.getLocale();
|
|
3404
3407
|
const numberOptions = {
|
|
3405
3408
|
style: options?.style || "decimal",
|
|
3406
3409
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
@@ -3463,18 +3466,17 @@ var MockTimeApi = class {
|
|
|
3463
3466
|
this.venusApi = venusApi;
|
|
3464
3467
|
}
|
|
3465
3468
|
formatNumber(value, options) {
|
|
3466
|
-
const locale = this.getLocale();
|
|
3469
|
+
const locale = this.venusApi.getLocale();
|
|
3467
3470
|
const numberOptions = {
|
|
3468
3471
|
style: options?.style || "decimal",
|
|
3469
3472
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
3470
3473
|
maximumFractionDigits: options?.maximumFractionDigits || 2,
|
|
3471
3474
|
...options
|
|
3472
3475
|
};
|
|
3473
|
-
console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
|
|
3474
3476
|
return value.toLocaleString(locale, numberOptions);
|
|
3475
3477
|
}
|
|
3476
3478
|
formatTime(timestamp, options) {
|
|
3477
|
-
const locale = this.getLocale();
|
|
3479
|
+
const locale = this.venusApi.getLocale();
|
|
3478
3480
|
const date = new Date(timestamp);
|
|
3479
3481
|
const dateTimeOptions = {
|
|
3480
3482
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -3482,13 +3484,9 @@ var MockTimeApi = class {
|
|
|
3482
3484
|
hour12: options.hour12 !== void 0 ? options.hour12 : true,
|
|
3483
3485
|
...options
|
|
3484
3486
|
};
|
|
3485
|
-
console.log(
|
|
3486
|
-
`[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
|
|
3487
|
-
);
|
|
3488
3487
|
return date.toLocaleString(locale, dateTimeOptions);
|
|
3489
3488
|
}
|
|
3490
3489
|
async getFutureTimeAsync(options) {
|
|
3491
|
-
console.log("[Venus Mock] Getting future time with options:", options);
|
|
3492
3490
|
const timeInfo = await this.requestTimeAsync();
|
|
3493
3491
|
const serverTime = new Date(timeInfo.serverTime);
|
|
3494
3492
|
const result = new Date(serverTime);
|
|
@@ -3533,7 +3531,6 @@ var MockTimeApi = class {
|
|
|
3533
3531
|
return result.getTime();
|
|
3534
3532
|
}
|
|
3535
3533
|
async requestTimeAsync() {
|
|
3536
|
-
console.log("[Venus Mock] Requesting time");
|
|
3537
3534
|
await createMockDelay(MOCK_DELAYS.short);
|
|
3538
3535
|
const venusApi = this.venusApi;
|
|
3539
3536
|
const mockOffset = venusApi._mock.serverTimeOffset || 2500;
|
|
@@ -3547,23 +3544,8 @@ var MockTimeApi = class {
|
|
|
3547
3544
|
formattedTime: new Date(localTime).toISOString(),
|
|
3548
3545
|
locale: venusApi._mock.user?.locale || "en-US"
|
|
3549
3546
|
};
|
|
3550
|
-
console.log("[Venus Mock] Time response:", {
|
|
3551
|
-
serverTime: new Date(timeInfo.serverTime).toISOString(),
|
|
3552
|
-
localTime: new Date(timeInfo.localTime).toISOString(),
|
|
3553
|
-
timezoneOffset: timeInfo.timezoneOffset
|
|
3554
|
-
});
|
|
3555
3547
|
return timeInfo;
|
|
3556
3548
|
}
|
|
3557
|
-
getLocale() {
|
|
3558
|
-
const venusApi = this.venusApi;
|
|
3559
|
-
let locale = "en-US";
|
|
3560
|
-
if (venusApi._mock.user && venusApi._mock.user.locale) {
|
|
3561
|
-
locale = venusApi._mock.user.locale;
|
|
3562
|
-
} else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
|
|
3563
|
-
locale = venusApi._mock.environment.browserInfo.language;
|
|
3564
|
-
}
|
|
3565
|
-
return locale;
|
|
3566
|
-
}
|
|
3567
3549
|
};
|
|
3568
3550
|
|
|
3569
3551
|
// src/time/index.ts
|
|
@@ -3583,11 +3565,35 @@ function initializeTime(venusApi, host) {
|
|
|
3583
3565
|
}
|
|
3584
3566
|
|
|
3585
3567
|
// src/version.ts
|
|
3586
|
-
var SDK_VERSION = "3.0
|
|
3568
|
+
var SDK_VERSION = "3.2.1-beta.0";
|
|
3587
3569
|
|
|
3588
|
-
// src/shared-assets/
|
|
3589
|
-
|
|
3590
|
-
|
|
3570
|
+
// src/shared-assets/base64Utils.ts
|
|
3571
|
+
function base64ToArrayBuffer(base64) {
|
|
3572
|
+
const binaryString = atob(base64);
|
|
3573
|
+
const len = binaryString.length;
|
|
3574
|
+
const bytes = new Uint8Array(len);
|
|
3575
|
+
for (let i = 0; i < len; i++) {
|
|
3576
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
3577
|
+
}
|
|
3578
|
+
return bytes.buffer;
|
|
3579
|
+
}
|
|
3580
|
+
function base64ToUtf8(base64) {
|
|
3581
|
+
if (typeof TextDecoder !== "undefined") {
|
|
3582
|
+
const decoder = new TextDecoder("utf-8");
|
|
3583
|
+
const buffer = base64ToArrayBuffer(base64);
|
|
3584
|
+
return decoder.decode(new Uint8Array(buffer));
|
|
3585
|
+
}
|
|
3586
|
+
if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
|
|
3587
|
+
const BufferCtor = globalThis.Buffer;
|
|
3588
|
+
return BufferCtor.from(base64, "base64").toString("utf-8");
|
|
3589
|
+
}
|
|
3590
|
+
const binaryString = atob(base64);
|
|
3591
|
+
let result = "";
|
|
3592
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
3593
|
+
result += String.fromCharCode(binaryString.charCodeAt(i));
|
|
3594
|
+
}
|
|
3595
|
+
return decodeURIComponent(escape(result));
|
|
3596
|
+
}
|
|
3591
3597
|
|
|
3592
3598
|
// src/shared-assets/RpcSharedAssetsApi.ts
|
|
3593
3599
|
var RpcSharedAssetsApi = class {
|
|
@@ -3597,46 +3603,22 @@ var RpcSharedAssetsApi = class {
|
|
|
3597
3603
|
this.rpcClient = rpcClient;
|
|
3598
3604
|
this.venusApi = venusApi;
|
|
3599
3605
|
}
|
|
3600
|
-
async
|
|
3601
|
-
try {
|
|
3602
|
-
const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
|
|
3603
|
-
assetKey: "burgerTimeCoreBundle"
|
|
3604
|
-
});
|
|
3605
|
-
return base64ToArrayBuffer(response.base64Data);
|
|
3606
|
-
} catch (err) {
|
|
3607
|
-
try {
|
|
3608
|
-
const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
|
|
3609
|
-
return await blob.arrayBuffer();
|
|
3610
|
-
} catch (e) {
|
|
3611
|
-
throw new Error("Failed to load burgerTimeAssetsBundle");
|
|
3612
|
-
}
|
|
3613
|
-
}
|
|
3614
|
-
}
|
|
3615
|
-
async loadCharactersBundle() {
|
|
3606
|
+
async loadAssetsBundle(game, bundleKey, fileType = "stow") {
|
|
3616
3607
|
try {
|
|
3617
3608
|
const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
|
|
3618
|
-
assetKey:
|
|
3609
|
+
assetKey: bundleKey
|
|
3619
3610
|
});
|
|
3620
3611
|
return base64ToArrayBuffer(response.base64Data);
|
|
3621
3612
|
} catch (err) {
|
|
3622
3613
|
try {
|
|
3623
|
-
const blob = await this.venusApi.cdn.fetchBlob(
|
|
3614
|
+
const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
|
|
3624
3615
|
return await blob.arrayBuffer();
|
|
3625
3616
|
} catch (e) {
|
|
3626
|
-
throw new Error(
|
|
3617
|
+
throw new Error(`Failed to load ${bundleKey}`);
|
|
3627
3618
|
}
|
|
3628
3619
|
}
|
|
3629
3620
|
}
|
|
3630
3621
|
};
|
|
3631
|
-
function base64ToArrayBuffer(base64) {
|
|
3632
|
-
const binaryString = atob(base64);
|
|
3633
|
-
const len = binaryString.length;
|
|
3634
|
-
const bytes = new Uint8Array(len);
|
|
3635
|
-
for (let i = 0; i < len; i++) {
|
|
3636
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
3637
|
-
}
|
|
3638
|
-
return bytes.buffer;
|
|
3639
|
-
}
|
|
3640
3622
|
|
|
3641
3623
|
// src/shared-assets/MockSharedAssetsApi.ts
|
|
3642
3624
|
var MockSharedAssetsApi = class {
|
|
@@ -3644,57 +3626,253 @@ var MockSharedAssetsApi = class {
|
|
|
3644
3626
|
__publicField(this, "venusApi");
|
|
3645
3627
|
this.venusApi = venusApi;
|
|
3646
3628
|
}
|
|
3647
|
-
async
|
|
3648
|
-
const blob = await this.venusApi.cdn.fetchBlob(
|
|
3649
|
-
return await blob.arrayBuffer();
|
|
3650
|
-
}
|
|
3651
|
-
async loadCharactersBundle() {
|
|
3652
|
-
const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
|
|
3629
|
+
async loadAssetsBundle(game, bundleKey, fileType = "stow") {
|
|
3630
|
+
const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
|
|
3653
3631
|
return await blob.arrayBuffer();
|
|
3654
3632
|
}
|
|
3655
3633
|
};
|
|
3656
3634
|
|
|
3635
|
+
// src/shared-assets/embeddedLibrariesManifest.ts
|
|
3636
|
+
var DEFAULT_SHARED_LIB_CDN_BASE = "https://venus-static-01293ak.web.app/libs";
|
|
3637
|
+
var EMBEDDED_LIBRARIES = [
|
|
3638
|
+
{
|
|
3639
|
+
libraryKey: "phaser@3.90.0",
|
|
3640
|
+
assetKey: "library:phaser@3.90.0",
|
|
3641
|
+
packageName: "phaser",
|
|
3642
|
+
version: "3.90.0",
|
|
3643
|
+
globalVar: "Phaser",
|
|
3644
|
+
cdnPath: "phaser/3.90.0/phaser.min.js",
|
|
3645
|
+
moduleSpecifiers: [{ match: "exact", value: "phaser" }],
|
|
3646
|
+
loadStage: 0,
|
|
3647
|
+
enabled: true
|
|
3648
|
+
},
|
|
3649
|
+
{
|
|
3650
|
+
libraryKey: "react@18.3.1",
|
|
3651
|
+
assetKey: "library:react@18.3.1",
|
|
3652
|
+
packageName: "react",
|
|
3653
|
+
version: "18.3.1",
|
|
3654
|
+
globalVar: "React",
|
|
3655
|
+
cdnPath: "react/18.3.1/react.production.min.js",
|
|
3656
|
+
moduleSpecifiers: [
|
|
3657
|
+
{ match: "exact", value: "react", behavior: "namespace" },
|
|
3658
|
+
{ match: "exact", value: "react/jsx-runtime", behavior: "react-jsx-runtime" },
|
|
3659
|
+
{
|
|
3660
|
+
match: "exact",
|
|
3661
|
+
value: "react/jsx-dev-runtime",
|
|
3662
|
+
behavior: "react-jsx-dev-runtime"
|
|
3663
|
+
}
|
|
3664
|
+
],
|
|
3665
|
+
loadStage: 0,
|
|
3666
|
+
// Must load before ReactDOM
|
|
3667
|
+
enabled: true
|
|
3668
|
+
},
|
|
3669
|
+
{
|
|
3670
|
+
libraryKey: "react-dom@18.3.1",
|
|
3671
|
+
assetKey: "library:react-dom@18.3.1",
|
|
3672
|
+
packageName: "react-dom",
|
|
3673
|
+
version: "18.3.1",
|
|
3674
|
+
globalVar: "ReactDOM",
|
|
3675
|
+
cdnPath: "react-dom/18.3.1/react-dom.production.min.js",
|
|
3676
|
+
moduleSpecifiers: [
|
|
3677
|
+
{ match: "exact", value: "react-dom", behavior: "namespace" },
|
|
3678
|
+
{ match: "exact", value: "react-dom/client", behavior: "namespace" }
|
|
3679
|
+
],
|
|
3680
|
+
loadStage: 1,
|
|
3681
|
+
// Depends on React (stage 0)
|
|
3682
|
+
enabled: true
|
|
3683
|
+
},
|
|
3684
|
+
{
|
|
3685
|
+
libraryKey: "three@0.170.0",
|
|
3686
|
+
assetKey: "library:three@0.170.0",
|
|
3687
|
+
packageName: "three",
|
|
3688
|
+
version: "0.170.0",
|
|
3689
|
+
globalVar: "THREE",
|
|
3690
|
+
cdnPath: "three/r170/three.min.js",
|
|
3691
|
+
moduleSpecifiers: [
|
|
3692
|
+
{ match: "exact", value: "three", behavior: "namespace" },
|
|
3693
|
+
{ match: "prefix", value: "three/examples/jsm/", behavior: "namespace" }
|
|
3694
|
+
],
|
|
3695
|
+
loadStage: 0,
|
|
3696
|
+
enabled: true
|
|
3697
|
+
},
|
|
3698
|
+
{
|
|
3699
|
+
libraryKey: "matter-js@0.19.0",
|
|
3700
|
+
assetKey: "library:matter-js@0.19.0",
|
|
3701
|
+
packageName: "matter-js",
|
|
3702
|
+
version: "0.19.0",
|
|
3703
|
+
globalVar: "Matter",
|
|
3704
|
+
cdnPath: "matter-js/0.19.0/matter.min.js",
|
|
3705
|
+
moduleSpecifiers: [{ match: "exact", value: "matter-js" }],
|
|
3706
|
+
loadStage: 0,
|
|
3707
|
+
enabled: true
|
|
3708
|
+
},
|
|
3709
|
+
{
|
|
3710
|
+
libraryKey: "inkjs@2.2.0",
|
|
3711
|
+
assetKey: "library:inkjs@2.2.0",
|
|
3712
|
+
packageName: "inkjs",
|
|
3713
|
+
version: "2.2.0",
|
|
3714
|
+
globalVar: "inkjs",
|
|
3715
|
+
cdnPath: "inkjs/2.2.0/ink.min.js",
|
|
3716
|
+
moduleSpecifiers: [{ match: "exact", value: "inkjs" }],
|
|
3717
|
+
loadStage: 0,
|
|
3718
|
+
enabled: true
|
|
3719
|
+
},
|
|
3720
|
+
{
|
|
3721
|
+
libraryKey: "zustand@5.0.3",
|
|
3722
|
+
assetKey: "library:zustand@5.0.3",
|
|
3723
|
+
packageName: "zustand",
|
|
3724
|
+
version: "5.0.3",
|
|
3725
|
+
globalVar: "zustand",
|
|
3726
|
+
cdnPath: "zustand/5.0.3/zustand.min.js",
|
|
3727
|
+
moduleSpecifiers: [
|
|
3728
|
+
{ match: "exact", value: "zustand" },
|
|
3729
|
+
{ match: "exact", value: "zustand/middleware" }
|
|
3730
|
+
],
|
|
3731
|
+
loadStage: 0,
|
|
3732
|
+
enabled: true
|
|
3733
|
+
},
|
|
3734
|
+
{
|
|
3735
|
+
libraryKey: "ammo.js@2024.11",
|
|
3736
|
+
assetKey: "library:ammo.js@2024.11",
|
|
3737
|
+
packageName: "ammo.js",
|
|
3738
|
+
version: "2024.11",
|
|
3739
|
+
globalVar: "Ammo",
|
|
3740
|
+
cdnPath: "ammo/2024.11/ammo.js",
|
|
3741
|
+
moduleSpecifiers: [
|
|
3742
|
+
{ match: "exact", value: "ammo.js" },
|
|
3743
|
+
{ match: "exact", value: "ammo.js/builds/ammo.wasm.js" }
|
|
3744
|
+
],
|
|
3745
|
+
loadStage: 0,
|
|
3746
|
+
enabled: false
|
|
3747
|
+
// Not ready yet - WASM loading needs additional work
|
|
3748
|
+
}
|
|
3749
|
+
];
|
|
3750
|
+
var EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARIES.reduce(
|
|
3751
|
+
(acc, lib) => {
|
|
3752
|
+
acc[lib.libraryKey] = lib;
|
|
3753
|
+
return acc;
|
|
3754
|
+
},
|
|
3755
|
+
{}
|
|
3756
|
+
);
|
|
3757
|
+
var MODULE_TO_LIBRARY_SPECIFIERS = EMBEDDED_LIBRARIES.filter(
|
|
3758
|
+
(lib) => lib.enabled
|
|
3759
|
+
).flatMap(
|
|
3760
|
+
(lib) => lib.moduleSpecifiers.map((specifier) => ({
|
|
3761
|
+
...specifier,
|
|
3762
|
+
libraryKey: lib.libraryKey
|
|
3763
|
+
}))
|
|
3764
|
+
);
|
|
3765
|
+
function getLibraryDefinition(libraryKey) {
|
|
3766
|
+
const definition = EMBEDDED_LIBRARY_BY_KEY[libraryKey];
|
|
3767
|
+
if (!definition) {
|
|
3768
|
+
const availableKeys = Object.keys(EMBEDDED_LIBRARY_BY_KEY).join(", ");
|
|
3769
|
+
throw new Error(
|
|
3770
|
+
`Unsupported embedded library: ${libraryKey}. Available libraries: ${availableKeys}`
|
|
3771
|
+
);
|
|
3772
|
+
}
|
|
3773
|
+
return definition;
|
|
3774
|
+
}
|
|
3775
|
+
|
|
3776
|
+
// src/leaderboard/utils.ts
|
|
3777
|
+
var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
|
|
3778
|
+
var HASH_ALGORITHM_NODE = "sha256";
|
|
3779
|
+
async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
|
|
3780
|
+
const payload = `score:${score}|duration:${duration}|token:${token}`;
|
|
3781
|
+
const fullPayload = `${payload}|nonce:${sealingNonce}`;
|
|
3782
|
+
const encoder = new TextEncoder();
|
|
3783
|
+
const keyData = encoder.encode(sealingSecret);
|
|
3784
|
+
const messageData = encoder.encode(fullPayload);
|
|
3785
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
3786
|
+
"raw",
|
|
3787
|
+
keyData,
|
|
3788
|
+
{ name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
|
|
3789
|
+
false,
|
|
3790
|
+
["sign"]
|
|
3791
|
+
);
|
|
3792
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
|
|
3793
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3794
|
+
}
|
|
3795
|
+
|
|
3657
3796
|
// src/leaderboard/RpcLeaderboardApi.ts
|
|
3658
3797
|
var RpcLeaderboardApi = class {
|
|
3659
3798
|
constructor(rpcClient) {
|
|
3660
3799
|
__publicField(this, "rpcClient");
|
|
3800
|
+
/** Cache of score tokens for automatic hash computation */
|
|
3801
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
3661
3802
|
this.rpcClient = rpcClient;
|
|
3662
3803
|
}
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3804
|
+
/**
|
|
3805
|
+
* Create a score token for submitting a score.
|
|
3806
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
3807
|
+
*
|
|
3808
|
+
* @param mode - Optional game mode
|
|
3809
|
+
* @returns Score token with sealing data if enabled
|
|
3810
|
+
*/
|
|
3811
|
+
async createScoreToken(mode) {
|
|
3812
|
+
const token = await this.rpcClient.call(
|
|
3813
|
+
"H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
|
|
3666
3814
|
mode ? { mode } : {}
|
|
3667
3815
|
);
|
|
3816
|
+
this.tokenCache.set(token.token, token);
|
|
3817
|
+
return token;
|
|
3668
3818
|
}
|
|
3669
|
-
|
|
3819
|
+
/**
|
|
3820
|
+
* Submit a score to the leaderboard.
|
|
3821
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
3822
|
+
*
|
|
3823
|
+
* @param params - Score submission parameters
|
|
3824
|
+
* @returns Submission result with acceptance status and rank
|
|
3825
|
+
* @throws Error if token not found in cache
|
|
3826
|
+
*/
|
|
3827
|
+
async submitScore(params) {
|
|
3828
|
+
let hash;
|
|
3829
|
+
if (params.token) {
|
|
3830
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
3831
|
+
if (!cachedToken) {
|
|
3832
|
+
throw new Error(
|
|
3833
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
3834
|
+
);
|
|
3835
|
+
}
|
|
3836
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
3837
|
+
hash = await computeScoreHash(
|
|
3838
|
+
params.score,
|
|
3839
|
+
params.duration,
|
|
3840
|
+
params.token,
|
|
3841
|
+
cachedToken.sealingNonce,
|
|
3842
|
+
cachedToken.sealingSecret
|
|
3843
|
+
);
|
|
3844
|
+
}
|
|
3845
|
+
this.tokenCache.delete(params.token);
|
|
3846
|
+
}
|
|
3670
3847
|
return this.rpcClient.call(
|
|
3671
3848
|
"H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
|
|
3672
3849
|
{
|
|
3673
|
-
|
|
3674
|
-
score,
|
|
3675
|
-
|
|
3676
|
-
mode:
|
|
3677
|
-
telemetry:
|
|
3678
|
-
metadata:
|
|
3679
|
-
hash
|
|
3850
|
+
token: params.token,
|
|
3851
|
+
score: params.score,
|
|
3852
|
+
duration: params.duration,
|
|
3853
|
+
mode: params.mode,
|
|
3854
|
+
telemetry: params.telemetry,
|
|
3855
|
+
metadata: params.metadata,
|
|
3856
|
+
hash
|
|
3857
|
+
// undefined if no sealing, computed if sealing enabled
|
|
3680
3858
|
}
|
|
3681
3859
|
);
|
|
3682
3860
|
}
|
|
3683
|
-
|
|
3861
|
+
getPagedScores(options) {
|
|
3684
3862
|
return this.rpcClient.call(
|
|
3685
|
-
"
|
|
3863
|
+
"H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
|
|
3686
3864
|
options ?? {}
|
|
3687
3865
|
);
|
|
3688
3866
|
}
|
|
3689
|
-
|
|
3867
|
+
getMyRank(options) {
|
|
3690
3868
|
return this.rpcClient.call(
|
|
3691
|
-
"
|
|
3869
|
+
"H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
|
|
3692
3870
|
options ?? {}
|
|
3693
3871
|
);
|
|
3694
3872
|
}
|
|
3695
|
-
|
|
3873
|
+
getPodiumScores(options) {
|
|
3696
3874
|
return this.rpcClient.call(
|
|
3697
|
-
"
|
|
3875
|
+
"H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
|
|
3698
3876
|
options ?? {}
|
|
3699
3877
|
);
|
|
3700
3878
|
}
|
|
@@ -3703,17 +3881,31 @@ var RpcLeaderboardApi = class {
|
|
|
3703
3881
|
// src/leaderboard/MockLeaderboardApi.ts
|
|
3704
3882
|
var MockLeaderboardApi = class {
|
|
3705
3883
|
constructor(options) {
|
|
3706
|
-
__publicField(this, "
|
|
3884
|
+
__publicField(this, "tokens", /* @__PURE__ */ new Map());
|
|
3885
|
+
/** Cache of score tokens for automatic hash computation */
|
|
3886
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
3707
3887
|
__publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
|
|
3708
|
-
__publicField(this, "
|
|
3709
|
-
__publicField(this, "
|
|
3710
|
-
|
|
3711
|
-
|
|
3888
|
+
__publicField(this, "tokenCounter", 0);
|
|
3889
|
+
__publicField(this, "enableScoreSealing", false);
|
|
3890
|
+
__publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
|
|
3891
|
+
if (options?.enableScoreSealing) {
|
|
3892
|
+
this.enableScoreSealing = true;
|
|
3893
|
+
}
|
|
3894
|
+
if (options?.scoreSealingSecret) {
|
|
3895
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
3712
3896
|
}
|
|
3713
3897
|
}
|
|
3898
|
+
/**
|
|
3899
|
+
* Configure mock leaderboard settings
|
|
3900
|
+
*
|
|
3901
|
+
* @param options - Configuration options
|
|
3902
|
+
*/
|
|
3714
3903
|
configure(options) {
|
|
3715
|
-
if (typeof options.
|
|
3716
|
-
this.
|
|
3904
|
+
if (typeof options.enableScoreSealing === "boolean") {
|
|
3905
|
+
this.enableScoreSealing = options.enableScoreSealing;
|
|
3906
|
+
}
|
|
3907
|
+
if (options.scoreSealingSecret) {
|
|
3908
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
3717
3909
|
}
|
|
3718
3910
|
}
|
|
3719
3911
|
generateNonce() {
|
|
@@ -3730,83 +3922,149 @@ var MockLeaderboardApi = class {
|
|
|
3730
3922
|
}
|
|
3731
3923
|
return this.entriesByMode.get(key);
|
|
3732
3924
|
}
|
|
3733
|
-
|
|
3734
|
-
|
|
3925
|
+
/**
|
|
3926
|
+
* Create a mock score token for testing.
|
|
3927
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
3928
|
+
*
|
|
3929
|
+
* @param mode - Optional game mode
|
|
3930
|
+
* @returns Score token with sealing data if enabled
|
|
3931
|
+
*/
|
|
3932
|
+
async createScoreToken(mode) {
|
|
3933
|
+
const token = `mock_token_${++this.tokenCounter}`;
|
|
3735
3934
|
const startTime = Date.now();
|
|
3736
3935
|
const expiresAt = startTime + 36e5;
|
|
3737
3936
|
const resolvedMode = mode || "default";
|
|
3738
|
-
const
|
|
3739
|
-
this.
|
|
3740
|
-
|
|
3937
|
+
const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
|
|
3938
|
+
const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
|
|
3939
|
+
this.tokens.set(token, {
|
|
3940
|
+
id: token,
|
|
3741
3941
|
expiresAt,
|
|
3742
3942
|
mode: resolvedMode,
|
|
3743
|
-
|
|
3943
|
+
sealingNonce,
|
|
3744
3944
|
used: false
|
|
3745
3945
|
});
|
|
3746
|
-
|
|
3747
|
-
|
|
3946
|
+
const result = {
|
|
3947
|
+
token,
|
|
3748
3948
|
startTime,
|
|
3749
3949
|
expiresAt,
|
|
3750
|
-
|
|
3950
|
+
sealingNonce,
|
|
3951
|
+
sealingSecret,
|
|
3751
3952
|
mode: resolvedMode
|
|
3752
3953
|
};
|
|
3954
|
+
this.tokenCache.set(token, result);
|
|
3955
|
+
return result;
|
|
3753
3956
|
}
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3957
|
+
/**
|
|
3958
|
+
* Submit a mock score to the leaderboard.
|
|
3959
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
3960
|
+
*
|
|
3961
|
+
* @param params - Score submission parameters
|
|
3962
|
+
* @returns Submission result with acceptance status and rank
|
|
3963
|
+
* @throws Error if token not found in cache or validation fails
|
|
3964
|
+
*/
|
|
3965
|
+
async submitScore(params) {
|
|
3966
|
+
let hash;
|
|
3967
|
+
if (params.token) {
|
|
3968
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
3969
|
+
if (!cachedToken) {
|
|
3970
|
+
throw new Error(
|
|
3971
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
3972
|
+
);
|
|
3973
|
+
}
|
|
3974
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
3975
|
+
hash = await computeScoreHash(
|
|
3976
|
+
params.score,
|
|
3977
|
+
params.duration,
|
|
3978
|
+
params.token,
|
|
3979
|
+
cachedToken.sealingNonce,
|
|
3980
|
+
cachedToken.sealingSecret
|
|
3981
|
+
);
|
|
3982
|
+
}
|
|
3983
|
+
}
|
|
3984
|
+
if (!params.token) {
|
|
3985
|
+
const mode = params.mode || "default";
|
|
3986
|
+
const submittedAt2 = Date.now();
|
|
3987
|
+
const entry2 = {
|
|
3988
|
+
profileId: `mock_profile`,
|
|
3989
|
+
username: "Mock Player",
|
|
3990
|
+
avatarUrl: null,
|
|
3991
|
+
score: params.score,
|
|
3992
|
+
duration: params.duration,
|
|
3993
|
+
submittedAt: submittedAt2,
|
|
3994
|
+
token: "simple-mode",
|
|
3995
|
+
rank: null,
|
|
3996
|
+
zScore: null,
|
|
3997
|
+
isAnomaly: false,
|
|
3998
|
+
trustScore: 50,
|
|
3999
|
+
metadata: params.metadata ?? null,
|
|
4000
|
+
isSeed: false
|
|
4001
|
+
};
|
|
4002
|
+
const modeEntries2 = this.getEntriesForMode(mode);
|
|
4003
|
+
modeEntries2.push(entry2);
|
|
4004
|
+
modeEntries2.sort((a, b) => {
|
|
4005
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
4006
|
+
return a.submittedAt - b.submittedAt;
|
|
4007
|
+
});
|
|
4008
|
+
modeEntries2.forEach((e, index) => {
|
|
4009
|
+
modeEntries2[index] = { ...e, rank: index + 1 };
|
|
4010
|
+
});
|
|
4011
|
+
const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
|
|
4012
|
+
return {
|
|
4013
|
+
accepted: true,
|
|
4014
|
+
rank: inserted2?.rank ?? null
|
|
4015
|
+
};
|
|
4016
|
+
}
|
|
4017
|
+
const scoreToken = this.tokens.get(params.token);
|
|
4018
|
+
if (!scoreToken) {
|
|
4019
|
+
throw new Error("Invalid score token");
|
|
3758
4020
|
}
|
|
3759
|
-
if (
|
|
3760
|
-
throw new Error("Invalid or expired
|
|
4021
|
+
if (scoreToken.expiresAt < Date.now()) {
|
|
4022
|
+
throw new Error("Invalid or expired score token");
|
|
3761
4023
|
}
|
|
3762
|
-
if (
|
|
3763
|
-
throw new Error("
|
|
4024
|
+
if (scoreToken.used) {
|
|
4025
|
+
throw new Error("Score token already used");
|
|
3764
4026
|
}
|
|
3765
|
-
if (
|
|
3766
|
-
throw new Error("Submission mode does not match
|
|
4027
|
+
if (params.mode && params.mode !== scoreToken.mode) {
|
|
4028
|
+
throw new Error("Submission mode does not match token mode");
|
|
3767
4029
|
}
|
|
3768
|
-
if (
|
|
3769
|
-
throw new Error("Score hash
|
|
4030
|
+
if (scoreToken.sealingNonce && !hash) {
|
|
4031
|
+
throw new Error("Score hash required when score sealing is enabled");
|
|
3770
4032
|
}
|
|
3771
4033
|
const submittedAt = Date.now();
|
|
3772
4034
|
const entry = {
|
|
3773
4035
|
profileId: `mock_profile`,
|
|
3774
4036
|
username: "Mock Player",
|
|
3775
4037
|
avatarUrl: null,
|
|
3776
|
-
score,
|
|
3777
|
-
|
|
4038
|
+
score: params.score,
|
|
4039
|
+
duration: params.duration,
|
|
3778
4040
|
submittedAt,
|
|
3779
|
-
|
|
4041
|
+
token: params.token,
|
|
3780
4042
|
rank: null,
|
|
3781
4043
|
zScore: null,
|
|
3782
4044
|
isAnomaly: false,
|
|
3783
4045
|
trustScore: 50,
|
|
3784
|
-
metadata:
|
|
4046
|
+
metadata: params.metadata ?? null,
|
|
3785
4047
|
isSeed: false
|
|
3786
4048
|
};
|
|
3787
|
-
const modeEntries = this.getEntriesForMode(
|
|
4049
|
+
const modeEntries = this.getEntriesForMode(scoreToken.mode);
|
|
3788
4050
|
modeEntries.push(entry);
|
|
3789
4051
|
modeEntries.sort((a, b) => {
|
|
3790
|
-
if (b.score !== a.score)
|
|
3791
|
-
return b.score - a.score;
|
|
3792
|
-
}
|
|
4052
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
3793
4053
|
return a.submittedAt - b.submittedAt;
|
|
3794
4054
|
});
|
|
3795
4055
|
modeEntries.forEach((e, index) => {
|
|
3796
|
-
modeEntries[index] = {
|
|
3797
|
-
...e,
|
|
3798
|
-
rank: index + 1
|
|
3799
|
-
};
|
|
4056
|
+
modeEntries[index] = { ...e, rank: index + 1 };
|
|
3800
4057
|
});
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
4058
|
+
scoreToken.used = true;
|
|
4059
|
+
scoreToken.sealingNonce = null;
|
|
4060
|
+
this.tokenCache.delete(params.token);
|
|
4061
|
+
const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
|
|
3804
4062
|
return {
|
|
3805
4063
|
accepted: true,
|
|
3806
4064
|
rank: inserted?.rank ?? null
|
|
3807
4065
|
};
|
|
3808
4066
|
}
|
|
3809
|
-
async
|
|
4067
|
+
async getPagedScores(options) {
|
|
3810
4068
|
const limit = options?.limit ?? 10;
|
|
3811
4069
|
const mode = options?.mode ?? "default";
|
|
3812
4070
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
@@ -3822,7 +4080,7 @@ var MockLeaderboardApi = class {
|
|
|
3822
4080
|
periodInstance: options?.period ?? "alltime"
|
|
3823
4081
|
};
|
|
3824
4082
|
}
|
|
3825
|
-
async
|
|
4083
|
+
async getMyRank(_options) {
|
|
3826
4084
|
const mode = _options?.mode ?? "default";
|
|
3827
4085
|
const modeEntries = this.getEntriesForMode(mode);
|
|
3828
4086
|
const playerEntry = modeEntries[0] ?? null;
|
|
@@ -3835,7 +4093,7 @@ var MockLeaderboardApi = class {
|
|
|
3835
4093
|
periodInstance: _options?.period ?? "alltime"
|
|
3836
4094
|
};
|
|
3837
4095
|
}
|
|
3838
|
-
async
|
|
4096
|
+
async getPodiumScores(options) {
|
|
3839
4097
|
const mode = options?.mode ?? "default";
|
|
3840
4098
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
3841
4099
|
const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
|
|
@@ -3903,105 +4161,29 @@ var MockPreloaderApi = class {
|
|
|
3903
4161
|
};
|
|
3904
4162
|
|
|
3905
4163
|
// src/game-preloader/RpcPreloaderApi.ts
|
|
3906
|
-
var RpcPreloaderApi = class {
|
|
3907
|
-
constructor(rpcClient) {
|
|
3908
|
-
__publicField(this, "rpcClient");
|
|
3909
|
-
this.rpcClient = rpcClient;
|
|
3910
|
-
}
|
|
3911
|
-
async showLoadScreen() {
|
|
3912
|
-
await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
|
|
3913
|
-
}
|
|
3914
|
-
async hideLoadScreen() {
|
|
3915
|
-
await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
|
|
3916
|
-
}
|
|
3917
|
-
async setLoaderText(text) {
|
|
3918
|
-
await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
|
|
3919
|
-
}
|
|
3920
|
-
async setLoaderProgress(progress) {
|
|
3921
|
-
await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
|
|
3922
|
-
}
|
|
3923
|
-
};
|
|
3924
|
-
|
|
3925
|
-
// src/game-preloader/index.ts
|
|
3926
|
-
function initializePreloader(venusApi, host) {
|
|
3927
|
-
venusApi.preloader = host.preloader;
|
|
3928
|
-
}
|
|
3929
|
-
|
|
3930
|
-
// src/post/MockPostApi.ts
|
|
3931
|
-
var MockPostApi = class {
|
|
3932
|
-
constructor(venusApi) {
|
|
3933
|
-
__publicField(this, "venusApi");
|
|
3934
|
-
this.venusApi = venusApi;
|
|
3935
|
-
}
|
|
3936
|
-
async getPostInfo() {
|
|
3937
|
-
const venusApi = this.venusApi;
|
|
3938
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3939
|
-
return venusApi._mock.currentPostInteractions;
|
|
3940
|
-
}
|
|
3941
|
-
async openCommentsAsync() {
|
|
3942
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3943
|
-
return {
|
|
3944
|
-
opened: true,
|
|
3945
|
-
commentsCount: 0
|
|
3946
|
-
};
|
|
3947
|
-
}
|
|
3948
|
-
async toggleFollowAsync() {
|
|
3949
|
-
const venusApi = this.venusApi;
|
|
3950
|
-
console.log("[Venus Mock] *Toggling follow status");
|
|
3951
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3952
|
-
venusApi._mock.currentPostInteractions.isFollowing = !venusApi._mock.currentPostInteractions.isFollowing;
|
|
3953
|
-
const isFollowing = venusApi._mock.currentPostInteractions.isFollowing;
|
|
3954
|
-
return {
|
|
3955
|
-
isFollowing,
|
|
3956
|
-
action: isFollowing ? "followed" : "unfollowed"
|
|
3957
|
-
};
|
|
3958
|
-
}
|
|
3959
|
-
async toggleLikeAsync() {
|
|
3960
|
-
const venusApi = this.venusApi;
|
|
3961
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3962
|
-
venusApi._mock.currentPostInteractions.isLiked = !venusApi._mock.currentPostInteractions.isLiked;
|
|
3963
|
-
const isLiked = venusApi._mock.currentPostInteractions.isLiked;
|
|
3964
|
-
if (isLiked) {
|
|
3965
|
-
venusApi._mock.currentPostInteractions.likesCount++;
|
|
3966
|
-
} else {
|
|
3967
|
-
venusApi._mock.currentPostInteractions.likesCount = Math.max(
|
|
3968
|
-
0,
|
|
3969
|
-
venusApi._mock.currentPostInteractions.likesCount - 1
|
|
3970
|
-
);
|
|
3971
|
-
}
|
|
3972
|
-
return {
|
|
3973
|
-
isLiked,
|
|
3974
|
-
likesCount: venusApi._mock.currentPostInteractions.likesCount,
|
|
3975
|
-
action: isLiked ? "liked" : "unliked"
|
|
3976
|
-
};
|
|
3977
|
-
}
|
|
3978
|
-
};
|
|
3979
|
-
|
|
3980
|
-
// src/post/RpcPostApi.ts
|
|
3981
|
-
var RpcPostApi = class {
|
|
4164
|
+
var RpcPreloaderApi = class {
|
|
3982
4165
|
constructor(rpcClient) {
|
|
3983
4166
|
__publicField(this, "rpcClient");
|
|
3984
4167
|
this.rpcClient = rpcClient;
|
|
3985
4168
|
}
|
|
3986
|
-
|
|
3987
|
-
|
|
4169
|
+
async showLoadScreen() {
|
|
4170
|
+
await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
|
|
3988
4171
|
}
|
|
3989
|
-
|
|
3990
|
-
|
|
4172
|
+
async hideLoadScreen() {
|
|
4173
|
+
await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
|
|
3991
4174
|
}
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
"H5_TOGGLE_FOLLOW" /* TOGGLE_FOLLOW */,
|
|
3995
|
-
{}
|
|
3996
|
-
);
|
|
4175
|
+
async setLoaderText(text) {
|
|
4176
|
+
await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
|
|
3997
4177
|
}
|
|
3998
|
-
|
|
3999
|
-
|
|
4178
|
+
async setLoaderProgress(progress) {
|
|
4179
|
+
await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
|
|
4000
4180
|
}
|
|
4001
4181
|
};
|
|
4002
4182
|
|
|
4003
|
-
// src/
|
|
4004
|
-
|
|
4183
|
+
// src/game-preloader/index.ts
|
|
4184
|
+
function initializePreloader(venusApi, host) {
|
|
4185
|
+
venusApi.preloader = host.preloader;
|
|
4186
|
+
}
|
|
4005
4187
|
|
|
4006
4188
|
// src/social/MockSocialApi.ts
|
|
4007
4189
|
var MOCK_QR_CODE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
|
|
@@ -4039,44 +4221,116 @@ var ROOMS_UNAVAILABLE_MESSAGE = "[Venus SDK] Rooms API is only available when ru
|
|
|
4039
4221
|
function createUnavailableRoomsApi() {
|
|
4040
4222
|
const roomsUnavailableError = () => new Error(ROOMS_UNAVAILABLE_MESSAGE);
|
|
4041
4223
|
return {
|
|
4042
|
-
async
|
|
4224
|
+
async createRoomAsync() {
|
|
4043
4225
|
throw roomsUnavailableError();
|
|
4044
4226
|
},
|
|
4045
|
-
async
|
|
4227
|
+
async joinOrCreateRoomAsync() {
|
|
4046
4228
|
throw roomsUnavailableError();
|
|
4047
4229
|
},
|
|
4048
|
-
async
|
|
4230
|
+
async joinRoomByCodeAsync() {
|
|
4049
4231
|
throw roomsUnavailableError();
|
|
4050
4232
|
},
|
|
4051
|
-
async
|
|
4233
|
+
async getUserRoomsAsync() {
|
|
4052
4234
|
throw roomsUnavailableError();
|
|
4053
4235
|
},
|
|
4054
|
-
|
|
4236
|
+
async subscribeAsync() {
|
|
4055
4237
|
throw roomsUnavailableError();
|
|
4056
4238
|
},
|
|
4057
|
-
async
|
|
4239
|
+
async updateRoomDataAsync() {
|
|
4058
4240
|
throw roomsUnavailableError();
|
|
4059
4241
|
},
|
|
4060
|
-
async
|
|
4242
|
+
async getRoomDataAsync() {
|
|
4061
4243
|
throw roomsUnavailableError();
|
|
4062
4244
|
},
|
|
4063
|
-
async
|
|
4245
|
+
async sendRoomMessageAsync() {
|
|
4064
4246
|
throw roomsUnavailableError();
|
|
4065
4247
|
},
|
|
4066
|
-
async
|
|
4248
|
+
async leaveRoomAsync() {
|
|
4067
4249
|
throw roomsUnavailableError();
|
|
4068
4250
|
},
|
|
4069
|
-
async
|
|
4251
|
+
async startRoomGameAsync() {
|
|
4070
4252
|
throw roomsUnavailableError();
|
|
4071
4253
|
},
|
|
4072
|
-
async
|
|
4254
|
+
async proposeMoveAsync() {
|
|
4073
4255
|
throw roomsUnavailableError();
|
|
4074
4256
|
},
|
|
4075
|
-
async
|
|
4257
|
+
async validateMoveAsync() {
|
|
4076
4258
|
throw roomsUnavailableError();
|
|
4077
4259
|
}
|
|
4078
4260
|
};
|
|
4079
4261
|
}
|
|
4262
|
+
var SIMULATION_UNAVAILABLE_MESSAGE = "[Venus SDK] Simulation API is only available when running inside the Venus host environment.";
|
|
4263
|
+
function createUnavailableSimulationApi() {
|
|
4264
|
+
const simulationUnavailableError = () => new Error(SIMULATION_UNAVAILABLE_MESSAGE);
|
|
4265
|
+
return {
|
|
4266
|
+
isEnabled() {
|
|
4267
|
+
return false;
|
|
4268
|
+
},
|
|
4269
|
+
async getStateAsync() {
|
|
4270
|
+
throw simulationUnavailableError();
|
|
4271
|
+
},
|
|
4272
|
+
async getConfigAsync() {
|
|
4273
|
+
throw simulationUnavailableError();
|
|
4274
|
+
},
|
|
4275
|
+
async executeRecipeAsync() {
|
|
4276
|
+
throw simulationUnavailableError();
|
|
4277
|
+
},
|
|
4278
|
+
async getActiveRunsAsync() {
|
|
4279
|
+
throw simulationUnavailableError();
|
|
4280
|
+
},
|
|
4281
|
+
async collectRecipeAsync() {
|
|
4282
|
+
throw simulationUnavailableError();
|
|
4283
|
+
},
|
|
4284
|
+
async executeScopedRecipeAsync() {
|
|
4285
|
+
throw simulationUnavailableError();
|
|
4286
|
+
},
|
|
4287
|
+
async triggerRecipeChainAsync() {
|
|
4288
|
+
throw simulationUnavailableError();
|
|
4289
|
+
},
|
|
4290
|
+
async getAvailableRecipesAsync() {
|
|
4291
|
+
throw simulationUnavailableError();
|
|
4292
|
+
},
|
|
4293
|
+
async getRecipeRequirementsAsync() {
|
|
4294
|
+
throw simulationUnavailableError();
|
|
4295
|
+
},
|
|
4296
|
+
async getBatchRecipeRequirementsAsync() {
|
|
4297
|
+
throw simulationUnavailableError();
|
|
4298
|
+
},
|
|
4299
|
+
async resolveFieldValueAsync() {
|
|
4300
|
+
throw simulationUnavailableError();
|
|
4301
|
+
},
|
|
4302
|
+
async getEntityMetadataAsync() {
|
|
4303
|
+
throw simulationUnavailableError();
|
|
4304
|
+
},
|
|
4305
|
+
async getSlotContainersAsync() {
|
|
4306
|
+
throw simulationUnavailableError();
|
|
4307
|
+
},
|
|
4308
|
+
async getSlotAssignmentsAsync() {
|
|
4309
|
+
throw simulationUnavailableError();
|
|
4310
|
+
},
|
|
4311
|
+
async assignItemToSlotAsync() {
|
|
4312
|
+
throw simulationUnavailableError();
|
|
4313
|
+
},
|
|
4314
|
+
async removeItemFromSlotAsync() {
|
|
4315
|
+
throw simulationUnavailableError();
|
|
4316
|
+
},
|
|
4317
|
+
async getAvailableItemsAsync() {
|
|
4318
|
+
throw simulationUnavailableError();
|
|
4319
|
+
},
|
|
4320
|
+
async calculatePowerPreviewAsync() {
|
|
4321
|
+
throw simulationUnavailableError();
|
|
4322
|
+
},
|
|
4323
|
+
async validateSlotAssignmentAsync() {
|
|
4324
|
+
throw simulationUnavailableError();
|
|
4325
|
+
},
|
|
4326
|
+
async executeBatchOperationsAsync() {
|
|
4327
|
+
throw simulationUnavailableError();
|
|
4328
|
+
},
|
|
4329
|
+
async subscribeAsync() {
|
|
4330
|
+
throw simulationUnavailableError();
|
|
4331
|
+
}
|
|
4332
|
+
};
|
|
4333
|
+
}
|
|
4080
4334
|
var MockHost = class {
|
|
4081
4335
|
constructor(venusApi) {
|
|
4082
4336
|
__publicField(this, "ads");
|
|
@@ -4089,9 +4343,9 @@ var MockHost = class {
|
|
|
4089
4343
|
__publicField(this, "notifications");
|
|
4090
4344
|
__publicField(this, "popups");
|
|
4091
4345
|
__publicField(this, "profile");
|
|
4346
|
+
__publicField(this, "system");
|
|
4092
4347
|
__publicField(this, "cdn");
|
|
4093
4348
|
__publicField(this, "time");
|
|
4094
|
-
__publicField(this, "post");
|
|
4095
4349
|
__publicField(this, "ai");
|
|
4096
4350
|
__publicField(this, "haptics");
|
|
4097
4351
|
__publicField(this, "features");
|
|
@@ -4123,15 +4377,17 @@ var MockHost = class {
|
|
|
4123
4377
|
this.navigation = new MockNavigationApi(venusApi);
|
|
4124
4378
|
this.notifications = new MockNotificationsApi(venusApi);
|
|
4125
4379
|
this.popups = new MockPopupsApi(this._overlay);
|
|
4126
|
-
this.profile = new MockProfileApi();
|
|
4127
|
-
|
|
4380
|
+
this.profile = new MockProfileApi(venusApi);
|
|
4381
|
+
const deviceApi = new MockDeviceApi(venusApi);
|
|
4382
|
+
const environmentApi = new MockEnvironmentApi(venusApi);
|
|
4383
|
+
this.system = new MockSystemApi(deviceApi, environmentApi, venusApi);
|
|
4384
|
+
this.cdn = new MockCdnApi(venusApi);
|
|
4128
4385
|
this.time = new MockTimeApi(venusApi);
|
|
4129
|
-
this.post = new MockPostApi(venusApi);
|
|
4130
4386
|
this.ai = new MockAiApi();
|
|
4131
4387
|
this.haptics = new MockHapticsApi(venusApi);
|
|
4132
4388
|
this.features = new MockFeaturesApi();
|
|
4133
4389
|
this.lifecycle = this._mockLifecyclesApi;
|
|
4134
|
-
this.simulation =
|
|
4390
|
+
this.simulation = createUnavailableSimulationApi();
|
|
4135
4391
|
this.rooms = createUnavailableRoomsApi();
|
|
4136
4392
|
this.logging = new MockLoggingApi();
|
|
4137
4393
|
this.iap = new MockIapApi();
|
|
@@ -4147,40 +4403,17 @@ var MockHost = class {
|
|
|
4147
4403
|
}
|
|
4148
4404
|
initialize(options) {
|
|
4149
4405
|
this._isInitialized = true;
|
|
4150
|
-
|
|
4406
|
+
this.venusApi._profileData = this.profile.getCurrentProfile();
|
|
4407
|
+
this.venusApi._deviceData = this.system.getDevice();
|
|
4408
|
+
this.venusApi._environmentData = this.system.getEnvironment();
|
|
4409
|
+
this.venusApi._localeData = this.venusApi._mock?.locale || "en-US";
|
|
4410
|
+
this.venusApi._languageCodeData = this.venusApi._mock?.languageCode || "en";
|
|
4151
4411
|
return Promise.resolve({
|
|
4152
4412
|
initializeAsleep: false,
|
|
4153
|
-
|
|
4154
|
-
top: controls.feedHeader.height,
|
|
4155
|
-
bottom: 0,
|
|
4156
|
-
left: 0,
|
|
4157
|
-
right: 0
|
|
4158
|
-
}
|
|
4413
|
+
safeArea: this.venusApi._safeAreaData
|
|
4159
4414
|
});
|
|
4160
4415
|
}
|
|
4161
|
-
updateUiControls() {
|
|
4162
|
-
const controls = {
|
|
4163
|
-
closeButton: { x: 16, y: 16, width: 32, height: 32 },
|
|
4164
|
-
menuButton: {
|
|
4165
|
-
x: window.innerWidth - 48,
|
|
4166
|
-
y: 16,
|
|
4167
|
-
width: 32,
|
|
4168
|
-
height: 32
|
|
4169
|
-
},
|
|
4170
|
-
feedHeader: { x: 0, y: 0, width: window.innerWidth, height: 56 },
|
|
4171
|
-
playButton: {
|
|
4172
|
-
x: 0,
|
|
4173
|
-
y: window.innerHeight - 60,
|
|
4174
|
-
width: window.innerWidth,
|
|
4175
|
-
height: 60
|
|
4176
|
-
}
|
|
4177
|
-
};
|
|
4178
|
-
return controls;
|
|
4179
|
-
}
|
|
4180
4416
|
createOverlay() {
|
|
4181
|
-
const venusApi = this.venusApi;
|
|
4182
|
-
venusApi.config.ui.controls = this.updateUiControls();
|
|
4183
|
-
const uiControls = venusApi.config.ui.controls;
|
|
4184
4417
|
const overlayContainer = document.createElement("div");
|
|
4185
4418
|
overlayContainer.id = "venus-mock-overlay";
|
|
4186
4419
|
overlayContainer.style.cssText = `
|
|
@@ -4196,7 +4429,7 @@ var MockHost = class {
|
|
|
4196
4429
|
const menuButton = this.createOverlayButton(
|
|
4197
4430
|
"close",
|
|
4198
4431
|
"Menu",
|
|
4199
|
-
|
|
4432
|
+
{ x: window.innerWidth - 48, y: 16, width: 32, height: 32 },
|
|
4200
4433
|
() => {
|
|
4201
4434
|
this.handleMenuButtonClicked();
|
|
4202
4435
|
},
|
|
@@ -4425,17 +4658,13 @@ var MockHost = class {
|
|
|
4425
4658
|
return button;
|
|
4426
4659
|
}
|
|
4427
4660
|
updateOverlayLayout() {
|
|
4428
|
-
const venusApi = this.venusApi;
|
|
4429
4661
|
const overlay = this._overlay;
|
|
4430
|
-
venusApi.config.ui.controls = this.updateUiControls();
|
|
4431
|
-
const uiControls = venusApi.config.ui.controls;
|
|
4432
4662
|
const menuBtn = overlay.elements.menuButton;
|
|
4433
|
-
|
|
4434
|
-
menuBtn.style.
|
|
4435
|
-
menuBtn.style.
|
|
4436
|
-
menuBtn.style.
|
|
4437
|
-
menuBtn.style.
|
|
4438
|
-
menuBtn.style.height = `${menuPos.height}px`;
|
|
4663
|
+
menuBtn.style.left = `${window.innerWidth - 48}px`;
|
|
4664
|
+
menuBtn.style.top = "16px";
|
|
4665
|
+
menuBtn.style.width = "32px";
|
|
4666
|
+
menuBtn.style.minWidth = "32px";
|
|
4667
|
+
menuBtn.style.height = "32px";
|
|
4439
4668
|
}
|
|
4440
4669
|
triggerLifecycleEvent(name) {
|
|
4441
4670
|
console.log("Trigger Lifecycle Event: ", name);
|
|
@@ -4664,6 +4893,16 @@ var VenusTransport = class {
|
|
|
4664
4893
|
this.isProcessingMessage = false;
|
|
4665
4894
|
return;
|
|
4666
4895
|
}
|
|
4896
|
+
if (message.type === "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */) {
|
|
4897
|
+
const notification = {
|
|
4898
|
+
type: "rpc-notification",
|
|
4899
|
+
id: message.type,
|
|
4900
|
+
payload: message.data
|
|
4901
|
+
};
|
|
4902
|
+
this.handleNotification(notification);
|
|
4903
|
+
this.isProcessingMessage = false;
|
|
4904
|
+
return;
|
|
4905
|
+
}
|
|
4667
4906
|
const requestId = messageData.requestId;
|
|
4668
4907
|
if (!requestId) {
|
|
4669
4908
|
this.logWarn("No requestId. Ignoring message...");
|
|
@@ -4830,294 +5069,6 @@ var VenusTransport = class {
|
|
|
4830
5069
|
}
|
|
4831
5070
|
};
|
|
4832
5071
|
|
|
4833
|
-
// src/RemoteHost.ts
|
|
4834
|
-
init_rooms();
|
|
4835
|
-
|
|
4836
|
-
// src/rooms/RpcRoomsApi.ts
|
|
4837
|
-
init_VenusRoom();
|
|
4838
|
-
var RpcRoomsApi = class {
|
|
4839
|
-
constructor(rpcClient) {
|
|
4840
|
-
__publicField(this, "rpcClient");
|
|
4841
|
-
__publicField(this, "subscriptions");
|
|
4842
|
-
__publicField(this, "transportSubscription", null);
|
|
4843
|
-
this.rpcClient = rpcClient;
|
|
4844
|
-
this.subscriptions = {
|
|
4845
|
-
data: {},
|
|
4846
|
-
messages: {},
|
|
4847
|
-
gameEvents: {},
|
|
4848
|
-
allEvents: {}
|
|
4849
|
-
};
|
|
4850
|
-
}
|
|
4851
|
-
/**
|
|
4852
|
-
* Get the subscription state for external access (used by setupRoomNotifications)
|
|
4853
|
-
*/
|
|
4854
|
-
getSubscriptions() {
|
|
4855
|
-
return this.subscriptions;
|
|
4856
|
-
}
|
|
4857
|
-
/**
|
|
4858
|
-
* Set up room notification routing from the transport
|
|
4859
|
-
*/
|
|
4860
|
-
setupNotifications(transport) {
|
|
4861
|
-
const { setupRoomNotifications: setupRoomNotifications2 } = (init_rooms(), __toCommonJS(rooms_exports));
|
|
4862
|
-
this.transportSubscription = setupRoomNotifications2(
|
|
4863
|
-
transport,
|
|
4864
|
-
() => this.getSubscriptions()
|
|
4865
|
-
);
|
|
4866
|
-
}
|
|
4867
|
-
/**
|
|
4868
|
-
* Clean up subscriptions and resources
|
|
4869
|
-
*/
|
|
4870
|
-
dispose() {
|
|
4871
|
-
if (this.transportSubscription) {
|
|
4872
|
-
this.transportSubscription.unsubscribe();
|
|
4873
|
-
this.transportSubscription = null;
|
|
4874
|
-
console.log("[Venus Rooms] Cleaned up room notification subscription");
|
|
4875
|
-
}
|
|
4876
|
-
}
|
|
4877
|
-
async createRoom(options) {
|
|
4878
|
-
const response = await this.rpcClient.call(
|
|
4879
|
-
"H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
|
|
4880
|
-
{
|
|
4881
|
-
options
|
|
4882
|
-
}
|
|
4883
|
-
);
|
|
4884
|
-
if (response.success === false) {
|
|
4885
|
-
throw new Error(response.error || "Failed to create room");
|
|
4886
|
-
}
|
|
4887
|
-
const roomData = response.roomData || response;
|
|
4888
|
-
const room = new exports.VenusRoom(roomData);
|
|
4889
|
-
return room;
|
|
4890
|
-
}
|
|
4891
|
-
async joinOrCreateRoom(options) {
|
|
4892
|
-
const response = await this.rpcClient.call(
|
|
4893
|
-
"H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
|
|
4894
|
-
{
|
|
4895
|
-
options
|
|
4896
|
-
}
|
|
4897
|
-
);
|
|
4898
|
-
if (response.success === false) {
|
|
4899
|
-
throw new Error(response.error || "Failed to join or create room");
|
|
4900
|
-
}
|
|
4901
|
-
const data = response.value || response;
|
|
4902
|
-
const room = new exports.VenusRoom(data.roomData);
|
|
4903
|
-
return {
|
|
4904
|
-
action: data.action,
|
|
4905
|
-
room,
|
|
4906
|
-
playersJoined: data.playersJoined
|
|
4907
|
-
};
|
|
4908
|
-
}
|
|
4909
|
-
async joinRoomByCode(roomCode) {
|
|
4910
|
-
const response = await this.rpcClient.call(
|
|
4911
|
-
"H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
|
|
4912
|
-
{
|
|
4913
|
-
roomCode
|
|
4914
|
-
}
|
|
4915
|
-
);
|
|
4916
|
-
if (response?.success === false) {
|
|
4917
|
-
throw new Error(response.error || "Failed to join room by code");
|
|
4918
|
-
}
|
|
4919
|
-
const roomData = response.roomData || response;
|
|
4920
|
-
const room = new exports.VenusRoom(roomData);
|
|
4921
|
-
return room;
|
|
4922
|
-
}
|
|
4923
|
-
// Get user's rooms with optional filtering
|
|
4924
|
-
async getUserRooms(includeArchived = false) {
|
|
4925
|
-
const response = await this.rpcClient.call(
|
|
4926
|
-
"H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
|
|
4927
|
-
{
|
|
4928
|
-
includeArchived
|
|
4929
|
-
}
|
|
4930
|
-
);
|
|
4931
|
-
if (response?.success === false) {
|
|
4932
|
-
throw new Error(response.error || "Failed to get user rooms");
|
|
4933
|
-
}
|
|
4934
|
-
const rawRooms = response.rooms || [];
|
|
4935
|
-
const venusRooms = [];
|
|
4936
|
-
for (const roomData of rawRooms) {
|
|
4937
|
-
if (!roomData.id) {
|
|
4938
|
-
console.warn("getUserRooms: Skipping room with missing ID:", roomData);
|
|
4939
|
-
continue;
|
|
4940
|
-
}
|
|
4941
|
-
try {
|
|
4942
|
-
const venusRoom = new exports.VenusRoom(roomData);
|
|
4943
|
-
venusRooms.push(venusRoom);
|
|
4944
|
-
} catch (error) {
|
|
4945
|
-
console.warn(
|
|
4946
|
-
"getUserRooms: Failed to create VenusRoom object:",
|
|
4947
|
-
error,
|
|
4948
|
-
roomData
|
|
4949
|
-
);
|
|
4950
|
-
}
|
|
4951
|
-
}
|
|
4952
|
-
return venusRooms;
|
|
4953
|
-
}
|
|
4954
|
-
async updateData(room, updates, merge = true) {
|
|
4955
|
-
const response = await this.rpcClient.call(
|
|
4956
|
-
"H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
|
|
4957
|
-
{
|
|
4958
|
-
roomId: room.id,
|
|
4959
|
-
updates,
|
|
4960
|
-
merge
|
|
4961
|
-
}
|
|
4962
|
-
);
|
|
4963
|
-
if (response?.success === false) {
|
|
4964
|
-
throw new Error(response.error || "Failed to update room data");
|
|
4965
|
-
}
|
|
4966
|
-
return response.data;
|
|
4967
|
-
}
|
|
4968
|
-
async getData(room) {
|
|
4969
|
-
const response = await this.rpcClient.call(
|
|
4970
|
-
"H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
|
|
4971
|
-
{
|
|
4972
|
-
roomId: room.id
|
|
4973
|
-
}
|
|
4974
|
-
);
|
|
4975
|
-
if (response?.success === false) {
|
|
4976
|
-
throw new Error(response.error || "Failed to get room data");
|
|
4977
|
-
}
|
|
4978
|
-
return response.data;
|
|
4979
|
-
}
|
|
4980
|
-
async sendMessage(venusRoom, messageData) {
|
|
4981
|
-
const response = await this.rpcClient.call(
|
|
4982
|
-
"H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
|
|
4983
|
-
{
|
|
4984
|
-
roomId: venusRoom.id,
|
|
4985
|
-
message: messageData
|
|
4986
|
-
}
|
|
4987
|
-
);
|
|
4988
|
-
if (response?.success === false) {
|
|
4989
|
-
throw new Error(response.error || "Failed to send message");
|
|
4990
|
-
}
|
|
4991
|
-
return response.messageId;
|
|
4992
|
-
}
|
|
4993
|
-
async leave(room) {
|
|
4994
|
-
const response = await this.rpcClient.call(
|
|
4995
|
-
"H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
|
|
4996
|
-
{
|
|
4997
|
-
roomId: room.id
|
|
4998
|
-
}
|
|
4999
|
-
);
|
|
5000
|
-
if (response?.success === false) {
|
|
5001
|
-
throw new Error(response.error || "Failed to leave room");
|
|
5002
|
-
}
|
|
5003
|
-
return response;
|
|
5004
|
-
}
|
|
5005
|
-
async startGame(room, gameConfig = {}, turnOrder = null) {
|
|
5006
|
-
const response = await this.rpcClient.call(
|
|
5007
|
-
"H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
|
|
5008
|
-
{
|
|
5009
|
-
roomId: room.id,
|
|
5010
|
-
gameConfig,
|
|
5011
|
-
turnOrder
|
|
5012
|
-
}
|
|
5013
|
-
);
|
|
5014
|
-
if (response?.success === false) {
|
|
5015
|
-
throw new Error(response.error || "Failed to start game");
|
|
5016
|
-
}
|
|
5017
|
-
return response.data;
|
|
5018
|
-
}
|
|
5019
|
-
async proposeMove(room, proposalPayload) {
|
|
5020
|
-
const response = await this.rpcClient.call(
|
|
5021
|
-
"h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
|
|
5022
|
-
{
|
|
5023
|
-
roomId: room.id,
|
|
5024
|
-
gameSpecificState: proposalPayload.gameSpecificState,
|
|
5025
|
-
moveType: proposalPayload.moveType,
|
|
5026
|
-
clientContext: proposalPayload.clientContext,
|
|
5027
|
-
clientProposalId: proposalPayload.clientProposalId
|
|
5028
|
-
}
|
|
5029
|
-
);
|
|
5030
|
-
if (response?.success === false) {
|
|
5031
|
-
throw new Error(response.error || "Failed to propose move");
|
|
5032
|
-
}
|
|
5033
|
-
return response.data;
|
|
5034
|
-
}
|
|
5035
|
-
async validateMove(room, moveId, isValid, reason = null, validatorId = null) {
|
|
5036
|
-
console.log(`[Venus Rooms] Validating move ${moveId}: ${isValid}`);
|
|
5037
|
-
return { success: true, moveId, isValid, reason };
|
|
5038
|
-
}
|
|
5039
|
-
async roomSubscribeToGameEvents(room, callback) {
|
|
5040
|
-
"game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5041
|
-
if (!this.subscriptions.gameEvents[room.id]) {
|
|
5042
|
-
this.subscriptions.gameEvents[room.id] = [];
|
|
5043
|
-
}
|
|
5044
|
-
this.subscriptions.gameEvents[room.id].push(callback);
|
|
5045
|
-
}
|
|
5046
|
-
subscribe(room, options = {}) {
|
|
5047
|
-
const subscriptionIds = [];
|
|
5048
|
-
const roomId = room.id;
|
|
5049
|
-
if (options.onData) {
|
|
5050
|
-
const dataSubId = "data_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5051
|
-
if (!this.subscriptions.data[roomId]) {
|
|
5052
|
-
this.subscriptions.data[roomId] = [];
|
|
5053
|
-
}
|
|
5054
|
-
this.subscriptions.data[roomId].push(options.onData);
|
|
5055
|
-
subscriptionIds.push({
|
|
5056
|
-
type: "data",
|
|
5057
|
-
id: dataSubId,
|
|
5058
|
-
callback: options.onData
|
|
5059
|
-
});
|
|
5060
|
-
}
|
|
5061
|
-
if (options.onMessages) {
|
|
5062
|
-
const msgSubId = "messages_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5063
|
-
if (!this.subscriptions.messages[roomId]) {
|
|
5064
|
-
this.subscriptions.messages[roomId] = [];
|
|
5065
|
-
}
|
|
5066
|
-
this.subscriptions.messages[roomId].push(options.onMessages);
|
|
5067
|
-
subscriptionIds.push({
|
|
5068
|
-
type: "messages",
|
|
5069
|
-
id: msgSubId,
|
|
5070
|
-
callback: options.onMessages
|
|
5071
|
-
});
|
|
5072
|
-
}
|
|
5073
|
-
if (options.onMoves || options.onGameEvents) {
|
|
5074
|
-
const handler = options.onMoves || options.onGameEvents;
|
|
5075
|
-
if (handler) {
|
|
5076
|
-
const gameSubId = "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5077
|
-
if (!this.subscriptions.gameEvents[roomId]) {
|
|
5078
|
-
this.subscriptions.gameEvents[roomId] = [];
|
|
5079
|
-
}
|
|
5080
|
-
this.subscriptions.gameEvents[roomId].push(handler);
|
|
5081
|
-
subscriptionIds.push({
|
|
5082
|
-
type: "gameEvents",
|
|
5083
|
-
id: gameSubId,
|
|
5084
|
-
callback: handler
|
|
5085
|
-
});
|
|
5086
|
-
}
|
|
5087
|
-
}
|
|
5088
|
-
const needsSubscription = subscriptionIds.length > 0 && (this.subscriptions.data[roomId]?.length ?? 0) <= 1 && (this.subscriptions.messages[roomId]?.length ?? 0) <= 1 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) <= 1;
|
|
5089
|
-
if (needsSubscription) {
|
|
5090
|
-
this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
|
|
5091
|
-
roomId,
|
|
5092
|
-
subscribeToData: !!options.onData,
|
|
5093
|
-
subscribeToMessages: !!options.onMessages,
|
|
5094
|
-
subscribeToProposedMoves: !!(options.onMoves || options.onGameEvents)
|
|
5095
|
-
}).catch((error) => {
|
|
5096
|
-
console.error("Failed to set up room subscription:", error);
|
|
5097
|
-
});
|
|
5098
|
-
}
|
|
5099
|
-
let called = false;
|
|
5100
|
-
return () => {
|
|
5101
|
-
if (called) return;
|
|
5102
|
-
called = true;
|
|
5103
|
-
subscriptionIds.forEach((sub) => {
|
|
5104
|
-
const bucket = this.subscriptions[sub.type];
|
|
5105
|
-
const callbacks = bucket && bucket[roomId] || [];
|
|
5106
|
-
const index = callbacks.indexOf(sub.callback);
|
|
5107
|
-
if (index > -1) callbacks.splice(index, 1);
|
|
5108
|
-
});
|
|
5109
|
-
const hasNoCallbacks = (this.subscriptions.data[roomId]?.length ?? 0) === 0 && (this.subscriptions.messages[roomId]?.length ?? 0) === 0 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) === 0;
|
|
5110
|
-
if (hasNoCallbacks) {
|
|
5111
|
-
this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
|
|
5112
|
-
roomId
|
|
5113
|
-
}).catch((error) => {
|
|
5114
|
-
console.error("Failed to clean up room subscription:", error);
|
|
5115
|
-
});
|
|
5116
|
-
}
|
|
5117
|
-
};
|
|
5118
|
-
}
|
|
5119
|
-
};
|
|
5120
|
-
|
|
5121
5072
|
// src/social/RpcSocialApi.ts
|
|
5122
5073
|
var RpcSocialApi = class {
|
|
5123
5074
|
constructor(rpcClient) {
|
|
@@ -5164,9 +5115,9 @@ var RemoteHost = class {
|
|
|
5164
5115
|
__publicField(this, "notifications");
|
|
5165
5116
|
__publicField(this, "popups");
|
|
5166
5117
|
__publicField(this, "profile");
|
|
5118
|
+
__publicField(this, "system");
|
|
5167
5119
|
__publicField(this, "cdn");
|
|
5168
5120
|
__publicField(this, "time");
|
|
5169
|
-
__publicField(this, "post");
|
|
5170
5121
|
__publicField(this, "ai");
|
|
5171
5122
|
__publicField(this, "haptics");
|
|
5172
5123
|
__publicField(this, "features");
|
|
@@ -5220,10 +5171,12 @@ var RemoteHost = class {
|
|
|
5220
5171
|
this.navigation = new RpcNavigationApi(rpcClient, venusApi);
|
|
5221
5172
|
this.notifications = new RpcNotificationsApi(rpcClient);
|
|
5222
5173
|
this.popups = new RpcPopupsApi(rpcClient);
|
|
5223
|
-
this.profile = new HostProfileApi();
|
|
5174
|
+
this.profile = new HostProfileApi(venusApi);
|
|
5175
|
+
const deviceApi = new HostDeviceApi(venusApi);
|
|
5176
|
+
const environmentApi = new HostEnvironmentApi(venusApi);
|
|
5177
|
+
this.system = new HostSystemApi(deviceApi, environmentApi, venusApi);
|
|
5224
5178
|
this.cdn = new HostCdnApi(getCdnBaseUrl());
|
|
5225
|
-
this.time = new HostTimeApi(rpcClient);
|
|
5226
|
-
this.post = new RpcPostApi(rpcClient);
|
|
5179
|
+
this.time = new HostTimeApi(rpcClient, venusApi);
|
|
5227
5180
|
this.ai = new RpcAiApi(rpcClient);
|
|
5228
5181
|
this.haptics = new RpcHapticsApi(rpcClient);
|
|
5229
5182
|
this.features = new RpcFeaturesApi(rpcClient);
|
|
@@ -5238,7 +5191,6 @@ var RemoteHost = class {
|
|
|
5238
5191
|
venusApi.isMock = () => false;
|
|
5239
5192
|
this.venusApi.sharedAssets = new RpcSharedAssetsApi(rpcClient, venusApi);
|
|
5240
5193
|
initializeRoomsApi(this.venusApi, this);
|
|
5241
|
-
console.log("[Venus SDK] Remote host created");
|
|
5242
5194
|
}
|
|
5243
5195
|
get isInitialized() {
|
|
5244
5196
|
return this._isInitialized;
|
|
@@ -5256,36 +5208,28 @@ var RemoteHost = class {
|
|
|
5256
5208
|
5e3
|
|
5257
5209
|
);
|
|
5258
5210
|
transport.instanceId = response.instanceId;
|
|
5259
|
-
this.log(`Remote Host Initialized with id: ${transport.instanceId}`);
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
if (venus._config) {
|
|
5273
|
-
venus._config.profile = sanitizedProfile;
|
|
5274
|
-
}
|
|
5275
|
-
if (venus.config) {
|
|
5276
|
-
venus.config.profile = sanitizedProfile;
|
|
5277
|
-
}
|
|
5278
|
-
}
|
|
5279
|
-
}
|
|
5211
|
+
this.log(`Remote Host Initialized with id: ${transport.instanceId}, response: ${JSON.stringify(response)}`);
|
|
5212
|
+
const profile = response.profile;
|
|
5213
|
+
const sanitizedProfile = {
|
|
5214
|
+
id: profile.id,
|
|
5215
|
+
username: profile.username,
|
|
5216
|
+
avatarUrl: profile.avatarUrl ?? null,
|
|
5217
|
+
isAnonymous: Boolean(profile.isAnonymous)
|
|
5218
|
+
};
|
|
5219
|
+
this.venusApi._profileData = sanitizedProfile;
|
|
5220
|
+
this.venusApi._deviceData = response.device;
|
|
5221
|
+
this.venusApi._environmentData = response.environment;
|
|
5222
|
+
this.venusApi._localeData = response.locale;
|
|
5223
|
+
this.venusApi._languageCodeData = response.languageCode;
|
|
5280
5224
|
this._isInitialized = true;
|
|
5281
|
-
this.venusApi.launchParams = response.launchParams
|
|
5225
|
+
this.venusApi.launchParams = response.launchParams;
|
|
5282
5226
|
await this.rpcClient.call("READY" /* READY */, {});
|
|
5283
|
-
const
|
|
5284
|
-
if (
|
|
5285
|
-
this.venusApi.
|
|
5227
|
+
const safeArea = response.safeArea;
|
|
5228
|
+
if (safeArea) {
|
|
5229
|
+
this.venusApi._safeAreaData = safeArea;
|
|
5286
5230
|
}
|
|
5287
5231
|
return {
|
|
5288
|
-
|
|
5232
|
+
safeArea,
|
|
5289
5233
|
initializeAsleep: response.initializeAsleep
|
|
5290
5234
|
};
|
|
5291
5235
|
}
|
|
@@ -5297,10 +5241,8 @@ var RemoteHost = class {
|
|
|
5297
5241
|
// src/Host.ts
|
|
5298
5242
|
function createHost(venusApi, isMock) {
|
|
5299
5243
|
if (isMock) {
|
|
5300
|
-
console.log("[Venus SDK] Creating Local Host");
|
|
5301
5244
|
return new MockHost(venusApi);
|
|
5302
5245
|
} else {
|
|
5303
|
-
console.log("[Venus SDK] Creating Remote Host");
|
|
5304
5246
|
return new RemoteHost(venusApi);
|
|
5305
5247
|
}
|
|
5306
5248
|
}
|
|
@@ -5313,15 +5255,35 @@ function initializeSocial(venusApi, host) {
|
|
|
5313
5255
|
};
|
|
5314
5256
|
}
|
|
5315
5257
|
|
|
5258
|
+
// raw-loader:/Users/pchan/Development/series/venus/venus-sdk/packages/api/src/webview/webviewLibraryShim.js
|
|
5259
|
+
var webviewLibraryShim_default = "/**\r\n * Venus Embedded Libraries WebView Shim\r\n *\r\n * This code is injected into H5 game WebViews BEFORE the game's main script runs.\r\n * It bootstraps the embedded libraries system by:\r\n * 1. Reading window.__venusLibrariesConfig (set by the Vite plugin)\r\n * 2. Loading libraries via RPC (mobile) or CDN (web)\r\n * 3. Registering libraries in window.__venusLibraryExports\r\n * 4. Allowing the game's virtual modules to access them\r\n *\r\n * This shim is NOT imported by H5 games - it's injected by the Venus host via\r\n * injectedJavaScriptBeforeContentLoaded in H5AppPoolRenderer.\r\n */\r\n\r\n;(function () {\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n if (window.__venusLibraryShim && window.__venusLibraryShim.__initialized) {\r\n return\r\n }\r\n\r\n var RESPONSE_TYPE = 'H5_RESPONSE'\r\n var REQUEST_TYPE = 'H5_LOAD_EMBEDDED_ASSET'\r\n var REQUEST_TIMEOUT_MS = 12000\r\n var pendingRequests = new Map()\r\n\r\n function ensureConfig() {\r\n if (!window.__venusLibrariesConfig) {\r\n window.__venusLibrariesConfig = {\r\n enabled: false,\r\n required: [],\r\n manifest: {},\r\n cdnBase: '',\r\n }\r\n }\r\n if (!window.__venusLibrariesConfig.manifest) {\r\n window.__venusLibrariesConfig.manifest = {}\r\n }\r\n if (!Array.isArray(window.__venusLibrariesConfig.required)) {\r\n window.__venusLibrariesConfig.required = []\r\n }\r\n return window.__venusLibrariesConfig\r\n }\r\n\r\n function ensureExportsRegistry() {\r\n if (!window.__venusLibraryExports) {\r\n window.__venusLibraryExports = {}\r\n }\r\n return window.__venusLibraryExports\r\n }\r\n\r\n function hasHostBridge() {\r\n return !!(\r\n window.ReactNativeWebView &&\r\n typeof window.ReactNativeWebView.postMessage === 'function'\r\n )\r\n }\r\n\r\n function registerResponseListeners() {\r\n if (\r\n window.__venusLibraryShim &&\r\n window.__venusLibraryShim.__listenerRegistered\r\n ) {\r\n return\r\n }\r\n\r\n function handleMessage(event) {\r\n var payload = parsePayload(event && event.data)\r\n if (!payload || payload.type !== RESPONSE_TYPE || !payload.data) {\r\n return\r\n }\r\n var requestId = payload.data.requestId\r\n if (!requestId || !pendingRequests.has(requestId)) {\r\n return\r\n }\r\n var pending = pendingRequests.get(requestId)\r\n pendingRequests.delete(requestId)\r\n clearTimeout(pending.timeout)\r\n\r\n if (payload.data.success === false) {\r\n pending.reject(\r\n new Error(payload.data.error || 'Embedded library load failed'),\r\n )\r\n return\r\n }\r\n\r\n var value = payload.data.value || payload.data\r\n if (!value || !value.base64Data) {\r\n pending.reject(\r\n new Error('Embedded library response was missing base64Data'),\r\n )\r\n return\r\n }\r\n\r\n pending.resolve(value.base64Data)\r\n }\r\n\r\n if (\r\n typeof document !== 'undefined' &&\r\n typeof document.addEventListener === 'function'\r\n ) {\r\n document.addEventListener('message', handleMessage, false)\r\n }\r\n if (\r\n typeof window !== 'undefined' &&\r\n typeof window.addEventListener === 'function'\r\n ) {\r\n window.addEventListener('message', handleMessage, false)\r\n }\r\n\r\n if (!window.__venusLibraryShim) {\r\n window.__venusLibraryShim = {}\r\n }\r\n window.__venusLibraryShim.__listenerRegistered = true\r\n }\r\n\r\n function parsePayload(raw) {\r\n if (!raw || typeof raw !== 'string') {\r\n return null\r\n }\r\n try {\r\n return JSON.parse(raw)\r\n } catch (error) {\r\n return null\r\n }\r\n }\r\n\r\n function createRequestId(libraryKey) {\r\n var sanitized = ''\r\n for (var i = 0; i < libraryKey.length; i++) {\r\n var c = libraryKey.charAt(i)\r\n if (\r\n (c >= 'a' && c <= 'z') ||\r\n (c >= 'A' && c <= 'Z') ||\r\n (c >= '0' && c <= '9') ||\r\n c === '-' ||\r\n c === '_'\r\n ) {\r\n sanitized += c\r\n } else {\r\n sanitized += '_'\r\n }\r\n }\r\n return (\r\n 'embedded-lib-' +\r\n sanitized +\r\n '-' +\r\n Date.now() +\r\n '-' +\r\n Math.random().toString(36).slice(2)\r\n )\r\n }\r\n\r\n function postHostRequest(assetKey, requestId) {\r\n if (!hasHostBridge()) {\r\n throw new Error('Host bridge is unavailable')\r\n }\r\n var bridge = window.ReactNativeWebView\r\n var message = {\r\n type: REQUEST_TYPE,\r\n direction: 'H5_TO_APP',\r\n data: {\r\n requestId: requestId,\r\n assetKey: assetKey,\r\n },\r\n instanceId:\r\n (window._venusInitState && window._venusInitState.poolId) || 'unknown',\r\n timestamp: Date.now(),\r\n }\r\n bridge.postMessage(JSON.stringify(message))\r\n }\r\n\r\n function loadLibraryViaHost(assetKey, libraryKey) {\r\n return new Promise(function (resolve, reject) {\r\n var requestId = createRequestId(libraryKey)\r\n var timeout = setTimeout(function () {\r\n pendingRequests.delete(requestId)\r\n reject(new Error('Timed out loading embedded library: ' + libraryKey))\r\n }, REQUEST_TIMEOUT_MS)\r\n\r\n pendingRequests.set(requestId, {\r\n resolve: resolve,\r\n reject: reject,\r\n timeout: timeout,\r\n })\r\n\r\n try {\r\n postHostRequest(assetKey, requestId)\r\n } catch (error) {\r\n pendingRequests.delete(requestId)\r\n clearTimeout(timeout)\r\n reject(error)\r\n }\r\n })\r\n }\r\n\r\n function buildCdnUrl(config, entry) {\r\n var base = config.cdnBase || ''\r\n if (!base.endsWith('/')) {\r\n base += '/'\r\n }\r\n var path = entry.cdnPath\r\n if (path.charAt(0) === '/') {\r\n path = path.substring(1)\r\n }\r\n return base + path\r\n }\r\n\r\n async function loadLibraryViaCdn(config, entry, libraryKey) {\r\n if (!config.cdnBase) {\r\n throw new Error('CDN base URL is not configured')\r\n }\r\n var url = buildCdnUrl(config, entry)\r\n var response = await fetch(url, { credentials: 'omit' })\r\n if (!response.ok) {\r\n throw new Error(\r\n 'Failed to fetch embedded library from CDN: ' + libraryKey,\r\n )\r\n }\r\n return await response.text()\r\n }\r\n\r\n function decodeBase64ToUtf8(base64) {\r\n if (typeof base64 !== 'string') {\r\n throw new Error('Invalid base64 payload')\r\n }\r\n\r\n if (typeof atob === 'function') {\r\n var binary = atob(base64)\r\n if (typeof TextDecoder !== 'undefined') {\r\n var len = binary.length\r\n var bytes = new Uint8Array(len)\r\n for (var i = 0; i < len; i++) {\r\n bytes[i] = binary.charCodeAt(i)\r\n }\r\n return new TextDecoder('utf-8').decode(bytes)\r\n }\r\n return decodeURIComponent(escape(binary))\r\n }\r\n\r\n var bufferCtor =\r\n (typeof globalThis !== 'undefined' && globalThis.Buffer) ||\r\n (typeof window !== 'undefined' && window.Buffer)\r\n if (bufferCtor) {\r\n return bufferCtor.from(base64, 'base64').toString('utf-8')\r\n }\r\n\r\n throw new Error('No base64 decoder available')\r\n }\r\n\r\n function evaluateLibrarySource(libraryKey, globalVar, source) {\r\n var registry = ensureExportsRegistry()\r\n if (!source) {\r\n throw new Error('Embedded library source was empty for ' + libraryKey)\r\n }\r\n\r\n var previousValue = window[globalVar]\r\n try {\r\n var executor = new Function(\r\n source + '\\n//# sourceURL=venus-library-' + libraryKey + '.js',\r\n )\r\n executor.call(window)\r\n } catch (error) {\r\n throw new Error(\r\n 'Failed to evaluate embedded library ' +\r\n libraryKey +\r\n ': ' +\r\n (error && error.message ? error.message : error),\r\n )\r\n }\r\n\r\n var exported = window[globalVar] || previousValue\r\n if (!exported) {\r\n throw new Error(\r\n 'Embedded library ' + libraryKey + ' did not register ' + globalVar,\r\n )\r\n }\r\n\r\n registry[libraryKey] = exported\r\n return exported\r\n }\r\n\r\n async function ensureLibraryLoaded(config, libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n if (registry[libraryKey]) {\r\n return registry[libraryKey]\r\n }\r\n\r\n var entry = config.manifest && config.manifest[libraryKey]\r\n if (!entry) {\r\n throw new Error('No manifest entry for embedded library ' + libraryKey)\r\n }\r\n\r\n var source = null\r\n if (config.useHost !== false && hasHostBridge()) {\r\n try {\r\n var base64 = await loadLibraryViaHost(entry.assetKey, libraryKey)\r\n source = decodeBase64ToUtf8(base64)\r\n } catch (error) {\r\n // Log the RPC error loudly before fallback\r\n console.error(\r\n '[Venus Libraries] Failed to load ' +\r\n libraryKey +\r\n ' from host via RPC:',\r\n error,\r\n )\r\n console.warn(\r\n '[Venus Libraries] Falling back to CDN for ' +\r\n libraryKey +\r\n '. This may indicate an asset packaging issue.',\r\n )\r\n }\r\n }\r\n\r\n if (!source) {\r\n source = await loadLibraryViaCdn(config, entry, libraryKey)\r\n }\r\n\r\n return evaluateLibrarySource(libraryKey, entry.globalVar, source)\r\n }\r\n\r\n async function bootstrap() {\r\n try {\r\n registerResponseListeners()\r\n getBootstrapPromise()\r\n\r\n var config = ensureConfig()\r\n\r\n if (!config.enabled) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n if (!Array.isArray(config.required) || config.required.length === 0) {\r\n if (bootstrapResolve) bootstrapResolve()\r\n return\r\n }\r\n\r\n // Group libraries by load stage for parallel loading within stages\r\n var librariesByStage = {}\r\n for (var i = 0; i < config.required.length; i++) {\r\n var libraryKey = config.required[i]\r\n var entry = config.manifest[libraryKey]\r\n var stage = entry.loadStage || 0\r\n if (!librariesByStage[stage]) librariesByStage[stage] = []\r\n librariesByStage[stage].push(libraryKey)\r\n }\r\n\r\n // Load stages sequentially, libraries within each stage in parallel\r\n var stages = Object.keys(librariesByStage).sort(function (a, b) {\r\n return parseInt(a, 10) - parseInt(b, 10)\r\n })\r\n\r\n for (var s = 0; s < stages.length; s++) {\r\n var stage = stages[s]\r\n var libs = librariesByStage[stage]\r\n\r\n // Load all libraries in this stage in parallel\r\n var stagePromises = libs.map(function (libraryKey) {\r\n return ensureLibraryLoaded(config, libraryKey).catch(\r\n function (error) {\r\n console.error(\r\n '[Venus Libraries] Failed to load library ' + libraryKey,\r\n error,\r\n )\r\n throw error\r\n },\r\n )\r\n })\r\n\r\n await Promise.all(stagePromises)\r\n }\r\n\r\n if (bootstrapResolve) bootstrapResolve()\r\n } catch (error) {\r\n console.error('[Venus Libraries] Bootstrap error', error)\r\n if (bootstrapReject) bootstrapReject(error)\r\n throw error\r\n }\r\n }\r\n\r\n // Create a promise that resolves when bootstrap completes\r\n var bootstrapPromise = null\r\n var bootstrapResolve = null\r\n var bootstrapReject = null\r\n\r\n function getBootstrapPromise() {\r\n if (!bootstrapPromise) {\r\n bootstrapPromise = new Promise(function (resolve, reject) {\r\n bootstrapResolve = resolve\r\n bootstrapReject = reject\r\n })\r\n }\r\n return bootstrapPromise\r\n }\r\n\r\n window.__venusLibraryShim = {\r\n bootstrap: bootstrap,\r\n ready: getBootstrapPromise,\r\n getExports: function (libraryKey) {\r\n var registry = ensureExportsRegistry()\r\n return registry[libraryKey]\r\n },\r\n __initialized: true,\r\n }\r\n})()\r\n";
|
|
5260
|
+
|
|
5261
|
+
// src/webview/webviewLibraryShimSource.ts
|
|
5262
|
+
var WEBVIEW_LIBRARY_SHIM_SOURCE = webviewLibraryShim_default;
|
|
5263
|
+
function getWebviewLibraryShimSource() {
|
|
5264
|
+
return WEBVIEW_LIBRARY_SHIM_SOURCE;
|
|
5265
|
+
}
|
|
5266
|
+
|
|
5267
|
+
exports.DEFAULT_SHARED_LIB_CDN_BASE = DEFAULT_SHARED_LIB_CDN_BASE;
|
|
5268
|
+
exports.EMBEDDED_LIBRARIES = EMBEDDED_LIBRARIES;
|
|
5269
|
+
exports.EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARY_BY_KEY;
|
|
5270
|
+
exports.HASH_ALGORITHM_NODE = HASH_ALGORITHM_NODE;
|
|
5271
|
+
exports.HASH_ALGORITHM_WEB_CRYPTO = HASH_ALGORITHM_WEB_CRYPTO;
|
|
5316
5272
|
exports.HapticFeedbackStyle = HapticFeedbackStyle;
|
|
5317
5273
|
exports.HostCdnApi = HostCdnApi;
|
|
5274
|
+
exports.HostDeviceApi = HostDeviceApi;
|
|
5275
|
+
exports.HostEnvironmentApi = HostEnvironmentApi;
|
|
5318
5276
|
exports.HostProfileApi = HostProfileApi;
|
|
5277
|
+
exports.HostSystemApi = HostSystemApi;
|
|
5319
5278
|
exports.HostTimeApi = HostTimeApi;
|
|
5279
|
+
exports.MODULE_TO_LIBRARY_SPECIFIERS = MODULE_TO_LIBRARY_SPECIFIERS;
|
|
5320
5280
|
exports.MockAdsApi = MockAdsApi;
|
|
5321
5281
|
exports.MockAiApi = MockAiApi;
|
|
5322
5282
|
exports.MockAnalyticsApi = MockAnalyticsApi;
|
|
5323
5283
|
exports.MockAvatarApi = MockAvatarApi;
|
|
5324
5284
|
exports.MockCdnApi = MockCdnApi;
|
|
5285
|
+
exports.MockDeviceApi = MockDeviceApi;
|
|
5286
|
+
exports.MockEnvironmentApi = MockEnvironmentApi;
|
|
5325
5287
|
exports.MockFeaturesApi = MockFeaturesApi;
|
|
5326
5288
|
exports.MockHapticsApi = MockHapticsApi;
|
|
5327
5289
|
exports.MockIapApi = MockIapApi;
|
|
@@ -5334,9 +5296,9 @@ exports.MockPopupsApi = MockPopupsApi;
|
|
|
5334
5296
|
exports.MockPreloaderApi = MockPreloaderApi;
|
|
5335
5297
|
exports.MockProfileApi = MockProfileApi;
|
|
5336
5298
|
exports.MockSharedAssetsApi = MockSharedAssetsApi;
|
|
5337
|
-
exports.MockSimulationApi = MockSimulationApi;
|
|
5338
5299
|
exports.MockSocialApi = MockSocialApi;
|
|
5339
5300
|
exports.MockStorageApi = MockStorageApi;
|
|
5301
|
+
exports.MockSystemApi = MockSystemApi;
|
|
5340
5302
|
exports.MockTimeApi = MockTimeApi;
|
|
5341
5303
|
exports.RemoteHost = RemoteHost;
|
|
5342
5304
|
exports.RpcAdsApi = RpcAdsApi;
|
|
@@ -5354,14 +5316,22 @@ exports.RpcNavigationApi = RpcNavigationApi;
|
|
|
5354
5316
|
exports.RpcNotificationsApi = RpcNotificationsApi;
|
|
5355
5317
|
exports.RpcPopupsApi = RpcPopupsApi;
|
|
5356
5318
|
exports.RpcPreloaderApi = RpcPreloaderApi;
|
|
5319
|
+
exports.RpcRoomsApi = RpcRoomsApi;
|
|
5357
5320
|
exports.RpcSharedAssetsApi = RpcSharedAssetsApi;
|
|
5358
5321
|
exports.RpcSimulationApi = RpcSimulationApi;
|
|
5359
5322
|
exports.RpcSocialApi = RpcSocialApi;
|
|
5360
5323
|
exports.RpcStorageApi = RpcStorageApi;
|
|
5361
5324
|
exports.SDK_VERSION = SDK_VERSION;
|
|
5362
5325
|
exports.VenusMessageId = VenusMessageId;
|
|
5326
|
+
exports.VenusRoom = VenusRoom;
|
|
5327
|
+
exports.WEBVIEW_LIBRARY_SHIM_SOURCE = WEBVIEW_LIBRARY_SHIM_SOURCE;
|
|
5328
|
+
exports.base64ToArrayBuffer = base64ToArrayBuffer;
|
|
5329
|
+
exports.base64ToUtf8 = base64ToUtf8;
|
|
5330
|
+
exports.computeScoreHash = computeScoreHash;
|
|
5363
5331
|
exports.createHost = createHost;
|
|
5364
5332
|
exports.createMockStorageApi = createMockStorageApi;
|
|
5333
|
+
exports.getLibraryDefinition = getLibraryDefinition;
|
|
5334
|
+
exports.getWebviewLibraryShimSource = getWebviewLibraryShimSource;
|
|
5365
5335
|
exports.initializeAds = initializeAds;
|
|
5366
5336
|
exports.initializeAi = initializeAi;
|
|
5367
5337
|
exports.initializeAnalytics = initializeAnalytics;
|
|
@@ -5382,6 +5352,7 @@ exports.initializeSimulation = initializeSimulation;
|
|
|
5382
5352
|
exports.initializeSocial = initializeSocial;
|
|
5383
5353
|
exports.initializeStackNavigation = initializeStackNavigation;
|
|
5384
5354
|
exports.initializeStorage = initializeStorage;
|
|
5355
|
+
exports.initializeSystem = initializeSystem;
|
|
5385
5356
|
exports.initializeTime = initializeTime;
|
|
5386
5357
|
exports.isPacificDaylightTime = isPacificDaylightTime;
|
|
5387
5358
|
exports.setupRoomNotifications = setupRoomNotifications;
|