feat: unify recommend anonymous runtime guest auth
- Route recommended runtime launches through shared runtime guest token handling - Extend recommend-page anonymous play beyond jump-hop - Add regression coverage for runtime guest launch clients - Update docs to reflect the full anonymous-play matrix
This commit is contained in:
@@ -117,6 +117,7 @@ import {
|
||||
BACKGROUND_AUTH_REQUEST_OPTIONS,
|
||||
} from '../../services/apiClient';
|
||||
import {
|
||||
ensureRuntimeGuestToken,
|
||||
getPublicAuthUserByCode,
|
||||
getPublicAuthUserById,
|
||||
} from '../../services/authService';
|
||||
@@ -127,6 +128,7 @@ import {
|
||||
publishBarkBattleWork,
|
||||
updateBarkBattleDraftConfig,
|
||||
} from '../../services/bark-battle-creation';
|
||||
import { startBarkBattleRun } from '../../services/bark-battle-runtime';
|
||||
import {
|
||||
createBigFishCreationSession,
|
||||
executeBigFishCreationAction,
|
||||
@@ -550,8 +552,13 @@ const AGENT_RESULT_STRUCTURAL_BLOCKER_CODES = new Set([
|
||||
]);
|
||||
const RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS =
|
||||
BACKGROUND_AUTH_REQUEST_OPTIONS;
|
||||
const PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS =
|
||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS;
|
||||
async function buildRecommendRuntimeGuestOptions() {
|
||||
const { token } = await ensureRuntimeGuestToken();
|
||||
return {
|
||||
...RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS,
|
||||
runtimeGuestToken: token,
|
||||
};
|
||||
}
|
||||
const PUZZLE_DRAFT_GENERATION_POINT_COST = 2;
|
||||
const MATCH3D_DRAFT_GENERATION_POINT_COST = 10;
|
||||
const BARK_BATTLE_DRAFT_GENERATION_POINT_COST = 3;
|
||||
@@ -3253,6 +3260,11 @@ export function PlatformEntryFlowShellImpl({
|
||||
resolveRpgCreationErrorMessage(error, fallback),
|
||||
[],
|
||||
);
|
||||
const resolveBarkBattleErrorMessage = useCallback(
|
||||
(error: unknown, fallback: string) =>
|
||||
resolveRpgCreationErrorMessage(error, fallback),
|
||||
[],
|
||||
);
|
||||
|
||||
const refreshBigFishShelf = useCallback(async () => {
|
||||
setIsBigFishLoadingLibrary(true);
|
||||
@@ -7135,11 +7147,14 @@ export function PlatformEntryFlowShellImpl({
|
||||
profileId: targetProfileId,
|
||||
mode: 'play' as const,
|
||||
};
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const { run } = options.embedded
|
||||
? await startVisualNovelRun(
|
||||
targetProfileId,
|
||||
startRunPayload,
|
||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS,
|
||||
runtimeGuestOptions,
|
||||
)
|
||||
: await startVisualNovelRun(targetProfileId, startRunPayload);
|
||||
setVisualNovelWork(workDetail);
|
||||
@@ -7186,9 +7201,14 @@ export function PlatformEntryFlowShellImpl({
|
||||
setVisualNovelError(null);
|
||||
setIsVisualNovelBusy(true);
|
||||
try {
|
||||
const runtimeGuestOptions =
|
||||
activeRecommendRuntimeKind === 'visual-novel'
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const nextRun = await streamVisualNovelRuntimeAction(
|
||||
visualNovelRun.runId,
|
||||
payload,
|
||||
runtimeGuestOptions,
|
||||
);
|
||||
setVisualNovelRun(nextRun);
|
||||
} catch (error) {
|
||||
@@ -7200,6 +7220,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
}
|
||||
},
|
||||
[
|
||||
activeRecommendRuntimeKind,
|
||||
isVisualNovelBusy,
|
||||
resolvePuzzleErrorMessage,
|
||||
setIsVisualNovelBusy,
|
||||
@@ -7608,12 +7629,12 @@ export function PlatformEntryFlowShellImpl({
|
||||
setJumpHopError(null);
|
||||
setJumpHopRuntimeReturnStage(options.returnStage ?? 'work-detail');
|
||||
try {
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const [detail, runResponse] = await Promise.all([
|
||||
jumpHopClient.getWorkDetail(normalizedProfileId).catch(() => null),
|
||||
jumpHopClient.startRun(
|
||||
normalizedProfileId,
|
||||
options.embedded ? RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS : {},
|
||||
),
|
||||
jumpHopClient.startRun(normalizedProfileId, runtimeGuestOptions),
|
||||
]);
|
||||
if (detail?.item) {
|
||||
setJumpHopWork(detail.item);
|
||||
@@ -7902,9 +7923,14 @@ export function PlatformEntryFlowShellImpl({
|
||||
setWoodenFishError(null);
|
||||
setWoodenFishRuntimeReturnStage(options.returnStage ?? 'work-detail');
|
||||
try {
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const [detail, runResponse] = await Promise.all([
|
||||
woodenFishClient.getWorkDetail(normalizedProfileId).catch(() => null),
|
||||
woodenFishClient.startRun(normalizedProfileId),
|
||||
options.embedded
|
||||
? woodenFishClient.startRun(normalizedProfileId, runtimeGuestOptions)
|
||||
: woodenFishClient.startRun(normalizedProfileId),
|
||||
]);
|
||||
if (detail?.item) {
|
||||
setWoodenFishWork(detail.item);
|
||||
@@ -8384,15 +8410,15 @@ export function PlatformEntryFlowShellImpl({
|
||||
profileId: item.profileId,
|
||||
levelId: levelId ?? null,
|
||||
};
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const authMode = options.embedded
|
||||
? 'isolated'
|
||||
: (options.authMode ?? 'default');
|
||||
const { run } =
|
||||
authMode === 'isolated'
|
||||
? await startPuzzleRun(
|
||||
startRunPayload,
|
||||
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
|
||||
)
|
||||
? await startPuzzleRun(startRunPayload, runtimeGuestOptions)
|
||||
: await startPuzzleRun(startRunPayload);
|
||||
setSelectedPuzzleDetail(item);
|
||||
setPuzzleRun(run);
|
||||
@@ -8488,10 +8514,11 @@ export function PlatformEntryFlowShellImpl({
|
||||
runtimeProfile.generatedBackgroundAsset,
|
||||
{ expireSeconds: 300 },
|
||||
);
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const runtimeOptions = {
|
||||
...(options.embedded
|
||||
? RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS
|
||||
: {}),
|
||||
...runtimeGuestOptions,
|
||||
...(typeof options.itemTypeCountOverride === 'number'
|
||||
? { itemTypeCountOverride: options.itemTypeCountOverride }
|
||||
: {}),
|
||||
@@ -8559,11 +8586,11 @@ export function PlatformEntryFlowShellImpl({
|
||||
setSquareHoleError(null);
|
||||
|
||||
try {
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const { run } = options.embedded
|
||||
? await startSquareHoleRun(
|
||||
profile.profileId,
|
||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS,
|
||||
)
|
||||
? await startSquareHoleRun(profile.profileId, runtimeGuestOptions)
|
||||
: await startSquareHoleRun(profile.profileId);
|
||||
setSquareHoleRun(run);
|
||||
setSquareHoleRuntimeReturnStage(returnStage);
|
||||
@@ -8715,9 +8742,14 @@ export function PlatformEntryFlowShellImpl({
|
||||
|
||||
bigFishInputInFlightRef.current = true;
|
||||
try {
|
||||
const runtimeGuestOptions =
|
||||
activeRecommendRuntimeKind === 'big-fish'
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const { run } = await submitBigFishRuntimeInput(
|
||||
bigFishRun.runId,
|
||||
payload,
|
||||
runtimeGuestOptions,
|
||||
);
|
||||
setBigFishRun(run);
|
||||
} catch (error) {
|
||||
@@ -8728,7 +8760,12 @@ export function PlatformEntryFlowShellImpl({
|
||||
bigFishInputInFlightRef.current = false;
|
||||
}
|
||||
},
|
||||
[bigFishRun, resolveBigFishErrorMessage, setBigFishError],
|
||||
[
|
||||
activeRecommendRuntimeKind,
|
||||
bigFishRun,
|
||||
resolveBigFishErrorMessage,
|
||||
setBigFishError,
|
||||
],
|
||||
);
|
||||
|
||||
const reportBigFishObservedPlayTime = useCallback(() => {
|
||||
@@ -8929,12 +8966,13 @@ export function PlatformEntryFlowShellImpl({
|
||||
profileId: currentLevel.profileId,
|
||||
levelId: resolvePuzzleRestartLevelId(currentRun, detailItem),
|
||||
};
|
||||
const runtimeGuestOptions =
|
||||
puzzleRuntimeAuthMode === 'isolated'
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const { run } =
|
||||
puzzleRuntimeAuthMode === 'isolated'
|
||||
? await startPuzzleRun(
|
||||
startRunPayload,
|
||||
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
|
||||
)
|
||||
? await startPuzzleRun(startRunPayload, runtimeGuestOptions)
|
||||
: await startPuzzleRun(startRunPayload);
|
||||
setSelectedPuzzleDetail(detailItem);
|
||||
puzzleRunRef.current = run;
|
||||
@@ -9057,10 +9095,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
|
||||
const submitLeaderboardPromise =
|
||||
puzzleRuntimeAuthMode === 'isolated'
|
||||
? submitPuzzleLeaderboard(
|
||||
puzzleRun.runId,
|
||||
payload,
|
||||
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
|
||||
? buildRecommendRuntimeGuestOptions().then((runtimeGuestOptions) =>
|
||||
submitPuzzleLeaderboard(puzzleRun.runId, payload, runtimeGuestOptions),
|
||||
)
|
||||
: submitPuzzleLeaderboard(puzzleRun.runId, payload);
|
||||
|
||||
@@ -9117,6 +9153,10 @@ export function PlatformEntryFlowShellImpl({
|
||||
return;
|
||||
}
|
||||
|
||||
const runtimeGuestOptions =
|
||||
puzzleRuntimeAuthMode === 'isolated'
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const targetProfileId = _target?.profileId?.trim() ?? '';
|
||||
if (puzzleRun.nextLevelMode === 'similarWorks' && targetProfileId) {
|
||||
const itemPromise =
|
||||
@@ -9132,7 +9172,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
{
|
||||
targetProfileId,
|
||||
},
|
||||
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
|
||||
runtimeGuestOptions,
|
||||
)
|
||||
: advancePuzzleNextLevel(puzzleRun.runId, {
|
||||
targetProfileId,
|
||||
@@ -9157,7 +9197,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
? await advancePuzzleNextLevel(
|
||||
puzzleRun.runId,
|
||||
{},
|
||||
PUBLIC_PUZZLE_RUNTIME_AUTH_OPTIONS,
|
||||
runtimeGuestOptions,
|
||||
)
|
||||
: await advancePuzzleNextLevel(puzzleRun.runId);
|
||||
setPuzzleRun(run);
|
||||
@@ -10993,11 +11033,11 @@ export function PlatformEntryFlowShellImpl({
|
||||
setBigFishRuntimeReturnStage(returnStage);
|
||||
setBigFishRun(null);
|
||||
try {
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const { run } = options.embedded
|
||||
? await startBigFishRuntimeRun(
|
||||
sessionId,
|
||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS,
|
||||
)
|
||||
? await startBigFishRuntimeRun(sessionId, runtimeGuestOptions)
|
||||
: await startBigFishRuntimeRun(sessionId);
|
||||
setBigFishRuntimeStartedAt(Date.now());
|
||||
setBigFishRun(run);
|
||||
@@ -11008,11 +11048,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
);
|
||||
}
|
||||
const recordPlayPromise = options.embedded
|
||||
? recordBigFishPlay(
|
||||
sessionId,
|
||||
{ elapsedMs: 0 },
|
||||
RECOMMEND_RUNTIME_BACKGROUND_AUTH_OPTIONS,
|
||||
)
|
||||
? recordBigFishPlay(sessionId, { elapsedMs: 0 }, runtimeGuestOptions)
|
||||
: recordBigFishPlay(sessionId, { elapsedMs: 0 });
|
||||
void recordPlayPromise.catch((error) => {
|
||||
setBigFishError(
|
||||
@@ -11031,9 +11067,10 @@ export function PlatformEntryFlowShellImpl({
|
||||
);
|
||||
|
||||
const startBarkBattleRunFromWork = useCallback(
|
||||
(
|
||||
async (
|
||||
item: BarkBattleWorkSummary,
|
||||
returnStage: BarkBattleRuntimeReturnStage = 'work-detail',
|
||||
options: { embedded?: boolean } = {},
|
||||
) => {
|
||||
if (item.status !== 'published') {
|
||||
setBarkBattleError('汪汪声浪作品发布后才能进入正式玩法。');
|
||||
@@ -11045,17 +11082,33 @@ export function PlatformEntryFlowShellImpl({
|
||||
setBarkBattleRuntimeMode('published');
|
||||
setBarkBattlePublishedConfig(mapBarkBattleWorkToPublishedConfig(item));
|
||||
setBarkBattleRuntimeReturnStage(returnStage);
|
||||
selectionStageRef.current = 'bark-battle-runtime';
|
||||
setSelectionStage('bark-battle-runtime');
|
||||
pushAppHistoryPath(
|
||||
buildPublicWorkStagePath(
|
||||
'bark-battle-runtime',
|
||||
buildBarkBattlePublicWorkCode(item.workId),
|
||||
),
|
||||
);
|
||||
return true;
|
||||
try {
|
||||
const runtimeGuestOptions = options.embedded
|
||||
? await buildRecommendRuntimeGuestOptions()
|
||||
: {};
|
||||
const runResponse = options.embedded
|
||||
? await startBarkBattleRun(item.workId, {}, runtimeGuestOptions)
|
||||
: await startBarkBattleRun(item.workId);
|
||||
void runResponse;
|
||||
selectionStageRef.current = 'bark-battle-runtime';
|
||||
if (!options.embedded) {
|
||||
setSelectionStage('bark-battle-runtime');
|
||||
pushAppHistoryPath(
|
||||
buildPublicWorkStagePath(
|
||||
'bark-battle-runtime',
|
||||
buildBarkBattlePublicWorkCode(item.workId),
|
||||
),
|
||||
);
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
setBarkBattleError(
|
||||
resolveBarkBattleErrorMessage(error, '启动汪汪声浪玩法失败。'),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[setSelectionStage],
|
||||
[resolveBarkBattleErrorMessage, setSelectionStage],
|
||||
);
|
||||
|
||||
const startSelectedPublicWork = useCallback(() => {
|
||||
@@ -11327,7 +11380,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
'当前汪汪声浪作品信息不完整,暂时无法进入玩法。',
|
||||
);
|
||||
} else {
|
||||
started = startBarkBattleRunFromWork(work, 'platform');
|
||||
started = await startBarkBattleRunFromWork(work, 'platform', {
|
||||
embedded: true,
|
||||
});
|
||||
}
|
||||
} else if (isEdutainmentGalleryEntry(entry)) {
|
||||
started = await startBabyObjectMatchRuntimeFromEntry(
|
||||
|
||||
Reference in New Issue
Block a user