AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Snippets and Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=112)
-   -   Using SourceHook (https://forums.alliedmods.net/showthread.php?t=78669)

BeetleFart 10-08-2008 08:32

Using SourceHook
 
Ive seen some sourcecode I believe it was for sdktools...used for hooking into IVoiceServer.

Ive tried taking the source and hooking into the IVoiceServer myself In my plugin...but I cant get it to work.
As soon as I try to do the hook..it crashs
I call
SH_ADD_HOOK_MEMFUNC(IVoiceServer, SetClientListening, g_pVoiceServer, &g_EmtpyServerPlugin,&CEmptyServerPlugin::OnS etClientListening, false);
but am having trouble.
Can anyone help me out to be able to hook into the setclientlistening functions so I can set up a proper mute function?

pRED* 10-08-2008 16:05

Re: Using SourceHook
 
That line looks fine..

Probably need to see the full code to try spot the problem.

BeetleFart 10-08-2008 16:16

Re: Using SourceHook
 
I scrapped out the code from sdktools source that I have from somewhere.

I changed it a bit because I dont have a IPluginContext pointer (passing null to test but each use of it is checked).

PHP Code:

cell_t t[4];
t[0]=4;

I call  SetClientListeningFlags(NULL,t); to set it up passing in my index (4)









size_t g_VoiceFlags[65];
size_t g_VoiceFlagsCount 0;


SH_DECL_HOOK3(IVoiceServerSetClientListeningSH_NOATTRIB0boolintintbool);



static 
cell_t SetClientListeningFlags(IPluginContext pContext, const cell_t *params)
{
    
//IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
    
int index=params[1];

    
edict_t player=g_EmtpyServerPlugin.GetPlayer(index);
    if (!
player)
    {
        return 
1;
        
//return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
    
}
     else if (
player->IsFree()) {
        return 
1;
        
//return pContext->ThrowNativeError("Client %d is not connected", params[1]);
    
}

    if (!
params[2] && g_VoiceFlags[params[1]])
    {
        if (!--
g_VoiceFlagsCount)
        {
            
SH_REMOVE_HOOK_MEMFUNC(IVoiceServerSetClientListeningg_pVoiceServer,&g_EmtpyServerPlugin, &CEmptyServerPlugin::OnSetClientListeningfalse);
        }
    } else if (!
g_VoiceFlags[params[1]] && params[2]) {

        if (!
g_VoiceFlagsCount++)
        {
            
//SH_ADD_HOOK_MEMFUNC(IVoiceServer, SetClientListening, g_pVoiceServer, &g_EmtpyServerPlugin,&CEmptyServerPlugin::OnSetClientListening, false);
            
SH_ADD_HOOK_MEMFUNC(IVoiceServerSetClientListeningg_pVoiceServer,&g_EmtpyServerPlugin,&CEmptyServerPlugin::OnSetClientListeningfalse);
        }
    }

    
g_VoiceFlags[params[1]] = params[2];

    return 
1;
}

static 
cell_t GetClientListeningFlags(IPluginContext *pContext, const cell_t *params)
{
//    IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
    
edict_t player=g_EmtpyServerPlugin.GetPlayer(params[1]);
    if (
player == NULL)
    {   if(
pContext)
        return 
pContext->ThrowNativeError("Client index %d is invalid"params[1]);

    }
    else 
    if (
player->IsFree()) 
    { if(
pContext)
        return 
pContext->ThrowNativeError("Client %d is not connected"params[1]);
    }

    return 
g_VoiceFlags[params[1]];
}

static 
cell_t SetClientListening(IPluginContext *pContext, const cell_t *params)
{
    
//IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
    
edict_t player=g_EmtpyServerPlugin.GetPlayer(params[1]);
    if (
player == NULL)
    { if(
pContext)
        return 
pContext->ThrowNativeError("Client index %d is invalid"params[1]);
    } else if (
player->IsFree())
    { if(
pContext)
        return 
pContext->ThrowNativeError("Client %d is not connected"params[1]);
    }

    
bool bListen = !params[3] ? false true;

    return 
g_pVoiceServer->SetClientListening(params[1], params[2], bListen) ? 0;
}

static 
cell_t GetClientListening(IPluginContext *pContext, const cell_t *params)
{
    
//IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
    
edict_t player=g_EmtpyServerPlugin.GetPlayer(params[1]);
    if (
player == NULL)
    { if(
pContext)
        return 
pContext->ThrowNativeError("Client index %d is invalid"params[1]);
    } else if (
player->IsFree()) {
         if(
pContext)
        return 
pContext->ThrowNativeError("Client %d is not connected"params[1]);
    }

    return 
g_pVoiceServer->GetClientListening(params[1], params[2]) ? 0;
}



bool CEmptyServerPlugin::OnSetClientListening(int iReceiverint iSenderbool bListen)
{
    if (
g_VoiceFlags[iSender] & SPEAK_MUTED)
    {
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSenderfalse));
    }

    if ((
g_VoiceFlags[iSender] & SPEAK_ALL) || (g_VoiceFlags[iReceiver] & SPEAK_LISTENALL))
    {
        
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSendertrue));
    }

    if ((
g_VoiceFlags[iSender] & SPEAK_TEAM) || (g_VoiceFlags[iReceiver] & SPEAK_LISTENTEAM))
    {
    
        
edict_t pReceiver=GetPlayer(iReceiver);
        
edict_t pSender=GetPlayer(iSender);
        
//IGamePlayer *pReceiver = playerhelpers->GetGamePlayer(iReceiver);
        //IGamePlayer *pSender = playerhelpers->GetGamePlayer(iSender);

        //if (pReceiver && pSender && pReceiver->IsInGame() && pSender->IsInGame())
        
if (pReceiver && pSender)
        {
            
IPlayerInfo *pRInfo playerinfomanager->GetPlayerInfo(pReceiver);//pReceiver->GetPlayerInfo();
            
IPlayerInfo *pSInfo =  playerinfomanager->GetPlayerInfo(pSender);//pSender->GetPlayerInfo();

            //if (pRInfo && pSInfo && pRInfo->GetTeamIndex() == pSInfo->GetTeamIndex())
            
if (pRInfo && pSInfo && pRInfo->GetTeamIndex() == pSInfo->GetTeamIndex())
            {
                
RETURN_META_VALUE_NEWPARAMS(MRES_IGNOREDbListen, &IVoiceServer::SetClientListening, (iReceiveriSendertrue));
            }
        }
    }

    
