⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapgroupkernel.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// MapGroupKernel.cpp: implementation of the CMapGroupKernel class.
//
//////////////////////////////////////////////////////////////////////

#include "MessagePort.h"
#include "inifile.h"
#include "protocol.h"
#include "MapGroupKernel.h"
#include "NetMsg.h"
#include "BaseFunc.h"
#include "MapGroup.h"
#include "Npc.h"
#include "Agent.h"
#include "MsgSyndicate.h"
#include "DeadLoop.h"
#include "I_mydb.h"

MYHEAP_IMPLEMENTATION(CMapGroupKernel,s_heap)
//////////////////////////////////////////////////////////////////////
// interface
//////////////////////////////////////////////////////////////////////
bool CMapGroupKernel::Create(IMessagePort* pPort)
{
	m_pMsgPort		= pPort;
	m_idProcess		= m_pMsgPort->GetID();		// process id == msg_port_id
	m_pMsgPort->Open();
	ASSERT(m_idProcess >= MSGPORT_MAPGROUP_FIRST);

	// 初始化数据库
	char	DB_IP	[DBSTR_SIZE] = "";
	char	DB_USER	[DBSTR_SIZE] = "";
	char	DB_PW	[DBSTR_SIZE] = "";
	char	DB_DB	[DBSTR_SIZE] = "";
	CIniFile	ini(CONFIG_FILENAME, "Database");
	ini.GetString(DB_IP,	"DB_IP",	DBSTR_SIZE);
	ini.GetString(DB_USER,	"DB_USER",	DBSTR_SIZE);
	ini.GetString(DB_PW,	"DB_PW",	DBSTR_SIZE);
	ini.GetString(DB_DB,	"DB_DB",	DBSTR_SIZE);
	m_pDb = ::CreateDatabase(DB_IP, DB_USER, DB_PW, DB_DB);
	if(!m_pDb)
	{
		LOGERROR("数据库连接失败!");
		return false;
	}

	// TODO: 请在此添加初始化代码
	CMapGroup::AddMapGroup(m_pMsgPort->GetID());
	if(!MapGroup(m_pMsgPort->GetID())->Create(pPort->GetID(), this, m_pDb, m_pMsgPort))
	{
		MapGroup(m_pMsgPort->GetID())->Destroy();
		return false;
	}

	return true;		// return false : 创建失败,程序关闭。
}

//////////////////////////////////////////////////////////////////////
bool CMapGroupKernel::Release()
{
	// TODO: 请在此添加代码
	MapGroup(m_pMsgPort->GetID())->Destroy();
	SAFE_RELEASE(m_pDb);

	delete this;
	return true;		// return false : 无意义。
}

