feat: wire lobby task and VIP prefab flows and sync UI assets
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
/** Isolated preview integration: real Runtime/Router/Store/UI, recording wire port. */
|
||||
export async function verifyTaskNetworkPreview(){
|
||||
const e=await System.import('cc'),modules=Array.from(System.entries()).map(([,m])=>m);
|
||||
const exported=name=>{const m=modules.find(m=>m[name]);if(!m)throw Error(`Missing ${name}`);return m[name];};
|
||||
const source=e.director.getScene().getChildByName('PlatformServices').getComponent('PlatformStartup');
|
||||
const config=source.config,assets=source.getComponent('LobbyAssets');
|
||||
source.unsubscribe?.();source.runtime?.stop();source.panel?.dispose();source.panel=null;
|
||||
await new Promise((resolve,reject)=>e.director.loadScene('PlatformLobby',err=>err?reject(err):resolve()));
|
||||
const sent=[],tips=[],checks=[];let receive,panel;
|
||||
const assert=(ok,message)=>{if(!ok)throw Error(message);checks.push(message);};
|
||||
const runtime=new (exported('PlatformRuntime'))({
|
||||
gameEntry:exported('createLoginStageGameEntry')(config.identity.gameid,()=>{}),
|
||||
resolveRuntimeConfig:async()=>config,
|
||||
createWireClient:()=>({subscribe:cb=>{receive=cb;return ()=>{};},start:()=>{},stop:()=>{},send:packet=>sent.push(packet),switchServer:()=>{},reconnectCurrent:()=>{}}),
|
||||
scene:{showLoading:()=>{},showLogin:()=>{},showLobby:()=>{},showRoom:()=>{},showReconnect:()=>{},showKicked:()=>{},showServerDenial:()=>{},showFatal:err=>{throw err;},
|
||||
showTips:(msg,time,kind)=>{if(kind==='show_message')panel?.cancelTaskRequest();tips.push(msg);}},
|
||||
loadResources:async()=>{},waitForMinimumDisplay:async()=>{},getLoginDeviceSnapshot:()=>{throw Error('Test uses inbound login fixture');},
|
||||
});
|
||||
await runtime.start();receive({type:'open',server:config.servers[0]});
|
||||
const packet=(rpc,data)=>receive({type:'message',message:{route:'agent',rpc,data}});
|
||||
packet('player_login',{state:0,playerid:7,nickname:'任务接线验证',avatar:'',sex:0,bean:0,roomcard:3,taskstate:1,score:0,sign:null,ip:'127.0.0.1'});
|
||||
const canvas=e.director.getScene().getChildByName('Canvas'),popup=new e.Node('TaskNetworkTestPopup');popup.parent=canvas;popup.layer=canvas.layer;popup.addComponent(e.UITransform).setContentSize(1600,720);
|
||||
const remote=exported('createRemoteConfig')({gameNoticeShow:-1,agentmode:1,hideTaskBtn:0},config.identity);
|
||||
panel=new (exported('LobbyPanel'))(canvas,popup,assets,config,exported('resolveLobbyPolicy')(remote),runtime.state,msg=>tips.push(msg),()=>{},()=>null,()=>{},
|
||||
exported('resolveLobbyMenuConfig')(remote),{versionState:0,launchMode:0},action=>{if(action==='tasks')runtime.getPlayerTasks();else tips.push(action);},id=>runtime.claimTask(id));
|
||||
popup.setSiblingIndex(canvas.children.length-1);
|
||||
const off=runtime.subscribeState(state=>panel.render(state),err=>{throw err;});
|
||||
const clickTask=()=>panel.menuNodes.get(17).emit(e.Button.EventType.CLICK);
|
||||
clickTask();clickTask();
|
||||
assert(sent.length===1&&sent[0].rpc==='get_player_task','task button sends one request while pending');
|
||||
assert(JSON.stringify(sent[0].data)===JSON.stringify({agentid:config.identity.agentid,playerid:7,gameid:config.identity.gameid}),'request identity comes from config and authenticated store');
|
||||
packet('update_roomcard',{roomcard:4,text:'余额更新'});
|
||||
assert(panel.taskPending==='list','balance notification preserves pending list');
|
||||
packet('get_player_task',{tasks:[{taskid:9,title:'今日登录奖励',award:2,finish:1,total:1,state:1}]});
|
||||
assert(panel.modalKind==='tasks','list response opens authored task prefab');
|
||||
const view=panel.modal.getComponent('TaskListView'),claim=view.scrollView.content.children[0].getComponent('TaskItemView').claimButton;
|
||||
claim.node.emit(e.Button.EventType.CLICK);claim.node.emit(e.Button.EventType.CLICK);
|
||||
assert(sent.length===2&&sent[1].rpc==='get_task_award','claim sends one award request');
|
||||
assert(JSON.stringify(sent[1].data)===JSON.stringify({agentid:config.identity.agentid,playerid:7,taskid:9}),'award packet preserves legacy fields');
|
||||
packet('update_roomcard',{roomcard:6,text:'奖励到账'});
|
||||
assert(panel.taskPending==='award','balance notification preserves duplicate claim guard');
|
||||
packet('get_task_award',{taskid:9,taskstate:0});
|
||||
assert(!panel.taskTip.active,'award response clears red dot');
|
||||
assert(view.scrollView.content.children[0].getComponent('TaskItemView').claimedMark.active,'award response renders claimed mark');
|
||||
panel.modal.getChildByPath('group-10/Spirit115').emit(e.Button.EventType.CLICK);
|
||||
assert(panel.modal===null,'close button closes task list');
|
||||
clickTask();packet('show_message',{msg:'任务暂不可用',time:0});assert(panel.taskPending===null,'server message releases request guard');
|
||||
clickTask();receive({type:'slow'});assert(panel.taskPending===null,'reconnect cancels pending request');
|
||||
const count=sent.length;clickTask();assert(sent.length===count,'reconnect blocks task sends');
|
||||
await new Promise(resolve=>e.director.once(e.Director.EVENT_AFTER_DRAW,resolve));
|
||||
assert(!document.body.innerText.includes('TypeError:'),'no deferred UI lifecycle errors');
|
||||
off();panel.dispose();runtime.stop();popup.destroy();
|
||||
return {checks,sent:sent.map(({rpc,data})=>({rpc,fields:Object.keys(data)}))};
|
||||
}
|
||||
Reference in New Issue
Block a user