RETURN_META_VALUE(MRES_IGNOREDbListen);
}







void CEmptyServerPlugin::OnClientDisconnecting(int client)
{
    if (
g_VoiceFlags[client])
    {
        
g_VoiceFlags[client] = 0;
        if (!--
g_VoiceFlagsCount)
        {
            
//SH_REMOVE_HOOK_MEMFUNC(IVoiceServer, SetClientListening, g_pVoiceServer , &g_SdkTools, &SDKTools::OnSetClientListening, false);
            
SH_REMOVE_HOOK_MEMFUNC(IVoiceServerSetClientListeningg_pVoiceServer , &g_EmtpyServerPlugin, &CEmptyServerPlugin::OnSetClientListeningfalse);
          
        }
    }
}



sp_nativeinfo_t g_VoiceNatives[] =
{
    {
"SetClientListeningFlags",        SetClientListeningFlags},
    {
"GetClientListeningFlags",        GetClientListeningFlags},
    {
"SetClientListening",            SetClientListening},
    {
"GetClientListening",            GetClientListening},
    {
NULL,                            NULL},
}; 


pRED* 10-08-2008 16:42

Re: Using SourceHook
 
Params arrays have the first index (0) as the number of params.

Notice you set
t[0] = 4;
then
int index=params[1];

t[1] is uninitialised..

You don't need the sp_nativeinfo_t since thats just to register the commands as natives.

