@series-inc/venus-sdk 3.0.4 → 3.0.6
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/README.md +14 -979
- package/dist/{AdsApi-CNGRf6j0.d.mts → AdsApi-CIXV8I_p.d.mts} +389 -186
- package/dist/{AdsApi-CNGRf6j0.d.ts → AdsApi-CIXV8I_p.d.ts} +389 -186
- package/dist/{chunk-PXWCNWJ6.mjs → chunk-LBJFUHOH.mjs} +948 -1370
- package/dist/chunk-LBJFUHOH.mjs.map +1 -0
- package/dist/{chunk-W7IPHM67.mjs → chunk-MWUS3A7C.mjs} +3 -22
- package/dist/chunk-MWUS3A7C.mjs.map +1 -0
- package/dist/core-RDMPQV6U.mjs +3 -0
- package/dist/{core-R3FHW62G.mjs.map → core-RDMPQV6U.mjs.map} +1 -1
- package/dist/index.cjs +944 -1386
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +142 -79
- package/dist/index.d.ts +142 -79
- package/dist/index.mjs +2 -6
- package/dist/index.mjs.map +1 -1
- package/dist/venus-api/index.cjs +1010 -1717
- 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 +43 -308
- package/dist/venus-api/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-PXWCNWJ6.mjs.map +0 -1
- package/dist/chunk-W7IPHM67.mjs.map +0 -1
- package/dist/core-R3FHW62G.mjs +0 -3
package/dist/index.cjs
CHANGED
|
@@ -1,243 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
4
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __esm = (fn, res) => function __init() {
|
|
9
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
-
};
|
|
11
|
-
var __export = (target, all) => {
|
|
12
|
-
for (var name in all)
|
|
13
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
-
};
|
|
15
|
-
var __copyProps = (to, from, except, desc) => {
|
|
16
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
-
for (let key of __getOwnPropNames(from))
|
|
18
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
5
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
25
6
|
|
|
26
|
-
// src/rooms/RoomsApi.ts
|
|
27
|
-
var init_RoomsApi = __esm({
|
|
28
|
-
"src/rooms/RoomsApi.ts"() {
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// src/rooms/VenusRoom.ts
|
|
33
|
-
exports.VenusRoom = void 0;
|
|
34
|
-
var init_VenusRoom = __esm({
|
|
35
|
-
"src/rooms/VenusRoom.ts"() {
|
|
36
|
-
exports.VenusRoom = class {
|
|
37
|
-
constructor(roomData) {
|
|
38
|
-
__publicField(this, "id");
|
|
39
|
-
__publicField(this, "name");
|
|
40
|
-
__publicField(this, "players");
|
|
41
|
-
__publicField(this, "maxPlayers");
|
|
42
|
-
__publicField(this, "gameType");
|
|
43
|
-
__publicField(this, "appId");
|
|
44
|
-
__publicField(this, "type");
|
|
45
|
-
__publicField(this, "createdBy");
|
|
46
|
-
__publicField(this, "createdAt");
|
|
47
|
-
__publicField(this, "updatedAt");
|
|
48
|
-
__publicField(this, "isPrivate");
|
|
49
|
-
__publicField(this, "currentPlayers");
|
|
50
|
-
__publicField(this, "status");
|
|
51
|
-
__publicField(this, "customMetadata");
|
|
52
|
-
__publicField(this, "admins");
|
|
53
|
-
__publicField(this, "roomCode");
|
|
54
|
-
__publicField(this, "description");
|
|
55
|
-
__publicField(this, "data");
|
|
56
|
-
__publicField(this, "version");
|
|
57
|
-
__publicField(this, "_subscriptions", /* @__PURE__ */ new Map());
|
|
58
|
-
this.id = roomData.id;
|
|
59
|
-
this.name = roomData.name;
|
|
60
|
-
this.players = roomData.currentPlayers || [];
|
|
61
|
-
this.maxPlayers = roomData.maxPlayers;
|
|
62
|
-
this.gameType = roomData.gameType;
|
|
63
|
-
this.appId = roomData.appId;
|
|
64
|
-
this.type = roomData.type;
|
|
65
|
-
this.createdBy = roomData.createdBy;
|
|
66
|
-
this.createdAt = roomData.createdAt;
|
|
67
|
-
this.updatedAt = roomData.updatedAt;
|
|
68
|
-
this.isPrivate = roomData.isPrivate;
|
|
69
|
-
this.currentPlayers = roomData.currentPlayers || [];
|
|
70
|
-
this.status = roomData.status;
|
|
71
|
-
this.customMetadata = roomData.customMetadata || {};
|
|
72
|
-
this.admins = roomData.admins || [];
|
|
73
|
-
this.roomCode = roomData.roomCode;
|
|
74
|
-
this.description = roomData.description;
|
|
75
|
-
this.data = roomData.data || {};
|
|
76
|
-
this.version = roomData.version;
|
|
77
|
-
console.log(`VenusRoom: Created room object for ${this.id}`, {
|
|
78
|
-
hasCustomMetadata: !!this.customMetadata,
|
|
79
|
-
hasGameState: !!this.customMetadata?.rules?.gameState,
|
|
80
|
-
gamePhase: this.customMetadata?.rules?.gameState?.phase,
|
|
81
|
-
currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
updateFromRoomData(newRoomData) {
|
|
85
|
-
if (newRoomData.id === this.id) {
|
|
86
|
-
this.name = newRoomData.name || this.name;
|
|
87
|
-
this.players = newRoomData.currentPlayers || this.players;
|
|
88
|
-
this.maxPlayers = newRoomData.maxPlayers || this.maxPlayers;
|
|
89
|
-
this.gameType = newRoomData.gameType || this.gameType;
|
|
90
|
-
this.currentPlayers = newRoomData.currentPlayers || this.currentPlayers;
|
|
91
|
-
this.customMetadata = newRoomData.customMetadata || this.customMetadata;
|
|
92
|
-
this.data = newRoomData.data || this.data;
|
|
93
|
-
this.status = newRoomData.status || this.status;
|
|
94
|
-
this.updatedAt = newRoomData.updatedAt || this.updatedAt;
|
|
95
|
-
console.log(`VenusRoom: Updated room object ${this.id} with fresh data`, {
|
|
96
|
-
hasCustomMetadata: !!this.customMetadata,
|
|
97
|
-
hasGameState: !!this.customMetadata?.rules?.gameState,
|
|
98
|
-
gamePhase: this.customMetadata?.rules?.gameState?.phase,
|
|
99
|
-
currentPlayer: this.customMetadata?.rules?.gameState?.currentPlayer
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// src/rooms/index.ts
|
|
108
|
-
var rooms_exports = {};
|
|
109
|
-
__export(rooms_exports, {
|
|
110
|
-
VenusRoom: () => exports.VenusRoom,
|
|
111
|
-
initializeRoomsApi: () => initializeRoomsApi,
|
|
112
|
-
setupRoomNotifications: () => setupRoomNotifications
|
|
113
|
-
});
|
|
114
|
-
function bindMethod(target, targetKey, source, sourceKey) {
|
|
115
|
-
const key = sourceKey ?? targetKey;
|
|
116
|
-
const fn = source?.[key];
|
|
117
|
-
if (typeof fn === "function") {
|
|
118
|
-
target[targetKey] = fn.bind(source);
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
function setupRoomNotifications(transport, getSubscriptions) {
|
|
124
|
-
console.log("[Venus Rooms] Setting up room notification listeners");
|
|
125
|
-
return transport.onVenusMessage((message) => {
|
|
126
|
-
const subscriptions = getSubscriptions();
|
|
127
|
-
if (!subscriptions) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
if (message.type === "H5_ROOM_DATA_UPDATED") {
|
|
131
|
-
const messageData = message.data;
|
|
132
|
-
const { roomId, roomData } = messageData;
|
|
133
|
-
if (!roomId) return;
|
|
134
|
-
const callbacks = subscriptions.data?.[roomId] || [];
|
|
135
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
136
|
-
console.log(`[Venus Rooms] \u{1F514} Room data updated for ${roomId}, notifying ${callbacks.length} callbacks`, roomData);
|
|
137
|
-
callbacks.forEach((callback) => {
|
|
138
|
-
try {
|
|
139
|
-
callback(roomData);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
console.error("[Venus Rooms] Error in room data callback:", error);
|
|
142
|
-
throw error;
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
allEventsCallbacks.forEach((callback) => {
|
|
146
|
-
try {
|
|
147
|
-
callback({ type: message.type, ...messageData });
|
|
148
|
-
} catch (error) {
|
|
149
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
150
|
-
throw error;
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
|
|
155
|
-
const messageData = message.data;
|
|
156
|
-
const { roomId } = messageData;
|
|
157
|
-
if (!roomId) return;
|
|
158
|
-
const callbacks = subscriptions.messages?.[roomId] || [];
|
|
159
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
160
|
-
console.log(`[Venus Rooms] \u{1F514} Room message event for ${roomId}, notifying ${callbacks.length} callbacks`);
|
|
161
|
-
callbacks.forEach((callback) => {
|
|
162
|
-
try {
|
|
163
|
-
callback(messageData);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
console.error("[Venus Rooms] Error in room message callback:", error);
|
|
166
|
-
throw error;
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
allEventsCallbacks.forEach((callback) => {
|
|
170
|
-
try {
|
|
171
|
-
callback({ type: message.type, ...messageData });
|
|
172
|
-
} catch (error) {
|
|
173
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
174
|
-
throw error;
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
if (message.type === "app:h5:proposedMoveValidationUpdated") {
|
|
179
|
-
const messageData = message.data;
|
|
180
|
-
const { roomId } = messageData;
|
|
181
|
-
if (!roomId) return;
|
|
182
|
-
const callbacks = subscriptions.gameEvents?.[roomId] || [];
|
|
183
|
-
const allEventsCallbacks = subscriptions.allEvents?.[roomId] || [];
|
|
184
|
-
console.log(`[Venus Rooms] \u{1F514} Proposed move validation updated for ${roomId}, notifying ${callbacks.length} callbacks`);
|
|
185
|
-
callbacks.forEach((callback) => {
|
|
186
|
-
try {
|
|
187
|
-
callback(messageData);
|
|
188
|
-
} catch (error) {
|
|
189
|
-
console.error("[Venus Rooms] Error in game event callback:", error);
|
|
190
|
-
throw error;
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
allEventsCallbacks.forEach((callback) => {
|
|
194
|
-
try {
|
|
195
|
-
callback({ type: message.type, ...messageData });
|
|
196
|
-
} catch (error) {
|
|
197
|
-
console.error("[Venus Rooms] Error in allEvents callback:", error);
|
|
198
|
-
throw error;
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
function initializeRoomsApi(venusApi, host) {
|
|
205
|
-
const roomsApi = host?.rooms;
|
|
206
|
-
if (!roomsApi) {
|
|
207
|
-
console.warn(
|
|
208
|
-
"[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
|
|
209
|
-
);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
const venus = venusApi;
|
|
213
|
-
const existingNamespace = venus.rooms || {};
|
|
214
|
-
const roomsNamespace = Object.assign({}, existingNamespace);
|
|
215
|
-
const namespaceBindings = [
|
|
216
|
-
["create", "createRoom"],
|
|
217
|
-
["joinOrCreate", "joinOrCreateRoom"],
|
|
218
|
-
["joinByCode", "joinRoomByCode"],
|
|
219
|
-
["list", "getUserRooms"],
|
|
220
|
-
["subscribeToRoom", "subscribe"],
|
|
221
|
-
["updateRoomData", "updateData"],
|
|
222
|
-
["getRoomData", "getData"],
|
|
223
|
-
["sendRoomMessage", "sendMessage"],
|
|
224
|
-
["leaveRoom", "leave"],
|
|
225
|
-
["startRoomGame", "startGame"],
|
|
226
|
-
["proposeMove"],
|
|
227
|
-
["validateMove"]
|
|
228
|
-
];
|
|
229
|
-
namespaceBindings.forEach(([targetKey, sourceKey]) => {
|
|
230
|
-
bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
|
|
231
|
-
});
|
|
232
|
-
venus.rooms = roomsNamespace;
|
|
233
|
-
}
|
|
234
|
-
var init_rooms = __esm({
|
|
235
|
-
"src/rooms/index.ts"() {
|
|
236
|
-
init_RoomsApi();
|
|
237
|
-
init_VenusRoom();
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
|
|
241
7
|
// src/VenusMessageId.ts
|
|
242
8
|
var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
243
9
|
VenusMessageId2["H5_RESPONSE"] = "H5_RESPONSE";
|
|
@@ -329,11 +95,14 @@ var VenusMessageId = /* @__PURE__ */ ((VenusMessageId2) => {
|
|
|
329
95
|
VenusMessageId2["H5_SIMULATION_GET_AVAILABLE_ITEMS"] = "H5_SIMULATION_GET_AVAILABLE_ITEMS";
|
|
330
96
|
VenusMessageId2["H5_SIMULATION_VALIDATE_ASSIGNMENT"] = "H5_SIMULATION_VALIDATE_ASSIGNMENT";
|
|
331
97
|
VenusMessageId2["H5_SIMULATION_BATCH_OPERATIONS"] = "H5_SIMULATION_BATCH_OPERATIONS";
|
|
332
|
-
VenusMessageId2["
|
|
98
|
+
VenusMessageId2["H5_SIMULATION_SUBSCRIBE"] = "H5_SIMULATION_SUBSCRIBE";
|
|
99
|
+
VenusMessageId2["H5_SIMULATION_UNSUBSCRIBE"] = "H5_SIMULATION_UNSUBSCRIBE";
|
|
100
|
+
VenusMessageId2["H5_SIMULATION_UPDATE"] = "H5_SIMULATION_UPDATE";
|
|
101
|
+
VenusMessageId2["H5_LEADERBOARD_CREATE_SCORE_TOKEN"] = "H5_LEADERBOARD_CREATE_SCORE_TOKEN";
|
|
333
102
|
VenusMessageId2["H5_LEADERBOARD_SUBMIT_SCORE"] = "H5_LEADERBOARD_SUBMIT_SCORE";
|
|
334
|
-
VenusMessageId2["
|
|
335
|
-
VenusMessageId2["
|
|
336
|
-
VenusMessageId2["
|
|
103
|
+
VenusMessageId2["H5_LEADERBOARD_GET_PAGED_SCORES"] = "H5_LEADERBOARD_GET_PAGED_SCORES";
|
|
104
|
+
VenusMessageId2["H5_LEADERBOARD_GET_PODIUM_SCORES"] = "H5_LEADERBOARD_GET_PODIUM_SCORES";
|
|
105
|
+
VenusMessageId2["H5_LEADERBOARD_GET_MY_RANK"] = "H5_LEADERBOARD_GET_MY_RANK";
|
|
337
106
|
VenusMessageId2["H5_ROOM_CREATE"] = "H5_ROOM_CREATE";
|
|
338
107
|
VenusMessageId2["H5_ROOM_JOIN"] = "H5_ROOM_JOIN";
|
|
339
108
|
VenusMessageId2["H5_ROOM_JOIN_OR_CREATE"] = "H5_ROOM_JOIN_OR_CREATE";
|
|
@@ -1793,13 +1562,8 @@ var MockNotificationsApi = class {
|
|
|
1793
1562
|
async cancelNotification(notificationId) {
|
|
1794
1563
|
const venusApi = this.venusApi;
|
|
1795
1564
|
if (isWebPlatform()) {
|
|
1796
|
-
console.log(
|
|
1797
|
-
"[Venus Mock] Cancel notification on web platform (simulated):",
|
|
1798
|
-
notificationId
|
|
1799
|
-
);
|
|
1800
1565
|
return true;
|
|
1801
1566
|
}
|
|
1802
|
-
console.log("[Venus Mock] Cancel local notification:", notificationId);
|
|
1803
1567
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1804
1568
|
if (venusApi._mock.scheduledNotifications && venusApi._mock.scheduledNotifications[notificationId]) {
|
|
1805
1569
|
delete venusApi._mock.scheduledNotifications[notificationId];
|
|
@@ -1809,12 +1573,8 @@ var MockNotificationsApi = class {
|
|
|
1809
1573
|
}
|
|
1810
1574
|
async getAllScheduledLocalNotifications() {
|
|
1811
1575
|
if (isWebPlatform()) {
|
|
1812
|
-
console.log(
|
|
1813
|
-
"[Venus Mock] Get notifications on web platform (returning empty list)"
|
|
1814
|
-
);
|
|
1815
1576
|
return [];
|
|
1816
1577
|
}
|
|
1817
|
-
console.log("[Venus Mock] Get all scheduled local notifications");
|
|
1818
1578
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1819
1579
|
const venusApi = this.venusApi;
|
|
1820
1580
|
const notifications = venusApi._mock.scheduledNotifications || {};
|
|
@@ -1822,10 +1582,8 @@ var MockNotificationsApi = class {
|
|
|
1822
1582
|
}
|
|
1823
1583
|
async isLocalNotificationsEnabled() {
|
|
1824
1584
|
if (isWebPlatform()) {
|
|
1825
|
-
console.log("[Venus Mock] Notifications not available on web platform");
|
|
1826
1585
|
return false;
|
|
1827
1586
|
}
|
|
1828
|
-
console.log("[Venus Mock] Check if local notifications are enabled");
|
|
1829
1587
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1830
1588
|
const venusApi = this.venusApi;
|
|
1831
1589
|
const isEnabled = venusApi._mock.notificationsEnabled !== false;
|
|
@@ -1834,9 +1592,6 @@ var MockNotificationsApi = class {
|
|
|
1834
1592
|
async scheduleAsync(title, body, seconds, notificationId, options) {
|
|
1835
1593
|
const { priority = 50, groupId, payload } = options || {};
|
|
1836
1594
|
if (isWebPlatform()) {
|
|
1837
|
-
console.log(
|
|
1838
|
-
"[Venus Mock] Notifications not supported on web platform, simulating success"
|
|
1839
|
-
);
|
|
1840
1595
|
console.info(
|
|
1841
1596
|
"\u{1F514} [Venus Mock] Notification would be scheduled:",
|
|
1842
1597
|
title || "Untitled",
|
|
@@ -1847,14 +1602,11 @@ var MockNotificationsApi = class {
|
|
|
1847
1602
|
const mockId = `mock-web-notification-${Date.now()}`;
|
|
1848
1603
|
return mockId;
|
|
1849
1604
|
}
|
|
1850
|
-
console.log("[Venus Mock] Schedule local notification:", { title, body, seconds, options });
|
|
1851
1605
|
const venusApi = this.venusApi;
|
|
1852
1606
|
if (!venusApi._mock.pendingRequests) {
|
|
1853
|
-
console.log("[Venus Mock] Initializing pendingRequests");
|
|
1854
1607
|
venusApi._mock.pendingRequests = {};
|
|
1855
1608
|
}
|
|
1856
1609
|
const requestId = Date.now().toString();
|
|
1857
|
-
console.log("[Venus Mock] Creating request with ID:", requestId);
|
|
1858
1610
|
return new Promise((resolve) => {
|
|
1859
1611
|
venusApi._mock.pendingRequests[requestId] = { resolve };
|
|
1860
1612
|
const id = notificationId || `mock-notification-${Date.now()}`;
|
|
@@ -1876,13 +1628,8 @@ var MockNotificationsApi = class {
|
|
|
1876
1628
|
async setLocalNotificationsEnabled(enabled) {
|
|
1877
1629
|
const venusApi = this.venusApi;
|
|
1878
1630
|
if (isWebPlatform()) {
|
|
1879
|
-
console.log(
|
|
1880
|
-
"[Venus Mock] Set notifications enabled on web platform (simulated):",
|
|
1881
|
-
enabled
|
|
1882
|
-
);
|
|
1883
1631
|
return true;
|
|
1884
1632
|
}
|
|
1885
|
-
console.log("[Venus Mock] Set local notifications enabled:", enabled);
|
|
1886
1633
|
await createMockDelay(MOCK_DELAYS.short);
|
|
1887
1634
|
venusApi._mock.notificationsEnabled = enabled;
|
|
1888
1635
|
return enabled;
|
|
@@ -2147,6 +1894,11 @@ function initializeProfile(venusApi, host) {
|
|
|
2147
1894
|
};
|
|
2148
1895
|
}
|
|
2149
1896
|
|
|
1897
|
+
// src/utils/idGenerator.ts
|
|
1898
|
+
function generateId() {
|
|
1899
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
2150
1902
|
// src/rpc/RpcClient.ts
|
|
2151
1903
|
var RpcClient = class {
|
|
2152
1904
|
constructor() {
|
|
@@ -2189,7 +1941,7 @@ var RpcClient = class {
|
|
|
2189
1941
|
}
|
|
2190
1942
|
async call(method, args, timeout = 5e3) {
|
|
2191
1943
|
return new Promise((resolve, reject) => {
|
|
2192
|
-
const id =
|
|
1944
|
+
const id = generateId();
|
|
2193
1945
|
this.addPendingCall(id, resolve, reject);
|
|
2194
1946
|
const request = {
|
|
2195
1947
|
type: "rpc-request",
|
|
@@ -2226,9 +1978,6 @@ var RpcClient = class {
|
|
|
2226
1978
|
getPendingCall(id) {
|
|
2227
1979
|
return this.pendingCalls.get(id);
|
|
2228
1980
|
}
|
|
2229
|
-
generateId() {
|
|
2230
|
-
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
2231
|
-
}
|
|
2232
1981
|
handleRpcResponse(response) {
|
|
2233
1982
|
const pending = this.getPendingCall(response.id);
|
|
2234
1983
|
if (!pending) {
|
|
@@ -2250,105 +1999,522 @@ var RpcClient = class {
|
|
|
2250
1999
|
}
|
|
2251
2000
|
};
|
|
2252
2001
|
|
|
2253
|
-
// src/
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2002
|
+
// src/rooms/VenusRoom.ts
|
|
2003
|
+
var VenusRoom = class {
|
|
2004
|
+
constructor(roomData) {
|
|
2005
|
+
__publicField(this, "id");
|
|
2006
|
+
__publicField(this, "name");
|
|
2007
|
+
__publicField(this, "players");
|
|
2008
|
+
__publicField(this, "maxPlayers");
|
|
2009
|
+
__publicField(this, "gameType");
|
|
2010
|
+
__publicField(this, "appId");
|
|
2011
|
+
__publicField(this, "type");
|
|
2012
|
+
__publicField(this, "createdBy");
|
|
2013
|
+
__publicField(this, "createdAt");
|
|
2014
|
+
__publicField(this, "updatedAt");
|
|
2015
|
+
__publicField(this, "isPrivate");
|
|
2016
|
+
__publicField(this, "status");
|
|
2017
|
+
__publicField(this, "customMetadata");
|
|
2018
|
+
__publicField(this, "admins");
|
|
2019
|
+
__publicField(this, "roomCode");
|
|
2020
|
+
__publicField(this, "description");
|
|
2021
|
+
__publicField(this, "data");
|
|
2022
|
+
__publicField(this, "version");
|
|
2023
|
+
this.id = roomData.id;
|
|
2024
|
+
this.name = roomData.name;
|
|
2025
|
+
this.players = Array.isArray(roomData.currentPlayers) ? [...roomData.currentPlayers] : [];
|
|
2026
|
+
this.maxPlayers = roomData.maxPlayers;
|
|
2027
|
+
this.gameType = roomData.gameType;
|
|
2028
|
+
this.appId = roomData.appId;
|
|
2029
|
+
this.type = roomData.type;
|
|
2030
|
+
this.createdBy = roomData.createdBy;
|
|
2031
|
+
this.createdAt = roomData.createdAt;
|
|
2032
|
+
this.updatedAt = roomData.updatedAt;
|
|
2033
|
+
this.isPrivate = roomData.isPrivate;
|
|
2034
|
+
this.status = roomData.status;
|
|
2035
|
+
this.customMetadata = roomData.customMetadata || {};
|
|
2036
|
+
this.admins = Array.isArray(roomData.admins) ? [...roomData.admins] : [];
|
|
2037
|
+
this.roomCode = roomData.roomCode;
|
|
2038
|
+
this.description = roomData.description;
|
|
2039
|
+
this.data = roomData.data || {};
|
|
2040
|
+
this.version = roomData.version;
|
|
2276
2041
|
}
|
|
2277
|
-
|
|
2278
|
-
|
|
2042
|
+
};
|
|
2043
|
+
|
|
2044
|
+
// src/rooms/setupRoomNotifications.ts
|
|
2045
|
+
function invokeCallbacks(callbacks, event, context) {
|
|
2046
|
+
callbacks.forEach((callback) => {
|
|
2047
|
+
try {
|
|
2048
|
+
callback(event);
|
|
2049
|
+
} catch (error) {
|
|
2050
|
+
console.error(`[Venus SDK] Error in ${context} callback:`, error);
|
|
2051
|
+
throw error;
|
|
2052
|
+
}
|
|
2053
|
+
});
|
|
2279
2054
|
}
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
this.syncDelay = syncDelay;
|
|
2286
|
-
}
|
|
2287
|
-
async clear() {
|
|
2288
|
-
const fullLength = localStorage.length;
|
|
2289
|
-
for (let i = 0; i < fullLength; i++) {
|
|
2290
|
-
const fullKey = localStorage.key(i);
|
|
2291
|
-
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
2292
|
-
localStorage.removeItem(fullKey);
|
|
2293
|
-
}
|
|
2055
|
+
function setupRoomNotifications(transport, getSubscriptions) {
|
|
2056
|
+
return transport.onVenusMessage((message) => {
|
|
2057
|
+
const subscriptions = getSubscriptions();
|
|
2058
|
+
if (!subscriptions) {
|
|
2059
|
+
return;
|
|
2294
2060
|
}
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
}
|
|
2061
|
+
if (message.type === "H5_ROOM_DATA_UPDATED") {
|
|
2062
|
+
const messageData = message.data;
|
|
2063
|
+
const { roomId, roomData } = messageData;
|
|
2064
|
+
if (!roomId) return;
|
|
2065
|
+
const callbacks = subscriptions.data[roomId] || [];
|
|
2066
|
+
const event = {
|
|
2067
|
+
type: "H5_ROOM_DATA_UPDATED",
|
|
2068
|
+
roomId,
|
|
2069
|
+
roomData,
|
|
2070
|
+
timestamp: messageData.timestamp
|
|
2071
|
+
};
|
|
2072
|
+
invokeCallbacks(callbacks, event, "room data");
|
|
2308
2073
|
}
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2074
|
+
if (message.type === "H5_ROOM_MESSAGE_RECEIVED" || message.type === "H5_ROOM_MESSAGE_UPDATED" || message.type === "H5_ROOM_MESSAGE_DELETED") {
|
|
2075
|
+
const messageData = message.data;
|
|
2076
|
+
const { roomId } = messageData;
|
|
2077
|
+
if (!roomId) return;
|
|
2078
|
+
const callbacks = subscriptions.messages[roomId] || [];
|
|
2079
|
+
const event = {
|
|
2080
|
+
type: message.type,
|
|
2081
|
+
roomId,
|
|
2082
|
+
message: messageData.message,
|
|
2083
|
+
timestamp: messageData.timestamp
|
|
2084
|
+
};
|
|
2085
|
+
invokeCallbacks(callbacks, event, "room message");
|
|
2320
2086
|
}
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2087
|
+
if (message.type === "app:h5:proposedMoveValidationUpdated") {
|
|
2088
|
+
const messageData = message.data;
|
|
2089
|
+
const { roomId } = messageData;
|
|
2090
|
+
if (!roomId) return;
|
|
2091
|
+
const callbacks = subscriptions.gameEvents[roomId] || [];
|
|
2092
|
+
const event = {
|
|
2093
|
+
type: "app:h5:proposedMoveValidationUpdated",
|
|
2094
|
+
roomId,
|
|
2095
|
+
proposedMoveData: messageData.proposedMoveData,
|
|
2096
|
+
proposedMoveId: messageData.proposedMoveId,
|
|
2097
|
+
changeType: messageData.changeType,
|
|
2098
|
+
timestamp: messageData.timestamp
|
|
2099
|
+
};
|
|
2100
|
+
invokeCallbacks(callbacks, event, "game event");
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
// src/rooms/RpcRoomsApi.ts
|
|
2106
|
+
var RpcRoomsApi = class {
|
|
2107
|
+
constructor(rpcClient) {
|
|
2108
|
+
__publicField(this, "rpcClient");
|
|
2109
|
+
__publicField(this, "subscriptions");
|
|
2110
|
+
this.rpcClient = rpcClient;
|
|
2111
|
+
this.subscriptions = {
|
|
2112
|
+
data: {},
|
|
2113
|
+
messages: {},
|
|
2114
|
+
gameEvents: {}
|
|
2115
|
+
};
|
|
2326
2116
|
}
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2117
|
+
/**
|
|
2118
|
+
* Get the subscription state for external access (used by setupRoomNotifications)
|
|
2119
|
+
*/
|
|
2120
|
+
getSubscriptions() {
|
|
2121
|
+
return this.subscriptions;
|
|
2331
2122
|
}
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2123
|
+
/**
|
|
2124
|
+
* Set up room notification routing from the transport
|
|
2125
|
+
*/
|
|
2126
|
+
setupNotifications(transport) {
|
|
2127
|
+
setupRoomNotifications(transport, () => this.getSubscriptions());
|
|
2336
2128
|
}
|
|
2337
|
-
async
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2129
|
+
async createRoomAsync(options) {
|
|
2130
|
+
const response = await this.rpcClient.call(
|
|
2131
|
+
"H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
|
|
2132
|
+
{
|
|
2133
|
+
options
|
|
2134
|
+
}
|
|
2135
|
+
);
|
|
2136
|
+
if (response.success === false) {
|
|
2137
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to create room";
|
|
2138
|
+
throw new Error(errorMessage);
|
|
2341
2139
|
}
|
|
2342
|
-
|
|
2140
|
+
const room = new VenusRoom(response.roomData);
|
|
2141
|
+
return room;
|
|
2343
2142
|
}
|
|
2344
|
-
async
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2143
|
+
async joinOrCreateRoomAsync(options) {
|
|
2144
|
+
const response = await this.rpcClient.call(
|
|
2145
|
+
"H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
|
|
2146
|
+
{
|
|
2147
|
+
options
|
|
2148
|
+
}
|
|
2149
|
+
);
|
|
2150
|
+
if (response.success === false) {
|
|
2151
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to join or create room";
|
|
2152
|
+
throw new Error(errorMessage);
|
|
2348
2153
|
}
|
|
2349
|
-
|
|
2154
|
+
const room = new VenusRoom(response.value.roomData);
|
|
2155
|
+
return {
|
|
2156
|
+
action: response.value.action,
|
|
2157
|
+
room,
|
|
2158
|
+
playersJoined: response.value.playersJoined
|
|
2159
|
+
};
|
|
2350
2160
|
}
|
|
2351
|
-
|
|
2161
|
+
async joinRoomByCodeAsync(roomCode) {
|
|
2162
|
+
const response = await this.rpcClient.call(
|
|
2163
|
+
"H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
|
|
2164
|
+
{
|
|
2165
|
+
roomCode
|
|
2166
|
+
}
|
|
2167
|
+
);
|
|
2168
|
+
if (response?.success === false) {
|
|
2169
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to join room by code";
|
|
2170
|
+
throw new Error(errorMessage);
|
|
2171
|
+
}
|
|
2172
|
+
const room = new VenusRoom(response.roomData);
|
|
2173
|
+
return room;
|
|
2174
|
+
}
|
|
2175
|
+
// Get user's rooms with optional filtering
|
|
2176
|
+
async getUserRoomsAsync(options = {}) {
|
|
2177
|
+
const response = await this.rpcClient.call(
|
|
2178
|
+
"H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
|
|
2179
|
+
{
|
|
2180
|
+
includeArchived: options.includeArchived ?? false
|
|
2181
|
+
}
|
|
2182
|
+
);
|
|
2183
|
+
if (response?.success === false) {
|
|
2184
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to get user rooms";
|
|
2185
|
+
throw new Error(errorMessage);
|
|
2186
|
+
}
|
|
2187
|
+
const venusRooms = [];
|
|
2188
|
+
for (const roomData of response.rooms) {
|
|
2189
|
+
if (!roomData.id) {
|
|
2190
|
+
console.warn("[Venus SDK] getUserRooms: Skipping room with missing ID:", roomData);
|
|
2191
|
+
continue;
|
|
2192
|
+
}
|
|
2193
|
+
try {
|
|
2194
|
+
const venusRoom = new VenusRoom(roomData);
|
|
2195
|
+
venusRooms.push(venusRoom);
|
|
2196
|
+
} catch (error) {
|
|
2197
|
+
console.warn(
|
|
2198
|
+
"[Venus SDK] getUserRooms: Failed to create VenusRoom object:",
|
|
2199
|
+
error,
|
|
2200
|
+
roomData
|
|
2201
|
+
);
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
return venusRooms;
|
|
2205
|
+
}
|
|
2206
|
+
async updateRoomDataAsync(room, updates, options = {}) {
|
|
2207
|
+
const response = await this.rpcClient.call(
|
|
2208
|
+
"H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
|
|
2209
|
+
{
|
|
2210
|
+
roomId: room.id,
|
|
2211
|
+
updates,
|
|
2212
|
+
merge: options.merge ?? true
|
|
2213
|
+
}
|
|
2214
|
+
);
|
|
2215
|
+
if (response?.success === false) {
|
|
2216
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to update room data";
|
|
2217
|
+
throw new Error(errorMessage);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
async getRoomDataAsync(room) {
|
|
2221
|
+
const response = await this.rpcClient.call(
|
|
2222
|
+
"H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
|
|
2223
|
+
{
|
|
2224
|
+
roomId: room.id
|
|
2225
|
+
}
|
|
2226
|
+
);
|
|
2227
|
+
if (response?.success === false) {
|
|
2228
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to get room data";
|
|
2229
|
+
throw new Error(errorMessage);
|
|
2230
|
+
}
|
|
2231
|
+
return response.data;
|
|
2232
|
+
}
|
|
2233
|
+
async sendRoomMessageAsync(venusRoom, request) {
|
|
2234
|
+
const response = await this.rpcClient.call(
|
|
2235
|
+
"H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
|
|
2236
|
+
{
|
|
2237
|
+
roomId: venusRoom.id,
|
|
2238
|
+
message: request.message,
|
|
2239
|
+
metadata: request.metadata
|
|
2240
|
+
}
|
|
2241
|
+
);
|
|
2242
|
+
if (response?.success === false) {
|
|
2243
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to send message";
|
|
2244
|
+
throw new Error(errorMessage);
|
|
2245
|
+
}
|
|
2246
|
+
return response.messageId;
|
|
2247
|
+
}
|
|
2248
|
+
async leaveRoomAsync(room) {
|
|
2249
|
+
const response = await this.rpcClient.call(
|
|
2250
|
+
"H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
|
|
2251
|
+
{
|
|
2252
|
+
roomId: room.id
|
|
2253
|
+
}
|
|
2254
|
+
);
|
|
2255
|
+
if (response?.success === false) {
|
|
2256
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to leave room";
|
|
2257
|
+
throw new Error(errorMessage);
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
async startRoomGameAsync(room, options = {}) {
|
|
2261
|
+
const response = await this.rpcClient.call(
|
|
2262
|
+
"H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
|
|
2263
|
+
{
|
|
2264
|
+
roomId: room.id,
|
|
2265
|
+
gameConfig: options.gameConfig ?? {},
|
|
2266
|
+
turnOrder: options.turnOrder ?? null
|
|
2267
|
+
}
|
|
2268
|
+
);
|
|
2269
|
+
if (response?.success === false) {
|
|
2270
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to start game";
|
|
2271
|
+
throw new Error(errorMessage);
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
async proposeMoveAsync(room, proposalPayload) {
|
|
2275
|
+
const response = await this.rpcClient.call(
|
|
2276
|
+
"h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
|
|
2277
|
+
{
|
|
2278
|
+
roomId: room.id,
|
|
2279
|
+
gameSpecificState: proposalPayload.gameSpecificState,
|
|
2280
|
+
moveType: proposalPayload.moveType,
|
|
2281
|
+
clientContext: proposalPayload.clientContext,
|
|
2282
|
+
clientProposalId: proposalPayload.clientProposalId
|
|
2283
|
+
}
|
|
2284
|
+
);
|
|
2285
|
+
if (response?.success === false) {
|
|
2286
|
+
const errorMessage = typeof response.error === "string" ? response.error : "Failed to propose move";
|
|
2287
|
+
throw new Error(errorMessage);
|
|
2288
|
+
}
|
|
2289
|
+
return response.data;
|
|
2290
|
+
}
|
|
2291
|
+
async validateMoveAsync(_room, moveId, verdict) {
|
|
2292
|
+
return {
|
|
2293
|
+
success: true,
|
|
2294
|
+
moveId,
|
|
2295
|
+
isValid: verdict.isValid,
|
|
2296
|
+
reason: verdict.reason
|
|
2297
|
+
};
|
|
2298
|
+
}
|
|
2299
|
+
async subscribeAsync(room, options = {}) {
|
|
2300
|
+
const roomId = room.id;
|
|
2301
|
+
const existingData = this.subscriptions.data[roomId];
|
|
2302
|
+
const existingMessages = this.subscriptions.messages[roomId];
|
|
2303
|
+
const existingGameEvents = this.subscriptions.gameEvents[roomId];
|
|
2304
|
+
const subscribeToData = Boolean(options.onData) && (existingData?.length ?? 0) === 0;
|
|
2305
|
+
const subscribeToMessages = Boolean(options.onMessages) && (existingMessages?.length ?? 0) === 0;
|
|
2306
|
+
const subscribeToProposedMoves = Boolean(options.onGameEvents) && (existingGameEvents?.length ?? 0) === 0;
|
|
2307
|
+
if (subscribeToData || subscribeToMessages || subscribeToProposedMoves) {
|
|
2308
|
+
try {
|
|
2309
|
+
await this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
|
|
2310
|
+
roomId,
|
|
2311
|
+
subscribeToData,
|
|
2312
|
+
subscribeToMessages,
|
|
2313
|
+
subscribeToProposedMoves
|
|
2314
|
+
});
|
|
2315
|
+
} catch (error) {
|
|
2316
|
+
console.error("[Venus SDK] Failed to set up room subscription:", error);
|
|
2317
|
+
throw error;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
if (options.onData) {
|
|
2321
|
+
if (!this.subscriptions.data[roomId]) {
|
|
2322
|
+
this.subscriptions.data[roomId] = [];
|
|
2323
|
+
}
|
|
2324
|
+
this.subscriptions.data[roomId].push(options.onData);
|
|
2325
|
+
}
|
|
2326
|
+
if (options.onMessages) {
|
|
2327
|
+
if (!this.subscriptions.messages[roomId]) {
|
|
2328
|
+
this.subscriptions.messages[roomId] = [];
|
|
2329
|
+
}
|
|
2330
|
+
this.subscriptions.messages[roomId].push(options.onMessages);
|
|
2331
|
+
}
|
|
2332
|
+
if (options.onGameEvents) {
|
|
2333
|
+
if (!this.subscriptions.gameEvents[roomId]) {
|
|
2334
|
+
this.subscriptions.gameEvents[roomId] = [];
|
|
2335
|
+
}
|
|
2336
|
+
this.subscriptions.gameEvents[roomId].push(options.onGameEvents);
|
|
2337
|
+
}
|
|
2338
|
+
let disposed = false;
|
|
2339
|
+
return () => {
|
|
2340
|
+
if (disposed) return;
|
|
2341
|
+
disposed = true;
|
|
2342
|
+
if (options.onData) {
|
|
2343
|
+
const callbacks = this.subscriptions.data[roomId];
|
|
2344
|
+
if (callbacks) {
|
|
2345
|
+
const index = callbacks.indexOf(options.onData);
|
|
2346
|
+
if (index > -1) {
|
|
2347
|
+
callbacks.splice(index, 1);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
if (options.onMessages) {
|
|
2352
|
+
const callbacks = this.subscriptions.messages[roomId];
|
|
2353
|
+
if (callbacks) {
|
|
2354
|
+
const index = callbacks.indexOf(options.onMessages);
|
|
2355
|
+
if (index > -1) {
|
|
2356
|
+
callbacks.splice(index, 1);
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
if (options.onGameEvents) {
|
|
2361
|
+
const callbacks = this.subscriptions.gameEvents[roomId];
|
|
2362
|
+
if (callbacks) {
|
|
2363
|
+
const index = callbacks.indexOf(options.onGameEvents);
|
|
2364
|
+
if (index > -1) {
|
|
2365
|
+
callbacks.splice(index, 1);
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
const hasAnySubscriptions = (this.subscriptions.data[roomId]?.length ?? 0) > 0 || (this.subscriptions.messages[roomId]?.length ?? 0) > 0 || (this.subscriptions.gameEvents[roomId]?.length ?? 0) > 0;
|
|
2370
|
+
if (!hasAnySubscriptions) {
|
|
2371
|
+
this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
|
|
2372
|
+
roomId
|
|
2373
|
+
}).catch((error) => {
|
|
2374
|
+
console.error("[Venus SDK] Failed to clean up room subscription:", error);
|
|
2375
|
+
});
|
|
2376
|
+
}
|
|
2377
|
+
};
|
|
2378
|
+
}
|
|
2379
|
+
};
|
|
2380
|
+
|
|
2381
|
+
// src/rooms/index.ts
|
|
2382
|
+
function bindMethod(target, targetKey, source, sourceKey) {
|
|
2383
|
+
const key = sourceKey ?? targetKey;
|
|
2384
|
+
const fn = source?.[key];
|
|
2385
|
+
if (typeof fn === "function") {
|
|
2386
|
+
target[targetKey] = fn.bind(source);
|
|
2387
|
+
return true;
|
|
2388
|
+
}
|
|
2389
|
+
return false;
|
|
2390
|
+
}
|
|
2391
|
+
function initializeRoomsApi(venusApi, host) {
|
|
2392
|
+
const roomsApi = host?.rooms;
|
|
2393
|
+
if (!roomsApi) {
|
|
2394
|
+
console.warn(
|
|
2395
|
+
"[Venus SDK] Host did not provide a rooms implementation. Rooms API will be unavailable."
|
|
2396
|
+
);
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
2399
|
+
const venus = venusApi;
|
|
2400
|
+
const existingNamespace = venus.rooms || {};
|
|
2401
|
+
const roomsNamespace = Object.assign({}, existingNamespace);
|
|
2402
|
+
const namespaceBindings = [
|
|
2403
|
+
["createRoomAsync"],
|
|
2404
|
+
["joinOrCreateRoomAsync"],
|
|
2405
|
+
["joinRoomByCodeAsync"],
|
|
2406
|
+
["getUserRoomsAsync"],
|
|
2407
|
+
["subscribeAsync"],
|
|
2408
|
+
["updateRoomDataAsync"],
|
|
2409
|
+
["getRoomDataAsync"],
|
|
2410
|
+
["sendRoomMessageAsync"],
|
|
2411
|
+
["leaveRoomAsync"],
|
|
2412
|
+
["startRoomGameAsync"],
|
|
2413
|
+
["proposeMoveAsync"],
|
|
2414
|
+
["validateMoveAsync"]
|
|
2415
|
+
];
|
|
2416
|
+
namespaceBindings.forEach(([targetKey, sourceKey]) => {
|
|
2417
|
+
bindMethod(roomsNamespace, targetKey, roomsApi, sourceKey);
|
|
2418
|
+
});
|
|
2419
|
+
venus.rooms = roomsNamespace;
|
|
2420
|
+
}
|
|
2421
|
+
|
|
2422
|
+
// src/storage/MockStorageApi.ts
|
|
2423
|
+
function createMockStorageApi(storageType, appUrl) {
|
|
2424
|
+
const appIdentifier = appUrl ? generateAppIdentifier(appUrl) : null;
|
|
2425
|
+
let prefix;
|
|
2426
|
+
let syncDelay = 0;
|
|
2427
|
+
switch (storageType) {
|
|
2428
|
+
case "deviceCache":
|
|
2429
|
+
prefix = "venus:app";
|
|
2430
|
+
syncDelay = 0;
|
|
2431
|
+
break;
|
|
2432
|
+
case "appStorage":
|
|
2433
|
+
prefix = "venus:app";
|
|
2434
|
+
syncDelay = 100;
|
|
2435
|
+
break;
|
|
2436
|
+
case "globalStorage":
|
|
2437
|
+
prefix = "venus:global";
|
|
2438
|
+
syncDelay = 100;
|
|
2439
|
+
break;
|
|
2440
|
+
default:
|
|
2441
|
+
throw new Error(`Unknown storage type: ${storageType}`);
|
|
2442
|
+
}
|
|
2443
|
+
prefix = storageType === "globalStorage" || !appIdentifier ? `${prefix}:` : `${prefix}:${appIdentifier}:`;
|
|
2444
|
+
return new MockStorageApi(prefix, syncDelay);
|
|
2445
|
+
}
|
|
2446
|
+
var MockStorageApi = class {
|
|
2447
|
+
constructor(prefix, syncDelay) {
|
|
2448
|
+
__publicField(this, "prefix");
|
|
2449
|
+
__publicField(this, "syncDelay");
|
|
2450
|
+
this.prefix = prefix;
|
|
2451
|
+
this.syncDelay = syncDelay;
|
|
2452
|
+
}
|
|
2453
|
+
async clear() {
|
|
2454
|
+
const fullLength = localStorage.length;
|
|
2455
|
+
for (let i = 0; i < fullLength; i++) {
|
|
2456
|
+
const fullKey = localStorage.key(i);
|
|
2457
|
+
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
2458
|
+
localStorage.removeItem(fullKey);
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
await this.simulateSyncDelay();
|
|
2462
|
+
}
|
|
2463
|
+
async getAllItems() {
|
|
2464
|
+
const items = new Array();
|
|
2465
|
+
const fullLength = localStorage.length;
|
|
2466
|
+
for (let i = 0; i < fullLength; i++) {
|
|
2467
|
+
const fullKey = localStorage.key(i);
|
|
2468
|
+
if (fullKey && fullKey.startsWith(this.prefix)) {
|
|
2469
|
+
const item = localStorage.getItem(fullKey);
|
|
2470
|
+
if (item) {
|
|
2471
|
+
items.push(item);
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
return items;
|
|
2476
|
+
}
|
|
2477
|
+
async getItem(key) {
|
|
2478
|
+
const fullKey = this.buildKey(key);
|
|
2479
|
+
await this.simulateSyncDelay();
|
|
2480
|
+
return localStorage.getItem(fullKey);
|
|
2481
|
+
}
|
|
2482
|
+
async key(index) {
|
|
2483
|
+
const keys = this.keys();
|
|
2484
|
+
if (index < 0 || index >= keys.length) {
|
|
2485
|
+
return null;
|
|
2486
|
+
}
|
|
2487
|
+
await this.simulateSyncDelay();
|
|
2488
|
+
return keys[index];
|
|
2489
|
+
}
|
|
2490
|
+
async length() {
|
|
2491
|
+
return this.keys().length;
|
|
2492
|
+
}
|
|
2493
|
+
async removeItem(key) {
|
|
2494
|
+
const fullKey = this.buildKey(key);
|
|
2495
|
+
await this.simulateSyncDelay();
|
|
2496
|
+
localStorage.removeItem(fullKey);
|
|
2497
|
+
}
|
|
2498
|
+
async setItem(key, item) {
|
|
2499
|
+
const fullKey = this.buildKey(key);
|
|
2500
|
+
await this.simulateSyncDelay();
|
|
2501
|
+
localStorage.setItem(fullKey, item);
|
|
2502
|
+
}
|
|
2503
|
+
async setMultipleItems(entries) {
|
|
2504
|
+
for (const entry of entries) {
|
|
2505
|
+
const fullKey = this.buildKey(entry.key);
|
|
2506
|
+
localStorage.setItem(fullKey, entry.value);
|
|
2507
|
+
}
|
|
2508
|
+
await this.simulateSyncDelay();
|
|
2509
|
+
}
|
|
2510
|
+
async removeMultipleItems(keys) {
|
|
2511
|
+
for (const key of keys) {
|
|
2512
|
+
const fullKey = this.buildKey(key);
|
|
2513
|
+
localStorage.removeItem(fullKey);
|
|
2514
|
+
}
|
|
2515
|
+
await this.simulateSyncDelay();
|
|
2516
|
+
}
|
|
2517
|
+
buildKey(key) {
|
|
2352
2518
|
const prefix = this.prefix;
|
|
2353
2519
|
return `${prefix}${key}`;
|
|
2354
2520
|
}
|
|
@@ -2486,24 +2652,20 @@ function initializeStorage(venusApiInstance, host) {
|
|
|
2486
2652
|
venusApiInstance.globalStorage = host.globalStorage;
|
|
2487
2653
|
}
|
|
2488
2654
|
|
|
2489
|
-
// src/simulation/utils.ts
|
|
2490
|
-
function sumContributions(contributions) {
|
|
2491
|
-
const totals = {};
|
|
2492
|
-
for (const profileId in contributions) {
|
|
2493
|
-
for (const entityId in contributions[profileId]) {
|
|
2494
|
-
const amount = contributions[profileId][entityId] || 0;
|
|
2495
|
-
totals[entityId] = (totals[entityId] || 0) + amount;
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
return totals;
|
|
2499
|
-
}
|
|
2500
|
-
|
|
2501
2655
|
// src/simulation/RpcSimulationApi.ts
|
|
2502
2656
|
var RpcSimulationApi = class {
|
|
2503
2657
|
constructor(rpcClient) {
|
|
2504
2658
|
__publicField(this, "rpcClient");
|
|
2505
2659
|
__publicField(this, "_simulationConfig", null);
|
|
2660
|
+
__publicField(this, "subscriptionCallbacks", /* @__PURE__ */ new Map());
|
|
2506
2661
|
this.rpcClient = rpcClient;
|
|
2662
|
+
this.rpcClient.onNotification(
|
|
2663
|
+
"H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */,
|
|
2664
|
+
this.handleSimulationUpdate.bind(this)
|
|
2665
|
+
);
|
|
2666
|
+
}
|
|
2667
|
+
isEnabled() {
|
|
2668
|
+
return true;
|
|
2507
2669
|
}
|
|
2508
2670
|
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2509
2671
|
return this.rpcClient.call(
|
|
@@ -2515,14 +2677,47 @@ var RpcSimulationApi = class {
|
|
|
2515
2677
|
}
|
|
2516
2678
|
);
|
|
2517
2679
|
}
|
|
2518
|
-
|
|
2519
|
-
|
|
2680
|
+
async subscribeAsync(options) {
|
|
2681
|
+
this.ensureValidSubscribeOptions(options);
|
|
2682
|
+
const subscriptionId = generateId();
|
|
2683
|
+
this.subscriptionCallbacks.set(subscriptionId, options.onUpdate);
|
|
2684
|
+
try {
|
|
2685
|
+
await this.rpcClient.call("H5_SIMULATION_SUBSCRIBE" /* H5_SIMULATION_SUBSCRIBE */, {
|
|
2686
|
+
subscriptionId,
|
|
2687
|
+
entities: options.entities,
|
|
2688
|
+
tags: options.tags,
|
|
2689
|
+
activeRuns: options.activeRuns,
|
|
2690
|
+
roomId: options.roomId
|
|
2691
|
+
});
|
|
2692
|
+
} catch (error) {
|
|
2693
|
+
this.subscriptionCallbacks.delete(subscriptionId);
|
|
2694
|
+
throw error;
|
|
2695
|
+
}
|
|
2696
|
+
let unsubscribed = false;
|
|
2697
|
+
return () => {
|
|
2698
|
+
if (unsubscribed) {
|
|
2699
|
+
return;
|
|
2700
|
+
}
|
|
2701
|
+
unsubscribed = true;
|
|
2702
|
+
this.subscriptionCallbacks.delete(subscriptionId);
|
|
2703
|
+
void this.rpcClient.call("H5_SIMULATION_UNSUBSCRIBE" /* H5_SIMULATION_UNSUBSCRIBE */, {
|
|
2704
|
+
subscriptionId
|
|
2705
|
+
}).catch((error) => {
|
|
2706
|
+
console.error(
|
|
2707
|
+
"[Venus SDK] Failed to unsubscribe simulation listener",
|
|
2708
|
+
error
|
|
2709
|
+
);
|
|
2710
|
+
});
|
|
2711
|
+
};
|
|
2520
2712
|
}
|
|
2521
2713
|
executeBatchOperationsAsync(operations, validateOnly) {
|
|
2522
|
-
return this.rpcClient.call(
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2714
|
+
return this.rpcClient.call(
|
|
2715
|
+
"H5_SIMULATION_BATCH_OPERATIONS" /* H5_SIMULATION_BATCH_OPERATIONS */,
|
|
2716
|
+
{
|
|
2717
|
+
operations,
|
|
2718
|
+
validateOnly
|
|
2719
|
+
}
|
|
2720
|
+
);
|
|
2526
2721
|
}
|
|
2527
2722
|
async getAvailableItemsAsync(containerId, slotId) {
|
|
2528
2723
|
const response = await this.rpcClient.call(
|
|
@@ -2545,17 +2740,23 @@ var RpcSimulationApi = class {
|
|
|
2545
2740
|
);
|
|
2546
2741
|
}
|
|
2547
2742
|
assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
2548
|
-
return this.rpcClient.call(
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2743
|
+
return this.rpcClient.call(
|
|
2744
|
+
"H5_SIMULATION_ASSIGN_ITEM" /* H5_SIMULATION_ASSIGN_ITEM */,
|
|
2745
|
+
{
|
|
2746
|
+
containerId,
|
|
2747
|
+
slotId,
|
|
2748
|
+
itemId
|
|
2749
|
+
}
|
|
2750
|
+
);
|
|
2553
2751
|
}
|
|
2554
2752
|
removeItemFromSlotAsync(containerId, slotId) {
|
|
2555
|
-
return this.rpcClient.call(
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2753
|
+
return this.rpcClient.call(
|
|
2754
|
+
"H5_SIMULATION_REMOVE_ITEM" /* H5_SIMULATION_REMOVE_ITEM */,
|
|
2755
|
+
{
|
|
2756
|
+
containerId,
|
|
2757
|
+
slotId
|
|
2758
|
+
}
|
|
2759
|
+
);
|
|
2559
2760
|
}
|
|
2560
2761
|
async getSlotContainersAsync() {
|
|
2561
2762
|
const response = await this.rpcClient.call(
|
|
@@ -2580,7 +2781,6 @@ var RpcSimulationApi = class {
|
|
|
2580
2781
|
roomId
|
|
2581
2782
|
}
|
|
2582
2783
|
);
|
|
2583
|
-
console.log("[Venus SDK] getStateAsync", response);
|
|
2584
2784
|
if (response.configuration) {
|
|
2585
2785
|
this._simulationConfig = response.configuration;
|
|
2586
2786
|
}
|
|
@@ -2592,9 +2792,10 @@ var RpcSimulationApi = class {
|
|
|
2592
2792
|
}
|
|
2593
2793
|
const config = await this.rpcClient.call(
|
|
2594
2794
|
"H5_SIMULATION_GET_CONFIG" /* H5_SIMULATION_GET_CONFIG */,
|
|
2595
|
-
{
|
|
2795
|
+
{
|
|
2796
|
+
roomId
|
|
2797
|
+
}
|
|
2596
2798
|
);
|
|
2597
|
-
console.log("[Venus SDK] getConfigAsync", config);
|
|
2598
2799
|
if (config) {
|
|
2599
2800
|
this._simulationConfig = config;
|
|
2600
2801
|
return config;
|
|
@@ -2602,14 +2803,17 @@ var RpcSimulationApi = class {
|
|
|
2602
2803
|
throw new Error("No simulation configuration available");
|
|
2603
2804
|
}
|
|
2604
2805
|
executeRecipeAsync(recipeId, inputs, options) {
|
|
2605
|
-
return this.rpcClient.call(
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2806
|
+
return this.rpcClient.call(
|
|
2807
|
+
"H5_SIMULATION_EXECUTE_RECIPE" /* H5_SIMULATION_EXECUTE_RECIPE */,
|
|
2808
|
+
{
|
|
2809
|
+
recipeId,
|
|
2810
|
+
inputs,
|
|
2811
|
+
roomId: options?.roomId,
|
|
2812
|
+
batchAmount: options?.batchAmount,
|
|
2813
|
+
allowPartialBatch: options?.allowPartialBatch,
|
|
2814
|
+
entity: options?.entity
|
|
2815
|
+
}
|
|
2816
|
+
);
|
|
2613
2817
|
}
|
|
2614
2818
|
collectRecipeAsync(runId) {
|
|
2615
2819
|
return this.rpcClient.call("H5_SIMULATION_COLLECT_RECIPE" /* H5_SIMULATION_COLLECT_RECIPE */, {
|
|
@@ -2617,9 +2821,12 @@ var RpcSimulationApi = class {
|
|
|
2617
2821
|
});
|
|
2618
2822
|
}
|
|
2619
2823
|
getActiveRunsAsync(options) {
|
|
2620
|
-
return this.rpcClient.call(
|
|
2621
|
-
|
|
2622
|
-
|
|
2824
|
+
return this.rpcClient.call(
|
|
2825
|
+
"H5_SIMULATION_GET_ACTIVE_RUNS" /* H5_SIMULATION_GET_ACTIVE_RUNS */,
|
|
2826
|
+
{
|
|
2827
|
+
roomId: options?.roomId
|
|
2828
|
+
}
|
|
2829
|
+
);
|
|
2623
2830
|
}
|
|
2624
2831
|
executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2625
2832
|
return this.rpcClient.call(
|
|
@@ -2689,583 +2896,52 @@ var RpcSimulationApi = class {
|
|
|
2689
2896
|
);
|
|
2690
2897
|
return response.value;
|
|
2691
2898
|
}
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
if (typeof window === "undefined") return "unknown-app";
|
|
2697
|
-
const url = window.location.href;
|
|
2698
|
-
const match = url.match(/\/H5\/([^\/]+)/);
|
|
2699
|
-
return match ? match[1] : "unknown-app";
|
|
2700
|
-
}
|
|
2701
|
-
var MockSimulationApi = class {
|
|
2702
|
-
constructor(simulationConfig = null) {
|
|
2703
|
-
__publicField(this, "mockSimulationConfigs", /* @__PURE__ */ new Map());
|
|
2704
|
-
// appIdentifier -> config
|
|
2705
|
-
__publicField(this, "mockSimulationStates", /* @__PURE__ */ new Map());
|
|
2706
|
-
// appIdentifier -> config
|
|
2707
|
-
__publicField(this, "mockActiveTimers", /* @__PURE__ */ new Map());
|
|
2708
|
-
// appIdentifier -> timers[]
|
|
2709
|
-
__publicField(this, "appId");
|
|
2710
|
-
__publicField(this, "providedSimulationConfig");
|
|
2711
|
-
this.appId = generateAppIdentifier2();
|
|
2712
|
-
this.providedSimulationConfig = simulationConfig;
|
|
2713
|
-
}
|
|
2714
|
-
sumContributions(contributions) {
|
|
2715
|
-
return sumContributions(contributions);
|
|
2716
|
-
}
|
|
2717
|
-
async validateSlotAssignmentAsync(containerId, slotId, itemId) {
|
|
2718
|
-
this.log("validateSlotAssignmentAsync called:", {
|
|
2719
|
-
containerId,
|
|
2720
|
-
slotId,
|
|
2721
|
-
itemId
|
|
2722
|
-
});
|
|
2723
|
-
return { valid: true, message: "Mock validation successful" };
|
|
2724
|
-
}
|
|
2725
|
-
async executeBatchOperationsAsync(operations, validateOnly) {
|
|
2726
|
-
this.log("executeBatchOperationsAsync called:", {
|
|
2727
|
-
operations,
|
|
2728
|
-
validateOnly
|
|
2729
|
-
});
|
|
2730
|
-
return {
|
|
2731
|
-
success: true,
|
|
2732
|
-
results: operations.map(() => ({ success: true }))
|
|
2733
|
-
};
|
|
2734
|
-
}
|
|
2735
|
-
async getAvailableItemsAsync(containerId, slotId) {
|
|
2736
|
-
console.log("[Venus Simulation Mock] getAvailableItemsAsync called:", {
|
|
2737
|
-
containerId,
|
|
2738
|
-
slotId
|
|
2739
|
-
});
|
|
2740
|
-
const appIdentifier = generateAppIdentifier2();
|
|
2741
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2742
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2743
|
-
entities: {}
|
|
2744
|
-
};
|
|
2745
|
-
const availableItems = Object.entries(config.entities).slice(0, 3).map(([entityId, entity]) => ({
|
|
2746
|
-
entityId,
|
|
2747
|
-
quantity: 1,
|
|
2748
|
-
metadata: entity.metadata,
|
|
2749
|
-
powerPreview: 100
|
|
2750
|
-
// Mock power value
|
|
2751
|
-
}));
|
|
2752
|
-
return availableItems;
|
|
2753
|
-
}
|
|
2754
|
-
async calculatePowerPreviewAsync(containerId, slotId, candidateItemId) {
|
|
2755
|
-
this.log("calculatePowerPreviewAsync called:", {
|
|
2756
|
-
containerId,
|
|
2757
|
-
slotId,
|
|
2758
|
-
candidateItemId
|
|
2759
|
-
});
|
|
2760
|
-
return {
|
|
2761
|
-
currentPower: 1e3,
|
|
2762
|
-
previewPower: 1200,
|
|
2763
|
-
powerDelta: 200,
|
|
2764
|
-
breakdown: { base: 800, weapon: 200, armor: 200 }
|
|
2765
|
-
};
|
|
2766
|
-
}
|
|
2767
|
-
async getSlotContainersAsync() {
|
|
2768
|
-
this.log("getSlotContainersAsync called");
|
|
2769
|
-
const appIdentifier = this.appId;
|
|
2770
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2771
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
2772
|
-
entities: {}
|
|
2773
|
-
};
|
|
2774
|
-
const containers = Object.entries(config.entities).filter(([_, entity]) => entity.metadata?.slots).map(([entityId, entity]) => ({
|
|
2775
|
-
entityId,
|
|
2776
|
-
slots: entity.metadata?.slots,
|
|
2777
|
-
isOwned: true
|
|
2778
|
-
// Mock: assume all containers are owned
|
|
2779
|
-
}));
|
|
2780
|
-
return containers;
|
|
2781
|
-
}
|
|
2782
|
-
async getSlotAssignmentsAsync(containerId) {
|
|
2783
|
-
this.log("getSlotAssignmentsAsync called for:", containerId);
|
|
2784
|
-
return [];
|
|
2785
|
-
}
|
|
2786
|
-
async resolveFieldValueAsync(entityId, fieldPath, entity) {
|
|
2787
|
-
this.log("resolveFieldValueAsync called:", {
|
|
2788
|
-
entityId,
|
|
2789
|
-
fieldPath,
|
|
2790
|
-
entity
|
|
2791
|
-
});
|
|
2792
|
-
const mockValues = {
|
|
2793
|
-
basePower: 850,
|
|
2794
|
-
weaponPower: 300,
|
|
2795
|
-
armorPower: 150,
|
|
2796
|
-
total_power: 1300,
|
|
2797
|
-
total_defense_power: 5e3
|
|
2798
|
-
};
|
|
2799
|
-
return mockValues[fieldPath] || 100;
|
|
2800
|
-
}
|
|
2801
|
-
async getEntityMetadataAsync(entityId) {
|
|
2802
|
-
this.log("getEntityMetadataAsync called for:", entityId);
|
|
2803
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2804
|
-
const appIdentifier = this.appId;
|
|
2805
|
-
const config = mockSimulationConfigs.get(
|
|
2806
|
-
appIdentifier
|
|
2807
|
-
) || {
|
|
2808
|
-
entities: {}};
|
|
2809
|
-
const entity = config.entities[entityId];
|
|
2810
|
-
return entity?.metadata || {};
|
|
2811
|
-
}
|
|
2812
|
-
async collectRecipeAsync(runId) {
|
|
2813
|
-
this.log("collectRecipeAsync called:", { runId });
|
|
2814
|
-
const mockRewards = {
|
|
2815
|
-
cash: Math.floor(Math.random() * 1e3) + 500,
|
|
2816
|
-
experience: Math.floor(Math.random() * 50) + 25
|
|
2817
|
-
};
|
|
2818
|
-
return {
|
|
2819
|
-
success: true,
|
|
2820
|
-
runId,
|
|
2821
|
-
rewards: mockRewards,
|
|
2822
|
-
message: "Rewards collected successfully"
|
|
2823
|
-
};
|
|
2824
|
-
}
|
|
2825
|
-
executeRecipeAsync(recipeId, inputs, options) {
|
|
2826
|
-
this.log("executeRecipeAsync called:", {
|
|
2827
|
-
recipeId,
|
|
2828
|
-
inputs,
|
|
2829
|
-
options
|
|
2830
|
-
});
|
|
2831
|
-
const appIdentifier = this.appId;
|
|
2832
|
-
return this.executeRecipe(appIdentifier, recipeId, inputs);
|
|
2833
|
-
}
|
|
2834
|
-
async executeScopedRecipeAsync(recipeId, entity, inputs, options) {
|
|
2835
|
-
this.log("executeScopedRecipeAsync called:", {
|
|
2836
|
-
recipeId,
|
|
2837
|
-
entity,
|
|
2838
|
-
inputs,
|
|
2839
|
-
roomId: options?.roomId,
|
|
2840
|
-
options
|
|
2841
|
-
});
|
|
2842
|
-
return {
|
|
2843
|
-
success: true,
|
|
2844
|
-
message: "Mock scoped recipe execution successful"
|
|
2845
|
-
};
|
|
2846
|
-
}
|
|
2847
|
-
async getActiveRunsAsync(options) {
|
|
2848
|
-
this.log("getActiveRunsAsync called:", options);
|
|
2849
|
-
const appIdentifier = this.appId;
|
|
2850
|
-
let state = this.mockSimulationStates.get(appIdentifier);
|
|
2851
|
-
if (!state) {
|
|
2852
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
2853
|
-
}
|
|
2854
|
-
return state.activeRuns || [];
|
|
2855
|
-
}
|
|
2856
|
-
async getAvailableRecipesAsync(options) {
|
|
2857
|
-
this.log("getAvailableRecipesAsync called:", options);
|
|
2858
|
-
const baseRecipes = [
|
|
2859
|
-
{ id: "collect_resources", scope: "player", clientViewable: true },
|
|
2860
|
-
{ id: "upgrade_equipment", scope: "player", clientViewable: true }
|
|
2861
|
-
];
|
|
2862
|
-
if (options?.roomId) {
|
|
2863
|
-
baseRecipes.push(
|
|
2864
|
-
{ id: "room_upgrade", scope: "room", clientViewable: true },
|
|
2865
|
-
{ id: "cooperative_project", scope: "room", clientViewable: true }
|
|
2866
|
-
);
|
|
2899
|
+
handleSimulationUpdate(notification) {
|
|
2900
|
+
if (!notification || !notification.subscriptionId) {
|
|
2901
|
+
console.warn("[Venus SDK] Received malformed simulation update");
|
|
2902
|
+
return;
|
|
2867
2903
|
}
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2904
|
+
const callback = this.subscriptionCallbacks.get(notification.subscriptionId);
|
|
2905
|
+
if (!callback) {
|
|
2906
|
+
console.warn(
|
|
2907
|
+
"[Venus SDK] Received update for unknown subscription:",
|
|
2908
|
+
notification.subscriptionId
|
|
2872
2909
|
);
|
|
2910
|
+
return;
|
|
2873
2911
|
}
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
count: recipes?.length
|
|
2879
|
-
});
|
|
2880
|
-
const results = (recipes || []).map((q) => ({
|
|
2881
|
-
recipeId: q.recipeId,
|
|
2882
|
-
entity: q.entity || null,
|
|
2883
|
-
amount: q.batchAmount || 1,
|
|
2884
|
-
inputs: { cash: "BE:0" },
|
|
2885
|
-
canAfford: true,
|
|
2886
|
-
disabled: false
|
|
2887
|
-
}));
|
|
2888
|
-
return { success: true, results };
|
|
2889
|
-
}
|
|
2890
|
-
async getRecipeRequirementsAsync(recipe) {
|
|
2891
|
-
this.log("getRecipeRequirementsAsync called:", recipe);
|
|
2892
|
-
return {
|
|
2893
|
-
recipeId: recipe.recipeId,
|
|
2894
|
-
entity: recipe.entity || null,
|
|
2895
|
-
amount: recipe.batchAmount,
|
|
2896
|
-
inputs: { cash: "BE:0" },
|
|
2897
|
-
canAfford: true,
|
|
2898
|
-
disabled: false
|
|
2899
|
-
};
|
|
2900
|
-
}
|
|
2901
|
-
async triggerRecipeChainAsync(recipeId, options) {
|
|
2902
|
-
this.log("triggerRecipeChainAsync called:", { recipeId, ...options });
|
|
2903
|
-
return {
|
|
2904
|
-
success: true,
|
|
2905
|
-
message: "Mock recipe chain triggered successfully"
|
|
2906
|
-
};
|
|
2907
|
-
}
|
|
2908
|
-
log(message, ...args) {
|
|
2909
|
-
console.log(`[Venus Sim Mock] ${message}`, args);
|
|
2910
|
-
}
|
|
2911
|
-
async executeRecipe(appIdentifier, recipeId, inputs) {
|
|
2912
|
-
this.log(`Executing recipe ${recipeId} for ${appIdentifier}`, inputs);
|
|
2913
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2914
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
2915
|
-
let config = mockSimulationConfigs.get(appIdentifier);
|
|
2916
|
-
let state = mockSimulationStates.get(appIdentifier);
|
|
2917
|
-
if (!config || !state) {
|
|
2918
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
2919
|
-
config = mockSimulationConfigs.get(appIdentifier);
|
|
2920
|
-
if (!config) {
|
|
2921
|
-
throw new Error("Failed to initialize simulation config");
|
|
2922
|
-
}
|
|
2923
|
-
}
|
|
2924
|
-
const recipe = config.recipes?.[recipeId];
|
|
2925
|
-
if (!recipe) {
|
|
2926
|
-
throw new Error(`Recipe ${recipeId} not found`);
|
|
2927
|
-
}
|
|
2928
|
-
if (state.disabledRecipes?.includes(recipeId)) {
|
|
2929
|
-
throw new Error(`Recipe ${recipeId} is disabled`);
|
|
2930
|
-
}
|
|
2931
|
-
if (recipe.inputs) {
|
|
2932
|
-
for (const [entityId, required] of Object.entries(recipe.inputs)) {
|
|
2933
|
-
const available = state.inventory[entityId] || 0;
|
|
2934
|
-
if (available < required) {
|
|
2935
|
-
throw new Error(
|
|
2936
|
-
`Insufficient ${entityId}: required ${required}, available ${available}`
|
|
2937
|
-
);
|
|
2938
|
-
}
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
if (recipe.inputs) {
|
|
2942
|
-
for (const [entityId, input] of Object.entries(recipe.inputs)) {
|
|
2943
|
-
const inventoryValue = state.inventory[entityId] || 0;
|
|
2944
|
-
if (typeof input === "number" && typeof inventoryValue === "number") {
|
|
2945
|
-
state.inventory[entityId] = inventoryValue - input;
|
|
2946
|
-
}
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
if (recipe.beginEffects) {
|
|
2950
|
-
this.applyEffects(state, recipe.beginEffects);
|
|
2951
|
-
}
|
|
2952
|
-
const runId = this.generateRunId();
|
|
2953
|
-
const now = Date.now();
|
|
2954
|
-
const expiresAt = now + (recipe.duration || 0);
|
|
2955
|
-
const run = {
|
|
2956
|
-
id: runId,
|
|
2957
|
-
recipeId,
|
|
2958
|
-
status: "running",
|
|
2959
|
-
startTime: now,
|
|
2960
|
-
expiresAt,
|
|
2961
|
-
inputs: recipe.inputs || {}
|
|
2962
|
-
};
|
|
2963
|
-
state.activeRuns.push(run);
|
|
2964
|
-
if (recipe.duration === 0) {
|
|
2965
|
-
this.completeRun(appIdentifier, runId);
|
|
2966
|
-
return { status: "completed", runId };
|
|
2967
|
-
} else {
|
|
2968
|
-
const mockActiveTimers = this.mockActiveTimers;
|
|
2969
|
-
const timer = setTimeout(() => {
|
|
2970
|
-
this.completeRun(appIdentifier, runId);
|
|
2971
|
-
}, recipe.duration);
|
|
2972
|
-
const timers = mockActiveTimers.get(appIdentifier) || [];
|
|
2973
|
-
timers.push(timer);
|
|
2974
|
-
mockActiveTimers.set(appIdentifier, timers);
|
|
2975
|
-
return {
|
|
2976
|
-
status: "running",
|
|
2977
|
-
runId,
|
|
2978
|
-
expiresAt: new Date(expiresAt).toISOString()
|
|
2979
|
-
};
|
|
2912
|
+
try {
|
|
2913
|
+
callback(notification.updates);
|
|
2914
|
+
} catch (error) {
|
|
2915
|
+
console.error("[Venus SDK] Error in simulation subscription callback", error);
|
|
2980
2916
|
}
|
|
2981
2917
|
}
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
2986
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
2987
|
-
const mockActiveTimers = this.mockActiveTimers;
|
|
2988
|
-
const config = providedSimulationConfig || {
|
|
2989
|
-
version: "1.0",
|
|
2990
|
-
entities: {},
|
|
2991
|
-
recipes: {}
|
|
2992
|
-
};
|
|
2993
|
-
mockSimulationConfigs.set(appIdentifier, config);
|
|
2994
|
-
const initialInventory = {};
|
|
2995
|
-
if (providedSimulationConfig && config.entities) {
|
|
2996
|
-
Object.keys(config.entities).forEach((entityId) => {
|
|
2997
|
-
initialInventory[entityId] = 0;
|
|
2998
|
-
});
|
|
2999
|
-
}
|
|
3000
|
-
const state = {
|
|
3001
|
-
inventory: initialInventory,
|
|
3002
|
-
activeRuns: [],
|
|
3003
|
-
disabledRecipes: new Array()
|
|
3004
|
-
};
|
|
3005
|
-
if (config.recipes) {
|
|
3006
|
-
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
3007
|
-
if (recipe.metadata?.startsDisabled) {
|
|
3008
|
-
state.disabledRecipes.push(recipeId);
|
|
3009
|
-
}
|
|
3010
|
-
});
|
|
3011
|
-
}
|
|
3012
|
-
mockSimulationStates.set(appIdentifier, state);
|
|
3013
|
-
mockActiveTimers.set(appIdentifier, []);
|
|
3014
|
-
console.log(
|
|
3015
|
-
`[Venus Simulation Mock] Initialized state for ${appIdentifier}:`,
|
|
3016
|
-
state
|
|
3017
|
-
);
|
|
3018
|
-
if (config.recipes) {
|
|
3019
|
-
Object.entries(config.recipes).forEach(([recipeId, recipe]) => {
|
|
3020
|
-
const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
|
|
3021
|
-
if (isAutoRestart && recipe.outputs) {
|
|
3022
|
-
this.log(`Found auto-restart recipe: ${recipeId}`, {
|
|
3023
|
-
topLevelAutoRestart: recipe.autoRestart,
|
|
3024
|
-
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
3025
|
-
hasOutputs: !!recipe.outputs,
|
|
3026
|
-
duration: recipe.duration
|
|
3027
|
-
});
|
|
3028
|
-
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
3029
|
-
if (condition && condition.entity) {
|
|
3030
|
-
const currentAmount = initialInventory[condition.entity] || 0;
|
|
3031
|
-
if (currentAmount < condition.maxValue) {
|
|
3032
|
-
console.log(
|
|
3033
|
-
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization`,
|
|
3034
|
-
{
|
|
3035
|
-
currentAmount,
|
|
3036
|
-
maxValue: condition.maxValue,
|
|
3037
|
-
entity: condition.entity
|
|
3038
|
-
}
|
|
3039
|
-
);
|
|
3040
|
-
setTimeout(() => {
|
|
3041
|
-
this.executeRecipe(appIdentifier, recipeId, {});
|
|
3042
|
-
}, 1e3);
|
|
3043
|
-
}
|
|
3044
|
-
} else {
|
|
3045
|
-
console.log(
|
|
3046
|
-
`[Venus Simulation Mock] Auto-starting ${recipeId} at initialization (no condition)`
|
|
3047
|
-
);
|
|
3048
|
-
setTimeout(() => {
|
|
3049
|
-
this.executeRecipe(appIdentifier, recipeId, {});
|
|
3050
|
-
}, 1e3);
|
|
3051
|
-
}
|
|
3052
|
-
}
|
|
3053
|
-
});
|
|
3054
|
-
}
|
|
3055
|
-
return state;
|
|
3056
|
-
}
|
|
3057
|
-
generateRunId() {
|
|
3058
|
-
return "run_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
3059
|
-
}
|
|
3060
|
-
completeRun(appIdentifier, runId) {
|
|
3061
|
-
this.log(`Completing run ${runId} for ${appIdentifier}`);
|
|
3062
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3063
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
3064
|
-
const config = mockSimulationConfigs.get(appIdentifier);
|
|
3065
|
-
const state = mockSimulationStates.get(appIdentifier);
|
|
3066
|
-
if (!config || !state) return;
|
|
3067
|
-
const runIndex = state.activeRuns.findIndex((r) => r.id === runId);
|
|
3068
|
-
if (runIndex === -1) return;
|
|
3069
|
-
const run = state.activeRuns[runIndex];
|
|
3070
|
-
const recipe = config.recipes?.[run.recipeId];
|
|
3071
|
-
if (!recipe) return;
|
|
3072
|
-
const outputs = {};
|
|
3073
|
-
const rng = this.createSeededRandom(runId);
|
|
3074
|
-
if (recipe.outputs) {
|
|
3075
|
-
for (const [entityId, value] of Object.entries(recipe.outputs)) {
|
|
3076
|
-
if (typeof value === "number") {
|
|
3077
|
-
outputs[entityId] = value;
|
|
3078
|
-
} else if (typeof value === "object" && value != null && "min" in value && "max" in value && typeof value.min == "number" && typeof value.max === "number") {
|
|
3079
|
-
outputs[entityId] = Math.floor(rng() * (value.max - value.min + 1)) + value.min;
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
2918
|
+
ensureValidSubscribeOptions(options) {
|
|
2919
|
+
if (typeof options !== "object" || options === null) {
|
|
2920
|
+
throw new Error("Simulation subscribe requires an options object");
|
|
3082
2921
|
}
|
|
3083
|
-
|
|
3084
|
-
|
|
2922
|
+
const opts = options;
|
|
2923
|
+
if (typeof opts.onUpdate !== "function") {
|
|
2924
|
+
throw new Error("Simulation subscribe requires an onUpdate callback");
|
|
3085
2925
|
}
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
run.outputs = outputs;
|
|
3091
|
-
state.activeRuns.splice(runIndex, 1);
|
|
3092
|
-
const isAutoRestart = recipe.autoRestart || recipe.metadata?.autoRestart;
|
|
3093
|
-
if (isAutoRestart) {
|
|
3094
|
-
console.log(
|
|
3095
|
-
`[Venus Simulation Mock] Checking auto-restart for ${run.recipeId}`,
|
|
3096
|
-
{
|
|
3097
|
-
topLevelAutoRestart: recipe.autoRestart,
|
|
3098
|
-
metadataAutoRestart: recipe.metadata?.autoRestart,
|
|
3099
|
-
hasCondition: !!(recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition)
|
|
3100
|
-
}
|
|
2926
|
+
const hasFilter = Array.isArray(opts.entities) && opts.entities.length > 0 || Array.isArray(opts.tags) && opts.tags.length > 0 || Boolean(opts.activeRuns);
|
|
2927
|
+
if (!hasFilter) {
|
|
2928
|
+
throw new Error(
|
|
2929
|
+
"Simulation subscribe requires at least one filter (entities, tags, activeRuns)"
|
|
3101
2930
|
);
|
|
3102
|
-
const condition = recipe.maxRestartCondition || recipe.metadata?.maxRestartCondition;
|
|
3103
|
-
if (condition) {
|
|
3104
|
-
const currentAmount = state.inventory[condition.entity] || 0;
|
|
3105
|
-
if (currentAmount < condition.maxValue) {
|
|
3106
|
-
console.log(
|
|
3107
|
-
`[Venus Simulation Mock] Auto-restarting ${run.recipeId}`,
|
|
3108
|
-
{
|
|
3109
|
-
currentAmount,
|
|
3110
|
-
maxValue: condition.maxValue,
|
|
3111
|
-
entity: condition.entity
|
|
3112
|
-
}
|
|
3113
|
-
);
|
|
3114
|
-
setTimeout(() => {
|
|
3115
|
-
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
3116
|
-
}, 1e3);
|
|
3117
|
-
}
|
|
3118
|
-
} else {
|
|
3119
|
-
console.log(
|
|
3120
|
-
`[Venus Simulation Mock] Auto-restarting ${run.recipeId} (no condition)`
|
|
3121
|
-
);
|
|
3122
|
-
setTimeout(() => {
|
|
3123
|
-
this.executeRecipe(appIdentifier, run.recipeId, recipe.inputs || {});
|
|
3124
|
-
}, 1e3);
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3127
|
-
console.log(
|
|
3128
|
-
`[Venus Simulation Mock] Completed run ${runId}, outputs:`,
|
|
3129
|
-
outputs
|
|
3130
|
-
);
|
|
3131
|
-
}
|
|
3132
|
-
createSeededRandom(seed) {
|
|
3133
|
-
let hash = 0;
|
|
3134
|
-
for (let i = 0; i < seed.length; i++) {
|
|
3135
|
-
const char = seed.charCodeAt(i);
|
|
3136
|
-
hash = (hash << 5) - hash + char;
|
|
3137
|
-
hash = hash & hash;
|
|
3138
|
-
}
|
|
3139
|
-
return () => {
|
|
3140
|
-
hash = (hash * 9301 + 49297) % 233280;
|
|
3141
|
-
return hash / 233280;
|
|
3142
|
-
};
|
|
3143
|
-
}
|
|
3144
|
-
applyEffects(state, effects) {
|
|
3145
|
-
if (!effects || !Array.isArray(effects)) return;
|
|
3146
|
-
for (const effect of effects) {
|
|
3147
|
-
switch (effect.type) {
|
|
3148
|
-
case "set":
|
|
3149
|
-
state.inventory[effect.target] = effect.value;
|
|
3150
|
-
console.log(
|
|
3151
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} = ${effect.value}`
|
|
3152
|
-
);
|
|
3153
|
-
break;
|
|
3154
|
-
case "add":
|
|
3155
|
-
state.inventory[effect.target] = (state.inventory[effect.target] || 0) + effect.value;
|
|
3156
|
-
console.log(
|
|
3157
|
-
`[Venus Simulation Mock] Effect: Add ${effect.value} to ${effect.target} (new value: ${state.inventory[effect.target]})`
|
|
3158
|
-
);
|
|
3159
|
-
break;
|
|
3160
|
-
case "multiply":
|
|
3161
|
-
state.inventory[effect.target] = (state.inventory[effect.target] || 0) * effect.value;
|
|
3162
|
-
console.log(
|
|
3163
|
-
`[Venus Simulation Mock] Effect: Multiply ${effect.target} by ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3164
|
-
);
|
|
3165
|
-
break;
|
|
3166
|
-
case "min":
|
|
3167
|
-
state.inventory[effect.target] = Math.max(
|
|
3168
|
-
state.inventory[effect.target] || 0,
|
|
3169
|
-
effect.value
|
|
3170
|
-
);
|
|
3171
|
-
console.log(
|
|
3172
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} min ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3173
|
-
);
|
|
3174
|
-
break;
|
|
3175
|
-
case "max":
|
|
3176
|
-
state.inventory[effect.target] = Math.min(
|
|
3177
|
-
state.inventory[effect.target] || 0,
|
|
3178
|
-
effect.value
|
|
3179
|
-
);
|
|
3180
|
-
console.log(
|
|
3181
|
-
`[Venus Simulation Mock] Effect: Set ${effect.target} max ${effect.value} (new value: ${state.inventory[effect.target]})`
|
|
3182
|
-
);
|
|
3183
|
-
break;
|
|
3184
|
-
case "enable_recipe":
|
|
3185
|
-
if (state.disabledRecipes?.includes(effect.target)) {
|
|
3186
|
-
state.disabledRecipes = state.disabledRecipes.filter(
|
|
3187
|
-
(r) => r !== effect.target
|
|
3188
|
-
);
|
|
3189
|
-
console.log(
|
|
3190
|
-
`[Venus Simulation Mock] Effect: Enabled recipe ${effect.target}`
|
|
3191
|
-
);
|
|
3192
|
-
}
|
|
3193
|
-
break;
|
|
3194
|
-
case "disable_recipe":
|
|
3195
|
-
if (!state.disabledRecipes) state.disabledRecipes = [];
|
|
3196
|
-
if (!state.disabledRecipes.includes(effect.target)) {
|
|
3197
|
-
state.disabledRecipes.push(effect.target);
|
|
3198
|
-
console.log(
|
|
3199
|
-
`[Venus Simulation Mock] Effect: Disabled recipe ${effect.target}`
|
|
3200
|
-
);
|
|
3201
|
-
}
|
|
3202
|
-
break;
|
|
3203
|
-
case "trigger_recipe":
|
|
3204
|
-
console.log(
|
|
3205
|
-
`[Venus Simulation Mock] Effect: Trigger recipe ${effect.target} (not implemented)`
|
|
3206
|
-
);
|
|
3207
|
-
break;
|
|
3208
|
-
default:
|
|
3209
|
-
console.warn(
|
|
3210
|
-
`[Venus Simulation Mock] Unknown effect type: ${effect.type}`
|
|
3211
|
-
);
|
|
3212
|
-
}
|
|
3213
2931
|
}
|
|
3214
2932
|
}
|
|
3215
|
-
async getConfigAsync() {
|
|
3216
|
-
console.log("[Venus Simulation Mock] getConfigAsync called");
|
|
3217
|
-
const appIdentifier = this.appId;
|
|
3218
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3219
|
-
const config = mockSimulationConfigs.get(appIdentifier) || {
|
|
3220
|
-
version: "1.0",
|
|
3221
|
-
entities: {},
|
|
3222
|
-
recipes: {}
|
|
3223
|
-
};
|
|
3224
|
-
return config;
|
|
3225
|
-
}
|
|
3226
|
-
async getStateAsync(roomId) {
|
|
3227
|
-
this.log("getStateAsync called:", roomId);
|
|
3228
|
-
const appIdentifier = this.appId;
|
|
3229
|
-
const mockSimulationStates = this.mockSimulationStates;
|
|
3230
|
-
let state = mockSimulationStates.get(appIdentifier);
|
|
3231
|
-
if (!state) {
|
|
3232
|
-
state = await this.initializeSimulationState(appIdentifier);
|
|
3233
|
-
}
|
|
3234
|
-
const mockSimulationConfigs = this.mockSimulationConfigs;
|
|
3235
|
-
return {
|
|
3236
|
-
...state,
|
|
3237
|
-
roomId,
|
|
3238
|
-
configuration: mockSimulationConfigs.get(appIdentifier)
|
|
3239
|
-
};
|
|
3240
|
-
}
|
|
3241
|
-
async assignItemToSlotAsync(containerId, slotId, itemId) {
|
|
3242
|
-
this.log("assignItemToSlotAsync called:", {
|
|
3243
|
-
containerId,
|
|
3244
|
-
slotId,
|
|
3245
|
-
itemId
|
|
3246
|
-
});
|
|
3247
|
-
return { success: true, message: "Mock assignment successful" };
|
|
3248
|
-
}
|
|
3249
|
-
async removeItemFromSlotAsync(containerId, slotId) {
|
|
3250
|
-
this.log("removeItemFromSlotAsync called:", {
|
|
3251
|
-
containerId,
|
|
3252
|
-
slotId
|
|
3253
|
-
});
|
|
3254
|
-
return { success: true, message: "Mock removal successful" };
|
|
3255
|
-
}
|
|
3256
2933
|
};
|
|
3257
2934
|
|
|
3258
2935
|
// src/simulation/index.ts
|
|
3259
2936
|
function initializeSimulation(venusApi, host) {
|
|
3260
|
-
console.log("[Venus SDK] Initializing new Simulation Api");
|
|
3261
2937
|
venusApi.simulation = {
|
|
3262
2938
|
isEnabled: () => true
|
|
3263
2939
|
};
|
|
3264
2940
|
venusApi.simulation.getConfigAsync = () => {
|
|
3265
2941
|
return host.simulation.getConfigAsync();
|
|
3266
2942
|
};
|
|
3267
|
-
venusApi.simulation.getStateAsync = (
|
|
3268
|
-
return host.simulation.getStateAsync(
|
|
2943
|
+
venusApi.simulation.getStateAsync = (roomId) => {
|
|
2944
|
+
return host.simulation.getStateAsync(roomId);
|
|
3269
2945
|
};
|
|
3270
2946
|
venusApi.simulation.executeRecipeAsync = (recipeId, inputs, options) => {
|
|
3271
2947
|
return host.simulation.executeRecipeAsync(recipeId, inputs, options);
|
|
@@ -3276,31 +2952,17 @@ function initializeSimulation(venusApi, host) {
|
|
|
3276
2952
|
venusApi.simulation.collectRecipeAsync = (runId) => {
|
|
3277
2953
|
return host.simulation.collectRecipeAsync(runId);
|
|
3278
2954
|
};
|
|
3279
|
-
venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs,
|
|
3280
|
-
return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs,
|
|
3281
|
-
roomId,
|
|
3282
|
-
...options
|
|
3283
|
-
});
|
|
2955
|
+
venusApi.simulation.executeScopedRecipeAsync = (recipeId, entity, inputs, options) => {
|
|
2956
|
+
return host.simulation.executeScopedRecipeAsync(recipeId, entity, inputs, options);
|
|
3284
2957
|
};
|
|
3285
|
-
venusApi.simulation.triggerRecipeChainAsync = (recipeId,
|
|
3286
|
-
return host.simulation.triggerRecipeChainAsync(recipeId,
|
|
3287
|
-
context,
|
|
3288
|
-
roomId
|
|
3289
|
-
});
|
|
2958
|
+
venusApi.simulation.triggerRecipeChainAsync = (recipeId, options) => {
|
|
2959
|
+
return host.simulation.triggerRecipeChainAsync(recipeId, options);
|
|
3290
2960
|
};
|
|
3291
|
-
venusApi.simulation.getAvailableRecipesAsync = async (
|
|
3292
|
-
|
|
3293
|
-
roomId,
|
|
3294
|
-
includeActorRecipes
|
|
3295
|
-
});
|
|
3296
|
-
return result.recipes;
|
|
2961
|
+
venusApi.simulation.getAvailableRecipesAsync = async (options) => {
|
|
2962
|
+
return host.simulation.getAvailableRecipesAsync(options);
|
|
3297
2963
|
};
|
|
3298
|
-
venusApi.simulation.getRecipeRequirementsAsync = (
|
|
3299
|
-
return host.simulation.getRecipeRequirementsAsync(
|
|
3300
|
-
recipeId,
|
|
3301
|
-
entity,
|
|
3302
|
-
batchAmount: amount
|
|
3303
|
-
});
|
|
2964
|
+
venusApi.simulation.getRecipeRequirementsAsync = (recipe) => {
|
|
2965
|
+
return host.simulation.getRecipeRequirementsAsync(recipe);
|
|
3304
2966
|
};
|
|
3305
2967
|
venusApi.simulation.getBatchRecipeRequirementsAsync = (recipes) => {
|
|
3306
2968
|
return host.simulation.getBatchRecipeRequirementsAsync(recipes);
|
|
@@ -3343,9 +3005,6 @@ function initializeSimulation(venusApi, host) {
|
|
|
3343
3005
|
itemId
|
|
3344
3006
|
);
|
|
3345
3007
|
};
|
|
3346
|
-
venusApi.simulation.sumContributions = (contributions) => {
|
|
3347
|
-
return host.simulation.sumContributions(contributions);
|
|
3348
|
-
};
|
|
3349
3008
|
}
|
|
3350
3009
|
|
|
3351
3010
|
// src/time/utils.ts
|
|
@@ -3364,9 +3023,11 @@ function isPacificDaylightTime(date) {
|
|
|
3364
3023
|
|
|
3365
3024
|
// src/time/HostTimeApi.ts
|
|
3366
3025
|
var HostTimeApi = class {
|
|
3367
|
-
constructor(rpcClient) {
|
|
3026
|
+
constructor(rpcClient, venusApi) {
|
|
3368
3027
|
__publicField(this, "rpcClient");
|
|
3028
|
+
__publicField(this, "venusApi");
|
|
3369
3029
|
this.rpcClient = rpcClient;
|
|
3030
|
+
this.venusApi = venusApi;
|
|
3370
3031
|
}
|
|
3371
3032
|
async requestTimeAsync() {
|
|
3372
3033
|
const response = await this.rpcClient.call(
|
|
@@ -3376,13 +3037,7 @@ var HostTimeApi = class {
|
|
|
3376
3037
|
return response;
|
|
3377
3038
|
}
|
|
3378
3039
|
formatTime(timestamp, options) {
|
|
3379
|
-
|
|
3380
|
-
const windowVenus = window.venus;
|
|
3381
|
-
if (windowVenus._config.locale) {
|
|
3382
|
-
locale = windowVenus._config.locale;
|
|
3383
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3384
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
3385
|
-
}
|
|
3040
|
+
const locale = this.venusApi.getLocale();
|
|
3386
3041
|
const date = new Date(timestamp);
|
|
3387
3042
|
const dateTimeOptions = {
|
|
3388
3043
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -3394,13 +3049,7 @@ var HostTimeApi = class {
|
|
|
3394
3049
|
}
|
|
3395
3050
|
formatNumber(value, options) {
|
|
3396
3051
|
try {
|
|
3397
|
-
|
|
3398
|
-
const windowVenus = window.venus;
|
|
3399
|
-
if (windowVenus._config.locale) {
|
|
3400
|
-
locale = windowVenus._config.locale;
|
|
3401
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
3402
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
3403
|
-
}
|
|
3052
|
+
const locale = this.venusApi.getLocale();
|
|
3404
3053
|
const numberOptions = {
|
|
3405
3054
|
style: options?.style || "decimal",
|
|
3406
3055
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
@@ -3463,18 +3112,17 @@ var MockTimeApi = class {
|
|
|
3463
3112
|
this.venusApi = venusApi;
|
|
3464
3113
|
}
|
|
3465
3114
|
formatNumber(value, options) {
|
|
3466
|
-
const locale = this.getLocale();
|
|
3115
|
+
const locale = this.venusApi.getLocale();
|
|
3467
3116
|
const numberOptions = {
|
|
3468
3117
|
style: options?.style || "decimal",
|
|
3469
3118
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
3470
3119
|
maximumFractionDigits: options?.maximumFractionDigits || 2,
|
|
3471
3120
|
...options
|
|
3472
3121
|
};
|
|
3473
|
-
console.log(`[Venus Mock] Formatting number ${value} with locale ${locale}`);
|
|
3474
3122
|
return value.toLocaleString(locale, numberOptions);
|
|
3475
3123
|
}
|
|
3476
3124
|
formatTime(timestamp, options) {
|
|
3477
|
-
const locale = this.getLocale();
|
|
3125
|
+
const locale = this.venusApi.getLocale();
|
|
3478
3126
|
const date = new Date(timestamp);
|
|
3479
3127
|
const dateTimeOptions = {
|
|
3480
3128
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -3482,13 +3130,9 @@ var MockTimeApi = class {
|
|
|
3482
3130
|
hour12: options.hour12 !== void 0 ? options.hour12 : true,
|
|
3483
3131
|
...options
|
|
3484
3132
|
};
|
|
3485
|
-
console.log(
|
|
3486
|
-
`[Venus Mock] Formatting time ${timestamp} with locale ${locale}`
|
|
3487
|
-
);
|
|
3488
3133
|
return date.toLocaleString(locale, dateTimeOptions);
|
|
3489
3134
|
}
|
|
3490
3135
|
async getFutureTimeAsync(options) {
|
|
3491
|
-
console.log("[Venus Mock] Getting future time with options:", options);
|
|
3492
3136
|
const timeInfo = await this.requestTimeAsync();
|
|
3493
3137
|
const serverTime = new Date(timeInfo.serverTime);
|
|
3494
3138
|
const result = new Date(serverTime);
|
|
@@ -3533,7 +3177,6 @@ var MockTimeApi = class {
|
|
|
3533
3177
|
return result.getTime();
|
|
3534
3178
|
}
|
|
3535
3179
|
async requestTimeAsync() {
|
|
3536
|
-
console.log("[Venus Mock] Requesting time");
|
|
3537
3180
|
await createMockDelay(MOCK_DELAYS.short);
|
|
3538
3181
|
const venusApi = this.venusApi;
|
|
3539
3182
|
const mockOffset = venusApi._mock.serverTimeOffset || 2500;
|
|
@@ -3547,23 +3190,8 @@ var MockTimeApi = class {
|
|
|
3547
3190
|
formattedTime: new Date(localTime).toISOString(),
|
|
3548
3191
|
locale: venusApi._mock.user?.locale || "en-US"
|
|
3549
3192
|
};
|
|
3550
|
-
console.log("[Venus Mock] Time response:", {
|
|
3551
|
-
serverTime: new Date(timeInfo.serverTime).toISOString(),
|
|
3552
|
-
localTime: new Date(timeInfo.localTime).toISOString(),
|
|
3553
|
-
timezoneOffset: timeInfo.timezoneOffset
|
|
3554
|
-
});
|
|
3555
3193
|
return timeInfo;
|
|
3556
3194
|
}
|
|
3557
|
-
getLocale() {
|
|
3558
|
-
const venusApi = this.venusApi;
|
|
3559
|
-
let locale = "en-US";
|
|
3560
|
-
if (venusApi._mock.user && venusApi._mock.user.locale) {
|
|
3561
|
-
locale = venusApi._mock.user.locale;
|
|
3562
|
-
} else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
|
|
3563
|
-
locale = venusApi._mock.environment.browserInfo.language;
|
|
3564
|
-
}
|
|
3565
|
-
return locale;
|
|
3566
|
-
}
|
|
3567
3195
|
};
|
|
3568
3196
|
|
|
3569
3197
|
// src/time/index.ts
|
|
@@ -3583,7 +3211,7 @@ function initializeTime(venusApi, host) {
|
|
|
3583
3211
|
}
|
|
3584
3212
|
|
|
3585
3213
|
// src/version.ts
|
|
3586
|
-
var SDK_VERSION = "3.0.
|
|
3214
|
+
var SDK_VERSION = "3.0.5";
|
|
3587
3215
|
|
|
3588
3216
|
// src/shared-assets/consts.ts
|
|
3589
3217
|
var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
|
|
@@ -3654,47 +3282,106 @@ var MockSharedAssetsApi = class {
|
|
|
3654
3282
|
}
|
|
3655
3283
|
};
|
|
3656
3284
|
|
|
3285
|
+
// src/leaderboard/utils.ts
|
|
3286
|
+
var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
|
|
3287
|
+
var HASH_ALGORITHM_NODE = "sha256";
|
|
3288
|
+
async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
|
|
3289
|
+
const payload = `score:${score}|duration:${duration}|token:${token}`;
|
|
3290
|
+
const fullPayload = `${payload}|nonce:${sealingNonce}`;
|
|
3291
|
+
const encoder = new TextEncoder();
|
|
3292
|
+
const keyData = encoder.encode(sealingSecret);
|
|
3293
|
+
const messageData = encoder.encode(fullPayload);
|
|
3294
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
3295
|
+
"raw",
|
|
3296
|
+
keyData,
|
|
3297
|
+
{ name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
|
|
3298
|
+
false,
|
|
3299
|
+
["sign"]
|
|
3300
|
+
);
|
|
3301
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
|
|
3302
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3657
3305
|
// src/leaderboard/RpcLeaderboardApi.ts
|
|
3658
3306
|
var RpcLeaderboardApi = class {
|
|
3659
3307
|
constructor(rpcClient) {
|
|
3660
3308
|
__publicField(this, "rpcClient");
|
|
3309
|
+
/** Cache of score tokens for automatic hash computation */
|
|
3310
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
3661
3311
|
this.rpcClient = rpcClient;
|
|
3662
3312
|
}
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3313
|
+
/**
|
|
3314
|
+
* Create a score token for submitting a score.
|
|
3315
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
3316
|
+
*
|
|
3317
|
+
* @param mode - Optional game mode
|
|
3318
|
+
* @returns Score token with sealing data if enabled
|
|
3319
|
+
*/
|
|
3320
|
+
async createScoreToken(mode) {
|
|
3321
|
+
const token = await this.rpcClient.call(
|
|
3322
|
+
"H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
|
|
3666
3323
|
mode ? { mode } : {}
|
|
3667
3324
|
);
|
|
3325
|
+
this.tokenCache.set(token.token, token);
|
|
3326
|
+
return token;
|
|
3668
3327
|
}
|
|
3669
|
-
|
|
3328
|
+
/**
|
|
3329
|
+
* Submit a score to the leaderboard.
|
|
3330
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
3331
|
+
*
|
|
3332
|
+
* @param params - Score submission parameters
|
|
3333
|
+
* @returns Submission result with acceptance status and rank
|
|
3334
|
+
* @throws Error if token not found in cache
|
|
3335
|
+
*/
|
|
3336
|
+
async submitScore(params) {
|
|
3337
|
+
let hash;
|
|
3338
|
+
if (params.token) {
|
|
3339
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
3340
|
+
if (!cachedToken) {
|
|
3341
|
+
throw new Error(
|
|
3342
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
3343
|
+
);
|
|
3344
|
+
}
|
|
3345
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
3346
|
+
hash = await computeScoreHash(
|
|
3347
|
+
params.score,
|
|
3348
|
+
params.duration,
|
|
3349
|
+
params.token,
|
|
3350
|
+
cachedToken.sealingNonce,
|
|
3351
|
+
cachedToken.sealingSecret
|
|
3352
|
+
);
|
|
3353
|
+
}
|
|
3354
|
+
this.tokenCache.delete(params.token);
|
|
3355
|
+
}
|
|
3670
3356
|
return this.rpcClient.call(
|
|
3671
3357
|
"H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
|
|
3672
3358
|
{
|
|
3673
|
-
|
|
3674
|
-
score,
|
|
3675
|
-
|
|
3676
|
-
mode:
|
|
3677
|
-
telemetry:
|
|
3678
|
-
metadata:
|
|
3679
|
-
hash
|
|
3359
|
+
token: params.token,
|
|
3360
|
+
score: params.score,
|
|
3361
|
+
duration: params.duration,
|
|
3362
|
+
mode: params.mode,
|
|
3363
|
+
telemetry: params.telemetry,
|
|
3364
|
+
metadata: params.metadata,
|
|
3365
|
+
hash
|
|
3366
|
+
// undefined if no sealing, computed if sealing enabled
|
|
3680
3367
|
}
|
|
3681
3368
|
);
|
|
3682
3369
|
}
|
|
3683
|
-
|
|
3370
|
+
getPagedScores(options) {
|
|
3684
3371
|
return this.rpcClient.call(
|
|
3685
|
-
"
|
|
3372
|
+
"H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
|
|
3686
3373
|
options ?? {}
|
|
3687
3374
|
);
|
|
3688
3375
|
}
|
|
3689
|
-
|
|
3376
|
+
getMyRank(options) {
|
|
3690
3377
|
return this.rpcClient.call(
|
|
3691
|
-
"
|
|
3378
|
+
"H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
|
|
3692
3379
|
options ?? {}
|
|
3693
3380
|
);
|
|
3694
3381
|
}
|
|
3695
|
-
|
|
3382
|
+
getPodiumScores(options) {
|
|
3696
3383
|
return this.rpcClient.call(
|
|
3697
|
-
"
|
|
3384
|
+
"H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
|
|
3698
3385
|
options ?? {}
|
|
3699
3386
|
);
|
|
3700
3387
|
}
|
|
@@ -3703,17 +3390,31 @@ var RpcLeaderboardApi = class {
|
|
|
3703
3390
|
// src/leaderboard/MockLeaderboardApi.ts
|
|
3704
3391
|
var MockLeaderboardApi = class {
|
|
3705
3392
|
constructor(options) {
|
|
3706
|
-
__publicField(this, "
|
|
3393
|
+
__publicField(this, "tokens", /* @__PURE__ */ new Map());
|
|
3394
|
+
/** Cache of score tokens for automatic hash computation */
|
|
3395
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
3707
3396
|
__publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
|
|
3708
|
-
__publicField(this, "
|
|
3709
|
-
__publicField(this, "
|
|
3710
|
-
|
|
3711
|
-
|
|
3397
|
+
__publicField(this, "tokenCounter", 0);
|
|
3398
|
+
__publicField(this, "enableScoreSealing", false);
|
|
3399
|
+
__publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
|
|
3400
|
+
if (options?.enableScoreSealing) {
|
|
3401
|
+
this.enableScoreSealing = true;
|
|
3402
|
+
}
|
|
3403
|
+
if (options?.scoreSealingSecret) {
|
|
3404
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
3712
3405
|
}
|
|
3713
3406
|
}
|
|
3407
|
+
/**
|
|
3408
|
+
* Configure mock leaderboard settings
|
|
3409
|
+
*
|
|
3410
|
+
* @param options - Configuration options
|
|
3411
|
+
*/
|
|
3714
3412
|
configure(options) {
|
|
3715
|
-
if (typeof options.
|
|
3716
|
-
this.
|
|
3413
|
+
if (typeof options.enableScoreSealing === "boolean") {
|
|
3414
|
+
this.enableScoreSealing = options.enableScoreSealing;
|
|
3415
|
+
}
|
|
3416
|
+
if (options.scoreSealingSecret) {
|
|
3417
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
3717
3418
|
}
|
|
3718
3419
|
}
|
|
3719
3420
|
generateNonce() {
|
|
@@ -3730,83 +3431,149 @@ var MockLeaderboardApi = class {
|
|
|
3730
3431
|
}
|
|
3731
3432
|
return this.entriesByMode.get(key);
|
|
3732
3433
|
}
|
|
3733
|
-
|
|
3734
|
-
|
|
3434
|
+
/**
|
|
3435
|
+
* Create a mock score token for testing.
|
|
3436
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
3437
|
+
*
|
|
3438
|
+
* @param mode - Optional game mode
|
|
3439
|
+
* @returns Score token with sealing data if enabled
|
|
3440
|
+
*/
|
|
3441
|
+
async createScoreToken(mode) {
|
|
3442
|
+
const token = `mock_token_${++this.tokenCounter}`;
|
|
3735
3443
|
const startTime = Date.now();
|
|
3736
3444
|
const expiresAt = startTime + 36e5;
|
|
3737
3445
|
const resolvedMode = mode || "default";
|
|
3738
|
-
const
|
|
3739
|
-
this.
|
|
3740
|
-
|
|
3446
|
+
const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
|
|
3447
|
+
const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
|
|
3448
|
+
this.tokens.set(token, {
|
|
3449
|
+
id: token,
|
|
3741
3450
|
expiresAt,
|
|
3742
3451
|
mode: resolvedMode,
|
|
3743
|
-
|
|
3452
|
+
sealingNonce,
|
|
3744
3453
|
used: false
|
|
3745
3454
|
});
|
|
3746
|
-
|
|
3747
|
-
|
|
3455
|
+
const result = {
|
|
3456
|
+
token,
|
|
3748
3457
|
startTime,
|
|
3749
3458
|
expiresAt,
|
|
3750
|
-
|
|
3459
|
+
sealingNonce,
|
|
3460
|
+
sealingSecret,
|
|
3751
3461
|
mode: resolvedMode
|
|
3752
3462
|
};
|
|
3463
|
+
this.tokenCache.set(token, result);
|
|
3464
|
+
return result;
|
|
3753
3465
|
}
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3466
|
+
/**
|
|
3467
|
+
* Submit a mock score to the leaderboard.
|
|
3468
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
3469
|
+
*
|
|
3470
|
+
* @param params - Score submission parameters
|
|
3471
|
+
* @returns Submission result with acceptance status and rank
|
|
3472
|
+
* @throws Error if token not found in cache or validation fails
|
|
3473
|
+
*/
|
|
3474
|
+
async submitScore(params) {
|
|
3475
|
+
let hash;
|
|
3476
|
+
if (params.token) {
|
|
3477
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
3478
|
+
if (!cachedToken) {
|
|
3479
|
+
throw new Error(
|
|
3480
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
3481
|
+
);
|
|
3482
|
+
}
|
|
3483
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
3484
|
+
hash = await computeScoreHash(
|
|
3485
|
+
params.score,
|
|
3486
|
+
params.duration,
|
|
3487
|
+
params.token,
|
|
3488
|
+
cachedToken.sealingNonce,
|
|
3489
|
+
cachedToken.sealingSecret
|
|
3490
|
+
);
|
|
3491
|
+
}
|
|
3758
3492
|
}
|
|
3759
|
-
if (
|
|
3760
|
-
|
|
3493
|
+
if (!params.token) {
|
|
3494
|
+
const mode = params.mode || "default";
|
|
3495
|
+
const submittedAt2 = Date.now();
|
|
3496
|
+
const entry2 = {
|
|
3497
|
+
profileId: `mock_profile`,
|
|
3498
|
+
username: "Mock Player",
|
|
3499
|
+
avatarUrl: null,
|
|
3500
|
+
score: params.score,
|
|
3501
|
+
duration: params.duration,
|
|
3502
|
+
submittedAt: submittedAt2,
|
|
3503
|
+
token: "simple-mode",
|
|
3504
|
+
rank: null,
|
|
3505
|
+
zScore: null,
|
|
3506
|
+
isAnomaly: false,
|
|
3507
|
+
trustScore: 50,
|
|
3508
|
+
metadata: params.metadata ?? null,
|
|
3509
|
+
isSeed: false
|
|
3510
|
+
};
|
|
3511
|
+
const modeEntries2 = this.getEntriesForMode(mode);
|
|
3512
|
+
modeEntries2.push(entry2);
|
|
3513
|
+
modeEntries2.sort((a, b) => {
|
|
3514
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
3515
|
+
return a.submittedAt - b.submittedAt;
|
|
3516
|
+
});
|
|
3517
|
+
modeEntries2.forEach((e, index) => {
|
|
3518
|
+
modeEntries2[index] = { ...e, rank: index + 1 };
|
|
3519
|
+
});
|
|
3520
|
+
const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
|
|
3521
|
+
return {
|
|
3522
|
+
accepted: true,
|
|
3523
|
+
rank: inserted2?.rank ?? null
|
|
3524
|
+
};
|
|
3525
|
+
}
|
|
3526
|
+
const scoreToken = this.tokens.get(params.token);
|
|
3527
|
+
if (!scoreToken) {
|
|
3528
|
+
throw new Error("Invalid score token");
|
|
3761
3529
|
}
|
|
3762
|
-
if (
|
|
3763
|
-
throw new Error("
|
|
3530
|
+
if (scoreToken.expiresAt < Date.now()) {
|
|
3531
|
+
throw new Error("Invalid or expired score token");
|
|
3764
3532
|
}
|
|
3765
|
-
if (
|
|
3766
|
-
throw new Error("
|
|
3533
|
+
if (scoreToken.used) {
|
|
3534
|
+
throw new Error("Score token already used");
|
|
3767
3535
|
}
|
|
3768
|
-
if (
|
|
3769
|
-
throw new Error("
|
|
3536
|
+
if (params.mode && params.mode !== scoreToken.mode) {
|
|
3537
|
+
throw new Error("Submission mode does not match token mode");
|
|
3538
|
+
}
|
|
3539
|
+
if (scoreToken.sealingNonce && !hash) {
|
|
3540
|
+
throw new Error("Score hash required when score sealing is enabled");
|
|
3770
3541
|
}
|
|
3771
3542
|
const submittedAt = Date.now();
|
|
3772
3543
|
const entry = {
|
|
3773
3544
|
profileId: `mock_profile`,
|
|
3774
3545
|
username: "Mock Player",
|
|
3775
3546
|
avatarUrl: null,
|
|
3776
|
-
score,
|
|
3777
|
-
|
|
3547
|
+
score: params.score,
|
|
3548
|
+
duration: params.duration,
|
|
3778
3549
|
submittedAt,
|
|
3779
|
-
|
|
3550
|
+
token: params.token,
|
|
3780
3551
|
rank: null,
|
|
3781
3552
|
zScore: null,
|
|
3782
3553
|
isAnomaly: false,
|
|
3783
3554
|
trustScore: 50,
|
|
3784
|
-
metadata:
|
|
3555
|
+
metadata: params.metadata ?? null,
|
|
3785
3556
|
isSeed: false
|
|
3786
3557
|
};
|
|
3787
|
-
const modeEntries = this.getEntriesForMode(
|
|
3558
|
+
const modeEntries = this.getEntriesForMode(scoreToken.mode);
|
|
3788
3559
|
modeEntries.push(entry);
|
|
3789
3560
|
modeEntries.sort((a, b) => {
|
|
3790
|
-
if (b.score !== a.score)
|
|
3791
|
-
return b.score - a.score;
|
|
3792
|
-
}
|
|
3561
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
3793
3562
|
return a.submittedAt - b.submittedAt;
|
|
3794
3563
|
});
|
|
3795
3564
|
modeEntries.forEach((e, index) => {
|
|
3796
|
-
modeEntries[index] = {
|
|
3797
|
-
...e,
|
|
3798
|
-
rank: index + 1
|
|
3799
|
-
};
|
|
3565
|
+
modeEntries[index] = { ...e, rank: index + 1 };
|
|
3800
3566
|
});
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3567
|
+
scoreToken.used = true;
|
|
3568
|
+
scoreToken.sealingNonce = null;
|
|
3569
|
+
this.tokenCache.delete(params.token);
|
|
3570
|
+
const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
|
|
3804
3571
|
return {
|
|
3805
3572
|
accepted: true,
|
|
3806
3573
|
rank: inserted?.rank ?? null
|
|
3807
3574
|
};
|
|
3808
3575
|
}
|
|
3809
|
-
async
|
|
3576
|
+
async getPagedScores(options) {
|
|
3810
3577
|
const limit = options?.limit ?? 10;
|
|
3811
3578
|
const mode = options?.mode ?? "default";
|
|
3812
3579
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
@@ -3822,7 +3589,7 @@ var MockLeaderboardApi = class {
|
|
|
3822
3589
|
periodInstance: options?.period ?? "alltime"
|
|
3823
3590
|
};
|
|
3824
3591
|
}
|
|
3825
|
-
async
|
|
3592
|
+
async getMyRank(_options) {
|
|
3826
3593
|
const mode = _options?.mode ?? "default";
|
|
3827
3594
|
const modeEntries = this.getEntriesForMode(mode);
|
|
3828
3595
|
const playerEntry = modeEntries[0] ?? null;
|
|
@@ -3835,7 +3602,7 @@ var MockLeaderboardApi = class {
|
|
|
3835
3602
|
periodInstance: _options?.period ?? "alltime"
|
|
3836
3603
|
};
|
|
3837
3604
|
}
|
|
3838
|
-
async
|
|
3605
|
+
async getPodiumScores(options) {
|
|
3839
3606
|
const mode = options?.mode ?? "default";
|
|
3840
3607
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
3841
3608
|
const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
|
|
@@ -3947,7 +3714,6 @@ var MockPostApi = class {
|
|
|
3947
3714
|
}
|
|
3948
3715
|
async toggleFollowAsync() {
|
|
3949
3716
|
const venusApi = this.venusApi;
|
|
3950
|
-
console.log("[Venus Mock] *Toggling follow status");
|
|
3951
3717
|
await createMockDelay(MOCK_DELAYS.short);
|
|
3952
3718
|
venusApi._mock.currentPostInteractions.isFollowing = !venusApi._mock.currentPostInteractions.isFollowing;
|
|
3953
3719
|
const isFollowing = venusApi._mock.currentPostInteractions.isFollowing;
|
|
@@ -4000,9 +3766,6 @@ var RpcPostApi = class {
|
|
|
4000
3766
|
}
|
|
4001
3767
|
};
|
|
4002
3768
|
|
|
4003
|
-
// src/MockHost.ts
|
|
4004
|
-
init_rooms();
|
|
4005
|
-
|
|
4006
3769
|
// src/social/MockSocialApi.ts
|
|
4007
3770
|
var MOCK_QR_CODE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
|
|
4008
3771
|
var MockSocialApi = class {
|
|
@@ -4039,44 +3802,116 @@ var ROOMS_UNAVAILABLE_MESSAGE = "[Venus SDK] Rooms API is only available when ru
|
|
|
4039
3802
|
function createUnavailableRoomsApi() {
|
|
4040
3803
|
const roomsUnavailableError = () => new Error(ROOMS_UNAVAILABLE_MESSAGE);
|
|
4041
3804
|
return {
|
|
4042
|
-
async
|
|
3805
|
+
async createRoomAsync() {
|
|
4043
3806
|
throw roomsUnavailableError();
|
|
4044
3807
|
},
|
|
4045
|
-
async
|
|
3808
|
+
async joinOrCreateRoomAsync() {
|
|
4046
3809
|
throw roomsUnavailableError();
|
|
4047
3810
|
},
|
|
4048
|
-
async
|
|
3811
|
+
async joinRoomByCodeAsync() {
|
|
4049
3812
|
throw roomsUnavailableError();
|
|
4050
3813
|
},
|
|
4051
|
-
async
|
|
3814
|
+
async getUserRoomsAsync() {
|
|
4052
3815
|
throw roomsUnavailableError();
|
|
4053
3816
|
},
|
|
4054
|
-
|
|
3817
|
+
async subscribeAsync() {
|
|
4055
3818
|
throw roomsUnavailableError();
|
|
4056
3819
|
},
|
|
4057
|
-
async
|
|
3820
|
+
async updateRoomDataAsync() {
|
|
4058
3821
|
throw roomsUnavailableError();
|
|
4059
3822
|
},
|
|
4060
|
-
async
|
|
3823
|
+
async getRoomDataAsync() {
|
|
4061
3824
|
throw roomsUnavailableError();
|
|
4062
3825
|
},
|
|
4063
|
-
async
|
|
3826
|
+
async sendRoomMessageAsync() {
|
|
4064
3827
|
throw roomsUnavailableError();
|
|
4065
3828
|
},
|
|
4066
|
-
async
|
|
3829
|
+
async leaveRoomAsync() {
|
|
4067
3830
|
throw roomsUnavailableError();
|
|
4068
3831
|
},
|
|
4069
|
-
async
|
|
3832
|
+
async startRoomGameAsync() {
|
|
4070
3833
|
throw roomsUnavailableError();
|
|
4071
3834
|
},
|
|
4072
|
-
async
|
|
3835
|
+
async proposeMoveAsync() {
|
|
4073
3836
|
throw roomsUnavailableError();
|
|
4074
3837
|
},
|
|
4075
|
-
async
|
|
3838
|
+
async validateMoveAsync() {
|
|
4076
3839
|
throw roomsUnavailableError();
|
|
4077
3840
|
}
|
|
4078
3841
|
};
|
|
4079
3842
|
}
|
|
3843
|
+
var SIMULATION_UNAVAILABLE_MESSAGE = "[Venus SDK] Simulation API is only available when running inside the Venus host environment.";
|
|
3844
|
+
function createUnavailableSimulationApi() {
|
|
3845
|
+
const simulationUnavailableError = () => new Error(SIMULATION_UNAVAILABLE_MESSAGE);
|
|
3846
|
+
return {
|
|
3847
|
+
isEnabled() {
|
|
3848
|
+
return false;
|
|
3849
|
+
},
|
|
3850
|
+
async getStateAsync() {
|
|
3851
|
+
throw simulationUnavailableError();
|
|
3852
|
+
},
|
|
3853
|
+
async getConfigAsync() {
|
|
3854
|
+
throw simulationUnavailableError();
|
|
3855
|
+
},
|
|
3856
|
+
async executeRecipeAsync() {
|
|
3857
|
+
throw simulationUnavailableError();
|
|
3858
|
+
},
|
|
3859
|
+
async getActiveRunsAsync() {
|
|
3860
|
+
throw simulationUnavailableError();
|
|
3861
|
+
},
|
|
3862
|
+
async collectRecipeAsync() {
|
|
3863
|
+
throw simulationUnavailableError();
|
|
3864
|
+
},
|
|
3865
|
+
async executeScopedRecipeAsync() {
|
|
3866
|
+
throw simulationUnavailableError();
|
|
3867
|
+
},
|
|
3868
|
+
async triggerRecipeChainAsync() {
|
|
3869
|
+
throw simulationUnavailableError();
|
|
3870
|
+
},
|
|
3871
|
+
async getAvailableRecipesAsync() {
|
|
3872
|
+
throw simulationUnavailableError();
|
|
3873
|
+
},
|
|
3874
|
+
async getRecipeRequirementsAsync() {
|
|
3875
|
+
throw simulationUnavailableError();
|
|
3876
|
+
},
|
|
3877
|
+
async getBatchRecipeRequirementsAsync() {
|
|
3878
|
+
throw simulationUnavailableError();
|
|
3879
|
+
},
|
|
3880
|
+
async resolveFieldValueAsync() {
|
|
3881
|
+
throw simulationUnavailableError();
|
|
3882
|
+
},
|
|
3883
|
+
async getEntityMetadataAsync() {
|
|
3884
|
+
throw simulationUnavailableError();
|
|
3885
|
+
},
|
|
3886
|
+
async getSlotContainersAsync() {
|
|
3887
|
+
throw simulationUnavailableError();
|
|
3888
|
+
},
|
|
3889
|
+
async getSlotAssignmentsAsync() {
|
|
3890
|
+
throw simulationUnavailableError();
|
|
3891
|
+
},
|
|
3892
|
+
async assignItemToSlotAsync() {
|
|
3893
|
+
throw simulationUnavailableError();
|
|
3894
|
+
},
|
|
3895
|
+
async removeItemFromSlotAsync() {
|
|
3896
|
+
throw simulationUnavailableError();
|
|
3897
|
+
},
|
|
3898
|
+
async getAvailableItemsAsync() {
|
|
3899
|
+
throw simulationUnavailableError();
|
|
3900
|
+
},
|
|
3901
|
+
async calculatePowerPreviewAsync() {
|
|
3902
|
+
throw simulationUnavailableError();
|
|
3903
|
+
},
|
|
3904
|
+
async validateSlotAssignmentAsync() {
|
|
3905
|
+
throw simulationUnavailableError();
|
|
3906
|
+
},
|
|
3907
|
+
async executeBatchOperationsAsync() {
|
|
3908
|
+
throw simulationUnavailableError();
|
|
3909
|
+
},
|
|
3910
|
+
async subscribeAsync() {
|
|
3911
|
+
throw simulationUnavailableError();
|
|
3912
|
+
}
|
|
3913
|
+
};
|
|
3914
|
+
}
|
|
4080
3915
|
var MockHost = class {
|
|
4081
3916
|
constructor(venusApi) {
|
|
4082
3917
|
__publicField(this, "ads");
|
|
@@ -4131,7 +3966,7 @@ var MockHost = class {
|
|
|
4131
3966
|
this.haptics = new MockHapticsApi(venusApi);
|
|
4132
3967
|
this.features = new MockFeaturesApi();
|
|
4133
3968
|
this.lifecycle = this._mockLifecyclesApi;
|
|
4134
|
-
this.simulation =
|
|
3969
|
+
this.simulation = createUnavailableSimulationApi();
|
|
4135
3970
|
this.rooms = createUnavailableRoomsApi();
|
|
4136
3971
|
this.logging = new MockLoggingApi();
|
|
4137
3972
|
this.iap = new MockIapApi();
|
|
@@ -4664,6 +4499,16 @@ var VenusTransport = class {
|
|
|
4664
4499
|
this.isProcessingMessage = false;
|
|
4665
4500
|
return;
|
|
4666
4501
|
}
|
|
4502
|
+
if (message.type === "H5_SIMULATION_UPDATE" /* H5_SIMULATION_UPDATE */) {
|
|
4503
|
+
const notification = {
|
|
4504
|
+
type: "rpc-notification",
|
|
4505
|
+
id: message.type,
|
|
4506
|
+
payload: message.data
|
|
4507
|
+
};
|
|
4508
|
+
this.handleNotification(notification);
|
|
4509
|
+
this.isProcessingMessage = false;
|
|
4510
|
+
return;
|
|
4511
|
+
}
|
|
4667
4512
|
const requestId = messageData.requestId;
|
|
4668
4513
|
if (!requestId) {
|
|
4669
4514
|
this.logWarn("No requestId. Ignoring message...");
|
|
@@ -4830,294 +4675,6 @@ var VenusTransport = class {
|
|
|
4830
4675
|
}
|
|
4831
4676
|
};
|
|
4832
4677
|
|
|
4833
|
-
// src/RemoteHost.ts
|
|
4834
|
-
init_rooms();
|
|
4835
|
-
|
|
4836
|
-
// src/rooms/RpcRoomsApi.ts
|
|
4837
|
-
init_VenusRoom();
|
|
4838
|
-
var RpcRoomsApi = class {
|
|
4839
|
-
constructor(rpcClient) {
|
|
4840
|
-
__publicField(this, "rpcClient");
|
|
4841
|
-
__publicField(this, "subscriptions");
|
|
4842
|
-
__publicField(this, "transportSubscription", null);
|
|
4843
|
-
this.rpcClient = rpcClient;
|
|
4844
|
-
this.subscriptions = {
|
|
4845
|
-
data: {},
|
|
4846
|
-
messages: {},
|
|
4847
|
-
gameEvents: {},
|
|
4848
|
-
allEvents: {}
|
|
4849
|
-
};
|
|
4850
|
-
}
|
|
4851
|
-
/**
|
|
4852
|
-
* Get the subscription state for external access (used by setupRoomNotifications)
|
|
4853
|
-
*/
|
|
4854
|
-
getSubscriptions() {
|
|
4855
|
-
return this.subscriptions;
|
|
4856
|
-
}
|
|
4857
|
-
/**
|
|
4858
|
-
* Set up room notification routing from the transport
|
|
4859
|
-
*/
|
|
4860
|
-
setupNotifications(transport) {
|
|
4861
|
-
const { setupRoomNotifications: setupRoomNotifications2 } = (init_rooms(), __toCommonJS(rooms_exports));
|
|
4862
|
-
this.transportSubscription = setupRoomNotifications2(
|
|
4863
|
-
transport,
|
|
4864
|
-
() => this.getSubscriptions()
|
|
4865
|
-
);
|
|
4866
|
-
}
|
|
4867
|
-
/**
|
|
4868
|
-
* Clean up subscriptions and resources
|
|
4869
|
-
*/
|
|
4870
|
-
dispose() {
|
|
4871
|
-
if (this.transportSubscription) {
|
|
4872
|
-
this.transportSubscription.unsubscribe();
|
|
4873
|
-
this.transportSubscription = null;
|
|
4874
|
-
console.log("[Venus Rooms] Cleaned up room notification subscription");
|
|
4875
|
-
}
|
|
4876
|
-
}
|
|
4877
|
-
async createRoom(options) {
|
|
4878
|
-
const response = await this.rpcClient.call(
|
|
4879
|
-
"H5_ROOM_CREATE" /* H5_ROOM_CREATE */,
|
|
4880
|
-
{
|
|
4881
|
-
options
|
|
4882
|
-
}
|
|
4883
|
-
);
|
|
4884
|
-
if (response.success === false) {
|
|
4885
|
-
throw new Error(response.error || "Failed to create room");
|
|
4886
|
-
}
|
|
4887
|
-
const roomData = response.roomData || response;
|
|
4888
|
-
const room = new exports.VenusRoom(roomData);
|
|
4889
|
-
return room;
|
|
4890
|
-
}
|
|
4891
|
-
async joinOrCreateRoom(options) {
|
|
4892
|
-
const response = await this.rpcClient.call(
|
|
4893
|
-
"H5_ROOM_JOIN_OR_CREATE" /* H5_ROOM_JOIN_OR_CREATE */,
|
|
4894
|
-
{
|
|
4895
|
-
options
|
|
4896
|
-
}
|
|
4897
|
-
);
|
|
4898
|
-
if (response.success === false) {
|
|
4899
|
-
throw new Error(response.error || "Failed to join or create room");
|
|
4900
|
-
}
|
|
4901
|
-
const data = response.value || response;
|
|
4902
|
-
const room = new exports.VenusRoom(data.roomData);
|
|
4903
|
-
return {
|
|
4904
|
-
action: data.action,
|
|
4905
|
-
room,
|
|
4906
|
-
playersJoined: data.playersJoined
|
|
4907
|
-
};
|
|
4908
|
-
}
|
|
4909
|
-
async joinRoomByCode(roomCode) {
|
|
4910
|
-
const response = await this.rpcClient.call(
|
|
4911
|
-
"H5_ROOM_JOIN_BY_CODE" /* H5_ROOM_JOIN_BY_CODE */,
|
|
4912
|
-
{
|
|
4913
|
-
roomCode
|
|
4914
|
-
}
|
|
4915
|
-
);
|
|
4916
|
-
if (response?.success === false) {
|
|
4917
|
-
throw new Error(response.error || "Failed to join room by code");
|
|
4918
|
-
}
|
|
4919
|
-
const roomData = response.roomData || response;
|
|
4920
|
-
const room = new exports.VenusRoom(roomData);
|
|
4921
|
-
return room;
|
|
4922
|
-
}
|
|
4923
|
-
// Get user's rooms with optional filtering
|
|
4924
|
-
async getUserRooms(includeArchived = false) {
|
|
4925
|
-
const response = await this.rpcClient.call(
|
|
4926
|
-
"H5_ROOM_GET_USER_ROOMS" /* H5_ROOM_GET_USER_ROOMS */,
|
|
4927
|
-
{
|
|
4928
|
-
includeArchived
|
|
4929
|
-
}
|
|
4930
|
-
);
|
|
4931
|
-
if (response?.success === false) {
|
|
4932
|
-
throw new Error(response.error || "Failed to get user rooms");
|
|
4933
|
-
}
|
|
4934
|
-
const rawRooms = response.rooms || [];
|
|
4935
|
-
const venusRooms = [];
|
|
4936
|
-
for (const roomData of rawRooms) {
|
|
4937
|
-
if (!roomData.id) {
|
|
4938
|
-
console.warn("getUserRooms: Skipping room with missing ID:", roomData);
|
|
4939
|
-
continue;
|
|
4940
|
-
}
|
|
4941
|
-
try {
|
|
4942
|
-
const venusRoom = new exports.VenusRoom(roomData);
|
|
4943
|
-
venusRooms.push(venusRoom);
|
|
4944
|
-
} catch (error) {
|
|
4945
|
-
console.warn(
|
|
4946
|
-
"getUserRooms: Failed to create VenusRoom object:",
|
|
4947
|
-
error,
|
|
4948
|
-
roomData
|
|
4949
|
-
);
|
|
4950
|
-
}
|
|
4951
|
-
}
|
|
4952
|
-
return venusRooms;
|
|
4953
|
-
}
|
|
4954
|
-
async updateData(room, updates, merge = true) {
|
|
4955
|
-
const response = await this.rpcClient.call(
|
|
4956
|
-
"H5_ROOM_UPDATE_DATA" /* H5_ROOM_UPDATE_DATA */,
|
|
4957
|
-
{
|
|
4958
|
-
roomId: room.id,
|
|
4959
|
-
updates,
|
|
4960
|
-
merge
|
|
4961
|
-
}
|
|
4962
|
-
);
|
|
4963
|
-
if (response?.success === false) {
|
|
4964
|
-
throw new Error(response.error || "Failed to update room data");
|
|
4965
|
-
}
|
|
4966
|
-
return response.data;
|
|
4967
|
-
}
|
|
4968
|
-
async getData(room) {
|
|
4969
|
-
const response = await this.rpcClient.call(
|
|
4970
|
-
"H5_ROOM_GET_DATA" /* H5_ROOM_GET_DATA */,
|
|
4971
|
-
{
|
|
4972
|
-
roomId: room.id
|
|
4973
|
-
}
|
|
4974
|
-
);
|
|
4975
|
-
if (response?.success === false) {
|
|
4976
|
-
throw new Error(response.error || "Failed to get room data");
|
|
4977
|
-
}
|
|
4978
|
-
return response.data;
|
|
4979
|
-
}
|
|
4980
|
-
async sendMessage(venusRoom, messageData) {
|
|
4981
|
-
const response = await this.rpcClient.call(
|
|
4982
|
-
"H5_ROOM_SEND_MESSAGE" /* H5_ROOM_SEND_MESSAGE */,
|
|
4983
|
-
{
|
|
4984
|
-
roomId: venusRoom.id,
|
|
4985
|
-
message: messageData
|
|
4986
|
-
}
|
|
4987
|
-
);
|
|
4988
|
-
if (response?.success === false) {
|
|
4989
|
-
throw new Error(response.error || "Failed to send message");
|
|
4990
|
-
}
|
|
4991
|
-
return response.messageId;
|
|
4992
|
-
}
|
|
4993
|
-
async leave(room) {
|
|
4994
|
-
const response = await this.rpcClient.call(
|
|
4995
|
-
"H5_ROOM_LEAVE" /* H5_ROOM_LEAVE */,
|
|
4996
|
-
{
|
|
4997
|
-
roomId: room.id
|
|
4998
|
-
}
|
|
4999
|
-
);
|
|
5000
|
-
if (response?.success === false) {
|
|
5001
|
-
throw new Error(response.error || "Failed to leave room");
|
|
5002
|
-
}
|
|
5003
|
-
return response;
|
|
5004
|
-
}
|
|
5005
|
-
async startGame(room, gameConfig = {}, turnOrder = null) {
|
|
5006
|
-
const response = await this.rpcClient.call(
|
|
5007
|
-
"H5_ROOM_START_GAME" /* H5_ROOM_START_GAME */,
|
|
5008
|
-
{
|
|
5009
|
-
roomId: room.id,
|
|
5010
|
-
gameConfig,
|
|
5011
|
-
turnOrder
|
|
5012
|
-
}
|
|
5013
|
-
);
|
|
5014
|
-
if (response?.success === false) {
|
|
5015
|
-
throw new Error(response.error || "Failed to start game");
|
|
5016
|
-
}
|
|
5017
|
-
return response.data;
|
|
5018
|
-
}
|
|
5019
|
-
async proposeMove(room, proposalPayload) {
|
|
5020
|
-
const response = await this.rpcClient.call(
|
|
5021
|
-
"h5:room:proposeMove" /* H5_ROOM_PROPOSE_MOVE */,
|
|
5022
|
-
{
|
|
5023
|
-
roomId: room.id,
|
|
5024
|
-
gameSpecificState: proposalPayload.gameSpecificState,
|
|
5025
|
-
moveType: proposalPayload.moveType,
|
|
5026
|
-
clientContext: proposalPayload.clientContext,
|
|
5027
|
-
clientProposalId: proposalPayload.clientProposalId
|
|
5028
|
-
}
|
|
5029
|
-
);
|
|
5030
|
-
if (response?.success === false) {
|
|
5031
|
-
throw new Error(response.error || "Failed to propose move");
|
|
5032
|
-
}
|
|
5033
|
-
return response.data;
|
|
5034
|
-
}
|
|
5035
|
-
async validateMove(room, moveId, isValid, reason = null, validatorId = null) {
|
|
5036
|
-
console.log(`[Venus Rooms] Validating move ${moveId}: ${isValid}`);
|
|
5037
|
-
return { success: true, moveId, isValid, reason };
|
|
5038
|
-
}
|
|
5039
|
-
async roomSubscribeToGameEvents(room, callback) {
|
|
5040
|
-
"game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5041
|
-
if (!this.subscriptions.gameEvents[room.id]) {
|
|
5042
|
-
this.subscriptions.gameEvents[room.id] = [];
|
|
5043
|
-
}
|
|
5044
|
-
this.subscriptions.gameEvents[room.id].push(callback);
|
|
5045
|
-
}
|
|
5046
|
-
subscribe(room, options = {}) {
|
|
5047
|
-
const subscriptionIds = [];
|
|
5048
|
-
const roomId = room.id;
|
|
5049
|
-
if (options.onData) {
|
|
5050
|
-
const dataSubId = "data_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5051
|
-
if (!this.subscriptions.data[roomId]) {
|
|
5052
|
-
this.subscriptions.data[roomId] = [];
|
|
5053
|
-
}
|
|
5054
|
-
this.subscriptions.data[roomId].push(options.onData);
|
|
5055
|
-
subscriptionIds.push({
|
|
5056
|
-
type: "data",
|
|
5057
|
-
id: dataSubId,
|
|
5058
|
-
callback: options.onData
|
|
5059
|
-
});
|
|
5060
|
-
}
|
|
5061
|
-
if (options.onMessages) {
|
|
5062
|
-
const msgSubId = "messages_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5063
|
-
if (!this.subscriptions.messages[roomId]) {
|
|
5064
|
-
this.subscriptions.messages[roomId] = [];
|
|
5065
|
-
}
|
|
5066
|
-
this.subscriptions.messages[roomId].push(options.onMessages);
|
|
5067
|
-
subscriptionIds.push({
|
|
5068
|
-
type: "messages",
|
|
5069
|
-
id: msgSubId,
|
|
5070
|
-
callback: options.onMessages
|
|
5071
|
-
});
|
|
5072
|
-
}
|
|
5073
|
-
if (options.onMoves || options.onGameEvents) {
|
|
5074
|
-
const handler = options.onMoves || options.onGameEvents;
|
|
5075
|
-
if (handler) {
|
|
5076
|
-
const gameSubId = "game_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
5077
|
-
if (!this.subscriptions.gameEvents[roomId]) {
|
|
5078
|
-
this.subscriptions.gameEvents[roomId] = [];
|
|
5079
|
-
}
|
|
5080
|
-
this.subscriptions.gameEvents[roomId].push(handler);
|
|
5081
|
-
subscriptionIds.push({
|
|
5082
|
-
type: "gameEvents",
|
|
5083
|
-
id: gameSubId,
|
|
5084
|
-
callback: handler
|
|
5085
|
-
});
|
|
5086
|
-
}
|
|
5087
|
-
}
|
|
5088
|
-
const needsSubscription = subscriptionIds.length > 0 && (this.subscriptions.data[roomId]?.length ?? 0) <= 1 && (this.subscriptions.messages[roomId]?.length ?? 0) <= 1 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) <= 1;
|
|
5089
|
-
if (needsSubscription) {
|
|
5090
|
-
this.rpcClient.call("H5_ROOM_SUBSCRIBE" /* H5_ROOM_SUBSCRIBE */, {
|
|
5091
|
-
roomId,
|
|
5092
|
-
subscribeToData: !!options.onData,
|
|
5093
|
-
subscribeToMessages: !!options.onMessages,
|
|
5094
|
-
subscribeToProposedMoves: !!(options.onMoves || options.onGameEvents)
|
|
5095
|
-
}).catch((error) => {
|
|
5096
|
-
console.error("Failed to set up room subscription:", error);
|
|
5097
|
-
});
|
|
5098
|
-
}
|
|
5099
|
-
let called = false;
|
|
5100
|
-
return () => {
|
|
5101
|
-
if (called) return;
|
|
5102
|
-
called = true;
|
|
5103
|
-
subscriptionIds.forEach((sub) => {
|
|
5104
|
-
const bucket = this.subscriptions[sub.type];
|
|
5105
|
-
const callbacks = bucket && bucket[roomId] || [];
|
|
5106
|
-
const index = callbacks.indexOf(sub.callback);
|
|
5107
|
-
if (index > -1) callbacks.splice(index, 1);
|
|
5108
|
-
});
|
|
5109
|
-
const hasNoCallbacks = (this.subscriptions.data[roomId]?.length ?? 0) === 0 && (this.subscriptions.messages[roomId]?.length ?? 0) === 0 && (this.subscriptions.gameEvents[roomId]?.length ?? 0) === 0;
|
|
5110
|
-
if (hasNoCallbacks) {
|
|
5111
|
-
this.rpcClient.call("H5_ROOM_UNSUBSCRIBE" /* H5_ROOM_UNSUBSCRIBE */, {
|
|
5112
|
-
roomId
|
|
5113
|
-
}).catch((error) => {
|
|
5114
|
-
console.error("Failed to clean up room subscription:", error);
|
|
5115
|
-
});
|
|
5116
|
-
}
|
|
5117
|
-
};
|
|
5118
|
-
}
|
|
5119
|
-
};
|
|
5120
|
-
|
|
5121
4678
|
// src/social/RpcSocialApi.ts
|
|
5122
4679
|
var RpcSocialApi = class {
|
|
5123
4680
|
constructor(rpcClient) {
|
|
@@ -5222,7 +4779,7 @@ var RemoteHost = class {
|
|
|
5222
4779
|
this.popups = new RpcPopupsApi(rpcClient);
|
|
5223
4780
|
this.profile = new HostProfileApi();
|
|
5224
4781
|
this.cdn = new HostCdnApi(getCdnBaseUrl());
|
|
5225
|
-
this.time = new HostTimeApi(rpcClient);
|
|
4782
|
+
this.time = new HostTimeApi(rpcClient, venusApi);
|
|
5226
4783
|
this.post = new RpcPostApi(rpcClient);
|
|
5227
4784
|
this.ai = new RpcAiApi(rpcClient);
|
|
5228
4785
|
this.haptics = new RpcHapticsApi(rpcClient);
|
|
@@ -5238,7 +4795,6 @@ var RemoteHost = class {
|
|
|
5238
4795
|
venusApi.isMock = () => false;
|
|
5239
4796
|
this.venusApi.sharedAssets = new RpcSharedAssetsApi(rpcClient, venusApi);
|
|
5240
4797
|
initializeRoomsApi(this.venusApi, this);
|
|
5241
|
-
console.log("[Venus SDK] Remote host created");
|
|
5242
4798
|
}
|
|
5243
4799
|
get isInitialized() {
|
|
5244
4800
|
return this._isInitialized;
|
|
@@ -5297,10 +4853,8 @@ var RemoteHost = class {
|
|
|
5297
4853
|
// src/Host.ts
|
|
5298
4854
|
function createHost(venusApi, isMock) {
|
|
5299
4855
|
if (isMock) {
|
|
5300
|
-
console.log("[Venus SDK] Creating Local Host");
|
|
5301
4856
|
return new MockHost(venusApi);
|
|
5302
4857
|
} else {
|
|
5303
|
-
console.log("[Venus SDK] Creating Remote Host");
|
|
5304
4858
|
return new RemoteHost(venusApi);
|
|
5305
4859
|
}
|
|
5306
4860
|
}
|
|
@@ -5313,6 +4867,8 @@ function initializeSocial(venusApi, host) {
|
|
|
5313
4867
|
};
|
|
5314
4868
|
}
|
|
5315
4869
|
|
|
4870
|
+
exports.HASH_ALGORITHM_NODE = HASH_ALGORITHM_NODE;
|
|
4871
|
+
exports.HASH_ALGORITHM_WEB_CRYPTO = HASH_ALGORITHM_WEB_CRYPTO;
|
|
5316
4872
|
exports.HapticFeedbackStyle = HapticFeedbackStyle;
|
|
5317
4873
|
exports.HostCdnApi = HostCdnApi;
|
|
5318
4874
|
exports.HostProfileApi = HostProfileApi;
|
|
@@ -5334,7 +4890,6 @@ exports.MockPopupsApi = MockPopupsApi;
|
|
|
5334
4890
|
exports.MockPreloaderApi = MockPreloaderApi;
|
|
5335
4891
|
exports.MockProfileApi = MockProfileApi;
|
|
5336
4892
|
exports.MockSharedAssetsApi = MockSharedAssetsApi;
|
|
5337
|
-
exports.MockSimulationApi = MockSimulationApi;
|
|
5338
4893
|
exports.MockSocialApi = MockSocialApi;
|
|
5339
4894
|
exports.MockStorageApi = MockStorageApi;
|
|
5340
4895
|
exports.MockTimeApi = MockTimeApi;
|
|
@@ -5354,12 +4909,15 @@ exports.RpcNavigationApi = RpcNavigationApi;
|
|
|
5354
4909
|
exports.RpcNotificationsApi = RpcNotificationsApi;
|
|
5355
4910
|
exports.RpcPopupsApi = RpcPopupsApi;
|
|
5356
4911
|
exports.RpcPreloaderApi = RpcPreloaderApi;
|
|
4912
|
+
exports.RpcRoomsApi = RpcRoomsApi;
|
|
5357
4913
|
exports.RpcSharedAssetsApi = RpcSharedAssetsApi;
|
|
5358
4914
|
exports.RpcSimulationApi = RpcSimulationApi;
|
|
5359
4915
|
exports.RpcSocialApi = RpcSocialApi;
|
|
5360
4916
|
exports.RpcStorageApi = RpcStorageApi;
|
|
5361
4917
|
exports.SDK_VERSION = SDK_VERSION;
|
|
5362
4918
|
exports.VenusMessageId = VenusMessageId;
|
|
4919
|
+
exports.VenusRoom = VenusRoom;
|
|
4920
|
+
exports.computeScoreHash = computeScoreHash;
|
|
5363
4921
|
exports.createHost = createHost;
|
|
5364
4922
|
exports.createMockStorageApi = createMockStorageApi;
|
|
5365
4923
|
exports.initializeAds = initializeAds;
|