void CServerRPCHandler::EmptyVehicleSync(CBitStream * pBitStream, CPlayerSocket * pSenderSocket)
{
	// Ensure we have a valid bit stream
	if(!pBitStream)
		return;

	EntityId playerId = pSenderSocket->playerId;

	if(CVAR_GET_BOOL("frequentevents"))
	{
		CSquirrelArguments pArguments;
		pArguments.push(playerId);

		if(g_pEvents->Call("playerEmptyVehicleSyncReceived", &pArguments).GetInteger() != 1 || g_pEvents->Call("playerSyncReceived", &pArguments).GetInteger() != 1)
			return;
	}

	CBitStream bsSend;
	EMPTYVEHICLESYNCPACKET syncPacket;

	if(!pBitStream->Read((PCHAR)&syncPacket, sizeof(EMPTYVEHICLESYNCPACKET)))
		return;

	CVehicle * pVehicle = g_pVehicleManager->GetAt(syncPacket.vehicleId);
	if(pVehicle && g_pVehicleManager->DoesExist(syncPacket.vehicleId))
		pVehicle->StoreEmptyVehicle(&syncPacket);

	//bsSend.Write((char *)&syncPacket, sizeof(EMPTYVEHICLESYNCPACKET));
	//g_pNetworkManager->RPC(RPC_EmptyVehicleSync, &bsSend, PRIORITY_LOW, RELIABILITY_UNRELIABLE_SEQUENCED, playerId, false);
}
void CServerRPCHandler::InVehicleSync(CBitStream * pBitStream, CPlayerSocket * pSenderSocket)
{
	// Ensure we have a valid bit stream
	if(!pBitStream)
		return;

	EntityId playerId = pSenderSocket->playerId;
	CPlayer * pPlayer = g_pPlayerManager->GetAt(playerId);

	if(pPlayer)
	{
		if(CVAR_GET_BOOL("frequentevents"))
		{
			CSquirrelArguments pArguments;
			pArguments.push(playerId);

			if(g_pEvents->Call("playerInVehicleSyncReceived", &pArguments).GetInteger() != 1 || g_pEvents->Call("playerSyncReceived", &pArguments).GetInteger() != 1)
				return;
		}

		EntityId vehicleId;
		InVehicleSyncData syncPacket;
		AimSyncData aimSyncData;

		if(!pBitStream->ReadCompressed(vehicleId))
			return;

		if(g_pVehicleManager->DoesExist(vehicleId))
		{
			if(!pBitStream->Read((char *)&syncPacket, sizeof(InVehicleSyncData)))
				return;

			bool bHasAimSyncData = pBitStream->ReadBit();

			if(bHasAimSyncData)
			{
				if(!pBitStream->Read((char *)&aimSyncData, sizeof(AimSyncData)))
					return;
			}

			CVehicle * pVehicle = g_pVehicleManager->GetAt(vehicleId);

			if(pVehicle)
			{
				pPlayer->StoreInVehicleSync(pVehicle, &syncPacket, bHasAimSyncData, &aimSyncData);
				pVehicle->StoreInVehicleSync(&syncPacket);
				//pVehicle->SetLastTimeOccupied(SharedUtility::GetTime());
			}
		}
	}
}
void CServerRPCHandler::HeadMovement(CBitStream * pBitStream, CPlayerSocket * pSenderSocket)
{
	// Ensure we have a valid bit stream
	if(!pBitStream)
		return;

	EntityId playerId = pSenderSocket->playerId;
	CPlayer * pPlayer = g_pPlayerManager->GetAt(playerId);
	CVector3 vecAim;

	if(!pBitStream->Read(vecAim.fX))
		return;

	if(!pBitStream->Read(vecAim.fY))
		return;

	if(!pBitStream->Read(vecAim.fZ))
		return;

	// Check if frequentevents and headmovement is enabled
	if(CVAR_GET_BOOL("headmovement"))
	{
		CBitStream bsSend;
		bsSend.WriteCompressed(playerId);
		bsSend.Write(vecAim.fX);
		bsSend.Write(vecAim.fY);
		bsSend.Write(vecAim.fZ);

		// Update our head sync
		if(pPlayer)
		{
			pPlayer->UpdateHeadMoveSync(vecAim);
			// jenksta: this is being sent to EVERYONE (including the player it came from), fix it
			g_pNetworkManager->RPC(RPC_HeadMovement, &bsSend, PRIORITY_LOW, RELIABILITY_UNRELIABLE_SEQUENCED, INVALID_ENTITY_ID, true);
		}
	}
}
void CServerRPCHandler::SmallSync(CBitStream * pBitStream, CPlayerSocket * pSenderSocket)
{
	// Ensure we have a valid bit stream
	if(!pBitStream)
		return;

	EntityId playerId = pSenderSocket->playerId;
	CPlayer * pPlayer = g_pPlayerManager->GetAt(playerId);

	if(pPlayer)
	{
		if(CVAR_GET_BOOL("frequentevents"))
		{
			CSquirrelArguments pArguments;
			pArguments.push(playerId);

			if(g_pEvents->Call("playerSmallSyncReceived", &pArguments).GetInteger() != 1 || g_pEvents->Call("playerSyncReceived", &pArguments).GetInteger() != 1)
				return;
		}

		SmallSyncData syncPacket;
		AimSyncData aimSyncData;

		if(!pBitStream->Read((char *)&syncPacket, sizeof(SmallSyncData)))
			return;

		bool bHasAimSyncData = pBitStream->ReadBit();

		if(bHasAimSyncData)
		{
			if(!pBitStream->Read((char *)&aimSyncData, sizeof(AimSyncData)))
				return;
		}

		pPlayer->StoreSmallSync(&syncPacket, bHasAimSyncData, &aimSyncData);
	}
}
// areFrequentEventsEnabled()
SQInteger CServerNatives::AreFrequentEventsEnabled(SQVM * pVM)
{
	sq_pushbool(pVM, CVAR_GET_BOOL("frequentevents"));
	return 1;
}
示例#6
0
BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved)
{
	switch(fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		{
			// Disable thread library notifications
			DisableThreadLibraryCalls(hModule);

			// Install the exception handler
			CExceptionHandler::Install();

			// Delete chatlog
			CLogFile::Open("Chatlog.log");
			CLogFile::Printf("New chatlog created!");
			CLogFile::Close();

			// Open the log file
			CLogFile::Open("Client.log");

			// Log the version
			CLogFile::Printf(VERSION_IDENTIFIER "| " __DATE__ " - " __TIME__ "");

			// Open the settings file
			CSettings::Open(SharedUtility::GetAbsolutePath("clientsettings.xml"));

			// Parse the command line
			CSettings::ParseCommandLine(GetCommandLine());

			// Load the global vars from the settings
			g_strHost = CVAR_GET_STRING("ip");
			g_usPort = CVAR_GET_INTEGER("port");
			g_strNick = CVAR_GET_STRING("nick");
			g_strPassword = CVAR_GET_STRING("pass");
			g_bWindowedMode = CVAR_GET_BOOL("windowed");
			g_bFPSToggle = CVAR_GET_BOOL("fps");

			// IE9 fix - disabled if disableie9fix is set or shift is pressed
			if(!CVAR_GET_BOOL("disableie9fix") || GetAsyncKeyState(VK_SHIFT) > 0)
			{
				// Get the version info
				DWORD dwHandle;
				DWORD dwSize = GetFileVersionInfoSize("wininet.dll", &dwHandle);
				BYTE* byteFileInfo = new BYTE[dwSize];
				GetFileVersionInfo("wininet.dll", dwHandle, dwSize, byteFileInfo);

				unsigned int uiLen;
				VS_FIXEDFILEINFO* fileInfo;
				VerQueryValue(byteFileInfo, "\\", (LPVOID *)&fileInfo, &uiLen);
				delete byteFileInfo;

				// using IE9?
				if(fileInfo->dwFileVersionMS == 0x90000)
				{
					// Try and load a wininet.dll from the iv:mp directory
					if(!LoadLibrary(SharedUtility::GetAbsolutePath("wininet.dll")))
					{
						// Get path to it
						char szFindPath[MAX_PATH] = {0};
						char szWinSxsPath[MAX_PATH] = {0};
						char szBuildVersion[] = "00000";
						GetEnvironmentVariable("windir", szWinSxsPath, sizeof(szWinSxsPath));
						strcat_s(szWinSxsPath, sizeof(szWinSxsPath), "\\WinSxS\\");
						strcpy_s(szFindPath, sizeof(szFindPath), szWinSxsPath);
						strcat_s(szFindPath, sizeof(szFindPath), "x86_microsoft-windows-i..tocolimplementation_31bf3856ad364e35*");

						// try to find a usable wininet.dll in WinSXS (basically any non-9.x version)
						bool bLoaded = false;
						WIN32_FIND_DATA lpFindFileData;
						HANDLE hFindFile = FindFirstFile(szFindPath, &lpFindFileData);
						do
						{
							if(hFindFile == INVALID_HANDLE_VALUE)
								break;

							if(strlen(lpFindFileData.cFileName) > 63)
							{
								if(lpFindFileData.cFileName[62] < '9')
								{
									char szFullPath[MAX_PATH];
									sprintf_s(szFullPath, MAX_PATH, "%s%s\\wininet.dll", szWinSxsPath, lpFindFileData.cFileName);
									if(LoadLibrary(szFullPath))
									{
										CLogFile::Printf("Using %s to address IE9 issue", szFullPath);
										bLoaded = true;
										break;
									}
								}
							}
						}
						while(FindNextFile(hFindFile, &lpFindFileData));

						// Still failed, tell the user
						if(!bLoaded)
						{
							if(MessageBox(0, "Unfortunately, you have Internet Explorer 9 installed which is not compatible with GTA:IV. Do you want proceed anyway (and possibly crash?)", "IV:MP", MB_YESNO | MB_ICONERROR) == IDNO)
							{
								// Doesn't want to continue
								ExitProcess(0);
							}

							// Save the user's choice
							CVAR_SET_BOOL("disableie9fix", true);
						}
					}
				}
			}

			// Initialize the streamer
			g_pStreamer = new CStreamer();

			// Initialize the time
			g_pTime = new CTime();

			// Initialize the traffic lights
			g_pTrafficLights = new CTrafficLights();

			// Initialize the client task manager
			g_pClientTaskManager = new CClientTaskManager();

			// Initialize the game
			CGame::Initialize();

			// Install the XLive hook
			CXLiveHook::Install();

			// Install the Direct3D hook
			CDirect3DHook::Install();

			// Install the DirectInput hook
			CDirectInputHook::Install();

			// Install the Cursor hook
#ifdef IVMP_DEBUG
			CCursorHook::Install();
			g_pDebugView = new CDebugView();
#endif
			// Initialize the client script manager
			g_pClientScriptManager = new CClientScriptManager();

			// Initialize the events manager
			g_pEvents = new CEvents();

			// Initialize the network module, if it fails, exit
			if(!CNetworkModule::Init())
			{
				CLogFile::Printf("Failed to initialize the network module!\n");
				ExitProcess(0);
			}

			// Initialize the file transfer
			g_pFileTransfer = new CFileTransfer();

			// Initialize audio manager
			CAudioManager::Init();
		}
		break;
	case DLL_PROCESS_DETACH:
		{

			// Delete our file transfer
			SAFE_DELETE(g_pFileTransfer);

			// Delete our camera
			SAFE_DELETE(g_pCamera);

			// Delete our model manager
			SAFE_DELETE(g_pModelManager);

			// Delete our pickup manager
			SAFE_DELETE(g_pPickupManager);

			// Delete our checkpoint manager
			SAFE_DELETE(g_pCheckpointManager);

			// Delete our object manager
			SAFE_DELETE(g_pObjectManager);

			// Delete our blip manager
			SAFE_DELETE(g_pBlipManager);

			// Delete our actor manager
			SAFE_DELETE(g_pActorManager);

			// Delete our vehicle manager
			SAFE_DELETE(g_pVehicleManager);

			// Delete our local player
			SAFE_DELETE(g_pLocalPlayer);

			// Delete our player manager
			SAFE_DELETE(g_pPlayerManager);

			// Delete our network manager
			SAFE_DELETE(g_pNetworkManager);

			// Delete our name tags
			SAFE_DELETE(g_pNameTags);

			// Delete our input window
			SAFE_DELETE(g_pInputWindow);

			// Delete our chat window
			SAFE_DELETE(g_pChatWindow);

			// Delete our fps counter
			SAFE_DELETE(g_pFPSCounter);

#ifdef IVMP_DEBUG
			// Delete out debug viewer
			SAFE_DELETE(g_pDebugView);
#endif
			// Delete our credits
			SAFE_DELETE(g_pCredits);

			// Delete our main menu
			SAFE_DELETE(g_pMainMenu);

			// Delete our gui
			SAFE_DELETE(g_pGUI);

			// Delete our streamer class
			SAFE_DELETE(g_pStreamer);

			// Delete our time class
			SAFE_DELETE(g_pTime);

			// Delete our traffic lights
			SAFE_DELETE(g_pTrafficLights);

			// Delete our client script manager
			SAFE_DELETE(g_pClientScriptManager);

			// Delete our client task manager
			SAFE_DELETE(g_pClientTaskManager);

			// Delete our events manager
			SAFE_DELETE(g_pEvents);

			// Uninstall the Cursor hook
#ifdef IVMP_DEBUG
			CCursorHook::Uninstall();
#endif

			// Uninstall the DirectInput hook
			CDirectInputHook::Uninstall();

			// Uninstall the Direct3D hook
			CDirect3DHook::Uninstall();

			// Shutdown audio manager
			CAudioManager::SetAllVolume(0.0f);
			CAudioManager::RemoveAll();

			// Shutdown our game
			CGame::Shutdown();

			// Close the settings file
			CSettings::Close();

			// Close the log file
			CLogFile::Close();

			// Uninstall the XLive hook
			//CXLiveHook::Uninstall(); // Not needed
		}
		break;
	}

	return TRUE;
}
示例#7
0
bool CClient::OnLoad()
{
	// Install the exception handler
	CExceptionHandler::Install();

	// Set our exception handler callback
	CExceptionHandler::SetCallback(ExceptionHandlerCallback);

	// jenksta: wtf?
	// Delete chatlog
	CLogFile::Open("Chatlog.log");
	CLogFile::Printf("New chatlog created!");
	CLogFile::Close();

	// Open the log file
	CLogFile::Open("Client.log");

	// Log the version
	CLogFile::Printf(VERSION_IDENTIFIER "| " __DATE__ " - " __TIME__ "");

	// Open the settings file
	CSettings::Open(SharedUtility::GetAbsolutePath("clientsettings.xml"));

	// Parse the command line
	CSettings::ParseCommandLine(GetCommandLine());

	// Load the global vars from the settings
	m_strHost = CVAR_GET_STRING("ip");
	m_usPort = CVAR_GET_INTEGER("port");
	m_strNick = CVAR_GET_STRING("nick");
	m_strPassword = CVAR_GET_STRING("pass");
	m_bWindowedMode = CVAR_GET_BOOL("windowed");
	m_bFPSToggle = CVAR_GET_BOOL("fps");
	m_strConnectHost = CVAR_GET_STRING("currentconnect_server");
	m_usConnectPort = CVAR_GET_INTEGER("currentconnect_port");

	// IE9 fix - disabled if disableie9fix is set or shift is pressed
	if(!CVAR_GET_BOOL("disableie9fix") || GetAsyncKeyState(VK_SHIFT) > 0)
	{
		// Get the version info
		DWORD dwHandle;
		DWORD dwSize = GetFileVersionInfoSize("wininet.dll", &dwHandle);
		BYTE* byteFileInfo = new BYTE[dwSize];
		GetFileVersionInfo("wininet.dll", dwHandle, dwSize, byteFileInfo);

		unsigned int uiLen;
		VS_FIXEDFILEINFO* fileInfo;
		VerQueryValue(byteFileInfo, "\\", (LPVOID *)&fileInfo, &uiLen);
		delete byteFileInfo;

		// using IE9?
		if(fileInfo->dwFileVersionMS == 0x90000)
		{
			// Try and load a wininet.dll from the iv:mp directory
			if(!LoadLibrary(SharedUtility::GetAbsolutePath("wininet.dll")))
			{
				// Get path to it
				char szFindPath[MAX_PATH] = {0};
				char szWinSxsPath[MAX_PATH] = {0};
				char szBuildVersion[] = "00000";
				GetEnvironmentVariable("windir", szWinSxsPath, sizeof(szWinSxsPath));
				strcat_s(szWinSxsPath, sizeof(szWinSxsPath), "\\WinSxS\\");
				strcpy_s(szFindPath, sizeof(szFindPath), szWinSxsPath);
				strcat_s(szFindPath, sizeof(szFindPath), "x86_microsoft-windows-i..tocolimplementation_31bf3856ad364e35*");

				// try to find a usable wininet.dll in WinSXS (basically any non-9.x version)
				bool bLoaded = false;
				WIN32_FIND_DATA lpFindFileData;
				HANDLE hFindFile = FindFirstFile(szFindPath, &lpFindFileData);
				do
				{
					if(hFindFile == INVALID_HANDLE_VALUE)
						break;

					if(strlen(lpFindFileData.cFileName) > 63)
					{
						if(lpFindFileData.cFileName[62] < '9')
						{
							char szFullPath[MAX_PATH];
							sprintf_s(szFullPath, MAX_PATH, "%s%s\\wininet.dll", szWinSxsPath, lpFindFileData.cFileName);
							if(LoadLibrary(szFullPath))
							{
								CLogFile::Printf("Using %s to address IE9 issue", szFullPath);
								bLoaded = true;
								break;
							}
						}
					}
				}
				while(FindNextFile(hFindFile, &lpFindFileData));

				// Still failed, tell the user
				if(!bLoaded)
				{
					if(MessageBox(0, "Unfortunately, you have Internet Explorer 9 installed which is not compatible with GTA:IV. Do you want proceed anyway (and possibly crash?)", "IV:MP", MB_YESNO | MB_ICONERROR) == IDNO)
					{
						// Doesn't want to continue
						return false;
					}

					// Save the user's choice
					CVAR_SET_BOOL("disableie9fix", true);
				}
			}
		}
	}

	// Initialize the streamer
	m_pStreamer = new CStreamer();

	// Initialize the time
	m_pTime = new CTime();

	// Initialize the traffic lights
	m_pTrafficLights = new CTrafficLights();

	// Initialize the client task manager
	m_pClientTaskManager = new CClientTaskManager();

	// Initialize the game
	CGame::Initialize();

	// Install the XLive hook
	CXLiveHook::Install();

	// Install the Direct3D hook
	CDirect3DHook::Install();

	// Install the DirectInput hook
	CDirectInputHook::Install();

#ifdef IVMP_DEBUG
	// Install the Cursor hook
	CCursorHook::Install();

	// Create our Debug View
	m_pDebugView = new CDebugView();
#endif

	// Initialize the client script manager
	m_pClientScriptManager = new CClientScriptManager();

	// Initialize the events manager
	m_pEvents = new CEvents();

	// Initialize the network module, if it fails, exit
	if(!CNetworkModule::Init())
	{
		CLogFile::Printf("Failed to initialize the network module!\n");
		return false;
	}

	// Initialize the file transfer manager
	m_pFileTransfer = new CFileTransferManager();

	// Initialize the http client
	m_pHttpClient = new CHttpClient();
	m_pHttpClient->SetRequestTimeout(10000);
	m_pHttpClient->SetHost(MASTERLIST_ADDRESS);
	return true;
}
示例#8
0
// areFrequentEventsEnabled()
int CServerNatives::AreFrequentEventsEnabled(lua_State * pVM)
{
	script_pushbool(pVM, CVAR_GET_BOOL("frequentevents"));
	return 1;
}
void CServerRPCHandler::PlayerConnect(CBitStream * pBitStream, CPlayerSocket * pSenderSocket)
{
	// Ensure we have a valid bit stream
	if(!pBitStream)
		return;

	// Read packet data
	EntityId playerId = pSenderSocket->playerId;
	int iVersion;
	pBitStream->Read(iVersion);

	String strName;
	pBitStream->Read(strName);

	CheckGTAFiles pCheckFiles;
	bool bGameFilesModded = false;
	pBitStream->Read((char *)&pCheckFiles, sizeof(CheckGTAFiles));

	if(pCheckFiles.bGTAFileChecksum || pCheckFiles.bHandleFileChanged) {
		if(CVAR_GET_BOOL("checkGTAFiles"))
			CLogFile::Printf("[FileCheckSum] Warning, detected modded GTA IV files at player %s", strName.Get());

		bGameFilesModded = true;
	}

	// Apply serial and ip
	String strIP = pSenderSocket->GetAddress(true);
	String strSerial = pSenderSocket->GetSerial();

	// Setup our reply packet
	CBitStream bsSend;
	
	// Check for matching network versions
	if(iVersion != NETWORK_VERSION)
	{
		bsSend.Write(REFUSE_REASON_INVALID_VERSION);
		g_pNetworkManager->RPC(RPC_ConnectionRefused, &bsSend, PRIORITY_HIGH, RELIABILITY_RELIABLE, playerId, false);
		CLogFile::Printf("[Connect] Authorization for %s (%s) failed (Invalid version (Client: %x, Server: %x))!", strIP.Get(), strName.Get(), iVersion, NETWORK_VERSION);
		return;
	}

	// Check that their name is valid
	if(strName.IsEmpty() || strName.GetLength() > MAX_NAME_LENGTH)
	{
		bsSend.Write(REFUSE_REASON_NAME_INVALID);
		g_pNetworkManager->RPC(RPC_ConnectionRefused, &bsSend, PRIORITY_HIGH, RELIABILITY_RELIABLE, playerId, false);
		CLogFile::Printf("[Connect] Authorization for %s (%s) failed (name invalid).", strIP.Get(), strName.Get());
		return;
	}

	// Check that their name is not already in use
	if(g_pPlayerManager->IsNameInUse(strName))
	{
		bsSend.Write(REFUSE_REASON_NAME_IN_USE);
		g_pNetworkManager->RPC(RPC_ConnectionRefused, &bsSend, PRIORITY_HIGH, RELIABILITY_RELIABLE, playerId, false);
		CLogFile::Printf("[Connect] Authorization for %s (%s) failed (name in use).", strIP.Get(), strName.Get());
		return;
	}

	CSquirrelArguments nameCheckArguments;
	nameCheckArguments.push(playerId);
	nameCheckArguments.push(strName);

	if(g_pEvents->Call("playerNameCheck", &nameCheckArguments).GetInteger() != 1)
	{
		bsSend.Write(REFUSE_REASON_NAME_INVALID);
		g_pNetworkManager->RPC(RPC_ConnectionRefused, &bsSend, PRIORITY_HIGH, RELIABILITY_RELIABLE, playerId, false);
		CLogFile::Printf("[Connect] Authorization for %s (%s) failed (name invalid).", strIP.Get(), strName.Get());
		return;
	}

	// Call the playerAuth event, and process the return value
	CSquirrelArguments playerAuthArguments;
	playerAuthArguments.push(playerId);
	playerAuthArguments.push(strName);
	playerAuthArguments.push(strIP);
	playerAuthArguments.push(strSerial);
	playerAuthArguments.push(bGameFilesModded);

	if(g_pEvents->Call("playerAuth", &playerAuthArguments).GetInteger() != 1)
	{
		bsSend.Write(REFUSE_REASON_ABORTED_BY_SCRIPT);
		g_pNetworkManager->RPC(RPC_ConnectionRefused, &bsSend, PRIORITY_HIGH, RELIABILITY_RELIABLE, playerId, false);
		CLogFile::Printf("[Connect] Authorization for %s (%s) failed (aborted by script).", strIP.Get(), strName.Get());
		return;
	}

	CLogFile::Printf("[Connect] Authorization for %s (%s) complete.", strIP.Get(), strName.Get());

	// Setup the player
	g_pPlayerManager->Add(playerId, strName);
	CPlayer * pPlayer = g_pPlayerManager->GetAt(playerId);
	
	// Check player creation
	if(!pPlayer)
	{
		CLogFile::Printf("[Connect] Failed to create player instance for %s.", strName.Get());
		return;
	}

	// Apply files
	pPlayer->SetFileCheck(pCheckFiles);

	// Let the vehicle manager handle the client join
	g_pVehicleManager->HandleClientJoin(playerId);

	// Let the player manager handle the client join
	g_pPlayerManager->HandleClientJoin(playerId);

	// Let the object manager handle the client join
	g_pObjectManager->HandleClientJoin(playerId);

	// Let the fire manager handle the client join
	g_pObjectManager->HandleClientJoinFire(playerId);

	// Let the blip manager handle the client join
	g_pBlipManager->HandleClientJoin(playerId);

	// Let the checkpoint manager handle the client join
	g_pCheckpointManager->HandleClientJoin(playerId);

	// Let the pickup manager handle the client join
	g_pPickupManager->HandleClientJoin(playerId);

	// Let the actor manager handle the client join
	g_pActorManager->HandleClientJoin(playerId);

	g_p3DLabelManager->HandleClientJoin(playerId);

	// Construct the reply bit stream
	bsSend.Write(playerId);
	bsSend.Write(CVAR_GET_STRING("hostname"));
	bsSend.WriteBit(CVAR_GET_BOOL("paynspray"));
	bsSend.WriteBit(CVAR_GET_BOOL("autoaim"));
	bsSend.Write(pPlayer->GetColor());
	bsSend.Write(CVAR_GET_STRING("httpserver"));
	bsSend.Write((unsigned short)CVAR_GET_INTEGER("httpport"));
	bsSend.Write((unsigned char)CVAR_GET_INTEGER("weather"));
	bsSend.WriteBit(CVAR_GET_BOOL("guinametags"));
	bsSend.WriteBit(CVAR_GET_BOOL("vehicledamage"));
	bsSend.WriteBit(CVAR_GET_BOOL("vehiclewaterdeath"));
	bsSend.WriteBit(CVAR_GET_BOOL("headmovement"));
	bsSend.Write(CVAR_GET_INTEGER("maxplayers"));

	// Time
	unsigned char ucHour = 0, ucMinute = 0;
	g_pTime->GetTime(&ucHour, &ucMinute);
	bsSend.Write((unsigned char)(ucHour + (24 * (1 + g_pTime->GetDayOfWeek()))));
	bsSend.Write(ucMinute);

	if(g_pTime->GetMinuteDuration() != CTime::DEFAULT_MINUTE_DURATION)
	{
		bsSend.Write1();
		bsSend.Write(g_pTime->GetMinuteDuration());
	}
	else
		bsSend.Write0();

	// Traffic Lights
	bsSend.Write((unsigned char)g_pTrafficLights->GetSetState());
	bsSend.Write(g_pTrafficLights->GetTimeThisCylce());

	if(g_pTrafficLights->GetSetState() != CTrafficLights::TRAFFIC_LIGHT_STATE_DISABLED_DISABLED)
	{
		if(g_pTrafficLights->IsLocked())
			bsSend.Write1();
		else
			bsSend.Write0();

		if(!g_pTrafficLights->IsUsingDefaultDurations())
		{
			bsSend.Write1();
			if(g_pTrafficLights->GetSetState() >= CTrafficLights::TRAFFIC_LIGHT_STATE_FLASHING_FLASHING)
				bsSend.Write(g_pTrafficLights->GetYellowDuration());
			else
			{
				bsSend.Write(g_pTrafficLights->GetGreenDuration());
				bsSend.Write(g_pTrafficLights->GetYellowDuration());
				bsSend.Write(g_pTrafficLights->GetRedDuration());
			}
		}
		else
			bsSend.Write0();
	}

	// Send the joined game RPC
	g_pNetworkManager->RPC(RPC_JoinedGame, &bsSend, PRIORITY_HIGH, RELIABILITY_RELIABLE_ORDERED, playerId, false);

	// Inform the resource file manager of the client join
	g_pClientResourceFileManager->HandleClientJoin(playerId);

	// Inform the script file manager of the client join
	g_pClientScriptFileManager->HandleClientJoin(playerId);

	CLogFile::Printf("[Join] %s (%d) is joining the game.", strName.Get(), playerId);

	CSquirrelArguments playerConnectArguments;
	playerConnectArguments.push(playerId);
	playerConnectArguments.push(strName);
	g_pEvents->Call("playerConnect", &playerConnectArguments);
}