예제 #1
0
	void AnalyzeGameState(const udtCuGamestateMessage& gameState)
	{
		_demoTakerClientNumber = gameState.ClientNumber;

		PrintInfo("");
		PrintInfo("================================");
		PrintInfo("New Game State");
		PrintInfo("================================");

		std::string playerName;
		udtCuConfigString cs;
		for(u32 i = 0; i < ID_MAX_CLIENTS; ++i)
		{
			udtCuGetConfigString(_cuContext, &cs, (u32)_protocolFirstPlayerCsIdx + i);
			if(cs.ConfigString != NULL && cs.ConfigStringLength > 0)
			{
				if(ExtractPlayerName(playerName, cs.ConfigString, _protocol))
				{
					_players[i].Name = playerName;
					_players[i].Valid = true;
					PrintInfo("Player: %s (client %u)%s", playerName.c_str(), i, (s32)i == _demoTakerClientNumber ? " <== demo taker" : "");
				}
			}
		}

		PrintInfo("================================");
	}
예제 #2
0
	void AnalyzeCommand(const udtCuCommandMessage& command, s32 serverTimeMs)
	{
		if(!command.IsConfigString)
		{
			return;
		}

		const s32 clientNumber = command.ConfigStringIndex - _protocolFirstPlayerCsIdx;
		if(clientNumber < 0 || clientNumber >= ID_MAX_CLIENTS)
		{
			// Not a player config string.
			return;
		}

		// Config string update commands always have 3 tokens:
		// 1. "cs"
		// 2. The index of the config string to update.
		// 3. The actual content, in quotes.
		if(command.TokenCount != 3)
		{
			// Not a proper config string command.
			return;
		}

		std::string serverTime;
		FormatServerTime(serverTime, serverTimeMs);

		const std::string configString = command.CommandTokens[2];
		std::string playerName;
		Player& player = _players[clientNumber];
		if(configString.empty() || !ExtractPlayerName(playerName, configString, _protocol))
		{
			PrintInfo("%s Player %s left (client %u)", serverTime.c_str(), player.Name.c_str(), (u32)clientNumber);
			player.Name = "";
			player.Valid = false;
			return;
		}
		
		const bool wasValid = player.Valid;
		player.Valid = true;
		if(!wasValid)
		{
			PrintInfo("%s Player %s joined (client %u)", serverTime.c_str(), playerName.c_str(), (u32)clientNumber);
			player.Name = playerName;
		}
		else if(playerName != player.Name)
		{
			PrintInfo("%s Player %s renamed to %s (client %u)", serverTime.c_str(), player.Name.c_str(), playerName.c_str(), (u32)clientNumber);
			player.Name = playerName;
		}
	}
예제 #3
0
IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol, int iChallenge, int iClientChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie)
#endif
{
	if (!pCookie || (size_t)cbCookie < sizeof(uint64))
		RETURN_META_VALUE(MRES_IGNORED, nullptr);

#if SOURCE_ENGINE == SE_CSGO
	// CS:GO doesn't send the player name in pchName, but only in the client info convars.
	// Try to extract the name from the protobuf msg.
	char playerName[MAX_PLAYER_NAME_LENGTH];
	if (ExtractPlayerName(pSplitPlayerConnectVector, playerName, sizeof(playerName)))
		pchName = playerName;
#endif

	char ipString[16];
	V_snprintf(ipString, sizeof(ipString), "%u.%u.%u.%u", address.ip[0], address.ip[1], address.ip[2], address.ip[3]);
	V_strncpy(passwordBuffer, pchPassword, 255);

	// SourceTV doesn't validate steamids?!

	char rejectReason[255];

	m_SpectatorPreConnectFwd->PushString(pchName);
	m_SpectatorPreConnectFwd->PushStringEx(passwordBuffer, 255, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
	m_SpectatorPreConnectFwd->PushString(ipString);
	m_SpectatorPreConnectFwd->PushStringEx(rejectReason, 255, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);

	cell_t retVal = 1;
	m_SpectatorPreConnectFwd->Execute(&retVal);

	IServer *server = META_IFACEPTR(IServer);
	if (retVal == 0)
	{
		if (m_bHasRejectConnectionOffset)
		{
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2
			SH_MCALL(server, CHLTVServer_RejectConnection)(address, rejectReason);
#else
			SH_MCALL(server, CHLTVServer_RejectConnection)(address, iClientChallenge, rejectReason);
#endif
		}
		RETURN_META_VALUE(MRES_SUPERCEDE, nullptr);
	}

	// Call the original function.
#if SOURCE_ENGINE == SE_CSGO
	IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie, pSplitPlayerConnectVector, bUnknown, platform, pUnknown, iUnknown);
#elif SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2
	IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie, pSplitPlayerConnectVector, bUnknown);
#else
	IClient *client = SH_MCALL(server, CHLTVServer_ConnectClient)(address, nProtocol, iChallenge, iClientChallenge, nAuthProtocol, pchName, passwordBuffer, pCookie, cbCookie);
#endif

	if (!client)
		RETURN_META_VALUE(MRES_SUPERCEDE, nullptr);

	HookClient(client);

	HLTVServerWrapper *wrapper = g_HLTVServers.GetWrapper(server);
	if (wrapper)
	{
		HLTVClientWrapper *clientWrapper = wrapper->GetClient(client->GetPlayerSlot() + 1);
		clientWrapper->Initialize(ipString, pchPassword, client);
	}

	m_SpectatorConnectedFwd->PushCell(client->GetPlayerSlot() + 1);
	m_SpectatorConnectedFwd->Execute();

	// Don't call the hooked function again, just return its value.
	RETURN_META_VALUE(MRES_SUPERCEDE, client);
}