• 小退


    小退
    void GameChannel::OnLogOut()
    {
        if(m_eGameState != eGameState_EnterMap)//小退玩家肯定是进入地图状态
            return;
    
        ClearMapRcd();//清除地图相关记录,实现就是给相应地图
        
        m_eGameState = eGameState_Login;//我在想这里设置成登录状态,不怕登下GS返回的时候不是登录状态
    }
    
    {
        //...
        else if (gs2ms_del_player == pkt.cmd)    //玩家下线
        {        
            OffLine(pkt.channelId);    
        }
        //...
    }
    /**
     *相关删除工作和保存工作
     */
    void Map::OffLine(int mapChannelId)
    {
        PlayerChannel* pPlayerChannel = m_vecPlayerChannel[mapChannelId];
        if (!pPlayerChannel)
        {
            ShuiHu::GetLogger()->Warning("下线函数%s:nChannelId = %d为空", 
                __FUNCTION__, mapChannelId);
            return;
        }
        // 清除地图相关数据
        DelPlayer(mapChannelId);
        // 下线清除玩家的临时罪恶
        m_spSinMgr->ClearTmpSin(pPlayerChannel);
        // 下线通知ReleationShip
        m_pRelationOpt->ActorOffline(pPlayerChannel);
        m_pGuildOpt->ActorOffline(pPlayerChannel);
        m_pTeamOpt->ActorOffline(pPlayerChannel);
    
        // 数据操作
        ShuiHu::ActorInfoEx* pInfoEx = pPlayerChannel->m_pActorInfoEx;
        pInfoEx->SetOnline(false);
        pInfoEx->m_bGaming = false;
        if(m_MapType == eMAPTYPE_ACTIVITY)                    //地宫地图下线传回新手村
        {
            pInfoEx->SetPos(4080, 2720);
            pInfoEx->SetMapID(1001);
        }
        else
        {
            pInfoEx->SetPos(pPlayerChannel->tgtPos.x, pPlayerChannel->tgtPos.y);
            pInfoEx->SetMapID(pPlayerChannel->m_nMapId); 
        }
        pInfoEx->SetCurHP(pPlayerChannel->stat.cur_hp);
        pInfoEx->SetCurMP(pPlayerChannel->stat.cur_mp);
        pInfoEx->SetCurXP(pPlayerChannel->stat.cur_exp);
        pPlayerChannel->m_PropOpt.SetPropsToActorinfoEx(pPlayerChannel->m_pActorInfoEx);//同步道具信息
        pPlayerChannel->m_fnSendInfoEx2Gs();//将玩家的数据信息存入gs中的数据库中,向GS发送ms2gs_db_buff_info消息
        ClearMem(mapChannelId);//不知道干啥的
    }
    
    
    void SendCmd2Gs(int nCmd, int nChannelId, void* pData, int nLen)
    {
        MapPkt Pkt;
        Pkt.cmd = nCmd;
        Pkt.channelId = nChannelId;
        char* pszNewBuffer = new char[nLen];
        memcpy(pszNewBuffer, pData, nLen);
        Pkt.data = pszNewBuffer;
        Pkt.len = nLen;
        PushData2GS(Pkt);//将数据放到MS->GS端的无锁队列中
    };
    
    在Share_Recv文件中
    void Share::ProcMapSendData()
    {
    
        for(auto itMap : m_mapMap)//遍历所有地图
        {
            MapPkt Pkt;
            try
            {
                for (;;)
                {
                    if(!itMap.second->RecvData(Pkt))//从相应map无锁队列中取数据
                        break;
                    if(Pkt.cmd == ms2gs_转client_cmd)
                    {
                        OnTurnToClient(Pkt.channelId, Pkt.data, Pkt.len);
                    }
                    else if(Pkt.cmd == ms2gs_json)
                    {
                        OnJson(Pkt.channelId, Pkt.data, Pkt.len);
                    }
                    else if(ms2gs_db_buff_info == Pkt.cmd)
                    {
                        OnLeaveMap(Pkt.channelId, Pkt.data, Pkt.len);
                    }
                    else if(ms2gs_obj_leave == Pkt.cmd)    //玩家切换地图
                    {
                        OnEnterNewMap(Pkt.channelId, Pkt.data, Pkt.len);
                    }
                    else if(ms2gs_guild_opt == Pkt.cmd)
                    {
                        m_spGuildOpt->OnGuildOpt(Pkt.channelId, Pkt.data, Pkt.len);
                    }
                    else if (ms2gs_prop_mgr == Pkt.cmd)
                    {
                        m_spPropManager->OnPropMgrOpt(Pkt.channelId, Pkt.data, Pkt.len);
                    }
                    else if (ms2ms_cmd == Pkt.cmd)
                    {
                        OnTurnToMap(Pkt.mapId, Pkt.data, Pkt.len);
                    }
                    else if (ms2gs_mall_opt == Pkt.cmd)
                    {
                        m_spMallOpt->OnMallOpt(Pkt.channelId, Pkt.data, Pkt.len);
                    }
                    delete[] Pkt.data;
                    Pkt.data = nullptr;
                }
            }
            catch(...)
            {
                char sErrMsg[256] = {0};
                sprintf(sErrMsg, "【%s】ShareCenter:接收%d地图的 cmd = %d 指令时时出错!", 
                    __FUNCTION__, itMap.first, Pkt.cmd);
                ShuiHu::GetLogger()->Fatal(sErrMsg);
                safe::error_msg(sErrMsg);
            }
        }
    
    }
    
    //看看GS这边针对下线的处理
    void Share::OnLeaveMap(int nChannelId, void* pData, int nLen)
    {
        //玩家一旦离开地图,保存数据到DB
        GameChannel* pGC = GetGcByChannelId(nChannelId);
        msg_assert(pGC);
        pGC->LeaveMap(pData, nLen);
    
        int nActorId = pGC->GetActorID();
        std::string strActorName = pGC->GetActorName();
    
        DelOnLinePlayer(nActorId, strActorName);//删除在线玩家的相关容器
        
        if(pGC->IsDisconnect()) //玩家打退,直接关闭客户端
        {
            //放入释放队列中,断开
            //PushFreeQueue(pGC);
            AutoFreeGC(pGC);//放到自动释放队列中,等没有数据库返回时在将pGC删除
            m_vecChannel[nChannelId] = nullptr;
        }
    }
    
    void GameChannel::LeaveMap(void* pData, int nLen)
    {
        // 数据保存到数据库
        SaveData(pData, nLen);//包括修改下线时间,同步等级,帮会名,保存玩家信息,保存角色详细信息
    
        
        if(m_eGameState == eGameState_Login)
            SendActorListSyn();    // 小退到登录界面,发送角色列表
    }
  • 相关阅读:
    CEF解决加载慢问题
    CEF之CefSettings设置locale
    Win32程序支持命令行参数的做法(转载)
    VC++实现程序重启的方法(转载)
    CEF之CefSettings设置日志等级
    libcurl开源库在Win32程序中使用下载文件显示进度条实例
    libcurl开源库在Win7 + VS2012环境下编译、配置详解 以及下载文件并显示下载进度 demo(转载)
    使用ShellExecute打开目标文件所在文件夹并选中目标文件
    linux下gimp的使用
    linux下的chm阅读器?
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/4159669.html
Copyright © 2020-2023  润新知