Raised This Month: $32 Target: $400
 8% 

Call Signature


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Accelerator
Senior Member
Join Date: Dec 2010
Location: Russia
Old 05-31-2017 , 06:44   Call Signature
Reply With Quote #1

Faced a problem, and I do not understand what happened...

Signature:
Code:
/* CTerrorGameRules::GetVersusCompletion(CTerrorPlayer*) */
_ZN16CTerrorGameRules19GetVersusCompletionEP13CTerrorPlayer
When I try to get the value with the help of SDKTools, everything works fine:
Code:
#include <sourcemod>
#include <sdktools>

Handle GetFlowDistanceSDKCall = null;
public void OnPluginStart()
{
	StartPrepSDKCall(SDKCall_GameRules);
	if (!PrepSDKCall_SetSignature(SDKLibrary_Server, "\x55\x8B\xEC\x83\xEC\x2A\x53\x56\x8B\x75\x2A\x8B\xD9\x85\xF6\x2A\x2A\x2A\x2A\x2A\x2A\x8B\xCE", 23))
		PrepSDKCall_SetSignature(SDKLibrary_Server, "@_ZN16CTerrorGameRules19GetVersusCompletionEP13CTerrorPlayer", 0)
	PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
	PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
	GetFlowDistanceSDKCall = EndPrepSDKCall();
	if (GetFlowDistanceSDKCall == null)
	{
		SetFailState("Unable to find the signature!");
	}
	
	RegConsoleCmd("sm_test", test);
}

public Action test(client, args)
{
	PrintToChatAll("%d", SDKCall(GetFlowDistanceSDKCall, client));
}
But when I try to do this in an extension, the server crashes when I call the function
Part of the code:
Code:
int VersusCompletion::GetVersusCompletion(int *client)
{
	void *pGameRules;
	if (!g_pSDKTools || !(pGameRules = g_pSDKTools->GetGameRules()))
	{
		g_pSM->LogError(myself, "Failed to find GameRules");
		return 0;
	}

	static int (*GetVersusCompletionFunc)(void *, CBaseEntity*);
	if(!GetVersusCompletionFunc) 
	{
		if( !g_pGameConf->GetMemSig("CTerrorGameRules_GetVersusCompletion", (void**)&GetVersusCompletionFunc) || !GetVersusCompletionFunc ) 
		{
			g_pSM->LogError(myself, "Can't resolve CTerrorGameRules_GetVersusCompletion signature");
			return 0;
		}
	}
	CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client);
	if(!pPlayer) return 0;

	return GetVersusCompletionFunc(pGameRules, pPlayer);
}
I found out that this is happening, obviously, because of the substitution of pGameRules (g_pSDKTools->GetGameRules()), but without them the function is not working... I can not understand what I'm doing wrong...
On older versions of the sourcemod (1.6.2 and older) function worked fine, after moving to branch 1.7 and newer the server began to fall.
I ask help

Last edited by Accelerator; 05-31-2017 at 12:43.
Accelerator is offline
WildCard65
Veteran Member
Join Date: Aug 2013
Location: Canada
Old 05-31-2017 , 07:43   Re: Call Signature
Reply With Quote #2

try:
PHP Code:
class CTerrorGameRules;
class 
CTerrorPlayer;

