mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-03-04 01:35:26 +03:00
Fix scriptanimevent_t::SetOption()
The string argument refers to memory managed by the Squirrel VM. It has no guarantee that the string will continue to exist after the hook, from which this can be called, has finished executing. To fix this, allocate memory to copy the string into and manage it as needed.
This commit is contained in:
parent
8e8bdfc371
commit
7d78384b26
@ -16,6 +16,10 @@
|
||||
#include "saverestore_utlvector.h"
|
||||
#include "dt_utlvector_send.h"
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
#include "mapbase/vscript_funcs_shared.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
@ -471,7 +475,8 @@ void CAnimationLayer::DispatchAnimEvents( CBaseAnimating *eventHandler, CBaseAni
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (eventHandler->m_ScriptScope.IsInitialized() && eventHandler->ScriptHookHandleAnimEvent( &event ) == false)
|
||||
scriptanimevent_t wrapper( event );
|
||||
if (eventHandler->m_ScriptScope.IsInitialized() && !eventHandler->ScriptHookHandleAnimEvent( wrapper ))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
@ -1261,7 +1261,8 @@ void CBaseAnimating::DispatchAnimEvents ( CBaseAnimating *eventHandler )
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
if (eventHandler->ScriptHookHandleAnimEvent( &event ) == false)
|
||||
scriptanimevent_t wrapper( event );
|
||||
if (!eventHandler->ScriptHookHandleAnimEvent( wrapper ))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
@ -1299,11 +1300,11 @@ void CBaseAnimating::DispatchAnimEvents ( CBaseAnimating *eventHandler )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseAnimating::ScriptHookHandleAnimEvent( animevent_t *pEvent )
|
||||
bool CBaseAnimating::ScriptHookHandleAnimEvent( scriptanimevent_t &event )
|
||||
{
|
||||
if (m_ScriptScope.IsInitialized() && g_Hook_HandleAnimEvent.CanRunInScope(m_ScriptScope))
|
||||
{
|
||||
HSCRIPT hEvent = g_pScriptVM->RegisterInstance( reinterpret_cast<scriptanimevent_t*>(pEvent) );
|
||||
HSCRIPT hEvent = g_pScriptVM->RegisterInstance( &event );
|
||||
|
||||
// event
|
||||
ScriptVariant_t args[] = { hEvent };
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "datacache/idatacache.h"
|
||||
#include "tier0/threadtools.h"
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
struct scriptanimevent_t;
|
||||
#endif
|
||||
|
||||
struct animevent_t;
|
||||
struct matrix3x4_t;
|
||||
@ -146,7 +149,7 @@ public:
|
||||
virtual void DispatchAnimEvents ( CBaseAnimating *eventHandler ); // Handle events that have happend since last time called up until X seconds into the future
|
||||
virtual void HandleAnimEvent( animevent_t *pEvent );
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
bool ScriptHookHandleAnimEvent( animevent_t *pEvent );
|
||||
bool ScriptHookHandleAnimEvent( scriptanimevent_t &event );
|
||||
#endif
|
||||
|
||||
int LookupPoseParameter( CStudioHdr *pStudioHdr, const char *szName );
|
||||
|
@ -535,7 +535,7 @@ bool CAnimEventTInstanceHelper::Get( void *p, const char *pszKey, ScriptVariant_
|
||||
{
|
||||
DevWarning( "VScript animevent_t.%s: animevent_t metamethod members are deprecated! Use 'script_help animevent_t' to see the correct functions.\n", pszKey );
|
||||
|
||||
animevent_t *ani = ((animevent_t *)p);
|
||||
animevent_t *ani = &((scriptanimevent_t *)p)->event;
|
||||
if (FStrEq( pszKey, "event" ))
|
||||
variant = ani->event;
|
||||
else if (FStrEq( pszKey, "options" ))
|
||||
@ -558,13 +558,21 @@ bool CAnimEventTInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_
|
||||
{
|
||||
DevWarning( "VScript animevent_t.%s: animevent_t metamethod members are deprecated! Use 'script_help animevent_t' to see the correct functions.\n", pszKey );
|
||||
|
||||
animevent_t *ani = ((animevent_t *)p);
|
||||
scriptanimevent_t *script_ani = ((scriptanimevent_t *)p);
|
||||
animevent_t *ani = &script_ani->event;
|
||||
if (FStrEq( pszKey, "event" ))
|
||||
{
|
||||
return variant.AssignTo( &ani->event );
|
||||
}
|
||||
else if (FStrEq( pszKey, "options" ))
|
||||
// broken: return variant.AssignTo( &ani->options );
|
||||
// variant memory is freed afterwards
|
||||
return false;
|
||||
{
|
||||
char *szOptions;
|
||||
if (!variant.AssignTo( &szOptions ))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
script_ani->SetOptions( szOptions );
|
||||
}
|
||||
else if (FStrEq( pszKey, "cycle" ))
|
||||
return variant.AssignTo( &ani->cycle );
|
||||
else if (FStrEq( pszKey, "eventtime" ))
|
||||
|
@ -172,30 +172,47 @@ private:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exposes animevent_t to VScript
|
||||
//-----------------------------------------------------------------------------
|
||||
struct scriptanimevent_t : public animevent_t
|
||||
struct scriptanimevent_t
|
||||
{
|
||||
int GetEvent() { return event; }
|
||||
void SetEvent( int nEvent ) { event = nEvent; }
|
||||
friend class CAnimEventTInstanceHelper;
|
||||
|
||||
const char *GetOptions() { return options; }
|
||||
void SetOptions( const char *pOptions ) { options = pOptions; }
|
||||
public:
|
||||
scriptanimevent_t( animevent_t &event ) : event( event ), options( NULL ) { }
|
||||
~scriptanimevent_t( ) { delete[] options; }
|
||||
|
||||
float GetCycle() { return cycle; }
|
||||
void SetCycle( float flCycle ) { cycle = flCycle; }
|
||||
int GetEvent() { return event.event; }
|
||||
void SetEvent( int nEvent ) { event.event = nEvent; }
|
||||
|
||||
float GetEventTime() { return eventtime; }
|
||||
void SetEventTime( float flEventTime ) { eventtime = flEventTime; }
|
||||
const char *GetOptions() { return event.options; }
|
||||
void SetOptions( const char *pOptions )
|
||||
{
|
||||
size_t len = strlen( pOptions );
|
||||
delete[] options;
|
||||
event.options = options = new char[len + 1];
|
||||
memcpy( options, pOptions, len + 1 );
|
||||
}
|
||||
|
||||
int GetType() { return type; }
|
||||
void SetType( int nType ) { eventtime = type; }
|
||||
float GetCycle() { return event.cycle; }
|
||||
void SetCycle( float flCycle ) { event.cycle = flCycle; }
|
||||
|
||||
HSCRIPT GetSource() { return ToHScript( pSource ); }
|
||||
float GetEventTime() { return event.eventtime; }
|
||||
void SetEventTime( float flEventTime ) { event.eventtime = flEventTime; }
|
||||
|
||||
int GetType() { return event.type; }
|
||||
void SetType( int nType ) { event.type = nType; }
|
||||
|
||||
HSCRIPT GetSource() { return ToHScript( event.pSource ); }
|
||||
void SetSource( HSCRIPT hSource )
|
||||
{
|
||||
CBaseEntity *pEnt = ToEnt( hSource );
|
||||
if (pEnt)
|
||||
pSource = pEnt->GetBaseAnimating();
|
||||
event.pSource = pEnt->GetBaseAnimating();
|
||||
}
|
||||
|
||||
private:
|
||||
animevent_t &event;
|
||||
// storage for ScriptVariant_t string, which may be temporary
|
||||
char *options;
|
||||
};
|
||||
|
||||
class CAnimEventTInstanceHelper : public IScriptInstanceHelper
|
||||
|
Loading…
x
Reference in New Issue
Block a user