Add IsClientTalking
This commit is contained in:
		
							parent
							
								
									d2905c03eb
								
							
						
					
					
						commit
						cfbaf18f66
					
				| @ -10,7 +10,9 @@ project = SM.HL2Project(builder, projectName + '.ext') | ||||
| project.sources += [ | ||||
|   'extension.cpp', | ||||
|   'ringbuffer.cpp', | ||||
|   '../../public/smsdk_ext.cpp' | ||||
|   '../../public/smsdk_ext.cpp', | ||||
|   '../../public/CDetour/detours.cpp', | ||||
|   '../../public/asm/asm.c', | ||||
| ] | ||||
| 
 | ||||
| for sdk_name in SM.sdks: | ||||
|  | ||||
							
								
								
									
										144
									
								
								extension.cpp
									
									
									
									
									
								
							
							
						
						
									
										144
									
								
								extension.cpp
									
									
									
									
									
								
							| @ -43,6 +43,7 @@ | ||||
| #include <iserver.h> | ||||
| #include <ISDKTools.h> | ||||
| 
 | ||||
| #include "CDetour/detours.h" | ||||
| #include "extension.h" | ||||
| 
 | ||||
| ConVar g_SmVoiceAddr("sm_voice_addr", "127.0.0.1", FCVAR_PROTECTED, "Voice server listen ip address."); | ||||
| @ -58,9 +59,36 @@ template <typename T> inline T min(T a, T b) { return a<b?a:b; } | ||||
| CVoice g_Interface; | ||||
| SMEXT_LINK(&g_Interface); | ||||
| 
 | ||||
| CGlobalVars *gpGlobals = NULL; | ||||
| ISDKTools *g_pSDKTools = NULL; | ||||
| IServer *iserver = NULL; | ||||
| SH_DECL_MANUALHOOK0(GetPlayerSlot, 0, 0, 0, int); // IClient::GetPlayerSlot
 | ||||
| 
 | ||||
| double g_fLastVoiceData[SM_MAXPLAYERS + 1]; | ||||
| 
 | ||||
| DETOUR_DECL_STATIC4(SV_BroadcastVoiceData, void, IClient *, pClient, int, nBytes, char *, data, int64, xuid) | ||||
| { | ||||
| 	g_Interface.OnBroadcastVoiceData(pClient, nBytes, data); | ||||
| 
 | ||||
| 	DETOUR_STATIC_CALL(SV_BroadcastVoiceData)(pClient, nBytes, data, xuid); | ||||
| } | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| DETOUR_DECL_STATIC2(SV_BroadcastVoiceData_LTCG, void, char *, data, int64, xuid) | ||||
| { | ||||
| 	IClient *pClient = NULL; | ||||
| 	int nBytes = 0; | ||||
| 
 | ||||
| 	__asm mov pClient, ecx; | ||||
| 	__asm mov nBytes, edx; | ||||
| 
 | ||||
| 	g_Interface.OnBroadcastVoiceData(pClient, nBytes, data); | ||||
| 
 | ||||
| 	__asm mov ecx, pClient; | ||||
| 	__asm mov edx, nBytes; | ||||
| 
 | ||||
| 	DETOUR_STATIC_CALL(SV_BroadcastVoiceData_LTCG)(data, xuid); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| double getTime() | ||||
| { | ||||
| @ -92,6 +120,7 @@ CVoice::CVoice() | ||||
| 	m_pMode = NULL; | ||||
| 	m_pCodec = NULL; | ||||
| 
 | ||||
| 	m_VoiceDetour = NULL; | ||||
| 	m_SV_BroadcastVoiceData = NULL; | ||||
| } | ||||
| 
 | ||||
| @ -114,47 +143,39 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late) | ||||
| 	} | ||||
| 
 | ||||
| 	int engineVersion = g_SMAPI->GetSourceEngineBuild(); | ||||
| 	int offsPlayerSlot = 0; | ||||
| 	void *adrVoiceData = NULL; | ||||
| 
 | ||||
