Beispiel #1
0
void CGameServer::ClientEnterGame(int iClient)
{
	TMsg(sprintf(tstring("Client %d (") + GameNetwork()->GetClientNickname(iClient) + ") entering game.\n", iClient));

	if (GetGame())
		GetGame()->OnClientEnterGame(iClient);

	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);

		if (!pEntity)
			continue;

		::CreateEntity.RunCommand(sprintf(tstring("%s %d %d"), pEntity->GetClassName(), pEntity->GetHandle(), pEntity->GetSpawnSeed()), iClient);
	}

	CGameServerNetwork::UpdateNetworkVariables(iClient, true);

	// Update entities after all creations have been run, so we don't refer to entities that haven't been created yet.
	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);

		if (!pEntity)
			continue;

		pEntity->ClientUpdate(iClient);
	}

	GameNetwork()->CallFunction(iClient, "EnterGame");

	GameNetwork()->CallFunction(iClient, "LoadingDone");
}
Beispiel #2
0
void CGameServer::DestroyAllEntities(const tvector<tstring>& asSpare, bool bRemakeGame)
{
	if (!GameNetwork()->IsHost() && !IsLoading())
		return;

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Locating dead nodes", GameServer()->GetMaxEntities());

	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);
		if (!pEntity)
			continue;

		bool bSpare = false;
		for (size_t j = 0; j < asSpare.size(); j++)
		{
			if (asSpare[j] == pEntity->GetClassName())
			{
				bSpare = true;
				break;
			}
		}

		if (bSpare)
			continue;

		pEntity->Delete();

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(i);
	}

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Clearing buffers", GameServer()->m_ahDeletedEntities.size());

	for (size_t i = 0; i < GameServer()->m_ahDeletedEntities.size(); i++)
	{
		delete GameServer()->m_ahDeletedEntities[i];

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(i);
	}

	GameServer()->m_ahDeletedEntities.clear();

	if (CBaseEntity::GetNumEntities() == 0)
		CBaseEntity::s_iNextEntityListIndex = 0;

	if (bRemakeGame && GameNetwork()->IsHost())
		m_hGame = CreateGame();
}
Beispiel #3
0
void CInstructor::CallOutput(const tstring& sOutput)
{
    if (!GetCurrentLesson())
        return;

    for (size_t i = 0; i < GetCurrentLesson()->m_aOutputs.size(); i++)
    {
        CLessonOutput* pOutput = &GetCurrentLesson()->m_aOutputs[i];
        if (pOutput->m_sOutput == sOutput)
        {
            for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
            {
                CBaseEntity* pEntity = CBaseEntity::GetEntity(i);

                if (!pEntity)
                    continue;

                if (pEntity->IsDeleted())
                    continue;

                if (pOutput->m_sTarget.length() == 0)
                    continue;

                if (pOutput->m_sTarget.length() == 0)
                    continue;

                if (pOutput->m_sTarget[0] == '*')
                {
                    if (tstring(pEntity->GetClassName()) != pOutput->m_sTarget.c_str()+1)
                        continue;
                }
                else
                {
                    if (pEntity->GetName() != pOutput->m_sTarget)
                        continue;
                }

                pEntity->CallInput(pOutput->m_sInput, convertstring<char, tchar>(pOutput->m_sArgs));
            }
        }
    }
}
Beispiel #4
0
void FireInput(class CCommand* pCommand, tvector<tstring>& asTokens, const tstring& sCommand)
{
	if (!CVar::GetCVarBool("cheats"))
		return;

	if (asTokens.size() < 3)
	{
		TMsg("Format: ent_input entityname input [optional args]\n");
		return;
	}

	tvector<CBaseEntity*> apEntities;
	CBaseEntity::FindEntitiesByName(asTokens[1], apEntities);

	if (!apEntities.size())
	{
		if (CVar::GetCVarBool("debug_entity_outputs"))
			TMsg("Console -> none\n");
		else
			TError("No entities found that match name \"" + asTokens[1] + "\".\n");

		return;
	}

	tstring sArgs;
	for (size_t i = 3; i < asTokens.size(); i++)
		sArgs += asTokens[i] + " ";

	for (size_t i = 0; i < apEntities.size(); i++)
	{
		CBaseEntity* pTargetEntity = apEntities[i];

		if (CVar::GetCVarBool("debug_entity_outputs"))
			TMsg("Console -> " + tstring(pTargetEntity->GetClassName()) + "(\"" + pTargetEntity->GetName() + "\")." + asTokens[2] + "(\"" + sArgs + "\")\n");

		pTargetEntity->CallInput(asTokens[2], sArgs);
	}
}
Beispiel #5
0
void CGameServer::LoadLevel(const CHandle<CLevel>& pLevel)
{
	// Create and name the entities first and add them to this array. This way we avoid a problem where
	// one entity needs to connect to another entity which has not yet been created.
	tmap<size_t, CBaseEntity*> apEntities;

	// Do a quick precache now to load default models and such. Another precache will come later.
	const auto& aEntities = pLevel->GetEntityData();
	for (size_t i = 0; i < aEntities.size(); i++)
		AddToPrecacheList("C" + aEntities[i].GetClass());

	PrecacheList();

	m_bAllowPrecaches = true;

	for (size_t i = 0; i < aEntities.size(); i++)
	{
		const CLevelEntity* pLevelEntity = &aEntities[i];

		tstring sClass = "C" + pLevelEntity->GetClass();

		auto it = CBaseEntity::GetEntityRegistration().find(sClass);
		TAssert(it != CBaseEntity::GetEntityRegistration().end());
		if (it == CBaseEntity::GetEntityRegistration().end())
		{
			TError("Unregistered entity '" + sClass + "'\n");
			continue;
		}

		AddToPrecacheList("C" + aEntities[i].GetClass());

		CBaseEntity* pEntity = Create<CBaseEntity>(sClass.c_str());

		apEntities[i] = pEntity;

		pEntity->SetName(pLevelEntity->GetName());

		// Process outputs here so that they exist when handle callbacks run.
		for (size_t k = 0; k < pLevelEntity->GetOutputs().size(); k++)
		{
			auto pOutput = &pLevelEntity->GetOutputs()[k];
			tstring sValue = pOutput->m_sOutput;

			CSaveData* pSaveData = CBaseEntity::FindOutput(pEntity->GetClassName(), sValue);
			TAssert(pSaveData);
			if (!pSaveData)
			{
				TError("Unknown output '" + sValue + "'\n");
				continue;
			}

			tstring sTarget = pOutput->m_sTargetName;
			tstring sInput = pOutput->m_sInput;
			tstring sArgs = pOutput->m_sArgs;
			bool bKill = pOutput->m_bKill;

			if (!sTarget.length())
			{
				TUnimplemented();
				TError("Output '" + sValue + "' of entity '" + pEntity->GetName() + "' (" + pEntity->GetClassName() + ") is missing a target.\n");
				continue;
			}

			if (!sInput.length())
			{
				TUnimplemented();
				TError("Output '" + sValue + "' of entity '" + pEntity->GetName() + "' (" + pEntity->GetClassName() + ") is missing an input.\n");
				continue;
			}

			pEntity->AddOutputTarget(sValue, sTarget, sInput, sArgs, bKill);
		}
	}

	for (auto it = apEntities.begin(); it != apEntities.end(); it++)
	{
		auto pLevelEntity = &aEntities[it->first];
		CBaseEntity* pEntity = it->second;

		// Force physics related stuff first so it's available if there's a physics model.
		auto itScale = pLevelEntity->GetParameters().find("Scale");
		if (itScale != pLevelEntity->GetParameters().end())
			UnserializeParameter("Scale", itScale->second, pEntity);

		auto itOrigin = pLevelEntity->GetParameters().find("Origin");
		if (itOrigin != pLevelEntity->GetParameters().end())
			UnserializeParameter("Origin", itOrigin->second, pEntity);

		for (auto it = pLevelEntity->GetParameters().begin(); it != pLevelEntity->GetParameters().end(); it++)
		{
			tstring sHandle = it->first;
			tstring sValue = it->second;

			if (sHandle == "MoveParent")
				continue;

			if (sHandle == "Scale")
				continue;

			if (sHandle == "Origin")
				continue;

			UnserializeParameter(sHandle, sValue, pEntity);
		}
	}

	for (auto it = apEntities.begin(); it != apEntities.end(); it++)
	{
		auto pLevelEntity = &aEntities[it->first];
		CBaseEntity* pEntity = it->second;

		// Force MoveParent last so that global -> local conversion is performed.
		auto itMoveParent = pLevelEntity->GetParameters().find("MoveParent");
		if (itMoveParent != pLevelEntity->GetParameters().end())
			UnserializeParameter("MoveParent", itMoveParent->second, pEntity);
	}

	for (size_t i = 0; i < apEntities.size(); i++)
		apEntities[i]->PostLoad();

	if (CWorkbench::IsActive())
		CWorkbench::LoadLevel(pLevel);
}
void CGameServerNetwork::UpdateNetworkVariables(int iClient, bool bForceAll)
{
	if (!GameNetwork()->IsConnected())
		return;

	double flTime = GameServer()->GetGameTime();

	size_t iMaxEnts = GameServer()->GetMaxEntities();
	for (size_t i = 0; i < iMaxEnts; i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);
		if (!pEntity)
			continue;

		const tchar* pszClassName = pEntity->GetClassName();

		CEntityRegistration* pRegistration = NULL;
		do
		{
			pRegistration = pEntity->GetRegisteredEntity(pszClassName);

			TAssert(pRegistration);
			if (!pRegistration)
				break;

			size_t iNetVarsSize = pRegistration->m_aNetworkVariables.size();
			for (size_t j = 0; j < iNetVarsSize; j++)
			{
				CNetworkedVariableData* pVarData = &pRegistration->m_aNetworkVariables[j];
				CNetworkedVariableBase* pVariable = pVarData->GetNetworkedVariableBase(pEntity);

				if (!bForceAll)
				{
					if (!pVariable->IsDirty())
						continue;

					if (flTime - pVariable->m_flLastUpdate < pVarData->m_flUpdateInterval)
						continue;
				}

				// For one, m_flLastUpdate needs to be a double
				pVariable->m_flLastUpdate = (float)flTime;
				// For two, it's shit.
				TUnimplemented();
				// Try some testing or something.

				CNetworkParameters p;
				p.ui1 = pEntity->GetHandle();

				size_t iDataSize;
				void* pValue = pVariable->Serialize(iDataSize);

				if (net_replication_debug.GetBool())
				{
					if (iDataSize >= 4)
						TMsg(tstring("Updating ") + pVarData->GetName() + sprintf(tstring(" (%x) (%f) (%d)\n"), *(unsigned int*)pValue, *(float*)pValue, *(int*)pValue));
					else
						TMsg(tstring("Updating ") + pVarData->GetName() + "\n");
				}

				p.CreateExtraData(iDataSize + strlen(pVarData->GetName())+1);
				strcpy((char*)p.m_pExtraData, pVarData->GetName());
				memcpy((unsigned char*)(p.m_pExtraData) + strlen(pVarData->GetName())+1, pValue, iDataSize);

				// UV stands for UpdateValue
				GameNetwork()->CallFunctionParameters(iClient, "UV", &p);

				// Only reset the dirty flag if all clients got the message.
				if (iClient == NETWORK_TOCLIENTS)
					pVariable->SetDirty(false);
			}

			pszClassName = pRegistration->m_pszParentClass;
		} while (pszClassName);
	}
}