feat: wire lobby task and VIP prefab flows and sync UI assets

This commit is contained in:
2026-09-06 18:46:37 +08:00
parent 842c68ef55
commit 9c4510697c
184 changed files with 8348 additions and 19133 deletions
@@ -59,6 +59,50 @@ function makeCommands(store: PlatformStore): {
};
}
test('VIP query and both entry forms use the exact agent protocol',()=>{
const store=makeStore('outside'),{commands,sent}=makeCommands(store);
commands.getVipRooms(['123456']);commands.joinVipRoom('123456',null);commands.joinVipRoom(900001,{city:'测试'});
assert.deepEqual(sent[0],{app:'youle',route:'agent',rpc:'getInfoByShortCode',data:{agentid:'agent-from-config',gameid:'game-from-config',shortcodeList:['123456']}});
assert.deepEqual(sent[1],{app:'youle',route:'agent',rpc:'self_join_room',data:{agentid:'agent-from-config',playerid:430511,gameid:'game-from-config',roomcode:'123456',joinmode:0,location:null,ip:store.getState().players.entities[430511].ip}});
assert.equal((sent[2].data as {roomcode:number}).roomcode,900001);
assert.throws(()=>makeCommands(new PlatformStore()).commands.getVipRooms([]),/logged-in/);
});
test('task requests preserve legacy identity fields and reject unclaimable entries',()=>{
const store=makeStore('outside');const {commands,sent}=makeCommands(store);
commands.getPlayerTasks();
store.applyTaskList({tasks:[{taskid:7,title:'任务',award:1,finish:1,total:1,state:1}]});
commands.claimTask(7);
assert.deepEqual(sent,[
{app:'youle',route:'agent',rpc:'get_player_task',data:{agentid:'agent-from-config',playerid:430511,gameid:'game-from-config'}},
{app:'youle',route:'agent',rpc:'get_task_award',data:{agentid:'agent-from-config',playerid:430511,taskid:7}},
]);
store.applyTaskAward({taskid:7,taskstate:0});
assert.equal(store.getState().tasks?.[0].state,2);
assert.equal(store.getState().players.entities[430511].taskstate,0);
assert.throws(()=>commands.claimTask(7),/claimable/);
const before=store.getState();
assert.throws(()=>store.applyTaskList({tasks:[{taskid:7}]}));
assert.equal(store.getState(),before);
assert.throws(()=>makeCommands(new PlatformStore()).commands.getPlayerTasks(),/logged-in/);
});
test('task numeric strings normalize at ingestion and invalid values never commit',()=>{
const store=makeStore('outside');
const task={taskid:'7',title:'任务',award:'3',finish:'2',total:'5',state:'0'};
store.applyTaskList({tasks:[task]});
assert.deepEqual(store.getState().tasks,[{...task,award:3,finish:2,total:5,state:0}]);
assert.equal(task.award,'3');
const before=store.getState();
for(const field of ['award','finish','total','state']){
for(const value of ['', ' ', 'abc', 'Infinity', null, true, [], {}, undefined]){
assert.throws(()=>store.applyTaskList({tasks:[{...task,[field]:value}]}),new RegExp(field));
assert.equal(store.getState(),before);
}
}
assert.throws(()=>store.applyTaskList({tasks:[{...task,state:'1.5'}]}),/state/);
});
test('prepare and exitRoom use the first-slice builders with authoritative config and room state', () => {
const { commands, sent } = makeCommands(makeStore('inside', 0));