重构NetManager支持MessagePair,新增TSRPCWsClient。
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import { find } from "cc";
|
||||
import { BaseState } from "../../Framework/FSM/BaseState";
|
||||
import { NetConfig, NetProtocolType } from "../../Framework/Net/NetConfig";
|
||||
import { NetEvent } from "../../Framework/Net/NetEvent";
|
||||
import { NetManager } from "../../Framework/Net/NetManager";
|
||||
import { UIMgr } from "../../Framework/UI/UIMgr";
|
||||
import { serviceProto } from "../../Shared/protocols/serviceProto";
|
||||
|
||||
/**
|
||||
* 应用启动状态
|
||||
@@ -15,15 +18,15 @@ export class AppStatusBoot extends BaseState {
|
||||
constructor(fsm: any) {
|
||||
super(fsm, "Boot");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 进入启动状态
|
||||
*/
|
||||
async onEnter(params?: any): Promise<void> {
|
||||
super.onEnter(params);
|
||||
|
||||
|
||||
console.log("[AppStatusBoot] 开始初始化应用...");
|
||||
|
||||
|
||||
try {
|
||||
// 初始化UI
|
||||
console.log("[AppStatusBoot] 初始化UI管理器...");
|
||||
@@ -31,32 +34,71 @@ export class AppStatusBoot extends BaseState {
|
||||
|
||||
// 1. 初始化并连接网络
|
||||
await this.initAndConnectNet();
|
||||
|
||||
|
||||
// 2. 初始化完成,切换到登录状态
|
||||
console.log("[AppStatusBoot] 启动完成,切换到登录状态");
|
||||
this._fsm.changeState("Login");
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error("[AppStatusBoot] 初始化失败:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化并连接网络
|
||||
*/
|
||||
private async initAndConnectNet(): Promise<void> {
|
||||
console.log("[AppStatusBoot] 初始化网络管理器...");
|
||||
|
||||
// TODO: 从配置文件读取服务器地址
|
||||
// import { serviceProto } from '../../Shared/protocols/serviceProto';
|
||||
// const netManager = NetManager.getInstance();
|
||||
// netManager.setServiceProto(serviceProto);
|
||||
// netManager.init({ serverUrl: 'http://localhost:3000' });
|
||||
// await netManager.connect();
|
||||
|
||||
console.log("[AppStatusBoot] 网络连接完成(待配置)");
|
||||
|
||||
// 1. 获取网络管理器实例
|
||||
const netManager = NetManager.getInstance();
|
||||
|
||||
// 2. 设置服务协议 (必须在 init 之前调用)
|
||||
netManager.setServiceProto(serviceProto);
|
||||
|
||||
// 3. 监听网络事件
|
||||
netManager.on(NetEvent.Connected, () => {
|
||||
console.log('✅ 网络已连接');
|
||||
this.onConnected();
|
||||
});
|
||||
|
||||
netManager.on(NetEvent.Disconnected, () => {
|
||||
console.log('❌ 网络已断开');
|
||||
});
|
||||
|
||||
netManager.on(NetEvent.Reconnecting, (count: number) => {
|
||||
console.log(`🔄 正在重连... (${count})`);
|
||||
});
|
||||
|
||||
netManager.on(NetEvent.Error, (error: any) => {
|
||||
console.error('⚠️ 网络错误:', error);
|
||||
});
|
||||
|
||||
const config: NetConfig = {
|
||||
serverUrl: 'http://localhost:3000', // TODO: 替换为实际服务器地址
|
||||
protocolType: NetProtocolType.WebSocket,
|
||||
timeout: 30000,
|
||||
autoReconnect: true,
|
||||
reconnectInterval: 3000,
|
||||
maxReconnectTimes: 5
|
||||
};
|
||||
|
||||
// 5. 初始化
|
||||
netManager.init(config);
|
||||
// 6. 连接服务器 (HttpClient 创建即可用)
|
||||
const success = await netManager.connect();
|
||||
|
||||
if (success) {
|
||||
console.log('[AppStatusBoot]✅ 网络初始化成功');
|
||||
} else {
|
||||
console.error('[AppStatusBoot]❌ 网络初始化失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private onConnected() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出启动状态
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { find } from "cc";
|
||||
import { BaseState } from "../../Framework/FSM/BaseState";
|
||||
import { UIMgr } from "../../Framework/UI/UIMgr";
|
||||
import { PlayerInfo } from "../../Shared/protocols/MsgResLogin";
|
||||
import { UIGame } from "../Game/UIGame";
|
||||
import { World } from "../Game/World";
|
||||
import { PlayerInfo } from "../../Shared/protocols/PtlLogin";
|
||||
|
||||
/**
|
||||
* 应用游戏状态
|
||||
@@ -16,19 +17,19 @@ export class AppStatusGame extends BaseState {
|
||||
private _player: PlayerInfo = null;
|
||||
private _isNewPlayer: boolean = false;
|
||||
private _uiGame: UIGame = null;
|
||||
|
||||
|
||||
constructor(fsm: any) {
|
||||
super(fsm, "Game");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 进入游戏状态
|
||||
*/
|
||||
async onEnter(params?: any): Promise<void> {
|
||||
super.onEnter(params);
|
||||
|
||||
|
||||
console.log("[AppStatusGame] 进入游戏世界");
|
||||
|
||||
|
||||
// 保存玩家信息
|
||||
if (params) {
|
||||
this._player = params.player || null;
|
||||
@@ -36,82 +37,82 @@ export class AppStatusGame extends BaseState {
|
||||
console.log(`[AppStatusGame] 玩家信息:`, this._player);
|
||||
console.log(`[AppStatusGame] 是否新玩家: ${this._isNewPlayer}`);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// 1. 加载游戏场景
|
||||
await this.loadGameScene();
|
||||
|
||||
|
||||
// 2. 初始化游戏
|
||||
await this.initGame();
|
||||
|
||||
|
||||
// 3. 开始监听服务器广播
|
||||
this.listenServerMessages();
|
||||
|
||||
|
||||
// 4. 开始游戏
|
||||
this.startGame();
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error("[AppStatusGame] 进入游戏失败:", error);
|
||||
// 返回登录
|
||||
this._fsm.changeState("Login");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载游戏场景
|
||||
*/
|
||||
private async loadGameScene(): Promise<void> {
|
||||
console.log("[AppStatusGame] 加载游戏场景...");
|
||||
|
||||
|
||||
// 加载游戏UI
|
||||
this._uiGame = await UIMgr.getInstance().load(UIGame);
|
||||
|
||||
|
||||
console.log("[AppStatusGame] 游戏场景加载完成");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化游戏
|
||||
*/
|
||||
private async initGame(): Promise<void> {
|
||||
console.log("[AppStatusGame] 初始化游戏...");
|
||||
|
||||
|
||||
if (!this._uiGame) {
|
||||
throw new Error("UIGame 未加载");
|
||||
}
|
||||
|
||||
// 获取世界根节点
|
||||
const worldRoot = this._uiGame.getWorldRoot();
|
||||
const worldRoot = find("Game")
|
||||
if (!worldRoot) {
|
||||
throw new Error("世界根节点未找到");
|
||||
}
|
||||
|
||||
// 初始化世界,传入本地玩家信息
|
||||
await World.getInstance().init(worldRoot, this._player);
|
||||
|
||||
|
||||
console.log("[AppStatusGame] 游戏初始化完成");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 监听服务器广播消息
|
||||
*/
|
||||
private listenServerMessages(): void {
|
||||
console.log("[AppStatusGame] 开始监听服务器广播...");
|
||||
|
||||
|
||||
// 网络消息监听已在 World 中注册
|
||||
// World 会自动处理 MsgPlayerJoin 和 MsgPlayerMove
|
||||
|
||||
|
||||
console.log("[AppStatusGame] 服务器广播监听已设置");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 开始游戏
|
||||
*/
|
||||
private startGame(): void {
|
||||
console.log("[AppStatusGame] 游戏开始!");
|
||||
|
||||
|
||||
// 游戏已启动,玩家可以通过 WASD 控制角色移动
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新游戏状态(每帧调用)
|
||||
*/
|
||||
@@ -122,7 +123,7 @@ export class AppStatusGame extends BaseState {
|
||||
// - 更新敌人AI
|
||||
// - 同步网络状态
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 暂停游戏
|
||||
*/
|
||||
@@ -132,7 +133,7 @@ export class AppStatusGame extends BaseState {
|
||||
// - 停止游戏更新
|
||||
// - 显示暂停菜单
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 恢复游戏
|
||||
*/
|
||||
@@ -142,60 +143,60 @@ export class AppStatusGame extends BaseState {
|
||||
// - 继续游戏更新
|
||||
// - 隐藏暂停菜单
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 玩家死亡
|
||||
*/
|
||||
onPlayerDeath(): void {
|
||||
console.log("[AppStatusGame] 玩家死亡");
|
||||
|
||||
|
||||
// TODO: 处理玩家死亡
|
||||
// - 显示死亡界面
|
||||
// - 显示复活选项或返回登录
|
||||
|
||||
|
||||
// 延迟后返回登录
|
||||
setTimeout(() => {
|
||||
this._fsm.changeState("Login");
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 退出游戏(返回登录)
|
||||
*/
|
||||
quitGame(): void {
|
||||
console.log("[AppStatusGame] 退出游戏");
|
||||
|
||||
|
||||
// TODO: 断开连接或通知服务器
|
||||
// const netManager = NetManager.getInstance();
|
||||
// await netManager.disconnect();
|
||||
|
||||
|
||||
// 返回登录
|
||||
this._fsm.changeState("Login");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 延迟辅助函数
|
||||
*/
|
||||
private delay(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 退出游戏状态
|
||||
*/
|
||||
onExit(): void {
|
||||
super.onExit();
|
||||
console.log("[AppStatusGame] 离开游戏状态");
|
||||
|
||||
|
||||
// 清理世界
|
||||
World.clear();
|
||||
|
||||
|
||||
// 卸载游戏UI
|
||||
if (this._uiGame) {
|
||||
UIMgr.getInstance().unload(UIGame);
|
||||
this._uiGame = null;
|
||||
}
|
||||
|
||||
|
||||
this._player = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Node, Vec3, instantiate, Prefab } from 'cc';
|
||||
import { instantiate, Node, Prefab } from 'cc';
|
||||
import { NetManager } from '../../Framework/Net/NetManager';
|
||||
import { ResMgr } from '../../Framework/ResMgr/ResMgr';
|
||||
import { MsgPlayerJoin } from '../../Shared/protocols/MsgPlayerJoin';
|
||||
import { MsgPlayerMove } from '../../Shared/protocols/MsgPlayerMove';
|
||||
import { PlayerInfo } from '../../Shared/protocols/PtlLogin';
|
||||
import { PlayerInfo } from '../../Shared/protocols/MsgResLogin';
|
||||
import { CameraController } from './CameraController';
|
||||
import { PlayerController } from './PlayerController';
|
||||
import { RemotePlayer } from './RemotePlayer';
|
||||
|
||||
@@ -33,7 +34,10 @@ export class World {
|
||||
/** 玩家模型预制体 */
|
||||
private playerPrefab: Prefab = null;
|
||||
|
||||
private constructor() {}
|
||||
/** 摄像机控制器 */
|
||||
private cameraController: CameraController = null;
|
||||
|
||||
private constructor() { }
|
||||
|
||||
public static getInstance(): World {
|
||||
if (!World.instance) {
|
||||
@@ -68,7 +72,7 @@ export class World {
|
||||
*/
|
||||
private async loadPlayerPrefab(): Promise<void> {
|
||||
try {
|
||||
this.playerPrefab = await ResMgr.getInstance().load('resources', 'res://Actor/M1/M1', Prefab);
|
||||
this.playerPrefab = await ResMgr.getInstance().load('res', 'Actor/M1/M1', Prefab);
|
||||
console.log('[World] 玩家模型预制体加载成功');
|
||||
} catch (error) {
|
||||
console.error('[World] 加载玩家模型预制体失败:', error);
|
||||
@@ -113,6 +117,10 @@ export class World {
|
||||
this.localPlayerController = this.localPlayerNode.addComponent(PlayerController);
|
||||
this.localPlayerController.init(this.localPlayer);
|
||||
|
||||
// 创建并绑定摄像机控制器(只有本地玩家需要)
|
||||
this.cameraController = this.worldRoot.addComponent(CameraController) as CameraController;
|
||||
this.cameraController.setTarget(this.localPlayerNode);
|
||||
|
||||
console.log('[World] 本地玩家创建完成:', this.localPlayer.name);
|
||||
}
|
||||
|
||||
@@ -198,6 +206,12 @@ export class World {
|
||||
}
|
||||
this.localPlayerController = null;
|
||||
|
||||
// 销毁摄像机控制器
|
||||
if (this.cameraController) {
|
||||
this.cameraController.node.removeComponent(CameraController);
|
||||
this.cameraController = null;
|
||||
}
|
||||
|
||||
// 销毁所有远程玩家
|
||||
this.remotePlayers.forEach((remotePlayer) => {
|
||||
remotePlayer.destroy();
|
||||
|
||||
9
client/assets/scripts/App/Msg.meta
Normal file
9
client/assets/scripts/App/Msg.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "9f8d42c2-cee9-4156-b0ee-992cb5d66317",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
76
client/assets/scripts/App/Msg/MessagePairBase.ts
Normal file
76
client/assets/scripts/App/Msg/MessagePairBase.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 消息对定义基类
|
||||
* 用于定义成对出现的请求和响应消息
|
||||
*/
|
||||
export abstract class MessagePair<TReq, TRes> {
|
||||
/** 请求消息名称 */
|
||||
abstract readonly requestName: string;
|
||||
|
||||
/** 响应消息名称 */
|
||||
abstract readonly responseName: string;
|
||||
|
||||
/** 请求消息类型检查 */
|
||||
abstract isValidRequest(msg: any): msg is TReq;
|
||||
|
||||
/** 响应消息类型检查 */
|
||||
abstract isValidResponse(msg: any): msg is TRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息对注册表
|
||||
* 用于管理所有的消息对
|
||||
*/
|
||||
export class MessagePairRegistry {
|
||||
private static _instance: MessagePairRegistry;
|
||||
private _pairs: Map<string, MessagePair<any, any>> = new Map();
|
||||
|
||||
static getInstance(): MessagePairRegistry {
|
||||
if (!this._instance) {
|
||||
this._instance = new MessagePairRegistry();
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册消息对
|
||||
* @param pair 消息对实例
|
||||
*/
|
||||
register(pair: MessagePair<any, any>): void {
|
||||
this._pairs.set(pair.requestName, pair);
|
||||
console.log(`[MessagePairRegistry] Registered message pair: ${pair.requestName} -> ${pair.responseName}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据请求消息名获取响应消息名
|
||||
* @param requestName 请求消息名
|
||||
* @returns 响应消息名,如果未找到返回null
|
||||
*/
|
||||
getResponseName(requestName: string): string | null {
|
||||
const pair = this._pairs.get(requestName);
|
||||
return pair ? pair.responseName : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据请求消息名获取消息对
|
||||
* @param requestName 请求消息名
|
||||
* @returns 消息对实例,如果未找到返回null
|
||||
*/
|
||||
getPair(requestName: string): MessagePair<any, any> | null {
|
||||
return this._pairs.get(requestName) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为已注册的请求消息
|
||||
* @param msgName 消息名
|
||||
*/
|
||||
isRegisteredRequest(msgName: string): boolean {
|
||||
return this._pairs.has(msgName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有已注册的消息对
|
||||
*/
|
||||
getAllPairs(): MessagePair<any, any>[] {
|
||||
return Array.from(this._pairs.values());
|
||||
}
|
||||
}
|
||||
9
client/assets/scripts/App/Msg/MessagePairBase.ts.meta
Normal file
9
client/assets/scripts/App/Msg/MessagePairBase.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "3ba46d91-073d-44d6-8157-05f1af758121",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
23
client/assets/scripts/App/Msg/MessagePairInit.ts
Normal file
23
client/assets/scripts/App/Msg/MessagePairInit.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { MessagePairRegistry } from './MessagePairBase';
|
||||
import { LoginMessagePair } from './Pair/LoginMessagePair';
|
||||
import { MoveMessagePair } from './Pair/MoveMessagePair';
|
||||
import { SendMessagePair } from './Pair/SendMessagePair';
|
||||
|
||||
/**
|
||||
* 消息对初始化
|
||||
* 在应用启动时调用此函数注册所有消息对
|
||||
*/
|
||||
export function initMessagePairs(): void {
|
||||
const registry = MessagePairRegistry.getInstance();
|
||||
|
||||
// 注册登录消息对
|
||||
registry.register(new LoginMessagePair());
|
||||
|
||||
// 注册移动消息对
|
||||
registry.register(new MoveMessagePair());
|
||||
|
||||
// 注册发送消息对
|
||||
registry.register(new SendMessagePair());
|
||||
|
||||
console.log('[MessagePairs] All message pairs registered successfully');
|
||||
}
|
||||
9
client/assets/scripts/App/Msg/MessagePairInit.ts.meta
Normal file
9
client/assets/scripts/App/Msg/MessagePairInit.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "9b552413-09a9-4ec6-b389-ea371b734a41",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
84
client/assets/scripts/App/Msg/MsgExample.ts
Normal file
84
client/assets/scripts/App/Msg/MsgExample.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { initMessagePairs } from './MessagePairInit';
|
||||
import { MsgManager } from './MsgManager';
|
||||
|
||||
/**
|
||||
* 消息系统使用示例
|
||||
*/
|
||||
export class MsgExample {
|
||||
|
||||
/**
|
||||
* 初始化消息系统
|
||||
* 应在游戏启动时调用
|
||||
*/
|
||||
static init(): void {
|
||||
// 初始化消息对注册表
|
||||
initMessagePairs();
|
||||
|
||||
console.log('[MsgExample] Message system initialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录示例
|
||||
*/
|
||||
static async loginExample(): Promise<void> {
|
||||
const msgMgr = MsgManager.getInstance();
|
||||
|
||||
try {
|
||||
const response = await msgMgr.login({
|
||||
playerId: 'player123',
|
||||
playerName: 'TestPlayer'
|
||||
});
|
||||
|
||||
if (response && response.success) {
|
||||
console.log('登录成功:', response.player);
|
||||
} else {
|
||||
console.log('登录失败:', response?.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('登录请求异常:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动示例
|
||||
*/
|
||||
static async moveExample(): Promise<void> {
|
||||
const msgMgr = MsgManager.getInstance();
|
||||
|
||||
try {
|
||||
const response = await msgMgr.move({
|
||||
x: 100,
|
||||
y: 200
|
||||
});
|
||||
|
||||
if (response && response.success) {
|
||||
console.log('移动成功:', response.position);
|
||||
} else {
|
||||
console.log('移动失败:', response?.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('移动请求异常:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息示例
|
||||
*/
|
||||
static async sendMessageExample(): Promise<void> {
|
||||
const msgMgr = MsgManager.getInstance();
|
||||
|
||||
try {
|
||||
const response = await msgMgr.send({
|
||||
content: 'Hello, World!'
|
||||
});
|
||||
|
||||
if (response) {
|
||||
console.log('消息发送成功:', response.time);
|
||||
} else {
|
||||
console.log('消息发送失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('发送消息异常:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
9
client/assets/scripts/App/Msg/MsgExample.ts.meta
Normal file
9
client/assets/scripts/App/Msg/MsgExample.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "4c559445-88e3-4fe2-a87c-8c9ef390aa60",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
55
client/assets/scripts/App/Msg/MsgManager.ts
Normal file
55
client/assets/scripts/App/Msg/MsgManager.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { NetManager } from '../../Framework/Net/NetManager';
|
||||
import { MsgReqLogin } from '../../Shared/protocols/MsgReqLogin';
|
||||
import { MsgReqMove } from '../../Shared/protocols/MsgReqMove';
|
||||
import { MsgReqSend } from '../../Shared/protocols/MsgReqSend';
|
||||
import { MsgResLogin } from '../../Shared/protocols/MsgResLogin';
|
||||
import { MsgResMove } from '../../Shared/protocols/MsgResMove';
|
||||
import { MsgResSend } from '../../Shared/protocols/MsgResSend';
|
||||
import { LoginMessagePair } from './Pair/LoginMessagePair';
|
||||
import { MoveMessagePair } from './Pair/MoveMessagePair';
|
||||
import { SendMessagePair } from './Pair/SendMessagePair';
|
||||
|
||||
/**
|
||||
* 消息管理器 - 提供类型安全的消息发送方法
|
||||
*/
|
||||
export class MsgManager {
|
||||
private static _instance: MsgManager;
|
||||
|
||||
static getInstance(): MsgManager {
|
||||
if (!this._instance) {
|
||||
this._instance = new MsgManager();
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
private get netManager(): NetManager {
|
||||
return NetManager.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送登录请求
|
||||
* @param loginData 登录数据
|
||||
* @returns 登录响应
|
||||
*/
|
||||
async login(loginData: MsgReqLogin): Promise<MsgResLogin | null> {
|
||||
return this.netManager.callMsg(new LoginMessagePair(), loginData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送移动请求
|
||||
* @param moveData 移动数据
|
||||
* @returns 移动响应
|
||||
*/
|
||||
async move(moveData: MsgReqMove): Promise<MsgResMove | null> {
|
||||
return this.netManager.callMsg(new MoveMessagePair(), moveData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息请求
|
||||
* @param sendData 发送数据
|
||||
* @returns 发送响应
|
||||
*/
|
||||
async send(sendData: MsgReqSend): Promise<MsgResSend | null> {
|
||||
return this.netManager.callMsg(new SendMessagePair(), sendData);
|
||||
}
|
||||
}
|
||||
9
client/assets/scripts/App/Msg/MsgManager.ts.meta
Normal file
9
client/assets/scripts/App/Msg/MsgManager.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "871b5daf-492f-4ff7-adac-a13bbf6b82ce",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
9
client/assets/scripts/App/Msg/Pair.meta
Normal file
9
client/assets/scripts/App/Msg/Pair.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "6f3ea388-fd67-45a4-9bfc-cae858378b7a",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
21
client/assets/scripts/App/Msg/Pair/LoginMessagePair.ts
Normal file
21
client/assets/scripts/App/Msg/Pair/LoginMessagePair.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { MsgReqLogin } from '../../../Shared/protocols/MsgReqLogin';
|
||||
import { MsgResLogin } from '../../../Shared/protocols/MsgResLogin';
|
||||
import { MessagePair } from '../MessagePairBase';
|
||||
|
||||
/**
|
||||
* 登录消息对实现
|
||||
*/
|
||||
export class LoginMessagePair extends MessagePair<MsgReqLogin, MsgResLogin> {
|
||||
readonly requestName = 'ReqLogin';
|
||||
readonly responseName = 'ResLogin';
|
||||
|
||||
isValidRequest(msg: any): msg is MsgReqLogin {
|
||||
return msg && typeof msg.playerId === 'string';
|
||||
}
|
||||
|
||||
isValidResponse(msg: any): msg is MsgResLogin {
|
||||
return msg &&
|
||||
typeof msg.success === 'boolean' &&
|
||||
typeof msg.message === 'string';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "8a0f8893-e078-4885-8407-70944f67d185",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
23
client/assets/scripts/App/Msg/Pair/MoveMessagePair.ts
Normal file
23
client/assets/scripts/App/Msg/Pair/MoveMessagePair.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { MsgReqMove } from '../../../Shared/protocols/MsgReqMove';
|
||||
import { MsgResMove } from '../../../Shared/protocols/MsgResMove';
|
||||
import { MessagePair } from '../MessagePairBase';
|
||||
|
||||
/**
|
||||
* 移动消息对实现
|
||||
*/
|
||||
export class MoveMessagePair extends MessagePair<MsgReqMove, MsgResMove> {
|
||||
readonly requestName = 'ReqMove';
|
||||
readonly responseName = 'ResMove';
|
||||
|
||||
isValidRequest(msg: any): msg is MsgReqMove {
|
||||
return msg &&
|
||||
typeof msg.x === 'number' &&
|
||||
typeof msg.y === 'number';
|
||||
}
|
||||
|
||||
isValidResponse(msg: any): msg is MsgResMove {
|
||||
return msg &&
|
||||
typeof msg.success === 'boolean' &&
|
||||
typeof msg.message === 'string';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "f95aa765-9371-4644-9694-8eb8dd7d8930",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
19
client/assets/scripts/App/Msg/Pair/SendMessagePair.ts
Normal file
19
client/assets/scripts/App/Msg/Pair/SendMessagePair.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { MsgReqSend } from '../../../Shared/protocols/MsgReqSend';
|
||||
import { MsgResSend } from '../../../Shared/protocols/MsgResSend';
|
||||
import { MessagePair } from '../MessagePairBase';
|
||||
|
||||
/**
|
||||
* 发送消息对实现
|
||||
*/
|
||||
export class SendMessagePair extends MessagePair<MsgReqSend, MsgResSend> {
|
||||
readonly requestName = 'ReqSend';
|
||||
readonly responseName = 'ResSend';
|
||||
|
||||
isValidRequest(msg: any): msg is MsgReqSend {
|
||||
return msg && typeof msg.content === 'string';
|
||||
}
|
||||
|
||||
isValidResponse(msg: any): msg is MsgResSend {
|
||||
return msg && msg.time instanceof Date;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d9ef0dad-c949-4a46-9306-d4a060a40a3b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
Reference in New Issue
Block a user