//////////////////////////////////////////////////////////////////////
bool CMapGroupKernel::ProcessMsg(OBJID idPacket, void* buf, int nType, int nFrom)
{
	switch(idPacket)
	{
	case	KERNEL_CLIENTMSG:
		{
			CLIENTMSG_PACKET0*	pMsg = (CLIENTMSG_PACKET0*)buf;
			SOCKET_ID	idSocket= pMsg->idSocket;
			OBJID	idMsg	= pMsg->idPacket;
			char*	pBuf	= pMsg->buf;
			int		nMsgLen	= pMsg->nSize;

			DEADLOOP_CHECK(PID, "KERNEL_CLIENTMSG: ")
			ProcessClientMsg(idSocket, idMsg, pBuf, nMsgLen);
		}
		break;
	case MAPGROUP_TRANSMITMSG_FORCHATROOM://聊天室消息
		{
			TRANSMSG_PACKET0*	pMsg = (TRANSMSG_PACKET0*)buf;
			SOCKET_ID	idSocket= pMsg->idSocket;
			OBJID		idNpc	= pMsg->idNpc;
			OBJID	idMsg	= pMsg->idPacket;
			char*	pBuf	= pMsg->buf;
			int		nMsgLen	= pMsg->nSize;
			int		nTrans	= pMsg->nTrans;

			DEADLOOP_CHECK(PID, "MAPGROUP_TRANSMITMSG: ")
			if(idSocket != SOCKET_NONE)
			{
				ProcessClientMsg(idSocket, idMsg, pBuf, nMsgLen, nTrans);
			}
		}
		break;
	case	MAPGROUP_TRANSMITMSG:
		{
			TRANSMSG_PACKET0*	pMsg = (TRANSMSG_PACKET0*)buf;
			SOCKET_ID	idSocket= pMsg->idSocket;
			OBJID		idNpc	= pMsg->idNpc;
			OBJID	idMsg	= pMsg->idPacket;
			char*	pBuf	= pMsg->buf;
			int		nMsgLen	= pMsg->nSize;
			int		nTrans	= pMsg->nTrans;

			DEADLOOP_CHECK(PID, "MAPGROUP_TRANSMITMSG: ")
			if(idSocket == SOCKET_NONE)
			{
				if(UserManager()->GetUser(idNpc) == NULL)
					ProcessNpcMsg(idNpc, idMsg, pBuf, nMsgLen, nTrans);
			}
			else
			{
				if(UserManager()->GetUserBySocketID(idSocket) == NULL)			//??? 玩家不在此地图组,防止自激!!!
					ProcessClientMsg(idSocket, idMsg, pBuf, nMsgLen, nTrans);
			}
		}
		break;
	case	MAPGROUP_REMOTECALL:
		{
			REMOTE_CALL0*	pInfo = (REMOTE_CALL0*)buf;
			CUser*	pUser = UserManager()->GetUser(pInfo->idUser);
			if(pUser)
			{
				DEADLOOP_CHECK(PID, "MAPGROUP_REMOTECALL: ")
				pUser->RemoteCall(pInfo);
			}
		}
		break;
	case	MAPGROUP_RPC:
		{
			DEBUG_TRY
			int	nMsgSize = nType;
			CEventPack	pack((char*)buf, nMsgSize);
			switch(pack.GetEventType())
			{
			case	OBJ_MAP:
				{
					CGameMap* pMap = MapManager()->QueryMap(pack.GetObjID());
					if(pMap)
						pMap->ProcessRpc(pack);
				}
				break;
			default:
				ASSERT(!"switch(MAPGROUP_RPC)");
			}
			DEBUG_CATCH("MAPGROUP_RPC")
		}
		break;
	case	KERNEL_NPCMSG:
		{
			NPCMSG_PACKET0*	pMsg = (NPCMSG_PACKET0*)buf;
			OBJID	idNpc	= pMsg->idNpc;
			OBJID	idMsg	= pMsg->idPacket;
			char*	pBuf	= pMsg->buf;
			int		nMsgLen	= pMsg->nSize;

			DEADLOOP_CHECK(PID, "KERNEL_NPCMSG: ")
			ProcessNpcMsg(idNpc, idMsg, pBuf, nMsgLen);
		}
		break;
	// TODO: 请在此添加内部消息处理代码
	case	KERNEL_CLOSEKERNEL:
		{
			SOCKET_ID	idSocket = *(SOCKET_ID*)buf;
			LOGDEBUG("DEBUG:地图组核心[%d]收到关闭核心消息,SOCKET_ID[%u]", PID, idSocket);

			DEBUG_TRY
			DEADLOOP_CHECK(PID, "KERNEL_CLOSEKERNEL: ")
#ifdef	NEW_LOGOUT
			if(UserManager()->IsLoginMapGroup(idSocket))	  // readme.txt(3-1), 否则不操作
			{
				g_UserManager.LogoutUser(idSocket);
				m_pMsgPort->Send(MSGPORT_WORLD, KERNEL_CLOSEKERNEL, VARTYPE_INT, &idSocket);	  // readme.txt(3-2)
			}
			else
			{
				m_pMsgPort->Send(m_idProcess-1, KERNEL_CLOSEKERNEL, VARTYPE_INT, &idSocket);	  // readme.txt(3-1)
			}
#else
			if(UserManager()->IsLoginMapGroup(idSocket))	  // readme.txt(3-1), 否则不操作
			{
				g_UserManager.LogoutUser(idSocket);
				m_pMsgPort->Send(MSGPORT_WORLD, WORLD_CLOSESOCKET, VARTYPE_INT, &idSocket);	  // readme.txt(3-2)
			}
#endif
			DEBUG_CATCH("KERNEL_CLOSEKERNEL")
		}
		break;
	case	MAPGROUP_LOGIN:
		{
			ST_LOGIN* pPacket = (ST_LOGIN*)buf;

			if(pPacket->idSocket == SOCKET_NONE)	// agent
			{
				DEBUG_TRY	// VVVVVVVVVVVVVV
				DEADLOOP_CHECK(PID, "MAPGROUP_LOGIN agent: ")
				CAgent* pAgent = UserManager()->CreateAgent(pPacket->idUser);
				IF_NOT(pAgent)
					break;

				CHANGE_NPCPROCESSID	buf;
				buf.idNpc		= pPacket->idUser;
				buf.idProcess	= m_idProcess;
				m_pMsgPort->Send(MSGPORT_SOCKET, SOCKET_SETNPCPROCESSID, STRUCT_TYPE(CHANGE_NPCPROCESSID), &buf);

				UserManager()->LoginAgent(pAgent);
				DEBUG_CATCH("LoginAgent")	//AAAAAAAAAAAAAAAAA@ temporary
			}
			else
			{
				DEBUG_TRY	// VVVVVVVVVVVVVV
				DEADLOOP_CHECK(PID, "MAPGROUP_LOGIN pUser: ")
				CUserPtr pUser = UserManager()->CreateUser(pPacket->idSocket, pPacket->idUser);
				IF_NOT(pUser)
					break;

				//? 必须先转PROCESS_ID
				CHANGE_USERDATA	obj;
				obj.idSocket	= pPacket->idSocket;
				obj.nData		= m_idProcess;
				m_pMsgPort->Send(MSGPORT_SOCKET, SOCKET_SETPROCESSID, STRUCT_TYPE(CHANGE_USERDATA), &obj);		// readme.txt(3-6)
				//@ 不需要再通知WORLDKERNEL(已经修改过了)

				g_UserManager.LoginUser(pPacket->idSocket, pUser);

				MapGroup(PID)->QueryMsgPort()->Send(MSGPORT_WORLD, WORLD_SENDTIME, VARTYPE_INT, &pPacket->idSocket);
				DEBUG_CATCH("LoginUser")	//AAAAAAAAAAAAAAAAA@ temporary
			}
		}
		break;
	case	MAPGROUP_BROADCASTMSG:
		{
			CLIENTMSG_PACKET0* pMsg = (CLIENTMSG_PACKET0*)buf;
			DEADLOOP_CHECK(PID, "MAPGROUP_BROADCASTMSG: ")

			BroadcastMapGroupMsg(pMsg->idSocket, pMsg->idPacket, pMsg->buf, pMsg->nSize);
		}
		break;

	case	MAPGROUP_SOCKETUSERINFO:			// 1: create user
		{
			ST_USERCHANGEMAPGORUP* pMsg = (ST_USERCHANGEMAPGORUP*)buf;
			DEADLOOP_CHECK(PID, "MAPGROUP_SOCKETUSERINFO: ")

			UserManager()->GetForMapGroup()->JoinMapGroup(pMsg->idSocket, &pMsg->info);

			//? 必须先通知, 再回送FLY消息
			CHANGE_USERDATA	st;
			st.idSocket		= pMsg->idSocket;
			st.nData		= m_idProcess;
			m_pMsgPort->Send(MSGPORT_SOCKET, SOCKET_SETPROCESSID, STRUCT_TYPE(CHANGE_USERDATA), &st);   // readme.txt (3-6)
			m_pMsgPort->Send(MSGPORT_WORLD, WORLD_SETPROCESSID, STRUCT_TYPE(CHANGE_USERDATA), &st);
		}
		break;

	case	MAPGROUP_SENDOBJINFO:				// 2: append info
		{
			CHANGEMAPGORUP_INFO0*	pInfo = (CHANGEMAPGORUP_INFO0*)buf;
			DEADLOOP_CHECK(PID, "MAPGROUP_SENDOBJINFO: ")

			CUserPtr pUser = UserManager()->GetUser(pInfo->idUser);
			if(pUser)
				pUser->AppendObjInfo((INFO_ID)pInfo->nInfoType, pInfo->info);
		}
		break;
	case	MAPGROUP_CHANGEMAPGROUP:			// 3: join map
		{
			ST_CHANGEMAPGROUP* pPacket = (ST_CHANGEMAPGROUP*)buf;
			DEADLOOP_CHECK(PID, "MAPGROUP_CHANGEMAPGROUP: ")

			CUserPtr pUser = UserManager()->GetUser(pPacket->idUser);
			if(pUser)
				pUser->JoinMap(pPacket->idMap, pPacket->nPosX, pPacket->nPosY);
		}
		break;
	case	MAPGROUP_DELALLMONSTER:
		{
			DEADLOOP_CHECK(PID, "DelAllMonster")
			NpcManager()->DelAllMonster();
		}
		break;
	case	MAPGROUP_LOADALLPET:
		{
			DEADLOOP_CHECK(PID, "LoadAllPet")
			RoleManager()->LoadAllPet();
		}
		break;
	case	MAPGROUP_CREATENEWNPC:
		{
			DEADLOOP_CHECK(PID, "MAPGROUP_CREATENEWNPC")
			ST_CREATENEWNPC* pPacket = (ST_CREATENEWNPC*)buf;
			NpcManager()->CreateMonster(pPacket);
		}
		break;
	case	MAPGROUP_CHANGETEAM:
		{
			ST_CHANGETEAM* pPacket = (ST_CHANGETEAM*)buf;
			switch(pPacket->nAction)
			{
			case	CHANGETEAM_ADD:
				{
					DEADLOOP_CHECK(PID, "MAPGROUP_CHANGETEAM: CHANGETEAM_ADD")
					CUserManager::Iterator pUser = UserManager()->NewEnum();
					while(pUser.Next())
					{
						if(pUser && pUser->GetTeam() && pUser->GetTeam()->GetID() == pPacket->idTeam)
							pUser->QueryChangeTeam()->AddTeamMember(pPacket->idUser);
					}
				}
				break;
			case	CHANGETEAM_DEL:
				{
					DEADLOOP_CHECK(PID, "MAPGROUP_CHANGETEAM: CHANGETEAM_DEL")
					CUserManager::Iterator pUser = UserManager()->NewEnum();
					while(pUser.Next())
					{
						if(pUser && pUser->GetTeam() && pUser->GetTeam()->GetID() == pPacket->idTeam)
							pUser->QueryChangeTeam()->DelTeamMember(pPacket->idUser);
					}
				}
				break;
			case	CHANGETEAM_DISMISS:
				{
					DEADLOOP_CHECK(PID, "MAPGROUP_CHANGETEAM: CHANGETEAM_DISMISS")
					CUserManager::Iterator pUser = UserManager()->NewEnum();
					while(pUser.Next())
					{
						if(pUser && pUser->GetTeam() && pUser->GetTeam()->GetID() == pPacket->idTeam)
							pUser->QueryChangeTeam()->DelTeam();
					}
				}
				break;
			case	CHANGETEAM_INFO:
				{
					DEADLOOP_CHECK(PID, "MAPGROUP_CHANGETEAM: CHANGETEAM_INFO")
					SOCKET_ID	idSocket	= pPacket->nData;
					OBJID		idAgent		= pPacket->idUser;
					CUserManager::Iterator pUser = UserManager()->NewEnum();
					while(pUser.Next())
					{
						if(pUser && pUser->GetTeam() && pUser->GetTeam()->GetID() == pPacket->idTeam)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -