feat: integrate login flow, lobby UI and bitmap font resources
This commit is contained in:
@@ -267,6 +267,7 @@ class RecordingScene implements ScenePort {
|
||||
showRoom(): void { this.record('room'); }
|
||||
showReconnect(): void { this.record('reconnect'); }
|
||||
showKicked(data: unknown): void { this.record('kicked', data); }
|
||||
showTips(message:string,time:number):void { this.record('tips',{message,time}); }
|
||||
showServerDenial(outcome: unknown): void { this.record('denied', outcome); }
|
||||
showFatal(error: Error): void { this.record('fatal', error); }
|
||||
}
|
||||
@@ -717,22 +718,27 @@ for (const count of [0, 2.5, 2]) {
|
||||
});
|
||||
}
|
||||
|
||||
test('a nonzero login outcome clears its guard, retains state and permits account retry', async () => {
|
||||
for(const loginRoute of ['agent','room','platform'])test(`${loginRoute} login denial clears its guard, retains state and permits account retry`, async () => {
|
||||
const { runtime, wire, scene, clock } = makeRuntime();
|
||||
await runtime.start();
|
||||
wire.emit({ type: 'open', server: 'ws://agent' });
|
||||
const before = runtime.state;
|
||||
runtime.login(ACCOUNT);
|
||||
const denial = { state: 7, roomcode: 'unavailable', showerror: 1, error: 'Login denied' };
|
||||
wire.emit({ type: 'message', message: { route: 'agent', rpc: 'player_login', data: denial } });
|
||||
const denial = { state: -1, msg: '短信验证码不正确', time: 0 };
|
||||
assert.equal(wire.sent.at(-1)?.route,'agent','outbound login remains agent');
|
||||
wire.emit({ type: 'message', message: { route: loginRoute, rpc: 'player_login', data: denial } });
|
||||
|
||||
assert.equal(runtime.state, before);
|
||||
assert.equal(wire.stopCalls, 0);
|
||||
assert.equal(clock.timers.size, 0);
|
||||
const outcome = scene.calls.find(call => call.name === 'denied')?.value;
|
||||
assert.deepEqual(outcome, { rpc: 'player_login', state: 7, data: denial });
|
||||
assert.deepEqual(outcome, { rpc: 'player_login', state: -1, data: denial });
|
||||
assert.equal((outcome as { data: unknown }).data, denial);
|
||||
assert.deepEqual(scene.calls.filter(call => call.name === 'fatal'), []);
|
||||
const sentBeforeReconnect=wire.sent.length;
|
||||
wire.emit({type:'reconnecting',server:'ws://agent'});
|
||||
wire.emit({type:'open',server:'ws://agent'});
|
||||
assert.equal(wire.sent.length,sentBeforeReconnect,'a denied first login must not be replayed');
|
||||
runtime.login({ ...ACCOUNT, openid: 'retry-account' });
|
||||
assert.equal((wire.sent[wire.sent.length - 1]!.data as Record<string, unknown>).openid, 'retry-account');
|
||||
wire.emit({ type: 'message', message: {
|
||||
@@ -1570,6 +1576,29 @@ test('slow and reconnecting show reconnect without clearing or replacing room st
|
||||
);
|
||||
});
|
||||
|
||||
test('kick_offline bypasses pending login and stops late navigation', async () => {
|
||||
const {runtime,wire,scene}=makeRuntime();
|
||||
await runtime.start();wire.emit({type:'open',server:'ws://agent'});runtime.login(ACCOUNT);
|
||||
const data={fromOther:true,gameid:'another-game'};
|
||||
wire.emit({type:'message',message:{route:'agent',rpc:'kick_offline',data}});
|
||||
assert.equal(scene.calls.at(-1)?.name,'kicked');assert.equal(scene.calls.at(-1)?.value,data);
|
||||
assert.equal(wire.stopCalls,1);
|
||||
const count=scene.calls.length;wire.emit({type:'open',server:'ws://agent'});
|
||||
assert.equal(scene.calls.length,count);
|
||||
});
|
||||
|
||||
test('show_message preserves text and legacy numeric timeout without navigating', async () => {
|
||||
const {runtime,wire,scene}=makeRuntime();
|
||||
await runtime.start();wire.emit({type:'open',server:'ws://agent'});
|
||||
const before=runtime.state;
|
||||
for(const time of ['3000','0','-1']){
|
||||
wire.emit({type:'message',message:{route:'agent',rpc:'show_message',data:{msg:'服务器提示#第二行',time}}});
|
||||
assert.deepEqual(scene.calls.at(-1),{name:'tips',value:{message:'服务器提示#第二行',time:Number(time)}});
|
||||
assert.equal(runtime.state,before);
|
||||
}
|
||||
runtime.stop();
|
||||
});
|
||||
|
||||
test('kick closes the game before showing kicked and stopping the wire', async () => {
|
||||
const log: string[] = [];
|
||||
const restored: unknown[] = [];
|
||||
|
||||
Reference in New Issue
Block a user