| 	switch (engineVersion) | ||||
| 	{ | ||||
| 		case SOURCE_ENGINE_CSGO: | ||||
| #ifdef _WIN32 | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x81\xEC\xD0\x00\x00\x00\x53\x56\x57", 12); | ||||
| 			offsPlayerSlot = 15; | ||||
| 			adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x81\xEC\xD0\x00\x00\x00\x53\x56\x57", 12); | ||||
| #else | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| 			offsPlayerSlot = 16; | ||||
| 			adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| #endif | ||||
| 			break; | ||||
| 
 | ||||
| 		case SOURCE_ENGINE_LEFT4DEAD2: | ||||
| #ifdef _WIN32 | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x70\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\xA1\x2A\x2A\x2A\x2A\x53\x56", 23); | ||||
| 			offsPlayerSlot = 14; | ||||
| 			adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x70\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\xA1\x2A\x2A\x2A\x2A\x53\x56", 23); | ||||
| #else | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| 			offsPlayerSlot = 15; | ||||
| 			adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| #endif | ||||
| 			break; | ||||
| 
 | ||||
| 		case SOURCE_ENGINE_NUCLEARDAWN: | ||||
| #ifdef _WIN32 | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x58\x57\x33\xFF", 14); | ||||
| 			offsPlayerSlot = 14; | ||||
| 			adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x58\x57\x33\xFF", 14); | ||||
| #else | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| 			offsPlayerSlot = 15; | ||||
| 			adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| #endif | ||||
| 			break; | ||||
| 
 | ||||
| 		case SOURCE_ENGINE_INSURGENCY: | ||||
| #ifdef _WIN32 | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x74\x68\x2A\x2A\x2A\x2A\x8D\x4D\xE4\xE8", 15); | ||||
| 			offsPlayerSlot = 14; | ||||
| 			adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x74\x68\x2A\x2A\x2A\x2A\x8D\x4D\xE4\xE8", 15); | ||||
| #else | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| 			offsPlayerSlot = 15; | ||||
| 			adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| #endif | ||||
| 			break; | ||||
| 
 | ||||
| @ -164,11 +185,9 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late) | ||||
| 		case SOURCE_ENGINE_DODS: | ||||
| 		case SOURCE_ENGINE_SDK2013: | ||||
| #ifdef _WIN32 | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x50\x83\x78\x30", 14); | ||||
| 			offsPlayerSlot = 14; | ||||
| 			adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x50\x83\x78\x30", 14); | ||||
| #else | ||||
| 			m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| 			offsPlayerSlot = 15; | ||||
| 			adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx"); | ||||
| #endif | ||||
| 			break; | ||||
| 
 | ||||
| @ -179,13 +198,36 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late) | ||||
| 	} | ||||
| 	dlclose(pEngineSo); | ||||
| 
 | ||||
