Exemplo n.º 1
0
SCreateChannelResult CGameClientNub::CreateChannel(INetChannel* pChannel, const char* pRequest)
{
	if (pRequest && !gEnv->pNetwork->IsRebroadcasterEnabled())
	{
		GameWarning("CGameClientNub::CreateChannel: pRequest is non-null, it should not be");
		CRY_ASSERT(false);
		SCreateChannelResult res(eDC_GameError);
		cry_strcpy(res.errorMsg, "CGameClientNub::CreateChannel: pRequest is non-null, it should not be");
		return res;
	}

	if (m_pClientChannel)
	{
		if (gEnv->pNetwork->IsRebroadcasterEnabled())
		{
			// A client channel has already been set up so this must be a rebroadcaster (peer to peer) channel
			pChannel->SetPeer(m_pGameContext->GetNetContext());
			SCreateChannelResult res(reinterpret_cast<IGameChannel*>(pChannel));
			return res;
		}
		else
		{
			GameWarning("CGameClientNub::CreateChannel: m_pClientChannel is non-null, it should not be");
			CRY_ASSERT(false);
			SCreateChannelResult res(eDC_GameError);
			cry_strcpy(res.errorMsg, "CGameClientNub::CreateChannel: m_pClientChannel is non-null, it should not be");
			return res;
		}
	}

	if (CCryAction::GetCryAction()->IsGameSessionMigrating())
	{
		pChannel->SetMigratingChannel(true);
	}

	m_pClientChannel = new CGameClientChannel(pChannel, m_pGameContext, this);

	ICVar* pPass = gEnv->pConsole->GetCVar("sv_password");
	if (pPass && gEnv->bMultiplayer)
		pChannel->SetPassword(pPass->GetString());

	return SCreateChannelResult(m_pClientChannel);
}
//------------------------------------------------------------------------
SCreateChannelResult CGameServerNub::CreateChannel(INetChannel *pChannel, const char *pRequest)
{
	CRY_ASSERT(m_maxPlayers);

	CGameServerChannel *pNewChannel;

	if (!pRequest)
	{
		CRY_ASSERT(false);
		SCreateChannelResult res(eDC_GameError);
		return res;
	}

	SParsedConnectionInfo info = m_pGameContext->ParseConnectionInfo(pRequest);
	if (!info.allowConnect)
	{
		GameWarning( "Not allowed to connect to server: %s", info.errmsg.c_str() );
		SCreateChannelResult res(info.cause);
		cry_strcpy(res.errorMsg, info.errmsg.c_str());
		return res;
	}

	if (int(m_channels.size()) >= m_maxPlayers)
	{
		SCreateChannelResult res(eDC_ServerFull);
		cry_strcpy(res.errorMsg, string().Format("Disallowing more than %d players",m_maxPlayers).c_str());
		return res;
	}

	if (info.isMigrating && CCryAction::GetCryAction()->IsGameSessionMigrating())
	{
		pChannel->SetMigratingChannel(true);
	}

	pNewChannel = GetOnHoldChannelFor(pChannel);
	if (!pNewChannel)
	{
		pNewChannel = new CGameServerChannel(pChannel, m_pGameContext, this);

		if (pChannel->GetSession() != CrySessionInvalidHandle)
		{
			// There is a valid CrySessionHandle created by the lobby so use this as the channel id
			// as it contains information that can identify the connection in the lobby.
			pNewChannel->SetChannelId(pChannel->GetSession());
		}
		else
		{
			// No valid CrySessionHandle so create an id here.
			pNewChannel->SetChannelId(++m_genId);
		}
		
		if (m_channels.find(pNewChannel->GetChannelId()) != m_channels.end())
		{
			CryFatalError("CGameServerNub::CreateChannel: Trying to create channel with duplicate id %d", pNewChannel->GetChannelId());
		}

		m_channels.insert(TServerChannelMap::value_type(pNewChannel->GetChannelId(), pNewChannel));
	}
	else
	{
		pNewChannel->SetNetChannel(pChannel);
#if !NEW_BANDWIDTH_MANAGEMENT
		pNewChannel->SetupNetChannel(pChannel);
#endif // NEW_BANDWIDTH_MANAGEMENT
	}

	ICVar* pPass = gEnv->pConsole->GetCVar("sv_password");
	if (pPass && gEnv->bMultiplayer)
	{
		pChannel->SetPassword(pPass->GetString());
	}
	pChannel->SetNickname(info.playerName.c_str());

	// Host migration
	if (info.isMigrating && CCryAction::GetCryAction()->IsGameSessionMigrating())
	{
		// Enable the game rules to find the migrating player details by channel id
		IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework();
		IGameRules *pGameRules = pGameFramework->GetIGameRulesSystem()->GetCurrentGameRules();
		
		if(pGameRules)
		{
			EntityId playerID = pGameRules->SetChannelForMigratingPlayer(info.playerName.c_str(), pNewChannel->GetChannelId());

			if (playerID)
			{
				CryLog("CGameServerNub::CreateChannel() assigning actor %d '%s' to channel %d", playerID, info.playerName.c_str(), pNewChannel->GetChannelId());
				pNewChannel->SetPlayerId(playerID);
			}
			else
			{
				CryLog("CGameServerNub::CreateChannel() failed to assign actor '%s' to channel %d", info.playerName.c_str(), pNewChannel->GetChannelId());
			}
		}
		else
		{
			CryLog("[host migration] terminating because game rules is NULL, game session migrating %d session 0x%08x", CCryAction::GetCryAction()->IsGameSessionMigrating(), pChannel->GetSession());
			gEnv->pNetwork->TerminateHostMigration(pChannel->GetSession());
		}
	}

	m_netchannels.insert(TNetServerChannelMap::value_type(pChannel, pNewChannel->GetChannelId()));

	return SCreateChannelResult(pNewChannel);
}