BeetleFart 10-08-2008 17:40

Re: Using SourceHook
 
i actually have it
t[0]=4;
t[1]=4;
I call the function and step thru it until it does the sh_add_hook_memfunc
and it then crashs at the
SH_DECL_HOOK3(IVoiceServer, SetClientListening, SH_NOATTRIB, 0, bool, int, int, bool);
line of code

pRED* 10-08-2008 19:14

Re: Using SourceHook
 
Thought that sounded too easy.

One of the pointers you are passing maybe?
g_pVoiceServer?

BeetleFart 10-08-2008 22:23

Re: Using SourceHook
 
i verified its not null ...
and its appears good in :Load

BeetleFart 10-09-2008 13:38

Re: Using SourceHook
 
When I Call the SH_ADD_HOOK_MEMFUNC(IVoiceServer, SetClientListening, g_pVoiceServer,&g_EmtpyServerPlugin,&CEmptySe rverPlugin::OnSetClientListening, false);

g_pVoiceServer is valid, g_EmptyServerPlugin is My main plugin class
and is valid as well..
I still dont see why it crashs...
with a breakpoint on SH_DECL_HOOK3
it appears to be hooking in ...i see it going thru the macro's etc for fastdelegate etc..
but 3rd time it goes thru sh_decl_hook3 it crashs

does the class that I pass in for handler_inst have to be derived from a specific class or something?

BeetleFart 10-09-2008 15:41

Re: Using SourceHook
 
The problem is with my not initializing source hook variable
SourceHook::ISourceHook *g_SHPtr

How do I initialize sourcehook correctly.
Im trying to follow the wiki at
http://wiki.alliedmods.net/SourceHoo...t#Simple_Hooks
but Im not having much luck.

pRED* 10-09-2008 15:59

Re: Using SourceHook
 
Is this a metamod plugin or a VSP?

The embedding section on that wiki page suggests that multiple versions of sourcehook in the same process will probably conflict, so not entirely sure how you'd add it to a VSP if metamod is running.

If it's metamod you need something like this in your metamod load function:

g_SHPtr = static_cast<SourceHook::ISourceHook *>(ismm->MetaFactory(MMIFACE_SOURCEHOOK, NULL, NULL));
g_PLID = id;

or look at the PLUGIN_SAVEVARS() macro in ISmmPlugin.h

BeetleFart 10-09-2008 16:01

Re: Using SourceHook
 
its a vsp..

Im trying to find the lastest single version of sourcehook.
to learn this on.
Ill check out the PLUGIN_SAVEVARS() macro in ISmmPlugin.h

pRED* 10-09-2008 16:03

Re: Using SourceHook
 
PLUGIN_SAVEVARS() relies on the metamod load forward to get all the pointers, which you won't have.

Have you followed the embedding SourceHook bit at the bottom of that wiki page?

BeetleFart 10-09-2008 16:11

Re: Using SourceHook
 
Thats where I'll start ...thanks for the pointer in the right direction.

BeetleFart 10-09-2008 16:32

Re: Using SourceHook
 
where can I download the latest versions of sourcehook...I may have 2 different versions and its not helping matters.

pRED* 10-09-2008 16:40

Re: Using SourceHook
 
http://hg.alliedmods.net/mmsource-ce...35/sourcehook/

Click one of the bz2/zip links or use mercurial to check out a copy.

BAILOPAN 10-09-2008 16:53

Re: Using SourceHook
 
You should really consider using MM:S, conflicting copies of SourceHook in the same address space is really problematic. ESTools does this and it causes conflicts with SourceMod.

One thing to do is what Mani does. VSP version with SourceHook embedded, MM:S version without. This works pretty nicely as the API stays the same.

The whole point of SourceHook is to unify hooking (making it easier through macros is just a side effect). If there's multiple SourceHooks, the original purpose is lost :|

BeetleFart 10-09-2008 18:29

Re: Using SourceHook
 
