feat: integrate login flow, lobby UI and bitmap font resources

This commit is contained in:
2026-09-06 13:46:57 +08:00
parent e1bcfd91ec
commit 842c68ef55
141 changed files with 11279 additions and 1717 deletions
@@ -1,4 +1,24 @@
import type { Transport } from './transport.ts';
import { STARTUP_CONFIG } from '../config/profiles.ts';
function logConnection(state:string,ws:WebSocket,detail:Record<string,unknown>={}):void{
if(STARTUP_CONFIG.debugIO)console.log(`[WebSocket] ${state}`,{state,url:ws.url,readyState:ws.readyState,time:new Date().toISOString(),...detail});
}
/** 日志解析不改变传输内容;非法 JSON 保留原始帧供协议层报错。 */
function logFrame(tag: string, url: string, frame: unknown): void {
if (!STARTUP_CONFIG.debugIO) return;
let data = frame;
if (typeof frame === 'string') {
try { data = JSON.parse(frame); }
catch { data = { parseError: 'Invalid JSON', raw: frame }; }
}
const packet = data !== null && typeof data === 'object' ? data as Record<string, unknown> : null;
const route = packet && typeof packet.route === 'string' ? packet.route : '';
const rpc = packet && typeof packet.rpc === 'string' ? packet.rpc : '';
const com = packet && typeof packet.com === 'string' ? packet.com : '';
console.log(`${tag}${route || rpc ? ` ${route}/${rpc}` : com ? ` ${com}` : ''}`, url, data);
}
/** 生产用 Transport:包装运行时全局 WebSocket(Cocos 原生/浏览器)。docs/protocol/01 §2。 */
export class CocosWebSocketTransport implements Transport {
@@ -10,13 +30,21 @@ export class CocosWebSocketTransport implements Transport {
connect(url: string): void {
const ws = new WebSocket(url); // url 形如 ws://ip:port
this.ws = ws;
ws.onopen = () => this.openCb?.();
ws.onmessage = (ev: MessageEvent) => this.msgCb?.(typeof ev.data === 'string' ? ev.data : String(ev.data));
ws.onclose = () => this.closeCb?.();
ws.onerror = () => { try { ws.close(); } catch { /* ignore */ } };
logConnection('连接中',ws);
ws.onopen = () => {logConnection('已连接',ws);this.openCb?.();};
ws.onmessage = (ev: MessageEvent) => {
logFrame('[收包 S→C]', url, ev.data);
this.msgCb?.(typeof ev.data === 'string' ? ev.data : String(ev.data));
};
ws.onclose = (event:CloseEvent) => {logConnection('已断开',ws,{code:event.code,reason:event.reason,wasClean:event.wasClean});this.closeCb?.();};
ws.onerror = (event:Event) => {logConnection('连接错误',ws,{eventType:event.type});try { ws.close(); } catch { /* ignore */ } };
}
send(frame: string): void { this.ws?.send(frame); }
close(): void { try { this.ws?.close(); } catch { /* ignore */ } }
send(frame: string): void {
if (!this.ws) return;
this.ws.send(frame);
logFrame('[发包 C→S]', this.ws.url, frame);
}
close(): void { if(this.ws)logConnection('客户端请求关闭',this.ws);try { this.ws?.close(); } catch { /* ignore */ } }
onOpen(cb: () => void): void { this.openCb = cb; }
onMessage(cb: (frame: string) => void): void { this.msgCb = cb; }
onClose(cb: () => void): void { this.closeCb = cb; }
@@ -9,6 +9,7 @@ import { decodeFrame } from './envelope-codec.ts';
import { HeartbeatWatchdog, realClock, type Clock } from './heartbeat.ts';
import { ReconnectPolicy } from './reconnect.ts';
import type { Transport } from './transport.ts';
import { STARTUP_CONFIG } from '../config/profiles.ts';
export type WireEvent =
| { readonly type: 'open'; readonly server: string }
@@ -398,6 +399,11 @@ export class WireClient {
}
private emit(event: WireEvent): void {
if(STARTUP_CONFIG.debugIO&&event.type!=='message'){
const states={open:'已连接',close:'已断开',slow:'收包超时',reconnecting:'正在重连'};
console.log(`[连接状态] ${states[event.type]}`,{event:event.type,server:this.policy.current(),connected:this.open,stopped:this.stopped,
time:new Date().toISOString(),...(event.type==='slow'?{timeoutMs:RECV_TIMEOUT_MS}:{}),...(event.type==='reconnecting'?{retryAfterMs:RECONNECT_INTERVAL_MS}:{})});
}
for (const listener of [...this.listeners]) {
try {
listener(event);