@series-inc/venus-sdk 3.0.4 → 3.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +324 -123
- package/dist/{AdsApi-CNGRf6j0.d.mts → AdsApi-meVfUcZy.d.mts} +37 -25
- package/dist/{AdsApi-CNGRf6j0.d.ts → AdsApi-meVfUcZy.d.ts} +37 -25
- package/dist/chunk-2PDL7CQK.mjs +26 -0
- package/dist/chunk-2PDL7CQK.mjs.map +1 -0
- package/dist/{chunk-PXWCNWJ6.mjs → chunk-EMVTVSGL.mjs} +421 -109
- package/dist/chunk-EMVTVSGL.mjs.map +1 -0
- package/dist/chunk-IZLOB7DV.mjs +343 -0
- package/dist/chunk-IZLOB7DV.mjs.map +1 -0
- package/dist/{chunk-W7IPHM67.mjs → chunk-QABXMFND.mjs} +3 -26
- package/dist/chunk-QABXMFND.mjs.map +1 -0
- package/dist/core-5JLON75E.mjs +4 -0
- package/dist/{core-R3FHW62G.mjs.map → core-5JLON75E.mjs.map} +1 -1
- package/dist/index.cjs +768 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +140 -25
- package/dist/index.d.ts +140 -25
- package/dist/index.mjs +5 -3
- package/dist/index.mjs.map +1 -1
- package/dist/venus-api/index.cjs +452 -101
- 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 +46 -3
- package/dist/venus-api/index.mjs.map +1 -1
- package/dist/vite/index.cjs +534 -0
- package/dist/vite/index.cjs.map +1 -0
- package/dist/vite/index.mjs +527 -0
- package/dist/vite/index.mjs.map +1 -0
- package/dist/webview/index.cjs +346 -0
- package/dist/webview/index.cjs.map +1 -0
- package/dist/webview/index.d.mts +17 -0
- package/dist/webview/index.d.ts +17 -0
- package/dist/webview/index.mjs +4 -0
- package/dist/webview/index.mjs.map +1 -0
- package/package.json +19 -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/venus-api/index.cjs
CHANGED
|
@@ -1157,9 +1157,11 @@ function isPacificDaylightTime(date) {
|
|
|
1157
1157
|
|
|
1158
1158
|
// src/time/HostTimeApi.ts
|
|
1159
1159
|
var HostTimeApi = class {
|
|
1160
|
-
constructor(rpcClient) {
|
|
1160
|
+
constructor(rpcClient, venusApi) {
|
|
1161
1161
|
__publicField(this, "rpcClient");
|
|
1162
|
+
__publicField(this, "venusApi");
|
|
1162
1163
|
this.rpcClient = rpcClient;
|
|
1164
|
+
this.venusApi = venusApi;
|
|
1163
1165
|
}
|
|
1164
1166
|
async requestTimeAsync() {
|
|
1165
1167
|
const response = await this.rpcClient.call(
|
|
@@ -1169,13 +1171,7 @@ var HostTimeApi = class {
|
|
|
1169
1171
|
return response;
|
|
1170
1172
|
}
|
|
1171
1173
|
formatTime(timestamp, options) {
|
|
1172
|
-
|
|
1173
|
-
const windowVenus = window.venus;
|
|
1174
|
-
if (windowVenus._config.locale) {
|
|
1175
|
-
locale = windowVenus._config.locale;
|
|
1176
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
1177
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
1178
|
-
}
|
|
1174
|
+
const locale = this.venusApi.getLocale();
|
|
1179
1175
|
const date = new Date(timestamp);
|
|
1180
1176
|
const dateTimeOptions = {
|
|
1181
1177
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -1187,13 +1183,7 @@ var HostTimeApi = class {
|
|
|
1187
1183
|
}
|
|
1188
1184
|
formatNumber(value, options) {
|
|
1189
1185
|
try {
|
|
1190
|
-
|
|
1191
|
-
const windowVenus = window.venus;
|
|
1192
|
-
if (windowVenus._config.locale) {
|
|
1193
|
-
locale = windowVenus._config.locale;
|
|
1194
|
-
} else if (windowVenus._config.environment && windowVenus._config.environment.browserInfo && windowVenus._config.environment.browserInfo.language) {
|
|
1195
|
-
locale = windowVenus._config.environment.browserInfo.language;
|
|
1196
|
-
}
|
|
1186
|
+
const locale = this.venusApi.getLocale();
|
|
1197
1187
|
const numberOptions = {
|
|
1198
1188
|
style: options?.style || "decimal",
|
|
1199
1189
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
@@ -1257,7 +1247,7 @@ var MockTimeApi = class {
|
|
|
1257
1247
|
this.venusApi = venusApi;
|
|
1258
1248
|
}
|
|
1259
1249
|
formatNumber(value, options) {
|
|
1260
|
-
const locale = this.getLocale();
|
|
1250
|
+
const locale = this.venusApi.getLocale();
|
|
1261
1251
|
const numberOptions = {
|
|
1262
1252
|
style: options?.style || "decimal",
|
|
1263
1253
|
minimumFractionDigits: options?.minimumFractionDigits || 0,
|
|
@@ -1268,7 +1258,7 @@ var MockTimeApi = class {
|
|
|
1268
1258
|
return value.toLocaleString(locale, numberOptions);
|
|
1269
1259
|
}
|
|
1270
1260
|
formatTime(timestamp, options) {
|
|
1271
|
-
const locale = this.getLocale();
|
|
1261
|
+
const locale = this.venusApi.getLocale();
|
|
1272
1262
|
const date = new Date(timestamp);
|
|
1273
1263
|
const dateTimeOptions = {
|
|
1274
1264
|
dateStyle: options.dateStyle || "medium",
|
|
@@ -1348,16 +1338,6 @@ var MockTimeApi = class {
|
|
|
1348
1338
|
});
|
|
1349
1339
|
return timeInfo;
|
|
1350
1340
|
}
|
|
1351
|
-
getLocale() {
|
|
1352
|
-
const venusApi = this.venusApi;
|
|
1353
|
-
let locale = "en-US";
|
|
1354
|
-
if (venusApi._mock.user && venusApi._mock.user.locale) {
|
|
1355
|
-
locale = venusApi._mock.user.locale;
|
|
1356
|
-
} else if (venusApi._mock.environment && venusApi._mock.environment.browserInfo.language) {
|
|
1357
|
-
locale = venusApi._mock.environment.browserInfo.language;
|
|
1358
|
-
}
|
|
1359
|
-
return locale;
|
|
1360
|
-
}
|
|
1361
1341
|
};
|
|
1362
1342
|
|
|
1363
1343
|
// src/time/index.ts
|
|
@@ -3976,47 +3956,105 @@ function initializeIap(venusApiInstance, host) {
|
|
|
3976
3956
|
venusApiInstance.iap = host.iap;
|
|
3977
3957
|
}
|
|
3978
3958
|
|
|
3959
|
+
// src/leaderboard/utils.ts
|
|
3960
|
+
var HASH_ALGORITHM_WEB_CRYPTO = "SHA-256";
|
|
3961
|
+
async function computeScoreHash(score, duration, token, sealingNonce, sealingSecret) {
|
|
3962
|
+
const payload = `score:${score}|duration:${duration}|token:${token}`;
|
|
3963
|
+
const fullPayload = `${payload}|nonce:${sealingNonce}`;
|
|
3964
|
+
const encoder = new TextEncoder();
|
|
3965
|
+
const keyData = encoder.encode(sealingSecret);
|
|
3966
|
+
const messageData = encoder.encode(fullPayload);
|
|
3967
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
3968
|
+
"raw",
|
|
3969
|
+
keyData,
|
|
3970
|
+
{ name: "HMAC", hash: HASH_ALGORITHM_WEB_CRYPTO },
|
|
3971
|
+
false,
|
|
3972
|
+
["sign"]
|
|
3973
|
+
);
|
|
3974
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
|
|
3975
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3976
|
+
}
|
|
3977
|
+
|
|
3979
3978
|
// src/leaderboard/RpcLeaderboardApi.ts
|
|
3980
3979
|
var RpcLeaderboardApi = class {
|
|
3981
3980
|
constructor(rpcClient) {
|
|
3982
3981
|
__publicField(this, "rpcClient");
|
|
3982
|
+
/** Cache of score tokens for automatic hash computation */
|
|
3983
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
3983
3984
|
this.rpcClient = rpcClient;
|
|
3984
3985
|
}
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3986
|
+
/**
|
|
3987
|
+
* Create a score token for submitting a score.
|
|
3988
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
3989
|
+
*
|
|
3990
|
+
* @param mode - Optional game mode
|
|
3991
|
+
* @returns Score token with sealing data if enabled
|
|
3992
|
+
*/
|
|
3993
|
+
async createScoreToken(mode) {
|
|
3994
|
+
const token = await this.rpcClient.call(
|
|
3995
|
+
"H5_LEADERBOARD_CREATE_SCORE_TOKEN" /* H5_LEADERBOARD_CREATE_SCORE_TOKEN */,
|
|
3988
3996
|
mode ? { mode } : {}
|
|
3989
3997
|
);
|
|
3998
|
+
this.tokenCache.set(token.token, token);
|
|
3999
|
+
return token;
|
|
3990
4000
|
}
|
|
3991
|
-
|
|
4001
|
+
/**
|
|
4002
|
+
* Submit a score to the leaderboard.
|
|
4003
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
4004
|
+
*
|
|
4005
|
+
* @param params - Score submission parameters
|
|
4006
|
+
* @returns Submission result with acceptance status and rank
|
|
4007
|
+
* @throws Error if token not found in cache
|
|
4008
|
+
*/
|
|
4009
|
+
async submitScore(params) {
|
|
4010
|
+
let hash;
|
|
4011
|
+
if (params.token) {
|
|
4012
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
4013
|
+
if (!cachedToken) {
|
|
4014
|
+
throw new Error(
|
|
4015
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
4016
|
+
);
|
|
4017
|
+
}
|
|
4018
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
4019
|
+
hash = await computeScoreHash(
|
|
4020
|
+
params.score,
|
|
4021
|
+
params.duration,
|
|
4022
|
+
params.token,
|
|
4023
|
+
cachedToken.sealingNonce,
|
|
4024
|
+
cachedToken.sealingSecret
|
|
4025
|
+
);
|
|
4026
|
+
}
|
|
4027
|
+
this.tokenCache.delete(params.token);
|
|
4028
|
+
}
|
|
3992
4029
|
return this.rpcClient.call(
|
|
3993
4030
|
"H5_LEADERBOARD_SUBMIT_SCORE" /* H5_LEADERBOARD_SUBMIT_SCORE */,
|
|
3994
4031
|
{
|
|
3995
|
-
|
|
3996
|
-
score,
|
|
3997
|
-
|
|
3998
|
-
mode:
|
|
3999
|
-
telemetry:
|
|
4000
|
-
metadata:
|
|
4001
|
-
hash
|
|
4032
|
+
token: params.token,
|
|
4033
|
+
score: params.score,
|
|
4034
|
+
duration: params.duration,
|
|
4035
|
+
mode: params.mode,
|
|
4036
|
+
telemetry: params.telemetry,
|
|
4037
|
+
metadata: params.metadata,
|
|
4038
|
+
hash
|
|
4039
|
+
// undefined if no sealing, computed if sealing enabled
|
|
4002
4040
|
}
|
|
4003
4041
|
);
|
|
4004
4042
|
}
|
|
4005
|
-
|
|
4043
|
+
getPagedScores(options) {
|
|
4006
4044
|
return this.rpcClient.call(
|
|
4007
|
-
"
|
|
4045
|
+
"H5_LEADERBOARD_GET_PAGED_SCORES" /* H5_LEADERBOARD_GET_PAGED_SCORES */,
|
|
4008
4046
|
options ?? {}
|
|
4009
4047
|
);
|
|
4010
4048
|
}
|
|
4011
|
-
|
|
4049
|
+
getMyRank(options) {
|
|
4012
4050
|
return this.rpcClient.call(
|
|
4013
|
-
"
|
|
4051
|
+
"H5_LEADERBOARD_GET_MY_RANK" /* H5_LEADERBOARD_GET_MY_RANK */,
|
|
4014
4052
|
options ?? {}
|
|
4015
4053
|
);
|
|
4016
4054
|
}
|
|
4017
|
-
|
|
4055
|
+
getPodiumScores(options) {
|
|
4018
4056
|
return this.rpcClient.call(
|
|
4019
|
-
"
|
|
4057
|
+
"H5_LEADERBOARD_GET_PODIUM_SCORES" /* H5_LEADERBOARD_GET_PODIUM_SCORES */,
|
|
4020
4058
|
options ?? {}
|
|
4021
4059
|
);
|
|
4022
4060
|
}
|
|
@@ -4025,17 +4063,31 @@ var RpcLeaderboardApi = class {
|
|
|
4025
4063
|
// src/leaderboard/MockLeaderboardApi.ts
|
|
4026
4064
|
var MockLeaderboardApi = class {
|
|
4027
4065
|
constructor(options) {
|
|
4028
|
-
__publicField(this, "
|
|
4066
|
+
__publicField(this, "tokens", /* @__PURE__ */ new Map());
|
|
4067
|
+
/** Cache of score tokens for automatic hash computation */
|
|
4068
|
+
__publicField(this, "tokenCache", /* @__PURE__ */ new Map());
|
|
4029
4069
|
__publicField(this, "entriesByMode", /* @__PURE__ */ new Map());
|
|
4030
|
-
__publicField(this, "
|
|
4031
|
-
__publicField(this, "
|
|
4032
|
-
|
|
4033
|
-
|
|
4070
|
+
__publicField(this, "tokenCounter", 0);
|
|
4071
|
+
__publicField(this, "enableScoreSealing", false);
|
|
4072
|
+
__publicField(this, "scoreSealingSecret", "mock-leaderboard-secret-key");
|
|
4073
|
+
if (options?.enableScoreSealing) {
|
|
4074
|
+
this.enableScoreSealing = true;
|
|
4075
|
+
}
|
|
4076
|
+
if (options?.scoreSealingSecret) {
|
|
4077
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
4034
4078
|
}
|
|
4035
4079
|
}
|
|
4080
|
+
/**
|
|
4081
|
+
* Configure mock leaderboard settings
|
|
4082
|
+
*
|
|
4083
|
+
* @param options - Configuration options
|
|
4084
|
+
*/
|
|
4036
4085
|
configure(options) {
|
|
4037
|
-
if (typeof options.
|
|
4038
|
-
this.
|
|
4086
|
+
if (typeof options.enableScoreSealing === "boolean") {
|
|
4087
|
+
this.enableScoreSealing = options.enableScoreSealing;
|
|
4088
|
+
}
|
|
4089
|
+
if (options.scoreSealingSecret) {
|
|
4090
|
+
this.scoreSealingSecret = options.scoreSealingSecret;
|
|
4039
4091
|
}
|
|
4040
4092
|
}
|
|
4041
4093
|
generateNonce() {
|
|
@@ -4052,83 +4104,149 @@ var MockLeaderboardApi = class {
|
|
|
4052
4104
|
}
|
|
4053
4105
|
return this.entriesByMode.get(key);
|
|
4054
4106
|
}
|
|
4055
|
-
|
|
4056
|
-
|
|
4107
|
+
/**
|
|
4108
|
+
* Create a mock score token for testing.
|
|
4109
|
+
* Token is cached for automatic hash computation if score sealing is enabled.
|
|
4110
|
+
*
|
|
4111
|
+
* @param mode - Optional game mode
|
|
4112
|
+
* @returns Score token with sealing data if enabled
|
|
4113
|
+
*/
|
|
4114
|
+
async createScoreToken(mode) {
|
|
4115
|
+
const token = `mock_token_${++this.tokenCounter}`;
|
|
4057
4116
|
const startTime = Date.now();
|
|
4058
4117
|
const expiresAt = startTime + 36e5;
|
|
4059
4118
|
const resolvedMode = mode || "default";
|
|
4060
|
-
const
|
|
4061
|
-
this.
|
|
4062
|
-
|
|
4119
|
+
const sealingNonce = this.enableScoreSealing ? this.generateNonce() : null;
|
|
4120
|
+
const sealingSecret = this.enableScoreSealing ? this.scoreSealingSecret : null;
|
|
4121
|
+
this.tokens.set(token, {
|
|
4122
|
+
id: token,
|
|
4063
4123
|
expiresAt,
|
|
4064
4124
|
mode: resolvedMode,
|
|
4065
|
-
|
|
4125
|
+
sealingNonce,
|
|
4066
4126
|
used: false
|
|
4067
4127
|
});
|
|
4068
|
-
|
|
4069
|
-
|
|
4128
|
+
const result = {
|
|
4129
|
+
token,
|
|
4070
4130
|
startTime,
|
|
4071
4131
|
expiresAt,
|
|
4072
|
-
|
|
4132
|
+
sealingNonce,
|
|
4133
|
+
sealingSecret,
|
|
4073
4134
|
mode: resolvedMode
|
|
4074
4135
|
};
|
|
4136
|
+
this.tokenCache.set(token, result);
|
|
4137
|
+
return result;
|
|
4075
4138
|
}
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4139
|
+
/**
|
|
4140
|
+
* Submit a mock score to the leaderboard.
|
|
4141
|
+
* Automatically computes hash if score sealing is enabled and token was created via createScoreToken().
|
|
4142
|
+
*
|
|
4143
|
+
* @param params - Score submission parameters
|
|
4144
|
+
* @returns Submission result with acceptance status and rank
|
|
4145
|
+
* @throws Error if token not found in cache or validation fails
|
|
4146
|
+
*/
|
|
4147
|
+
async submitScore(params) {
|
|
4148
|
+
let hash;
|
|
4149
|
+
if (params.token) {
|
|
4150
|
+
const cachedToken = this.tokenCache.get(params.token);
|
|
4151
|
+
if (!cachedToken) {
|
|
4152
|
+
throw new Error(
|
|
4153
|
+
"Invalid token: not found in cache. Did you call createScoreToken() first?"
|
|
4154
|
+
);
|
|
4155
|
+
}
|
|
4156
|
+
if (cachedToken.sealingNonce && cachedToken.sealingSecret) {
|
|
4157
|
+
hash = await computeScoreHash(
|
|
4158
|
+
params.score,
|
|
4159
|
+
params.duration,
|
|
4160
|
+
params.token,
|
|
4161
|
+
cachedToken.sealingNonce,
|
|
4162
|
+
cachedToken.sealingSecret
|
|
4163
|
+
);
|
|
4164
|
+
}
|
|
4165
|
+
}
|
|
4166
|
+
if (!params.token) {
|
|
4167
|
+
const mode = params.mode || "default";
|
|
4168
|
+
const submittedAt2 = Date.now();
|
|
4169
|
+
const entry2 = {
|
|
4170
|
+
profileId: `mock_profile`,
|
|
4171
|
+
username: "Mock Player",
|
|
4172
|
+
avatarUrl: null,
|
|
4173
|
+
score: params.score,
|
|
4174
|
+
duration: params.duration,
|
|
4175
|
+
submittedAt: submittedAt2,
|
|
4176
|
+
token: "simple-mode",
|
|
4177
|
+
rank: null,
|
|
4178
|
+
zScore: null,
|
|
4179
|
+
isAnomaly: false,
|
|
4180
|
+
trustScore: 50,
|
|
4181
|
+
metadata: params.metadata ?? null,
|
|
4182
|
+
isSeed: false
|
|
4183
|
+
};
|
|
4184
|
+
const modeEntries2 = this.getEntriesForMode(mode);
|
|
4185
|
+
modeEntries2.push(entry2);
|
|
4186
|
+
modeEntries2.sort((a, b) => {
|
|
4187
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
4188
|
+
return a.submittedAt - b.submittedAt;
|
|
4189
|
+
});
|
|
4190
|
+
modeEntries2.forEach((e, index) => {
|
|
4191
|
+
modeEntries2[index] = { ...e, rank: index + 1 };
|
|
4192
|
+
});
|
|
4193
|
+
const inserted2 = modeEntries2.find((e) => e.submittedAt === submittedAt2);
|
|
4194
|
+
return {
|
|
4195
|
+
accepted: true,
|
|
4196
|
+
rank: inserted2?.rank ?? null
|
|
4197
|
+
};
|
|
4080
4198
|
}
|
|
4081
|
-
|
|
4082
|
-
|
|
4199
|
+
const scoreToken = this.tokens.get(params.token);
|
|
4200
|
+
if (!scoreToken) {
|
|
4201
|
+
throw new Error("Invalid score token");
|
|
4083
4202
|
}
|
|
4084
|
-
if (
|
|
4085
|
-
throw new Error("
|
|
4203
|
+
if (scoreToken.expiresAt < Date.now()) {
|
|
4204
|
+
throw new Error("Invalid or expired score token");
|
|
4086
4205
|
}
|
|
4087
|
-
if (
|
|
4088
|
-
throw new Error("
|
|
4206
|
+
if (scoreToken.used) {
|
|
4207
|
+
throw new Error("Score token already used");
|
|
4089
4208
|
}
|
|
4090
|
-
if (
|
|
4091
|
-
throw new Error("
|
|
4209
|
+
if (params.mode && params.mode !== scoreToken.mode) {
|
|
4210
|
+
throw new Error("Submission mode does not match token mode");
|
|
4211
|
+
}
|
|
4212
|
+
if (scoreToken.sealingNonce && !hash) {
|
|
4213
|
+
throw new Error("Score hash required when score sealing is enabled");
|
|
4092
4214
|
}
|
|
4093
4215
|
const submittedAt = Date.now();
|
|
4094
4216
|
const entry = {
|
|
4095
4217
|
profileId: `mock_profile`,
|
|
4096
4218
|
username: "Mock Player",
|
|
4097
4219
|
avatarUrl: null,
|
|
4098
|
-
score,
|
|
4099
|
-
|
|
4220
|
+
score: params.score,
|
|
4221
|
+
duration: params.duration,
|
|
4100
4222
|
submittedAt,
|
|
4101
|
-
|
|
4223
|
+
token: params.token,
|
|
4102
4224
|
rank: null,
|
|
4103
4225
|
zScore: null,
|
|
4104
4226
|
isAnomaly: false,
|
|
4105
4227
|
trustScore: 50,
|
|
4106
|
-
metadata:
|
|
4228
|
+
metadata: params.metadata ?? null,
|
|
4107
4229
|
isSeed: false
|
|
4108
4230
|
};
|
|
4109
|
-
const modeEntries = this.getEntriesForMode(
|
|
4231
|
+
const modeEntries = this.getEntriesForMode(scoreToken.mode);
|
|
4110
4232
|
modeEntries.push(entry);
|
|
4111
4233
|
modeEntries.sort((a, b) => {
|
|
4112
|
-
if (b.score !== a.score)
|
|
4113
|
-
return b.score - a.score;
|
|
4114
|
-
}
|
|
4234
|
+
if (b.score !== a.score) return b.score - a.score;
|
|
4115
4235
|
return a.submittedAt - b.submittedAt;
|
|
4116
4236
|
});
|
|
4117
4237
|
modeEntries.forEach((e, index) => {
|
|
4118
|
-
modeEntries[index] = {
|
|
4119
|
-
...e,
|
|
4120
|
-
rank: index + 1
|
|
4121
|
-
};
|
|
4238
|
+
modeEntries[index] = { ...e, rank: index + 1 };
|
|
4122
4239
|
});
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4240
|
+
scoreToken.used = true;
|
|
4241
|
+
scoreToken.sealingNonce = null;
|
|
4242
|
+
this.tokenCache.delete(params.token);
|
|
4243
|
+
const inserted = modeEntries.find((e) => e.token === params.token && e.submittedAt === submittedAt);
|
|
4126
4244
|
return {
|
|
4127
4245
|
accepted: true,
|
|
4128
4246
|
rank: inserted?.rank ?? null
|
|
4129
4247
|
};
|
|
4130
4248
|
}
|
|
4131
|
-
async
|
|
4249
|
+
async getPagedScores(options) {
|
|
4132
4250
|
const limit = options?.limit ?? 10;
|
|
4133
4251
|
const mode = options?.mode ?? "default";
|
|
4134
4252
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
@@ -4144,7 +4262,7 @@ var MockLeaderboardApi = class {
|
|
|
4144
4262
|
periodInstance: options?.period ?? "alltime"
|
|
4145
4263
|
};
|
|
4146
4264
|
}
|
|
4147
|
-
async
|
|
4265
|
+
async getMyRank(_options) {
|
|
4148
4266
|
const mode = _options?.mode ?? "default";
|
|
4149
4267
|
const modeEntries = this.getEntriesForMode(mode);
|
|
4150
4268
|
const playerEntry = modeEntries[0] ?? null;
|
|
@@ -4157,7 +4275,7 @@ var MockLeaderboardApi = class {
|
|
|
4157
4275
|
periodInstance: _options?.period ?? "alltime"
|
|
4158
4276
|
};
|
|
4159
4277
|
}
|
|
4160
|
-
async
|
|
4278
|
+
async getPodiumScores(options) {
|
|
4161
4279
|
const mode = options?.mode ?? "default";
|
|
4162
4280
|
const modeEntries = [...this.getEntriesForMode(mode)];
|
|
4163
4281
|
const topCount = Math.max(1, Math.min(options?.topCount ?? 3, 10));
|
|
@@ -5706,6 +5824,174 @@ function initializeLoggingApi(venusApi, host) {
|
|
|
5706
5824
|
var BurgerTimeAssetsCdnPath = "burger-time/Core.stow";
|
|
5707
5825
|
var CharacterAssetsCdnPath = "burger-time/Character.stow";
|
|
5708
5826
|
|
|
5827
|
+
// src/shared-assets/embeddedLibrariesManifest.ts
|
|
5828
|
+
var EMBEDDED_LIBRARIES = [
|
|
5829
|
+
{
|
|
5830
|
+
libraryKey: "phaser@3.90.0",
|
|
5831
|
+
assetKey: "library:phaser@3.90.0",
|
|
5832
|
+
packageName: "phaser",
|
|
5833
|
+
version: "3.90.0",
|
|
5834
|
+
globalVar: "Phaser",
|
|
5835
|
+
cdnPath: "phaser/3.90.0/phaser.min.js",
|
|
5836
|
+
moduleSpecifiers: [{ match: "exact", value: "phaser" }],
|
|
5837
|
+
loadStage: 0,
|
|
5838
|
+
enabled: true
|
|
5839
|
+
},
|
|
5840
|
+
{
|
|
5841
|
+
libraryKey: "react@18.3.1",
|
|
5842
|
+
assetKey: "library:react@18.3.1",
|
|
5843
|
+
packageName: "react",
|
|
5844
|
+
version: "18.3.1",
|
|
5845
|
+
globalVar: "React",
|
|
5846
|
+
cdnPath: "react/18.3.1/react.production.min.js",
|
|
5847
|
+
moduleSpecifiers: [
|
|
5848
|
+
{ match: "exact", value: "react", behavior: "namespace" },
|
|
5849
|
+
{ match: "exact", value: "react/jsx-runtime", behavior: "react-jsx-runtime" },
|
|
5850
|
+
{
|
|
5851
|
+
match: "exact",
|
|
5852
|
+
value: "react/jsx-dev-runtime",
|
|
5853
|
+
behavior: "react-jsx-dev-runtime"
|
|
5854
|
+
}
|
|
5855
|
+
],
|
|
5856
|
+
loadStage: 0,
|
|
5857
|
+
// Must load before ReactDOM
|
|
5858
|
+
enabled: true
|
|
5859
|
+
},
|
|
5860
|
+
{
|
|
5861
|
+
libraryKey: "react-dom@18.3.1",
|
|
5862
|
+
assetKey: "library:react-dom@18.3.1",
|
|
5863
|
+
packageName: "react-dom",
|
|
5864
|
+
version: "18.3.1",
|
|
5865
|
+
globalVar: "ReactDOM",
|
|
5866
|
+
cdnPath: "react-dom/18.3.1/react-dom.production.min.js",
|
|
5867
|
+
moduleSpecifiers: [
|
|
5868
|
+
{ match: "exact", value: "react-dom", behavior: "namespace" },
|
|
5869
|
+
{ match: "exact", value: "react-dom/client", behavior: "namespace" }
|
|
5870
|
+
],
|
|
5871
|
+
loadStage: 1,
|
|
5872
|
+
// Depends on React (stage 0)
|
|
5873
|
+
enabled: true
|
|
5874
|
+
},
|
|
5875
|
+
{
|
|
5876
|
+
libraryKey: "three@0.170.0",
|
|
5877
|
+
assetKey: "library:three@0.170.0",
|
|
5878
|
+
packageName: "three",
|
|
5879
|
+
version: "0.170.0",
|
|
5880
|
+
globalVar: "THREE",
|
|
5881
|
+
cdnPath: "three/r170/three.min.js",
|
|
5882
|
+
moduleSpecifiers: [
|
|
5883
|
+
{ match: "exact", value: "three", behavior: "namespace" },
|
|
5884
|
+
{ match: "prefix", value: "three/examples/jsm/", behavior: "namespace" }
|
|
5885
|
+
],
|
|
5886
|
+
loadStage: 0,
|
|
5887
|
+
enabled: true
|
|
5888
|
+
},
|
|
5889
|
+
{
|
|
5890
|
+
libraryKey: "matter-js@0.19.0",
|
|
5891
|
+
assetKey: "library:matter-js@0.19.0",
|
|
5892
|
+
packageName: "matter-js",
|
|
5893
|
+
version: "0.19.0",
|
|
5894
|
+
globalVar: "Matter",
|
|
5895
|
+
cdnPath: "matter-js/0.19.0/matter.min.js",
|
|
5896
|
+
moduleSpecifiers: [{ match: "exact", value: "matter-js" }],
|
|
5897
|
+
loadStage: 0,
|
|
5898
|
+
enabled: true
|
|
5899
|
+
},
|
|
5900
|
+
{
|
|
5901
|
+
libraryKey: "inkjs@2.2.0",
|
|
5902
|
+
assetKey: "library:inkjs@2.2.0",
|
|
5903
|
+
packageName: "inkjs",
|
|
5904
|
+
version: "2.2.0",
|
|
5905
|
+
globalVar: "inkjs",
|
|
5906
|
+
cdnPath: "inkjs/2.2.0/ink.min.js",
|
|
5907
|
+
moduleSpecifiers: [{ match: "exact", value: "inkjs" }],
|
|
5908
|
+
loadStage: 0,
|
|
5909
|
+
enabled: true
|
|
5910
|
+
},
|
|
5911
|
+
{
|
|
5912
|
+
libraryKey: "zustand@5.0.3",
|
|
5913
|
+
assetKey: "library:zustand@5.0.3",
|
|
5914
|
+
packageName: "zustand",
|
|
5915
|
+
version: "5.0.3",
|
|
5916
|
+
globalVar: "zustand",
|
|
5917
|
+
cdnPath: "zustand/5.0.3/zustand.min.js",
|
|
5918
|
+
moduleSpecifiers: [
|
|
5919
|
+
{ match: "exact", value: "zustand" },
|
|
5920
|
+
{ match: "exact", value: "zustand/middleware" }
|
|
5921
|
+
],
|
|
5922
|
+
loadStage: 0,
|
|
5923
|
+
enabled: true
|
|
5924
|
+
},
|
|
5925
|
+
{
|
|
5926
|
+
libraryKey: "ammo.js@2024.11",
|
|
5927
|
+
assetKey: "library:ammo.js@2024.11",
|
|
5928
|
+
packageName: "ammo.js",
|
|
5929
|
+
version: "2024.11",
|
|
5930
|
+
globalVar: "Ammo",
|
|
5931
|
+
cdnPath: "ammo/2024.11/ammo.js",
|
|
5932
|
+
moduleSpecifiers: [
|
|
5933
|
+
{ match: "exact", value: "ammo.js" },
|
|
5934
|
+
{ match: "exact", value: "ammo.js/builds/ammo.wasm.js" }
|
|
5935
|
+
],
|
|
5936
|
+
loadStage: 0,
|
|
5937
|
+
enabled: false
|
|
5938
|
+
// Not ready yet - WASM loading needs additional work
|
|
5939
|
+
}
|
|
5940
|
+
];
|
|
5941
|
+
var EMBEDDED_LIBRARY_BY_KEY = EMBEDDED_LIBRARIES.reduce(
|
|
5942
|
+
(acc, lib) => {
|
|
5943
|
+
acc[lib.libraryKey] = lib;
|
|
5944
|
+
return acc;
|
|
5945
|
+
},
|
|
5946
|
+
{}
|
|
5947
|
+
);
|
|
5948
|
+
EMBEDDED_LIBRARIES.filter(
|
|
5949
|
+
(lib) => lib.enabled
|
|
5950
|
+
).flatMap(
|
|
5951
|
+
(lib) => lib.moduleSpecifiers.map((specifier) => ({
|
|
5952
|
+
...specifier,
|
|
5953
|
+
libraryKey: lib.libraryKey
|
|
5954
|
+
}))
|
|
5955
|
+
);
|
|
5956
|
+
function getLibraryDefinition(libraryKey) {
|
|
5957
|
+
const definition = EMBEDDED_LIBRARY_BY_KEY[libraryKey];
|
|
5958
|
+
if (!definition) {
|
|
5959
|
+
const availableKeys = Object.keys(EMBEDDED_LIBRARY_BY_KEY).join(", ");
|
|
5960
|
+
throw new Error(
|
|
5961
|
+
`Unsupported embedded library: ${libraryKey}. Available libraries: ${availableKeys}`
|
|
5962
|
+
);
|
|
5963
|
+
}
|
|
5964
|
+
return definition;
|
|
5965
|
+
}
|
|
5966
|
+
|
|
5967
|
+
// src/shared-assets/base64Utils.ts
|
|
5968
|
+
function base64ToArrayBuffer(base64) {
|
|
5969
|
+
const binaryString = atob(base64);
|
|
5970
|
+
const len = binaryString.length;
|
|
5971
|
+
const bytes = new Uint8Array(len);
|
|
5972
|
+
for (let i = 0; i < len; i++) {
|
|
5973
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
5974
|
+
}
|
|
5975
|
+
return bytes.buffer;
|
|
5976
|
+
}
|
|
5977
|
+
function base64ToUtf8(base64) {
|
|
5978
|
+
if (typeof TextDecoder !== "undefined") {
|
|
5979
|
+
const decoder = new TextDecoder("utf-8");
|
|
5980
|
+
const buffer = base64ToArrayBuffer(base64);
|
|
5981
|
+
return decoder.decode(new Uint8Array(buffer));
|
|
5982
|
+
}
|
|
5983
|
+
if (typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined") {
|
|
5984
|
+
const BufferCtor = globalThis.Buffer;
|
|
5985
|
+
return BufferCtor.from(base64, "base64").toString("utf-8");
|
|
5986
|
+
}
|
|
5987
|
+
const binaryString = atob(base64);
|
|
5988
|
+
let result = "";
|
|
5989
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
5990
|
+
result += String.fromCharCode(binaryString.charCodeAt(i));
|
|
5991
|
+
}
|
|
5992
|
+
return decodeURIComponent(escape(result));
|
|
5993
|
+
}
|
|
5994
|
+
|
|
5709
5995
|
// src/shared-assets/RpcSharedAssetsApi.ts
|
|
5710
5996
|
var RpcSharedAssetsApi = class {
|
|
5711
5997
|
constructor(rpcClient, venusApi) {
|
|
@@ -5744,16 +6030,33 @@ var RpcSharedAssetsApi = class {
|
|
|
5744
6030
|
}
|
|
5745
6031
|
}
|
|
5746
6032
|
}
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
6033
|
+
async loadLibraryCode(libraryKey) {
|
|
6034
|
+
const definition = getLibraryDefinition(libraryKey);
|
|
6035
|
+
try {
|
|
6036
|
+
const response = await this.rpcClient.callT("H5_LOAD_EMBEDDED_ASSET" /* H5_LOAD_EMBEDDED_ASSET */, {
|
|
6037
|
+
assetKey: definition.assetKey
|
|
6038
|
+
});
|
|
6039
|
+
return base64ToUtf8(response.base64Data);
|
|
6040
|
+
} catch (err) {
|
|
6041
|
+
console.error(
|
|
6042
|
+
`[Venus Libraries] Failed to load ${libraryKey} from host via RPC:`,
|
|
6043
|
+
err
|
|
6044
|
+
);
|
|
6045
|
+
console.warn(
|
|
6046
|
+
`[Venus Libraries] Falling back to CDN for ${libraryKey}. This may indicate an asset packaging issue.`
|
|
6047
|
+
);
|
|
6048
|
+
try {
|
|
6049
|
+
const cdnUrl = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
|
|
6050
|
+
const response = await this.venusApi.cdn.fetchFromCdn(cdnUrl);
|
|
6051
|
+
return await response.text();
|
|
6052
|
+
} catch (cdnError) {
|
|
6053
|
+
throw new Error(
|
|
6054
|
+
`Failed to load embedded library ${libraryKey}: RPC failed, CDN fallback failed: ${cdnError.message}`
|
|
6055
|
+
);
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
5754
6058
|
}
|
|
5755
|
-
|
|
5756
|
-
}
|
|
6059
|
+
};
|
|
5757
6060
|
|
|
5758
6061
|
// src/shared-assets/MockSharedAssetsApi.ts
|
|
5759
6062
|
var MockSharedAssetsApi = class {
|
|
@@ -5769,6 +6072,12 @@ var MockSharedAssetsApi = class {
|
|
|
5769
6072
|
const blob = await this.venusApi.cdn.fetchBlob(CharacterAssetsCdnPath);
|
|
5770
6073
|
return await blob.arrayBuffer();
|
|
5771
6074
|
}
|
|
6075
|
+
async loadLibraryCode(libraryKey) {
|
|
6076
|
+
const definition = getLibraryDefinition(libraryKey);
|
|
6077
|
+
const url = this.venusApi.cdn.resolveSharedLibUrl(definition.cdnPath);
|
|
6078
|
+
const response = await this.venusApi.cdn.fetchFromCdn(url);
|
|
6079
|
+
return await response.text();
|
|
6080
|
+
}
|
|
5772
6081
|
};
|
|
5773
6082
|
|
|
5774
6083
|
// src/game-preloader/MockPreloaderApi.ts
|
|
@@ -7134,7 +7443,7 @@ var RemoteHost = class {
|
|
|
7134
7443
|
this.popups = new RpcPopupsApi(rpcClient);
|
|
7135
7444
|
this.profile = new HostProfileApi();
|
|
7136
7445
|
this.cdn = new HostCdnApi(getCdnBaseUrl());
|
|
7137
|
-
this.time = new HostTimeApi(rpcClient);
|
|
7446
|
+
this.time = new HostTimeApi(rpcClient, venusApi);
|
|
7138
7447
|
this.post = new RpcPostApi(rpcClient);
|
|
7139
7448
|
this.ai = new RpcAiApi(rpcClient);
|
|
7140
7449
|
this.haptics = new RpcHapticsApi(rpcClient);
|
|
@@ -7221,7 +7530,7 @@ function createHost(venusApi, isMock) {
|
|
|
7221
7530
|
init_rooms();
|
|
7222
7531
|
|
|
7223
7532
|
// src/version.ts
|
|
7224
|
-
var SDK_VERSION = "3.0.
|
|
7533
|
+
var SDK_VERSION = "3.1.0-beta.0";
|
|
7225
7534
|
|
|
7226
7535
|
// src/social/index.ts
|
|
7227
7536
|
function initializeSocial(venusApi, host) {
|
|
@@ -7527,6 +7836,26 @@ var VenusAPI2 = class {
|
|
|
7527
7836
|
}
|
|
7528
7837
|
}
|
|
7529
7838
|
});
|
|
7839
|
+
const originalConfig = this.config;
|
|
7840
|
+
this.config = new Proxy(originalConfig, {
|
|
7841
|
+
get(target, prop) {
|
|
7842
|
+
if (prop === "locale" || prop === "languageCode") {
|
|
7843
|
+
console.error(
|
|
7844
|
+
`[Venus SDK] config.${prop} is deprecated and will be removed in v4.0.0. Use VenusAPI.${prop === "locale" ? "getLocale()" : "getLanguageCode()"}() instead.`
|
|
7845
|
+
);
|
|
7846
|
+
}
|
|
7847
|
+
return target[prop];
|
|
7848
|
+
},
|
|
7849
|
+
set(target, prop, value) {
|
|
7850
|
+
if (prop === "locale" || prop === "languageCode") {
|
|
7851
|
+
console.error(
|
|
7852
|
+
`[Venus SDK] config.${prop} is deprecated and will be removed in v4.0.0. Use VenusAPI.${prop === "locale" ? "getLocale()" : "getLanguageCode()"}() instead.`
|
|
7853
|
+
);
|
|
7854
|
+
}
|
|
7855
|
+
target[prop] = value;
|
|
7856
|
+
return true;
|
|
7857
|
+
}
|
|
7858
|
+
});
|
|
7530
7859
|
const isInsideHostedEnv = this._bootstrap.isInsideHostedEnvironment;
|
|
7531
7860
|
const host = createHost(this, !isInsideHostedEnv);
|
|
7532
7861
|
this.host = host;
|
|
@@ -7557,6 +7886,28 @@ var VenusAPI2 = class {
|
|
|
7557
7886
|
initializeSimulation(this, host);
|
|
7558
7887
|
initializeSocial(this, host);
|
|
7559
7888
|
initializeAssetLoader(this, createProxiedMethod);
|
|
7889
|
+
this.getLocale = () => {
|
|
7890
|
+
if (typeof window !== "undefined" && window.venus) {
|
|
7891
|
+
const venus = window.venus;
|
|
7892
|
+
if (venus.config && venus.config.locale) {
|
|
7893
|
+
return venus.config.locale;
|
|
7894
|
+
}
|
|
7895
|
+
if (venus._config && venus._config.locale) {
|
|
7896
|
+
return venus._config.locale;
|
|
7897
|
+
}
|
|
7898
|
+
if (venus.config?.environment?.browserInfo?.language) {
|
|
7899
|
+
return venus.config.environment.browserInfo.language;
|
|
7900
|
+
}
|
|
7901
|
+
}
|
|
7902
|
+
if (typeof navigator !== "undefined" && navigator.language) {
|
|
7903
|
+
return navigator.language;
|
|
7904
|
+
}
|
|
7905
|
+
return "en-US";
|
|
7906
|
+
};
|
|
7907
|
+
this.getLanguageCode = () => {
|
|
7908
|
+
const locale = this.getLocale();
|
|
7909
|
+
return locale.split("-")[0];
|
|
7910
|
+
};
|
|
7560
7911
|
}
|
|
7561
7912
|
// Generate deterministic instance ID based on current page URL
|
|
7562
7913
|
_generateDeterministicInstanceId() {
|