import { _decorator, Component, director } from 'cc'; import { PlatformSession } from '../framework/platform/session.ts'; import { NetClient, type NetClientEvents } from '../framework/net/net-client.ts'; import { resolveBootstrap } from '../framework/config/bootstrap.ts'; import { HttpConfigFetcher } from '../framework/config/remote-config-fetcher.ts'; import { RoomRPCBus } from '../framework/platform/room-rpc-bus.ts'; import { EventBus } from '../framework/core/events.ts'; import type { Transport } from '../framework/net/transport.ts'; const { ccclass } = _decorator; /** 旧登录编排兼容入口;启动配置由 profiles.ts 统一提供。 */ class WSTransport implements Transport { private onOpenCb?: () => void; private onMessageCb?: (f: string) => void; private onCloseCb?: () => void; private ws: WebSocket | null = null; connect(url: string): void { console.log('[LoginFlow] WS connect to ' + url); try { this.ws = new WebSocket(url); this.ws.onopen = () => { console.log('[LoginFlow] WS open'); this.onOpenCb?.(); }; this.ws.onmessage = (ev) => { this.onMessageCb?.(typeof ev.data === 'string' ? ev.data : ''); }; this.ws.onerror = (ev) => { console.warn('[LoginFlow] WS error: ' + (ev as any).message); this.onCloseCb?.(); }; this.ws.onclose = () => { console.log('[LoginFlow] WS close'); this.onCloseCb?.(); }; } catch (e) { console.error('[LoginFlow] WebSocket construct failed: ' + (e as Error).message); this.onCloseCb?.(); } } send(frame: string): void { this.ws?.send(frame); } close(): void { this.ws?.close(); this.onCloseCb?.(); } onOpen(cb: () => void): void { this.onOpenCb = cb; } onMessage(cb: (f: string) => void): void { this.onMessageCb = cb; } onClose(cb: () => void): void { this.onCloseCb = cb; } } @ccclass('LoginFlow') export class LoginFlow extends Component { start(): void { const bus = new EventBus(); const session = new PlatformSession(bus); (async () => { try { const result = await resolveBootstrap({ win: window as any, search: window.location.search, fetcher: new HttpConfigFetcher(), isNative: false, }); session.app.setIdentity(result.identity); session.app.setServers(result.servers); console.log('[LoginFlow] bootstrap OK, servers=' + result.servers[0] + ' profile=' + result.profile.name); } catch (e) { console.warn('[LoginFlow] bootstrap failed: ' + (e as Error).message); return; } // 构造 NetClient + 真实 WS transport console.log('[LoginFlow] constructing NetClient with servers=' + session.app.state.value.servers); const net = new NetClient({ servers: session.app.state.value.servers, transportFactory: () => new WSTransport(), bus, }); net.setIdentity({ agentid: 'A', channelid: 'C', gameid: 'G', marketid: 4, version: 10000, openid: 'mock_openid', nickname: '测试玩家', avatar: '', sex: 0, } as any); let loginHandled = false; bus.on('login', (data: any) => { console.log('[LoginFlow] bus.on(login) fired, state=' + data?.state); if (loginHandled) return; loginHandled = true; console.log('[LoginFlow] login success, phase=' + session.app.state.value.phase); if (session.app.state.value.phase === 'loggedIn') { new RoomRPCBus(bus, session).start(); console.log('[LoginFlow] RoomRPCBus started'); this.scheduleOnce(() => director.loadScene('MainMenu'), 0.5); } else { console.warn('[LoginFlow] phase is not loggedIn: ' + session.app.state.value.phase); } }); bus.on('open', () => console.log('[LoginFlow] bus.on(open) fired')); bus.on('reconnecting', (s) => console.log('[LoginFlow] bus.on(reconnecting) to ' + s)); try { net.start(); console.log('[LoginFlow] net.start() called'); } catch (e) { console.error('[LoginFlow] net.start() failed: ' + (e as Error).message); } })(); } }