Music Shake 첫 박 시각 · 카운트다운 · 옛 일시 정지 판 정리
This commit is contained in:
@@ -178,6 +178,8 @@ export const fnQuestProgress = onCall(async (req) => {
|
||||
total: count(data, 'total', 1_000_000),
|
||||
positionMs: count(data, 'positionMs', 86_400_000),
|
||||
...(hits !== undefined ? { hits } : {}),
|
||||
// 판을 시작할 때의 첫 박 — 운영값이 바뀌면 앱이 옛 일시 정지를 버리고 새 판으로 시작한다.
|
||||
...(typeof data.firstBeatMs === 'number' ? { firstBeatMs: count(data, 'firstBeatMs', 86_400_000) } : {}),
|
||||
...(tally ? { judgement: tally } : {}),
|
||||
updatedAt: FieldValue.serverTimestamp(),
|
||||
},
|
||||
|
||||
@@ -119,6 +119,13 @@ export const fnQuestVerifyMusicShake = onCall(async (req) => {
|
||||
if (typeof questSegments === 'number' && questSegments !== totalSegments) {
|
||||
fail(ERR.questAbnormal, '곡의 구간 수가 퀘스트 정의와 다릅니다.');
|
||||
}
|
||||
// 첫 박 시각(영상 시각 기준 박 위치 `firstBeatMs + i·60/bpm`)도 같은 기준이어야 한다.
|
||||
const questFirstBeat = quest.get('firstBeatMs');
|
||||
const firstBeatMs = typeof questFirstBeat === 'number' ? questFirstBeat : 0;
|
||||
const sentFirstBeat = req.data?.firstBeatMs;
|
||||
if (sentFirstBeat !== undefined && sentFirstBeat !== firstBeatMs) {
|
||||
fail(ERR.questAbnormal, '첫 박 시각이 퀘스트 정의와 다릅니다.');
|
||||
}
|
||||
const limit = await dailyLimitOf(questId);
|
||||
const state = await progress(uid, questId, key);
|
||||
if (state.count >= limit) {
|
||||
@@ -134,7 +141,7 @@ export const fnQuestVerifyMusicShake = onCall(async (req) => {
|
||||
type: 'musicShake',
|
||||
fandomId: optionalStr(req.data, 'fandomId') ?? '',
|
||||
value: judgement.perfect,
|
||||
evidence: { musicShake: { trackId, totalSegments, judgements: judgement } },
|
||||
evidence: { musicShake: { trackId, totalSegments, firstBeatMs, judgements: judgement } },
|
||||
questId,
|
||||
verified: grade !== 'F',
|
||||
rejectReason: grade === 'F' ? ERR.questIncomplete : null,
|
||||
|
||||
Reference in New Issue
Block a user