Id love to be able to do it that way..
Im still learning alot of this stuff and I dont know if the sourcehook files I have are mixed versions or not..
I have ones that Ive downloaded or have bits and pieces of from other plugins..
At the very least it would be great to get sourcehook going...then once thats working and I (hopefully) better understand its use then I can think about going full mm...but for now I having issues just to get the simple logprint hook to work. So until thats working correctly for me.....

BeetleFart 10-10-2008 09:32

Re: Using SourceHook
 
I've had no luck at all getting sourcehook to not crash.

I tried it in both my orangebox version and non orangebox versions.
I followed the embedding portion on http://wiki.alliedmods.net/SourceHook_Development
without any luck.
I included the files ..everything compiles fine.
I try just to hook logprint and as soon as I give it a
int log_hook = SH_ADD_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(Hook_LogPrint), false);
command it crashs.

PM 10-10-2008 17:14

Re: Using SourceHook
 
With what error? Maybe a call stack would help. Is g_SHPtr valid? Is engine valid? Also make sure g_PLID doesn't change (though that wouldn't crash).

When it crashes on AddHook, it might mean:
1) g_SHPtr is not a valid pointer to a CSourceHookImpl instance
2) Dereferencing the virtual table and the function entry failed. This could be the passed interface pointer not actually being of the same type as the class used for SH_DECL_HOOK
3) If something went wrong it could be a memory access error (vtables are read-only memory, SourceHook uses VirtualProtect to make it read-write, this might fail on some (security) systems).
4) Something I didn't think of at the moment went wrong.

BeetleFart 10-10-2008 21:33

Re: Using SourceHook
 
Thanks ..it was g_SHPtr...I mistakenly defined a local copy so the global didnt get set.
Now back to trying to trap the ivoiceserver.
Thanks

BeetleFart 11-06-2008 14:07

Re: Using SourceHook
 
Im now trying to hook
the WeaponCanUse virtual function

SH_DECL_MANUALHOOK1(WeaponCanUseHook, 0, 0, 0, bool, CBaseCombatWeapon *);
declared globally

i added into clientactive:

int Offset=216;
SH_MANUALHOOK_RECONFIGURE(WeaponCanUseHook, Offset, 0, 0);
SH_ADD_MANUALHOOK_MEMFUNC(WeaponCanUseHook, pBase, &g_EmtpyServerPlugin, &CEmptyServerPlugin::WeaponCanUseFunction, false);

and have:
bool CEmptyServerPlugin::WeaponCanUseFunction(CBas eCombatWeapon *pWeapon)
{
RETURN_META_VALUE(MRES_IGNORED, false);
}

and it appears to hook etc...but when the WeaponCanUseFunction is called
it comes up with and ESP problem with parameters not being stored correctly across the function call and Dont know what Im doing wrong.
I want to hook if someone can use a specific weapon .
What am I doing incorrectly?

BeetleFart 11-06-2008 15:23

Re: Using SourceHook
 
Im not sure what I did..but I redid it and now it seems to be working correctly.
Not sure what was wrong..maybe I had the offset wrong or something

L. Duke 11-07-2008 11:13

Re: Using SourceHook
 
Yes, I've had that error when I have the wrong offset or if the function parameters or call type are defined wrong.

BeetleFart 01-07-2009 11:52

Re: Using SourceHook
 
Does anyone know if theres something I need to do with sourcehook and linux.
Ive added a soucehook into the g_VoiceServer to trap the voice comms
and it works great in windows. I have one linux box that its being tested on
and when I do the sh_add_hook_memfunc it returns a 1 (or number of times Ive hooked it)
but the OnSetClientListening function never gets called on the linux box.
I would think that if the return value was ok..like it appears to be ..that the
hook is in place..or is the return value of 1 when I hook it once incorrect?

BeetleFart 01-08-2009 12:40

Re: Using SourceHook
 
anyone know why a hook would work in windows but not in linux???


All times are GMT -4. The time now is 18:40.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.