@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
|
@@ -1,219 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
// src/rooms/VenusRoom.ts
|
|
4
|
-
var VenusRoom;
|
|
5
|
-
var init_VenusRoom = __esm({
|
|
6
|
-
"src/rooms/VenusRoom.ts"() {
|
|
7
|
-
VenusRoom = class {
|
|
8
|
-
constructor(roomData) {
|
|
9
|
-
__publicField(this, "id");
|
|
10
|
-
__publicField(this, "name");
|
|
11
|
-
__publicField(this, "players");
|
|
12
|
-
__publicField(this, "maxPlayers");
|
|
13
|
-
__publicField(this, "gameType");
|
|
14
|
-
__publicField(this, "appId");
|
|
15
|
-
__publicField(this, "type");
|
|
16
|
-
__publicField(this, "createdBy");
|
|
17
|
-
__publicField(this, "createdAt");
|
|
18
|
-
__publicField(this, "updatedAt");
|
|
19
|
-
__publicField(this, "isPrivate");
|
|
20
|
-
__publicField(this, "currentPlayers");
|
|
21
|
-
__publicField(this, "status");
|
|
22
|
-
__publicField(this, "customMetadata");
|
|
23
|
-
__publicField(this, "admins");
|
|
24
|
-
__publicField(this, "roomCode");
|
|
25
|
-
__publicField(this, "description");
|
|
26
|
-
__publicField(this, "data");
|
|
27
|
-
__publicField(this, "version");
|
|
28
|
-
__publicField(this, "_subscriptions", /* @__PURE__ */ new Map());
|
|
29
|
-
this.id = roomData.id;
|
|
30
|
-
this.name = roomData.name;
|
|
31
|
-
this.players = roomData.currentPlayers || [];
|
|
32
|
-
this.maxPlayers = roomData.maxPlayers;
|
|
33
|
-
this.gameType = roomData.gameType;
|
|
34
|
-
this.appId = roomData.appId;
|
|
35
|
-
this.type = roomData.type;
|
|
36
|
-
this.createdBy = roomData.createdBy;
|
|
37
|
-
this.createdAt = roomData.createdAt;
|
|
38
|
-
this.updatedAt = roomData.updatedAt;
|
|
39
|
-
this.isPrivate = roomData.isPrivate;
|
|
40
|
-
this.currentPlayers = roomData.currentPlayers || [];
|
|
41
|
-
this.status = roomData.status;
|
|
42
|
-
this.customMetadata = roomData.customMetadata || {};
|
|
43
|
-
this.admins = roomData.admins || [];
|
|
44
|
-
this.roomCode = roomData.roomCode;
|
|
45
|
-
this.description = roomData.description;
|
|
46
|
-
this.data = roomData.data || {};
|
|
47
|
-
this.version = roomData.version;
|
|
48
|
-
console.log(`VenusRoom: Created room object for ${this.id}`, {
|
|
49
|
-
hasCustomMetadata: !!this.customMetadata,
|
|
50
|
-
hasGameState: !!this.customMetadata?.rules?.gameState,
|
|
51
|
-
gamePhase: this.customMetadata?.rules?.gameState?.phase,
|
|
52
|
-
currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
updateFromRoomData(newRoomData) {
|
|
56
|
-
if (newRoomData.id === this.id) {
|
|
57
|
-
this.name = newRoomData.name || this.name;
|
|
58
|
-
this.players = newRoomData.currentPlayers || this.players;
|
|
59
|
-
this.maxPlayers = newRoomData.maxPlayers || this.maxPlayers;
|
|
60
|
-
this.gameType = newRoomData.gameType || this.gameType;
|
|
61
|
-
this.currentPlayers = newRoomData.currentPlayers || this.currentPlayers;
|
|
62
|
-
this.customMetadata = newRoomData.customMetadata || this.customMetadata;
|
|
63
|
-
this.data = newRoomData.data || this.data;
|
|
64
|
-
this.status = newRoomData.status || this.status;
|
|
65
|
-
this.updatedAt = newRoomData.updatedAt || this.updatedAt;
|
|
66
|
-
console.log(`VenusRoom: Updated room object ${this.id} with fresh data`, {
|
|
67
|
-
hasCustomMetadata: !!this.customMetadata,
|
|
68
|
-
hasGameState: !!this.customMetadata?.rules?.gameState,
|
|
69
|
-
gamePhase: this.customMetadata?.rules?.gameState?.phase,
|
|
70
|
-
currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// src/rooms/RoomsApi.ts
|
|
79
|
-
var init_RoomsApi = __esm({
|
|
80
|
-
"src/rooms/RoomsApi.ts"() {
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// src/rooms/index.ts
|
|
85
|
-
var rooms_exports = {};
|
|
86
|
-
__export(rooms_exports, {
|
|
87
|
-
VenusRoom: () => VenusRoom,
|
|
88
|
-
initializeRoomsApi: () => initializeRoomsApi,
|
|
89
|
-
setupRoomNotifications: () => setupRoomNotifications
|
|
90
|
-
});
|
|
91
|
-
function bindMethod(target, targetKey, source, sourceKey) {
|
|
92
|
-
const key = sourceKey ?? targetKey;
|
|
93
|
-
const fn = source?.[key];
|
|
94
|
-
if (typeof fn === "function") {
|
|
95
|
-
target[targetKey] = fn.bind(source);
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
function setupRoomNotifications(transport, getSubscriptions) {
|
|
101
|
-
console.log("[Venus Rooms] Setting up room notification listeners");
|
|
102
|
-
return transport.onVenusMessage((message) => {
|
|
103
|
-
const subscriptions = getSubscriptions();
|
|
104
|
-
if (!subscriptions) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
if (message.type === "H5_ROOM_DATA_UPDATED") {
|
|
108
|
-
const messageData = message.data;
|
|
109
|
-
const { roomId, roomData } = messageData;
|
|
110
|
-
if (!roomId) return;
|
|
111
|
-
const callbacks = subscriptions.data?.[roomId] || [];
|
|
112
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
113
|
-
console.log(`[Venus Rooms] \u{1F514} Room data updated for ${roomId}, notifying ${callbacks.length} callbacks`, roomData);
|
|
114
|
-
callbacks.forEach((callback) => {
|
|
115
|
-
try {
|
|
116
|
-
callback(roomData);
|
|
117
|
-
} catch (error) {
|
|
118
|
-
console.error("[Venus Rooms] Error in room data callback:", error);
|
|
119
|
-
throw error;
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
allEventsCallbacks.forEach((callback) => {
|
|
123
|
-
try {
|
|
124
|
-
callback({ type: message.type, ...messageData });
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
127
|
-
throw error;
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
|
|
132
|
-
const messageData = message.data;
|
|
133
|
-
const { roomId } = messageData;
|
|
134
|
-
if (!roomId) return;
|
|
135
|
-
const callbacks = subscriptions.messages?.[roomId] || [];
|
|
136
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
137
|
-
console.log(`[Venus Rooms] \u{1F514} Room message event for ${roomId}, notifying ${callbacks.length} callbacks`);
|
|
138
|
-
callbacks.forEach((callback) => {
|
|
139
|
-
try {
|
|
140
|
-
callback(messageData);
|
|
141
|
-
} catch (error) {
|
|
142
|
-
console.error("[Venus Rooms] Error in room message callback:", error);
|
|
143
|
-
throw error;
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
allEventsCallbacks.forEach((callback) => {
|
|
147
|
-
try {
|
|
148
|
-
callback({ type: message.type, ...messageData });
|
|
149
|
-
} catch (error) {
|
|
150
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
151
|
-
throw error;
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
if (message.type === "app:h5:proposedMoveValidationUpdated") {
|
|
156
|
-
const messageData = message.data;
|
|
157
|
-
const { roomId } = messageData;
|
|
158
|
-
if (!roomId) return;
|
|
159
|
-
const callbacks = subscriptions.gameEvents?.[roomId] || [];
|
|
160
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
161
|
-
console.log(`[Venus Rooms] \u{1F514} Proposed move validation updated for ${roomId}, notifying ${callbacks.length} callbacks`);
|
|
162
|
-
callbacks.forEach((callback) => {
|
|
163
|
-
try {
|
|
164
|
-
callback(messageData);
|
|
165
|
-
} catch (error) {
|
|
166
|
-
console.error("[Venus Rooms] Error in game event callback:", error);
|
|
167
|
-
throw error;
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
allEventsCallbacks.forEach((callback) => {
|
|
171
|
-
try {
|
|
172
|
-
callback({ type: message.type, ...messageData });
|
|
173
|
-
} catch (error) {
|
|
174
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
175
|
-
throw error;
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
function initializeRoomsApi(venusApi, host) {
|
|
182
|
-
const roomsApi = host?.rooms;
|
|
183
|
-
if (!roomsApi) {
|
|
184
|
-
console.warn(
|
|
185
|
-
"[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
|
|
186
|
-
);
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
const venus = venusApi;
|
|
190
|
-
const existingNamespace = venus.rooms || {};
|
|
191
|
-
const roomsNamespace = Object.assign({}, existingNamespace);
|
|
192
|
-
const namespaceBindings = [
|
|
193
|
-
["create", "createRoom"],
|
|
194
|
-
["joinOrCreate", "joinOrCreateRoom"],
|
|
195
|
-
["joinByCode", "joinRoomByCode"],
|
|
196
|
-
["list", "getUserRooms"],
|
|
197
|
-
["subscribeToRoom", "subscribe"],
|
|
198
|
-
["updateRoomData", "updateData"],
|
|
199
|
-
["getRoomData", "getData"],
|
|
200
|
-
["sendRoomMessage", "sendMessage"],
|
|
201
|
-
["leaveRoom", "leave"],
|
|
202
|
-
["startRoomGame", "startGame"],
|
|
203
|
-
["proposeMove"],
|
|
204
|
-
["validateMove"]
|
|
205
|
-
];
|
|
206
|
-
namespaceBindings.forEach(([targetKey, sourceKey]) => {
|
|
207
|
-
bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
|
|
208
|
-
});
|
|
209
|
-
venus.rooms = roomsNamespace;
|
|
210
|
-
}
|
|
211
|
-
var init_rooms = __esm({
|
|
212
|
-
"src/rooms/index.ts"() {
|
|
213
|
-
init_RoomsApi();
|
|
214
|
-
init_VenusRoom();
|
|
215
|
-
}
|
|
216
|
-
});
|
|
1
|
+
import { createMockDelay, MOCK_DELAYS, isWebPlatform } from './chunk-QABXMFND.mjs';
|
|
2
|
+
import { __publicField } from './chunk-NSSMTXJJ.mjs';
|
|
217
3
|
|
|
218
4
|
// src/VenusMessageId.ts
|
|
219
5
|
var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
@@ -261,10 +47,6 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
|
261
47
|
VenusMessageId2["CONFIRM_DIALOG"] = "H5_CONFIRM_DIALOG";
|
|
262
48
|
VenusMessageId2["ACTION_SHEET_SHOW"] = "H5_ACTION_SHEET_SHOW";
|
|
263
49
|
VenusMessageId2["REQUEST_SERVER_TIME"] = "H5_REQUEST_SERVER_TIME";
|
|
264
|
-
VenusMessageId2["GET_POST_INTERACTIONS"] = "H5_GET_POST_INTERACTIONS";
|
|
265
|
-
VenusMessageId2["TOGGLE_LIKE"] = "H5_TOGGLE_LIKE";
|
|
266
|
-
VenusMessageId2["OPEN_COMMENTS"] = "H5_OPEN_COMMENTS";
|
|
267
|
-
VenusMessageId2["TOGGLE_FOLLOW"] = "H5_TOGGLE_FOLLOW";
|
|
268
50
|
VenusMessageId2["SHARE_LINK"] = "H5_SHARE_LINK";
|
|
269
51
|
VenusMessageId2["CREATE_SHARE_QRCODE"] = "H5_CREATE_SHARE_QRCODE";
|
|
270
52
|
VenusMessageId2["AI_CHAT_COMPLETION"] = "H5_AI_CHAT_COMPLETION";
|
|
@@ -306,11 +88,14 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
|
306
88
|
VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
|
|
307
89
|
VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
|
|
308
90
|
VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
|
|
309
|
-
VenusMessageId2["
|
|
91
|
+
VenusMessageId2["H5_SIMULATION_SUBSCRIBE"] = "H5_SIMULATION_SUBSCRIBE";
|
|
92
|
+
VenusMessageId2["H5_SIMULATION_UNSUBSCRIBE"] = "H5_SIMULATION_UNSUBSCRIBE";
|
|
93
|
+
VenusMessageId2["H5_SIMULATION_UPDATE"] = "H5_SIMULATION_UPDATE";
|
|
94
|
+
VenusMessageId2["H5_LEADERBOARD_CREATE_SCORE_TOKEN"] = "H5_LEADERBOARD_CREATE_SCORE_TOKEN";
|
|
310
95
|
VenusMessageId2["H5_LEADERBOARD_SUBMIT_SCORE"] = "H5_LEADERBOARD_SUBMIT_SCORE";
|
|
311
|
-
VenusMessageId2["
|
|
312
|
-
VenusMessageId2["
|
|
313
|
-
VenusMessageId2["
|
|
96
|
+
VenusMessageId2["H5_LEADERBOARD_GET_PAGED_SCORES"] = "H5_LEADERBOARD_GET_PAGED_SCORES";
|
|
97
|
+
VenusMessageId2["H5_LEADERBOARD_GET_PODIUM_SCORES"] = "H5_LEADERBOARD_GET_PODIUM_SCORES";
|
|
98
|
+
VenusMessageId2["H5_LEADERBOARD_GET_MY_RANK"] = "H5_LEADERBOARD_GET_MY_RANK";
|
|
314
99
|
VenusMessageId2["H5_ROOM_CREATE"] = "H5_ROOM_CREATE";
|
|
315
100
|
VenusMessageId2["H5_ROOM_JOIN"] = "H5_ROOM_JOIN";
|
|
316
101
|
VenusMessageId2["H5_ROOM_JOIN_OR_CREATE"] = "H5_ROOM_JOIN_OR_CREATE";
|
|
@@ -553,7 +338,7 @@ var MockAvatarApi = class {
|
|
|
553
338
|
async deleteAvatar() {
|
|
554
339
|
console.log(`[Venus Mock] Deleting avatar3d config`);
|
|
555
340
|
const venusApi = this._venusApi;
|
|
556
|
-
const currentProfile = venusApi.
|
|
341
|
+
const currentProfile = venusApi.getProfile();
|
|
557
342
|
const profileId = currentProfile?.id || "default_profile";
|
|
558
343
|
localStorage.removeItem(`venus-mock-avatar3d-${profileId}`);
|
|
559
344
|
console.log(
|
|
@@ -568,7 +353,7 @@ var MockAvatarApi = class {
|
|
|
568
353
|
console.log(`[Venus Mock] Loading shared avatar3d by ID: ${avatar3dId}`);
|
|
569
354
|
config = await this.selectAvatarConfig(avatar3dId, false);
|
|
570
355
|
} else {
|
|
571
|
-
const currentProfile = venusApi.
|
|
356
|
+
const currentProfile = venusApi.getProfile();
|
|
572
357
|
const profileId = currentProfile?.id || "default_profile";
|
|
573
358
|
console.log(`[Venus Mock] Loading avatar3d for profile: ${profileId}`);
|
|
574
359
|
console.log(
|
|
@@ -585,7 +370,7 @@ var MockAvatarApi = class {
|
|
|
585
370
|
async saveAvatar(config) {
|
|
586
371
|
console.log(`[Venus Mock] Saving avatar3d config:`, config);
|
|
587
372
|
const venusApi = this._venusApi;
|
|
588
|
-
const currentProfile = venusApi.
|
|
373
|
+
const currentProfile = venusApi.getProfile();
|
|
589
374
|
const profileId = currentProfile?.id || "default_profile";
|
|
590
375
|
localStorage.setItem(
|
|
591
376
|
`venus-mock-avatar3d-${profileId}`,
|
|
@@ -1101,7 +886,8 @@ var HostCdnApi = class {
|
|
|
1101
886
|
return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
|
|
1102
887
|
});
|
|
1103
888
|
const encodedSubPath = encodedParts.join("/");
|
|
1104
|
-
const
|
|
889
|
+
const cacheBust = Date.now();
|
|
890
|
+
const fullUrl = this.baseUrl + "/" + encodedSubPath + `?cacheBust=${cacheBust}`;
|
|
1105
891
|
return fullUrl;
|
|
1106
892
|
}
|
|
1107
893
|
resolveAvatarAssetUrl(subPath) {
|
|
@@ -1116,9 +902,15 @@ var HostCdnApi = class {
|
|
|
1116
902
|
|
|
1117
903
|
// src/cdn/MockCdnApi.ts
|
|
1118
904
|
var MockCdnApi = class {
|
|
1119
|
-
constructor() {
|
|
1120
|
-
__publicField(this, "
|
|
1121
|
-
this.
|
|
905
|
+
constructor(venusApi) {
|
|
906
|
+
__publicField(this, "venusApi");
|
|
907
|
+
this.venusApi = venusApi;
|
|
908
|
+
}
|
|
909
|
+
get baseUrl() {
|
|
910
|
+
return this.venusApi._mock?.cdnBaseUrl ?? "https://venus-static-01293ak.web.app/";
|
|
911
|
+
}
|
|
912
|
+
get forceRemoteCdn() {
|
|
913
|
+
return this.venusApi._mock?.cdnForceRemote ?? false;
|
|
1122
914
|
}
|
|
1123
915
|
async fetchBlob(path, options) {
|
|
1124
916
|
const controller = new AbortController();
|
|
@@ -1155,6 +947,10 @@ var MockCdnApi = class {
|
|
|
1155
947
|
return subPath;
|
|
1156
948
|
}
|
|
1157
949
|
const cleanSubPath = subPath.startsWith("/") ? subPath.slice(1) : subPath;
|
|
950
|
+
const isLocalhost = typeof window !== "undefined" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1");
|
|
951
|
+
if (isLocalhost && !this.forceRemoteCdn) {
|
|
952
|
+
return `/${cleanSubPath}`;
|
|
953
|
+
}
|
|
1158
954
|
const pathParts = cleanSubPath.split("/");
|
|
1159
955
|
const encodedParts = pathParts.map((part, index) => {
|
|
1160
956
|
return index === pathParts.length - 1 ? encodeURIComponent(part) : part;
|
|
@@ -1276,6 +1072,212 @@ function initializeCdn(venusApi, host) {
|
|
|
1276
1072
|
venusApi.cdn = host.cdn;
|
|
1277
1073
|
}
|
|
1278
1074
|
|
|
1075
|
+
// src/device/HostDeviceApi.ts
|
|
1076
|
+
var HostDeviceApi = class {
|
|
1077
|
+
constructor(venusApi) {
|
|
1078
|
+
__publicField(this, "venusApi");
|
|
1079
|
+
this.venusApi = venusApi;
|
|
1080
|
+
}
|
|
1081
|
+
getDevice() {
|
|
1082
|
+
const device = this.venusApi._deviceData;
|
|
1083
|
+
if (!device) {
|
|
1084
|
+
throw new Error(
|
|
1085
|
+
"[Venus SDK] Device info not available. You must await VenusAPI.initializeAsync() before calling getDevice(). INIT_SDK has not completed."
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
return device;
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
// src/device/MockDeviceApi.ts
|
|
1093
|
+
var MockDeviceApi = class {
|
|
1094
|
+
constructor(venusApi) {
|
|
1095
|
+
__publicField(this, "venusApi");
|
|
1096
|
+
this.venusApi = venusApi;
|
|
1097
|
+
}
|
|
1098
|
+
getDevice() {
|
|
1099
|
+
const width = typeof window !== "undefined" ? window.innerWidth : 400;
|
|
1100
|
+
const height = typeof window !== "undefined" ? window.innerHeight : 800;
|
|
1101
|
+
return {
|
|
1102
|
+
screenSize: { width, height },
|
|
1103
|
+
viewportSize: {
|
|
1104
|
+
width: width - 20,
|
|
1105
|
+
// account for safe area
|
|
1106
|
+
height: height - 20
|
|
1107
|
+
},
|
|
1108
|
+
orientation: width > height ? "landscape" : "portrait",
|
|
1109
|
+
pixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
|
|
1110
|
+
fontScale: 1,
|
|
1111
|
+
deviceType: width > 768 ? "tablet" : "phone",
|
|
1112
|
+
hapticsEnabled: false,
|
|
1113
|
+
haptics: { supported: false, enabled: false }
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
};
|
|
1117
|
+
|
|
1118
|
+
// src/environment/HostEnvironmentApi.ts
|
|
1119
|
+
var HostEnvironmentApi = class {
|
|
1120
|
+
constructor(venusApi) {
|
|
1121
|
+
__publicField(this, "venusApi");
|
|
1122
|
+
this.venusApi = venusApi;
|
|
1123
|
+
}
|
|
1124
|
+
getEnvironment() {
|
|
1125
|
+
const environment = this.venusApi._environmentData;
|
|
1126
|
+
if (!environment) {
|
|
1127
|
+
throw new Error(
|
|
1128
|
+
"[Venus SDK] Environment info not available. You must await VenusAPI.initializeAsync() before calling getEnvironment(). INIT_SDK has not completed."
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
return environment;
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
|
|
1135
|
+
// src/environment/MockEnvironmentApi.ts
|
|
1136
|
+
var MockEnvironmentApi = class {
|
|
1137
|
+
constructor(venusApi) {
|
|
1138
|
+
__publicField(this, "venusApi");
|
|
1139
|
+
this.venusApi = venusApi;
|
|
1140
|
+
}
|
|
1141
|
+
getEnvironment() {
|
|
1142
|
+
const getBrowser = () => {
|
|
1143
|
+
if (typeof navigator === "undefined") return "unknown";
|
|
1144
|
+
const userAgent = navigator.userAgent;
|
|
1145
|
+
if (/chrome|chromium|crios/i.test(userAgent)) return "chrome";
|
|
1146
|
+
if (/firefox|fxios/i.test(userAgent)) return "firefox";
|
|
1147
|
+
if (/safari/i.test(userAgent)) return "safari";
|
|
1148
|
+
if (/edg/i.test(userAgent)) return "edge";
|
|
1149
|
+
if (/opera|opr/i.test(userAgent)) return "opera";
|
|
1150
|
+
return "unknown";
|
|
1151
|
+
};
|
|
1152
|
+
return {
|
|
1153
|
+
isDevelopment: true,
|
|
1154
|
+
platform: "web",
|
|
1155
|
+
platformVersion: "mock-1.0",
|
|
1156
|
+
browserInfo: {
|
|
1157
|
+
browser: getBrowser(),
|
|
1158
|
+
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "mock-agent",
|
|
1159
|
+
isMobile: typeof navigator !== "undefined" ? /Mobi|Android/i.test(navigator.userAgent) : false,
|
|
1160
|
+
isTablet: typeof navigator !== "undefined" ? /iPad|Tablet|Pad/i.test(navigator.userAgent) : false,
|
|
1161
|
+
language: typeof navigator !== "undefined" ? navigator.language || "en-US" : "en-US"
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
|
|
1167
|
+
// src/system/HostSystemApi.ts
|
|
1168
|
+
var HostSystemApi = class {
|
|
1169
|
+
constructor(deviceApi, environmentApi, venusApi) {
|
|
1170
|
+
__publicField(this, "deviceApi");
|
|
1171
|
+
__publicField(this, "environmentApi");
|
|
1172
|
+
__publicField(this, "venusApi");
|
|
1173
|
+
this.deviceApi = deviceApi;
|
|
1174
|
+
this.environmentApi = environmentApi;
|
|
1175
|
+
this.venusApi = venusApi;
|
|
1176
|
+
}
|
|
1177
|
+
getDevice() {
|
|
1178
|
+
return this.deviceApi.getDevice();
|
|
1179
|
+
}
|
|
1180
|
+
getEnvironment() {
|
|
1181
|
+
return this.environmentApi.getEnvironment();
|
|
1182
|
+
}
|
|
1183
|
+
getSafeArea() {
|
|
1184
|
+
const safeArea = this.venusApi._safeAreaData;
|
|
1185
|
+
if (!safeArea) {
|
|
1186
|
+
throw new Error(
|
|
1187
|
+
"[Venus SDK] getSafeArea() called before initialization. Call VenusAPI.initializeAsync() first."
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
return { ...safeArea };
|
|
1191
|
+
}
|
|
1192
|
+
isMobile() {
|
|
1193
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1194
|
+
if (environment.platform === "ios" || environment.platform === "android") {
|
|
1195
|
+
return true;
|
|
1196
|
+
}
|
|
1197
|
+
if (environment.browserInfo) {
|
|
1198
|
+
return environment.browserInfo.isMobile;
|
|
1199
|
+
}
|
|
1200
|
+
return true;
|
|
1201
|
+
}
|
|
1202
|
+
isWeb() {
|
|
1203
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1204
|
+
if (environment.platform === "web") {
|
|
1205
|
+
return true;
|
|
1206
|
+
}
|
|
1207
|
+
if (environment.browserInfo && !environment.browserInfo.isMobile) {
|
|
1208
|
+
return true;
|
|
1209
|
+
}
|
|
1210
|
+
return false;
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
|
|
1214
|
+
// src/system/MockSystemApi.ts
|
|
1215
|
+
var MockSystemApi = class {
|
|
1216
|
+
constructor(deviceApi, environmentApi, venusApi) {
|
|
1217
|
+
__publicField(this, "deviceApi");
|
|
1218
|
+
__publicField(this, "environmentApi");
|
|
1219
|
+
__publicField(this, "venusApi");
|
|
1220
|
+
this.deviceApi = deviceApi;
|
|
1221
|
+
this.environmentApi = environmentApi;
|
|
1222
|
+
this.venusApi = venusApi;
|
|
1223
|
+
}
|
|
1224
|
+
getDevice() {
|
|
1225
|
+
return this.deviceApi.getDevice();
|
|
1226
|
+
}
|
|
1227
|
+
getEnvironment() {
|
|
1228
|
+
return this.environmentApi.getEnvironment();
|
|
1229
|
+
}
|
|
1230
|
+
getSafeArea() {
|
|
1231
|
+
const safeArea = this.venusApi._safeAreaData;
|
|
1232
|
+
if (!safeArea) {
|
|
1233
|
+
return {
|
|
1234
|
+
top: 0,
|
|
1235
|
+
right: 0,
|
|
1236
|
+
bottom: 34,
|
|
1237
|
+
left: 0
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
return { ...safeArea };
|
|
1241
|
+
}
|
|
1242
|
+
isMobile() {
|
|
1243
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1244
|
+
if (environment.platform === "ios" || environment.platform === "android") {
|
|
1245
|
+
return true;
|
|
1246
|
+
}
|
|
1247
|
+
if (environment.browserInfo) {
|
|
1248
|
+
return environment.browserInfo.isMobile;
|
|
1249
|
+
}
|
|
1250
|
+
return true;
|
|
1251
|
+
}
|
|
1252
|
+
isWeb() {
|
|
1253
|
+
const environment = this.environmentApi.getEnvironment();
|
|
1254
|
+
if (environment.platform === "web") {
|
|
1255
|
+
return true;
|
|
1256
|
+
}
|
|
1257
|
+
if (environment.browserInfo && !environment.browserInfo.isMobile) {
|
|
1258
|
+
return true;
|
|
1259
|
+
}
|
|
1260
|
+
return false;
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
// src/system/index.ts
|
|
1265
|
+
function initializeSystem(venusApi, host) {
|
|
1266
|
+
venusApi.system = host.system;
|
|
1267
|
+
venusApi.isMobile = () => {
|
|
1268
|
+
console.warn(
|
|
1269
|
+
"[Venus SDK] DEPRECATED: VenusAPI.isMobile() is deprecated. Use VenusAPI.system.isMobile() instead."
|
|
1270
|
+
);
|
|
1271
|
+
return host.system.isMobile();
|
|
1272
|
+
};
|
|
1273
|
+
venusApi.isWeb = () => {
|
|
1274
|
+
console.warn(
|
|
1275
|
+
"[Venus SDK] DEPRECATED: VenusAPI.isWeb() is deprecated. Use VenusAPI.system.isWeb() instead."
|
|
1276
|
+
);
|
|
1277
|
+
return host.system.isWeb();
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1279
1281
|
// src/features/RpcFeaturesApi.ts
|
|
1280
1282
|
var RpcFeaturesApi = class {
|
|
1281
1283
|
constructor(rcpClient) {
|
|
@@ -1758,13 +1760,8 @@ var MockNotificationsApi = class {
|
|
|
1758
1760
|
async cancelNotification(notificationId) {
|
|
1759
1761
|
const venusApi = this.venusApi;
|
|
1760
1762
|
if (isWebPlatform()) {
|
|
1761
|
-
console.log(
|
|
1762
|
-
"[Venus Mock] Cancel notification on web platform (simulated):",
|
|
1763
|
-
notificationId
|
|
1764
|
-
);
|
|
1765
1763
|
return true;
|
|
1766
1764
|
}
|
|
1767
|
-
console.log("[Venus Mock] Cancel local notification:", notificationId);
|
|
1768
1765
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1769
1766
|
if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
|
|
1770
1767
|
delete venusApi._mock.scheduledNotifications[notificationId];
|
|
@@ -1774,12 +1771,8 @@ var MockNotificationsApi = class {
|
|
|
1774
1771
|
}
|
|
1775
1772
|
async getAllScheduledLocalNotifications() {
|
|
1776
1773
|
if (isWebPlatform()) {
|
|
1777
|
-
console.log(
|
|
1778
|
-
"[Venus Mock] Get notifications on web platform (returning empty list)"
|
|
1779
|
-
);
|
|
1780
1774
|
return [];
|
|
1781
1775
|
}
|
|
1782
|
-
console.log("[Venus Mock] Get all scheduled local notifications");
|
|
1783
1776
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1784
1777
|
const venusApi = this.venusApi;
|
|
1785
1778
|
const notifications = venusApi._mock.scheduledNotifications || {};
|
|
@@ -1787,10 +1780,8 @@ var MockNotificationsApi = class {
|
|
|
1787
1780
|
}
|
|
1788
1781
|
async isLocalNotificationsEnabled() {
|
|
1789
1782
|
if (isWebPlatform()) {
|
|
1790
|
-
console.log("[Venus Mock] Notifications not available on web platform");
|
|
1791
1783
|
return false;
|
|
1792
1784
|
}
|
|
1793
|
-
console.log("[Venus Mock] Check if local notifications are enabled");
|
|
1794
1785
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1795
1786
|
const venusApi = this.venusApi;
|
|
1796
1787
|
const isEnabled = venusApi._mock.notificationsEnabled !== false;
|
|
@@ -1799,9 +1790,6 @@ var MockNotificationsApi = class {
|
|
|
1799
1790
|
async scheduleAsync(title, body, seconds, notificationId, options) {
|
|
1800
1791
|
const { priority = 50, groupId, payload } = options || {};
|
|
1801
1792
|
if (isWebPlatform()) {
|
|
1802
|
-
console.log(
|
|
1803
|
-
"[Venus Mock] Notifications not supported on web platform, simulating success"
|
|
1804
|
-
);
|
|
1805
1793
|
console.info(
|
|
1806
1794
|
"\u{1F514} [Venus Mock] Notification would be scheduled:",
|
|
1807
1795
|
title || "Untitled",
|
|
@@ -1812,14 +1800,11 @@ var MockNotificationsApi = class {
|
|
|
1812
1800
|
const mockId = `mock-web-notification-${Date.now()}`;
|
|
1813
1801
|
return mockId;
|
|
1814
1802
|
}
|
|
1815
|
-
console.log("[Venus Mock] Schedule local notification:", { title, body, seconds, options });
|
|
1816
1803
|
const venusApi = this.venusApi;
|
|
1817
1804
|
if (!venusApi._mock.pendingRequests) {
|
|
1818
|
-
console.log("[Venus Mock] Initializing pendingRequests");
|
|
1819
1805
|
venusApi._mock.pendingRequests = {};
|
|
1820
1806
|
}
|
|
1821
1807
|
const requestId = Date.now().toString();
|
|
1822
|
-
console.log("[Venus Mock] Creating request with ID:", requestId);
|
|
1823
1808
|
return new Promise((resolve) => {
|
|
1824
1809
|
venusApi._mock.pendingRequests[requestId] = { resolve };
|
|
1825
1810
|
const id = notificationId || `mock-notification-${Date.now()}`;
|
|
@@ -1841,13 +1826,8 @@ var MockNotificationsApi = class {
|
|
|
1841
1826
|
async setLocalNotificationsEnabled(enabled) {
|
|
1842
1827
|
const venusApi = this.venusApi;
|
|
1843
1828
|
if (isWebPlatform()) {
|
|
1844
|
-
console.log(
|
|
1845
|
-
"[Venus Mock] Set notifications enabled on web platform (simulated):",
|
|
1846
|
-
enabled
|
|
1847
|
-
);
|
|
1848
1829
|
return true;
|
|
1849
1830
|
}
|
|
1850
|
-
console.log("[Venus Mock] Set local notifications enabled:", enabled);
|
|
1851
1831
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1852
1832
|
venusApi._mock.notificationsEnabled = enabled;
|
|
1853
1833
|
return enabled;
|
|
@@ -2072,16 +2052,20 @@ function initializePopups(venusApi, host) {
|
|
|
2072
2052
|
|
|
2073
2053
|
// src/profile/HostProfileApi.ts
|
|
2074
2054
|
var HostProfileApi = class {
|
|
2055
|
+
constructor(venusApi) {
|
|
2056
|
+
__publicField(this, "venusApi");
|
|
2057
|
+
this.venusApi = venusApi;
|
|
2058
|
+
}
|
|
2075
2059
|
getCurrentProfile() {
|
|
2076
|
-
const profile =
|
|
2060
|
+
const profile = this.venusApi._profileData;
|
|
2077
2061
|
if (!profile) {
|
|
2078
2062
|
throw new Error(
|
|
2079
|
-
"[Venus SDK]
|
|
2063
|
+
"[Venus SDK] Profile not available. You must await VenusAPI.initializeAsync() before calling getProfile(). INIT_SDK has not completed."
|
|
2080
2064
|
);
|
|
2081
2065
|
}
|
|
2082
2066
|
if (!profile.id || !profile.username) {
|
|
2083
2067
|
throw new Error(
|
|
2084
|
-
"[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply
|
|
2068
|
+
"[Venus SDK] INIT_SDK returned an incomplete profile (missing id/username). The host must supply valid profile data."
|
|
2085
2069
|
);
|
|
2086
2070
|
}
|
|
2087
2071
|
return {
|
|
@@ -2095,6 +2079,10 @@ var HostProfileApi = class {
|
|
|
2095
2079
|
|
|
2096
2080
|
// src/profile/MockProfileApi.ts
|
|
2097
2081
|
var MockProfileApi = class {
|
|
2082
|
+
constructor(venusApi) {
|
|
2083
|
+
__publicField(this, "venusApi");
|
|
2084
|
+
this.venusApi = venusApi;
|
|
2085
|
+
}
|
|
2098
2086
|
getCurrentProfile() {
|
|
2099
2087
|
return {
|
|
2100
2088
|
id: "mock_profile_123",
|
|
@@ -2107,11 +2095,22 @@ var MockProfileApi = class {
|
|
|
2107
2095
|
|
|
2108
2096
|
// src/profile/index.ts
|
|
2109
2097
|
function initializeProfile(venusApi, host) {
|
|
2098
|
+
venusApi.getProfile = () => {
|
|
2099
|
+
return host.profile.getCurrentProfile();
|
|
2100
|
+
};
|
|
2110
2101
|
venusApi.getCurrentProfile = () => {
|
|
2102
|
+
console.warn(
|
|
2103
|
+
"[Venus SDK] DEPRECATED: VenusAPI.getCurrentProfile() is deprecated. Use VenusAPI.getProfile() instead. See migration guide: https://docs.venus.com/migration/profile-api"
|
|
2104
|
+
);
|
|
2111
2105
|
return host.profile.getCurrentProfile();
|
|
2112
2106
|
};
|
|
2113
2107
|
}
|
|
2114
2108
|
|
|
2109
|
+
// src/utils/idGenerator.ts
|
|
2110
|
+
function generateId() {
|
|
2111
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2115
2114
|
// src/rpc/RpcClient.ts
|
|
2116
2115
|
var RpcClient = class {
|
|
2117
2116
|
constructor() {
|
|
@@ -2154,7 +2153,7 @@ var RpcClient = class {
|
|
|
2154
2153
|
}
|
|
2155
2154
|
async call(method, args, timeout = 5e3) {
|
|
2156
2155
|
return new Promise((resolve, reject) => {
|
|
2157
|
-
const id =
|
|
2156
|
+
const id = generateId();
|
|
2158
2157
|
this.addPendingCall(id, resolve, reject);
|
|
2159
2158
|
const request = {
|
|
2160
2159
|
type: "rpc-request",
|
|
@@ -2191,9 +2190,6 @@ var RpcClient = class {
|
|
|
2191
2190
|
getPendingCall(id) {
|
|
2192
2191
|
return this.pendingCalls.get(id);
|
|
2193
2192
|
}
|
|
2194
|
-
generateId() {
|
|
2195
|
-
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2196
|
-
}
|
|
2197
2193
|
handleRpcResponse(response) {
|
|
2198
2194
|
const pending = this.getPendingCall(response.id);
|
|
2199
2195
|
if (!pending) {
|
|
@@ -2215,57 +2211,488 @@ var RpcClient = class {
|
|
|
2215
2211
|
}
|
|
2216
2212
|
};
|
|
2217
2213
|
|
|
2218
|
-
// src/
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2214
|
+
// src/rooms/VenusRoom.ts
|
|
2215
|
+
var VenusRoom = class {
|
|
2216
|
+
constructor(roomData) {
|
|
2217
|
+
__publicField(this, "id");
|
|
2218
|
+
__publicField(this, "name");
|
|
2219
|
+
__publicField(this, "players");
|
|
2220
|
+
__publicField(this, "maxPlayers");
|
|
2221
|
+
__publicField(this, "gameType");
|
|
2222
|
+
__publicField(this, "appId");
|
|
2223
|
+
__publicField(this, "type");
|
|
2224
|
+
__publicField(this, "createdBy");
|
|
2225
|
+
__publicField(this, "createdAt");
|
|
2226
|
+
__publicField(this, "updatedAt");
|
|
2227
|
+
__publicField(this, "isPrivate");
|
|
2228
|
+
__publicField(this, "status");
|
|
2229
|
+
__publicField(this, "customMetadata");
|
|
2230
|
+
__publicField(this, "admins");
|
|
2231
|
+
__publicField(this, "roomCode");
|
|
2232
|
+
__publicField(this, "description");
|
|
2233
|
+
__publicField(this, "data");
|
|
2234
|
+
__publicField(this, "version");
|
|
2235
|
+
this.id = roomData.id;
|
|
2236
|
+
this.name = roomData.name;
|
|
2237
|
+
this.players = Array.isArray(roomData.currentPlayers) ? [...roomData.currentPlayers] : [];
|
|
2238
|
+
this.maxPlayers = roomData.maxPlayers;
|
|
2239
|
+
this.gameType = roomData.gameType;
|
|
2240
|
+
this.appId = roomData.appId;
|
|
2241
|
+
this.type = roomData.type;
|
|
2242
|
+
this.createdBy = roomData.createdBy;
|
|
2243
|
+
this.createdAt = roomData.createdAt;
|
|
2244
|
+
this.updatedAt = roomData.updatedAt;
|
|
2245
|
+
this.isPrivate = roomData.isPrivate;
|
|
2246
|
+
this.status = roomData.status;
|
|
2247
|
+
this.customMetadata = roomData.customMetadata || {};
|
|
2248
|
+
this.admins = Array.isArray(roomData.admins) ? [...roomData.admins] : [];
|
|
2249
|
+
this.roomCode = roomData.roomCode;
|
|
2250
|
+
this.description = roomData.description;
|
|
2251
|
+
this.data = roomData.data || {};
|
|
2252
|
+
this.version = roomData.version;
|
|
2238
2253
|
}
|
|
2239
|
-
|
|
2240
|
-
|
|
2254
|
+
};
|
|
2255
|
+
|
|
2256
|
+
// src/rooms/setupRoomNotifications.ts
|
|
2257
|
+
function invokeCallbacks(callbacks, event, context) {
|
|
2258
|
+
callbacks.forEach((callback) => {
|
|
2259
|
+
try {
|
|
2260
|
+
callback(event);
|
|
2261
|
+
} catch (error) {
|
|
2262
|
+
console.error(`[Venus SDK] Error in ${context} callback:`, error);
|
|
2263
|
+
throw error;
|
|
2264
|
+
}
|
|
2265
|
+
});
|
|
2241
2266
|
}
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
this.syncDelay = syncDelay;
|
|
2248
|
-
}
|
|
2249
|
-
async clear() {
|
|
2250
|
-
const fullLength = localStorage.length;
|
|
2251
|
-
for (let i = 0; i < fullLength; i++) {
|
|
2252
|
-
const fullKey = localStorage.key(i);
|
|
2253
|
-
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
2254
|
-
localStorage.removeItem(fullKey);
|
|
2255
|
-
}
|
|
2267
|
+
function setupRoomNotifications(transport, getSubscriptions) {
|
|
2268
|
+
return transport.onVenusMessage((message) => {
|
|
2269
|
+
const subscriptions = getSubscriptions();
|
|
2270
|
+
if (!subscriptions) {
|
|
2271
|
+
return;
|
|
2256
2272
|
}
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2273
|
+
if (message.type === "H5_ROOM_DATA_UPDATED") {
|
|
2274
|
+
const messageData = message.data;
|
|
2275
|
+
const { roomId, roomData } = messageData;
|
|
2276
|
+
if (!roomId) return;
|
|
2277
|
+
const callbacks = subscriptions.data[roomId] || [];
|
|
2278
|
+
const event = {
|
|
2279
|
+
type: "H5_ROOM_DATA_UPDATED",
|
|
2280
|
+
roomId,
|
|
2281
|
+
roomData,
|
|
2282
|
+
timestamp: messageData.timestamp
|
|
2283
|
+
};
|
|
2284
|
+
invokeCallbacks(callbacks, event, "room data");
|
|
2285
|
+
}
|
|
2286
|
+
if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
|
|
2287
|
+
const messageData = message.data;
|
|
2288
|
+
const { roomId } = messageData;
|
|
2289
|
+
if (!roomId) return;
|
|
2290
|
+
const callbacks = subscriptions.messages[roomId] || [];
|
|
2291
|
+
const event = {
|
|
2292
|
+
type: message.type,
|
|
2293
|
+
roomId,
|
|
2294
|
+
message: messageData.message,
|
|
2295
|
+
timestamp: messageData.timestamp
|
|
2296
|
+
};
|
|
2297
|
+
invokeCallbacks(callbacks, event, "room message");
|
|
2298
|
+
}
|
|
2299
|
+
if (message.type === "app:h5:proposedMoveValidationUpdated") {
|
|
2300
|
+
const messageData = message.data;
|
|
2301
|
+
const { roomId } = messageData;
|
|
2302
|
+
if (!roomId) return;
|
|
2303
|
+
const callbacks = subscriptions.gameEvents[roomId] || [];
|
|
2304
|
+
const event = {
|
|
2305
|
+
type: "app:h5:proposedMoveValidationUpdated",
|
|
2306
|
+
roomId,
|
|
2307
|
+
proposedMoveData: messageData.proposedMoveData,
|
|
2308
|
+
proposedMoveId: messageData.proposedMoveId,
|
|
2309
|
+
changeType: messageData.changeType,
|
|
2310
|
+
timestamp: messageData.timestamp
|
|
2311
|
+
};
|
|
2312
|
+
invokeCallbacks(callbacks, event, "game event");
|
|
2313
|
+
}
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
// src/rooms/RpcRoomsApi.ts
|
|
2318
|
+
var RpcRoomsApi = class {
|
|
2319
|
+
constructor(rpcClient) {
|
|
2320
|
+
__publicField(this, "rpcClient");
|
|
2321
|
+
__publicField(this, "subscriptions");
|
|
2322
|
+
this.rpcClient = rpcClient;
|
|
2323
|
+
this.subscriptions = {
|
|
2324
|
+
data: {},
|
|
2325
|
+
messages: {},
|
|
2326
|
+
gameEvents: {}
|
|
2327
|
+
};
|
|
2328
|
+
}
|
|
2329
|
+
/**
|
|
2330
|
+
* Get the subscription state for external access (used by setupRoomNotifications)
|
|
2331
|
+
*/
|
|
2332
|
+
getSubscriptions() {
|
|
2333
|
+
return this.subscriptions;
|
|
2334
|
+
}
|
|
2335
|
+
/**
|
|
2336
|
+
* Set up room notification routing from the transport
|
|
2337
|
+
*/
|
|
2338
|
+
setupNotifications(transport) {
|
|
2339
|
+
setupRoomNotifications(transport, () => this.getSubscriptions());
|
|
2340
|
+
}
|
|
2341
|
+
async createRoomAsync(options) {
|
|
2342
|
+
const response = await this.rpcClient.call(
|
|
2343
|
+
"H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
|
|
2344
|
+
{
|
|
2345
|
+
options
|
|
2346
|
+
}
|
|
2347
|
+
);
|
|
2348
|
+
if (response.success === false) {
|
|
2349
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to create room";
|
|
2350
|
+
throw new Error(errorMessage);
|
|
2351
|
+
}
|
|
2352
|
+
const room = new VenusRoom(response.roomData);
|
|
2353
|
+
return room;
|
|
2354
|
+
}
|
|
2355
|
+
async joinOrCreateRoomAsync(options) {
|
|
2356
|
+
const response = await this.rpcClient.call(
|
|
2357
|
+
"H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
|
|
2358
|
+
{
|
|
2359
|
+
options
|
|
2360
|
+
}
|
|
2361
|
+
);
|
|
2362
|
+
if (response.success === false) {
|
|
2363
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to join or create room";
|
|
2364
|
+
throw new Error(errorMessage);
|
|
2365
|
+
}
|
|
2366
|
+
const room = new VenusRoom(response.value.roomData);
|
|
2367
|
+
return {
|
|
2368
|
+
action: response.value.action,
|
|
2369
|
+
room,
|
|
2370
|
+
playersJoined: response.value.playersJoined
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2373
|
+
async joinRoomByCodeAsync(roomCode) {
|
|
2374
|
+
const response = await this.rpcClient.call(
|
|
2375
|
+
"H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
|
|
2376
|
+
{
|
|
2377
|
+
roomCode
|
|
2378
|
+
}
|
|
2379
|
+
);
|
|
2380
|
+
if (response?.success === false) {
|
|
2381
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to join room by code";
|
|
2382
|
+
throw new Error(errorMessage);
|
|
2383
|
+
}
|
|
2384
|
+
const room = new VenusRoom(response.roomData);
|
|
2385
|
+
return room;
|
|
2386
|
+
}
|
|
2387
|
+
// Get user's rooms with optional filtering
|
|
2388
|
+
async getUserRoomsAsync(options = {}) {
|
|
2389
|
+
const response = await this.rpcClient.call(
|
|
2390
|
+
"H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
|
|
2391
|
+
{
|
|
2392
|
+
includeArchived: options.includeArchived ?? false
|
|
2393
|
+
}
|
|
2394
|
+
);
|
|
2395
|
+
if (response?.success === false) {
|
|
2396
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to get user rooms";
|
|
2397
|
+
throw new Error(errorMessage);
|
|
2398
|
+
}
|
|
2399
|
+
const venusRooms = [];
|
|
2400
|
+
for (const roomData of response.rooms) {
|
|
2401
|
+
if (!roomData.id) {
|
|
2402
|
+
console.warn("[Venus SDK] getUserRooms: Skipping room with missing ID:", roomData);
|
|
2403
|
+
continue;
|
|
2404
|
+
}
|
|
2405
|
+
try {
|
|
2406
|
+
const venusRoom = new VenusRoom(roomData);
|
|
2407
|
+
venusRooms.push(venusRoom);
|
|
2408
|
+
} catch (error) {
|
|
2409
|
+
console.warn(
|
|
2410
|
+
"[Venus SDK] getUserRooms: Failed to create VenusRoom object:",
|
|
2411
|
+
error,
|
|
2412
|
+
roomData
|
|
2413
|
+
);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
return venusRooms;
|
|
2417
|
+
}
|
|
2418
|
+
async updateRoomDataAsync(room, updates, options = {}) {
|
|
2419
|
+
const response = await this.rpcClient.call(
|
|
2420
|
+
"H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
|
|
2421
|
+
{
|
|
2422
|
+
roomId: room.id,
|
|
2423
|
+
updates,
|
|
2424
|
+
merge: options.merge ?? true
|
|
2425
|
+
}
|
|
2426
|
+
);
|
|
2427
|
+
if (response?.success === false) {
|
|
2428
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to update room data";
|
|
2429
|
+
throw new Error(errorMessage);
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
async getRoomDataAsync(room) {
|
|
2433
|
+
const response = await this.rpcClient.call(
|
|
2434
|
+
"H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
|
|
2435
|
+
{
|
|
2436
|
+
roomId: room.id
|
|
2437
|
+
}
|
|
2438
|
+
);
|
|
2439
|
+
if (response?.success === false) {
|
|
2440
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to get room data";
|
|
2441
|
+
throw new Error(errorMessage);
|
|
2442
|
+
}
|
|
2443
|
+
return response.data;
|
|
2444
|
+
}
|
|
2445
|
+
async sendRoomMessageAsync(venusRoom, request) {
|
|
2446
|
+
const response = await this.rpcClient.call(
|
|
2447
|
+
"H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
|
|
2448
|
+
{
|
|
2449
|
+
roomId: venusRoom.id,
|
|
2450
|
+
message: request.message,
|
|
2451
|
+
metadata: request.metadata
|
|
2452
|
+
}
|
|
2453
|
+
);
|
|
2454
|
+
if (response?.success === false) {
|
|
2455
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to send message";
|
|
2456
|
+
throw new Error(errorMessage);
|
|
2457
|
+
}
|
|
2458
|
+
return response.messageId;
|
|
2459
|
+
}
|
|
2460
|
+
async leaveRoomAsync(room) {
|
|
2461
|
+
const response = await this.rpcClient.call(
|
|
2462
|
+
"H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
|
|
2463
|
+
{
|
|
2464
|
+
roomId: room.id
|
|
2465
|
+
}
|
|
2466
|
+
);
|
|
2467
|
+
if (response?.success === false) {
|
|
2468
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to leave room";
|
|
2469
|
+
throw new Error(errorMessage);
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
async startRoomGameAsync(room, options = {}) {
|
|
2473
|
+
const response = await this.rpcClient.call(
|
|
2474
|
+
"H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
|
|
2475
|
+
{
|
|
2476
|
+
roomId: room.id,
|
|
2477
|
+
gameConfig: options.gameConfig ?? {},
|
|
2478
|
+
turnOrder: options.turnOrder ?? null
|
|
2479
|
+
}
|
|
2480
|
+
);
|
|
2481
|
+
if (response?.success === false) {
|
|
2482
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to start game";
|
|
2483
|
+
throw new Error(errorMessage);
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
async proposeMoveAsync(room, proposalPayload) {
|
|
2487
|
+
const response = await this.rpcClient.call(
|
|
2488
|
+
"h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
|
|
2489
|
+
{
|
|
2490
|
+
roomId: room.id,
|
|
2491
|
+
gameSpecificState: proposalPayload.gameSpecificState,
|
|
2492
|
+
moveType: proposalPayload.moveType,
|
|
2493
|
+
clientContext: proposalPayload.clientContext,
|
|
2494
|
+
clientProposalId: proposalPayload.clientProposalId
|
|
2495
|
+
}
|
|
2496
|
+
);
|
|
2497
|
+
if (response?.success === false) {
|
|
2498
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to propose move";
|
|
2499
|
+
throw new Error(errorMessage);
|
|
2500
|
+
}
|
|
2501
|
+
return response.data;
|
|
2502
|
+
}
|
|
2503
|
+
async validateMoveAsync(_room, moveId, verdict) {
|
|
2504
|
+
return {
|
|
2505
|
+
success: true,
|
|
2506
|
+
moveId,
|
|
2507
|
+
isValid: verdict.isValid,
|
|
2508
|
+
reason: verdict.reason
|
|
2509
|
+
};
|
|
2510
|
+
}
|
|
2511
|
+
async subscribeAsync(room, options = {}) {
|
|
2512
|
+
const roomId = room.id;
|
|
2513
|
+
const existingData = this.subscriptions.data[roomId];
|
|
2514
|
+
const existingMessages = this.subscriptions.messages[roomId];
|
|
2515
|
+
const existingGameEvents = this.subscriptions.gameEvents[roomId];
|
|
2516
|
+
const subscribeToData = Boolean(options.onData) && (existingData?.length ?? 0) === 0;
|
|
2517
|
+
const subscribeToMessages = Boolean(options.onMessages) && (existingMessages?.length ?? 0) === 0;
|
|
2518
|
+
const subscribeToProposedMoves = Boolean(options.onGameEvents) && (existingGameEvents?.length ?? 0) === 0;
|
|
2519
|
+
if (subscribeToData || subscribeToMessages || subscribeToProposedMoves) {
|
|
2520
|
+
try {
|
|
2521
|
+
await this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
|
|
2522
|
+
roomId,
|
|
2523
|
+
subscribeToData,
|
|
2524
|
+
subscribeToMessages,
|
|
2525
|
+
subscribeToProposedMoves
|
|
2526
|
+
});
|
|
2527
|
+
} catch (error) {
|
|
2528
|
+
console.error("[Venus SDK] Failed to set up room subscription:", error);
|
|
2529
|
+
throw error;
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
if (options.onData) {
|
|
2533
|
+
if (!this.subscriptions.data[roomId]) {
|
|
2534
|
+
this.subscriptions.data[roomId] = [];
|
|
2535
|
+
}
|
|
2536
|
+
this.subscriptions.data[roomId].push(options.onData);
|
|
2537
|
+
}
|
|
2538
|
+
if (options.onMessages) {
|
|
2539
|
+
if (!this.subscriptions.messages[roomId]) {
|
|
2540
|
+
this.subscriptions.messages[roomId] = [];
|
|
2541
|
+
}
|
|
2542
|
+
this.subscriptions.messages[roomId].push(options.onMessages);
|
|
2543
|
+
}
|
|
2544
|
+
if (options.onGameEvents) {
|
|
2545
|
+
if (!this.subscriptions.gameEvents[roomId]) {
|
|
2546
|
+
this.subscriptions.gameEvents[roomId] = [];
|
|
2547
|
+
}
|
|
2548
|
+
this.subscriptions.gameEvents[roomId].push(options.onGameEvents);
|
|
2549
|
+
}
|
|
2550
|
+
let disposed = false;
|
|
2551
|
+
return () => {
|
|
2552
|
+
if (disposed) return;
|
|
2553
|
+
disposed = true;
|
|
2554
|
+
if (options.onData) {
|
|
2555
|
+
const callbacks = this.subscriptions.data[roomId];
|
|
2556
|
+
if (callbacks) {
|
|
2557
|
+
const index = callbacks.indexOf(options.onData);
|
|
2558
|
+
if (index > -1) {
|
|
2559
|
+
callbacks.splice(index, 1);
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
if (options.onMessages) {
|
|
2564
|
+
const callbacks = this.subscriptions.messages[roomId];
|
|
2565
|
+
if (callbacks) {
|
|
2566
|
+
const index = callbacks.indexOf(options.onMessages);
|
|
2567
|
+
if (index > -1) {
|
|
2568
|
+
callbacks.splice(index, 1);
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
if (options.onGameEvents) {
|
|
2573
|
+
const callbacks = this.subscriptions.gameEvents[roomId];
|
|
2574
|
+
if (callbacks) {
|
|
2575
|
+
const index = callbacks.indexOf(options.onGameEvents);
|
|
2576
|
+
if (index > -1) {
|
|
2577
|
+
callbacks.splice(index, 1);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
const hasAnySubscriptions = (this.subscriptions.data[roomId]?.length ?? 0) > 0 || (this.subscriptions.messages[roomId]?.length ?? 0) > 0 || (this.subscriptions.gameEvents[roomId]?.length ?? 0) > 0;
|
|
2582
|
+
if (!hasAnySubscriptions) {
|
|
2583
|
+
this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
|
|
2584
|
+
roomId
|
|
2585
|
+
}).catch((error) => {
|
|
2586
|
+
console.error("[Venus SDK] Failed to clean up room subscription:", error);
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
};
|
|
2590
|
+
}
|
|
2591
|
+
};
|
|
2592
|
+
|
|
2593
|
+
// src/rooms/index.ts
|
|
2594
|
+
function bindMethod(target, targetKey, source, sourceKey) {
|
|
2595
|
+
const key = sourceKey ?? targetKey;
|
|
2596
|
+
const fn = source?.[key];
|
|
2597
|
+
if (typeof fn === "function") {
|
|
2598
|
+
target[targetKey] = fn.bind(source);
|
|
2599
|
+
return true;
|
|
2600
|
+
}
|
|
2601
|
+
return false;
|
|
2602
|
+
}
|
|
2603
|
+
function initializeRoomsApi(venusApi, host) {
|
|
2604
|
+
const roomsApi = host?.rooms;
|
|
2605
|
+
if (!roomsApi) {
|
|
2606
|
+
console.warn(
|
|
2607
|
+
"[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
|
|
2608
|
+
);
|
|
2609
|
+
return;
|
|
2610
|
+
}
|
|
2611
|
+
const venus = venusApi;
|
|
2612
|
+
const existingNamespace = venus.rooms || {};
|
|
2613
|
+
const roomsNamespace = Object.assign({}, existingNamespace);
|
|
2614
|
+
const namespaceBindings = [
|
|
2615
|
+
["createRoomAsync"],
|
|
2616
|
+
["joinOrCreateRoomAsync"],
|
|
2617
|
+
["joinRoomByCodeAsync"],
|
|
2618
|
+
["getUserRoomsAsync"],
|
|
2619
|
+
["subscribeAsync"],
|
|
2620
|
+
["updateRoomDataAsync"],
|
|
2621
|
+
["getRoomDataAsync"],
|
|
2622
|
+
["sendRoomMessageAsync"],
|
|
2623
|
+
["leaveRoomAsync"],
|
|
2624
|
+
["startRoomGameAsync"],
|
|
2625
|
+
["proposeMoveAsync"],
|
|
2626
|
+
["validateMoveAsync"]
|
|
2627
|
+
];
|
|
2628
|
+
namespaceBindings.forEach(([targetKey, sourceKey]) => {
|
|
2629
|
+
bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
|
|
2630
|
+
});
|
|
2631
|
+
venus.rooms = roomsNamespace;
|
|
2632
|
+
}
|
|
2633
|
+
|
|
2634
|
+
// src/storage/MockStorageApi.ts
|
|
2635
|
+
var STORAGE_PREFIXES = {
|
|
2636
|
+
globalStorage: "venus:global",
|
|
2637
|
+
deviceCache: "venus:deviceCache",
|
|
2638
|
+
appStorage: "venus:appStorage"
|
|
2639
|
+
};
|
|
2640
|
+
function createMockStorageApi(storageType, appUrl) {
|
|
2641
|
+
const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
|
|
2642
|
+
let prefix = STORAGE_PREFIXES[storageType];
|
|
2643
|
+
let syncDelay = 0;
|
|
2644
|
+
switch (storageType) {
|
|
2645
|
+
case "deviceCache":
|
|
2646
|
+
syncDelay = 0;
|
|
2647
|
+
break;
|
|
2648
|
+
case "appStorage":
|
|
2649
|
+
syncDelay = 100;
|
|
2650
|
+
break;
|
|
2651
|
+
case "globalStorage":
|
|
2652
|
+
syncDelay = 100;
|
|
2653
|
+
break;
|
|
2654
|
+
default:
|
|
2655
|
+
throw new Error(`Unknown storage type: ${storageType}`);
|
|
2656
|
+
}
|
|
2657
|
+
prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
|
|
2658
|
+
return new MockStorageApi(prefix, syncDelay);
|
|
2659
|
+
}
|
|
2660
|
+
var MockStorageApi = class {
|
|
2661
|
+
constructor(prefix, syncDelay) {
|
|
2662
|
+
__publicField(this, "prefix");
|
|
2663
|
+
__publicField(this, "syncDelay");
|
|
2664
|
+
__publicField(this, "orderStorageKey");
|
|
2665
|
+
this.prefix = prefix;
|
|
2666
|
+
this.syncDelay = syncDelay;
|
|
2667
|
+
this.orderStorageKey = `${prefix}__order__`;
|
|
2668
|
+
}
|
|
2669
|
+
async clear() {
|
|
2670
|
+
const keysToRemove = [];
|
|
2261
2671
|
const fullLength = localStorage.length;
|
|
2262
2672
|
for (let i = 0; i < fullLength; i++) {
|
|
2263
2673
|
const fullKey = localStorage.key(i);
|
|
2264
|
-
if (fullKey
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2674
|
+
if (!fullKey || fullKey === this.orderStorageKey) {
|
|
2675
|
+
continue;
|
|
2676
|
+
}
|
|
2677
|
+
if (fullKey.startsWith(this.prefix)) {
|
|
2678
|
+
keysToRemove.push(fullKey);
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
for (const key of keysToRemove) {
|
|
2682
|
+
localStorage.removeItem(key);
|
|
2683
|
+
}
|
|
2684
|
+
this.clearOrder();
|
|
2685
|
+
await this.simulateSyncDelay();
|
|
2686
|
+
}
|
|
2687
|
+
async getAllItems() {
|
|
2688
|
+
const items = new Array();
|
|
2689
|
+
const orderedKeys = this.keys();
|
|
2690
|
+
for (const key of orderedKeys) {
|
|
2691
|
+
const value = localStorage.getItem(this.buildKey(key));
|
|
2692
|
+
if (value !== null) {
|
|
2693
|
+
items.push(value);
|
|
2694
|
+
} else {
|
|
2695
|
+
this.removeFromOrder(key);
|
|
2269
2696
|
}
|
|
2270
2697
|
}
|
|
2271
2698
|
return items;
|
|
@@ -2290,11 +2717,13 @@ var MockStorageApi = class {
|
|
|
2290
2717
|
const fullKey = this.buildKey(key);
|
|
2291
2718
|
await this.simulateSyncDelay();
|
|
2292
2719
|
localStorage.removeItem(fullKey);
|
|
2720
|
+
this.removeFromOrder(key);
|
|
2293
2721
|
}
|
|
2294
2722
|
async setItem(key, item) {
|
|
2295
2723
|
const fullKey = this.buildKey(key);
|
|
2296
2724
|
await this.simulateSyncDelay();
|
|
2297
2725
|
localStorage.setItem(fullKey, item);
|
|
2726
|
+
this.upsertOrder(key);
|
|
2298
2727
|
}
|
|
2299
2728
|
async setMultipleItems(entries) {
|
|
2300
2729
|
for (const entry of entries) {
|
|
@@ -2302,6 +2731,7 @@ var MockStorageApi = class {
|
|
|
2302
2731
|
localStorage.setItem(fullKey, entry.value);
|
|
2303
2732
|
}
|
|
2304
2733
|
await this.simulateSyncDelay();
|
|
2734
|
+
this.bulkUpsertOrder(entries.map((entry) => entry.key));
|
|
2305
2735
|
}
|
|
2306
2736
|
async removeMultipleItems(keys) {
|
|
2307
2737
|
for (const key of keys) {
|
|
@@ -2309,6 +2739,7 @@ var MockStorageApi = class {
|
|
|
2309
2739
|
localStorage.removeItem(fullKey);
|
|
2310
2740
|
}
|
|
2311
2741
|
await this.simulateSyncDelay();
|
|
2742
|
+
this.bulkRemoveFromOrder(keys);
|
|
2312
2743
|
}
|
|
2313
2744
|
buildKey(key) {
|
|
2314
2745
|
const prefix = this.prefix;
|
|
@@ -2319,17 +2750,8 @@ var MockStorageApi = class {
|
|
|
2319
2750
|
return fullKey.substring(prefix.length);
|
|
2320
2751
|
}
|
|
2321
2752
|
keys() {
|
|
2322
|
-
const
|
|
2323
|
-
|
|
2324
|
-
for (let i = 0; i < length; i++) {
|
|
2325
|
-
const fullKey = localStorage.key(i);
|
|
2326
|
-
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
2327
|
-
length++;
|
|
2328
|
-
const key = this.extractKey(fullKey);
|
|
2329
|
-
keys.push(key);
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
return keys;
|
|
2753
|
+
const order = this.readOrder();
|
|
2754
|
+
return [...order];
|
|
2333
2755
|
}
|
|
2334
2756
|
async simulateSyncDelay() {
|
|
2335
2757
|
const syncDelay = this.syncDelay;
|
|
@@ -2337,6 +2759,127 @@ var MockStorageApi = class {
|
|
|
2337
2759
|
await new Promise((resolve) => setTimeout(resolve, syncDelay));
|
|
2338
2760
|
}
|
|
2339
2761
|
}
|
|
2762
|
+
readOrder() {
|
|
2763
|
+
const raw = localStorage.getItem(this.orderStorageKey);
|
|
2764
|
+
if (!raw) {
|
|
2765
|
+
return this.rebuildOrderFromStorage();
|
|
2766
|
+
}
|
|
2767
|
+
try {
|
|
2768
|
+
const parsed = JSON.parse(raw);
|
|
2769
|
+
if (Array.isArray(parsed)) {
|
|
2770
|
+
return this.normalizeOrder(parsed);
|
|
2771
|
+
}
|
|
2772
|
+
} catch {
|
|
2773
|
+
}
|
|
2774
|
+
return this.rebuildOrderFromStorage();
|
|
2775
|
+
}
|
|
2776
|
+
normalizeOrder(order) {
|
|
2777
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2778
|
+
const normalized = [];
|
|
2779
|
+
let changed = false;
|
|
2780
|
+
for (const entry of order) {
|
|
2781
|
+
if (typeof entry !== "string") {
|
|
2782
|
+
changed = true;
|
|
2783
|
+
continue;
|
|
2784
|
+
}
|
|
2785
|
+
if (seen.has(entry)) {
|
|
2786
|
+
changed = true;
|
|
2787
|
+
continue;
|
|
2788
|
+
}
|
|
2789
|
+
const fullKey = this.buildKey(entry);
|
|
2790
|
+
if (localStorage.getItem(fullKey) === null) {
|
|
2791
|
+
changed = true;
|
|
2792
|
+
continue;
|
|
2793
|
+
}
|
|
2794
|
+
seen.add(entry);
|
|
2795
|
+
normalized.push(entry);
|
|
2796
|
+
}
|
|
2797
|
+
if (changed) {
|
|
2798
|
+
this.writeOrder(normalized);
|
|
2799
|
+
}
|
|
2800
|
+
return normalized;
|
|
2801
|
+
}
|
|
2802
|
+
rebuildOrderFromStorage() {
|
|
2803
|
+
const keys = [];
|
|
2804
|
+
const total = localStorage.length;
|
|
2805
|
+
for (let i = 0; i < total; i++) {
|
|
2806
|
+
const fullKey = localStorage.key(i);
|
|
2807
|
+
if (!fullKey) continue;
|
|
2808
|
+
if (fullKey === this.orderStorageKey) continue;
|
|
2809
|
+
if (fullKey.startsWith(this.prefix)) {
|
|
2810
|
+
keys.push(this.extractKey(fullKey));
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2813
|
+
this.writeOrder(keys);
|
|
2814
|
+
return keys;
|
|
2815
|
+
}
|
|
2816
|
+
upsertOrder(key) {
|
|
2817
|
+
const order = this.readOrder();
|
|
2818
|
+
const index = order.indexOf(key);
|
|
2819
|
+
if (index !== -1) {
|
|
2820
|
+
order.splice(index, 1);
|
|
2821
|
+
}
|
|
2822
|
+
order.push(key);
|
|
2823
|
+
this.writeOrder(order);
|
|
2824
|
+
}
|
|
2825
|
+
bulkUpsertOrder(keys) {
|
|
2826
|
+
const dedupedKeys = this.dedupeKeys(keys);
|
|
2827
|
+
if (dedupedKeys.length === 0) {
|
|
2828
|
+
return;
|
|
2829
|
+
}
|
|
2830
|
+
const order = this.readOrder();
|
|
2831
|
+
const keysSet = new Set(dedupedKeys);
|
|
2832
|
+
const filtered = order.filter((entry) => !keysSet.has(entry));
|
|
2833
|
+
for (const key of dedupedKeys) {
|
|
2834
|
+
filtered.push(key);
|
|
2835
|
+
}
|
|
2836
|
+
this.writeOrder(filtered);
|
|
2837
|
+
}
|
|
2838
|
+
removeFromOrder(key) {
|
|
2839
|
+
const order = this.readOrder();
|
|
2840
|
+
const index = order.indexOf(key);
|
|
2841
|
+
if (index !== -1) {
|
|
2842
|
+
order.splice(index, 1);
|
|
2843
|
+
this.writeOrder(order);
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
bulkRemoveFromOrder(keys) {
|
|
2847
|
+
const dedupedKeys = this.dedupeKeys(keys);
|
|
2848
|
+
if (dedupedKeys.length === 0) {
|
|
2849
|
+
return;
|
|
2850
|
+
}
|
|
2851
|
+
const order = this.readOrder();
|
|
2852
|
+
const keysSet = new Set(dedupedKeys);
|
|
2853
|
+
const filtered = order.filter((entry) => !keysSet.has(entry));
|
|
2854
|
+
if (filtered.length !== order.length) {
|
|
2855
|
+
this.writeOrder(filtered);
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
writeOrder(order) {
|
|
2859
|
+
if (order.length === 0) {
|
|
2860
|
+
localStorage.removeItem(this.orderStorageKey);
|
|
2861
|
+
return;
|
|
2862
|
+
}
|
|
2863
|
+
localStorage.setItem(this.orderStorageKey, JSON.stringify(order));
|
|
2864
|
+
}
|
|
2865
|
+
clearOrder() {
|
|
2866
|
+
localStorage.removeItem(this.orderStorageKey);
|
|
2867
|
+
}
|
|
2868
|
+
dedupeKeys(keys) {
|
|
2869
|
+
const result = [];
|
|
2870
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2871
|
+
for (const key of keys) {
|
|
2872
|
+
if (typeof key !== "string") {
|
|
2873
|
+
continue;
|
|
2874
|
+
}
|
|
2875
|
+
if (seen.has(key)) {
|
|
2876
|
+
continue;
|
|
2877
|
+
}
|
|
2878
|
+
seen.add(key);
|
|
2879
|
+
result.push(key);
|
|
2880
|
+
}
|
|
2881
|
+
return result;
|
|
2882
|
+
}
|
|
2340
2883
|
};
|
|
2341
2884
|
function generateAppIdentifier(appUrl) {
|
|
2342
2885
|
if (!appUrl) appUrl = "";
|
|
@@ -2448,24 +2991,20 @@ function initializeStorage(venusApiInstance, host) {
|
|
|
2448
2991
|
venusApiInstance.globalStorage = host.globalStorage;
|
|
2449
2992
|
}
|
|
2450
2993
|
|
|
2451
|
-
// src/simulation/utils.ts
|
|
2452
|
-
function sumContributions(contributions) {
|
|
2453
|
-
const totals = {};
|
|
2454
|
-
for (const profileId in contributions) {
|
|
2455
|
-
for (const entityId in contributions[profileId]) {
|
|
2456
|
-
const amount = contributions[profileId][entityId] || 0;
|
|
2457
|
-
totals[entityId] = (totals[entityId] || 0) + amount;
|
|
2458
|
-
}
|
|
2459
|
-
}
|
|
2460
|
-
return totals;
|
|
2461
|
-
}
|
|
2462
|
-
|
|
2463
2994
|
// src/simulation/RpcSimulationApi.ts
|
|
2464
2995
|
var RpcSimulationApi = class {
|
|
2465
2996
|
constructor(rpcClient) {
|
|
2466
2997
|
__publicField(this, "rpcClient");
|
|
2467
2998
|
__publicField(this, "_simulationConfig", null);
|
|
2999
|
+
__publicField(this, "subscriptionCallbacks", /* @__PURE__ */ new Map());
|
|
2468
3000
|
this.rpcClient = rpcClient;
|
|
3001
|
+
this.rpcClient.onNotification(
|
|
3002
|
+
"H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */,
|
|
3003
|
+
this.handleSimulationUpdate.bind(this)
|
|
3004
|
+
);
|
|
3005
|
+
}
|
|
3006
|
+
isEnabled() {
|
|
3007
|
+
return true;
|
|
2469
3008
|
}
|
|
2470
3009
|
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2471
3010
|
return this.rpcClient.call(
|
|
@@ -2477,14 +3016,47 @@ var RpcSimulationApi = class {
|
|
|
2477
3016
|
}
|
|
2478
3017
|
);
|
|
2479
3018
|
}
|
|
2480
|
-
|
|
2481
|
-
|
|
3019
|
+
async subscribeAsync(options) {
|
|
3020
|
+
this.ensureValidSubscribeOptions(options);
|
|
3021
|
+
const subscriptionId = generateId();
|
|
3022
|
+
this.subscriptionCallbacks.set(subscriptionId, options.onUpdate);
|
|
3023
|
+
try {
|
|
3024
|
+
await this.rpcClient.call("H5_SIMULATION_SUBSCRIBE" /* H5_SIMULATION_SUBSCRIBE */, {
|
|
3025
|
+
subscriptionId,
|
|
3026
|
+
entities: options.entities,
|
|
3027
|
+
tags: options.tags,
|
|
3028
|
+
activeRuns: options.activeRuns,
|
|
3029
|
+
roomId: options.roomId
|
|
3030
|
+
});
|
|
3031
|
+
} catch (error) {
|
|
3032
|
+
this.subscriptionCallbacks.delete(subscriptionId);
|
|
3033
|
+
throw error;
|
|
3034
|
+
}
|
|
3035
|
+
let unsubscribed = false;
|
|
3036
|
+
return () => {
|
|
3037
|
+
if (unsubscribed) {
|
|
3038
|
+
return;
|
|
3039
|
+
}
|
|
3040
|
+
unsubscribed = true;
|
|
3041
|
+
this.subscriptionCallbacks.delete(subscriptionId);
|
|
3042
|
+
void this.rpcClient.call("H5_SIMULATION_UNSUBSCRIBE" /* H5_SIMULATION_UNSUBSCRIBE */, {
|
|
3043
|
+
subscriptionId
|
|
3044
|
+
}).catch((error) => {
|
|
3045
|
+
console.error(
|
|
3046
|
+
"[Venus SDK] Failed to unsubscribe simulation listener",
|
|
3047
|
+
error
|
|
3048
|
+
);
|
|
3049
|
+
});
|
|
3050
|
+
};
|
|
2482
3051
|
}
|
|
2483
3052
|
executeBatchOperationsAsync(operations, validateOnly) {
|
|
2484
|
-
return this.rpcClient.call(
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
3053
|
+
return this.rpcClient.call(
|
|
3054
|
+
"H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */,
|
|
3055
|
+
{
|
|
3056
|
+
operations,
|
|
3057
|
+
validateOnly
|
|
3058
|
+
}
|
|
3059
|
+
);
|
|
2488
3060
|
}
|
|
2489
3061
|
async getAvailableItemsAsync(containerId, slotId) {
|
|
2490
3062
|
const response = await this.rpcClient.call(
|
|
@@ -2507,17 +3079,23 @@ var RpcSimulationApi = class {
|
|
|
2507
3079
|
);
|
|
2508
3080
|
}
|
|
2509
3081
|
assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
2510
|
-
return this.rpcClient.call(
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
3082
|
+
return this.rpcClient.call(
|
|
3083
|
+
"H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */,
|
|
3084
|
+
{
|
|
3085
|
+
containerId,
|
|
3086
|
+
slotId,
|
|
3087
|
+
itemId
|
|
3088
|
+
}
|
|
3089
|
+
);
|
|
2515
3090
|
}
|
|
2516
3091
|
removeItemFromSlotAsync(containerId, slotId) {
|
|
2517
|
-
return this.rpcClient.call(
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
3092
|
+
return this.rpcClient.call(
|
|
3093
|
+
"H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */,
|
|
3094
|
+
{
|
|
3095
|
+
containerId,
|
|
3096
|
+
slotId
|
|
3097
|
+
}
|
|
3098
|
+
);
|
|
2521
3099
|
}
|
|
2522
3100
|
async getSlotContainersAsync() {
|
|
2523
3101
|
const response = await this.rpcClient.call(
|
|
@@ -2542,7 +3120,6 @@ var RpcSimulationApi = class {
|
|
|
2542
3120
|
roomId
|
|
2543
3121
|
}
|
|
2544
3122
|
);
|
|
2545
|
-
console.log("[Venus SDK] getStateAsync", response);
|
|
2546
3123
|
if (response.configuration) {
|
|
2547
3124
|
this._simulationConfig = response.configuration;
|
|
2548
3125
|
}
|
|
@@ -2554,9 +3131,10 @@ var RpcSimulationApi = class {
|
|
|
2554
3131
|
}
|
|
2555
3132
|
const config = await this.rpcClient.call(
|
|
2556
3133
|
"H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
|
|
2557
|
-
{
|
|
3134
|
+
{
|
|
3135
|
+
roomId
|
|
3136
|
+
}
|
|
2558
3137
|
);
|
|
2559
|
-
console.log("[Venus SDK] getConfigAsync", config);
|
|
2560
3138
|
if (config) {
|
|
2561
3139
|
this._simulationConfig = config;
|
|
2562
3140
|
return config;
|
|
@@ -2564,14 +3142,17 @@ var RpcSimulationApi = class {
|
|
|
2564
3142
|
throw new Error("No simulation configuration available");
|
|
2565
3143
|
}
|
|
2566
3144
|
executeRecipeAsync(recipeId, inputs, options) {
|
|
2567
|
-
return this.rpcClient.call(
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
3145
|
+
return this.rpcClient.call(
|
|
3146
|
+
"H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */,
|
|
3147
|
+
{
|
|
3148
|
+
recipeId,
|
|
3149
|
+
inputs,
|
|
3150
|
+
roomId: options?.roomId,
|
|
3151
|
+
batchAmount: options?.batchAmount,
|
|
3152
|
+
allowPartialBatch: options?.allowPartialBatch,
|
|
3153
|
+
entity: options?.entity
|
|
3154
|
+
}
|
|
3155
|
+
);
|
|
2575
3156
|
}
|
|
2576
3157
|
collectRecipeAsync(runId) {
|
|
2577
3158
|
return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
|
|
@@ -2579,9 +3160,12 @@ var RpcSimulationApi = class {
|
|
|
2579
3160
|
});
|
|
2580
3161
|
}
|
|
2581
3162
|
getActiveRunsAsync(options) {
|
|
2582
|
-
return this.rpcClient.call(
|
|
2583
|
-
|
|
2584
|
-
|
|
3163
|
+
return this.rpcClient.call(
|
|
3164
|
+
"H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */,
|
|
3165
|
+
{
|
|
3166
|
+
roomId: options?.roomId
|
|
3167
|
+
}
|
|
3168
|
+
);
|
|
2585
3169
|
}
|
|
2586
3170
|
executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2587
3171
|
return this.rpcClient.call(
|
|
@@ -2633,601 +3217,70 @@ var RpcSimulationApi = class {
|
|
|
2633
3217
|
);
|
|
2634
3218
|
}
|
|
2635
3219
|
getEntityMetadataAsync(entityId) {
|
|
2636
|
-
return this.rpcClient.call(
|
|
2637
|
-
"H5_SIMULATION_GET_ENTITY_METADATA" /* H5_SIMULATION_GET_ENTITY_METADATA */,
|
|
2638
|
-
{
|
|
2639
|
-
entityId
|
|
2640
|
-
}
|
|
2641
|
-
);
|
|
2642
|
-
}
|
|
2643
|
-
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
2644
|
-
const response = await this.rpcClient.call(
|
|
2645
|
-
"H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
|
|
2646
|
-
{
|
|
2647
|
-
entityId,
|
|
2648
|
-
fieldPath,
|
|
2649
|
-
entity
|
|
2650
|
-
}
|
|
2651
|
-
);
|
|
2652
|
-
return response.value;
|
|
2653
|
-
}
|
|
2654
|
-
};
|
|
2655
|
-
|
|
2656
|
-
// src/simulation/MockSimulationApi.ts
|
|
2657
|
-
function generateAppIdentifier2() {
|
|
2658
|
-
if (typeof window === "undefined") return "unknown-app";
|
|
2659
|
-
const url = window.location.href;
|
|
2660
|
-
const match = url.match(/\/H5\/([^\/]+)/);
|
|
2661
|
-
return match ? match[1] : "unknown-app";
|
|
2662
|
-
}
|
|
2663
|
-
var MockSimulationApi = class {
|
|
2664
|
-
constructor(simulationConfig = null) {
|
|
2665
|
-
__publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
|
|
2666
|
-
// appIdentifier -> config
|
|
2667
|
-
__publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
|
|
2668
|
-
// appIdentifier -> config
|
|
2669
|
-
__publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
|
|
2670
|
-
// appIdentifier -> timers[]
|
|
2671
|
-
__publicField(this, "appId");
|
|
2672
|
-
__publicField(this, "providedSimulationConfig");
|
|
2673
|
-
this.appId = generateAppIdentifier2();
|
|
2674
|
-
this.providedSimulationConfig = simulationConfig;
|
|
2675
|
-
}
|
|
2676
|
-
sumContributions(contributions) {
|
|
2677
|
-
return sumContributions(contributions);
|
|
2678
|
-
}
|
|
2679
|
-
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2680
|
-
this.log("validateSlotAssignmentAsync called:", {
|
|
2681
|
-
containerId,
|
|
2682
|
-
slotId,
|
|
2683
|
-
itemId
|
|
2684
|
-
});
|
|
2685
|
-
return { valid: true, message: "Mock validation successful" };
|
|
2686
|
-
}
|
|
2687
|
-
async executeBatchOperationsAsync(operations, validateOnly) {
|
|
2688
|
-
this.log("executeBatchOperationsAsync called:", {
|
|
2689
|
-
operations,
|
|
2690
|
-
validateOnly
|
|
2691
|
-
});
|
|
2692
|
-
return {
|
|
2693
|
-
success: true,
|
|
2694
|
-
results: operations.map(() => ({ success: true }))
|
|
2695
|
-
};
|
|
2696
|
-
}
|
|
2697
|
-
async getAvailableItemsAsync(containerId, slotId) {
|
|
2698
|
-
console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
|
|
2699
|
-
containerId,
|
|
2700
|
-
slotId
|
|
2701
|
-
});
|
|
2702
|
-
const appIdentifier = generateAppIdentifier2();
|
|
2703
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2704
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2705
|
-
entities: {}
|
|
2706
|
-
};
|
|
2707
|
-
const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
|
|
2708
|
-
entityId,
|
|
2709
|
-
quantity: 1,
|
|
2710
|
-
metadata: entity.metadata,
|
|
2711
|
-
powerPreview: 100
|
|
2712
|
-
// Mock power value
|
|
2713
|
-
}));
|
|
2714
|
-
return availableItems;
|
|
2715
|
-
}
|
|
2716
|
-
async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
|
|
2717
|
-
this.log("calculatePowerPreviewAsync called:", {
|
|
2718
|
-
containerId,
|
|
2719
|
-
slotId,
|
|
2720
|
-
candidateItemId
|
|
2721
|
-
});
|
|
2722
|
-
return {
|
|
2723
|
-
currentPower: 1e3,
|
|
2724
|
-
previewPower: 1200,
|
|
2725
|
-
powerDelta: 200,
|
|
2726
|
-
breakdown: { base: 800, weapon: 200, armor: 200 }
|
|
2727
|
-
};
|
|
2728
|
-
}
|
|
2729
|
-
async getSlotContainersAsync() {
|
|
2730
|
-
this.log("getSlotContainersAsync called");
|
|
2731
|
-
const appIdentifier = this.appId;
|
|
2732
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2733
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2734
|
-
entities: {}
|
|
2735
|
-
};
|
|
2736
|
-
const containers = Object.entries(config.entities).filter(([_, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
|
|
2737
|
-
entityId,
|
|
2738
|
-
slots: entity.metadata?.slots,
|
|
2739
|
-
isOwned: true
|
|
2740
|
-
// Mock: assume all containers are owned
|
|
2741
|
-
}));
|
|
2742
|
-
return containers;
|
|
2743
|
-
}
|
|
2744
|
-
async getSlotAssignmentsAsync(containerId) {
|
|
2745
|
-
this.log("getSlotAssignmentsAsync called for:", containerId);
|
|
2746
|
-
return [];
|
|
2747
|
-
}
|
|
2748
|
-
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
2749
|
-
this.log("resolveFieldValueAsync called:", {
|
|
2750
|
-
entityId,
|
|
2751
|
-
fieldPath,
|
|
2752
|
-
entity
|
|
2753
|
-
});
|
|
2754
|
-
const mockValues = {
|
|
2755
|
-
basePower: 850,
|
|
2756
|
-
weaponPower: 300,
|
|
2757
|
-
armorPower: 150,
|
|
2758
|
-
total_power: 1300,
|
|
2759
|
-
total_defense_power: 5e3
|
|
2760
|
-
};
|
|
2761
|
-
return mockValues[fieldPath] || 100;
|
|
2762
|
-
}
|
|
2763
|
-
async getEntityMetadataAsync(entityId) {
|
|
2764
|
-
this.log("getEntityMetadataAsync called for:", entityId);
|
|
2765
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2766
|
-
const appIdentifier = this.appId;
|
|
2767
|
-
const config = mockSimulationConfigs.get(
|
|
2768
|
-
appIdentifier
|
|
2769
|
-
) || {
|
|
2770
|
-
entities: {}};
|
|
2771
|
-
const entity = config.entities[entityId];
|
|
2772
|
-
return entity?.metadata || {};
|
|
2773
|
-
}
|
|
2774
|
-
async collectRecipeAsync(runId) {
|
|
2775
|
-
this.log("collectRecipeAsync called:", { runId });
|
|
2776
|
-
const mockRewards = {
|
|
2777
|
-
cash: Math.floor(Math.random() * 1e3) + 500,
|
|
2778
|
-
experience: Math.floor(Math.random() * 50) + 25
|
|
2779
|
-
};
|
|
2780
|
-
return {
|
|
2781
|
-
success: true,
|
|
2782
|
-
runId,
|
|
2783
|
-
rewards: mockRewards,
|
|
2784
|
-
message: "Rewards collected successfully"
|
|
2785
|
-
};
|
|
2786
|
-
}
|
|
2787
|
-
executeRecipeAsync(recipeId, inputs, options) {
|
|
2788
|
-
this.log("executeRecipeAsync called:", {
|
|
2789
|
-
recipeId,
|
|
2790
|
-
inputs,
|
|
2791
|
-
options
|
|
2792
|
-
});
|
|
2793
|
-
const appIdentifier = this.appId;
|
|
2794
|
-
return this.executeRecipe(appIdentifier, recipeId, inputs);
|
|
2795
|
-
}
|
|
2796
|
-
async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2797
|
-
this.log("executeScopedRecipeAsync called:", {
|
|
2798
|
-
recipeId,
|
|
2799
|
-
entity,
|
|
2800
|
-
inputs,
|
|
2801
|
-
roomId: options?.roomId,
|
|
2802
|
-
options
|
|
2803
|
-
});
|
|
2804
|
-
return {
|
|
2805
|
-
success: true,
|
|
2806
|
-
message: "Mock scoped recipe execution successful"
|
|
2807
|
-
};
|
|
2808
|
-
}
|
|
2809
|
-
async getActiveRunsAsync(options) {
|
|
2810
|
-
this.log("getActiveRunsAsync called:", options);
|
|
2811
|
-
const appIdentifier = this.appId;
|
|
2812
|
-
let state = this.mockSimulationStates.get(appIdentifier);
|
|
2813
|
-
if (!state) {
|
|
2814
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
2815
|
-
}
|
|
2816
|
-
return state.activeRuns || [];
|
|
2817
|
-
}
|
|
2818
|
-
async getAvailableRecipesAsync(options) {
|
|
2819
|
-
this.log("getAvailableRecipesAsync called:", options);
|
|
2820
|
-
const baseRecipes = [
|
|
2821
|
-
{ id: "collect_resources", scope: "player", clientViewable: true },
|
|
2822
|
-
{ id: "upgrade_equipment", scope: "player", clientViewable: true }
|
|
2823
|
-
];
|
|
2824
|
-
if (options?.roomId) {
|
|
2825
|
-
baseRecipes.push(
|
|
2826
|
-
{ id: "room_upgrade", scope: "room", clientViewable: true },
|
|
2827
|
-
{ id: "cooperative_project", scope: "room", clientViewable: true }
|
|
2828
|
-
);
|
|
2829
|
-
}
|
|
2830
|
-
if (options?.includeActorRecipes && options?.roomId) {
|
|
2831
|
-
baseRecipes.push(
|
|
2832
|
-
{ id: "trade_with_npc", scope: "actor", clientViewable: true },
|
|
2833
|
-
{ id: "attack_monster", scope: "actor", clientViewable: true }
|
|
2834
|
-
);
|
|
2835
|
-
}
|
|
2836
|
-
return { success: true, recipes: baseRecipes };
|
|
2837
|
-
}
|
|
2838
|
-
async getBatchRecipeRequirementsAsync(recipes) {
|
|
2839
|
-
this.log("getBatchRecipeRequirementsAsync called:", {
|
|
2840
|
-
count: recipes?.length
|
|
2841
|
-
});
|
|
2842
|
-
const results = (recipes || []).map((q) => ({
|
|
2843
|
-
recipeId: q.recipeId,
|
|
2844
|
-
entity: q.entity || null,
|
|
2845
|
-
amount: q.batchAmount || 1,
|
|
2846
|
-
inputs: { cash: "BE:0" },
|
|
2847
|
-
canAfford: true,
|
|
2848
|
-
disabled: false
|
|
2849
|
-
}));
|
|
2850
|
-
return { success: true, results };
|
|
2851
|
-
}
|
|
2852
|
-
async getRecipeRequirementsAsync(recipe) {
|
|
2853
|
-
this.log("getRecipeRequirementsAsync called:", recipe);
|
|
2854
|
-
return {
|
|
2855
|
-
recipeId: recipe.recipeId,
|
|
2856
|
-
entity: recipe.entity || null,
|
|
2857
|
-
amount: recipe.batchAmount,
|
|
2858
|
-
inputs: { cash: "BE:0" },
|
|
2859
|
-
canAfford: true,
|
|
2860
|
-
disabled: false
|
|
2861
|
-
};
|
|
2862
|
-
}
|
|
2863
|
-
async triggerRecipeChainAsync(recipeId, options) {
|
|
2864
|
-
this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
|
|
2865
|
-
return {
|
|
2866
|
-
success: true,
|
|
2867
|
-
message: "Mock recipe chain triggered successfully"
|
|
2868
|
-
};
|
|
2869
|
-
}
|
|
2870
|
-
log(message, ...args) {
|
|
2871
|
-
console.log(`[Venus Sim Mock] ${message}`, args);
|
|
2872
|
-
}
|
|
2873
|
-
async executeRecipe(appIdentifier, recipeId, inputs) {
|
|
2874
|
-
this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
|
|
2875
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2876
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
2877
|
-
let config = mockSimulationConfigs.get(appIdentifier);
|
|
2878
|
-
let state = mockSimulationStates.get(appIdentifier);
|
|
2879
|
-
if (!config || !state) {
|
|
2880
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
2881
|
-
config = mockSimulationConfigs.get(appIdentifier);
|
|
2882
|
-
if (!config) {
|
|
2883
|
-
throw new Error("Failed to initialize simulation config");
|
|
2884
|
-
}
|
|
2885
|
-
}
|
|
2886
|
-
const recipe = config.recipes?.[recipeId];
|
|
2887
|
-
if (!recipe) {
|
|
2888
|
-
throw new Error(`Recipe ${recipeId} not found`);
|
|
2889
|
-
}
|
|
2890
|
-
if (state.disabledRecipes?.includes(recipeId)) {
|
|
2891
|
-
throw new Error(`Recipe ${recipeId} is disabled`);
|
|
2892
|
-
}
|
|
2893
|
-
if (recipe.inputs) {
|
|
2894
|
-
for (const [entityId, required] of Object.entries(recipe.inputs)) {
|
|
2895
|
-
const available = state.inventory[entityId] || 0;
|
|
2896
|
-
if (available < required) {
|
|
2897
|
-
throw new Error(
|
|
2898
|
-
`Insufficient ${entityId}: required ${required}, available ${available}`
|
|
2899
|
-
);
|
|
2900
|
-
}
|
|
3220
|
+
return this.rpcClient.call(
|
|
3221
|
+
"H5_SIMULATION_GET_ENTITY_METADATA" /* H5_SIMULATION_GET_ENTITY_METADATA */,
|
|
3222
|
+
{
|
|
3223
|
+
entityId
|
|
2901
3224
|
}
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
3225
|
+
);
|
|
3226
|
+
}
|
|
3227
|
+
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
3228
|
+
const response = await this.rpcClient.call(
|
|
3229
|
+
"H5_SIMULATION_RESOLVE_VALUE" /* H5_SIMULATION_RESOLVE_VALUE */,
|
|
3230
|
+
{
|
|
3231
|
+
entityId,
|
|
3232
|
+
fieldPath,
|
|
3233
|
+
entity
|
|
2909
3234
|
}
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
this.applyEffects(state, recipe.beginEffects);
|
|
2913
|
-
}
|
|
2914
|
-
const runId = this.generateRunId();
|
|
2915
|
-
const now = Date.now();
|
|
2916
|
-
const expiresAt = now + (recipe.duration || 0);
|
|
2917
|
-
const run = {
|
|
2918
|
-
id: runId,
|
|
2919
|
-
recipeId,
|
|
2920
|
-
status: "running",
|
|
2921
|
-
startTime: now,
|
|
2922
|
-
expiresAt,
|
|
2923
|
-
inputs: recipe.inputs || {}
|
|
2924
|
-
};
|
|
2925
|
-
state.activeRuns.push(run);
|
|
2926
|
-
if (recipe.duration === 0) {
|
|
2927
|
-
this.completeRun(appIdentifier, runId);
|
|
2928
|
-
return { status: "completed", runId };
|
|
2929
|
-
} else {
|
|
2930
|
-
const mockActiveTimers = this.mockActiveTimers;
|
|
2931
|
-
const timer = setTimeout(() => {
|
|
2932
|
-
this.completeRun(appIdentifier, runId);
|
|
2933
|
-
}, recipe.duration);
|
|
2934
|
-
const timers = mockActiveTimers.get(appIdentifier) || [];
|
|
2935
|
-
timers.push(timer);
|
|
2936
|
-
mockActiveTimers.set(appIdentifier, timers);
|
|
2937
|
-
return {
|
|
2938
|
-
status: "running",
|
|
2939
|
-
runId,
|
|
2940
|
-
expiresAt: new Date(expiresAt).toISOString()
|
|
2941
|
-
};
|
|
2942
|
-
}
|
|
3235
|
+
);
|
|
3236
|
+
return response.value;
|
|
2943
3237
|
}
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
2949
|
-
const mockActiveTimers = this.mockActiveTimers;
|
|
2950
|
-
const config = providedSimulationConfig || {
|
|
2951
|
-
version: "1.0",
|
|
2952
|
-
entities: {},
|
|
2953
|
-
recipes: {}
|
|
2954
|
-
};
|
|
2955
|
-
mockSimulationConfigs.set(appIdentifier, config);
|
|
2956
|
-
const initialInventory = {};
|
|
2957
|
-
if (providedSimulationConfig && config.entities) {
|
|
2958
|
-
Object.keys(config.entities).forEach((entityId) => {
|
|
2959
|
-
initialInventory[entityId] = 0;
|
|
2960
|
-
});
|
|
2961
|
-
}
|
|
2962
|
-
const state = {
|
|
2963
|
-
inventory: initialInventory,
|
|
2964
|
-
activeRuns: [],
|
|
2965
|
-
disabledRecipes: new Array()
|
|
2966
|
-
};
|
|
2967
|
-
if (config.recipes) {
|
|
2968
|
-
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
2969
|
-
if (recipe.metadata?.startsDisabled) {
|
|
2970
|
-
state.disabledRecipes.push(recipeId);
|
|
2971
|
-
}
|
|
2972
|
-
});
|
|
3238
|
+
handleSimulationUpdate(notification) {
|
|
3239
|
+
if (!notification || !notification.subscriptionId) {
|
|
3240
|
+
console.warn("[Venus SDK] Received malformed simulation update");
|
|
3241
|
+
return;
|
|
2973
3242
|
}
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
2982
|
-
const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
|
|
2983
|
-
if (isAutoRestart && recipe.outputs) {
|
|
2984
|
-
this.log(`Found auto-restart recipe: ${recipeId}`, {
|
|
2985
|
-
topLevelAutoRestart: recipe.autoRestart,
|
|
2986
|
-
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
2987
|
-
hasOutputs: !!recipe.outputs,
|
|
2988
|
-
duration: recipe.duration
|
|
2989
|
-
});
|
|
2990
|
-
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
2991
|
-
if (condition && condition.entity) {
|
|
2992
|
-
const currentAmount = initialInventory[condition.entity] || 0;
|
|
2993
|
-
if (currentAmount < condition.maxValue) {
|
|
2994
|
-
console.log(
|
|
2995
|
-
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
|
|
2996
|
-
{
|
|
2997
|
-
currentAmount,
|
|
2998
|
-
maxValue: condition.maxValue,
|
|
2999
|
-
entity: condition.entity
|
|
3000
|
-
}
|
|
3001
|
-
);
|
|
3002
|
-
setTimeout(() => {
|
|
3003
|
-
this.executeRecipe(appIdentifier, recipeId, {});
|
|
3004
|
-
}, 1e3);
|
|
3005
|
-
}
|
|
3006
|
-
} else {
|
|
3007
|
-
console.log(
|
|
3008
|
-
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
|
|
3009
|
-
);
|
|
3010
|
-
setTimeout(() => {
|
|
3011
|
-
this.executeRecipe(appIdentifier, recipeId, {});
|
|
3012
|
-
}, 1e3);
|
|
3013
|
-
}
|
|
3014
|
-
}
|
|
3015
|
-
});
|
|
3243
|
+
const callback = this.subscriptionCallbacks.get(notification.subscriptionId);
|
|
3244
|
+
if (!callback) {
|
|
3245
|
+
console.warn(
|
|
3246
|
+
"[Venus SDK] Received update for unknown subscription:",
|
|
3247
|
+
notification.subscriptionId
|
|
3248
|
+
);
|
|
3249
|
+
return;
|
|
3016
3250
|
}
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
}
|
|
3022
|
-
completeRun(appIdentifier, runId) {
|
|
3023
|
-
this.log(`Completing run ${runId} for ${appIdentifier}`);
|
|
3024
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3025
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
3026
|
-
const config = mockSimulationConfigs.get(appIdentifier);
|
|
3027
|
-
const state = mockSimulationStates.get(appIdentifier);
|
|
3028
|
-
if (!config || !state) return;
|
|
3029
|
-
const runIndex = state.activeRuns.findIndex((r) => r.id === runId);
|
|
3030
|
-
if (runIndex === -1) return;
|
|
3031
|
-
const run = state.activeRuns[runIndex];
|
|
3032
|
-
const recipe = config.recipes?.[run.recipeId];
|
|
3033
|
-
if (!recipe) return;
|
|
3034
|
-
const outputs = {};
|
|
3035
|
-
const rng = this.createSeededRandom(runId);
|
|
3036
|
-
if (recipe.outputs) {
|
|
3037
|
-
for (const [entityId, value] of Object.entries(recipe.outputs)) {
|
|
3038
|
-
if (typeof value === "number") {
|
|
3039
|
-
outputs[entityId] = value;
|
|
3040
|
-
} else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
|
|
3041
|
-
outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
|
|
3042
|
-
}
|
|
3043
|
-
}
|
|
3251
|
+
try {
|
|
3252
|
+
callback(notification.updates);
|
|
3253
|
+
} catch (error) {
|
|
3254
|
+
console.error("[Venus SDK] Error in simulation subscription callback", error);
|
|
3044
3255
|
}
|
|
3045
|
-
|
|
3046
|
-
|
|
3256
|
+
}
|
|
3257
|
+
ensureValidSubscribeOptions(options) {
|
|
3258
|
+
if (typeof options !== "object" || options === null) {
|
|
3259
|
+
throw new Error("Simulation subscribe requires an options object");
|
|
3047
3260
|
}
|
|
3048
|
-
|
|
3049
|
-
|
|
3261
|
+
const opts = options;
|
|
3262
|
+
if (typeof opts.onUpdate !== "function") {
|
|
3263
|
+
throw new Error("Simulation subscribe requires an onUpdate callback");
|
|
3050
3264
|
}
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
if (isAutoRestart) {
|
|
3056
|
-
console.log(
|
|
3057
|
-
`[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
|
|
3058
|
-
{
|
|
3059
|
-
topLevelAutoRestart: recipe.autoRestart,
|
|
3060
|
-
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
3061
|
-
hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
|
|
3062
|
-
}
|
|
3265
|
+
const hasFilter = Array.isArray(opts.entities) && opts.entities.length > 0 || Array.isArray(opts.tags) && opts.tags.length > 0 || Boolean(opts.activeRuns);
|
|
3266
|
+
if (!hasFilter) {
|
|
3267
|
+
throw new Error(
|
|
3268
|
+
"Simulation subscribe requires at least one filter (entities, tags, activeRuns)"
|
|
3063
3269
|
);
|
|
3064
|
-
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
3065
|
-
if (condition) {
|
|
3066
|
-
const currentAmount = state.inventory[condition.entity] || 0;
|
|
3067
|
-
if (currentAmount < condition.maxValue) {
|
|
3068
|
-
console.log(
|
|
3069
|
-
`[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
|
|
3070
|
-
{
|
|
3071
|
-
currentAmount,
|
|
3072
|
-
maxValue: condition.maxValue,
|
|
3073
|
-
entity: condition.entity
|
|
3074
|
-
}
|
|
3075
|
-
);
|
|
3076
|
-
setTimeout(() => {
|
|
3077
|
-
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
3078
|
-
}, 1e3);
|
|
3079
|
-
}
|
|
3080
|
-
} else {
|
|
3081
|
-
console.log(
|
|
3082
|
-
`[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
|
|
3083
|
-
);
|
|
3084
|
-
setTimeout(() => {
|
|
3085
|
-
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
3086
|
-
}, 1e3);
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
|
-
console.log(
|
|
3090
|
-
`[Venus Simulation Mock] Completed run ${runId}, outputs:`,
|
|
3091
|
-
outputs
|
|
3092
|
-
);
|
|
3093
|
-
}
|
|
3094
|
-
createSeededRandom(seed) {
|
|
3095
|
-
let hash = 0;
|
|
3096
|
-
for (let i = 0; i < seed.length; i++) {
|
|
3097
|
-
const char = seed.charCodeAt(i);
|
|
3098
|
-
hash = (hash << 5) - hash + char;
|
|
3099
|
-
hash = hash & hash;
|
|
3100
3270
|
}
|
|
3101
|
-
return () => {
|
|
3102
|
-
hash = (hash * 9301 + 49297) % 233280;
|
|
3103
|
-
return hash / 233280;
|
|
3104
|
-
};
|
|
3105
|
-
}
|
|
3106
|
-
applyEffects(state, effects) {
|
|
3107
|
-
if (!effects || !Array.isArray(effects)) return;
|
|
3108
|
-
for (const effect of effects) {
|
|
3109
|
-
switch (effect.type) {
|
|
3110
|
-
case "set":
|
|
3111
|
-
state.inventory[effect.target] = effect.value;
|
|
3112
|
-
console.log(
|
|
3113
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
|
|
3114
|
-
);
|
|
3115
|
-
break;
|
|
3116
|
-
case "add":
|
|
3117
|
-
state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
|
|
3118
|
-
console.log(
|
|
3119
|
-
`[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
|
|
3120
|
-
);
|
|
3121
|
-
break;
|
|
3122
|
-
case "multiply":
|
|
3123
|
-
state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
|
|
3124
|
-
console.log(
|
|
3125
|
-
`[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3126
|
-
);
|
|
3127
|
-
break;
|
|
3128
|
-
case "min":
|
|
3129
|
-
state.inventory[effect.target] = Math.max(
|
|
3130
|
-
state.inventory[effect.target] || 0,
|
|
3131
|
-
effect.value
|
|
3132
|
-
);
|
|
3133
|
-
console.log(
|
|
3134
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3135
|
-
);
|
|
3136
|
-
break;
|
|
3137
|
-
case "max":
|
|
3138
|
-
state.inventory[effect.target] = Math.min(
|
|
3139
|
-
state.inventory[effect.target] || 0,
|
|
3140
|
-
effect.value
|
|
3141
|
-
);
|
|
3142
|
-
console.log(
|
|
3143
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3144
|
-
);
|
|
3145
|
-
break;
|
|
3146
|
-
case "enable_recipe":
|
|
3147
|
-
if (state.disabledRecipes?.includes(effect.target)) {
|
|
3148
|
-
state.disabledRecipes = state.disabledRecipes.filter(
|
|
3149
|
-
(r) => r !== effect.target
|
|
3150
|
-
);
|
|
3151
|
-
console.log(
|
|
3152
|
-
`[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
|
|
3153
|
-
);
|
|
3154
|
-
}
|
|
3155
|
-
break;
|
|
3156
|
-
case "disable_recipe":
|
|
3157
|
-
if (!state.disabledRecipes) state.disabledRecipes = [];
|
|
3158
|
-
if (!state.disabledRecipes.includes(effect.target)) {
|
|
3159
|
-
state.disabledRecipes.push(effect.target);
|
|
3160
|
-
console.log(
|
|
3161
|
-
`[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
|
|
3162
|
-
);
|
|
3163
|
-
}
|
|
3164
|
-
break;
|
|
3165
|
-
case "trigger_recipe":
|
|
3166
|
-
console.log(
|
|
3167
|
-
`[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
|
|
3168
|
-
);
|
|
3169
|
-
break;
|
|
3170
|
-
default:
|
|
3171
|
-
console.warn(
|
|
3172
|
-
`[Venus Simulation Mock] Unknown effect type: ${effect.type}`
|
|
3173
|
-
);
|
|
3174
|
-
}
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
async getConfigAsync() {
|
|
3178
|
-
console.log("[Venus Simulation Mock] getConfigAsync called");
|
|
3179
|
-
const appIdentifier = this.appId;
|
|
3180
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3181
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
3182
|
-
version: "1.0",
|
|
3183
|
-
entities: {},
|
|
3184
|
-
recipes: {}
|
|
3185
|
-
};
|
|
3186
|
-
return config;
|
|
3187
|
-
}
|
|
3188
|
-
async getStateAsync(roomId) {
|
|
3189
|
-
this.log("getStateAsync called:", roomId);
|
|
3190
|
-
const appIdentifier = this.appId;
|
|
3191
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
3192
|
-
let state = mockSimulationStates.get(appIdentifier);
|
|
3193
|
-
if (!state) {
|
|
3194
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
3195
|
-
}
|
|
3196
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3197
|
-
return {
|
|
3198
|
-
...state,
|
|
3199
|
-
roomId,
|
|
3200
|
-
configuration: mockSimulationConfigs.get(appIdentifier)
|
|
3201
|
-
};
|
|
3202
|
-
}
|
|
3203
|
-
async assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
3204
|
-
this.log("assignItemToSlotAsync called:", {
|
|
3205
|
-
containerId,
|
|
3206
|
-
slotId,
|
|
3207
|
-
itemId
|
|
3208
|
-
});
|
|
3209
|
-
return { success: true, message: "Mock assignment successful" };
|
|
3210
|
-
}
|
|
3211
|
-
async removeItemFromSlotAsync(containerId, slotId) {
|
|
3212
|
-
this.log("removeItemFromSlotAsync called:", {
|
|
3213
|
-
containerId,
|
|
3214
|
-
slotId
|
|
3215
|
-
});
|
|
3216
|
-
return { success: true, message: "Mock removal successful" };
|
|
3217
3271
|
}
|
|
3218
3272
|
};
|
|
3219
3273
|
|
|
3220
3274
|
// src/simulation/index.ts
|
|
3221
3275
|
function initializeSimulation(venusApi, host) {
|
|
3222
|
-
console.log("[Venus SDK] Initializing new Simulation Api");
|
|
3223
3276
|
venusApi.simulation = {
|
|
3224
3277
|
isEnabled: () => true
|
|
3225
3278
|
};
|
|
3226
3279
|
venusApi.simulation.getConfigAsync = () => {
|
|
3227
3280
|
return host.simulation.getConfigAsync();
|
|
3228
3281
|
};
|
|
3229
|
-
venusApi.simulation.getStateAsync = (
|
|
3230
|
-
return host.simulation.getStateAsync(
|
|
3282
|
+
venusApi.simulation.getStateAsync = (roomId) => {
|
|
3283
|
+
return host.simulation.getStateAsync(roomId);
|
|
3231
3284
|
};
|
|
3232
3285
|
venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
|
|
3233
3286
|
return host.simulation.executeRecipeAsync(recipeId, inputs, options);
|
|
@@ -3238,31 +3291,17 @@ function initializeSimulation(venusApi, host) {
|
|
|
3238
3291
|
venusApi.simulation.collectRecipeAsync = (runId) => {
|
|
3239
3292
|
return host.simulation.collectRecipeAsync(runId);
|
|
3240
3293
|
};
|
|
3241
|
-
venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs,
|
|
3242
|
-
return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs,
|
|
3243
|
-
roomId,
|
|
3244
|
-
...options
|
|
3245
|
-
});
|
|
3294
|
+
venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, options) => {
|
|
3295
|
+
return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, options);
|
|
3246
3296
|
};
|
|
3247
|
-
venusApi.simulation.triggerRecipeChainAsync = (recipeId,
|
|
3248
|
-
return host.simulation.triggerRecipeChainAsync(recipeId,
|
|
3249
|
-
context,
|
|
3250
|
-
roomId
|
|
3251
|
-
});
|
|
3297
|
+
venusApi.simulation.triggerRecipeChainAsync = (recipeId, options) => {
|
|
3298
|
+
return host.simulation.triggerRecipeChainAsync(recipeId, options);
|
|
3252
3299
|
};
|
|
3253
|
-
venusApi.simulation.getAvailableRecipesAsync = async (
|
|
3254
|
-
|
|
3255
|
-
roomId,
|
|
3256
|
-
includeActorRecipes
|
|
3257
|
-
});
|
|
3258
|
-
return result.recipes;
|
|
3300
|
+
venusApi.simulation.getAvailableRecipesAsync = async (options) => {
|
|
3301
|
+
return host.simulation.getAvailableRecipesAsync(options);
|
|
3259
3302
|
};
|
|
3260
|
-
venusApi.simulation.getRecipeRequirementsAsync = (
|
|
3261
|
-
return host.simulation.getRecipeRequirementsAsync(
|
|
3262
|
-
recipeId,
|
|
3263
|
-
entity,
|
|
3264
|
-
batchAmount: amount
|
|
3265
|
-
});
|
|
3303
|
+
venusApi.simulation.getRecipeRequirementsAsync = (recipe) => {
|
|
3304
|
+
return host.simulation.getRecipeRequirementsAsync(recipe);
|
|
3266
3305
|
};
|
|
3267
3306
|
venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
|
|
3268
3307
|
return host.simulation.getBatchRecipeRequirementsAsync(recipes);
|
|
@@ -3305,9 +3344,6 @@ function initializeSimulation(venusApi, host) {
|
|
|
3305
3344
|
itemId
|
|
3306
3345
|
);
|
|
3307
3346
|
};
|
|
3308
|
-
venusApi.simulation.sumContributions = (contributions) => {
|
|
3309
|
-
return host.simulation.sumContributions(contributions);
|
|
3310
|
-
};
|
|
3311
3347
|
}
|
|
3312
3348
|
|
|
3313
3349
|
// src/time/utils.ts
|
|
@@ -3326,9 +3362,11 @@ function isPacificDaylightTime(date) {
|
|
|
3326
3362
|
|
|
3327
3363
|
// src/time/HostTimeApi.ts
|
|
3328
3364
|
var HostTimeApi = class {
|
|
3329
|
-
constructor(rpcClient) {
|
|
3365
|
+
constructor(rpcClient, venusApi) {
|
|
3330
3366
|
__publicField(this, "rpcClient");
|
|
3367
|
+
__publicField(this, "venusApi");
|
|
3331
3368
|
this.rpcClient = rpcClient;
|
|
3369
|
+
this.venusApi = venusApi;
|
|
3332
3370
|
}
|
|
3333
3371
|
async requestTimeAsync() {
|
|
3334
3372
|
const response = await this.rpcClient.call(
|
|
@@ -3338,13 +3376,7 @@ var HostTimeApi = class {
|
|
|
3338
3376
|
return response;
|
|
3339
3377
|
}
|
|
3340
3378
|
formatTime(timestamp, options) {
|
|
3341
|
-
|
|
3342
|
-
const windowVenus = window.venus;
|
|
3343
|
-
if (windowVenus._config.locale) {
|
|
3344
|
-
locale = windowVenus._config.locale;
|
|
3345
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3346
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
3347
|
-
}
|
|
3379
|
+
const locale = this.venusApi.getLocale();
|
|
3348
3380
|
const date = new Date(timestamp);
|
|
3349
3381
|
const dateTimeOptions = {
|
|
3350
3382
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -3356,13 +3388,7 @@ var HostTimeApi = class {
|
|
|
3356
3388
|
}
|
|
3357
3389
|
formatNumber(value, options) {
|
|
3358
3390
|
try {
|
|
3359
|
-
|
|
3360
|
-
const windowVenus = window.venus;
|
|
3361
|
-
if (windowVenus._config.locale) {
|
|
3362
|
-
locale = windowVenus._config.locale;
|
|
3363
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3364
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
3365
|
-
}
|
|
3391
|
+
const locale = this.venusApi.getLocale();
|
|
3366
3392
|
const numberOptions = {
|
|
3367
3393
|
style: options?.style || "decimal",
|
|
3368
3394
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
@@ -3425,18 +3451,17 @@ var MockTimeApi = class {
|
|
|
3425
3451
|
this.venusApi = venusApi;
|
|
3426
3452
|
}
|
|
3427
3453
|
formatNumber(value, options) {
|
|
3428
|
-
const locale = this.getLocale();
|
|
3454
|
+
const locale = this.venusApi.getLocale();
|
|
3429
3455
|
const numberOptions = {
|
|
3430
3456
|
style: options?.style || "decimal",
|
|
3431
3457
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
3432
3458
|
maximumFractionDigits: options?.maximumFractionDigits || 2,
|
|
3433
3459
|
...options
|
|
3434
3460
|
};
|
|
3435
|
-
console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
|
|
3436
3461
|
return value.toLocaleString(locale, numberOptions);
|
|
3437
3462
|
}
|
|
3438
3463
|
formatTime(timestamp, options) {
|
|
3439
|
-
const locale = this.getLocale();
|
|
3464
|
+
const locale = this.venusApi.getLocale();
|
|
3440
3465
|
const date = new Date(timestamp);
|
|
3441
3466
|
const dateTimeOptions = {
|
|
3442
3467
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -3444,13 +3469,9 @@ var MockTimeApi = class {
|
|
|
3444
3469
|
hour12: options.hour12 !== void 0 ? options.hour12 : true,
|
|
3445
3470
|
...options
|
|
3446
3471
|
};
|
|
3447
|
-
console.log(
|
|
3448
|
-
`[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
|
|
3449
|
-
);
|
|
3450
3472
|
return date.toLocaleString(locale, dateTimeOptions);
|
|
3451
3473
|
}
|
|
3452
3474
|
async getFutureTimeAsync(options) {
|
|
3453
|
-
console.log("[Venus Mock] Getting future time with options:", options);
|
|
3454
3475
|
const timeInfo = await this.requestTimeAsync();
|
|
3455
3476
|
const serverTime = new Date(timeInfo.serverTime);
|
|
3456
3477
|
const result = new Date(serverTime);
|
|
@@ -3495,7 +3516,6 @@ var MockTimeApi = class {
|
|
|
3495
3516
|
return result.getTime();
|
|
3496
3517
|
}
|
|
3497
3518
|
async requestTimeAsync() {
|
|
3498
|
-
console.log("[Venus Mock] Requesting time");
|
|
3499
3519
|
await createMockDelay(MOCK_DELAYS.short);
|
|
3500
3520
|
const venusApi = this.venusApi;
|
|
3501
3521
|
const mockOffset = venusApi._mock.serverTimeOffset || 2500;
|
|
@@ -3509,23 +3529,8 @@ var MockTimeApi = class {
|
|
|
3509
3529
|
formattedTime: new Date(localTime).toISOString(),
|
|
3510
3530
|
locale: venusApi._mock.user?.locale || "en-US"
|
|
3511
3531
|
};
|
|
3512
|
-
console.log("[Venus Mock] Time response:", {
|
|
3513
|
-
serverTime: new Date(timeInfo.serverTime).toISOString(),
|
|
3514
|
-
localTime: new Date(timeInfo.localTime).toISOString(),
|
|
3515
|
-
timezoneOffset: timeInfo.timezoneOffset
|
|
3516
|
-
});
|
|
3517
3532
|
return timeInfo;
|
|
3518
3533
|
}
|
|
3519
|
-
getLocale() {
|
|
3520
|
-
const venusApi = this.venusApi;
|
|
3521
|
-
let locale = "en-US";
|
|
3522
|
-
if (venusApi._mock.user && venusApi._mock.user.locale) {
|
|
3523
|
-
locale = venusApi._mock.user.locale;
|
|
3524
|
-
} else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
|
|
3525
|
-
locale = venusApi._mock.environment.browserInfo.language;
|
|
3526
|
-
}
|
|
3527
|
-
return locale;
|
|
3528
|
-
}
|
|
3529
3534
|
};
|
|
3530
3535
|
|
|
3531
3536
|
// src/time/index.ts
|
|
@@ -3545,11 +3550,35 @@ function initializeTime(venusApi, host) {
|
|
|
3545
3550
|
}
|
|
3546
3551
|
|
|
3547
3552
|
// src/version.ts
|
|
3548
|
-
var SDK_VERSION = "3.0
|
|
3553
|
+
var SDK_VERSION = "3.2.1-beta.0";
|
|
3549
3554
|
|
|
3550
|
-
// src/shared-assets/
|
|
3551
|
-
|
|
3552
|
-
|
|
3555
|
+
// src/shared-assets/base64Utils.ts
|
|
3556
|
+
function base64ToArrayBuffer(base64) {
|
|
3557
|
+
const binaryString = atob(base64);
|
|
3558
|
+
const len = binaryString.length;
|
|
3559
|
+
const bytes = new Uint8Array(len);
|
|
3560
|
+
for (let i = 0; i < len; i++) {
|
|
3561
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
3562
|
+
}
|
|
3563
|
+
return bytes.buffer;
|
|
3564
|
+
}
|
|
3565
|
+
function base64ToUtf8(base64) {
|
|
3566
|
+
if (typeof TextDecoder !== "undefined") {
|
|
3567
|
+
const decoder = new TextDecoder("utf-8");
|
|
3568
|
+
const buffer = base64ToArrayBuffer(base64);
|
|
3569
|
+
return decoder.decode(new Uint8Array(buffer));
|
|
3570
|
+
}
|
|
3571
|
+
if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
|
|
3572
|
+
const BufferCtor = globalThis.Buffer;
|
|
3573
|
+
return BufferCtor.from(base64, "base64").toString("utf-8");
|
|
3574
|
+
}
|
|
3575
|
+
const binaryString = atob(base64);
|
|
3576
|
+
let result = "";
|
|
3577
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
3578
|
+
result += String.fromCharCode(binaryString.charCodeAt(i));
|
|
3579
|
+
}
|
|
3580
|
+
return decodeURIComponent(escape(result));
|
|
3581
|
+
}
|
|
3553
3582
|
|
|
3554
3583
|
// src/shared-assets/RpcSharedAssetsApi.ts
|
|
3555
3584
|
var RpcSharedAssetsApi = class {
|
|
@@ -3559,46 +3588,22 @@ var RpcSharedAssetsApi = class {
|
|
|
3559
3588
|
this.rpcClient = rpcClient;
|
|
3560
3589
|
this.venusApi = venusApi;
|
|
3561
3590
|
}
|
|
3562
|
-
async
|
|
3563
|
-
try {
|
|
3564
|
-
const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
|
|
3565
|
-
assetKey: "burgerTimeCoreBundle"
|
|
3566
|
-
});
|
|
3567
|
-
return base64ToArrayBuffer(response.base64Data);
|
|
3568
|
-
} catch (err) {
|
|
3569
|
-
try {
|
|
3570
|
-
const blob = await this.venusApi.cdn.fetchBlob(BurgerTimeAssetsCdnPath);
|
|
3571
|
-
return await blob.arrayBuffer();
|
|
3572
|
-
} catch (e) {
|
|
3573
|
-
throw new Error("Failed to load burgerTimeAssetsBundle");
|
|
3574
|
-
}
|
|
3575
|
-
}
|
|
3576
|
-
}
|
|
3577
|
-
async loadCharactersBundle() {
|
|
3591
|
+
async loadAssetsBundle(game, bundleKey, fileType = "stow") {
|
|
3578
3592
|
try {
|
|
3579
3593
|
const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
|
|
3580
|
-
assetKey:
|
|
3594
|
+
assetKey: bundleKey
|
|
3581
3595
|
});
|
|
3582
3596
|
return base64ToArrayBuffer(response.base64Data);
|
|
3583
3597
|
} catch (err) {
|
|
3584
3598
|
try {
|
|
3585
|
-
const blob = await this.venusApi.cdn.fetchBlob(
|
|
3599
|
+
const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
|
|
3586
3600
|
return await blob.arrayBuffer();
|
|
3587
3601
|
} catch (e) {
|
|
3588
|
-
throw new Error(
|
|
3602
|
+
throw new Error(`Failed to load ${bundleKey}`);
|
|
3589
3603
|
}
|
|
3590
3604
|
}
|
|
3591
3605
|
}
|
|
3592
3606
|
};
|
|
3593
|
-
function base64ToArrayBuffer(base64) {
|
|
3594
|
-
const binaryString = atob(base64);
|
|
3595
|
-
const len = binaryString.length;
|
|
3596
|
-
const bytes = new Uint8Array(len);
|
|
3597
|
-
for (let i = 0; i < len; i++) {
|
|
3598
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
3599
|
-
}
|
|
3600
|
-
return bytes.buffer;
|
|
3601
|
-
}
|
|
3602
3607
|
|
|
3603
3608
|
// src/shared-assets/MockSharedAssetsApi.ts
|
|
3604
3609
|
var MockSharedAssetsApi = class {
|
|
@@ -3606,57 +3611,253 @@ var MockSharedAssetsApi = class {
|
|
|
3606
3611
|
__publicField(this, "venusApi");
|
|
3607
3612
|
this.venusApi = venusApi;
|
|
3608
3613
|
}
|
|
3609
|
-
async
|
|
3610
|
-
const blob = await this.venusApi.cdn.fetchBlob(
|
|
3611
|
-
return await blob.arrayBuffer();
|
|
3612
|
-
}
|
|
3613
|
-
async loadCharactersBundle() {
|
|
3614
|
-
const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
|
|
3614
|
+
async loadAssetsBundle(game, bundleKey, fileType = "stow") {
|
|
3615
|
+
const blob = await this.venusApi.cdn.fetchBlob(`${game}/${bundleKey}.${fileType}`);
|
|
3615
3616
|
return await blob.arrayBuffer();
|
|
3616
3617
|
}
|
|
3617
3618
|
};
|
|
3618
3619
|
|
|
3620
|
+
// src/shared-assets/embeddedLibrariesManifest.ts
|
|
3621
|
+
var DEFAULT_SHARED_LIB_CDN_BASE = "https://venus-static-01293ak.web.app/libs";
|
|
3622
|
+
var EMBEDDED_LIBRARIES = [
|
|
3623
|
+
{
|
|
3624
|
+
libraryKey: "phaser@3.90.0",
|
|
3625
|
+
assetKey: "library:phaser@3.90.0",
|
|
3626
|
+
packageName: "phaser",
|
|
3627
|
+
version: "3.90.0",
|
|
3628
|
+
globalVar: "Phaser",
|
|
3629
|
+
cdnPath: "phaser/3.90.0/phaser.min.js",
|
|
3630
|
+
moduleSpecifiers: [{ match: "exact", value: "phaser" }],
|
|
3631
|
+
loadStage: 0,
|
|
3632
|
+
enabled: true
|
|
3633
|
+
},
|
|
3634
|
+
{
|
|
3635
|
+
libraryKey: "react@18.3.1",
|
|
3636
|
+
assetKey: "library:react@18.3.1",
|
|
3637
|
+
packageName: "react",
|
|
3638
|
+
version: "18.3.1",
|
|
3639
|
+
globalVar: "React",
|
|
3640
|
+
cdnPath: "react/18.3.1/react.production.min.js",
|
|
3641
|
+
moduleSpecifiers: [
|
|
3642
|
+
{ match: "exact", value: "react", behavior: "namespace" },
|
|
3643
|
+
{ match: "exact", value: "react/jsx-runtime", behavior: "react-jsx-runtime" },
|
|
3644
|
+
{
|
|
3645
|
+
match: "exact",
|
|
3646
|
+
value: "react/jsx-dev-runtime",
|
|
3647
|
+
behavior: "react-jsx-dev-runtime"
|
|
3648
|
+
}
|
|
3649
|
+
],
|
|
3650
|
+
loadStage: 0,
|
|
3651
|
+
// Must load before ReactDOM
|
|
3652
|
+
enabled: true
|
|
3653
|
+
},
|
|
3654
|
+
{
|
|
3655
|
+
libraryKey: "react-dom@18.3.1",
|
|
3656
|
+
assetKey: "library:react-dom@18.3.1",
|
|
3657
|
+
packageName: "react-dom",
|
|
3658
|
+
version: "18.3.1",
|
|
3659
|
+
globalVar: "ReactDOM",
|
|
3660
|
+
cdnPath: "react-dom/18.3.1/react-dom.production.min.js",
|
|
3661
|
+
moduleSpecifiers: [
|
|
3662
|
+
{ match: "exact", value: "react-dom", behavior: "namespace" },
|
|
3663
|
+
{ match: "exact", value: "react-dom/client", behavior: "namespace" }
|
|
3664
|
+
],
|
|
3665
|
+
loadStage: 1,
|
|
3666
|
+
// Depends on React (stage 0)
|
|
3667
|
+
enabled: true
|
|
3668
|
+
},
|
|
3669
|
+
{
|
|
3670
|
+
libraryKey: "three@0.170.0",
|
|
3671
|
+
assetKey: "library:three@0.170.0",
|
|
3672
|
+
packageName: "three",
|
|
3673
|
+
version: "0.170.0",
|
|
3674
|
+
globalVar: "THREE",
|
|
3675
|
+
cdnPath: "three/r170/three.min.js",
|
|
3676
|
+
moduleSpecifiers: [
|
|
3677
|
+
{ match: "exact", value: "three", behavior: "namespace" },
|
|
3678
|
+
{ match: "prefix", value: "three/examples/jsm/", behavior: "namespace" }
|
|
3679
|
+
],
|
|
3680
|
+
loadStage: 0,
|
|
3681
|
+
enabled: true
|
|
3682
|
+
},
|
|
3683
|
+
{
|
|
3684
|
+
libraryKey: "matter-js@0.19.0",
|
|
3685
|
+
assetKey: "library:matter-js@0.19.0",
|
|
3686
|
+
packageName: "matter-js",
|
|
3687
|
+
version: "0.19.0",
|
|
3688
|
+
globalVar: "Matter",
|
|
3689
|
+
cdnPath: "matter-js/0.19.0/matter.min.js",
|
|
3690
|
+
moduleSpecifiers: [{ match: "exact", value: "matter-js" }],
|
|
3691
|
+
loadStage: 0,
|
|
3692
|
+
enabled: true
|
|
3693
|
+
},
|
|
3694
|
+
{
|
|
3695
|
+
libraryKey: "inkjs@2.2.0",
|
|
3696
|
+
assetKey: "library:inkjs@2.2.0",
|
|
3697
|
+
packageName: "inkjs",
|
|
3698
|
+
version: "2.2.0",
|
|
3699
|
+
globalVar: "inkjs",
|
|
3700
|
+
cdnPath: "inkjs/2.2.0/ink.min.js",
|
|
3701
|
+
moduleSpecifiers: [{ match: "exact", value: "inkjs" }],
|
|
3702
|
+
loadStage: 0,
|
|
3703
|
+
enabled: true
|
|
3704
|
+
},
|
|
3705
|
+
{
|
|
3706
|
+
libraryKey: "zustand@5.0.3",
|
|
3707
|
+
assetKey: "library:zustand@5.0.3",
|
|
3708
|
+
packageName: "zustand",
|
|
3709
|
+
version: "5.0.3",
|
|
3710
|
+
globalVar: "zustand",
|
|
3711
|
+
cdnPath: "zustand/5.0.3/zustand.min.js",
|
|
3712
|
+
moduleSpecifiers: [
|
|
3713
|
+
{ match: "exact", value: "zustand" },
|
|
3714
|
+
{ match: "exact", value: "zustand/middleware" }
|
|
3715
|
+
],
|
|
3716
|
+
loadStage: 0,
|
|
3717
|
+
enabled: true
|
|
3718
|
+
},
|
|
3719
|
+
{
|
|
3720
|
+
libraryKey: "ammo.js@2024.11",
|
|
3721
|
+
assetKey: "library:ammo.js@2024.11",
|
|
3722
|
+
packageName: "ammo.js",
|
|
3723
|
+
version: "2024.11",
|
|
3724
|
+
globalVar: "Ammo",
|
|
3725
|
+
cdnPath: "ammo/2024.11/ammo.js",
|
|
3726
|
+
moduleSpecifiers: [
|
|
3727
|
+
{ match: "exact", value: "ammo.js" },
|
|
3728
|
+
{ match: "exact", value: "ammo.js/builds/ammo.wasm.js" }
|
|
3729
|
+
],
|
|
3730
|
+
loadStage: 0,
|
|
3731
|
+
enabled: false
|
|
3732
|
+
// Not ready yet - WASM loading needs additional work
|
|
3733
|
+
}
|
|
3734
|
+
];
|
|
3735
|
+
var EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARIES.reduce(
|
|
3736
|
+
(acc, lib) => {
|
|
3737
|
+
acc[lib.libraryKey] = lib;
|
|
3738
|
+
return acc;
|
|
3739
|
+
},
|
|
3740
|
+
{}
|
|
3741
|
+
);
|
|
3742
|
+
var MODULE_TO_LIBRARY_SPECIFIERS = EMBEDDED_LIBRARIES.filter(
|
|
3743
|
+
(lib) => lib.enabled
|
|
3744
|
+
).flatMap(
|
|
3745
|
+
(lib) => lib.moduleSpecifiers.map((specifier) => ({
|
|
3746
|
+
...specifier,
|
|
3747
|
+
libraryKey: lib.libraryKey
|
|
3748
|
+
}))
|
|
3749
|
+
);
|
|
3750
|
+
function getLibraryDefinition(libraryKey) {
|
|
3751
|
+
const definition = EMBEDDED_LIBRARY_BY_KEY[libraryKey];
|
|
3752
|
+
if (!definition) {
|
|
3753
|
+
const availableKeys = Object.keys(EMBEDDED_LIBRARY_BY_KEY).join(", ");
|
|
3754
|
+
throw new Error(
|
|
3755
|
+
`Unsupported embedded library: ${libraryKey}. Available libraries: ${availableKeys}`
|
|
3756
|
+
);
|
|
3757
|
+
}
|
|
3758
|
+
return definition;
|
|
3759
|
+
}
|
|
3760
|
+
|
|
3761
|
+
// src/leaderboard/utils.ts
|
|
3762
|
+
var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
|
|
3763
|
+
var HASH_ALGORITHM_NODE = "sha256";
|
|
3764
|
+
async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
|
|
3765
|
+
const payload = `score:${score}|duration:${duration}|token:${token}`;
|
|
3766
|
+
const fullPayload = `${payload}|nonce:${sealingNonce}`;
|
|
3767
|
+
const encoder = new TextEncoder();
|
|
3768
|
+
const keyData = encoder.encode(sealingSecret);
|
|
3769
|
+
const messageData = encoder.encode(fullPayload);
|
|
3770
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
3771
|
+
"raw",
|
|
3772
|
+
keyData,
|
|
3773
|
+
{ name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
|
|
3774
|
+
false,
|
|
3775
|
+
["sign"]
|
|
3776
|
+
);
|
|
3777
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
|
|
3778
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3779
|
+
}
|
|
3780
|
+
|
|
3619
3781
|
// src/leaderboard/RpcLeaderboardApi.ts
|
|
3620
3782
|
var RpcLeaderboardApi = class {
|
|
3621
3783
|
constructor(rpcClient) {
|
|
3622
3784
|
__publicField(this, "rpcClient");
|
|
3785
|
+
/** Cache of score tokens for automatic hash computation */
|
|
3786
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
3623
3787
|
this.rpcClient = rpcClient;
|
|
3624
3788
|
}
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3789
|
+
/**
|
|
3790
|
+
* Create a score token for submitting a score.
|
|
3791
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
3792
|
+
*
|
|
3793
|
+
* @param mode - Optional game mode
|
|
3794
|
+
* @returns Score token with sealing data if enabled
|
|
3795
|
+
*/
|
|
3796
|
+
async createScoreToken(mode) {
|
|
3797
|
+
const token = await this.rpcClient.call(
|
|
3798
|
+
"H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
|
|
3628
3799
|
mode ? { mode } : {}
|
|
3629
3800
|
);
|
|
3801
|
+
this.tokenCache.set(token.token, token);
|
|
3802
|
+
return token;
|
|
3630
3803
|
}
|
|
3631
|
-
|
|
3804
|
+
/**
|
|
3805
|
+
* Submit a score to the leaderboard.
|
|
3806
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
3807
|
+
*
|
|
3808
|
+
* @param params - Score submission parameters
|
|
3809
|
+
* @returns Submission result with acceptance status and rank
|
|
3810
|
+
* @throws Error if token not found in cache
|
|
3811
|
+
*/
|
|
3812
|
+
async submitScore(params) {
|
|
3813
|
+
let hash;
|
|
3814
|
+
if (params.token) {
|
|
3815
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
3816
|
+
if (!cachedToken) {
|
|
3817
|
+
throw new Error(
|
|
3818
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
3819
|
+
);
|
|
3820
|
+
}
|
|
3821
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
3822
|
+
hash = await computeScoreHash(
|
|
3823
|
+
params.score,
|
|
3824
|
+
params.duration,
|
|
3825
|
+
params.token,
|
|
3826
|
+
cachedToken.sealingNonce,
|
|
3827
|
+
cachedToken.sealingSecret
|
|
3828
|
+
);
|
|
3829
|
+
}
|
|
3830
|
+
this.tokenCache.delete(params.token);
|
|
3831
|
+
}
|
|
3632
3832
|
return this.rpcClient.call(
|
|
3633
3833
|
"H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
|
|
3634
3834
|
{
|
|
3635
|
-
|
|
3636
|
-
score,
|
|
3637
|
-
|
|
3638
|
-
mode:
|
|
3639
|
-
telemetry:
|
|
3640
|
-
metadata:
|
|
3641
|
-
hash
|
|
3835
|
+
token: params.token,
|
|
3836
|
+
score: params.score,
|
|
3837
|
+
duration: params.duration,
|
|
3838
|
+
mode: params.mode,
|
|
3839
|
+
telemetry: params.telemetry,
|
|
3840
|
+
metadata: params.metadata,
|
|
3841
|
+
hash
|
|
3842
|
+
// undefined if no sealing, computed if sealing enabled
|
|
3642
3843
|
}
|
|
3643
3844
|
);
|
|
3644
3845
|
}
|
|
3645
|
-
|
|
3846
|
+
getPagedScores(options) {
|
|
3646
3847
|
return this.rpcClient.call(
|
|
3647
|
-
"
|
|
3848
|
+
"H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
|
|
3648
3849
|
options ?? {}
|
|
3649
3850
|
);
|
|
3650
3851
|
}
|
|
3651
|
-
|
|
3852
|
+
getMyRank(options) {
|
|
3652
3853
|
return this.rpcClient.call(
|
|
3653
|
-
"
|
|
3854
|
+
"H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
|
|
3654
3855
|
options ?? {}
|
|
3655
3856
|
);
|
|
3656
3857
|
}
|
|
3657
|
-
|
|
3858
|
+
getPodiumScores(options) {
|
|
3658
3859
|
return this.rpcClient.call(
|
|
3659
|
-
"
|
|
3860
|
+
"H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
|
|
3660
3861
|
options ?? {}
|
|
3661
3862
|
);
|
|
3662
3863
|
}
|
|
@@ -3665,17 +3866,31 @@ var RpcLeaderboardApi = class {
|
|
|
3665
3866
|
// src/leaderboard/MockLeaderboardApi.ts
|
|
3666
3867
|
var MockLeaderboardApi = class {
|
|
3667
3868
|
constructor(options) {
|
|
3668
|
-
__publicField(this, "
|
|
3869
|
+
__publicField(this, "tokens", /* @__PURE__ */ new Map());
|
|
3870
|
+
/** Cache of score tokens for automatic hash computation */
|
|
3871
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
3669
3872
|
__publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
|
|
3670
|
-
__publicField(this, "
|
|
3671
|
-
__publicField(this, "
|
|
3672
|
-
|
|
3673
|
-
|
|
3873
|
+
__publicField(this, "tokenCounter", 0);
|
|
3874
|
+
__publicField(this, "enableScoreSealing", false);
|
|
3875
|
+
__publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
|
|
3876
|
+
if (options?.enableScoreSealing) {
|
|
3877
|
+
this.enableScoreSealing = true;
|
|
3878
|
+
}
|
|
3879
|
+
if (options?.scoreSealingSecret) {
|
|
3880
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
3674
3881
|
}
|
|
3675
3882
|
}
|
|
3883
|
+
/**
|
|
3884
|
+
* Configure mock leaderboard settings
|
|
3885
|
+
*
|
|
3886
|
+
* @param options - Configuration options
|
|
3887
|
+
*/
|
|
3676
3888
|
configure(options) {
|
|
3677
|
-
if (typeof options.
|
|
3678
|
-
this.
|
|
3889
|
+
if (typeof options.enableScoreSealing === "boolean") {
|
|
3890
|
+
this.enableScoreSealing = options.enableScoreSealing;
|
|
3891
|
+
}
|
|
3892
|
+
if (options.scoreSealingSecret) {
|
|
3893
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
3679
3894
|
}
|
|
3680
3895
|
}
|
|
3681
3896
|
generateNonce() {
|
|
@@ -3692,83 +3907,149 @@ var MockLeaderboardApi = class {
|
|
|
3692
3907
|
}
|
|
3693
3908
|
return this.entriesByMode.get(key);
|
|
3694
3909
|
}
|
|
3695
|
-
|
|
3696
|
-
|
|
3910
|
+
/**
|
|
3911
|
+
* Create a mock score token for testing.
|
|
3912
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
3913
|
+
*
|
|
3914
|
+
* @param mode - Optional game mode
|
|
3915
|
+
* @returns Score token with sealing data if enabled
|
|
3916
|
+
*/
|
|
3917
|
+
async createScoreToken(mode) {
|
|
3918
|
+
const token = `mock_token_${++this.tokenCounter}`;
|
|
3697
3919
|
const startTime = Date.now();
|
|
3698
3920
|
const expiresAt = startTime + 36e5;
|
|
3699
3921
|
const resolvedMode = mode || "default";
|
|
3700
|
-
const
|
|
3701
|
-
this.
|
|
3702
|
-
|
|
3922
|
+
const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
|
|
3923
|
+
const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
|
|
3924
|
+
this.tokens.set(token, {
|
|
3925
|
+
id: token,
|
|
3703
3926
|
expiresAt,
|
|
3704
3927
|
mode: resolvedMode,
|
|
3705
|
-
|
|
3928
|
+
sealingNonce,
|
|
3706
3929
|
used: false
|
|
3707
3930
|
});
|
|
3708
|
-
|
|
3709
|
-
|
|
3931
|
+
const result = {
|
|
3932
|
+
token,
|
|
3710
3933
|
startTime,
|
|
3711
3934
|
expiresAt,
|
|
3712
|
-
|
|
3935
|
+
sealingNonce,
|
|
3936
|
+
sealingSecret,
|
|
3713
3937
|
mode: resolvedMode
|
|
3714
3938
|
};
|
|
3939
|
+
this.tokenCache.set(token, result);
|
|
3940
|
+
return result;
|
|
3715
3941
|
}
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3942
|
+
/**
|
|
3943
|
+
* Submit a mock score to the leaderboard.
|
|
3944
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
3945
|
+
*
|
|
3946
|
+
* @param params - Score submission parameters
|
|
3947
|
+
* @returns Submission result with acceptance status and rank
|
|
3948
|
+
* @throws Error if token not found in cache or validation fails
|
|
3949
|
+
*/
|
|
3950
|
+
async submitScore(params) {
|
|
3951
|
+
let hash;
|
|
3952
|
+
if (params.token) {
|
|
3953
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
3954
|
+
if (!cachedToken) {
|
|
3955
|
+
throw new Error(
|
|
3956
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
3957
|
+
);
|
|
3958
|
+
}
|
|
3959
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
3960
|
+
hash = await computeScoreHash(
|
|
3961
|
+
params.score,
|
|
3962
|
+
params.duration,
|
|
3963
|
+
params.token,
|
|
3964
|
+
cachedToken.sealingNonce,
|
|
3965
|
+
cachedToken.sealingSecret
|
|
3966
|
+
);
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
if (!params.token) {
|
|
3970
|
+
const mode = params.mode || "default";
|
|
3971
|
+
const submittedAt2 = Date.now();
|
|
3972
|
+
const entry2 = {
|
|
3973
|
+
profileId: `mock_profile`,
|
|
3974
|
+
username: "Mock Player",
|
|
3975
|
+
avatarUrl: null,
|
|
3976
|
+
score: params.score,
|
|
3977
|
+
duration: params.duration,
|
|
3978
|
+
submittedAt: submittedAt2,
|
|
3979
|
+
token: "simple-mode",
|
|
3980
|
+
rank: null,
|
|
3981
|
+
zScore: null,
|
|
3982
|
+
isAnomaly: false,
|
|
3983
|
+
trustScore: 50,
|
|
3984
|
+
metadata: params.metadata ?? null,
|
|
3985
|
+
isSeed: false
|
|
3986
|
+
};
|
|
3987
|
+
const modeEntries2 = this.getEntriesForMode(mode);
|
|
3988
|
+
modeEntries2.push(entry2);
|
|
3989
|
+
modeEntries2.sort((a, b) => {
|
|
3990
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
3991
|
+
return a.submittedAt - b.submittedAt;
|
|
3992
|
+
});
|
|
3993
|
+
modeEntries2.forEach((e, index) => {
|
|
3994
|
+
modeEntries2[index] = { ...e, rank: index + 1 };
|
|
3995
|
+
});
|
|
3996
|
+
const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
|
|
3997
|
+
return {
|
|
3998
|
+
accepted: true,
|
|
3999
|
+
rank: inserted2?.rank ?? null
|
|
4000
|
+
};
|
|
4001
|
+
}
|
|
4002
|
+
const scoreToken = this.tokens.get(params.token);
|
|
4003
|
+
if (!scoreToken) {
|
|
4004
|
+
throw new Error("Invalid score token");
|
|
3720
4005
|
}
|
|
3721
|
-
if (
|
|
3722
|
-
throw new Error("Invalid or expired
|
|
4006
|
+
if (scoreToken.expiresAt < Date.now()) {
|
|
4007
|
+
throw new Error("Invalid or expired score token");
|
|
3723
4008
|
}
|
|
3724
|
-
if (
|
|
3725
|
-
throw new Error("
|
|
4009
|
+
if (scoreToken.used) {
|
|
4010
|
+
throw new Error("Score token already used");
|
|
3726
4011
|
}
|
|
3727
|
-
if (
|
|
3728
|
-
throw new Error("Submission mode does not match
|
|
4012
|
+
if (params.mode && params.mode !== scoreToken.mode) {
|
|
4013
|
+
throw new Error("Submission mode does not match token mode");
|
|
3729
4014
|
}
|
|
3730
|
-
if (
|
|
3731
|
-
throw new Error("Score hash
|
|
4015
|
+
if (scoreToken.sealingNonce && !hash) {
|
|
4016
|
+
throw new Error("Score hash required when score sealing is enabled");
|
|
3732
4017
|
}
|
|
3733
4018
|
const submittedAt = Date.now();
|
|
3734
4019
|
const entry = {
|
|
3735
4020
|
profileId: `mock_profile`,
|
|
3736
4021
|
username: "Mock Player",
|
|
3737
4022
|
avatarUrl: null,
|
|
3738
|
-
score,
|
|
3739
|
-
|
|
4023
|
+
score: params.score,
|
|
4024
|
+
duration: params.duration,
|
|
3740
4025
|
submittedAt,
|
|
3741
|
-
|
|
4026
|
+
token: params.token,
|
|
3742
4027
|
rank: null,
|
|
3743
4028
|
zScore: null,
|
|
3744
4029
|
isAnomaly: false,
|
|
3745
4030
|
trustScore: 50,
|
|
3746
|
-
metadata:
|
|
4031
|
+
metadata: params.metadata ?? null,
|
|
3747
4032
|
isSeed: false
|
|
3748
4033
|
};
|
|
3749
|
-
const modeEntries = this.getEntriesForMode(
|
|
4034
|
+
const modeEntries = this.getEntriesForMode(scoreToken.mode);
|
|
3750
4035
|
modeEntries.push(entry);
|
|
3751
4036
|
modeEntries.sort((a, b) => {
|
|
3752
|
-
if (b.score !== a.score)
|
|
3753
|
-
return b.score - a.score;
|
|
3754
|
-
}
|
|
4037
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
3755
4038
|
return a.submittedAt - b.submittedAt;
|
|
3756
4039
|
});
|
|
3757
4040
|
modeEntries.forEach((e, index) => {
|
|
3758
|
-
modeEntries[index] = {
|
|
3759
|
-
...e,
|
|
3760
|
-
rank: index + 1
|
|
3761
|
-
};
|
|
4041
|
+
modeEntries[index] = { ...e, rank: index + 1 };
|
|
3762
4042
|
});
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
4043
|
+
scoreToken.used = true;
|
|
4044
|
+
scoreToken.sealingNonce = null;
|
|
4045
|
+
this.tokenCache.delete(params.token);
|
|
4046
|
+
const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
|
|
3766
4047
|
return {
|
|
3767
4048
|
accepted: true,
|
|
3768
4049
|
rank: inserted?.rank ?? null
|
|
3769
4050
|
};
|
|
3770
4051
|
}
|
|
3771
|
-
async
|
|
4052
|
+
async getPagedScores(options) {
|
|
3772
4053
|
const limit = options?.limit ?? 10;
|
|
3773
4054
|
const mode = options?.mode ?? "default";
|
|
3774
4055
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
@@ -3784,7 +4065,7 @@ var MockLeaderboardApi = class {
|
|
|
3784
4065
|
periodInstance: options?.period ?? "alltime"
|
|
3785
4066
|
};
|
|
3786
4067
|
}
|
|
3787
|
-
async
|
|
4068
|
+
async getMyRank(_options) {
|
|
3788
4069
|
const mode = _options?.mode ?? "default";
|
|
3789
4070
|
const modeEntries = this.getEntriesForMode(mode);
|
|
3790
4071
|
const playerEntry = modeEntries[0] ?? null;
|
|
@@ -3797,7 +4078,7 @@ var MockLeaderboardApi = class {
|
|
|
3797
4078
|
periodInstance: _options?.period ?? "alltime"
|
|
3798
4079
|
};
|
|
3799
4080
|
}
|
|
3800
|
-
async
|
|
4081
|
+
async getPodiumScores(options) {
|
|
3801
4082
|
const mode = options?.mode ?? "default";
|
|
3802
4083
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
3803
4084
|
const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
|
|
@@ -3865,117 +4146,28 @@ var MockPreloaderApi = class {
|
|
|
3865
4146
|
};
|
|
3866
4147
|
|
|
3867
4148
|
// src/game-preloader/RpcPreloaderApi.ts
|
|
3868
|
-
var RpcPreloaderApi = class {
|
|
3869
|
-
constructor(rpcClient) {
|
|
3870
|
-
__publicField(this, "rpcClient");
|
|
3871
|
-
this.rpcClient = rpcClient;
|
|
3872
|
-
}
|
|
3873
|
-
async showLoadScreen() {
|
|
3874
|
-
await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
|
|
3875
|
-
}
|
|
3876
|
-
async hideLoadScreen() {
|
|
3877
|
-
await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
|
|
3878
|
-
}
|
|
3879
|
-
async setLoaderText(text) {
|
|
3880
|
-
await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
|
|
3881
|
-
}
|
|
3882
|
-
async setLoaderProgress(progress) {
|
|
3883
|
-
await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
|
|
3884
|
-
}
|
|
3885
|
-
};
|
|
3886
|
-
|
|
3887
|
-
// src/game-preloader/index.ts
|
|
3888
|
-
function initializePreloader(venusApi, host) {
|
|
3889
|
-
venusApi.preloader = host.preloader;
|
|
3890
|
-
}
|
|
3891
|
-
|
|
3892
|
-
// src/post/MockPostApi.ts
|
|
3893
|
-
var MockPostApi = class {
|
|
3894
|
-
constructor(venusApi) {
|
|
3895
|
-
__publicField(this, "venusApi");
|
|
3896
|
-
this.venusApi = venusApi;
|
|
3897
|
-
}
|
|
3898
|
-
async getPostInfo() {
|
|
3899
|
-
const venusApi = this.venusApi;
|
|
3900
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3901
|
-
return venusApi._mock.currentPostInteractions;
|
|
3902
|
-
}
|
|
3903
|
-
async openCommentsAsync() {
|
|
3904
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3905
|
-
return {
|
|
3906
|
-
opened: true,
|
|
3907
|
-
commentsCount: 0
|
|
3908
|
-
};
|
|
3909
|
-
}
|
|
3910
|
-
async toggleFollowAsync() {
|
|
3911
|
-
const venusApi = this.venusApi;
|
|
3912
|
-
console.log("[Venus Mock] *Toggling follow status");
|
|
3913
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3914
|
-
venusApi._mock.currentPostInteractions.isFollowing = !venusApi._mock.currentPostInteractions.isFollowing;
|
|
3915
|
-
const isFollowing = venusApi._mock.currentPostInteractions.isFollowing;
|
|
3916
|
-
return {
|
|
3917
|
-
isFollowing,
|
|
3918
|
-
action: isFollowing ? "followed" : "unfollowed"
|
|
3919
|
-
};
|
|
3920
|
-
}
|
|
3921
|
-
async toggleLikeAsync() {
|
|
3922
|
-
const venusApi = this.venusApi;
|
|
3923
|
-
await createMockDelay(MOCK_DELAYS.short);
|
|
3924
|
-
venusApi._mock.currentPostInteractions.isLiked = !venusApi._mock.currentPostInteractions.isLiked;
|
|
3925
|
-
const isLiked = venusApi._mock.currentPostInteractions.isLiked;
|
|
3926
|
-
if (isLiked) {
|
|
3927
|
-
venusApi._mock.currentPostInteractions.likesCount++;
|
|
3928
|
-
} else {
|
|
3929
|
-
venusApi._mock.currentPostInteractions.likesCount = Math.max(
|
|
3930
|
-
0,
|
|
3931
|
-
venusApi._mock.currentPostInteractions.likesCount - 1
|
|
3932
|
-
);
|
|
3933
|
-
}
|
|
3934
|
-
return {
|
|
3935
|
-
isLiked,
|
|
3936
|
-
likesCount: venusApi._mock.currentPostInteractions.likesCount,
|
|
3937
|
-
action: isLiked ? "liked" : "unliked"
|
|
3938
|
-
};
|
|
3939
|
-
}
|
|
3940
|
-
};
|
|
3941
|
-
|
|
3942
|
-
// src/post/RpcPostApi.ts
|
|
3943
|
-
var RpcPostApi = class {
|
|
4149
|
+
var RpcPreloaderApi = class {
|
|
3944
4150
|
constructor(rpcClient) {
|
|
3945
4151
|
__publicField(this, "rpcClient");
|
|
3946
4152
|
this.rpcClient = rpcClient;
|
|
3947
4153
|
}
|
|
3948
|
-
|
|
3949
|
-
|
|
4154
|
+
async showLoadScreen() {
|
|
4155
|
+
await this.rpcClient.call("H5_SHOW_LOAD_SCREEN" /* H5_SHOW_LOAD_SCREEN */);
|
|
3950
4156
|
}
|
|
3951
|
-
|
|
3952
|
-
|
|
4157
|
+
async hideLoadScreen() {
|
|
4158
|
+
await this.rpcClient.call("H5_HIDE_LOAD_SCREEN" /* H5_HIDE_LOAD_SCREEN */);
|
|
3953
4159
|
}
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
"H5_TOGGLE_FOLLOW" /* TOGGLE_FOLLOW */,
|
|
3957
|
-
{}
|
|
3958
|
-
);
|
|
4160
|
+
async setLoaderText(text) {
|
|
4161
|
+
await this.rpcClient.call("H5_SET_LOADER_TEXT" /* H5_SET_LOADER_TEXT */, { text });
|
|
3959
4162
|
}
|
|
3960
|
-
|
|
3961
|
-
|
|
4163
|
+
async setLoaderProgress(progress) {
|
|
4164
|
+
await this.rpcClient.call("H5_SET_LOADER_PROGRESS" /* H5_SET_LOADER_PROGRESS */, { progress });
|
|
3962
4165
|
}
|
|
3963
4166
|
};
|
|
3964
4167
|
|
|
3965
|
-
// src/
|
|
3966
|
-
function
|
|
3967
|
-
venusApi.
|
|
3968
|
-
return host.post.getPostInfo();
|
|
3969
|
-
};
|
|
3970
|
-
venusApi.toggleFollowAsync = () => {
|
|
3971
|
-
return host.post.toggleFollowAsync();
|
|
3972
|
-
};
|
|
3973
|
-
venusApi.toggleLikeAsync = () => {
|
|
3974
|
-
return host.post.toggleLikeAsync();
|
|
3975
|
-
};
|
|
3976
|
-
venusApi.openCommentsAsync = async () => {
|
|
3977
|
-
await host.post.openCommentsAsync();
|
|
3978
|
-
};
|
|
4168
|
+
// src/game-preloader/index.ts
|
|
4169
|
+
function initializePreloader(venusApi, host) {
|
|
4170
|
+
venusApi.preloader = host.preloader;
|
|
3979
4171
|
}
|
|
3980
4172
|
|
|
3981
4173
|
// src/social/MockSocialApi.ts
|
|
@@ -4080,6 +4272,16 @@ var VenusTransport = class {
|
|
|
4080
4272
|
this.isProcessingMessage = false;
|
|
4081
4273
|
return;
|
|
4082
4274
|
}
|
|
4275
|
+
if (message.type === "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */) {
|
|
4276
|
+
const notification = {
|
|
4277
|
+
type: "rpc-notification",
|
|
4278
|
+
id: message.type,
|
|
4279
|
+
payload: message.data
|
|
4280
|
+
};
|
|
4281
|
+
this.handleNotification(notification);
|
|
4282
|
+
this.isProcessingMessage = false;
|
|
4283
|
+
return;
|
|
4284
|
+
}
|
|
4083
4285
|
const requestId = messageData.requestId;
|
|
4084
4286
|
if (!requestId) {
|
|
4085
4287
|
this.logWarn("No requestId. Ignoring message...");
|
|
@@ -4246,294 +4448,6 @@ var VenusTransport = class {
|
|
|
4246
4448
|
}
|
|
4247
4449
|
};
|
|
4248
4450
|
|
|
4249
|
-
// src/RemoteHost.ts
|
|
4250
|
-
init_rooms();
|
|
4251
|
-
|
|
4252
|
-
// src/rooms/RpcRoomsApi.ts
|
|
4253
|
-
init_VenusRoom();
|
|
4254
|
-
var RpcRoomsApi = class {
|
|
4255
|
-
constructor(rpcClient) {
|
|
4256
|
-
__publicField(this, "rpcClient");
|
|
4257
|
-
__publicField(this, "subscriptions");
|
|
4258
|
-
__publicField(this, "transportSubscription", null);
|
|
4259
|
-
this.rpcClient = rpcClient;
|
|
4260
|
-
this.subscriptions = {
|
|
4261
|
-
data: {},
|
|
4262
|
-
messages: {},
|
|
4263
|
-
gameEvents: {},
|
|
4264
|
-
allEvents: {}
|
|
4265
|
-
};
|
|
4266
|
-
}
|
|
4267
|
-
/**
|
|
4268
|
-
* Get the subscription state for external access (used by setupRoomNotifications)
|
|
4269
|
-
*/
|
|
4270
|
-
getSubscriptions() {
|
|
4271
|
-
return this.subscriptions;
|
|
4272
|
-
}
|
|
4273
|
-
/**
|
|
4274
|
-
* Set up room notification routing from the transport
|
|
4275
|
-
*/
|
|
4276
|
-
setupNotifications(transport) {
|
|
4277
|
-
const { setupRoomNotifications: setupRoomNotifications2 } = (init_rooms(), __toCommonJS(rooms_exports));
|
|
4278
|
-
this.transportSubscription = setupRoomNotifications2(
|
|
4279
|
-
transport,
|
|
4280
|
-
() => this.getSubscriptions()
|
|
4281
|
-
);
|
|
4282
|
-
}
|
|
4283
|
-
/**
|
|
4284
|
-
* Clean up subscriptions and resources
|
|
4285
|
-
*/
|
|
4286
|
-
dispose() {
|
|
4287
|
-
if (this.transportSubscription) {
|
|
4288
|
-
this.transportSubscription.unsubscribe();
|
|
4289
|
-
this.transportSubscription = null;
|
|
4290
|
-
console.log("[Venus Rooms] Cleaned up room notification subscription");
|
|
4291
|
-
}
|
|
4292
|
-
}
|
|
4293
|
-
async createRoom(options) {
|
|
4294
|
-
const response = await this.rpcClient.call(
|
|
4295
|
-
"H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
|
|
4296
|
-
{
|
|
4297
|
-
options
|
|
4298
|
-
}
|
|
4299
|
-
);
|
|
4300
|
-
if (response.success === false) {
|
|
4301
|
-
throw new Error(response.error || "Failed to create room");
|
|
4302
|
-
}
|
|
4303
|
-
const roomData = response.roomData || response;
|
|
4304
|
-
const room = new VenusRoom(roomData);
|
|
4305
|
-
return room;
|
|
4306
|
-
}
|
|
4307
|
-
async joinOrCreateRoom(options) {
|
|
4308
|
-
const response = await this.rpcClient.call(
|
|
4309
|
-
"H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
|
|
4310
|
-
{
|
|
4311
|
-
options
|
|
4312
|
-
}
|
|
4313
|
-
);
|
|
4314
|
-
if (response.success === false) {
|
|
4315
|
-
throw new Error(response.error || "Failed to join or create room");
|
|
4316
|
-
}
|
|
4317
|
-
const data = response.value || response;
|
|
4318
|
-
const room = new VenusRoom(data.roomData);
|
|
4319
|
-
return {
|
|
4320
|
-
action: data.action,
|
|
4321
|
-
room,
|
|
4322
|
-
playersJoined: data.playersJoined
|
|
4323
|
-
};
|
|
4324
|
-
}
|
|
4325
|
-
async joinRoomByCode(roomCode) {
|
|
4326
|
-
const response = await this.rpcClient.call(
|
|
4327
|
-
"H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
|
|
4328
|
-
{
|
|
4329
|
-
roomCode
|
|
4330
|
-
}
|
|
4331
|
-
);
|
|
4332
|
-
if (response?.success === false) {
|
|
4333
|
-
throw new Error(response.error || "Failed to join room by code");
|
|
4334
|
-
}
|
|
4335
|
-
const roomData = response.roomData || response;
|
|
4336
|
-
const room = new VenusRoom(roomData);
|
|
4337
|
-
return room;
|
|
4338
|
-
}
|
|
4339
|
-
// Get user's rooms with optional filtering
|
|
4340
|
-
async getUserRooms(includeArchived = false) {
|
|
4341
|
-
const response = await this.rpcClient.call(
|
|
4342
|
-
"H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
|
|
4343
|
-
{
|
|
4344
|
-
includeArchived
|
|
4345
|
-
}
|
|
4346
|
-
);
|
|
4347
|
-
if (response?.success === false) {
|
|
4348
|
-
throw new Error(response.error || "Failed to get user rooms");
|
|
4349
|
-
}
|
|
4350
|
-
const rawRooms = response.rooms || [];
|
|
4351
|
-
const venusRooms = [];
|
|
4352
|
-
for (const roomData of rawRooms) {
|
|
4353
|
-
if (!roomData.id) {
|
|
4354
|
-
console.warn("getUserRooms: Skipping room with missing ID:", roomData);
|
|
4355
|
-
continue;
|
|
4356
|
-
}
|
|
4357
|
-
try {
|
|
4358
|
-
const venusRoom = new VenusRoom(roomData);
|
|
4359
|
-
venusRooms.push(venusRoom);
|
|
4360
|
-
} catch (error) {
|
|
4361
|
-
console.warn(
|
|
4362
|
-
"getUserRooms: Failed to create VenusRoom object:",
|
|
4363
|
-
error,
|
|
4364
|
-
roomData
|
|
4365
|
-
);
|
|
4366
|
-
}
|
|
4367
|
-
}
|
|
4368
|
-
return venusRooms;
|
|
4369
|
-
}
|
|
4370
|
-
async updateData(room, updates, merge = true) {
|
|
4371
|
-
const response = await this.rpcClient.call(
|
|
4372
|
-
"H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
|
|
4373
|
-
{
|
|
4374
|
-
roomId: room.id,
|
|
4375
|
-
updates,
|
|
4376
|
-
merge
|
|
4377
|
-
}
|
|
4378
|
-
);
|
|
4379
|
-
if (response?.success === false) {
|
|
4380
|
-
throw new Error(response.error || "Failed to update room data");
|
|
4381
|
-
}
|
|
4382
|
-
return response.data;
|
|
4383
|
-
}
|
|
4384
|
-
async getData(room) {
|
|
4385
|
-
const response = await this.rpcClient.call(
|
|
4386
|
-
"H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
|
|
4387
|
-
{
|
|
4388
|
-
roomId: room.id
|
|
4389
|
-
}
|
|
4390
|
-
);
|
|
4391
|
-
if (response?.success === false) {
|
|
4392
|
-
throw new Error(response.error || "Failed to get room data");
|
|
4393
|
-
}
|
|
4394
|
-
return response.data;
|
|
4395
|
-
}
|
|
4396
|
-
async sendMessage(venusRoom, messageData) {
|
|
4397
|
-
const response = await this.rpcClient.call(
|
|
4398
|
-
"H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
|
|
4399
|
-
{
|
|
4400
|
-
roomId: venusRoom.id,
|
|
4401
|
-
message: messageData
|
|
4402
|
-
}
|
|
4403
|
-
);
|
|
4404
|
-
if (response?.success === false) {
|
|
4405
|
-
throw new Error(response.error || "Failed to send message");
|
|
4406
|
-
}
|
|
4407
|
-
return response.messageId;
|
|
4408
|
-
}
|
|
4409
|
-
async leave(room) {
|
|
4410
|
-
const response = await this.rpcClient.call(
|
|
4411
|
-
"H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
|
|
4412
|
-
{
|
|
4413
|
-
roomId: room.id
|
|
4414
|
-
}
|
|
4415
|
-
);
|
|
4416
|
-
if (response?.success === false) {
|
|
4417
|
-
throw new Error(response.error || "Failed to leave room");
|
|
4418
|
-
}
|
|
4419
|
-
return response;
|
|
4420
|
-
}
|
|
4421
|
-
async startGame(room, gameConfig = {}, turnOrder = null) {
|
|
4422
|
-
const response = await this.rpcClient.call(
|
|
4423
|
-
"H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
|
|
4424
|
-
{
|
|
4425
|
-
roomId: room.id,
|
|
4426
|
-
gameConfig,
|
|
4427
|
-
turnOrder
|
|
4428
|
-
}
|
|
4429
|
-
);
|
|
4430
|
-
if (response?.success === false) {
|
|
4431
|
-
throw new Error(response.error || "Failed to start game");
|
|
4432
|
-
}
|
|
4433
|
-
return response.data;
|
|
4434
|
-
}
|
|
4435
|
-
async proposeMove(room, proposalPayload) {
|
|
4436
|
-
const response = await this.rpcClient.call(
|
|
4437
|
-
"h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
|
|
4438
|
-
{
|
|
4439
|
-
roomId: room.id,
|
|
4440
|
-
gameSpecificState: proposalPayload.gameSpecificState,
|
|
4441
|
-
moveType: proposalPayload.moveType,
|
|
4442
|
-
clientContext: proposalPayload.clientContext,
|
|
4443
|
-
clientProposalId: proposalPayload.clientProposalId
|
|
4444
|
-
}
|
|
4445
|
-
);
|
|
4446
|
-
if (response?.success === false) {
|
|
4447
|
-
throw new Error(response.error || "Failed to propose move");
|
|
4448
|
-
}
|
|
4449
|
-
return response.data;
|
|
4450
|
-
}
|
|
4451
|
-
async validateMove(room, moveId, isValid, reason = null, validatorId = null) {
|
|
4452
|
-
console.log(`[Venus Rooms] Validating move ${moveId}: ${isValid}`);
|
|
4453
|
-
return { success: true, moveId, isValid, reason };
|
|
4454
|
-
}
|
|
4455
|
-
async roomSubscribeToGameEvents(room, callback) {
|
|
4456
|
-
"game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
4457
|
-
if (!this.subscriptions.gameEvents[room.id]) {
|
|
4458
|
-
this.subscriptions.gameEvents[room.id] = [];
|
|
4459
|
-
}
|
|
4460
|
-
this.subscriptions.gameEvents[room.id].push(callback);
|
|
4461
|
-
}
|
|
4462
|
-
subscribe(room, options = {}) {
|
|
4463
|
-
const subscriptionIds = [];
|
|
4464
|
-
const roomId = room.id;
|
|
4465
|
-
if (options.onData) {
|
|
4466
|
-
const dataSubId = "data_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
4467
|
-
if (!this.subscriptions.data[roomId]) {
|
|
4468
|
-
this.subscriptions.data[roomId] = [];
|
|
4469
|
-
}
|
|
4470
|
-
this.subscriptions.data[roomId].push(options.onData);
|
|
4471
|
-
subscriptionIds.push({
|
|
4472
|
-
type: "data",
|
|
4473
|
-
id: dataSubId,
|
|
4474
|
-
callback: options.onData
|
|
4475
|
-
});
|
|
4476
|
-
}
|
|
4477
|
-
if (options.onMessages) {
|
|
4478
|
-
const msgSubId = "messages_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
4479
|
-
if (!this.subscriptions.messages[roomId]) {
|
|
4480
|
-
this.subscriptions.messages[roomId] = [];
|
|
4481
|
-
}
|
|
4482
|
-
this.subscriptions.messages[roomId].push(options.onMessages);
|
|
4483
|
-
subscriptionIds.push({
|
|
4484
|
-
type: "messages",
|
|
4485
|
-
id: msgSubId,
|
|
4486
|
-
callback: options.onMessages
|
|
4487
|
-
});
|
|
4488
|
-
}
|
|
4489
|
-
if (options.onMoves || options.onGameEvents) {
|
|
4490
|
-
const handler = options.onMoves || options.onGameEvents;
|
|
4491
|
-
if (handler) {
|
|
4492
|
-
const gameSubId = "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
4493
|
-
if (!this.subscriptions.gameEvents[roomId]) {
|
|
4494
|
-
this.subscriptions.gameEvents[roomId] = [];
|
|
4495
|
-
}
|
|
4496
|
-
this.subscriptions.gameEvents[roomId].push(handler);
|
|
4497
|
-
subscriptionIds.push({
|
|
4498
|
-
type: "gameEvents",
|
|
4499
|
-
id: gameSubId,
|
|
4500
|
-
callback: handler
|
|
4501
|
-
});
|
|
4502
|
-
}
|
|
4503
|
-
}
|
|
4504
|
-
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;
|
|
4505
|
-
if (needsSubscription) {
|
|
4506
|
-
this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
|
|
4507
|
-
roomId,
|
|
4508
|
-
subscribeToData: !!options.onData,
|
|
4509
|
-
subscribeToMessages: !!options.onMessages,
|
|
4510
|
-
subscribeToProposedMoves: !!(options.onMoves || options.onGameEvents)
|
|
4511
|
-
}).catch((error) => {
|
|
4512
|
-
console.error("Failed to set up room subscription:", error);
|
|
4513
|
-
});
|
|
4514
|
-
}
|
|
4515
|
-
let called = false;
|
|
4516
|
-
return () => {
|
|
4517
|
-
if (called) return;
|
|
4518
|
-
called = true;
|
|
4519
|
-
subscriptionIds.forEach((sub) => {
|
|
4520
|
-
const bucket = this.subscriptions[sub.type];
|
|
4521
|
-
const callbacks = bucket && bucket[roomId] || [];
|
|
4522
|
-
const index = callbacks.indexOf(sub.callback);
|
|
4523
|
-
if (index > -1) callbacks.splice(index, 1);
|
|
4524
|
-
});
|
|
4525
|
-
const hasNoCallbacks = (this.subscriptions.data[roomId]?.length ?? 0) === 0 && (this.subscriptions.messages[roomId]?.length ?? 0) === 0 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) === 0;
|
|
4526
|
-
if (hasNoCallbacks) {
|
|
4527
|
-
this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
|
|
4528
|
-
roomId
|
|
4529
|
-
}).catch((error) => {
|
|
4530
|
-
console.error("Failed to clean up room subscription:", error);
|
|
4531
|
-
});
|
|
4532
|
-
}
|
|
4533
|
-
};
|
|
4534
|
-
}
|
|
4535
|
-
};
|
|
4536
|
-
|
|
4537
4451
|
// src/RemoteHost.ts
|
|
4538
4452
|
var getCdnBaseUrl = () => {
|
|
4539
4453
|
return "https://venus-static-01293ak.web.app/";
|
|
@@ -4550,9 +4464,9 @@ var RemoteHost = class {
|
|
|
4550
4464
|
__publicField(this, "notifications");
|
|
4551
4465
|
__publicField(this, "popups");
|
|
4552
4466
|
__publicField(this, "profile");
|
|
4467
|
+
__publicField(this, "system");
|
|
4553
4468
|
__publicField(this, "cdn");
|
|
4554
4469
|
__publicField(this, "time");
|
|
4555
|
-
__publicField(this, "post");
|
|
4556
4470
|
__publicField(this, "ai");
|
|
4557
4471
|
__publicField(this, "haptics");
|
|
4558
4472
|
__publicField(this, "features");
|
|
@@ -4606,10 +4520,12 @@ var RemoteHost = class {
|
|
|
4606
4520
|
this.navigation = new RpcNavigationApi(rpcClient, venusApi);
|
|
4607
4521
|
this.notifications = new RpcNotificationsApi(rpcClient);
|
|
4608
4522
|
this.popups = new RpcPopupsApi(rpcClient);
|
|
4609
|
-
this.profile = new HostProfileApi();
|
|
4523
|
+
this.profile = new HostProfileApi(venusApi);
|
|
4524
|
+
const deviceApi = new HostDeviceApi(venusApi);
|
|
4525
|
+
const environmentApi = new HostEnvironmentApi(venusApi);
|
|
4526
|
+
this.system = new HostSystemApi(deviceApi, environmentApi, venusApi);
|
|
4610
4527
|
this.cdn = new HostCdnApi(getCdnBaseUrl());
|
|
4611
|
-
this.time = new HostTimeApi(rpcClient);
|
|
4612
|
-
this.post = new RpcPostApi(rpcClient);
|
|
4528
|
+
this.time = new HostTimeApi(rpcClient, venusApi);
|
|
4613
4529
|
this.ai = new RpcAiApi(rpcClient);
|
|
4614
4530
|
this.haptics = new RpcHapticsApi(rpcClient);
|
|
4615
4531
|
this.features = new RpcFeaturesApi(rpcClient);
|
|
@@ -4624,7 +4540,6 @@ var RemoteHost = class {
|
|
|
4624
4540
|
venusApi.isMock = () => false;
|
|
4625
4541
|
this.venusApi.sharedAssets = new RpcSharedAssetsApi(rpcClient, venusApi);
|
|
4626
4542
|
initializeRoomsApi(this.venusApi, this);
|
|
4627
|
-
console.log("[Venus SDK] Remote host created");
|
|
4628
4543
|
}
|
|
4629
4544
|
get isInitialized() {
|
|
4630
4545
|
return this._isInitialized;
|
|
@@ -4642,36 +4557,28 @@ var RemoteHost = class {
|
|
|
4642
4557
|
5e3
|
|
4643
4558
|
);
|
|
4644
4559
|
transport.instanceId = response.instanceId;
|
|
4645
|
-
this.log(`Remote Host Initialized with id: ${transport.instanceId}`);
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
if (venus._config) {
|
|
4659
|
-
venus._config.profile = sanitizedProfile;
|
|
4660
|
-
}
|
|
4661
|
-
if (venus.config) {
|
|
4662
|
-
venus.config.profile = sanitizedProfile;
|
|
4663
|
-
}
|
|
4664
|
-
}
|
|
4665
|
-
}
|
|
4560
|
+
this.log(`Remote Host Initialized with id: ${transport.instanceId}, response: ${JSON.stringify(response)}`);
|
|
4561
|
+
const profile = response.profile;
|
|
4562
|
+
const sanitizedProfile = {
|
|
4563
|
+
id: profile.id,
|
|
4564
|
+
username: profile.username,
|
|
4565
|
+
avatarUrl: profile.avatarUrl ?? null,
|
|
4566
|
+
isAnonymous: Boolean(profile.isAnonymous)
|
|
4567
|
+
};
|
|
4568
|
+
this.venusApi._profileData = sanitizedProfile;
|
|
4569
|
+
this.venusApi._deviceData = response.device;
|
|
4570
|
+
this.venusApi._environmentData = response.environment;
|
|
4571
|
+
this.venusApi._localeData = response.locale;
|
|
4572
|
+
this.venusApi._languageCodeData = response.languageCode;
|
|
4666
4573
|
this._isInitialized = true;
|
|
4667
|
-
this.venusApi.launchParams = response.launchParams
|
|
4574
|
+
this.venusApi.launchParams = response.launchParams;
|
|
4668
4575
|
await this.rpcClient.call("READY" /* READY */, {});
|
|
4669
|
-
const
|
|
4670
|
-
if (
|
|
4671
|
-
this.venusApi.
|
|
4576
|
+
const safeArea = response.safeArea;
|
|
4577
|
+
if (safeArea) {
|
|
4578
|
+
this.venusApi._safeAreaData = safeArea;
|
|
4672
4579
|
}
|
|
4673
4580
|
return {
|
|
4674
|
-
|
|
4581
|
+
safeArea,
|
|
4675
4582
|
initializeAsleep: response.initializeAsleep
|
|
4676
4583
|
};
|
|
4677
4584
|
}
|
|
@@ -4681,49 +4588,120 @@ var RemoteHost = class {
|
|
|
4681
4588
|
};
|
|
4682
4589
|
|
|
4683
4590
|
// src/MockHost.ts
|
|
4684
|
-
init_rooms();
|
|
4685
4591
|
var ROOMS_UNAVAILABLE_MESSAGE = "[Venus SDK] Rooms API is only available when running inside the Venus host environment.";
|
|
4686
4592
|
function createUnavailableRoomsApi() {
|
|
4687
4593
|
const roomsUnavailableError = () => new Error(ROOMS_UNAVAILABLE_MESSAGE);
|
|
4688
4594
|
return {
|
|
4689
|
-
async
|
|
4595
|
+
async createRoomAsync() {
|
|
4690
4596
|
throw roomsUnavailableError();
|
|
4691
4597
|
},
|
|
4692
|
-
async
|
|
4598
|
+
async joinOrCreateRoomAsync() {
|
|
4693
4599
|
throw roomsUnavailableError();
|
|
4694
4600
|
},
|
|
4695
|
-
async
|
|
4601
|
+
async joinRoomByCodeAsync() {
|
|
4696
4602
|
throw roomsUnavailableError();
|
|
4697
4603
|
},
|
|
4698
|
-
async
|
|
4604
|
+
async getUserRoomsAsync() {
|
|
4699
4605
|
throw roomsUnavailableError();
|
|
4700
4606
|
},
|
|
4701
|
-
|
|
4607
|
+
async subscribeAsync() {
|
|
4702
4608
|
throw roomsUnavailableError();
|
|
4703
4609
|
},
|
|
4704
|
-
async
|
|
4610
|
+
async updateRoomDataAsync() {
|
|
4705
4611
|
throw roomsUnavailableError();
|
|
4706
4612
|
},
|
|
4707
|
-
async
|
|
4613
|
+
async getRoomDataAsync() {
|
|
4708
4614
|
throw roomsUnavailableError();
|
|
4709
4615
|
},
|
|
4710
|
-
async
|
|
4616
|
+
async sendRoomMessageAsync() {
|
|
4711
4617
|
throw roomsUnavailableError();
|
|
4712
4618
|
},
|
|
4713
|
-
async
|
|
4619
|
+
async leaveRoomAsync() {
|
|
4714
4620
|
throw roomsUnavailableError();
|
|
4715
4621
|
},
|
|
4716
|
-
async
|
|
4622
|
+
async startRoomGameAsync() {
|
|
4717
4623
|
throw roomsUnavailableError();
|
|
4718
4624
|
},
|
|
4719
|
-
async
|
|
4625
|
+
async proposeMoveAsync() {
|
|
4720
4626
|
throw roomsUnavailableError();
|
|
4721
4627
|
},
|
|
4722
|
-
async
|
|
4628
|
+
async validateMoveAsync() {
|
|
4723
4629
|
throw roomsUnavailableError();
|
|
4724
4630
|
}
|
|
4725
4631
|
};
|
|
4726
4632
|
}
|
|
4633
|
+
var SIMULATION_UNAVAILABLE_MESSAGE = "[Venus SDK] Simulation API is only available when running inside the Venus host environment.";
|
|
4634
|
+
function createUnavailableSimulationApi() {
|
|
4635
|
+
const simulationUnavailableError = () => new Error(SIMULATION_UNAVAILABLE_MESSAGE);
|
|
4636
|
+
return {
|
|
4637
|
+
isEnabled() {
|
|
4638
|
+
return false;
|
|
4639
|
+
},
|
|
4640
|
+
async getStateAsync() {
|
|
4641
|
+
throw simulationUnavailableError();
|
|
4642
|
+
},
|
|
4643
|
+
async getConfigAsync() {
|
|
4644
|
+
throw simulationUnavailableError();
|
|
4645
|
+
},
|
|
4646
|
+
async executeRecipeAsync() {
|
|
4647
|
+
throw simulationUnavailableError();
|
|
4648
|
+
},
|
|
4649
|
+
async getActiveRunsAsync() {
|
|
4650
|
+
throw simulationUnavailableError();
|
|
4651
|
+
},
|
|
4652
|
+
async collectRecipeAsync() {
|
|
4653
|
+
throw simulationUnavailableError();
|
|
4654
|
+
},
|
|
4655
|
+
async executeScopedRecipeAsync() {
|
|
4656
|
+
throw simulationUnavailableError();
|
|
4657
|
+
},
|
|
4658
|
+
async triggerRecipeChainAsync() {
|
|
4659
|
+
throw simulationUnavailableError();
|
|
4660
|
+
},
|
|
4661
|
+
async getAvailableRecipesAsync() {
|
|
4662
|
+
throw simulationUnavailableError();
|
|
4663
|
+
},
|
|
4664
|
+
async getRecipeRequirementsAsync() {
|
|
4665
|
+
throw simulationUnavailableError();
|
|
4666
|
+
},
|
|
4667
|
+
async getBatchRecipeRequirementsAsync() {
|
|
4668
|
+
throw simulationUnavailableError();
|
|
4669
|
+
},
|
|
4670
|
+
async resolveFieldValueAsync() {
|
|
4671
|
+
throw simulationUnavailableError();
|
|
4672
|
+
},
|
|
4673
|
+
async getEntityMetadataAsync() {
|
|
4674
|
+
throw simulationUnavailableError();
|
|
4675
|
+
},
|
|
4676
|
+
async getSlotContainersAsync() {
|
|
4677
|
+
throw simulationUnavailableError();
|
|
4678
|
+
},
|
|
4679
|
+
async getSlotAssignmentsAsync() {
|
|
4680
|
+
throw simulationUnavailableError();
|
|
4681
|
+
},
|
|
4682
|
+
async assignItemToSlotAsync() {
|
|
4683
|
+
throw simulationUnavailableError();
|
|
4684
|
+
},
|
|
4685
|
+
async removeItemFromSlotAsync() {
|
|
4686
|
+
throw simulationUnavailableError();
|
|
4687
|
+
},
|
|
4688
|
+
async getAvailableItemsAsync() {
|
|
4689
|
+
throw simulationUnavailableError();
|
|
4690
|
+
},
|
|
4691
|
+
async calculatePowerPreviewAsync() {
|
|
4692
|
+
throw simulationUnavailableError();
|
|
4693
|
+
},
|
|
4694
|
+
async validateSlotAssignmentAsync() {
|
|
4695
|
+
throw simulationUnavailableError();
|
|
4696
|
+
},
|
|
4697
|
+
async executeBatchOperationsAsync() {
|
|
4698
|
+
throw simulationUnavailableError();
|
|
4699
|
+
},
|
|
4700
|
+
async subscribeAsync() {
|
|
4701
|
+
throw simulationUnavailableError();
|
|
4702
|
+
}
|
|
4703
|
+
};
|
|
4704
|
+
}
|
|
4727
4705
|
var MockHost = class {
|
|
4728
4706
|
constructor(venusApi) {
|
|
4729
4707
|
__publicField(this, "ads");
|
|
@@ -4736,9 +4714,9 @@ var MockHost = class {
|
|
|
4736
4714
|
__publicField(this, "notifications");
|
|
4737
4715
|
__publicField(this, "popups");
|
|
4738
4716
|
__publicField(this, "profile");
|
|
4717
|
+
__publicField(this, "system");
|
|
4739
4718
|
__publicField(this, "cdn");
|
|
4740
4719
|
__publicField(this, "time");
|
|
4741
|
-
__publicField(this, "post");
|
|
4742
4720
|
__publicField(this, "ai");
|
|
4743
4721
|
__publicField(this, "haptics");
|
|
4744
4722
|
__publicField(this, "features");
|
|
@@ -4770,15 +4748,17 @@ var MockHost = class {
|
|
|
4770
4748
|
this.navigation = new MockNavigationApi(venusApi);
|
|
4771
4749
|
this.notifications = new MockNotificationsApi(venusApi);
|
|
4772
4750
|
this.popups = new MockPopupsApi(this._overlay);
|
|
4773
|
-
this.profile = new MockProfileApi();
|
|
4774
|
-
|
|
4751
|
+
this.profile = new MockProfileApi(venusApi);
|
|
4752
|
+
const deviceApi = new MockDeviceApi(venusApi);
|
|
4753
|
+
const environmentApi = new MockEnvironmentApi(venusApi);
|
|
4754
|
+
this.system = new MockSystemApi(deviceApi, environmentApi, venusApi);
|
|
4755
|
+
this.cdn = new MockCdnApi(venusApi);
|
|
4775
4756
|
this.time = new MockTimeApi(venusApi);
|
|
4776
|
-
this.post = new MockPostApi(venusApi);
|
|
4777
4757
|
this.ai = new MockAiApi();
|
|
4778
4758
|
this.haptics = new MockHapticsApi(venusApi);
|
|
4779
4759
|
this.features = new MockFeaturesApi();
|
|
4780
4760
|
this.lifecycle = this._mockLifecyclesApi;
|
|
4781
|
-
this.simulation =
|
|
4761
|
+
this.simulation = createUnavailableSimulationApi();
|
|
4782
4762
|
this.rooms = createUnavailableRoomsApi();
|
|
4783
4763
|
this.logging = new MockLoggingApi();
|
|
4784
4764
|
this.iap = new MockIapApi();
|
|
@@ -4794,40 +4774,17 @@ var MockHost = class {
|
|
|
4794
4774
|
}
|
|
4795
4775
|
initialize(options) {
|
|
4796
4776
|
this._isInitialized = true;
|
|
4797
|
-
|
|
4777
|
+
this.venusApi._profileData = this.profile.getCurrentProfile();
|
|
4778
|
+
this.venusApi._deviceData = this.system.getDevice();
|
|
4779
|
+
this.venusApi._environmentData = this.system.getEnvironment();
|
|
4780
|
+
this.venusApi._localeData = this.venusApi._mock?.locale || "en-US";
|
|
4781
|
+
this.venusApi._languageCodeData = this.venusApi._mock?.languageCode || "en";
|
|
4798
4782
|
return Promise.resolve({
|
|
4799
4783
|
initializeAsleep: false,
|
|
4800
|
-
|
|
4801
|
-
top: controls.feedHeader.height,
|
|
4802
|
-
bottom: 0,
|
|
4803
|
-
left: 0,
|
|
4804
|
-
right: 0
|
|
4805
|
-
}
|
|
4784
|
+
safeArea: this.venusApi._safeAreaData
|
|
4806
4785
|
});
|
|
4807
4786
|
}
|
|
4808
|
-
updateUiControls() {
|
|
4809
|
-
const controls = {
|
|
4810
|
-
closeButton: { x: 16, y: 16, width: 32, height: 32 },
|
|
4811
|
-
menuButton: {
|
|
4812
|
-
x: window.innerWidth - 48,
|
|
4813
|
-
y: 16,
|
|
4814
|
-
width: 32,
|
|
4815
|
-
height: 32
|
|
4816
|
-
},
|
|
4817
|
-
feedHeader: { x: 0, y: 0, width: window.innerWidth, height: 56 },
|
|
4818
|
-
playButton: {
|
|
4819
|
-
x: 0,
|
|
4820
|
-
y: window.innerHeight - 60,
|
|
4821
|
-
width: window.innerWidth,
|
|
4822
|
-
height: 60
|
|
4823
|
-
}
|
|
4824
|
-
};
|
|
4825
|
-
return controls;
|
|
4826
|
-
}
|
|
4827
4787
|
createOverlay() {
|
|
4828
|
-
const venusApi = this.venusApi;
|
|
4829
|
-
venusApi.config.ui.controls = this.updateUiControls();
|
|
4830
|
-
const uiControls = venusApi.config.ui.controls;
|
|
4831
4788
|
const overlayContainer = document.createElement("div");
|
|
4832
4789
|
overlayContainer.id = "venus-mock-overlay";
|
|
4833
4790
|
overlayContainer.style.cssText = `
|
|
@@ -4843,7 +4800,7 @@ var MockHost = class {
|
|
|
4843
4800
|
const menuButton = this.createOverlayButton(
|
|
4844
4801
|
"close",
|
|
4845
4802
|
"Menu",
|
|
4846
|
-
|
|
4803
|
+
{ x: window.innerWidth - 48, y: 16, width: 32, height: 32 },
|
|
4847
4804
|
() => {
|
|
4848
4805
|
this.handleMenuButtonClicked();
|
|
4849
4806
|
},
|
|
@@ -5072,17 +5029,13 @@ var MockHost = class {
|
|
|
5072
5029
|
return button;
|
|
5073
5030
|
}
|
|
5074
5031
|
updateOverlayLayout() {
|
|
5075
|
-
const venusApi = this.venusApi;
|
|
5076
5032
|
const overlay = this._overlay;
|
|
5077
|
-
venusApi.config.ui.controls = this.updateUiControls();
|
|
5078
|
-
const uiControls = venusApi.config.ui.controls;
|
|
5079
5033
|
const menuBtn = overlay.elements.menuButton;
|
|
5080
|
-
|
|
5081
|
-
menuBtn.style.
|
|
5082
|
-
menuBtn.style.
|
|
5083
|
-
menuBtn.style.
|
|
5084
|
-
menuBtn.style.
|
|
5085
|
-
menuBtn.style.height = `${menuPos.height}px`;
|
|
5034
|
+
menuBtn.style.left = `${window.innerWidth - 48}px`;
|
|
5035
|
+
menuBtn.style.top = "16px";
|
|
5036
|
+
menuBtn.style.width = "32px";
|
|
5037
|
+
menuBtn.style.minWidth = "32px";
|
|
5038
|
+
menuBtn.style.height = "32px";
|
|
5086
5039
|
}
|
|
5087
5040
|
triggerLifecycleEvent(name) {
|
|
5088
5041
|
console.log("Trigger Lifecycle Event: ", name);
|
|
@@ -5273,10 +5226,8 @@ var MockHost = class {
|
|
|
5273
5226
|
// src/Host.ts
|
|
5274
5227
|
function createHost(venusApi, isMock) {
|
|
5275
5228
|
if (isMock) {
|
|
5276
|
-
console.log("[Venus SDK] Creating Local Host");
|
|
5277
5229
|
return new MockHost(venusApi);
|
|
5278
5230
|
} else {
|
|
5279
|
-
console.log("[Venus SDK] Creating Remote Host");
|
|
5280
5231
|
return new RemoteHost(venusApi);
|
|
5281
5232
|
}
|
|
5282
5233
|
}
|
|
@@ -5289,6 +5240,6 @@ function initializeSocial(venusApi, host) {
|
|
|
5289
5240
|
};
|
|
5290
5241
|
}
|
|
5291
5242
|
|
|
5292
|
-
export { HapticFeedbackStyle, HostCdnApi, HostProfileApi, HostTimeApi, MockAdsApi, MockAiApi, MockAnalyticsApi, MockAvatarApi, MockCdnApi, MockFeaturesApi, MockHapticsApi, MockIapApi, MockLeaderboardApi, MockLifecycleApi, MockLoggingApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockPreloaderApi, MockProfileApi, MockSharedAssetsApi,
|
|
5293
|
-
//# sourceMappingURL=chunk-
|
|
5294
|
-
//# sourceMappingURL=chunk-
|
|
5243
|
+
export { DEFAULT_SHARED_LIB_CDN_BASE, EMBEDDED_LIBRARIES, EMBEDDED_LIBRARY_BY_KEY, HASH_ALGORITHM_NODE, HASH_ALGORITHM_WEB_CRYPTO, HapticFeedbackStyle, HostCdnApi, HostDeviceApi, HostEnvironmentApi, HostProfileApi, HostSystemApi, HostTimeApi, MODULE_TO_LIBRARY_SPECIFIERS, MockAdsApi, MockAiApi, MockAnalyticsApi, MockAvatarApi, MockCdnApi, MockDeviceApi, MockEnvironmentApi, MockFeaturesApi, MockHapticsApi, MockIapApi, MockLeaderboardApi, MockLifecycleApi, MockLoggingApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockPreloaderApi, MockProfileApi, MockSharedAssetsApi, MockSocialApi, MockStorageApi, MockSystemApi, MockTimeApi, RemoteHost, RpcAdsApi, RpcAiApi, RpcAnalyticsApi, RpcAvatarApi, RpcClient, RpcFeaturesApi, RpcHapticsApi, RpcIapApi, RpcLeaderboardApi, RpcLifecycleApi, RpcLoggingApi, RpcNavigationApi, RpcNotificationsApi, RpcPopupsApi, RpcPreloaderApi, RpcRoomsApi, RpcSharedAssetsApi, RpcSimulationApi, RpcSocialApi, RpcStorageApi, SDK_VERSION, VenusMessageId, VenusRoom, base64ToArrayBuffer, base64ToUtf8, computeScoreHash, createHost, createMockStorageApi, getLibraryDefinition, initializeAds, initializeAi, initializeAnalytics, initializeAvatar3d, initializeCdn, initializeFeaturesApi, initializeHaptics, initializeIap, initializeLeaderboard, initializeLifecycleApi, initializeLocalNotifications, initializeLoggingApi, initializePopups, initializePreloader, initializeProfile, initializeRoomsApi, initializeSimulation, initializeSocial, initializeStackNavigation, initializeStorage, initializeSystem, initializeTime, isPacificDaylightTime, setupRoomNotifications };
|
|
5244
|
+
//# sourceMappingURL=chunk-YOBDYPKZ.mjs.map
|
|
5245
|
+
//# sourceMappingURL=chunk-YOBDYPKZ.mjs.map
|