| 	m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)adrVoiceData; | ||||
| 	if(!m_SV_BroadcastVoiceData) | ||||
| 	{ | ||||
| 		g_SMAPI->Format(error, maxlength, "SV_BroadcastVoiceData sigscan failed."); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	SH_MANUALHOOK_RECONFIGURE(GetPlayerSlot, offsPlayerSlot, 0, 0); | ||||
| 	// Setup voice detour.
 | ||||
| 	CDetourManager::Init(g_pSM->GetScriptingEngine(), NULL); | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 	if (engineVersion == SOURCE_ENGINE_CSGO || engineVersion == SOURCE_ENGINE_INSURGENCY) | ||||
| 	{ | ||||
| 		m_VoiceDetour = DETOUR_CREATE_STATIC(SV_BroadcastVoiceData_LTCG, adrVoiceData); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		m_VoiceDetour = DETOUR_CREATE_STATIC(SV_BroadcastVoiceData, adrVoiceData); | ||||
| 	} | ||||
| #else | ||||
| 	m_VoiceDetour = DETOUR_CREATE_STATIC(SV_BroadcastVoiceData, adrVoiceData); | ||||
| #endif | ||||
| 
 | ||||
| 	if (!m_VoiceDetour) | ||||
| 	{ | ||||
| 		g_SMAPI->Format(error, maxlength, "SV_BroadcastVoiceData detour failed."); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	m_VoiceDetour->EnableDetour(); | ||||
| 
 | ||||
| 	// Init tcp server
 | ||||
| 	m_ListenSocket = socket(AF_INET, SOCK_STREAM, 0); | ||||
| @ -271,6 +313,7 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late) | ||||
| bool CVoice::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late) | ||||
| { | ||||
| 	GET_V_IFACE_CURRENT(GetEngineFactory, g_pCVar, ICvar, CVAR_INTERFACE_VERSION); | ||||
| 	gpGlobals = ismm->GetCGlobals(); | ||||
| 	ConVar_Register(0, this); | ||||
| 
 | ||||
| 	return true; | ||||
| @ -282,8 +325,37 @@ bool CVoice::RegisterConCommandBase(ConCommandBase *pVar) | ||||
| 	return META_REGCVAR(pVar); | ||||
| } | ||||
| 
 | ||||
| cell_t IsClientTalking(IPluginContext *pContext, const cell_t *params) | ||||
| { | ||||
| 	int client = params[1]; | ||||
| 
 | ||||
| 	if(client < 1 || client > SM_MAXPLAYERS) | ||||
| 	{ | ||||
| 		return pContext->ThrowNativeError("Client index %d is invalid", client); | ||||
| 	} | ||||
| 
 | ||||
| 	double d = gpGlobals->curtime - g_fLastVoiceData[client]; | ||||
| 
 | ||||
| 	if(d < 0) // mapchange
 | ||||
| 		return false; | ||||
| 
 | ||||
| 	if(d > 0.33) | ||||
| 		return false; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| const sp_nativeinfo_t MyNatives[] = | ||||
| { | ||||
| 	{ "IsClientTalking", IsClientTalking }, | ||||
| 	{ NULL, NULL } | ||||
| }; | ||||
| 
 | ||||
| void CVoice::SDK_OnAllLoaded() | ||||
| { | ||||
| 	sharesys->AddNatives(myself, MyNatives); | ||||
| 	sharesys->RegisterLibrary(myself, "Voice"); | ||||
| 
 | ||||
| 	SM_GET_LATE_IFACE(SDKTOOLS, g_pSDKTools); | ||||
| 	if(g_pSDKTools == NULL) | ||||
| 		smutils->LogError(myself, "SDKTools interface not found"); | ||||
| @ -297,6 +369,12 @@ void CVoice::SDK_OnUnload() | ||||
| { | ||||
| 	smutils->RemoveGameFrameHook(::OnGameFrame); | ||||
| 
 | ||||
| 	if(m_VoiceDetour) | ||||
| 	{ | ||||
| 		m_VoiceDetour->Destroy(); | ||||
| 		m_VoiceDetour = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if(m_ListenSocket != -1) | ||||
| 	{ | ||||
| 		close(m_ListenSocket); | ||||
| @ -325,6 +403,13 @@ void CVoice::OnGameFrame(bool simulating) | ||||
| 	HandleVoiceData(); | ||||
| } | ||||
| 
 | ||||
| void CVoice::OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data) | ||||
| { | ||||
| 	int client = pClient->GetPlayerSlot() + 1; | ||||
| 
 | ||||
| 	g_fLastVoiceData[client] = gpGlobals->curtime; | ||||
| } | ||||
| 
 | ||||
| void CVoice::HandleNetwork() | ||||
| { | ||||
| 	if(m_ListenSocket == -1) | ||||
| @ -553,7 +638,7 @@ void CVoice::HandleVoiceData() | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		SV_BroadcastVoiceData(pClient, FinalSize, aFinal); | ||||
| 		BroadcastVoiceData(pClient, FinalSize, aFinal); | ||||
| 	} | ||||
| 
 | ||||
| 	if(m_AvailableTime < getTime()) | ||||
| @ -562,7 +647,14 @@ void CVoice::HandleVoiceData() | ||||
| 	m_AvailableTime += (double)FramesAvailable * m_EncoderSettings.FrameTime; | ||||
| } | ||||
| 
 | ||||
| void CVoice::SV_BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData) | ||||
| void CVoice::BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData) | ||||
| { | ||||
| 	m_SV_BroadcastVoiceData(pClient, nBytes, pData, 0); | ||||
| 	#ifdef _WIN32 | ||||
| 	__asm mov ecx, pClient; | ||||
| 	__asm mov edx, nBytes; | ||||
| 
 | ||||
| 	DETOUR_STATIC_CALL(SV_BroadcastVoiceData_LTCG)((char *)pData, 0); | ||||
| 	#else | ||||
| 	DETOUR_STATIC_CALL(SV_BroadcastVoiceData)(pClient, nBytes, (char *)pData, 0); | ||||
| 	#endif | ||||
| } | ||||
|  | ||||
| @ -32,6 +32,7 @@ | ||||
| #ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ | ||||
| #define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ | ||||
| 
 | ||||
