From 60c7c8aa4afcbc88f9e5ce6d43a3f52fb45d1416 Mon Sep 17 00:00:00 2001 From: "COMPUTER\\EDY" <249929363@qq.com> Date: Fri, 16 Oct 2026 20:29:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D3=E8=BF=9E=E8=83=9C=E4=B8=8D?= =?UTF-8?q?=E6=96=AD=E8=BF=9E=E8=83=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/Script/Map.ts | 2 +- assets/Script/module/Pay/Utils.ts | 4 +- tools/test-three-win-streak.cjs | 106 ++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/assets/Script/Map.ts b/assets/Script/Map.ts index 1752295a..fbea85a2 100644 --- a/assets/Script/Map.ts +++ b/assets/Script/Map.ts @@ -5763,7 +5763,7 @@ export default class MapConroler extends cc.Component { } // MiniGameSdk.API.showToast("体力值减少"); cc.fx.GameConfig.LEVEL_INFO_init(false, 0, false); - if (customEventData == false) this.threeWinStreak.fail(); + if (!this.gameWin) this.threeWinStreak.fail(); if (cc.fx.GameConfig.GM_INFO.otherLevel == 0 && customEventData == false) { cc.fx.GameTool.setWinStreak("fail"); DailyTaskProgressTracker.invalidateAttempt(); diff --git a/assets/Script/module/Pay/Utils.ts b/assets/Script/module/Pay/Utils.ts index 431ec466..7a7c9cf1 100644 --- a/assets/Script/module/Pay/Utils.ts +++ b/assets/Script/module/Pay/Utils.ts @@ -181,8 +181,8 @@ export default class Utils { static outTradeNo: string = ""; // static httpip: string = `https://laf.nika4games.com/`; //五彩消消乐 static httpip: string = `https://q6rvwvtnga.sealoshzh.site/`; //消消王者 - static testHttpip: string = `https://sor779u2w8.sealoshzh.site/`; //测试服务器 - // static testHttpip: string = `https://q6rvwvtnga.sealoshzh.site/`; //消消王者测试服暂替 + // static testHttpip: string = `https://sor779u2w8.sealoshzh.site/`; //测试服务器 + static testHttpip: string = `https://q6rvwvtnga.sealoshzh.site/`; //消消王者测试服暂替 //#region 安卓支付 /**获取用户信息*/ static getUserInfo(callBack, from?: string, wucaiEntryId = "") { diff --git a/tools/test-three-win-streak.cjs b/tools/test-three-win-streak.cjs index 0e46baae..e9a24c89 100644 --- a/tools/test-three-win-streak.cjs +++ b/tools/test-three-win-streak.cjs @@ -28,6 +28,112 @@ function fixture(cache = {}, acknowledge = true) { return { Streak: output.exports.default, info: cc.fx.GameConfig.GM_INFO, storage, saves, cc }; } +function methods(file, names, globals) { + const source = ts.createSourceFile(file, read(file), ts.ScriptTarget.Latest, true); + const type = source.statements.find(ts.isClassDeclaration); + const members = names.map(name => type.members.find(node => node.name && node.name.getText(source) === name).getText(source)); + return vm.runInNewContext(compile('class Subject {' + members.join('\n') + '}\nSubject;'), { ...globals }).prototype; +} + +function gameFixture(count) { + const f = fixture(); + f.Streak.restore({ threeWinStreak: count }); + Object.assign(f.info, { level: 50, hp: 1, otherLevel: 0, GameplayType: 0 }); + Object.assign(f.cc.fx.GameConfig, { isWinStreakUnlocked: () => true, LEVEL_INFO_init() {} }); + f.cc.fx.AudioManager = { _instance: { playEffect() {} } }; + f.cc.fx.GameTool = { getUserPowerTime: () => false, setUserHealth() {}, maxLevel: () => false, + shushu_Track() {}, setWinStreak() {}, getAuthorizationAvatar: () => true }; + f.cc.director = { preloadScene() {}, loadScene() {} }; + f.cc.find = () => null; + const transition = { active: false, getComponent: () => ({ setAnimation() {} }) }; + const map = { gameStart: false, gameWin: false, gameOver: false, againCanTouch: true, + threeWinStreak: new f.Streak(true), isMapRuntimeAlive: () => true, + settleCloudRiseLoss: async () => true, startBoostLoadout: { streak: count }, startBoostKey: '50:0:0', + onBlockClick() {}, iceTrue: () => false, startTimeCutDown() {}, stopTimeCutDown() {}, trackFinishi() {}, + node: { parent: { parent: { parent: { getChildByName: () => transition } } } } }; + const MapConroler = { _instance: map, startBoostReplay: null }; + const globals = { cc: f.cc, MapConroler, console: { log() {} }, sp: { Skeleton: class {} }, + CloudRiseView: { continueFromNextLevel: async () => true }, + DailyTaskProgressTracker: { invalidateAttempt() {}, resetWinStreak() {} }, setTimeout: callback => callback() }; + const mapMethods = methods('assets/Script/Map.ts', ['startUpdate', 'returnHome', 'againLevel'], globals); + map.startUpdate = mapMethods.startUpdate; + for (const name of ['returnHome', 'againLevel']) { + map[name] = (...args) => f.exit = mapMethods[name].apply(map, args); + } + const ui = Object.create(methods('assets/Script/setUi.ts', ['clickExit', 'returnHome', 'clickRestart', 'cancelExit'], globals)); + ui.showGiveUpConfirmation = () => true; + ui.win = { active: true }; ui.win2 = { active: true }; + return { ...f, map, ui, controller: MapConroler, exited: () => f.exit }; +} + +test('pause give-up clears all three tiers, through confirmation and the direct exit path', async () => { + for (const count of [1, 2, 3]) { + for (const confirm of [true, false]) { + const f = gameFixture(count); + f.map.startUpdate(); + assert.equal(f.storage.threeWinStreakPending, true); + f.ui.showGiveUpConfirmation = () => confirm; + f.ui.clickExit(); + if (confirm) { + assert.equal(f.info.threeWinStreak, count, 'opening the prompt must not settle the round'); + f.ui.returnHome(); // This callback invokes Map.returnHome without customEventData. + } + await f.exited(); + assert.equal(f.info.threeWinStreak, 0); + assert.equal(f.storage.threeWinStreakPending, false); + assert.deepEqual(f.saves.map(save => save.fields.threeWinStreak), [0]); + } + } +}); + +test('actual pause restart clears played rounds at every tier and preserves untouched rounds', async () => { + for (const count of [1, 2, 3]) { + for (const played of [true, false]) { + const f = gameFixture(count); + if (played) f.map.startUpdate(); + f.ui.clickRestart(null, 'hp'); + await f.exited(); + assert.equal(f.info.threeWinStreak, played ? 0 : count); + assert.equal(f.saves.length, played ? 1 : 0); + assert.equal(!!f.controller.startBoostReplay, !played); + } + } +}); + +test('cancel, untouched exit and victory exit preserve the streak', async () => { + const cancelled = gameFixture(2); + cancelled.map.startUpdate(); + cancelled.ui.clickExit(); + cancelled.ui.cancelExit(); + assert.equal(cancelled.info.threeWinStreak, 2); + assert.equal(cancelled.storage.threeWinStreakPending, true); + assert.equal(cancelled.exited(), undefined); + for (const won of [false, true]) { + const f = gameFixture(2); + if (won) { + f.map.startUpdate(); + f.map.threeWinStreak.win(); + f.map.gameWin = true; + } + await f.map.returnHome(); + assert.equal(f.info.threeWinStreak, won ? 3 : 2); + assert.equal(f.saves.length, won ? 1 : 0); + } +}); + +test('force quit after an actual first operation clears every tier on relaunch despite stale server data', () => { + for (const count of [1, 2, 3]) { + const f = gameFixture(count); + f.map.startUpdate(); + const reloaded = fixture(f.storage); + reloaded.Streak.restore(); + reloaded.Streak.restore({ threeWinStreak: count }); + assert.equal(reloaded.info.threeWinStreak, 0); + assert.equal(reloaded.storage.threeWinStreakPending, false); + assert.deepEqual(reloaded.saves.map(save => save.fields.threeWinStreak), [0]); + } +}); + test('existing accounts without the new field start at zero, independent of ten wins', () => { const f = fixture({ threeWinStreak: 2 }); f.Streak.restore();