import { IncomingMessage } from "http"; import { WebSocket } from "ws"; import { CoroutineV2 } from "../../../../CatanEngine/CoroutineV2/CoroutineV2"; import { Action } from "../../../../CatanEngine/CSharp/System/Action"; import { Encoding } from "../../../../CatanEngine/CSharp/System/Text/Encoding"; import { ClientData } from "../../../../shared/protocols/define/interface"; import { INetRequest } from "./Core/INetRequest"; import { INetResponse } from "./Core/INetResponse"; let id = 1; export class NetConnector { readonly OnDataReceived: Action> = new Action>(); readonly OnDisconnected: Action = new Action(); readonly OnLoadUIMask: Action = new Action(); public static readonly clients = new Map(); public static OnWebSocketConnection(socket: WebSocket, request: IncomingMessage) { const ip = request.socket.remoteAddress.replace("::ffff:", "") || 'Unknown IP'; console.log(`Client connected from IP: ${ip}`); NetConnector.clients.set(socket, { socket, id: id, name: "", money: 0 }); id++; socket.on('message', (message: Buffer) => NetConnector.OnWebSocketMessage(socket, message)); socket.on('close', NetConnector.OnWebSocketClose); } public static async OnWebSocketMessage(socket: WebSocket, message: Buffer) { // 将 Buffer 转换为 ArrayBuffer const buffer = message.buffer.slice(message.byteOffset, message.byteOffset + message.byteLength); let startIndex = 0, byteLength = buffer.byteLength; while (startIndex + 4 < byteLength) { const view: DataView = new DataView(buffer, 0, 3); const strlen: number = view.getUint16(0, true) + (view.getUint8(2) << 16); const decoder: TextDecoder = new TextDecoder("utf-8"); const str: string = decoder.decode(new Uint8Array(buffer, startIndex + 4, strlen)); startIndex += strlen + 4; // try { let json = JSON.parse(str); let method = json[0]; let data = json[1]; let req = >{ Method: method, Data: data, }; if (data) { console.log(`[RPC] 收到client呼叫: ${req.Method}(${JSON.stringify(req.Data)})`); } else { console.log(`[RPC] 收到client呼叫: ${req.Method}()`); } // 动态导入处理函数 try { // 动态导入文件 const module = await import(`../../../../api/${req.Method.replace(".", "/")}`); // 调用导入模块中的处理函数 if (module.default) { let AsyncFunction: () => IterableIterator = function* (): IterableIterator { const clientData: ClientData = NetConnector.clients.get(socket); const response: INetResponse = yield* module.default(clientData, req); if (response) { NetConnector.Send(socket, response); } }; CoroutineV2.Single(AsyncFunction()).Start(); } else { throw new Error(`Module for ${req.Method} does not export a default function.`); } } catch (error) { console.error(`Error handling request ${req.Method}: ${error.message}`); const response: INetResponse = { Status: -1, Method: req.Method, Data: null, IsValid: false }; NetConnector.Send(socket, response); } } } public static OnWebSocketClose() { console.log('Client disconnected'); } private static Send(socket: WebSocket, resp: INetResponse) { let json: any = [resp.Method, [resp.Status]]; //@ts-ignore if (resp.Data != null && resp.Data != undefined && resp.Data != NaN) { json[1].push(resp.Data); } //@ts-ignore if (resp.Data != null && resp.Data != undefined && resp.Data != NaN) { console.log(`[RPC] 回傳client呼叫:(${resp.Status}): ${resp.Method}(${JSON.stringify(resp.Data)})`); } else { console.log(`[RPC] 回傳client呼叫:(${resp.Status}): ${resp.Method}()`); } let str = JSON.stringify(json); if (str.length > 65535) { throw new Error("要傳的資料太大囉"); } let strary = Encoding.UTF8.GetBytes(str); let buffer = new Uint8Array(4 + strary.byteLength); let u16ary = new Uint16Array(buffer.buffer, 0, 3); u16ary[0] = strary.byteLength; buffer[3] = 0x01; buffer.set(strary, 4); socket.send(buffer); } } const ErrorResponse: INetResponse = { Status: -1, Method: "", Data: {}, IsValid: false };