2025-12-18 12:03:03 +08:00
|
|
|
|
import { MsgCall } from "tsrpc";
|
|
|
|
|
|
import { playerManager } from "../managers/PlayerManager";
|
|
|
|
|
|
import { MsgPlayerMove } from "../shared/protocols/MsgPlayerMove";
|
|
|
|
|
|
import { MsgReqMove } from "../shared/protocols/MsgReqMove";
|
|
|
|
|
|
import { broadcastToAll } from "../utils/broadcast";
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 移动消息处理器
|
|
|
|
|
|
* 处理玩家移动请求,验证位置合法性,更新玩家位置并广播给其他玩家
|
|
|
|
|
|
*/
|
|
|
|
|
|
export default async function (call: MsgCall<MsgReqMove>) {
|
|
|
|
|
|
const { x, y } = call.msg;
|
|
|
|
|
|
|
|
|
|
|
|
// 从连接中获取玩家ID(需要在登录时保存)
|
|
|
|
|
|
const playerId = (call.conn as any).playerId;
|
|
|
|
|
|
|
|
|
|
|
|
if (!playerId) {
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '未登录,请先登录'
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取玩家信息
|
|
|
|
|
|
const player = playerManager.getPlayer(playerId);
|
|
|
|
|
|
|
|
|
|
|
|
if (!player) {
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '玩家不存在'
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查玩家是否存活
|
|
|
|
|
|
if (!player.isAlive) {
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '玩家已死亡,无法移动'
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证坐标是否为数字
|
|
|
|
|
|
if (typeof x !== 'number' || typeof y !== 'number') {
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '坐标格式错误'
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证坐标是否为整数
|
|
|
|
|
|
if (!Number.isInteger(x) || !Number.isInteger(y)) {
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '坐标必须为整数'
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 尝试更新玩家位置
|
|
|
|
|
|
const success = playerManager.updatePlayerPosition(playerId, x, y);
|
|
|
|
|
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: '移动失败,位置无效或超出世界边界'
|
|
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取更新后的位置
|
|
|
|
|
|
const newPosition = { x, y };
|
|
|
|
|
|
|
|
|
|
|
|
// 广播移动消息给所有其他玩家
|
|
|
|
|
|
const moveMsg: MsgPlayerMove = {
|
|
|
|
|
|
playerId: player.id,
|
|
|
|
|
|
playerName: player.name,
|
|
|
|
|
|
position: newPosition,
|
|
|
|
|
|
timestamp: Date.now()
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
broadcastToAll('MsgPlayerMove', moveMsg, call.conn.id);
|
|
|
|
|
|
|
|
|
|
|
|
// 返回成功结果
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: true,
|
|
|
|
|
|
message: '移动成功',
|
|
|
|
|
|
position: newPosition
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`玩家 ${player.name} 移动到 (${x}, ${y})`);
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('移动失败:', error);
|
|
|
|
|
|
call.conn.sendMsg('ResMove', {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
message: `移动失败: ${error instanceof Error ? error.message : '未知错误'}`
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|