AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   General hamsandwich questions (https://forums.alliedmods.net/showthread.php?t=95139)

joaquimandrade 06-20-2009 01:31

General hamsandwich questions
 
I would like to have available for scripting some functions existent in CS.

Particularly functions related to spectating. I don't know any method of manipulating that now. I would like to have them to make a plugin that would force players with the same IP to be able only to spectate their lanmates and a plugin that would make admins able to go through players by their scores, like the first one to spectate would be the person with the highest score and another plugin that when one player were carrying a knife and was closer to an enemy would force those who want to spectate him.

I guess those functions are:

Observer_FindNextPlayer
Observer_SetMode
Observer_HandleButtons
Observer_FindNextPlayer

A part from these i also would like to have:

FlashlightTurnOn
FlashlightTurnOff

To be able to use the flashlight button in plugins.

Also:

SetNewPlayerModel
SetPlayerModel

That I guess that would make clean the way of changing player models

Also:

SetAnimation


I understand the concept of hamsandwich and I know that with it and by knowing the function offsets in the entity virtual table one could easily add support to almost any function with it. My question is, if someone can find any of these offsets or point me to reading material to understand how to figure out how to get those offsets.

Apart from that, I learnt that by doing

PHP Code:

RegisterHam(Ham_ObjectCaps,"player",... 

we can get everytime the use key is pressed and released, what would be great to improve plugins that handle the use key like the parachute one. My question is if it's really ObjectCaps being hooked and, if yes, if is safe to use it as to hook the use key usage or if it happens in more situations.

hleV 06-20-2009 08:13

Re: General hamsandwich questions
 
Is that ObjectCaps better than this?
Code:
#include <fakemeta>   public plugin_init()         register_forward(FM_CmdStart, "fwdCmdStart");   public fwdCmdStart(iCl, iHandle) {         static iButtons, iOldButtons;         iButtons = get_uc(iHandle, UC_Buttons);         iOldButtons = pev(iCl, pev_oldbuttons);           if ((iButtons & IN_USE) && !(iOldButtons & IN_USE))         {                 // Pressed +use         }         else if (!(iButtons & IN_USE) && (iOldButtons & IN_USE))         {                 // Unpressed +use         } }

ConnorMcLeod 06-20-2009 08:31

Re: General hamsandwich questions
 
Quote:

Originally Posted by hleV (Post 852846)
Is that ObjectCaps better than this?

Off Topic.

joaquimandrade 06-20-2009 14:24

Re: General hamsandwich questions
 
Quote:

Originally Posted by hleV (Post 852846)
Is that ObjectCaps better than this?
Code:
#include <fakemeta> public plugin_init() register_forward(FM_CmdStart, "fwdCmdStart");

public fwdCmdStart(iCl, iHandle) { static iButtons, iOldButtons;
iButtons = get_uc(iHandle, UC_Buttons);
iOldButtons = pev(iCl, pev_oldbuttons);

if ((iButtons & IN_USE) && !(iOldButtons & IN_USE)) { // Pressed +use } else if (!(iButtons & IN_USE) && (iOldButtons & IN_USE)) { // Unpressed +use } }


cmdStart occurs many times per second. I tested once and it happens so often as PreThink. So, when using it, every player is always being checked (many times per second) to see if he is pressing the use key. Even if he is away or spectating.

joaquimandrade 06-20-2009 15:52

Re: General hamsandwich questions
 
1 Attachment(s)
Try this to see the difference.

jim_yang 06-21-2009 02:47

Re: General hamsandwich questions
 
vtable only contains virtual member function pointers, all of your provided functions are non virtual member function, they
don't exist in CBasePlayer's Obj's vtable.
calling function is simple if you know its real address, prototype and calling conventions. here is an example to call
CBasePlayer::DropPlayerItem(const char *szItem), I use it to instead "engclient_cmd" method to force a player drop an item.
Code:

void CallDllDropPlayerItem(edict_t *pEdict, const char *szWeapon)
{
    HMODULE handle = GetModuleHandle("mp.dll");
    unsigned long baseaddr = (unsigned long)handle;
    void *g_CBasePlayer_DropPlayerItem = (void *)(baseaddr + 0xB3DB0);
    CBasePlayer *pPlayer = (CBasePlayer *)pEdict->pvPrivateData;
    __asm
    {
        PUSH    szItem;    //push param into stack
        MOV    ECX, pPlayer; //push "this" to ecx
        CALL    [g_CBasePlayer_DropPlayerItem]; //call function
    }
}

To get the real address and prototype, you need to disassemble the gamedll. "mp.dll" here for windows.
Then find the function address you want to call.
By this way, you can call all the functions you list above. Hooking them is another story.
To get virtual offsets, here is a tut:
http://wiki.alliedmods.net/Finding_Virtual_Offsets

joaquimandrade 06-21-2009 03:28

Re: General hamsandwich questions
 
Quote:

Originally Posted by jim_yang (Post 853288)
vtable only contains virtual member function pointers, all of your provided functions are non virtual member function, they
don't exist in CBasePlayer's Obj's vtable.
calling function is simple if you know its real address, prototype and calling conventions. here is an example to call
CBasePlayer::DropPlayerItem(const char *szItem), I use it to instead "engclient_cmd" method to force a player drop an item.
Code:

void CallDllDropPlayerItem(edict_t *pEdict, const char *szWeapon)
{
    HMODULE handle = GetModuleHandle("mp.dll");
    unsigned long baseaddr = (unsigned long)handle;
    void *g_CBasePlayer_DropPlayerItem = (void *)(baseaddr + 0xB3DB0);
    CBasePlayer *pPlayer = (CBasePlayer *)pEdict->pvPrivateData;
    __asm
    {
        PUSH    szItem;    //push param into stack
        MOV    ECX, pPlayer; //push "this" to ecx
        CALL    [g_CBasePlayer_DropPlayerItem]; //call function
    }
}

To get the real address and prototype, you need to disassemble the gamedll. "mp.dll" here for windows.
Then find the function address you want to call.
By this way, you can call all the functions you list above. Hooking them is another story.
To get virtual offsets, here is a tut:
http://wiki.alliedmods.net/Finding_Virtual_Offsets

Thank you. So hamsandwich has nothing to do with this. I will deepen my knowledge in this area.

(And that was a nice example. I also don't like to use engclient_cmd)

joaquimandrade 06-21-2009 04:40

Re: General hamsandwich questions
 
I have one question. How do you know if a function is virtual or not by analizing the library dump and, how you get the position, in the virtual table of the entity, for those which are virtual?

(edit: I'm guessing that the virtual functions are those who are inherited from base classes and not those from the actual class)

ConnorMcLeod 10-20-2012 04:35

Re: General hamsandwich questions
 
Just to say that i've just figured out that ObjectCaps is not a reliable method to detect player pressing +use key.
If some players stay near to that player, ObjectCaps is triggered also for those players, which trigger false positives.

You could say that checking for pev_button could fix it, but if the 'near' player is also holding +use, then the function is sent 2 times instead of 1, and button check gonna be past.


All times are GMT -4. The time now is 15:33.

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