zoukankan      html  css  js  c++  java
  • GS发包到MS

    GS发包到MS(GS,MS包交互过程)
    例:人物上线
    首先看看其实如何确定是哪张地图的
    数据库首先只保存一个mapid
    在share初始化的时候已经初始化了所有map,并保存了map的指针信息,其key就是mapid
    if(rActorEx.GetMapID() <= 0)
        rActorEx.SetMapID(1009);
    int mapID = rActorEx.GetMapID();
    rActorEx.m_nBodyID = m_pShare->TGetnBodyId(rActorEx.GetProf(), rActorEx.GetSex());//现在那个bodyid用到了
    
    m_pMap = m_pShare->GetMapByMapId(mapID);//通过mapid就能获得map指针信息
    if(!m_pMap)
    {
        m_ActorId = 0;
        return;
    }
    
    
    m_pMap->Gs2MsData(gs2ms_add_player, m_nChannelId, (void*)&rActorEx, sizeof(rActorEx));//传入MS,m_pMap即玩家所在地图指针
    void Map::Gs2MsData(int cmd, int channel_id, void* data, int len)
    {
        MapPkt pkt;
        pkt.channelId = channel_id;
        pkt.data = m_memPool.popPkt(len);//从内存池中分配一块内存出来,以前用的new,然后这个new很容易失败的
        memcpy(pkt.data, data, len);
        pkt.len = len;
        pkt.cmd = cmd;
    
        PushPkt(pkt);
    }
    //接下来就是起的线程的作用了
    void ThrTransData::PushPkt(MapPkt Pkt)
    {
    #ifdef BOOST_LOCKFREE
        for (;;)
        {
            if(m_gs2msPkts2.push(Pkt))//将这个包放入无锁队列中
                break;
            cxx11::this_thread::interruptible_wait(1);
        }
    #else
        {
            cxx11::lock_guard lock(m_mtxGs2Ms);
            m_queGs2MsPkts.push(Pkt);
        }
    #endif
    };
    
    void ThrTransData::ThreadLoop()
    {
        //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
        MapPkt Pkt;
        try
        {
            int nCount = 0;
            while (true)
            {
                if(GetDataFromQueue(&Pkt))//从无锁队列中取包
                {
                    ProcessPkt(Pkt);
                    m_memPool.pushPkt(Pkt.data, Pkt.len);
    
                    nCount++;
                    if(nCount > 30)
                    {
                        nCount = 0;
                        m_spTimerFactory->driveTimer();
                    }
                    continue;
                }
                {
                    m_spTimerFactory->driveTimer();
                    if (m_bStopWork)
                        break;
                    cxx11::this_thread::interruptible_wait(1);
                }
            }
        }
        catch(...)
        {
            char szMsg[256] = {0};
            sprintf(szMsg, "【%s】线程%dMap :Pkt.cmd = %d",
                __FUNCTION__, ::GetCurrentThreadId(), Pkt.cmd);
            safe::error_msg(szMsg);
        }
    }
    
    void Map::ProcessPkt(MapPkt pkt)
    {
        //...
        //gs2ms_add_player属于GS与MS通信的内部协议,内部协议采用树的形式,平行关系就太多了管理不方便
        else if(gs2ms_add_player == pkt.cmd)//玩家进入地图消息,仅仅是个小例子
        {
            PlayerChannel* pPC = new PlayerChannel(this);//这个PlayerChannel是很大的一个模块,玩家信息,回头再看
            //加到地图中,但是并未激活该玩家
            int nChannelId = pPC->OnPlayerEnter(pkt.data, pkt.len);
            m_vecPlayerChannel[nChannelId] = pPC;
            AddPlayer(nChannelId);        
        }
        //...
    }
  • 相关阅读:
    jvm的方法栈在干什么
    时间段交集查询
    linux 设置静态ip配置
    elk 学习
    内网穿透 https:natapp.cn
    mysql当前时间,日期转换,日期格式化
    swaggerui api.docs
    linux java -jar 后台进程
    druid 数据源 sql控制台输出
    spring pointcut 表达式
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/4149684.html
Copyright © 2011-2022 走看看