Merge branch 'main' into feat-newPass

# Conflicts:
#	assets/GameplayIntro/compressed.meta
#	assets/Script/module/Pay/Utils.ts
#	assets/gacha_bundle/compressed.meta
#	assets/gacha_bundle/img/cat.meta
#	assets/libs/dn-sdk-minigame.meta
#	assets/passCheck/script.meta
#	assets/propWindow/compressed.meta
#	assets/res/shop.meta
#	assets/win/compressed.meta
#	settings/project.json
#	tools/test-battle-pass.cjs
This commit is contained in:
COMPUTER\EDY 2026-10-09 11:04:16 +08:00
commit b5db0d3920
7 changed files with 51 additions and 36 deletions

View File

@ -31,7 +31,7 @@ export function normalizePass(stage: any, rows: any[]): any {
} }
return stage; return stage;
} }
export function mergePassInfo(raw: any, extra: any, rows: any[], oldRows: any[] = rows): any { export function mergePassInfo(raw: any, extra: any, rows: any[]): any {
if (!raw) return raw; if (!raw) return raw;
for (const key of [1, 2]) { for (const key of [1, 2]) {
const old = raw[key]; const old = raw[key];
@ -45,17 +45,17 @@ export function mergePassInfo(raw: any, extra: any, rows: any[], oldRows: any[]
for (let i = 0; i < Math.min(30, (old[lane] || []).length); i++) if (old[lane][i] === 0) raw[key][lane][i] = 0; for (let i = 0; i < Math.min(30, (old[lane] || []).length); i++) if (old[lane][i] === 0) raw[key][lane][i] = 0;
} }
} }
raw[key] = normalizePass(raw[key], key === 1 ? oldRows : rows); raw[key] = normalizePass(raw[key], rows);
} }
return raw; return raw;
} }
export function legacyPassInfo(pass: any, rows: any[], oldRows: any[] = rows): any { export function legacyPassInfo(pass: any, rows: any[]): any {
const legacy: any = {}; const legacy: any = {};
for (const key of [1, 2]) { for (const key of [1, 2]) {
const stage = pass[key]; const stage = pass[key];
if (!stage || !Number(stage.time)) { legacy[key] = stage; continue; } if (!stage || !Number(stage.time)) { legacy[key] = stage; continue; }
const level = Math.max(1, Math.min(30, stage.progressLevel)); const level = Math.max(1, Math.min(30, stage.progressLevel));
const row = (key === 1 ? oldRows : rows)[stage.progressLevel - 1]; const row = rows[stage.progressLevel - 1];
const progress = stage.unlocked >= level ? OLD_TOKENS[level - 1] : Math.min(OLD_TOKENS[level - 1], Math.floor(stage.progress * OLD_TOKENS[level - 1] / Math.max(1, Number(row.token)))); const progress = stage.unlocked >= level ? OLD_TOKENS[level - 1] : Math.min(OLD_TOKENS[level - 1], Math.floor(stage.progress * OLD_TOKENS[level - 1] / Math.max(1, Number(row.token))));
legacy[key] = { time: stage.time, activate: passTier(stage) > 0, progressLevel: level, progress, legacy[key] = { time: stage.time, activate: passTier(stage) > 0, progressLevel: level, progress,
free: (stage.free || []).slice(0, 30), passCheck: (stage.passCheck || []).slice(0, 30) }; free: (stage.free || []).slice(0, 30), passCheck: (stage.passCheck || []).slice(0, 30) };

View File

@ -74,7 +74,6 @@ export class GameConfig {
: this.defaultNewGuide; : this.defaultNewGuide;
} }
static PASS_CHECK: any; static PASS_CHECK: any;
static PASS_CHECK_OLD: any;
private static defaultPassRate: any[] = []; private static defaultPassRate: any[] = [];
private static newPlayerPassRate: any[] = []; private static newPlayerPassRate: any[] = [];
static get PASS_RATE(): any[] { static get PASS_RATE(): any[] {
@ -773,7 +772,7 @@ export class GameConfig {
vibrateOpen: true, //震动 vibrateOpen: true, //震动
coinnum: 0, //每局的金币数 coinnum: 0, //每局的金币数
paid_user: false, //是否是付费用户 paid_user: false, //是否是付费用户
version: "1.0.75", //版本号 version: "1.0.78", //版本号
shushu_DistinctId: "", //数数访客ID shushu_DistinctId: "", //数数访客ID
shushu_AccountId: "", //数数账号ID shushu_AccountId: "", //数数账号ID
uid: "", //用户和后端唯一id uid: "", //用户和后端唯一id
@ -882,14 +881,7 @@ export class GameConfig {
return; return;
} }
const newLevelData = res.json; const newLevelData = res.json;
cc.resources.load("Json/PASS_CHECK_OLD", (oldError: any, oldRes: cc.JsonAsset) => {
if (oldError) {
console.error("加载 PASS_CHECK_OLD.JSON 失败:", oldError);
return;
}
this.PASS_CHECK_OLD = oldRes.json.Sheet1;
this.PASS_CHECK = newLevelData.Sheet1; this.PASS_CHECK = newLevelData.Sheet1;
});
// 可以根据需求对 newLevelData 进行处理 // 可以根据需求对 newLevelData 进行处理
// //console.log("PASS_CHECK.JSON 加载成功:", newLevelData); // //console.log("PASS_CHECK.JSON 加载成功:", newLevelData);
}) })

View File

@ -1510,7 +1510,7 @@ export default class Utils {
cc.fx.StorageMessage.setStorage('coin', { coin: cc.fx.GameConfig.GM_INFO.coin, timestamp: Date.now() }); cc.fx.StorageMessage.setStorage('coin', { coin: cc.fx.GameConfig.GM_INFO.coin, timestamp: Date.now() });
} }
static getPassCheckInfo(callBack) { static getPassCheckInfo(callBack) {
if (!cc.fx.GameConfig.PASS_CHECK || !cc.fx.GameConfig.PASS_CHECK_OLD) { if (!cc.fx.GameConfig.PASS_CHECK) {
if (callBack) callBack({ code: 0, msg: '战令配置尚未加载,请稍后重试' }); if (callBack) callBack({ code: 0, msg: '战令配置尚未加载,请稍后重试' });
return; return;
} }
@ -1518,7 +1518,7 @@ export default class Utils {
if (res.code !== 1) { if (callBack) callBack(res); return; } if (res.code !== 1) { if (callBack) callBack(res); return; }
Utils.passRequest('read').then(extra => { Utils.passRequest('read').then(extra => {
const raw = typeof extra.data.legacy === 'string' ? JSON.parse(extra.data.legacy) : extra.data.legacy; const raw = typeof extra.data.legacy === 'string' ? JSON.parse(extra.data.legacy) : extra.data.legacy;
let pass = mergePassInfo(raw, extra.data.extra, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); let pass = mergePassInfo(raw, extra.data.extra, cc.fx.GameConfig.PASS_CHECK);
// Expired periods are archived by the read API before the current season is rotated. // Expired periods are archived by the read API before the current season is rotated.
const rotated = pass && (!pass[2] || Number(pass[2].time) <= Date.now()); const rotated = pass && (!pass[2] || Number(pass[2].time) <= Date.now());
if (pass) { if (pass) {
@ -1546,17 +1546,17 @@ export default class Utils {
let pass = data; let pass = data;
for (let attempt = 0; attempt < 3; attempt++) { for (let attempt = 0; attempt < 3; attempt++) {
const latest = await Utils.passRequest('read'); const latest = await Utils.passRequest('read');
const merged = mergePassInfo(JSON.parse(latest.data.legacy || 'null'), latest.data.extra, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); const merged = mergePassInfo(JSON.parse(latest.data.legacy || 'null'), latest.data.extra, cc.fx.GameConfig.PASS_CHECK);
for (const key of [1, 2]) { for (const key of [1, 2]) {
if (!pass[key] || !Number(pass[key].time)) continue; if (!pass[key] || !Number(pass[key].time)) continue;
pass[key] = normalizePass(pass[key], key === 1 ? cc.fx.GameConfig.PASS_CHECK_OLD : cc.fx.GameConfig.PASS_CHECK); pass[key] = normalizePass(pass[key], cc.fx.GameConfig.PASS_CHECK);
const current = merged && [merged[1], merged[2]].find(s => String(s && s.time) === String(pass[key].time)); const current = merged && [merged[1], merged[2]].find(s => String(s && s.time) === String(pass[key].time));
if (current) { if (current) {
pass[key].experience = Math.max(pass[key].experience, current.experience); pass[key].experience = Math.max(pass[key].experience, current.experience);
for (const lane of ['free', 'passCheck']) for (let i = 0; i < current[lane].length; i++) { for (const lane of ['free', 'passCheck']) for (let i = 0; i < current[lane].length; i++) {
if (current[lane][i] === 0) pass[key][lane][i] = 0; if (current[lane][i] === 0) pass[key][lane][i] = 0;
} }
pass[key] = normalizePass(pass[key], key === 1 ? cc.fx.GameConfig.PASS_CHECK_OLD : cc.fx.GameConfig.PASS_CHECK); pass[key] = normalizePass(pass[key], cc.fx.GameConfig.PASS_CHECK);
} }
} }
try { return await Utils.passRequest('save', { ...Utils.passUpload(pass), revision: latest.data.revision }); } try { return await Utils.passRequest('save', { ...Utils.passUpload(pass), revision: latest.data.revision }); }
@ -1578,7 +1578,7 @@ export default class Utils {
private static passUpload(pass: any, paidOrder = false): any { private static passUpload(pass: any, paidOrder = false): any {
pass = { ...pass }; pass = { ...pass };
for (const key of [1, 2]) if (!paidOrder && pass[key] && Number(pass[key].time) <= Date.now()) pass[key] = { time: '0', free: [], passCheck: [] }; for (const key of [1, 2]) if (!paidOrder && pass[key] && Number(pass[key].time) <= Date.now()) pass[key] = { time: '0', free: [], passCheck: [] };
const legacy = legacyPassInfo(pass, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); const legacy = legacyPassInfo(pass, cc.fx.GameConfig.PASS_CHECK);
for (const key of [1, 2]) if (pass[key] && Number(pass[key].time)) pass[key].legacyExperience = legacyExperience(legacy[key]); for (const key of [1, 2]) if (pass[key] && Number(pass[key].time)) pass[key].legacyExperience = legacyExperience(legacy[key]);
return { passCheck: JSON.stringify(pass), legacy: JSON.stringify(legacy) }; return { passCheck: JSON.stringify(pass), legacy: JSON.stringify(legacy) };
} }
@ -1613,13 +1613,13 @@ export default class Utils {
return { ...result, data: { ...result.data, postSeason: true } }; return { ...result, data: { ...result.data, postSeason: true } };
} }
if (order.data.alreadyGranted) { Utils.applyPassGift(outTradeNo); return order; } if (order.data.alreadyGranted) { Utils.applyPassGift(outTradeNo); return order; }
const pass = mergePassInfo(JSON.parse(order.data.legacy || '{}'), order.data.extra, cc.fx.GameConfig.PASS_CHECK, cc.fx.GameConfig.PASS_CHECK_OLD); const pass = mergePassInfo(JSON.parse(order.data.legacy || '{}'), order.data.extra, cc.fx.GameConfig.PASS_CHECK);
let key = [1, 2].find(k => String(pass[k] && pass[k].time) === order.data.passEnd); let key = [1, 2].find(k => String(pass[k] && pass[k].time) === order.data.passEnd);
if (!key && order.data.extra[order.data.passEnd]) { key = 1; pass[1] = order.data.extra[order.data.passEnd]; } if (!key && order.data.extra[order.data.passEnd]) { key = 1; pass[1] = order.data.extra[order.data.passEnd]; }
if (!key) throw { code: 410, msg: '订单所属期已过期,请联系客服' }; if (!key) throw { code: 410, msg: '订单所属期已过期,请联系客服' };
pass[key].activate = true; pass[key].tier = order.data.targetTier; pass[key].activate = true; pass[key].tier = order.data.targetTier;
if (order.data.bonus) pass[key].experience += 20; if (order.data.bonus) pass[key].experience += 20;
pass[key] = normalizePass(pass[key], key === 1 ? cc.fx.GameConfig.PASS_CHECK_OLD : cc.fx.GameConfig.PASS_CHECK); pass[key] = normalizePass(pass[key], cc.fx.GameConfig.PASS_CHECK);
// 沿用客户端计算后上传,赠金仅通过战令接口随本期发奖记录一起保存。 // 沿用客户端计算后上传,赠金仅通过战令接口随本期发奖记录一起保存。
const coinAmount = Math.floor(cc.fx.GameConfig.GM_INFO.coin) + (order.data.bonus ? 3000 : 0); const coinAmount = Math.floor(cc.fx.GameConfig.GM_INFO.coin) + (order.data.bonus ? 3000 : 0);
const giftKey = (cc.fx.GameConfig.GM_INFO.uid || Utils.uid) + ':' + outTradeNo; const giftKey = (cc.fx.GameConfig.GM_INFO.uid || Utils.uid) + ':' + outTradeNo;

View File

@ -109,8 +109,7 @@ export default class passCheck extends cc.Component {
} }
onInit(passCheckInfo) { onInit(passCheckInfo) {
this.passData = passCheckInfo; this.passData = passCheckInfo;
const passCheckData = cc.fx.GameConfig.GM_INFO.getItemType == 2 const passCheckData = cc.fx.GameConfig.PASS_CHECK;
? cc.fx.GameConfig.PASS_CHECK : cc.fx.GameConfig.PASS_CHECK_OLD;
// let _playerPassLevel = cc.fx.GameConfig.GM_INFO.playerPassLevel // let _playerPassLevel = cc.fx.GameConfig.GM_INFO.playerPassLevel
// let getUserLevel = cc.fx.GameConfig.GM_INFO.level; // let getUserLevel = cc.fx.GameConfig.GM_INFO.level;

View File

@ -5,6 +5,16 @@ function load(file,deps={},globals={}) { const exports={};vm.runInNewContext(ts.
const model=load('assets/Script/module/Config/BattlePassModel.ts'); const model=load('assets/Script/module/Config/BattlePassModel.ts');
const settlementModel=load('assets/Script/module/Config/BattlePassSettlementModel.ts',{'./BattlePassModel':model}); const settlementModel=load('assets/Script/module/Config/BattlePassSettlementModel.ts',{'./BattlePassModel':model});
const config=JSON.parse(fs.readFileSync('assets/resources/Json/PASS_CHECK.json')).Sheet1; const config=JSON.parse(fs.readFileSync('assets/resources/Json/PASS_CHECK.json')).Sheet1;
test('archived season retains new tiers and excludes claimed rewards with the current table',()=>{
const stage=model.normalizePass({time:'100',experience:config.slice(0,40).reduce((sum,row)=>sum+row.token,0),tier:30,activate:true,free:Array(39).fill(0),passCheck:Array(39).fill(0)},config);
const snapshot={stage:plain(stage)};
const restored=model.normalizePass(snapshot.stage,config);
assert.equal(restored.unlocked,40);
assert.equal(restored.free[37],0);
assert.equal(model.canClaimPass(restored,39,false),true);
assert.deepEqual(plain(settlementModel.settlementRewards(snapshot,config)),[{type:'coin',count:1200},{type:'infinite_health',count:1800}]);
assert.deepEqual(plain(settlementModel.settlementClaimFlags(snapshot,config)).free.slice(0,40),Array(40).fill(0));
});
function fixture() { function fixture() {
const now=1800000000000,end=now-1000,tables={users:[{_id:'u',openid:'o',token:'t',coinAmount:10,freezeAmount:1,hammerAmount:2,magicAmount:3,userPowerTime:0,passCheck:JSON.stringify({2:{time:String(end),experience:4,free:[0,1,1],passCheck:[1,1,1],activate:false}})}],order:[],idcount:[{_id:'clock',passcheckTime:end-model.PASS_PERIOD}]}; const now=1800000000000,end=now-1000,tables={users:[{_id:'u',openid:'o',token:'t',coinAmount:10,freezeAmount:1,hammerAmount:2,magicAmount:3,userPowerTime:0,passCheck:JSON.stringify({2:{time:String(end),experience:4,free:[0,1,1],passCheck:[1,1,1],activate:false}})}],order:[],idcount:[{_id:'clock',passcheckTime:end-model.PASS_PERIOD}]};
let clock=now,drop=false; let clock=now,drop=false;

View File

@ -76,7 +76,6 @@ function animationFixture() {
const storage = new Map(), actions = [], stopped = new Set(); const storage = new Map(), actions = [], stopped = new Set();
cc.fx.StorageMessage = { getStorage: key => storage.get(key), setStorage: (key, value) => storage.set(key, value) }; cc.fx.StorageMessage = { getStorage: key => storage.get(key), setStorage: (key, value) => storage.set(key, value) };
cc.fx.GameConfig.GM_INFO = { uid: 'animation-player', getItemType: 2 }; cc.fx.GameConfig.GM_INFO = { uid: 'animation-player', getItemType: 2 };
cc.fx.GameConfig.PASS_CHECK_OLD = JSON.parse(fs.readFileSync('assets/resources/Json/PASS_CHECK_OLD.json', 'utf8')).Sheet1;
cc.Tween.stopAllByTarget = target => actions.filter(a => a.target === target).forEach(a => stopped.add(a)); cc.Tween.stopAllByTarget = target => actions.filter(a => a.target === target).forEach(a => stopped.add(a));
cc.tween = target => { cc.tween = target => {
const steps = []; const steps = [];
@ -110,8 +109,7 @@ function animationFixture() {
function show(level, partial = 0, options = {}) { function show(level, partial = 0, options = {}) {
const season = options.season || '2000000000000', tier = options.tier || 0; const season = options.season || '2000000000000', tier = options.tier || 0;
cc.fx.GameConfig.GM_INFO.getItemType = options.old ? 1 : 2; cc.fx.GameConfig.GM_INFO.getItemType = options.old ? 1 : 2;
const config = options.old ? cc.fx.GameConfig.PASS_CHECK_OLD : rows; const stage = { time: season, experience: rows.slice(0, level).reduce((sum, row) => sum + row.token, 0) + partial,
const stage = { time: season, experience: config.slice(0, level).reduce((sum, row) => sum + row.token, 0) + partial,
free: Array(level).fill(0), passCheck: Array(level).fill(1), tier, activate: tier > 0 }; free: Array(level).fill(0), passCheck: Array(level).fill(1), tier, activate: tier > 0 };
const input = { 1: options.old ? stage : { time: '0' }, 2: options.old ? { time: '0' } : stage }; const input = { 1: options.old ? stage : { time: '0' }, 2: options.old ? { time: '0' } : stage };
const before = JSON.stringify(input); const before = JSON.stringify(input);
@ -224,7 +222,23 @@ test('battle pass level never exceeds unlocked tiers or the entitlement cap at a
assert.equal(f.panel.currentLv.number, 6); assert.equal(f.panel.currentLv.number, 6);
} }
const empty = animationFixture(); empty.show(0, 0, { old: true, season: '1900000000000' }); const empty = animationFixture(); empty.show(0, 0, { old: true, season: '1900000000000' });
assert.equal(empty.panel.currentLv.number, 0); assert.equal(empty.panel.currentLv.number, 1);
});
test('previous and current panels display the same new rewards beyond tier thirty', () => {
for (const old of [false, true]) {
const f = animationFixture();
f.show(40, 0, { old, tier: 30 });
assert.equal(f.panel.currentLv.number, 40);
assert.equal(f.manager.listData.length, 45);
for (const index of [0, 29, 34, 39]) {
const reward = f.manager.listData[index];
assert.equal(`${reward.ItemID1}:${reward.ItemNum1}`, rows[index].free);
assert.equal(`${reward.ItemID2}:${reward.ItemNum2}`, rows[index].paid);
assert.equal(reward.free, 0);
assert.equal(reward.passCheck, 1);
}
}
}); });
test('battle pass periods and accounts cannot overwrite each other animation records', () => { test('battle pass periods and accounts cannot overwrite each other animation records', () => {

View File

@ -7,7 +7,6 @@ const cp = require('node:child_process');
const path = require('node:path'); const path = require('node:path');
const backend = path.resolve(__dirname, '../../server/laf-cloud/functions'); const backend = path.resolve(__dirname, '../../server/laf-cloud/functions');
const rows = JSON.parse(fs.readFileSync('assets/resources/Json/PASS_CHECK.json', 'utf8')).Sheet1; const rows = JSON.parse(fs.readFileSync('assets/resources/Json/PASS_CHECK.json', 'utf8')).Sheet1;
const oldRows = JSON.parse(fs.readFileSync('assets/resources/Json/PASS_CHECK_OLD.json', 'utf8')).Sheet1;
const plain = value => JSON.parse(JSON.stringify(value)); const plain = value => JSON.parse(JSON.stringify(value));
function load(path, deps = {}, globals = {}) { function load(path, deps = {}, globals = {}) {
const exports = {}; const exports = {};
@ -46,7 +45,7 @@ function fixture(owned = 18) {
const legacy = load(path.join(backend, 'passCheck.ts'), deps).default; const legacy = load(path.join(backend, 'passCheck.ts'), deps).default;
const call = body => upgrade.default({ body: { uid: 'u', token: 't', ...body } }); const call = body => upgrade.default({ body: { uid: 'u', token: 't', ...body } });
const old = body => legacy({ body: { uid: 'u', token: 't', ...body } }); const old = body => legacy({ body: { uid: 'u', token: 't', ...body } });
const cc = { fx: { GameConfig: { PASS_CHECK: rows, PASS_CHECK_OLD: oldRows, GM_INFO: { uid: 'u', coin: 100 } }, const cc = { fx: { GameConfig: { PASS_CHECK: rows, GM_INFO: { uid: 'u', coin: 100 } },
StorageMessage: { setStorage() {}, getStorage() {} } } }; StorageMessage: { setStorage() {}, getStorage() {} } } };
const context = { cc, ...model, Date, console, setTimeout, clearTimeout }; const context = { cc, ...model, Date, console, setTimeout, clearTimeout };
const source = ts.createSourceFile('Utils.ts', fs.readFileSync('assets/Script/module/Pay/Utils.ts', 'utf8'), 99, true); const source = ts.createSourceFile('Utils.ts', fs.readFileSync('assets/Script/module/Pay/Utils.ts', 'utf8'), 99, true);
@ -63,7 +62,7 @@ const at = (level, tier = 30) => model.normalizePass({ time: '100', experience:
test('previous season is archived before client rotates into the current season', async () => { test('previous season is archived before client rotates into the current season', async () => {
const f = fixture(0); const f = fixture(0);
const previous = { time: String(f.start), progress: 2, progressLevel: 6, activate: false, const previous = { time: String(f.start), progress: 4, progressLevel: 6, activate: false,
free: [0, 0, 0, 1, 0, 0, ...Array(24).fill(-1)], passCheck: [...Array(6).fill(1), ...Array(24).fill(-1)] }; free: [0, 0, 0, 1, 0, 0, ...Array(24).fill(-1)], passCheck: [...Array(6).fill(1), ...Array(24).fill(-1)] };
f.tables.users[0].passCheck = JSON.stringify({ 1: previous, f.tables.users[0].passCheck = JSON.stringify({ 1: previous,
2: { time: String(f.end), progress: 1, progressLevel: 1, activate: false, free: [1], passCheck: [1] } }); 2: { time: String(f.end), progress: 1, progressLevel: 1, activate: false, free: [1], passCheck: [1] } });
@ -71,7 +70,7 @@ test('previous season is archived before client rotates into the current season'
assert.equal(pass[1].time, '0'); assert.equal(pass[1].time, '0');
const frozen = f.tables.users[0].passSettlements[f.start].stage; const frozen = f.tables.users[0].passSettlements[f.start].stage;
assert.equal(frozen.progressLevel, 6); assert.equal(frozen.progressLevel, 6);
assert.equal(frozen.progress, 2); assert.equal(frozen.progress, 4);
assert.equal(pass[2].experience, 0); assert.equal(pass[2].experience, 0);
assert.equal(pass[2].unlocked, 1); assert.equal(pass[2].unlocked, 1);
assert.equal(frozen.free[3], 1); assert.equal(frozen.free[3], 1);
@ -84,13 +83,14 @@ test('previous season is archived before client rotates into the current season'
assert.equal(legacy[1].time, '0'); assert.equal(legacy[1].time, '0');
}); });
test('previous partial progress projects with OLD costs and missing OLD cannot use new costs', async () => { test('previous partial progress uses new costs while preserving legacy projection', async () => {
const pass = { 1: model.normalizePass({ time: '100', experience: 10 }, oldRows) }; const pass = { 1: model.normalizePass({ time: '100', experience: 10 }, rows) };
const projected = model.legacyPassInfo(pass, rows, oldRows); const projected = model.legacyPassInfo(pass, rows);
assert.equal(projected[1].progressLevel, 6); assert.equal(projected[1].progressLevel, 6);
assert.equal(projected[1].progress, 1); assert.equal(projected[1].progress, 1);
const f = fixture(); const f = fixture();
delete f.cc.fx.GameConfig.PASS_CHECK_OLD; assert.equal((await read(f)).code, 1);
delete f.cc.fx.GameConfig.PASS_CHECK;
assert.equal((await read(f)).code, 0); assert.equal((await read(f)).code, 0);
}); });