diff --git a/assets/Script/CoinMadnessProgress.ts b/assets/Script/CoinMadnessProgress.ts index 1ac6a47..d2d606e 100644 --- a/assets/Script/CoinMadnessProgress.ts +++ b/assets/Script/CoinMadnessProgress.ts @@ -10,7 +10,9 @@ export function recordCoinMadnessMockWin(level: number): void { const key = coinMadnessMockKey(); const state = cc.fx.StorageMessage.getStorage(key); if (!state || !state.paidAt || state.settled || Date.now() >= state.config.endsAt || level <= state.lastLevel) return; - if (level === state.lastLevel + 1) state.totalWins++; + // This hook represents one actual victory, not a level delta. Gaps can follow + // config catchup or older builds; count this win once without backfilling them. + state.totalWins++; state.lastLevel = level; cc.fx.StorageMessage.setStorage(key, state); } catch (error) { cc.warn('Coin Madness mock progress unavailable', error); } diff --git a/assets/Script/module/Tool/GameTool.ts b/assets/Script/module/Tool/GameTool.ts index 3316a19..d39a451 100644 --- a/assets/Script/module/Tool/GameTool.ts +++ b/assets/Script/module/Tool/GameTool.ts @@ -397,7 +397,9 @@ var GameTool = { cc.fx.GameConfig.GM_INFO.level += 1; } - if (!endLevel && cc.fx.GameConfig.GM_INFO.GameplayType == 1) recordCoinMadnessMockWin(stageId); + // 普通主线为 0;空计时调用来自配置缺关补进度,不属于实际胜利。 + if (!isMaxLevel && cc.fx.GameConfig.GM_INFO.GameplayType == 0 + && !cc.fx.GameConfig.GM_INFO.otherLevel && time1 != null && time2 != null) recordCoinMadnessMockWin(stageId); cc.fx.GameTool.maxLevel() MiniGameSdk.API.setNewCloudlevel(); const timestamp = Date.now(); diff --git a/tools/coin-madness/check-mock.cjs b/tools/coin-madness/check-mock.cjs index 23a7aff..569210a 100644 --- a/tools/coin-madness/check-mock.cjs +++ b/tools/coin-madness/check-mock.cjs @@ -37,6 +37,6 @@ progressExports.recordCoinMadnessMockWin(11); assert.equal(state.totalWins, 0); api.request('purchase', { periodId: state.config.periodId }); progressExports.recordCoinMadnessMockWin(11); progressExports.recordCoinMadnessMockWin(11); assert.equal(state.totalWins, 1); -progressExports.recordCoinMadnessMockWin(14); assert.equal(state.totalWins, 1); -progressExports.recordCoinMadnessMockWin(15); assert.equal(state.totalWins, 2); -console.log('Closed-panel progress checks passed: no prepay, duplicate or batch catchup wins.'); +progressExports.recordCoinMadnessMockWin(14); assert.equal(state.totalWins, 2); +progressExports.recordCoinMadnessMockWin(15); assert.equal(state.totalWins, 3); +console.log('Closed-panel progress checks passed: no prepay/duplicates; a live win after a gap counts once without backfill.'); diff --git a/tools/coin-madness/check-win-hook.cjs b/tools/coin-madness/check-win-hook.cjs new file mode 100644 index 0000000..78da1c0 --- /dev/null +++ b/tools/coin-madness/check-win-hook.cjs @@ -0,0 +1,27 @@ +const ts = require('typescript'); +const fs = require('node:fs'); +const assert = require('node:assert/strict'); +// Execute the actual addLevel method, with external game services stubbed. +const source = fs.readFileSync('assets/Script/module/Tool/GameTool.ts', 'utf8'); +const ast = ts.createSourceFile('GameTool.ts', source, ts.ScriptTarget.Latest, true); +let method; +function visit(node) { + if (ts.isMethodDeclaration(node) && node.name.getText(ast) === 'addLevel') method = node; + ts.forEachChild(node, visit); +} +visit(ast); assert.ok(method); +const calls = []; +const info = { level: 10, GameplayType: 0, otherLevel: 0 }; +let max = false; +const cc = { fx: { GameConfig: { GM_INFO: info }, StorageMessage: { setStorage() {} }, + GameTool: { maxLevel: () => max, shushu_Track() {} } } }; +const run = new Function('cc', 'recordCoinMadnessMockWin', 'MiniGameSdk', 'Utils', 'MapConroler', + 'return ({' + method.getText(ast) + '}).addLevel;')(cc, level => calls.push(level), + { API: { setNewCloudlevel() {}, shushu_SetSuperProperties() {} } }, { setUserLevel() {} }, { _instance: null }); +run(1000, 0, null); assert.deepEqual(calls, [11]); +info.GameplayType = 1; run(1000, 0, null); assert.equal(calls.length, 1); +info.GameplayType = 0; info.otherLevel = 3; run(1000, 0, null); assert.equal(calls.length, 1); +info.otherLevel = 0; run(null, null, null); assert.equal(calls.length, 1); +max = true; run(1000, 0, null); assert.equal(calls.length, 1); +max = false; info.level = 1979; run(1000, 0, null); assert.deepEqual(calls, [11, 1980]); +console.log('Actual addLevel hook passed: normal wins, last normal level, excluded endless/special/config catchup.');