fix: new build system (#4)
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||
import os
|
||||
|
||||
projectName = 'outputinfo'
|
||||
|
||||
project = builder.LibraryProject(projectName)
|
||||
project.sources += [
|
||||
os.path.join(Extension.ext_root, 'src', 'extension.cpp'),
|
||||
os.path.join(Extension.sm_root, 'public', 'smsdk_ext.cpp')
|
||||
]
|
||||
|
||||
for sdk_name in Extension.sdks:
|
||||
sdk = Extension.sdks[sdk_name]
|
||||
if sdk['name'] in ['mock']:
|
||||
continue
|
||||
|
||||
for cxx in builder.targets:
|
||||
if not cxx.target.arch in sdk['platforms'][cxx.target.platform]:
|
||||
continue
|
||||
|
||||
binary = Extension.HL2ExtConfig(project, builder, cxx, projectName + '.ext.' + sdk['extension'], sdk)
|
||||
|
||||
Extension.AddCDetour(binary)
|
||||
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(sdk['path'], 'game', 'server'),
|
||||
]
|
||||
|
||||
Extension.extensions += builder.Add(project)
|
||||
@@ -0,0 +1,687 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <amtl/am-string.h>
|
||||
#include "extension.h"
|
||||
|
||||
/**
|
||||
* @file extension.cpp
|
||||
* @brief Implement extension code here.
|
||||
*/
|
||||
|
||||
Outputinfo g_Outputinfo; /**< Global singleton for extension's main interface */
|
||||
|
||||
SMEXT_LINK(&g_Outputinfo);
|
||||
|
||||
IGameConfig *g_pGameConf = NULL;
|
||||
|
||||
#include <isaverestore.h>
|
||||
#include <variant_t.h>
|
||||
|
||||
struct varianthax_t
|
||||
{
|
||||
union
|
||||
{
|
||||
bool bVal;
|
||||
string_t iszVal;
|
||||
int iVal;
|
||||
float flVal;
|
||||
float vecVal[3];
|
||||
color32 rgbaVal;
|
||||
};
|
||||
CHandle<CBaseEntity> eVal; // this can't be in the union because it has a constructor.
|
||||
|
||||
fieldtype_t fieldType;
|
||||
};
|
||||
|
||||
class CEventAction
|
||||
{
|
||||
public:
|
||||
CEventAction( const char *ActionData = NULL );
|
||||
|
||||
string_t m_iTarget; // name of the entity(s) to cause the action in
|
||||
string_t m_iTargetInput; // the name of the action to fire
|
||||
string_t m_iParameter; // parameter to send, 0 if none
|
||||
float m_flDelay; // the number of seconds to wait before firing the action
|
||||
int m_nTimesToFire; // The number of times to fire this event, or EVENT_FIRE_ALWAYS (-1).
|
||||
|
||||
int m_iIDStamp; // unique identifier stamp
|
||||
|
||||
static int s_iNextIDStamp;
|
||||
|
||||
CEventAction *m_pNext;
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
static int *s_pBlocksAllocated;
|
||||
static void **s_ppHeadOfFreeList;
|
||||
#else
|
||||
static void (*s_pOperatorDeleteFunc)(void *pMem);
|
||||
#endif
|
||||
|
||||
static void operator delete(void *pMem);
|
||||
};
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
int *CEventAction::s_pBlocksAllocated;
|
||||
void **CEventAction::s_ppHeadOfFreeList;
|
||||
#else
|
||||
void (*CEventAction::s_pOperatorDeleteFunc)(void *pMem);
|
||||
#endif
|
||||
|
||||
void CEventAction::operator delete(void *pMem)
|
||||
{
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
(*s_pBlocksAllocated)--;
|
||||
|
||||
// make the block point to the first item in the list
|
||||
*((void **)pMem) = *s_ppHeadOfFreeList;
|
||||
|
||||
// the list head is now the new block
|
||||
*s_ppHeadOfFreeList = pMem;
|
||||
#else
|
||||
s_pOperatorDeleteFunc(pMem);
|
||||
#endif
|
||||
}
|
||||
|
||||
class CBaseEntityOutput
|
||||
{
|
||||
public:
|
||||
varianthax_t m_Value;
|
||||
CEventAction *m_ActionList;
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
|
||||
int NumberOfElements(void);
|
||||
CEventAction *GetElement(int Index);
|
||||
int DeleteElement(int Index);
|
||||
int DeleteAllElements(void);
|
||||
};
|
||||
|
||||
int CBaseEntityOutput::NumberOfElements(void)
|
||||
{
|
||||
int Count = 0;
|
||||
for(CEventAction *ev = m_ActionList; ev != NULL; ev = ev->m_pNext)
|
||||
Count++;
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
CEventAction *CBaseEntityOutput::GetElement(int Index)
|
||||
{
|
||||
int Count = 0;
|
||||
for(CEventAction *ev = m_ActionList; ev != NULL; ev = ev->m_pNext)
|
||||
{
|
||||
if(Count == Index)
|
||||
return ev;
|
||||
|
||||
Count++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CBaseEntityOutput::DeleteElement(int Index)
|
||||
{
|
||||
CEventAction *pPrevEvent = NULL;
|
||||
CEventAction *pEvent = NULL;
|
||||
|
||||
int Count = 0;
|
||||
for(CEventAction *ev = m_ActionList; ev != NULL; ev = ev->m_pNext)
|
||||
{
|
||||
if(Count == Index)
|
||||
{
|
||||
pEvent = ev;
|
||||
break;
|
||||
}
|
||||
pPrevEvent = ev;
|
||||
Count++;
|
||||
}
|
||||
|
||||
if(pEvent == NULL)
|
||||
return 0;
|
||||
|
||||
if(pPrevEvent != NULL)
|
||||
pPrevEvent->m_pNext = pEvent->m_pNext;
|
||||
else
|
||||
m_ActionList = pEvent->m_pNext;
|
||||
|
||||
delete pEvent;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBaseEntityOutput::DeleteAllElements(void)
|
||||
{
|
||||
// walk front to back, deleting as we go. We needn't fix up pointers because
|
||||
// EVERYTHING will die.
|
||||
|
||||
int Count = 0;
|
||||
CEventAction *pNext = m_ActionList;
|
||||
// wipe out the head
|
||||
m_ActionList = NULL;
|
||||
while(pNext)
|
||||
{
|
||||
CEventAction *pStrikeThis = pNext;
|
||||
pNext = pNext->m_pNext;
|
||||
delete pStrikeThis;
|
||||
Count++;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
inline int GetDataMapOffset(CBaseEntity *pEnt, const char *pName, typedescription_t **ppTypeDesc=NULL)
|
||||
{
|
||||
datamap_t *pMap = gamehelpers->GetDataMap(pEnt);
|
||||
if(!pMap)
|
||||
return -1;
|
||||
|
||||
typedescription_t *pTypeDesc = gamehelpers->FindInDataMap(pMap, pName);
|
||||
if(pTypeDesc == NULL)
|
||||
return -1;
|
||||
|
||||
if(ppTypeDesc)
|
||||
*ppTypeDesc = pTypeDesc;
|
||||
|
||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||
return pTypeDesc->fieldOffset;
|
||||
#else
|
||||
return pTypeDesc->fieldOffset[TD_OFFSET_NORMAL];
|
||||
#endif
|
||||
}
|
||||
|
||||
inline CBaseEntityOutput *GetOutput(CBaseEntity *pEntity, const char *pOutput, typedescription_t **ppTypeDesc=NULL)
|
||||
{
|
||||
typedescription_t *pTypeDesc = NULL;
|
||||
int Offset = GetDataMapOffset(pEntity, pOutput, &pTypeDesc);
|
||||
|
||||
if(ppTypeDesc)
|
||||
*ppTypeDesc = pTypeDesc;
|
||||
|
||||
if(Offset == -1)
|
||||
return NULL;
|
||||
|
||||
if(pTypeDesc->fieldType != FIELD_CUSTOM)
|
||||
return NULL;
|
||||
|
||||
if(!(pTypeDesc->flags & FTYPEDESC_OUTPUT))
|
||||
return NULL;
|
||||
|
||||
return (CBaseEntityOutput *)((intptr_t)pEntity + Offset);
|
||||
}
|
||||
|
||||
cell_t GetOutputCount(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL)
|
||||
return -1;
|
||||
|
||||
return pEntityOutput->NumberOfElements();
|
||||
}
|
||||
|
||||
cell_t GetOutputTarget(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return 0;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return 0;
|
||||
|
||||
CEventAction *pAction = pEntityOutput->GetElement(params[3]);
|
||||
if(!pAction)
|
||||
return 0;
|
||||
|
||||
size_t Length;
|
||||
pContext->StringToLocalUTF8(params[4], params[5], pAction->m_iTarget.ToCStr(), &Length);
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
cell_t GetOutputTargetInput(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return 0;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return 0;
|
||||
|
||||
CEventAction *pAction = pEntityOutput->GetElement(params[3]);
|
||||
if(!pAction)
|
||||
return 0;
|
||||
|
||||
size_t Length;
|
||||
pContext->StringToLocalUTF8(params[4], params[5], pAction->m_iTargetInput.ToCStr(), &Length);
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
cell_t GetOutputParameter(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return 0;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return 0;
|
||||
|
||||
CEventAction *pAction = pEntityOutput->GetElement(params[3]);
|
||||
if(!pAction)
|
||||
return 0;
|
||||
|
||||
size_t Length;
|
||||
pContext->StringToLocalUTF8(params[4], params[5], pAction->m_iParameter.ToCStr(), &Length);
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
cell_t GetOutputDelay(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return 0;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return -1;
|
||||
|
||||
CEventAction *pAction = pEntityOutput->GetElement(params[3]);
|
||||
if(!pAction)
|
||||
return -1;
|
||||
|
||||
return *(cell_t *)&pAction->m_flDelay;
|
||||
}
|
||||
|
||||
cell_t GetOutputFormatted(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return 0;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return 0;
|
||||
|
||||
CEventAction *pAction = pEntityOutput->GetElement(params[3]);
|
||||
if(!pAction)
|
||||
return 0;
|
||||
|
||||
char aBuffer[1024];
|
||||
ke::SafeSprintf(aBuffer, sizeof(aBuffer), "%s,%s,%s,%g,%d",
|
||||
pAction->m_iTarget.ToCStr(),
|
||||
pAction->m_iTargetInput.ToCStr(),
|
||||
pAction->m_iParameter.ToCStr(),
|
||||
pAction->m_flDelay,
|
||||
pAction->m_nTimesToFire);
|
||||
|
||||
size_t Length;
|
||||
pContext->StringToLocalUTF8(params[4], params[5], aBuffer, &Length);
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
cell_t GetOutputValue(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL)
|
||||
return -1;
|
||||
|
||||
switch(pEntityOutput->m_Value.fieldType)
|
||||
{
|
||||
case FIELD_TICK:
|
||||
case FIELD_MODELINDEX:
|
||||
case FIELD_MATERIALINDEX:
|
||||
case FIELD_INTEGER:
|
||||
case FIELD_COLOR32:
|
||||
case FIELD_SHORT:
|
||||
case FIELD_CHARACTER:
|
||||
case FIELD_BOOLEAN:
|
||||
break;
|
||||
default:
|
||||
return pContext->ThrowNativeError("%s value is not an integer (%d)", pOutput, pEntityOutput->m_Value.fieldType);
|
||||
}
|
||||
|
||||
return (cell_t)pEntityOutput->m_Value.iVal;
|
||||
}
|
||||
|
||||
cell_t GetOutputValueFloat(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL)
|
||||
return -1;
|
||||
|
||||
switch(pEntityOutput->m_Value.fieldType)
|
||||
{
|
||||
case FIELD_FLOAT:
|
||||
case FIELD_TIME:
|
||||
break;
|
||||
default:
|
||||
return pContext->ThrowNativeError("%s value is not a float (%d)", pOutput, pEntityOutput->m_Value.fieldType);
|
||||
}
|
||||
|
||||
return sp_ftoc((cell_t)pEntityOutput->m_Value.flVal);
|
||||
}
|
||||
|
||||
cell_t GetOutputValueString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL)
|
||||
return -1;
|
||||
|
||||
switch(pEntityOutput->m_Value.fieldType)
|
||||
{
|
||||
case FIELD_CHARACTER:
|
||||
case FIELD_STRING:
|
||||
case FIELD_MODELNAME:
|
||||
case FIELD_SOUNDNAME:
|
||||
break;
|
||||
default:
|
||||
return pContext->ThrowNativeError("%s value is not a string (%d)", pOutput, pEntityOutput->m_Value.fieldType);
|
||||
}
|
||||
|
||||
size_t len;
|
||||
pContext->StringToLocalUTF8(params[3], params[4], pEntityOutput->m_Value.iszVal.ToCStr(), &len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
cell_t GetOutputValueVector(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL)
|
||||
return -1;
|
||||
|
||||
switch(pEntityOutput->m_Value.fieldType)
|
||||
{
|
||||
case FIELD_FLOAT:
|
||||
case FIELD_TIME:
|
||||
break;
|
||||
default:
|
||||
return pContext->ThrowNativeError("%s value is not a float (%d)", pOutput, pEntityOutput->m_Value.fieldType);
|
||||
}
|
||||
|
||||
cell_t *vec;
|
||||
pContext->LocalToPhysAddr(params[3], &vec);
|
||||
|
||||
vec[0] = sp_ftoc(pEntityOutput->m_Value.vecVal[0]);
|
||||
vec[1] = sp_ftoc(pEntityOutput->m_Value.vecVal[1]);
|
||||
vec[2] = sp_ftoc(pEntityOutput->m_Value.vecVal[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
cell_t FindOutput(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return -1;
|
||||
|
||||
char *piTarget;
|
||||
pContext->LocalToStringNULL(params[4], &piTarget);
|
||||
char *piTargetInput;
|
||||
pContext->LocalToStringNULL(params[5], &piTargetInput);
|
||||
char *piParameter;
|
||||
pContext->LocalToStringNULL(params[6], &piParameter);
|
||||
float flDelay = *(float *)¶ms[7];
|
||||
cell_t nTimesToFire = params[8];
|
||||
|
||||
int StartCount = params[3];
|
||||
int Count = 0;
|
||||
for(CEventAction *ev = pEntityOutput->m_ActionList; ev != NULL; ev = ev->m_pNext)
|
||||
{
|
||||
Count++;
|
||||
if(StartCount > 0)
|
||||
{
|
||||
StartCount--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(piTarget != NULL && strcmp(ev->m_iTarget.ToCStr(), piTarget) != 0)
|
||||
continue;
|
||||
|
||||
if(piTargetInput != NULL && strcmp(ev->m_iTargetInput.ToCStr(), piTargetInput) != 0)
|
||||
continue;
|
||||
|
||||
if(piParameter != NULL && strcmp(ev->m_iParameter.ToCStr(), piParameter) != 0)
|
||||
continue;
|
||||
|
||||
if(flDelay >= 0 && flDelay != ev->m_flDelay)
|
||||
continue;
|
||||
|
||||
if(nTimesToFire != 0 && nTimesToFire != ev->m_nTimesToFire)
|
||||
continue;
|
||||
|
||||
return Count - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
cell_t DeleteOutput(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return -1;
|
||||
|
||||
return pEntityOutput->DeleteElement(params[3]);
|
||||
}
|
||||
|
||||
cell_t DeleteAllOutputs(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *pOutput;
|
||||
pContext->LocalToString(params[2], &pOutput);
|
||||
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
CBaseEntityOutput *pEntityOutput = GetOutput(pEntity, pOutput);
|
||||
if(pEntityOutput == NULL || pEntityOutput->m_ActionList == NULL)
|
||||
return -1;
|
||||
|
||||
return pEntityOutput->DeleteAllElements();
|
||||
}
|
||||
|
||||
cell_t GetOutputNames(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(gamehelpers->IndexToReference(params[1]));
|
||||
if(!pEntity)
|
||||
return -1;
|
||||
|
||||
datamap_t *pMap = gamehelpers->GetDataMap(pEntity);
|
||||
if(!pMap)
|
||||
return -1;
|
||||
|
||||
for(int count = 0; pMap != NULL; pMap = pMap->baseMap)
|
||||
{
|
||||
for(int i = 0; i < pMap->dataNumFields; i++)
|
||||
{
|
||||
typedescription_t *pTypeDesc = &pMap->dataDesc[i];
|
||||
|
||||
if(pTypeDesc->fieldType != FIELD_CUSTOM)
|
||||
continue;
|
||||
|
||||
if(!(pTypeDesc->flags & FTYPEDESC_OUTPUT))
|
||||
continue;
|
||||
|
||||
if(params[2] == count)
|
||||
{
|
||||
size_t len;
|
||||
pContext->StringToLocalUTF8(params[3], params[4], pTypeDesc->fieldName, &len);
|
||||
return len;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const sp_nativeinfo_t MyNatives[] =
|
||||
{
|
||||
{ "GetOutputCount", GetOutputCount },
|
||||
{ "GetOutputTarget", GetOutputTarget },
|
||||
{ "GetOutputTargetInput", GetOutputTargetInput },
|
||||
{ "GetOutputParameter", GetOutputParameter },
|
||||
{ "GetOutputDelay", GetOutputDelay },
|
||||
{ "GetOutputFormatted", GetOutputFormatted },
|
||||
{ "GetOutputValue", GetOutputValue },
|
||||
{ "GetOutputValueFloat", GetOutputValueFloat },
|
||||
{ "GetOutputValueString", GetOutputValueString },
|
||||
{ "GetOutputValueVector", GetOutputValueVector },
|
||||
{ "FindOutput", FindOutput },
|
||||
{ "DeleteOutput", DeleteOutput },
|
||||
{ "DeleteAllOutputs", DeleteAllOutputs },
|
||||
{ "GetOutputNames", GetOutputNames },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
bool Outputinfo::SDK_OnLoad(char *error, size_t maxlen, bool late)
|
||||
{
|
||||
char conf_error[255] = "";
|
||||
if(!gameconfs->LoadGameConfigFile("outputinfo.games", &g_pGameConf, conf_error, sizeof(conf_error)))
|
||||
{
|
||||
if(conf_error[0])
|
||||
{
|
||||
snprintf(error, maxlen, "Could not read outputinfo.games.txt: %s\n", conf_error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, path, sizeof(path), "bin/server.dll");
|
||||
|
||||
HMODULE hModule = GetModuleHandle(path);
|
||||
|
||||
uintptr_t pCode = (uintptr_t)memutils->FindPattern(hModule,
|
||||
"\x8B\x4C\x24\x28\x89\x41\x14\x8B\x4F\x18\xA1****\xFF\x0D****\x89\x07\x89\x3D****\x8B\xF9\xEB\x07",
|
||||
33);
|
||||
|
||||
if(!pCode)
|
||||
{
|
||||
snprintf(error, maxlen, "Failed to find windows signature.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uintptr_t ppHeadOfFreeList = *(uintptr_t *)(pCode + 11);
|
||||
uintptr_t pBlocksAllocated = *(uintptr_t *)(pCode + 17);
|
||||
|
||||
CEventAction::s_pBlocksAllocated = (int *)pBlocksAllocated;
|
||||
CEventAction::s_ppHeadOfFreeList = (void **)ppHeadOfFreeList;
|
||||
#else
|
||||
if(!g_pGameConf->GetMemSig("CEventAction__operator_delete", (void **)(&CEventAction::s_pOperatorDeleteFunc)) || !CEventAction::s_pOperatorDeleteFunc)
|
||||
{
|
||||
snprintf(error, maxlen, "Failed to find CEventAction__operator_delete function.\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Outputinfo::SDK_OnUnload()
|
||||
{
|
||||
gameconfs->CloseGameConfigFile(g_pGameConf);
|
||||
}
|
||||
|
||||
void Outputinfo::SDK_OnAllLoaded()
|
||||
{
|
||||
sharesys->AddNatives(myself, MyNatives);
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
/**
|
||||
* @file extension.h
|
||||
* @brief Sample extension code header.
|
||||
*/
|
||||
|
||||
#include "smsdk_ext.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sample implementation of the SDK Extension.
|
||||
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
|
||||
*/
|
||||
class Outputinfo : public SDKExtension
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief This is called after the initial loading sequence has been processed.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @param late Whether or not the module was loaded after map load.
|
||||
* @return True to succeed loading, false to fail.
|
||||
*/
|
||||
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief This is called right before the extension is unloaded.
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
|
||||
/**
|
||||
* @brief This is called once all known extensions have been loaded.
|
||||
* Note: It is is a good idea to add natives here, if any are provided.
|
||||
*/
|
||||
virtual void SDK_OnAllLoaded();
|
||||
|
||||
/**
|
||||
* @brief Called when the pause state is changed.
|
||||
*/
|
||||
//virtual void SDK_OnPauseChange(bool paused);
|
||||
|
||||
/**
|
||||
* @brief this is called when Core wants to know if your extension is working.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @return True if working, false otherwise.
|
||||
*/
|
||||
//virtual bool QueryRunning(char *error, size_t maxlength);
|
||||
public:
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
/**
|
||||
* @brief Called when Metamod is attached, before the extension version is called.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @param late Whether or not Metamod considers this a late load.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod is detaching, after the extension version is called.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod's pause state is changing.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param paused Pause state being set.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod Sample Extension
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||
|
||||
/**
|
||||
* @file smsdk_config.h
|
||||
* @brief Contains macros for configuring basic extension information.
|
||||
*/
|
||||
|
||||
#include "version.h"
|
||||
|
||||
/* Basic information exposed publicly */
|
||||
#define SMEXT_CONF_NAME "OutputInfo"
|
||||
#define SMEXT_CONF_DESCRIPTION "Read entity outputs"
|
||||
#define SMEXT_CONF_VERSION SM_FULL_VERSION
|
||||
#define SMEXT_CONF_AUTHOR "BotoX"
|
||||
#define SMEXT_CONF_URL ""
|
||||
#define SMEXT_CONF_LOGTAG "OUTPUTINFO"
|
||||
#define SMEXT_CONF_LICENSE "GPL"
|
||||
#define SMEXT_CONF_DATESTRING __DATE__
|
||||
|
||||
/**
|
||||
* @brief Exposes plugin's main interface.
|
||||
*/
|
||||
#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name;
|
||||
|
||||
/**
|
||||
* @brief Sets whether or not this plugin required Metamod.
|
||||
* NOTE: Uncomment to enable, comment to disable.
|
||||
*/
|
||||
//#define SMEXT_CONF_METAMOD
|
||||
|
||||
/** Enable interfaces you want to use here by uncommenting lines */
|
||||
//#define SMEXT_ENABLE_FORWARDSYS
|
||||
//#define SMEXT_ENABLE_HANDLESYS
|
||||
//#define SMEXT_ENABLE_PLAYERHELPERS
|
||||
//#define SMEXT_ENABLE_DBMANAGER
|
||||
#define SMEXT_ENABLE_GAMECONF
|
||||
#define SMEXT_ENABLE_MEMUTILS
|
||||
#define SMEXT_ENABLE_GAMEHELPERS
|
||||
//#define SMEXT_ENABLE_TIMERSYS
|
||||
//#define SMEXT_ENABLE_THREADER
|
||||
//#define SMEXT_ENABLE_LIBSYS
|
||||
//#define SMEXT_ENABLE_MENUS
|
||||
//#define SMEXT_ENABLE_ADTFACTORY
|
||||
//#define SMEXT_ENABLE_PLUGINSYS
|
||||
//#define SMEXT_ENABLE_ADMINSYS
|
||||
//#define SMEXT_ENABLE_TEXTPARSERS
|
||||
//#define SMEXT_ENABLE_USERMSGS
|
||||
//#define SMEXT_ENABLE_TRANSLATOR
|
||||
//#define SMEXT_ENABLE_ROOTCONSOLEMENU
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||
Reference in New Issue
Block a user