/* In function int VersusCompletion::GetVersusCompletion(int *client) */
static int (CTerrorGameRules::*GetVersusCompletionFunc(CTerrorPlayer *);

/* Later in same function */
(static_cast<CTerrorGameRules *>(pGameRules)->*GetVersusCompletionFunc)(static_cast<CTerrorPlayer *>(pPlayer)); 
Also why are you passing a pointer instead of an integer to ReferenceToEntity, why is your client param a pointer anyway?
__________________

Last edited by WildCard65; 05-31-2017 at 07:45.
WildCard65 is offline
Accelerator
Senior Member
Join Date: Dec 2010
Location: Russia
Old 05-31-2017 , 08:06   Re: Call Signature
Reply With Quote #3

Quote:
Originally Posted by WildCard65 View Post
Also why are you passing a pointer instead of an integer to ReferenceToEntity, why is your client param a pointer anyway?
My mistake

Tried:
Code:
class CTerrorGameRules;
class CTerrorPlayer;

int VersusCompletion::GetVersusCompletion(int client)
{
	void *pGameRules;
	if (!g_pSDKTools || !(pGameRules = g_pSDKTools->GetGameRules()))
	{
		g_pSM->LogError(myself, "Failed to find GameRules");
		return 0;
	}

	static int (CTerrorGameRules::*GetVersusCompletionFunc)(CTerrorPlayer *);
	if(!GetVersusCompletionFunc) 
	{
		if( !g_pGameConf->GetMemSig("CTerrorGameRules_GetVersusCompletion", (void**)&GetVersusCompletionFunc) || !GetVersusCompletionFunc ) 
		{
			g_pSM->LogError(myself, "Can't resolve CTerrorGameRules_GetVersusCompletion signature");
			return 0;
		}
	}
	CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client);
	if(!pPlayer) return 0;

	return (static_cast<CTerrorGameRules *>(pGameRules)->*GetVersusCompletionFunc)(reinterpret_cast<CTerrorPlayer *>(pPlayer)); // reinterpret_cast - because 'error: invalid static_cast from type 'CBaseEntity*' to type 'CTerrorPlayer*'. 
}
===> Server crashed when function call
I also tried changing the CTerrorPlayer to CBasePlayer. The server is also falling.

Last edited by Accelerator; 05-31-2017 at 12:43.
Accelerator is offline
Accelerator
Senior Member
Join Date: Dec 2010
Location: Russia
Old 05-31-2017 , 09:10   Re: Call Signature
Reply With Quote #4

I checked. On windows, everything works fine and with my old example, but on linux this all does not work.
Accelerator is offline
WildCard65
Veteran Member
Join Date: Aug 2013
Location: Canada
Old 05-31-2017 , 10:23   Re: Call Signature
Reply With Quote #5

By chance, when you declare the function pointer, try setting it to nullptr and see if it crashes still
__________________
WildCard65 is offline
Accelerator
Senior Member
Join Date: Dec 2010
Location: Russia
Old 05-31-2017 , 10:40   Re: Call Signature
Reply With Quote #6

I tried reinterpret_cast<CTerrorPlayer *>(pPlayer) -->> reinterpret_cast<CTerrorPlayer *>(nullptr). No crash. But the function then does not work (of course)

Last edited by Accelerator; 05-31-2017 at 10:42.
Accelerator is offline
WildCard65
Veteran Member
Join Date: Aug 2013
Location: Canada
Old 05-31-2017 , 10:56   Re: Call Signature
Reply With Quote #7

I meant:
PHP Code:
static int (CTerrorGameRules::*GetVersusCompletionFunc)(CTerrorPlayer *) = nullptr
__________________
WildCard65 is offline
Accelerator
Senior Member
Join Date: Dec 2010
Location: Russia
Old 05-31-2017 , 10:59   Re: Call Signature
Reply With Quote #8

Also tried. With this crash.
Accelerator is offline
Accelerator
Senior Member
Join Date: Dec 2010
Location: Russia
Old 05-31-2017 , 15:39   Re: Call Signature
Reply With Quote #9

It seems that the player parameter (pPlayer) is incorrectly send. It seems that the data type is some other, but which one... But CTerrorPlayer is the same as CBaseEntity...
How can I get the CBasePlayer data type from SDKTools?

Last edited by Accelerator; 05-31-2017 at 15:39.
Accelerator is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 06-01-2017 , 02:31   Re: Call Signature
Reply With Quote #10

The type of a pointer doesn't matter, your problem is calling conventions.
If you look at the source for my Connect extension there are some examples in there you can copy.
__________________

Last edited by asherkin; 06-01-2017 at 02:33.
asherkin is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 21:25.


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