Files
youle_cocos/cocoscreator_projects/YouleNexus/assets/scripts/LoginFlow.ts
T

116 lines
4.1 KiB
TypeScript

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<NetClientEvents>();
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);
}
})();
}
}