Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pre/postEventFunction to addDebugHook #126

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion Client/mods/deathmatch/logic/CMapEventManager.cpp
Expand Up @@ -193,6 +193,9 @@ bool CMapEventManager::Call ( const char* szName, const CLuaArguments& Arguments
if ( bEnabled )
g_pCore->LogEvent ( 0, "Lua Event", pMapEvent->GetVM ()->GetScriptName (), szName );

if ( !g_pClientGame->GetDebugHookManager()->OnPreEventFunction( szName, Arguments, pSource, nullptr, pMapEvent ) )
continue;

// Store the current values of the globals
lua_getglobal ( pState, "source" );
CLuaArgument OldSource ( pState, -1 );
Expand Down Expand Up @@ -242,11 +245,13 @@ bool CMapEventManager::Call ( const char* szName, const CLuaArguments& Arguments

lua_pushstring ( pState, szName );
lua_setglobal ( pState, "eventName" );

// Call it
pMapEvent->Call ( Arguments );
bCalled = true;

g_pClientGame->GetDebugHookManager()->OnPostEventFunction( szName, Arguments, pSource, nullptr, pMapEvent );

// Reset the globals on that VM
OldSource.Push ( pState );
lua_setglobal ( pState, "source" );
Expand Down
5 changes: 5 additions & 0 deletions Server/mods/deathmatch/logic/CMapEventManager.cpp
Expand Up @@ -173,6 +173,9 @@ bool CMapEventManager::Call ( const char* szName, const CLuaArguments& Arguments

TIMEUS startTime = GetTimeUs();

if ( !g_pGame->GetDebugHookManager()->OnPreEventFunction( szName, Arguments, pSource, pCaller, pMapEvent ) )
continue;

// Store the current values of the globals
lua_getglobal ( pState, "source" );
CLuaArgument OldSource ( pState, -1 );
Expand Down Expand Up @@ -242,6 +245,8 @@ bool CMapEventManager::Call ( const char* szName, const CLuaArguments& Arguments
pMapEvent->Call ( Arguments );
bCalled = true;

g_pGame->GetDebugHookManager()->OnPostEventFunction( szName, Arguments, pSource, pCaller, pMapEvent );

// Reset the globals on that VM
OldSource.Push ( pState );
lua_setglobal ( pState, "source" );
Expand Down
204 changes: 195 additions & 9 deletions Shared/mods/deathmatch/logic/CDebugHookManager.cpp
Expand Up @@ -57,14 +57,25 @@ CDebugHookManager::~CDebugHookManager( void )
///////////////////////////////////////////////////////////////
std::vector < SDebugHookCallInfo >& CDebugHookManager::GetHookInfoListForType( EDebugHookType hookType )
{
if ( hookType == EDebugHook::PRE_EVENT )
return m_PreEventHookList;
if ( hookType == EDebugHook::POST_EVENT )
return m_PostEventHookList;
if ( hookType == EDebugHook::PRE_FUNCTION )
return m_PreFunctionHookList;
dassert( hookType == EDebugHook::POST_FUNCTION );
return m_PostFunctionHookList;
switch ( hookType )
{
case EDebugHookType::PRE_EVENT:
return m_PreEventHookList;
case EDebugHookType::POST_EVENT:
return m_PostEventHookList;
case EDebugHookType::PRE_FUNCTION:
return m_PreFunctionHookList;
case EDebugHookType::POST_FUNCTION:
return m_PostFunctionHookList;
case EDebugHookType::PRE_EVENT_FUNCTION:
return m_PreEventFunctionHookList;
case EDebugHookType::POST_EVENT_FUNCTION:
return m_PostEventFunctionHookList;
case EDebugHookType::MAX_DEBUG_HOOK_TYPE:
default:
dassert ( hookType == EDebugHook::POST_FUNCTION );
return m_PostFunctionHookList;
}
}


Expand Down Expand Up @@ -132,7 +143,7 @@ bool CDebugHookManager::RemoveDebugHook( EDebugHookType hookType, const CLuaFunc
///////////////////////////////////////////////////////////////
void CDebugHookManager::OnLuaMainDestroy( CLuaMain* pLuaMain )
{
for( uint hookType = EDebugHook::PRE_EVENT ; hookType <= EDebugHook::POST_FUNCTION ; hookType++ )
for( uint hookType = EDebugHook::PRE_EVENT ; hookType < EDebugHook::MAX_DEBUG_HOOK_TYPE ; hookType++ )
{
std::vector < SDebugHookCallInfo >& hookInfoList = GetHookInfoListForType( (EDebugHookType)hookType );
for( uint i = 0 ; i < hookInfoList.size() ; )
Expand Down Expand Up @@ -179,6 +190,49 @@ void GetDebugInfo( lua_State* luaVM, lua_Debug& debugInfo, const char*& szFilena
}


///////////////////////////////////////////////////////////////
//
// GetMapEventDebugInfo
//
// Get current Lua source file and line number
//
///////////////////////////////////////////////////////////////
void GetMapEventDebugInfo( CMapEvent* pMapEvent, const char*& szFilename, int& iLineNumber )
{
CLuaMain* pLuaMain = pMapEvent->GetVM();

if ( !pLuaMain )
return;

lua_State* luaVM = pLuaMain->GetVirtualMachine();

if ( !luaVM )
return;

const CLuaFunctionRef& iLuaFunction = pMapEvent->GetLuaFunction();
lua_Debug debugInfo;
lua_getref( luaVM, iLuaFunction.ToInt() );

if ( lua_getinfo( luaVM, ">lS", &debugInfo ) ) {
// Make sure this function isn't defined in a string
if ( debugInfo.source[0] == '@' ) {
szFilename = debugInfo.source;
iLineNumber = debugInfo.currentline != -1 ? debugInfo.currentline : debugInfo.linedefined;
}
else {
szFilename = debugInfo.short_src;
}

// Remove path
if ( const char* szNext = strrchr( szFilename, '\\' ) )
szFilename = szNext + 1;

if ( const char* szNext = strrchr( szFilename, '/' ) )
szFilename = szNext + 1;
}
}


///////////////////////////////////////////////////////////////
//
// CDebugHookManager::OnPreFunction
Expand Down Expand Up @@ -373,6 +427,135 @@ void CDebugHookManager::OnPostEvent( const char* szName, const CLuaArguments& Ar
}


///////////////////////////////////////////////////////////////
//
// CDebugHookManager::OnPreEventFunction
//
// Called before a MTA event function is called
// Returns false if function call should be skipped
//
///////////////////////////////////////////////////////////////
bool CDebugHookManager::OnPreEventFunction( const char* szName, const CLuaArguments& Arguments, CElement* pSource, CPlayer* pCaller, CMapEvent* pMapEvent )
{
DECLARE_PROFILER_SECTION( OnPreEventFunction )

if ( m_PreEventFunctionHookList.empty() )
return true;

// Check if name is not used
if ( !IsNameAllowed( szName, m_PreEventFunctionHookList ) )
return true;

CLuaMain* pEventLuaMain = g_pGame->GetScriptDebugging()->GetTopLuaMain();
CResource* pEventResource = pEventLuaMain ? pEventLuaMain->GetResource() : NULL;

// Get file/line number for event
const char* szEventFilename = "";
int iEventLineNumber = 0;
lua_Debug eventDebugInfo;
lua_State* eventLuaVM = pEventLuaMain ? pEventLuaMain->GetVM() : NULL;
if ( eventLuaVM )
GetDebugInfo( eventLuaVM, eventDebugInfo, szEventFilename, iEventLineNumber );

// Get file/line number for function
const char* szFunctionFilename = "";
int iFunctionLineNumber = 0;
GetMapEventDebugInfo( pMapEvent, szFunctionFilename, iFunctionLineNumber );

CLuaMain* pFunctionLuaMain = pMapEvent->GetVM();
CResource* pFunctionResource = pFunctionLuaMain ? pFunctionLuaMain->GetResource() : NULL;

CLuaArguments NewArguments;
// resource eventResource, string eventName, element eventSource, element eventClient, string eventFilename, int eventLineNumber,
if ( pEventResource )
NewArguments.PushResource( pEventResource );
else
NewArguments.PushNil();

NewArguments.PushString( szName );
NewArguments.PushElement( pSource );
NewArguments.PushElement( pCaller );
NewArguments.PushString( szEventFilename );
NewArguments.PushNumber( iEventLineNumber );

// resource functionResource, string functionFilename, int functionLineNumber, ...args
if ( pFunctionResource )
NewArguments.PushResource( pFunctionResource );
else
NewArguments.PushNil();

NewArguments.PushString( szFunctionFilename );
NewArguments.PushNumber( iFunctionLineNumber );
NewArguments.PushArguments( Arguments );

return CallHook( szName, m_PreEventFunctionHookList, NewArguments );
}


///////////////////////////////////////////////////////////////
//
// CDebugHookManager::OnPostEventFunction
//
// Called after a MTA event function is called
//
///////////////////////////////////////////////////////////////
void CDebugHookManager::OnPostEventFunction( const char* szName, const CLuaArguments& Arguments, CElement* pSource, CPlayer* pCaller, CMapEvent* pMapEvent )
{
DECLARE_PROFILER_SECTION( OnPostEventFunction )

if ( m_PostEventFunctionHookList.empty() )
return;

// Check if name is not used
if ( !IsNameAllowed( szName, m_PostEventFunctionHookList ) )
return;

CLuaMain* pEventLuaMain = g_pGame->GetScriptDebugging()->GetTopLuaMain();
CResource* pEventResource = pEventLuaMain ? pEventLuaMain->GetResource() : NULL;

// Get file/line number for event
const char* szEventFilename = "";
int iEventLineNumber = 0;
lua_Debug eventDebugInfo;
lua_State* eventLuaVM = pEventLuaMain ? pEventLuaMain->GetVM() : NULL;
if ( eventLuaVM )
GetDebugInfo( eventLuaVM, eventDebugInfo, szEventFilename, iEventLineNumber );

// Get file/line number for function
const char* szFunctionFilename = "";
int iFunctionLineNumber = 0;
GetMapEventDebugInfo( pMapEvent, szFunctionFilename, iFunctionLineNumber );

CLuaMain* pFunctionLuaMain = pMapEvent->GetVM();
CResource* pFunctionResource = pFunctionLuaMain ? pFunctionLuaMain->GetResource() : NULL;

CLuaArguments NewArguments;
// resource eventResource, string eventName, element eventSource, element eventClient, string eventFilename, int eventLineNumber,
if ( pEventResource )
NewArguments.PushResource( pEventResource );
else
NewArguments.PushNil();

NewArguments.PushString( szName );
NewArguments.PushElement( pSource );
NewArguments.PushElement( pCaller );
NewArguments.PushString( szEventFilename );
NewArguments.PushNumber( iEventLineNumber );

// resource functionResource, string functionFilename, int functionLineNumber, ...args
if ( pFunctionResource )
NewArguments.PushResource( pFunctionResource );
else
NewArguments.PushNil();

NewArguments.PushString( szFunctionFilename );
NewArguments.PushNumber( iFunctionLineNumber );
NewArguments.PushArguments( Arguments );

CallHook( szName, m_PostEventFunctionHookList, NewArguments );
}


///////////////////////////////////////////////////////////////
//
// CDebugHookManager::IsNameAllowed
Expand Down Expand Up @@ -458,6 +641,9 @@ bool CDebugHookManager::CallHook( const char* szName, const std::vector < SDebug

lua_State* pState = info.pLuaMain->GetVirtualMachine();

if ( !pState )
continue;

// Save script MTA globals in case hook messes with them
lua_getglobal ( pState, "source" );
CLuaArgument OldSource ( pState, -1 );
Expand Down
5 changes: 4 additions & 1 deletion Shared/mods/deathmatch/logic/CDebugHookManager.h
Expand Up @@ -42,7 +42,8 @@ class CDebugHookManager
void OnPostFunction ( lua_CFunction f, lua_State* luaVM );
bool OnPreEvent ( const char* szName, const CLuaArguments& Arguments, CElement* pSource, CPlayer* pCaller );
void OnPostEvent ( const char* szName, const CLuaArguments& Arguments, CElement* pSource, CPlayer* pCaller );

bool OnPreEventFunction ( const char* szName, const CLuaArguments& Arguments, CElement* pSource, CPlayer* pCaller, CMapEvent* pMapEvent );
void OnPostEventFunction ( const char* szName, const CLuaArguments& Arguments, CElement* pSource, CPlayer* pCaller, CMapEvent* pMapEvent );
bool HasPostFunctionHooks ( void ) const { return !m_PostFunctionHookList.empty() || m_uiPostFunctionOverride; }

protected:
Expand All @@ -57,5 +58,7 @@ class CDebugHookManager
std::vector < SDebugHookCallInfo > m_PostEventHookList;
std::vector < SDebugHookCallInfo > m_PreFunctionHookList;
std::vector < SDebugHookCallInfo > m_PostFunctionHookList;
std::vector < SDebugHookCallInfo > m_PreEventFunctionHookList;
std::vector < SDebugHookCallInfo > m_PostEventFunctionHookList;
std::map< SString, std::vector<uint> > m_MaskArgumentsMap;
};
10 changes: 6 additions & 4 deletions Shared/mods/deathmatch/logic/Enums.cpp
Expand Up @@ -24,10 +24,12 @@ IMPLEMENT_ENUM_BEGIN( EPlayerScreenShotResult::EPlayerScreenShotResultType )
IMPLEMENT_ENUM_END( "player-screenshot-result" )

IMPLEMENT_ENUM_BEGIN( EDebugHook::EDebugHookType )
ADD_ENUM ( EDebugHook::PRE_EVENT, "preEvent" )
ADD_ENUM ( EDebugHook::POST_EVENT, "postEvent" )
ADD_ENUM ( EDebugHook::PRE_FUNCTION, "preFunction" )
ADD_ENUM ( EDebugHook::POST_FUNCTION, "postFunction" )
ADD_ENUM ( EDebugHook::PRE_EVENT, "preEvent" )
ADD_ENUM ( EDebugHook::POST_EVENT, "postEvent" )
ADD_ENUM ( EDebugHook::PRE_FUNCTION, "preFunction" )
ADD_ENUM ( EDebugHook::POST_FUNCTION, "postFunction" )
ADD_ENUM ( EDebugHook::PRE_EVENT_FUNCTION, "preEventFunction" )
ADD_ENUM ( EDebugHook::POST_EVENT_FUNCTION, "postEventFunction" )
IMPLEMENT_ENUM_END( "debug-hook" )

IMPLEMENT_ENUM_BEGIN( eEulerRotationOrder )
Expand Down
3 changes: 3 additions & 0 deletions Shared/mods/deathmatch/logic/Enums.h
Expand Up @@ -46,6 +46,9 @@ namespace EDebugHook
POST_EVENT,
PRE_FUNCTION,
POST_FUNCTION,
PRE_EVENT_FUNCTION,
POST_EVENT_FUNCTION,
MAX_DEBUG_HOOK_TYPE
};
}
using EDebugHook::EDebugHookType;
Expand Down