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

📄 msgaction.cpp

📁 网络游戏魔域的服务端与客户端完整源代码 包括详细的说明文档与开发日志
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// MsgAction.cpp: implementation of the CMsgAction class.
//
//////////////////////////////////////////////////////////////////////
#include "AllMsg.h"
#include "mapgroup.h"
#include "transformation.h"
#include "Agent.h"
#include "MercenaryTask.h"
#include "User.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMsgAction::CMsgAction()
{
	Init();
	m_pInfo	=(MSG_Info *)m_bufMsg;
}

CMsgAction::~CMsgAction()
{

}

//////////////////////////////////////////////////////////////////////
BOOL CMsgAction::Create(OBJID idPlayer, int nPosX, int nPosY, USHORT usDir, USHORT usAction, DWORD dwData)
{
	DEBUG_CREATEMSG("ACTION",idPlayer,usAction,"",usDir,0);

	// param check
	if (idPlayer == ID_NONE)
		return false;

	// init
	this->Init();

	// fill info now
	m_unMsgSize	=sizeof(MSG_Info);
	m_unMsgType	=_MSG_ACTION;
	m_pInfo->dwTimeStamp=::TimeGet();	

	m_pInfo->idUser		=idPlayer;
	m_pInfo->unPosX		=(USHORT)nPosX;
	m_pInfo->unPosY		=(USHORT)nPosY;
	m_pInfo->unDir		=usDir;
	m_pInfo->dwData		=dwData;
	m_pInfo->usAction	=usAction;

	return true;
}

//////////////////////////////////////////////////////////////////////
BOOL CMsgAction::Create(OBJID idPlayer, int nPosX, int nPosY, USHORT usDir, USHORT usAction, USHORT usTargetPosX, USHORT usTargetPosY)
{
	DEBUG_CREATEMSG("ACTION",idPlayer,usAction,"",usDir,0);

	// param check
	if (idPlayer == ID_NONE)
		return false;

	// init
	this->Init();

	// fill info now
	m_unMsgSize	=sizeof(MSG_Info);
	m_unMsgType	=_MSG_ACTION;
	m_pInfo->dwTimeStamp=::TimeGet();	

	m_pInfo->idUser		=idPlayer;
	m_pInfo->unPosX		=(USHORT)nPosX;
	m_pInfo->unPosY		=(USHORT)nPosY;
	m_pInfo->unDir		=usDir;
	m_pInfo->usAction	=usAction;

	m_pInfo->usTargetPosX	=usTargetPosX;
	m_pInfo->usTargetPosY	=usTargetPosY;

	return true;
}

//////////////////////////////////////////////////////////////////////
BOOL CMsgAction::Create(char* pbufMsg, DWORD dwMsgSize)
{
	if (!CNetMsg::Create(pbufMsg, dwMsgSize))
		return false;

	if(_MSG_ACTION != this->GetType())
		return false;

	return true;
}

