Esempio n. 1
0
/**
 * 改变一个玩家的游戏房间
 *
 * @param pPlayer 要改变游戏房间的玩家
 */
bool RoomManager::ChangeGameRoom(Player *pPlayer)
{
	if(pPlayer == NULL ||
		m_RoomList.empty()) 
		return false;

	// 首先检测玩家当前的状态,如果玩家处于准备,等待,游戏中,掉线等状态时说明玩家已经在房间中,不能进入新的房间
	if(pPlayer->GetState() != PLAYERSTATE_NORAML)
		return false;

	// 得到原来玩家所在的房间
	Room *pSrcRoom = GetRoomById(pPlayer->GetRoomId());
	if(pSrcRoom == NULL || pSrcRoom->GetRoomState() != ROOMSTATE_WAITING) return false;

	// 向房间中其它用户发送用户离开消息
	CMolMessageOut out(IDD_MESSAGE_FRAME);
	out.writeShort(IDD_MESSAGE_LEAVE_ROOM);
	out.writeShort(pPlayer->GetID());

	ServerPlayerManager.SendMsgToEveryone(out);

	// 先处理用户在原来房间中离开消息
	pSrcRoom->OnProcessLeaveRoomMsg(pPlayer->GetRoomIndex());

	// 第一遍搜索当前房间中已经存在玩家在那里等待的房间
	bool state = false;

	m_RoomLock.Acquire();
	std::list<Room*>::iterator iter = m_RoomList.begin();
	for(;iter != m_RoomList.end();iter++)
	{
		if((*iter))
		{
			//(*iter)->UpdateAllPlayers();
			// 如果玩家不能满足房间要求的最少金币值,就不能进入房间
			if((*iter)->GetLastMoney() > pPlayer->GetMoney()) continue;

			if(!(*iter)->IsFull() &&
				(*iter)->GetPlayerCount() > 0 &&
				(*iter)->GetRoomState() != ROOMSTATE_GAMING)
			{
				// 找一个与原来不一样的房间
				if(pSrcRoom->GetID() != (*iter)->GetID())
				{
					//PlayerState oldstate = pPlayer->GetState();

					// 设置玩家状态为改变房间状态,这样可以防止服务器将玩家强行掉线
					//pPlayer->SetState(PLAYERSTATE_CHANGEROOM);

					// 先从原来的房间中删除这个玩家
					pSrcRoom->ClearPlayer(pPlayer);

					// 更新一下房间中的用户
					(*iter)->UpdateOnlinePlayers();

					pPlayer->SetRoomId((*iter)->GetID());
					//pPlayer->SetState(oldstate);
					
					int playerIndex = (*iter)->AddPlayer(pPlayer);
					pPlayer->SetRoomIndex(playerIndex);					

					state = true;
					break;
				}
			}
		}
	}	
	m_RoomLock.Release();

	if(state) return state;

	// 第二遍搜索当前房间中没有坐满的房间或者空房间
	state = false;

	m_RoomLock.Acquire();
	iter = m_RoomList.begin();
	for(;iter != m_RoomList.end();iter++)
	{
		if((*iter))
		{
			//(*iter)->UpdateAllPlayers();
			// 如果玩家不能满足房间要求的最少金币值,就不能进入房间
			if((*iter)->GetLastMoney() > pPlayer->GetMoney()) continue;

			if(!(*iter)->IsFull() &&
				(*iter)->GetRoomState() != ROOMSTATE_GAMING)
			{
				// 找一个与原来不一样的房间
				if(pSrcRoom->GetID() != (*iter)->GetID())
				{
					//PlayerState oldstate = pPlayer->GetState();

					// 设置玩家状态为改变房间状态,这样可以防止服务器将玩家强行掉线
					//pPlayer->SetState(PLAYERSTATE_CHANGEROOM);

					// 先从原来的房间中删除这个玩家
					pSrcRoom->ClearPlayer(pPlayer);

					// 更新一下房间中的用户
					(*iter)->UpdateOnlinePlayers();

					if(pPlayer == NULL) 
					{
						state = false;
						break;
					}

					pPlayer->SetRoomId((*iter)->GetID());
					//pPlayer->SetState(oldstate);

					int playerIndex = (*iter)->AddPlayer(pPlayer);
					pPlayer->SetRoomIndex(playerIndex);		

					state = true;
					break;
				}
			}
		}
	}	
	m_RoomLock.Release();

	return state;
}
Esempio n. 2
0
/**
 * 用于处理用于断开网络连接消息
 *
 * @param connId 要断开网络连接的客户端连接ID
 */
void RoomManager::OnProcessDisconnectNetMes(int connId)
{
	// 首先根据用户连接ID得到用户,然后根据用户信息得到房间信息,最后交给房间处理
	Player *pPlayer = ServerPlayerManager.GetPlayer(connId);
	if(pPlayer == NULL) return;

	Room *pRoom = GetRoomById(pPlayer->GetRoomId());
	if(pRoom == NULL) 
	{
		// 如果用户没有进入任何房间的话,删除这个玩家
		CMolMessageOut out(IDD_MESSAGE_FRAME);	
		out.writeShort(IDD_MESSAGE_LEAVE_SERVER);
		out.writeShort(pPlayer->GetID());

		ServerPlayerManager.SendMsgToEveryone(out);

		Disconnect(pPlayer->GetConnectID());
		ServerPlayerManager.ClearPlayer(pPlayer);
		return;
	}

	//m_RoomLock.Acquire();
	//int playerId = pRoom->GetPlayerIndex(pPlayer->GetConnectID());

	if(pPlayer->GetState() == PLAYERSTATE_GAMING)
	{
		pPlayer->SetState(PLAYERSTATE_LOSTLINE);

		// 向房间所有玩家广播玩家离开房间消息
		CMolMessageOut out(IDD_MESSAGE_FRAME);
		out.writeShort(IDD_MESSAGE_FALLLINE_ROOM);
		out.writeLong(pPlayer->GetID());
		
		ServerPlayerManager.SendMsgToEveryone(out);
	}
	else 
	{
		// 向房间所有玩家广播玩家离开服务器消息
		CMolMessageOut out(IDD_MESSAGE_FRAME);
		out.writeShort(IDD_MESSAGE_LEAVE_SERVER);
		out.writeLong(pPlayer->GetID());		
		ServerPlayerManager.SendMsgToEveryone(out);

		pRoom->ClearPlayer(pPlayer);

		Disconnect(pPlayer->GetConnectID());
		ServerPlayerManager.ClearPlayer(pPlayer);
		return;
	}

	pRoom->OnProcessDisconnectNetMes(pPlayer->GetRoomIndex());

	// 如果当前处于游戏中状态下的话,用户就不用退出房间,否则退出房间
  //  if(pRoom->GetRoomState() == ROOMSTATE_GAMING)
		//pPlayer->SetState(PLAYERSTATE_LOSTLINE);

	if(pPlayer->GetState() != PLAYERSTATE_LOSTLINE)
		pRoom->ClearPlayer(pPlayer);

	// 如果房间中的用户全部掉线,就清空房间状态
	if(pRoom->GetPlayerCount(PLAYERSTATE_LOSTLINE) == pRoom->GetMaxPlayer()/* ||
		pRoom->GetLostPlayerCount() >= pRoom->GetMaxPlayer()-1*/)
	{
		pRoom->GameEnd();
		pRoom->AllPlayerLeveaServer();
	}
	//m_RoomLock.Release();
}