玩家游戏状态变化 enum GameState//玩家游戏状态 { eGameState_OnlyConnect = 0, ///< 仅连接 eGameState_Login = 1, ///< 登录 eGameState_EnterMap = 2, ///< 进入地图 eGameState_Disconnect = 3, ///< 下线 }; 1.当libevent收到连接事件的时候 GameChannel::GameChannel() { //... m_eGameState = eGameState_OnlyConnect;//客户端仅仅连接 //... } 2.客户端点击登录,然后数据库根据名字去查询userinfo,返回密码跟用户匹配,如果相同 void GameChannel::ProcessGetUserInfo(const ShuiHu::UserInfo& User) { if(0 == strncmp(User.m_szUserPwd, m_pUserInfo->m_szUserPwd, MAX_NAME_LEN)) { m_eGameState = eGameState_Login;//玩家状态为登录状态 } } 3.等用户登录成功之后服务器会想客户端发送角色表 用户选择角色点击开始,GS收到消息之后根据id从数据库查询角色的详细信息 void GameChannel::ProcessGetActorInfoEx(bool bRet, const ShuiHu::ActorInfoEx& crActorEx) { //... //给客户端发送本地玩家信息 LocPlayerInfo info; InitLocalPlayer(rActorEx, info); SendCmd(s2c_local_player_info, &info, sizeof(info)); m_pShare->m_spLog->Logs(eLogLevel_Info, "s2c_local_player_info"); //放入ShareCenter中 m_strActorName = rActorEx.GetName(); m_pShare->AddOnLinePlayer(m_ActorId, m_strActorName, m_nChannelId); // 标记已进入地图 //看来这个是在向客户端发送本地玩家信息,就直接标记成进入地图状态,个人觉得不对 //因为此时还没有进入地图,进入地图是在客户端发送激活包之后才算真正进入地图 m_eGameState = eGameState_EnterMap; //序列化ActorInfoEx准备传入MS rActorEx.m_nChannelId = m_nChannelId; //... } 4.libevent收到客户端连接断开事件 //... void GameChannel::OnOffLine() { //未登录或者已离线 if(m_eGameState == eGameState_OnlyConnect || m_eGameState == eGameState_Disconnect)//此处为什么没有登录状态的判断 return; //玩家断开时才真正删除角色 for(std::map<int, ShuiHu::ActorInfo>::iterator it = m_mapDelActors.begin(); it != m_mapDelActors.end(); ++it) { int actID = it->first; m_pAsynDBC->DelActor(actID, m_UserId); //帮会操作通知删除角色 m_pShare->m_spGuildOpt->OnActorDelete(actID, safe::mbstowcs(it->second.m_szGuildName)); } //删除在线用户 m_pShare->DelOnLineUser(m_UserId); if(m_eGameState != eGameState_EnterMap) //未登录游戏 return; //通知Map玩家下线 m_pMap->Gs2MsData(gs2ms_del_player, m_nChannelId, NULL, 0); m_eGameState = eGameState_Disconnect;//此时标记玩家下线状态,此时map玩家下线消息已经发送,GS这边还有很多需要处理 }
时间: 2024-10-11 22:15:46