| #include <poll.h> | ||||
| #include "smsdk_ext.h" | ||||
| #include "celt_header.h" | ||||
| #include "ringbuffer.h" | ||||
| @ -49,6 +50,7 @@ typedef __int64		int64; | ||||
| typedef long long	int64; | ||||
| #endif | ||||
| 
 | ||||
| class CDetour; | ||||
| class IClient; | ||||
| typedef void (*t_SV_BroadcastVoiceData)(IClient *, int, unsigned char *, int64); | ||||
| 
 | ||||
| @ -135,6 +137,7 @@ public:  // IConCommandBaseAccessor | ||||
| public: | ||||
| 	CVoice(); | ||||
| 	void OnGameFrame(bool simulating); | ||||
| 	void OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data); | ||||
| 
 | ||||
| private: | ||||
| 	int m_ListenSocket; | ||||
| @ -169,11 +172,12 @@ private: | ||||
| 	CELTEncoder *m_pCodec; | ||||
| 
 | ||||
| 	t_SV_BroadcastVoiceData m_SV_BroadcastVoiceData; | ||||
| 	CDetour *m_VoiceDetour; | ||||
| 
 | ||||
| 	void HandleNetwork(); | ||||
| 	void OnDataReceived(CClient *pClient, int16_t *pData, size_t Samples); | ||||
| 	void HandleVoiceData(); | ||||
| 	void SV_BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData); | ||||
| 	void BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData); | ||||
| }; | ||||
| 
 | ||||
| #endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
 | ||||
|  | ||||
| @ -40,7 +40,7 @@ | ||||
| /* Basic information exposed publicly */ | ||||
| #define SMEXT_CONF_NAME			"Voice" | ||||
| #define SMEXT_CONF_DESCRIPTION	"Inject voice data over existing clients" | ||||
| #define SMEXT_CONF_VERSION		"1.0" | ||||
| #define SMEXT_CONF_VERSION		"1.1" | ||||
| #define SMEXT_CONF_AUTHOR		"BotoX" | ||||
| #define SMEXT_CONF_URL			"" | ||||
| #define SMEXT_CONF_LOGTAG		"VOICE" | ||||
| @ -61,7 +61,7 @@ | ||||
| /** Enable interfaces you want to use here by uncommenting lines */ | ||||
| //#define SMEXT_ENABLE_FORWARDSYS
 | ||||
| //#define SMEXT_ENABLE_HANDLESYS
 | ||||
| //#define SMEXT_ENABLE_PLAYERHELPERS
 | ||||
| #define SMEXT_ENABLE_PLAYERHELPERS | ||||
| //#define SMEXT_ENABLE_DBMANAGER
 | ||||
| #define SMEXT_ENABLE_GAMECONF | ||||
| #define SMEXT_ENABLE_MEMUTILS | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user