feat: integrate erqiwang rooms and use spec-compliant Web compilation

This commit is contained in:
2026-09-07 22:36:24 +08:00
parent 30a1b4114c
commit a7ec8aa6a7
49 changed files with 11603 additions and 1183 deletions
@@ -1,3 +1,4 @@
import {createErqiwangGame} from '../../YouleNexus/assets/games/erqiwang/erqiwang-game.ts';
import { STARTUP_CONFIG as EDITABLE_STARTUP_CONFIG } from '../../YouleNexus/assets/framework/config/profiles.ts';
// 固定测试来源,允许开发者独立切换项目的 local/remote 开关。
const STARTUP_CONFIG = Object.freeze({...EDITABLE_STARTUP_CONFIG, configSource:'remote' as const});
@@ -736,7 +737,7 @@ test('a denied join retains the lobby root, reports the raw outcome and permits
});
test('runtime resolves seats only from the actual game-owned server roomtype at room entry', async () => {
const roomtypes: Array<readonly unknown[]> = [];
const roomtypes: Array<string | readonly unknown[]> = [];
const attached: GameHost[] = [];
const setup = makeRuntime(runtimeConfig(), makeGameEntry({
resolveSeatCount(roomtype) {
@@ -795,7 +796,7 @@ for(const loginRoute of ['agent','room','platform'])test(`${loginRoute} login de
const before = runtime.state;
runtime.login(ACCOUNT);
const denial = { state: -1, msg: '短信验证码不正确', time: 0 };
assert.equal(wire.sent.at(-1)?.route,'agent','outbound login remains agent');
assert.equal(wire.sent[wire.sent.length - 1]?.route,'agent','outbound login remains agent');
wire.emit({ type: 'message', message: { route: loginRoute, rpc: 'player_login', data: denial } });
assert.equal(runtime.state, before);
@@ -1651,7 +1652,7 @@ test('kick_offline bypasses pending login and stops late navigation', async () =
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(scene.calls[scene.calls.length - 1]?.name,'kicked');assert.equal(scene.calls[scene.calls.length - 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);
@@ -1663,7 +1664,7 @@ test('show_message preserves text and legacy numeric timeout without navigating'
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.deepEqual(scene.calls[scene.calls.length - 1],{name:'tips',value:{message:'服务器提示#第二行',time:Number(time)}});
assert.equal(runtime.state,before);
}
runtime.stop();
@@ -2394,3 +2395,18 @@ test('create wire outcome enters only on success and a repeated success leaves t
if(runtime.state.room.kind==='inside')assert.equal(runtime.state.room.seatPlayerIds.length,10);
runtime.stop();assert.equal(disposals,1);
});
test('erqiwang creation preserves wire string, three seats and room host exit',async()=>{
const config=runtimeConfig(),game=createErqiwangGame(config.identity.gameid);
const {runtime,wire,scene}=makeRuntime(config,game.entry);await runtime.start();
wire.emit({type:'open',server:'ws://agent'});runtime.login(ACCOUNT);
wire.emit({type:'message',message:{route:'agent',rpc:'player_login',data:fixture('player-login-success.json')}});
const roomtype='11011000000';runtime.createRoom({roomtype,location:null,ip:'127.0.0.1'});
assert.equal((wire.sent[wire.sent.length - 1]?.data as {roomtype:unknown}).roomtype,roomtype);
wire.emit({type:'message',message:{route:'agent',rpc:'create_room',data:{state:0,roomcode:'123456',seat:0,roomtype,needprepare:1}}});
assert.equal(runtime.state.room.kind,'inside');
if(runtime.state.room.kind==='inside'){assert.equal(runtime.state.room.roomtype,roomtype);assert.equal(runtime.state.room.seatPlayerIds.length,3);}
assert.equal(scene.calls.filter(x=>x.name==='room').length,1);
let rendered=false;game.mount({render(snapshot,actions){assert.equal(snapshot.room.roomtype,roomtype);rendered=true;actions.exit();},close(){}});
assert.ok(rendered);assert.equal(wire.sent[wire.sent.length - 1]?.rpc,'self_exit_room');runtime.stop();
});