示例#1
0
void CClientMgr::SendMsg(CClient *cl, google::protobuf::Message &pMsg, int32 maintype, int32 subtype)
{
	assert(cl != nullptr);

	MessagePack pk;
	pk.Pack(&pMsg, maintype, subtype);
	cl->SendMsg(&pk);
}
示例#2
0
void ServiceCore::OperateAM(const MessagePack &rstMPK)
{
    switch(rstMPK.Type()){
        case MPK_BADCHANNEL:
            {
                On_MPK_BADCHANNEL(rstMPK);
                break;
            }
        case MPK_METRONOME:
            {
                On_MPK_METRONOME(rstMPK);
                break;
            }
        case MPK_ADDCHAROBJECT:
            {
                On_MPK_ADDCHAROBJECT(rstMPK);
                break;
            }
        case MPK_TRYMAPSWITCH:
            {
                On_MPK_TRYMAPSWITCH(rstMPK);
                break;
            }
        case MPK_NETPACKAGE:
            {
                On_MPK_NETPACKAGE(rstMPK);
                break;
            }
        case MPK_QUERYMAPLIST:
            {
                On_MPK_QUERYMAPLIST(rstMPK);
                break;
            }
        case MPK_QUERYCOCOUNT:
            {
                On_MPK_QUERYCOCOUNT(rstMPK);
                break;
            }
        case MPK_QUERYMAPUID:
            {
                On_MPK_QUERYMAPUID(rstMPK);
                break;
            }
        default:
            {
                extern MonoServer *g_MonoServer;
                g_MonoServer->AddLog(LOGTYPE_WARNING, "Unsupported message: %s", rstMPK.Name());
                break;
            }
    }
}
示例#3
0
static void back_dofunction(lxnet::Socketer *sock)
{
	MessagePack *pack;
	char commandstr[32];
	Msg *pmsg = sock->GetMsg();
	if (!pmsg)
		return;
	pack = (MessagePack *)pmsg;
	pack->Begin();
	pack->GetString(commandstr, sizeof(commandstr));
	commandstr[sizeof(commandstr) - 1] = 0;

	ProcessCommand(sock, commandstr);
}
示例#4
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());
    }
}
示例#5
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());
}
示例#6
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());
}
示例#7
0
void ServiceCore::On_MPK_BADCHANNEL(const MessagePack &rstMPK)
{
    // channel may go down before bind to one actor
    // then stop it here

    AMBadChannel stAMBC;
    std::memcpy(&stAMBC, rstMPK.Data(), sizeof(stAMBC));

    extern NetDriver *g_NetDriver;
    g_NetDriver->Shutdown(stAMBC.ChannID, false);
}
示例#8
0
void ServiceCore::On_MPK_TRYMAPSWITCH(const MessagePack &rstMPK)
{
    AMTryMapSwitch stAMTMS;
    std::memcpy(&stAMTMS, rstMPK.Data(), sizeof(stAMTMS));

    if(stAMTMS.MapID){
        if(auto pMap = RetrieveMap(stAMTMS.MapID)){
            m_ActorPod->Forward(pMap->UID(), {MPK_TRYMAPSWITCH, stAMTMS});
        }
    }
}
示例#9
0
void CClientMgr::SendMsg(int32 clientid, google::protobuf::Message &pMsg, int32 maintype, int32 subtype)
{
	if (clientid > 0)
	{
		CClient *cl = FindClientByClientID(clientid);
		if (cl)
		{
			MessagePack pk;
			pk.Pack(&pMsg, maintype, subtype);
			cl->SendMsg(&pk);
		}
	}
	else
	{
		MessagePack pk;
		pk.Pack(&pMsg, maintype, subtype);

		std::list<CClient*>::iterator _Iter = m_ClientList.begin();
		for (; _Iter != m_ClientList.end(); ++_Iter)
			(*_Iter)->SendMsg(&pk);
	}

}
示例#10
0
// ServiceCore accepts net packages from *many* sessions and based on it to create
// the player object for a one to one map
//
// So servicecore <-> session is 1 to N, means we have to put put pointer of session
// in the net package otherwise we can't find the session even we have session's 
// address, session is a sync-driver, even we have it's address we can't find it
//
void ServiceCore::On_MPK_NETPACKAGE(const MessagePack &rstMPK)
{
    AMNetPackage stAMNP;
    std::memcpy(&stAMNP, rstMPK.Data(), sizeof(AMNetPackage));

    uint8_t *pDataBuf = nullptr;
    if(stAMNP.DataLen){
        if(stAMNP.Data){
            pDataBuf = stAMNP.Data;
        }else{
            pDataBuf = stAMNP.DataBuf;
        }
    }

    OperateNet(stAMNP.ChannID, stAMNP.Type, pDataBuf, stAMNP.DataLen);

    if(stAMNP.Data){
        delete [] stAMNP.Data;
    }
}
示例#11
0
void CBaseObj::SendRefMsg(Msg &pMsg)
{
	assert(m_GateIDMax < gateinfo_count);
	for (int i = m_GateIDMin; i <= m_GateIDMax; ++i)
	{
		gateinfo[i]->Reset();
	}

	static bool bNeeSendMsg = false;
	static msgtail tail;
	std::unordered_map<uint32, CBaseObj *> *playerlist = GetAoiList();
	std::unordered_map<uint32, CBaseObj *>::iterator iter = playerlist->begin();
	for (; iter != playerlist->end(); ++iter)
	{
		if (iter->second->IsPlayer())
		{
			CPlayer * p = (CPlayer *)iter->second;
			if (FuncUti::isValidCret(p))
			{
				int32 gateid = p->GetGateID();
				if (gateid >= 0 && gateid < gateinfo_count)
				{
					if (gateid > m_GateIDMax)
					{
						m_GateIDMax = gateid;
					}
					else if (gateid < m_GateIDMin)
					{
						m_GateIDMin = gateid;
					}

					if (gateinfo[gateid]->gate == nullptr)
					{
						gateinfo[gateid]->gate = p->GetGateInfo();
					}
					gateinfo[gateid]->nClientId[gateinfo[gateid]->nCount] = p->GetClientID();
					gateinfo[gateid]->nCount += 1;
				}
			}
		}
	}

	static bool bIsPlayer = false;
	bIsPlayer = IsPlayer();
	if (bNeeSendMsg || bIsPlayer)
	{
		if (bIsPlayer)
		{
			CPlayer *p = (CPlayer *)this;
			int32 gateid = p->GetGateID();
			if (gateid >= 0 && gateid < gateinfo_count)
			{
				if (gateid > m_GateIDMax)
				{
					m_GateIDMax = gateid;
				}
				else if (gateid < m_GateIDMin)
				{
					m_GateIDMin = gateid;
				}

				if (gateinfo[gateid]->gate == nullptr)
				{
					gateinfo[gateid]->gate = p->GetGateInfo();
				}

				gateinfo[gateid]->nClientId[gateinfo[gateid]->nCount] = p->GetClientID();
				gateinfo[gateid]->nCount += 1;
			}
		}

		bNeeSendMsg = false;
		MessagePack pkmain;
		pkmain.PushInt32(pMsg.GetLength());
		pkmain.PushBlock(&pMsg, pMsg.GetLength());
		int32 pkmainlen = pkmain.GetLength();

		for (int i = m_GateIDMin; i < m_GateIDMax; ++i)
		{
			if (gateinfo[i]->nCount > 0)
			{
				tail.id = 0;
				for (int j = 0; j < gateinfo[i]->nCount; ++j)
				{
					pkmain.PushInt32(gateinfo[i]->nClientId[j]);
					--tail.id;
				}
				GameGatewayMgr.SendMsg(gateinfo[i]->gate, pkmain, &tail, sizeof(tail));
				pkmain.SetLength(pkmainlen);
				pkmain.m_index = pkmainlen - (int32)sizeof(Msg);
			}
		}
	}
}
示例#12
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;
            }
    }
}
示例#13
0
static void ProcessCommand(lxnet::Socketer *sock, const char *commandstr)
{
	static char s_buf[32 * 1024];
	short size = 0;
	MessagePack res;
	if (strcmp(commandstr, "help") == 0)
	{
		snprintf(s_buf, sizeof(s_buf) - 1, "help 帮助\nopenelapsed/closeelapsed 打开/关闭帧开销实时日志\ncurrentinfo 输出当前信息\nnetmeminfo 输出网络库内存使用情况\nallmeminfo 输出此程序内存池使用信息到文件\n");
		size = static_cast<short>(strlen(s_buf)) + 1;
		s_buf[size] = 0;
		res.PushString(s_buf);
		sock->SendMsg(&res);
	}
	else if (strcmp(commandstr, "openelapsed") == 0)
	{
		g_elapsed_log_flag = true;

		snprintf(s_buf, sizeof(s_buf) - 1, "帧开销实时日志已打开");
		size = static_cast<short>(strlen(s_buf)) + 1;
		s_buf[size] = 0;
		res.PushString(s_buf);
		sock->SendMsg(&res);
	}
	else if (strcmp(commandstr, "closeelapsed") == 0)
	{
		g_elapsed_log_flag = false;

		snprintf(s_buf, sizeof(s_buf) - 1, "帧开销实时日志已关闭");
		size = static_cast<short>(strlen(s_buf)) + 1;
		s_buf[size] = 0;
		res.PushString(s_buf);
		sock->SendMsg(&res);
	}
	else if (strcmp(commandstr, "currentinfo") == 0)
	{
		size = 0;

		DBCenterConnect.GetCurrentInfo(&s_buf[size], sizeof(s_buf) - size - 1);
		size = static_cast<short>(strlen(s_buf));
		DBCenterConnect.GetDataHandInfo(&s_buf[size], sizeof(s_buf) - size - 1);
		size = static_cast<short>(strlen(s_buf));
		DBCache.GetCurrentInfo(&s_buf[size], sizeof(s_buf) - size - 1);
		s_buf[sizeof(s_buf) - 1] = 0;
		res.PushString(s_buf);
		sock->SendMsg(&res);
	}
	else if (strcmp(commandstr, "netmeminfo") == 0)
	{
		snprintf(s_buf, sizeof(s_buf) - 1, "%s", lxnet::net_get_memory_info(s_buf, sizeof(s_buf) - 1));
		size = static_cast<short>(strlen(s_buf)) + 1;
		s_buf[size] = 0;
		res.PushString(s_buf);
		sock->SendMsg(&res);
	}
	else if (strcmp(commandstr, "allmeminfo") == 0)
	{
		sPoolInfo.writeinfotofile();

		snprintf(s_buf, sizeof(s_buf) - 1, "所有内存信息已经写入到文件");
		size = static_cast<short>(strlen(s_buf)) + 1;
		s_buf[size] = 0;
		res.PushString(s_buf);
		sock->SendMsg(&res);
	}
	else
	{
		res.PushString(commandstr);
		sock->SendMsg(&res);
	}
}
示例#14
0
文件: listen.cpp 项目: Manhelp/lxnet
int main()
{
	if(!lxnet::net_init(512, 1, 1024*32, 100, 1, 4, 1))
	{
		printf("init network error!\n");
		system("pause");
		return 0;
	}

	lxnet::Listener *list = lxnet::Listener::Create();
	if (!list->Listen(30012, 10))
	{
		printf("listen error\n");
	}
	if (list)
	{
		MessagePack sendpack;
		MessagePack *recvpack;
		char neirong[1024*30]="a1234567";
		//char recvneirong[32*1024];
		int size = sizeof(neirong);
		sendpack.PushBlock(neirong, size);


		printf("listen succeed!\n");
		lxnet::Socketer *newclient = NULL;
		while (1)
		{
#ifdef WIN32
			Sleep(100);
#else
			usleep(100000);
#endif
			lxnet::net_run();
			if (!list->CanAccept())
				continue;
			if (!(newclient = list->Accept()))
				continue;

			printf("accept succeed!\n");
			//newclient->UseCompress();
			//newclient->UseUncompress();
			//newclient->UseDecrypt();
			//newclient->UseEncrypt();
			newclient->SetSendLimit(-1);
			//newclient->SetRecvLimit(16*1024);

			newclient->CheckRecv();
			while(1)
			{
				recvpack = (MessagePack *)newclient->GetMsg();
				if (recvpack)
				{
					//recvpack->Begin();
					//recvpack->GetBlock(recvneirong, size);
					//if (memcmp(recvneirong, neirong, size) != 0)
					//{
					//	printf("data error!\n");
					//	system("pause");
					//}
					newclient->SendMsg(&sendpack);
					newclient->CheckSend();
				}
				else
#ifdef WIN32
					Sleep(0);
#else
					sleep(0);
#endif

				lxnet::net_run();
				if (newclient->IsClose())
				{
					system("pause");
					lxnet::Socketer::Release(newclient);
					goto s_exit;
				}
			}
		}
	}
	else
	{
		printf("listen failed!\n");
	}

s_exit:
	system("pause");
	printf("begin ... release..\n");
#ifdef WIN32
	Sleep(1000);
#else
	usleep(1000000);
#endif
	lxnet::Listener::Release(list);
	lxnet::net_release();
	system("pause");
	return 0;
}