[add] slot1

This commit is contained in:
2024-08-26 16:44:51 +08:00
parent cad4bb3b56
commit 1d0ad3fd99
53 changed files with 3299 additions and 77 deletions

View File

@@ -0,0 +1,13 @@
import { Action } from "../../../../../CatanEngine/CSharp/System/Action";
import { INetResponse } from "./INetResponse";
export interface INetConnector {
readonly OnDataReceived: Action<INetResponse<any>>;
readonly OnDisconnected: Action<void>;
readonly IsConnected: boolean;
// SendAsync<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>): Iterator<any>;
// Send<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>);
// Logout();
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "f97991b5-0da6-4220-ab29-13c8f8f7e405",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,17 @@
export interface INetRequest<TResponse> {
readonly Method: string;
readonly Data: TResponse;
}
// import { INetResponse } from "./INetResponse";
// export interface INetRequest<TRequest, TResponse> {
// readonly Method: string;
// readonly MethodBack: string;
// Data: TRequest;
// Result: INetResponse<TResponse>;
// SendAsync(): Iterator<any>;
// Send();
// }

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "339fcf27-bdb9-4b8f-ae18-dd54c9500145",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,6 @@
export interface INetResponse<TResponse> {
readonly Method: string;
readonly Status: number;
readonly Data: TResponse;
readonly IsValid: boolean;
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "c4cb0cd4-b98c-4f8e-b1e6-ac3b51281b28",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,4 @@
export default class NetConfig {
/**是否顯示RPC接送JSON的LOG */
public static ShowServerLog: boolean = true;
}

View File

@@ -0,0 +1,149 @@
import { CoroutineV2 } from "@/CatanEngine/CoroutineV2/CoroutineV2";
import { Encoding } from "@/CatanEngine/CSharp/System/Text/Encoding";
import { ClientData } from "@/shared/protocols/define/interface";
import { IncomingMessage } from "http";
import { WebSocket } from "ws";
import { Action } from "../../../../CatanEngine/CSharp/System/Action";
import { INetRequest } from "./Core/INetRequest";
import { INetResponse } from "./Core/INetResponse";
let id = 1;
export class NetConnector {
readonly OnDataReceived: Action<INetResponse<any>> = new Action<INetResponse<any>>();
readonly OnDisconnected: Action<void> = new Action<void>();
readonly OnLoadUIMask: Action<boolean> = new Action<boolean>();
public static readonly clients = new Map<WebSocket, ClientData>();
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 = <string>json[0];
let data = json[1];
let req = <INetRequest<any>>{
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<any> = function* (): IterableIterator<any> {
const clientData: ClientData = NetConnector.clients.get(socket);
const response: INetResponse<any> = 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<any> = {
Status: -1,
Method: req.Method,
Data: null,
IsValid: false
};
NetConnector.Send(socket, response);
}
// const module = await import(`@/api/${req.Method.replace(".", "/")}`);
// if (module) {
// let AsyncFunction: () => IterableIterator<any> = function* (): IterableIterator<any> {
// const response: INetResponse<any> = yield* module.default(req);
// NetConnector.Send(socket, response);
// };
// CoroutineV2.Single(AsyncFunction()).Start();
// } else {
// const response: INetResponse<any> = {
// Status: -1,
// Method: req.Method,
// Data: null,
// IsValid: false
// };
// NetConnector.Send(socket, response);
// }
// } catch (e) {
// console.error(e);
// throw new Error(`[RPC] 無法解析Server回應: ${str}`);
// }
}
}
public static OnWebSocketClose() {
console.log('Client disconnected');
}
private static Send(socket: WebSocket, resp: INetResponse<any>) {
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<any> = {
Status: -1,
Method: "",
Data: {},
IsValid: false
};

View File

@@ -0,0 +1,53 @@
// import { INetRequest } from "./Core/INetRequest";
// import { NetConnector } from "./NetConnector";
// export class NetManager {
// static get IsConnected() { return this._connector && this._connector.IsConnected; }
// static get HasInit() { return this._connector != null; }
// private static _connector: NetConnector;
// static Initialize(connector: NetConnector) {
// this._connector = connector;
// }
// static ConnectAsync() {
// this.CheckConnector();
// return this._connector.ConnectAsync();
// }
// /**
// * 斷線
// */
// static Disconnect() {
// this.CheckConnector();
// this._connector.Disconnect();
// }
// /**
// * 傳送資料給Server, 不等待回應
// * @param req
// */
// static Send(req: INetRequest<any, any>) {
// this.CheckConnector();
// if (NativeClass.IsLineProject) {
// NativeClass.Instance.GetSend(req);
// } else {
// this._connector.Send(req);
// }
// }
// /**
// * 傳送資料給Server, 並等待回應
// * @param req
// */
// static SendAsync(req: INetRequest<any, any>, mask: boolean) {
// this.CheckConnector();
// return this._connector.SendAsync(req, mask);
// }
// private static CheckConnector() {
// if (!this._connector) throw new Error("請先呼叫CasinoNetManager.Initialize()初始化connector");
// }
// }

View File

@@ -0,0 +1,21 @@
// import { INetRequest } from "./Core/INetRequest";
// import { NetManager } from "./NetManager";
// export abstract class NetRequest<TResquest, TResponse> implements INetRequest<TResquest, TResponse> {
// abstract get Method(): string;
// get MethodBack(): string {
// return this.Method;
// }
// Data: TResquest;
// Result: import("./Core/INetResponse").INetResponse<TResponse>;
// SendAsync(mask: boolean = false): Iterator<any> {
// return NetManager.SendAsync(this, mask);
// }
// Send() {
// NetManager.Send(this);
// }
// }