diff --git a/AMBuilder b/AMBuilder index be3ff3a..b2aa758 100644 --- a/AMBuilder +++ b/AMBuilder @@ -31,7 +31,7 @@ else: project.sources += sourceFiles -for sdk_name in ['css', 'tf2', 'dods', 'hl2dm', 'csgo', 'l4d']: +for sdk_name in ['css', 'tf2', 'dods', 'hl2dm', 'csgo', 'l4d', 'l4d2']: if sdk_name not in Extension.sdks: continue sdk = Extension.sdks[sdk_name] diff --git a/forwards.cpp b/forwards.cpp index 67d5aa8..5044103 100644 --- a/forwards.cpp +++ b/forwards.cpp @@ -54,7 +54,7 @@ SH_DECL_HOOK1_void(IClient, Disconnect, SH_NOATTRIB, 0, const char *); SH_DECL_MANUALHOOK1_void(CBaseClient_Disconnect, 0, 0, 0, const char *); #endif // !WIN32 -#elif SOURCE_ENGINE == SE_LEFT4DEAD +#elif SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 SH_DECL_MANUALHOOK10(CHLTVServer_ConnectClient, 0, 0, 0, IClient *, const netadr_t &, int, int, int, const char *, const char *, const char *, int, CUtlVector &, bool); SH_DECL_MANUALHOOK1_void_vafmt(CHLTVServer_RejectConnection, 0, 0, 0, const netadr_t &); SH_DECL_HOOK0_void_vafmt(IClient, Disconnect, SH_NOATTRIB, 0); @@ -296,7 +296,7 @@ char passwordBuffer[255]; #if SOURCE_ENGINE == SE_CSGO // CHLTVServer::ConnectClient(ns_address const&, int, int, int, char const*, char const*, char const*, int, CUtlVector *, CUtlMemory *, int>> &, bool, CrossPlayPlatform_t, unsigned char const*, int) IClient *CForwardManager::OnSpectatorConnect(const netadr_t & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown) -#elif SOURCE_ENGINE == SE_LEFT4DEAD +#elif SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 IClient *CForwardManager::OnSpectatorConnect(const netadr_t & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector &pSplitPlayerConnectVector, bool bUnknown) #else 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) @@ -334,7 +334,7 @@ IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol, { if (m_bHasRejectConnectionOffset) { -#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_LEFT4DEAD +#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); @@ -346,7 +346,7 @@ IClient *CForwardManager::OnSpectatorConnect(netadr_t & address, int nProtocol, // 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 +#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); diff --git a/forwards.h b/forwards.h index ddf0ec5..2ce45f0 100644 --- a/forwards.h +++ b/forwards.h @@ -99,7 +99,7 @@ private: #if SOURCE_ENGINE == SE_CSGO void OnStopRecording(CGameInfo const *info); IClient *OnSpectatorConnect(const netadr_t & address, int nProtocol, int iChallenge, int nAuthProtocol, const char *pchName, const char *pchPassword, const char *pCookie, int cbCookie, CUtlVector &pSplitPlayerConnectVector, bool bUnknown, CrossPlayPlatform_t platform, const unsigned char *pUnknown, int iUnknown); -#elif SOURCE_ENGINE == SE_LEFT4DEAD +#elif SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 void OnStopRecording(); IClient *OnSpectatorConnect(const netadr_t & address, int nProtocol, int iChallenge, int iClientChallenge, const char * pchName, const char * pchPassword, const char * pCookie, int, CUtlVector &pSplitPlayerConnectVector, bool bUnknown); #else diff --git a/hltvserverwrapper.cpp b/hltvserverwrapper.cpp index 1b51571..4a976a3 100644 --- a/hltvserverwrapper.cpp +++ b/hltvserverwrapper.cpp @@ -254,7 +254,7 @@ void HLTVServerWrapper::OnCGameClient_ClientPrintf_Post(const char* buf) IClient *pClient = (IClient *)((intptr_t)pGameClient + 4); HandleClientPrintf(pClient, buf); -#if SOURCE_ENGINE == SE_LEFT4DEAD +#if SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 // Left4Dead doesn't check the netchan before using it RETURN_META(MRES_SUPERCEDE); #else @@ -267,7 +267,7 @@ void HLTVServerWrapper::OnIClient_ClientPrintf_Post(const char* buf) IClient *pClient = META_IFACEPTR(IClient); HandleClientPrintf(pClient, buf); -#if SOURCE_ENGINE == SE_LEFT4DEAD +#if SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 // Left4Dead doesn't check the netchan before using it RETURN_META(MRES_SUPERCEDE); #else diff --git a/ihltvdemorecorder.h b/ihltvdemorecorder.h index 04f2b50..50077ef 100644 --- a/ihltvdemorecorder.h +++ b/ihltvdemorecorder.h @@ -26,7 +26,7 @@ public: virtual void RecordPacket(void) = 0; virtual void RecordServerClasses(ServerClass *pClasses) = 0; virtual void RecordStringTables(void) = 0; -#if SOURCE_ENGINE == SE_LEFT4DEAD +#if SOURCE_ENGINE == SE_LEFT4DEAD || SOURCE_ENGINE == SE_LEFT4DEAD2 virtual void RecordCustomData(int, void const *, unsigned int) = 0; #endif diff --git a/sourcetvmanager.games.txt b/sourcetvmanager.games.txt index 92a9f44..45270a9 100644 --- a/sourcetvmanager.games.txt +++ b/sourcetvmanager.games.txt @@ -506,4 +506,174 @@ } } } + + "left4dead2" + { + "Addresses" + { + "host_client" + { + "windows" + { + "signature" "host_client" + "read" "32" + } + "linux" + { + "signature" "host_client" + } + } + + "CHLTVServer::m_DemoRecorder" + { + "windows" + { + "signature" "CHLTVServer::Shutdown" + "read" "5" + } + "linux" + { + "signature" "CHLTVServer::Shutdown" + "read" "12" + } + } + } + "Offsets" + { + "CNetChan::SendNetMsg" + { + "windows" "41" + "linux" "42" + } + + "CBaseClient::m_NetChannel" + { + "windows" "224" + "linux" "228" + } + + "CGameClient::ClientPrintf" + { + "linux" "26" + } + + "CBaseServer::BroadcastPrintf" + { + "windows" "36" + "linux" "37" + } + + "CHLTVServer::ConnectClient" + { + "windows" "50" + "linux" "51" + } + + "CHLTVServer::RejectConnection" + { + "windows" "48" + "linux" "49" + } + + "CHLTVServer::GetChallengeType" + { + "windows" "54" + "linux" "55" + } + + "CBaseClient::ActivatePlayer" + { + "windows" "15" + "linux" "61" + } + + "CBaseClient::FireGameEvent" + { + "windows" "1" + "linux" "2" + } + + "CBaseClient::Disconnect" + { + "linux" "15" + } + + "CHLTVServer::Shutdown" + { + "windows" "42" + "linux" "43" + } + + "CHLTVDirector::m_iPVSEntity" + { + "windows" "16" + "linux" "16" + } + + "CHLTVDirector::m_vPVSOrigin" + { + "windows" "20" + "linux" "20" + } + + "CHLTVDirector::m_nNextShotTick" + { + "windows" "40" + "linux" "40" + } + "CHLTVDemoRecorder_BaseOffset" + { + "windows" "0" + "linux" "4" + } + } + "Signatures" + { + "host_client" + { + "library" "engine" + "linux" "@host_client" + // ping(CCommand const&) "Client ping times:\n" + "windows" "\x55\x8B\xEC\x51\x83\x3D\x2A\x2A\x2A\x2A\x01\x75\x2A" + } + + "CHLTVServer::BroadcastEventLocal" + { + "library" "engine" + "linux" "@_ZN11CHLTVServer19BroadcastEventLocalEP10IGameEventb" + // "SourceTV broadcast local event: %s\n" + "windows" "\x55\x8B\xEC\x81\xEC\x58\x04\x00\x00\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x53\x56" + } + + "CHLTVServer::BroadcastLocalChat" + { + "library" "engine" + "linux" "@_ZN11CHLTVServer18BroadcastLocalChatEPKcS1_" + // "hltv_chat" + "windows" "\x55\x8B\xEC\x81\xEC\x60\x04\x00\x00\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\x8B\x45\x0C\x53\x8B\x5D\x08\x56\x57\x8B\xF1" + } + + "CHLTVServer::Shutdown" + { + "library" "engine" + "linux" "@_ZN11CHLTVServer8ShutdownEv" + // "SourceTV stop." + "windows" "\x56\x8B\xF1\x8B\x86\x2A\x2A\x2A\x2A\x8B\x50\x2A\x8D\x8E\x2A\x2A\x2A\x2A\xFF\xD2\x8B\x86\x2A\x2A\x2A\x2A\x8B\x50\x2A\x8D\x8E" + } + + // StartRecording and StopRecording are virtual, but get called directly in the linux binary.. + // Need to add a detour. + "CHLTVDemoRecorder::StartRecording" + { + "library" "engine" + "linux" "@_ZN17CHLTVDemoRecorder14StartRecordingEPKcb" + } + + "CHLTVDemoRecorder::StopRecording" + { + "library" "engine" + "linux" "@_ZN17CHLTVDemoRecorder13StopRecordingEv" + } + } + } } \ No newline at end of file