One easy way you can do this:
First read the orginal address for this function.
0xA87E08 for dvamp executable.
0xA87498 for normal PTS.
Lets call it UserSayOriginalAddr.
Then write the function hook at same address ( 4 bytes )
void CYourAwesomeClass::OnUserSay(User* pUser, WCHAR* pText)
{
//Check if user and socket is valid.
if(pUser->IsValidUser() && pUser->Socket->IsValidUserSocket())
{
bool bCustomSay = FALSE;
if(pText[0] == '~')
{
//Make some custom say if you write ~Hello for example.
BroadcastToAll(L"%ls: %ls", PlayerName, pText+1)....
bCustomSay = TRUE;
}
if(!bCustomSay)
{
//Return to orginal function if no custom say have been done.
typedef void (__fastcall*_FT)(User*, WCHAR*);
_FT f = (_FT)UserSayOriginalAddr;
f(pUser, pText);
}
}
}
That should work, Give it a try.
-manton