Пример #1
0
void ServiceCore::On_MPK_ADDCHAROBJECT(const MessagePack &rstMPK)
{
    AMAddCharObject stAMACO;
    std::memcpy(&stAMACO, rstMPK.Data(), sizeof(stAMACO));

    if(stAMACO.Common.MapID){
        if(auto pMap = RetrieveMap(stAMACO.Common.MapID)){
            if(false
                    || stAMACO.Common.Random
                    || pMap->In(stAMACO.Common.MapID, stAMACO.Common.X, stAMACO.Common.Y)){

                m_ActorPod->Forward(pMap->UID(), {MPK_ADDCHAROBJECT, stAMACO}, [this, stAMACO, rstMPK](const MessagePack &rstRMPK)
                {
                    switch(rstRMPK.Type()){
                        case MPK_OK:
                            {
                                m_ActorPod->Forward(rstMPK.From(), MPK_OK, rstMPK.ID());
                                break;
                            }
                        default:
                            {
                                m_ActorPod->Forward(rstMPK.From(), MPK_ERROR, rstMPK.ID());
                                break;
                            }
                    }
                });
                return;
            }
        }
    }

    // invalid location info, return error directly
    m_ActorPod->Forward(rstMPK.From(), MPK_ERROR, rstMPK.ID());
}
Пример #2
0
void ServiceCore::On_MPK_QUERYMAPUID(const MessagePack &rstMPK)
{
    AMQueryMapUID stAMQMUID;
    std::memcpy(&stAMQMUID, rstMPK.Data(), sizeof(stAMQMUID));

    if(auto pMap = RetrieveMap(stAMQMUID.MapID)){
        AMUID stAMUID;
        std::memset(&stAMUID, 0, sizeof(stAMUID));

        stAMUID.UID = pMap->UID();
        m_ActorPod->Forward(rstMPK.From(), {MPK_UID, stAMUID}, rstMPK.ID());
    }else{
        m_ActorPod->Forward(rstMPK.From(), MPK_ERROR, rstMPK.ID());
    }
}
Пример #3
0
void ServiceCore::On_MPK_QUERYMAPLIST(const MessagePack &rstMPK)
{
    AMMapList stAMML;
    std::memset(&stAMML, 0, sizeof(stAMML));

    size_t nIndex = 0;
    for(auto pMap: m_MapList){
        if(pMap.second && pMap.second->ID()){
            if(nIndex < (sizeof(stAMML.MapList) / sizeof(stAMML.MapList[0]))){
                stAMML.MapList[nIndex++] = pMap.second->ID();
            }else{
                extern MonoServer *g_MonoServer;
                g_MonoServer->AddLog(LOGTYPE_FATAL, "Need larger map list size in AMMapList");
                g_MonoServer->Restart();
            }
        }
    }
    m_ActorPod->Forward(rstMPK.From(), {MPK_MAPLIST, stAMML}, rstMPK.ID());
}
Пример #4
0
void ServiceCore::On_MPK_QUERYCOCOUNT(const MessagePack &rstMPK)
{
    AMQueryCOCount stAMQCOC;
    std::memcpy(&stAMQCOC, rstMPK.Data(), sizeof(stAMQCOC));

    int nCheckCount = 0;
    if(stAMQCOC.MapID){
        if(m_MapList.find(stAMQCOC.MapID) == m_MapList.end()){
            nCheckCount = 0;
        }else{
            nCheckCount = 1;
        }
    }else{
        nCheckCount = (int)(m_MapList.size());
    }

    switch(nCheckCount){
        case 0:
            {
                m_ActorPod->Forward(rstMPK.From(), MPK_ERROR, rstMPK.ID());
                return;
            }
        case 1:
            {
                if(auto pMap = (stAMQCOC.MapID ? m_MapList[stAMQCOC.MapID] : m_MapList.begin()->second)){
                    m_ActorPod->Forward(pMap->UID(), {MPK_QUERYCOCOUNT, stAMQCOC}, [this, rstMPK](const MessagePack &rstRMPK)
                    {
                        switch(rstRMPK.Type()){
                            case MPK_COCOUNT:
                                {
                                    m_ActorPod->Forward(rstMPK.From(), {MPK_COCOUNT, rstRMPK.Data(), rstRMPK.DataLen()}, rstMPK.ID());
                                    return;
                                }
                            case MPK_ERROR:
                            default:
                                {
                                    m_ActorPod->Forward(rstMPK.From(), MPK_ERROR, rstMPK.ID());
                                    return;
                                }
                        }
                    });
                    return;
                }else{
                    m_MapList.erase(stAMQCOC.MapID);
                    m_ActorPod->Forward(rstMPK.From(), MPK_ERROR, rstMPK.ID());
                    return;
                }
            }
        default:
            {
                // difficult part
                // need send multiple query message and collect them
                // after all collected we need to return the sum, problem:
                // 1. share state
                // 2. error handle

                struct SharedState
                {
                    bool Done;
                    int  CheckCount;
                    int  COCount;

                    SharedState(int nCheckCount)
                        : Done(false)
                        , CheckCount(nCheckCount)
                        , COCount(0)
                    {}
                };

                // current I don't have error handling
                // means if one query didn't get responded it will wait forever
                // to solve this issue, we can install an state hook but for simplity not now

                auto pSharedState = std::make_shared<SharedState>(nCheckCount);
                auto fnOnResp = [pSharedState, this, rstMPK](const MessagePack &rstRMPK)
                {
                    switch(rstRMPK.Type()){
                        case MPK_COCOUNT:
                            {
                                if(pSharedState->Done){
                                    // we get response but shared state shows ``done"
                                    // means more than one error has alreay happened before
                                    // do nothing
                                }else{
                                    // get one more valid response
                                    // need to check if we need to response to sender
                                    AMCOCount stAMCOC;
                                    std::memcpy(&stAMCOC, rstRMPK.Data(), sizeof(stAMCOC));

                                    if(pSharedState->CheckCount == 1){
                                        stAMCOC.Count += pSharedState->COCount;
                                        m_ActorPod->Forward(rstMPK.From(), {MPK_COCOUNT, stAMCOC}, rstMPK.ID());
                                    }else{
                                        pSharedState->CheckCount--;
                                        pSharedState->COCount += (int)(stAMCOC.Count);
                                    }
                                }
                                return;
                            }
                        case MPK_ERROR:
                        default:
                            {
                                if(pSharedState->Done){
                                    // we get response but shared state shows ``done"
                                    // means more than one error has alreay happened before
                                    // do nothing
                                }else{
                                    // get first error
                                    m_ActorPod->Forward(rstMPK.From(), MPK_ERROR, rstMPK.ID());
                                }
                                return;
                            }
                    }
                };

                for(auto p: m_MapList){
                    m_ActorPod->Forward(p.second->UID(), {MPK_QUERYCOCOUNT, stAMQCOC}, fnOnResp);
                }
                return;
            }
    }
}