当前位置 : 145z游戏站 | 热血传奇 | 技术教程 | 

传奇服务端响应逻辑:玩家移动与消息广播机制

热度:
服务器端对客户端操作的响应以玩家移动为典型场景展开。GameSrv服务器通过ProcessUserHuman线程处理玩家消息,该线程遍历UserInfoList列表,依次调用每个UserInfo的Operate方法处理命令队列中的所有操作。Operate方法内部调用m_pxPlayerObject->Operate执行具体逻辑。

移动响应的核心判断在于玩家存活状态。若玩家已死亡,服务器发送_MSG_FAIL消息,该消息在客户端被优先处理。存活状态下则调用WalkTo函数并发送_MSG_GOOD消息给客户端。WalkTo函数的执行流程包含坐标计算与地图交互判断。WalkNextPos根据随机值产生八个方向的坐标位置,WalkXY处理怪物走动的坐标值。CheckDoorEvent依据pMapCellInfo->m_sLightNEvent返回四种状态:移动位置为门且可开返回_DOOR_OPEN,不是门返回_DOOR_NOT,门无法打开则返回_DOOR_MAPMOVE_BACK或_DOOR_MAPMOVE_FRONT对应玩家前后移动。

门状态处理中,若为_DOOR_OPEN则发送SM_DOOROPEN消息给周围玩家。地图移动判定通过m_pMap->CanMove检查目标格子是否可通行,确认可移动后执行MoveToMovingObject从当前点移动到目标点,随后调用AddRefMsg(RM_WALK)向周围玩家广播移动消息。AddRefMsg根据X、Y坐标,在以自身坐标为中心周围26*26区域内按地图单元格划分,遍历所有单元格及其内的玩家列表,广播发送RM_WALK消息。

客户端接收服务器响应后执行不同分支。收到_MSG_FAIL时由CGameProcess::OnProcPacketNotEncode处理,调用m_xMyHero.SetOldPosition将角色拉回移动前位置,设置动作帧为站立状态,AdjustMyPostion重绘地图,并将m_bMotionLock与m_bInputLock置为FALSE。收到_MSG_GOOD时则将m_xMyHero.m_bMotionLock置为FALSE,允许继续操作。

其他客户端收到广播消息后的执行流程与当前玩家不同。其他玩家的角色设置动作帧为行走方向对应的帧,骑马状态则设为马匹行走帧,m_bMoveSpeed赋值为_SPEED_WALK,SetMoving设置m_shShiftPixelX和m_shShiftPixelY坐标用于像素级平滑移动。NPC和怪物同样设置_MON_WALK帧与位移坐标。CGameProcess::RenderObject通过DrawActor根据位移坐标重绘发消息的玩家、NPC和怪物位置。

客户端消息接收的底层机制通过CClientSocket::OnSocketMessage的FD_READ事件完成,接收到的数据包压入PacketQ队列。队列数据由CGameProcess::OnTimer在定时器循环中处理,依次调用OnMessageReceive、ProcessPacket和ProcessDefaultPacket。OnMessageReceive判断心跳数据包并发送'*'保持连接,随后调用OnSocketMessageRecieve处理游戏逻辑数据包。以'+'开头的数据包调用OnProcPacketNotEncode处理,否则按_TDEFAULTMESSAGE结构解析。

OnSocketMessageRecieve函数处理服务器下发的各类消息码。SM_SENDNOTICE显示服务器提示信息,SM_NEWMAP初始化地图数据,SM_LOGON在登录成功后本地创建游戏对象并请求物品清单。SM_ABILITY和SM_SUBABILITY接收玩家属性与技能数据,SM_SENDMYMAGIC加载魔法列表,SM_BAGITEMS和SM_SENDUSEITEMS分别接收背包与装备清单。新登录玩家按顺序收到SM_NEWMAP、SM_LOGON、SM_USERNAME、SM_MAPDESCRIPTION、SM_ABILITY、SM_SUBABILITY、SM_DAYCHANGING、SM_SENDUSEITEMS、SM_SENDMYMAGIC等消息,客户端依次执行地图加载、角色创建、属性设置和界面渲染。

ProcessMonster线程和ProcessMerchants线程负责怪物与商人的响应逻辑。怪物对象创建后加入xMonsterObjList和地图单元格列表,SearchViewRange更新视线目标,Operate遍历m_DelayProcessQ过滤RM_DOOPENHEALTH、RM_STRUCK和RM_MAGSTRUCK三个事件分别对应恢复生命、物理攻击和魔法攻击处理。商人对象按地图和类型创建,SearchViewRange遍历m_xVisibleObjectList更新可见标志,删除视野外的对象,RunRace调用AddRefMsg向周围玩家发送SM_TURN和SM_HIT消息。

客户端对玩家、怪物、商人、物品和事件的统一处理通过遍历多个可见列表完成。m_xVisibleObjectList包含所有移动角色,RM_DISAPPEAR触发消失处理,RM_DEATH触发死亡处理,RM_TURN触发转向处理。m_xVisibleItemList管理地图物品,RM_ITEMHIDE从m_stMapItemList删除物品。m_xVisibleEventList处理地图事件,RM_HIDEEVENT隐藏事件对象。所有未即时处理的数据加入m_xWaitPacketQueue队列,由ProcessPacket延后处理。
[顶部]