//////////////////////////////////////////////////////////////////////
void CMsgAction::Process(void *pInfo)
{
#ifdef _MSGDEBUG
	::LogMsg("Process CMsgAction, idUser:%u, data:%u",
					m_pInfo->idUser,
					m_pInfo->dwData);
#endif
//	DEBUG_PROCESSMSG("ACTION",m_pInfo->idUser,m_pInfo->usAction,"",m_pInfo->unDir,0);

	// get obj
	IRole* pRole	= RoleManager()->QueryRole(this, m_pInfo->idUser);
	if (!pRole)
	{
		if(IsNpcMsg())
			return;

		// TransmitMsg
		switch(m_pInfo->usAction)
		{
		case actionQueryFriendInfo:
			{
				CUser* pTarget = UserManager()->GetUser(m_pInfo->idTarget);
				if(pTarget)
				{
					CMsgFriendInfo	msg;
					IF_OK(msg.Create(_FRIEND_INFO, pTarget->GetID(), pTarget->GetLookFace(), pTarget->GetLev(), 
							pTarget->GetProfession(), pTarget->GetPk(), pTarget->GetSynID(), pTarget->GetSynRankShow(), 
							pTarget->GetMate(), pTarget->GetNobilityRank()))
						SendMsg(&msg);
				}
			}
			break;
		case actionQueryEnemyInfo:
			{
				CUser* pTarget = UserManager()->GetUser(m_pInfo->idTarget);
				if(pTarget)
				{
					CMsgFriendInfo	msg;
					IF_OK(msg.Create(_ENEMY_INFO, pTarget->GetID(), pTarget->GetLookFace(), pTarget->GetLev(), 
							pTarget->GetProfession(), pTarget->GetPk(), pTarget->GetSynID(), pTarget->GetSynRankShow(), 
							pTarget->GetMate(), pTarget->GetNobilityRank()))
						SendMsg(&msg);
				}
			}
			break;
		case actionQueryStudentsOfStudent:
			{
				CUser* pStudent = UserManager()->GetUser(m_pInfo->idTarget);
				if (pStudent)
				{
					CMsgSchoolMember	msg;
					msg.Create(MESSAGEBOARD_ADDMEMBER, NULL, 0);

					for (int i=0; i<pStudent->GetStudentAmount(); i++)
					{
						CTutor* pTutor = pStudent->GetStudentByIndex(i);
						if (pTutor)
						{
							CUser* pTarget = UserManager()->GetUser(pTutor->GetUserID());
							if (pTarget)
								msg.Append(RELATION_STUDENTOFSTUDENT, MEMBERSTATUS_ONLINE, pTarget);
							else
								msg.Append(RELATION_STUDENTOFSTUDENT, MEMBERSTATUS_OFFLINE, pTutor->GetUserID(), pTutor->GetUserName());
						}
					}
					if (pStudent->GetStudentAmount() > 0)
						SendMsg(&msg);
				}
			}
			break;
		}
		return;
	}

	CUser* pUser = NULL;
	pRole->QueryObj(OBJ_USER, IPP_OF(pUser));

	// fill id
	if(m_pInfo->usAction != actionXpCLear)
		m_pInfo->idUser	= pRole->GetID();

	// stop fight
	switch(m_pInfo->usAction)
	{
	case actionQueryFriendInfo:
	case actionQueryEnemyInfo:
	case actionQueryLeaveWord:
	case actionQueryPlayer:
	case actionXpCLear:
	case actionQueryCryOut:
	case actionQueryTeamMember:
	case actionQueryEquipment:
	case actionQuerySynInfo:
		break;

	default:
		pRole->ClrAttackTarget();
		break;
	}

	// actions...
	DEBUG_TRY	// VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
	switch(m_pInfo->usAction)
	{
	case actionQueryTeamMember:
		{
			if (pUser)
			{
				CUser* pTarget = UserManager()->GetUser(m_pInfo->idTarget);
				if (pTarget && pTarget->GetMapID() == pUser->GetMapID())
				{
					CMsgAction msg;
					IF_OK (msg.Create(m_pInfo->idUser, pTarget->GetPosX(), pTarget->GetPosY(), 0, actionQueryTeamMember, m_pInfo->idTarget))
						pUser->SendMsg(&msg);
				}
			}
		}
		break;

	case actionQueryPlayer:
		{
			if (pUser)
			{
				IRole* pRole = pUser->FindAroundRole(m_pInfo->idTarget);
				if (pRole)
				{
					if (pRole->GetDistance(pUser->GetPosX(), pUser->GetPosY()) <= CELLS_PER_VIEW)
					{
						pRole->QueryMapThing()->SendShow(pUser->QueryRole());
					}
				}
				if(pUser->IsGM())
				{
					pUser->SendSysMsg("actionQueryPlayer: [%d]", m_pInfo->idTarget);
					if(pRole)
						pUser->SendSysMsg("target: [%s][%d], pos: [%d][%d]", pRole->GetName(), pRole->GetID(), pRole->GetPosX(), pRole->GetPosY());
#ifdef	PALED_DEBUG
					LOGERROR("actionQueryPlayer: [%d]", m_pInfo->idTarget);
					if(pRole)
					{
						LOGERROR("target: [%s][%d], pos: [%d][%d]", pRole->GetName(), pRole->GetID(), pRole->GetPosX(), pRole->GetPosY());
					}
					//ASSERT(!"actionQueryPlayer");
#endif
				}
			}
		}
		break;

/*
	case actionMine:
		{
			if (pUser)
			{
				if (!pUser->IsAlive())
				{
					pUser->SendSysMsg(STR_DIE);
					return;
				}

				if (!pUser->GetMap()->IsMineField())
				{
					pUser->SendSysMsg(STR_NO_MINE);
					return;
				}

				pUser->Mine();
			}
		}
		break;
*/

	case actionChangeFace:
		{
			if (pUser)
			{
				// spend money
				if (!pUser->SpendMoney(500, true))
				{
					pUser->SendSysMsg(STR_NOT_SO_MUCH_MONEY);
					return;
				}

				// set face
				pUser->SetFace(m_pInfo->dwData);

				// to self
				pUser->BroadcastRoomMsg(this, true);

				// to team
				CTeam* pTeam = pUser->GetTeam();
				if (pTeam)
					pTeam->BroadcastTeamMsg(this, pUser);
			}
		}
		break;
	case actionChgDir:
		{
			pRole->SetDir(m_pInfo->unDir);
			pRole->BroadcastRoomMsg(this, EXCLUDE_SELF);
		}
		break;
	case actionPosition:
		{
		}
		break;
	case actionEmotion:
		{
			if (pUser)
			{
				pRole->SetPose(m_pInfo->dwData);

				if (_ACTION_COOL == m_pInfo->dwData)
				{
					if (::TimeGet()-pUser->m_dwLastCoolShow > 3000)
					{
						if (pUser->IsAllNonsuchEquip())
							m_pInfo->dwData	|= (pUser->GetProfession()*0x00010000 + 0x01000000);
						else if ((pUser->GetArmorTypeID()%10) == 9)
							m_pInfo->dwData |= pUser->GetProfession()*0x010000;

						pUser->m_dwLastCoolShow = ::TimeGet();
					}
				}
#if	defined(PALED_DEBUG)
				if(m_pInfo->dwData >= 1 && m_pInfo->dwData <= 10)		// 1: default dance, <10: dance emotion
					pUser->GetMap()->BroadcastDance(pUser, m_pInfo->dwData);
				else
#endif
				pRole->BroadcastRoomMsg(this, INCLUDE_SELF);
			}
		}
		break;
	case actionBroadcastPos:
		{
			//pRole->BroadcastRoomMsg(this, EXCLUDE_SELF);
		}
		break;
	case actionDivorce:
		{
			ASSERT(!"仅下传此消息");
		}
		break;
	case actionChgMap:
		{
			if (pUser && !pUser->IsAlive())
			{
					pUser->SendSysMsg(STR_DIE);
					return;
			}

			if(!pUser)
				break;
			pRole->ProcessOnMove(MOVEMODE_CHGMAP);
			pUser->ChangeMap();				// 注意:没有回应actionChgMap,而是回应actionFlyMap. call - may be delete this;
		}
		break;
	case actionFlyMap:
		{
			if (pUser && !pUser->IsAlive())
			{
					pUser->SendSysMsg(STR_DIE);
					return;
			}

			ASSERT(!"actionFlyMap");		// 好象不应该支持吧?
			return ;//////////////////////////////////////////////////

			if(!pUser)
				break;
			pRole->ProcessOnMove(MOVEMODE_CHGMAP);
			OBJID idMap = m_pInfo->idTarget;
			pUser->FlyMap(idMap, m_pInfo->unPosX, m_pInfo->unPosY);		// 回应actionFlyMap. call - may be delete this;
		}
		break;
	case actionChgWeather:
		{
			ASSERT(!"仅下传此消息");
		}
		break;
	case actionFireworks:
		{
			pRole->BroadcastRoomMsg(this, EXCLUDE_SELF);
		}
		break;
	case actionDie:
		{
			// 自杀
			CMonster* pMonster;
			if(pRole->QueryObj(OBJ_MONSTER, IPP_OF(pMonster)))
			{
				if(!pMonster->IsDeleted())
				{
					pMonster->DelMonster();
				}
			}
			else if(pUser)
			{
				pUser->AddAttrib(_USERATTRIB_LIFE, -1*pUser->GetLife(), SYNCHRO_FALSE);
				pUser->AddAttrib(_USERATTRIB_MANA, -1*(pUser->GetMana()/2), SYNCHRO_TRUE);
				pUser->BroadcastRoomMsg(this, EXCLUDE_SELF);

				UserManager()->KickOutSocket(this->GetSocketID(), "玩家自杀");
			}
		}
		break;
	case actionQuitSyn:
		{
		}
		break;
	case actionWalk:
	case actionRun:
		{
		}
		break;
	case actionEnterMap:			// 1
		{
			if(pUser)
			{
				OBJID idMapDoc = ID_NONE;
				CGameMap* pMap = MapManager()->QueryMap(pUser->GetMapID());
				IF_OK (pMap)
				{
					idMapDoc = pMap->GetDocID();

					CMsgAction	msg;
					if(msg.Create(pUser->GetMapID(), pUser->GetPosX(), pUser->GetPosY(), pUser->GetDir(), actionEnterMap, idMapDoc))
						SendMsg(&msg);		// can't send to other user, because have not user id.

					pUser->EnterMap();
					if(!pUser->IsAgent())
						MapGroup(PID)->QueryIntraMsg()->QueryFee(pUser->GetAccountID());
				}
				else
				{
					LOGERROR("Error: invalid map id[%u] of user:%u", pUser->GetMapID(), pUser->GetID());
				}
			}
		}
		break;
	case actionGetItemSet:			// 2
		{
			if(!pUser)
				break;
			pUser->SendItemSet();

			// bonus
			pUser->SendBonusInfo();

			CMsgAction	msg;
			if(msg.Create(pUser->GetID(), 0, 0, 0, actionGetItemSet, 0, 0))
				SendMsg(&msg);
		}
		break;
	case actionGetGoodFriend:		// 3
		{
			if(!pUser)
				break;
			CMsgAction	msg;
			if(msg.Create(pUser->GetID(), 0, 0, 0, actionGetGoodFriend, 0, 0))
				SendMsg(&msg);

			pUser->SendGoodFriend();
			pUser->QueryEnemy()->SendToClient();

			LeaveWord()->ShowWords(pUser);
		}
		break;
	case actionGetWeaponSkillSet:	// 4
		{
			if(!pUser)
				break;
			CMsgAction	msg;
			if(msg.Create(pUser->GetID(), 0, 0, 0, actionGetWeaponSkillSet, 0, 0))
				SendMsg(&msg);

			pUser->SendAllWeaponSkillInfo();
		}
		break;
	case actionGetMagicSet:			// 5
		{
			if(!pUser)
				break;
			CMsgAction	msg;
			if(msg.Create(pUser->GetID(), 0, 0, 0, actionGetMagicSet, 0, 0))
				SendMsg(&msg);

			pUser->SendAllMagicInfo();
			pUser->QuerySupermanSecs();
		}
		break;
	case actionGetSynAttr:			// 6
		{
			if(!pUser)
				break;
			CMsgAction	msg;
			if(msg.Create(pUser->GetID(), 0, 0, 0, actionGetSynAttr, 0, 0))
				SendMsg(&msg);

			pUser->QuerySynAttr()->SendInfoToClient();

			// 帮派部分
			CSynPtr pSyn = SynManager()->QuerySyndicate(pUser->GetSynID());
			if(pSyn)
			{
				pSyn = pSyn->GetMasterSyn();
				pSyn->SendInfoToClient(pUser);
			}

			if(pSyn && pSyn->GetInt(SYNDATA_MONEY) <= 0)
				pUser->SendSysMsg(_TXTATR_GM, STR_DESTROY_SYNDICATE_SOON);

			// syn map owner
			OBJID idSyn = _SynManager(PID)->GetMapSynID(WHITE_SYN_MAP_ID);
			if(idSyn != ID_NONE)
			{
				CMsgSyndicate	msg;
				IF_OK(msg.Create(SET_WHITE_SYN, idSyn))
					pUser->SendMsg(&msg);
			}
			 idSyn = _SynManager(PID)->GetMapSynID(BLACK_SYN_MAP_ID);
			if(idSyn != ID_NONE)
			{
				CMsgSyndicate	msg;
				IF_OK(msg.Create(SET_BLACK_SYN, idSyn))
					pUser->SendMsg(&msg);
			}
		}
		break;
	case actionQuerySchoolMember:	// 7
		{
			if (!pUser)
				break;
//			CMsgAction	msg;
//			if(msg.Create(pUser->GetID(), 0, 0, 0, actionQuerySchoolMember, 0, 0))
//				SendMsg(&msg);
			pUser->SendTutorInfo();
		}
		break;
	case actionForward:
		{
			/*/ 测试 PALED_DEBUG
			{
				char	szText[1024];
				sprintf(szText, "MsgAction: forword, dir[%d], x[%d], y[%d]", m_pInfo->unDir, m_pInfo->unPosX, m_pInfo->unPosY);
				CMsgTalk msg;
				if(msg.Create("测试", "测试", szText))
					pRole->SendMsg(&msg);
			}
			//*/
#ifdef	FW_ENABLE
				if (this->Create(pRole->GetID(), pRole->GetPosX(), pRole->GetPosY(), pRole->GetDir(), actionPosition))
					pRole->BroadcastRoomMsg(this, EXCLUDE_SELF);
			if (pRole->MoveToward(m_pInfo->unDir))		// return true: 是n步模数
			{
				//if (this->Create(pRole->GetID(), m_pInfo->unPosX, m_pInfo->unPosY, m_pInfo->unDir, actionPosition))

				// 回送
				m_pInfo->unPosX	= pRole->GetPosX();
				m_pInfo->unPosY	= pRole->GetPosY();
				pRole->SendMsg(this);		
			}
#endif
		}
		break;

	case actionJump:
		{
			if (pUser)
			{
				pUser->m_dwLastJump = m_pInfo->dwTimeStamp;

				if (!pUser->IsAlive())
				{
					pUser->SendSysMsg(STR_DIE);
					return;
				}

				if (!pUser->IsGM() && pUser->GetDistance(m_pInfo->usTargetPosX, m_pInfo->usTargetPosY) >= 2*CELLS_PER_BLOCK)
				{
					pUser->SendSysMsg(STR_INVALID_MSG);
					UserManager()->KickOutSocket(m_idSocket, "Jump 超远");
					return;
				}
				if (pUser->QueryTransformation() && !pUser->QueryTransformation()->IsJumpEnable())		// BUG: 刚变时,客户端还没禁跳
				{
					UserManager()->KickOutSocket(m_idSocket, "不能跳!");
					return;
				}
			}

			//if (pRole->AddAttrib(_USERATTRIB_MANA, -10, SYNCHRO_TRUE))
			{
				pRole->BroadcastRoomMsg(this, INCLUDE_SELF);

				//if(pUser && !pUser->IsJumpPass(m_pInfo->usTargetPosX, m_pInfo->usTargetPosY, pUser->IsWing() ? FLY_ALT : JUMP_ALT))
				//	pUser->KickBack();

				if(pRole->GetDistance(m_pInfo->usTargetPosX, m_pInfo->usTargetPosY) >= CELLS_PER_BLOCK)
				{
					pRole->ProcessOnMove(MOVEMODE_TRANS);			//@@@ 临时代码,不应该跳这么远。
					pRole->TransPos(m_pInfo->usTargetPosX, m_pInfo->usTargetPosY);
				}
				else
				{
					pRole->ProcessOnMove(MOVEMODE_JUMP);
					pRole->JumpPos(m_pInfo->usTargetPosX, m_pInfo->usTargetPosY);
				}
			}
		}
		break;
	case actionSynchro:
		{
			if (pUser && pUser->IsAlive())		// IsAlive: 打飞
			{
				if(pUser->IsSynchro())
				{
					LOGERROR("★Receive synchro msg when no flag!!![%s]", pUser->GetName());
				}
				pUser->SetSynchro(true);
			}

			if (pRole->GetPosX() != m_pInfo->usTargetPosX || pRole->GetPosY() != m_pInfo->usTargetPosY)
			{
				pRole->BroadcastRoomMsg(this, EXCLUDE_SELF);

				if(pRole->GetDistance(m_pInfo->usTargetPosX, m_pInfo->usTargetPosY) >= CELLS_PER_BLOCK)
				{
					pRole->ProcessOnMove(MOVEMODE_SYNCHRO);			//@@@ 临时代码,不应该跳这么远。
					pRole->TransPos(m_pInfo->usTargetPosX, m_pInfo->usTargetPosY);
				}
				else

⌨️ 快捷键说明

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