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