Upgrading the normal sound hook for games like CS:GO
This commit is contained in:
parent
ff27484527
commit
cddae6f456
@ -283,6 +283,57 @@ void SoundHooks::OnEmitAmbientSound(int entindex, const Vector &pos, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
|
// This should probably be moved to the gamedata
|
||||||
|
#define SOUND_ENTRY_HASH_SEED 0x444F5441
|
||||||
|
|
||||||
|
uint32 GenerateSoundEntryHash(char const *pSoundEntry)
|
||||||
|
{
|
||||||
|
// First we need to convert the sound entry to lowercase before we calculate the hash
|
||||||
|
int nSoundEntryLength = strlen(pSoundEntry);
|
||||||
|
char *pSoundEntryLowerCase = (char *)stackalloc(nSoundEntryLength + 1);
|
||||||
|
|
||||||
|
for (int nIndex = 0; nIndex < nSoundEntryLength; nIndex++)
|
||||||
|
pSoundEntryLowerCase[nIndex] = tolower(pSoundEntry[nIndex]);
|
||||||
|
|
||||||
|
// Second we need to calculate the hash using the algorithm reconstructed from CS:GO
|
||||||
|
const uint32 nMagicNumber = 0x5bd1e995;
|
||||||
|
|
||||||
|
uint32 nSoundHash = SOUND_ENTRY_HASH_SEED ^ nSoundEntryLength;
|
||||||
|
|
||||||
|
unsigned char *pData = (unsigned char *)pSoundEntryLowerCase;
|
||||||
|
|
||||||
|
while (nSoundEntryLength >= 4)
|
||||||
|
{
|
||||||
|
uint32 nLittleDWord = LittleDWord(*(uint32 *)pData);
|
||||||
|
|
||||||
|
nLittleDWord *= nMagicNumber;
|
||||||
|
nLittleDWord ^= nLittleDWord >> 24;
|
||||||
|
nLittleDWord *= nMagicNumber;
|
||||||
|
|
||||||
|
nSoundHash *= nMagicNumber;
|
||||||
|
nSoundHash ^= nLittleDWord;
|
||||||
|
|
||||||
|
pData += 4;
|
||||||
|
nSoundEntryLength -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (nSoundEntryLength)
|
||||||
|
{
|
||||||
|
case 3: nSoundHash ^= pData[2] << 16;
|
||||||
|
case 2: nSoundHash ^= pData[1] << 8;
|
||||||
|
case 1: nSoundHash ^= pData[0];
|
||||||
|
nSoundHash *= nMagicNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
nSoundHash ^= nSoundHash >> 13;
|
||||||
|
nSoundHash *= nMagicNumber;
|
||||||
|
nSoundHash ^= nSoundHash >> 15;
|
||||||
|
|
||||||
|
return nSoundHash;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
int SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample,
|
int SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSoundEntry, unsigned int nSoundEntryHash, const char *pSample,
|
||||||
float flVolume, soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
float flVolume, soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
|
||||||
@ -306,6 +357,15 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
|
|||||||
char buffer[PLATFORM_MAX_PATH];
|
char buffer[PLATFORM_MAX_PATH];
|
||||||
strcpy(buffer, pSample);
|
strcpy(buffer, pSample);
|
||||||
|
|
||||||
|
char soundEntry[PLATFORM_MAX_PATH];
|
||||||
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
|
strcpy(soundEntry, pSoundEntry);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE < SE_PORTAL2
|
||||||
|
int nSeed = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++)
|
for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++)
|
||||||
{
|
{
|
||||||
int players[SM_MAXPLAYERS], size;
|
int players[SM_MAXPLAYERS], size;
|
||||||
@ -321,6 +381,8 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
|
|||||||
pFunc->PushCellByRef(reinterpret_cast<cell_t *>(&iSoundlevel));
|
pFunc->PushCellByRef(reinterpret_cast<cell_t *>(&iSoundlevel));
|
||||||
pFunc->PushCellByRef(&iPitch);
|
pFunc->PushCellByRef(&iPitch);
|
||||||
pFunc->PushCellByRef(&iFlags);
|
pFunc->PushCellByRef(&iFlags);
|
||||||
|
pFunc->PushStringEx(soundEntry, sizeof(soundEntry), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
|
||||||
|
pFunc->PushCellByRef(&nSeed);
|
||||||
g_InSoundHook = true;
|
g_InSoundHook = true;
|
||||||
pFunc->Execute(&res);
|
pFunc->Execute(&res);
|
||||||
g_InSoundHook = false;
|
g_InSoundHook = false;
|
||||||
@ -360,6 +422,16 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
|
if (strcmp(pSoundEntry, soundEntry) != 0 || strcmp(pSample, buffer) != 0)
|
||||||
|
{
|
||||||
|
if (strcmp(soundEntry, buffer) == 0)
|
||||||
|
nSoundEntryHash = -1;
|
||||||
|
else if (strcmp(soundEntry, "") != 0)
|
||||||
|
nSoundEntryHash = GenerateSoundEntryHash(soundEntry);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CellRecipientFilter crf;
|
CellRecipientFilter crf;
|
||||||
crf.Initialize(players, size);
|
crf.Initialize(players, size);
|
||||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
@ -368,7 +440,7 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
|
|||||||
-1,
|
-1,
|
||||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t,
|
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char*, unsigned int, const char*, float, soundlevel_t,
|
||||||
int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound),
|
int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound),
|
||||||
(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, iSoundlevel, nSeed, iFlags, iPitch, pOrigin,
|
(crf, iEntIndex, iChannel, soundEntry, nSoundEntryHash, buffer, flVolume, iSoundlevel, nSeed, iFlags, iPitch, pOrigin,
|
||||||
pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
|
pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
|
||||||
);
|
);
|
||||||
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
|
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
|
||||||
@ -421,6 +493,15 @@ void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChan
|
|||||||
char buffer[PLATFORM_MAX_PATH];
|
char buffer[PLATFORM_MAX_PATH];
|
||||||
strcpy(buffer, pSample);
|
strcpy(buffer, pSample);
|
||||||
|
|
||||||
|
char soundEntry[PLATFORM_MAX_PATH];
|
||||||
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
|
strcpy(soundEntry, pSoundEntry);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE < SE_PORTAL2
|
||||||
|
int nSeed = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++)
|
for (iter=m_NormalFuncs.begin(); iter!=m_NormalFuncs.end(); iter++)
|
||||||
{
|
{
|
||||||
int players[SM_MAXPLAYERS], size;
|
int players[SM_MAXPLAYERS], size;
|
||||||
@ -436,6 +517,8 @@ void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChan
|
|||||||
pFunc->PushCellByRef(&sndlevel);
|
pFunc->PushCellByRef(&sndlevel);
|
||||||
pFunc->PushCellByRef(&iPitch);
|
pFunc->PushCellByRef(&iPitch);
|
||||||
pFunc->PushCellByRef(&iFlags);
|
pFunc->PushCellByRef(&iFlags);
|
||||||
|
pFunc->PushStringEx(soundEntry, sizeof(soundEntry), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
|
||||||
|
pFunc->PushCellByRef(&nSeed);
|
||||||
g_InSoundHook = true;
|
g_InSoundHook = true;
|
||||||
pFunc->Execute(&res);
|
pFunc->Execute(&res);
|
||||||
g_InSoundHook = false;
|
g_InSoundHook = false;
|
||||||
@ -475,6 +558,16 @@ void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChan
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
|
if (strcmp(pSoundEntry, soundEntry) != 0 || strcmp(pSample, buffer) != 0)
|
||||||
|
{
|
||||||
|
if (strcmp(soundEntry, buffer) == 0)
|
||||||
|
nSoundEntryHash = -1;
|
||||||
|
else if (strcmp(soundEntry, "") != 0)
|
||||||
|
nSoundEntryHash = GenerateSoundEntryHash(soundEntry);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CellRecipientFilter crf;
|
CellRecipientFilter crf;
|
||||||
crf.Initialize(players, size);
|
crf.Initialize(players, size);
|
||||||
#if SOURCE_ENGINE >= SE_PORTAL2
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
@ -483,7 +576,7 @@ void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChan
|
|||||||
-1,
|
-1,
|
||||||
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float,
|
static_cast<int (IEngineSound::*)(IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float,
|
||||||
int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound),
|
int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int)>(&IEngineSound::EmitSound),
|
||||||
(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)),
|
(crf, iEntIndex, iChannel, soundEntry, nSoundEntryHash, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)),
|
||||||
nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
|
nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
|
||||||
);
|
);
|
||||||
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
|
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
|
||||||
|
@ -307,6 +307,8 @@ typedef AmbientSHook = function Action (
|
|||||||
* @param level Sound level.
|
* @param level Sound level.
|
||||||
* @param pitch Sound pitch.
|
* @param pitch Sound pitch.
|
||||||
* @param flags Sound flags.
|
* @param flags Sound flags.
|
||||||
|
* @param soundEntry Game sound entry name. (Used in engines newer than Portal 2)
|
||||||
|
* @param seed Sound seed. (Used in engines newer than Portal 2)
|
||||||
* @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it,
|
* @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it,
|
||||||
* Plugin_Changed when any parameter has been modified.
|
* Plugin_Changed when any parameter has been modified.
|
||||||
*/
|
*/
|
||||||
@ -319,7 +321,9 @@ typedef NormalSHook = function Action (
|
|||||||
float &volume,
|
float &volume,
|
||||||
int &level,
|
int &level,
|
||||||
int &pitch,
|
int &pitch,
|
||||||
int &flags
|
int &flags,
|
||||||
|
char soundEntry[PLATFORM_MAX_PATH],
|
||||||
|
int &seed
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user