- added bool type

- added pointer support
- added three default natives
- added include file for sdktools
- cleaned up decoding api a bit

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40960
This commit is contained in:
David Anderson 2007-06-16 18:03:05 +00:00
parent 6c64c00f6b
commit 11ff381289
11 changed files with 593 additions and 77 deletions

View File

@ -23,6 +23,7 @@
#include "extension.h"
#include "vcallbuilder.h"
#include "vnatives.h"
/**
* @file extension.cpp
@ -43,6 +44,7 @@ bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
sharesys->AddDependency(myself, "bintools.ext", true, true);
sharesys->AddNatives(myself, g_CallNatives);
sharesys->AddNatives(myself, g_Natives);
if (!gameconfs->LoadGameConfigFile("sdktools.games", &g_pGameConf, error, maxlength))
{
@ -65,6 +67,15 @@ void SDKTools::OnHandleDestroy(HandleType_t type, void *object)
void SDKTools::SDK_OnUnload()
{
List<ValveCall *>::iterator iter;
for (iter = g_RegCalls.begin();
iter != g_RegCalls.end();
iter++)
{
delete (*iter);
}
g_RegCalls.clear();
gameconfs->CloseGameConfigFile(g_pGameConf);
}

View File

@ -197,6 +197,10 @@
RelativePath="..\vdecoder.cpp"
>
</File>
<File
RelativePath="..\vnatives.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -215,6 +219,10 @@
RelativePath="..\vdecoder.h"
>
</File>
<File
RelativePath="..\vnatives.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"

View File

@ -8,29 +8,6 @@
using namespace SourceMod;
using namespace SourceHook;
/**
* @brief Valve pre-defined calling types
*/
enum ValveCallType
{
ValveCall_Static, /**< Static call */
ValveCall_Entity, /**< Thiscall (CBaseEntity implicit first parameter) */
ValveCall_Player, /**< Thiscall (CBasePlayer implicit first parameter) */
};
/**
* @brief Valve parameter info
*/
struct ValvePassInfo
{
ValveType vtype; /**< IN: Valve type */
unsigned int decflags; /**< IN: VDECODE_FLAG_* */
unsigned int encflags; /**< IN: VENCODE_FLAG_* */
PassType type; /**< IN: Pass information */
unsigned int flags; /**< IN: Pass flags */
size_t offset; /**< OUT: stack offset */
};
/**
* @brief Info necessary to call a Valve function
*/

View File

@ -29,9 +29,10 @@ inline void DecodePassMethod(ValveType vtype, SDKPassMethod method, PassType &ty
{
type = PassType_Basic;
if (vtype == Valve_POD
|| vtype == Valve_Float)
|| vtype == Valve_Float
|| vtype == Valve_Bool)
{
flags = PASSFLAG_BYREF;
flags = PASSFLAG_ASPOINTER;
} else {
flags = PASSFLAG_BYVAL;
}
@ -169,7 +170,7 @@ static cell_t PrepSDKCall_AddParameter(IPluginContext *pContext, const cell_t *p
ValvePassInfo *info = &s_params[s_numparams++];
info->vtype = (ValveType)params[1];
DecodePassMethod(info->vtype, (SDKPassMethod)params[2], info->type, info->flags);
info->decflags = params[3];
info->decflags = params[3] | VDECODE_FLAG_BYREF;
info->encflags = params[4];
return 1;
@ -227,9 +228,7 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
}
if (DecodeValveParam(pContext,
params[startparam],
vc->thisinfo->vtype,
vc->thisinfo->decflags | VDECODE_FLAG_BYREF,
vc->thisinfo->type,
vc->thisinfo,
ptr) == Data_Fail)
{
vc->stk_put(ptr);
@ -264,9 +263,7 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
}
if (DecodeValveParam(pContext,
params[p],
vc->vparams[i].vtype,
vc->vparams[i].decflags | VDECODE_FLAG_BYREF,
vc->vparams[i].type,
&(vc->vparams[i]),
ptr + vc->vparams[i].offset) == Data_Fail)
{
vc->stk_put(ptr);
@ -290,8 +287,7 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
{
if (EncodeValveParam(pContext,
startparam + i,
vc->vparams[i].vtype,
vc->vparams[i].type,
&vc->vparams[i],
ptr + vc->vparams[i].offset) == Data_Fail)
{
vc->stk_put(ptr);
@ -325,7 +321,7 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
{
return pContext->ThrowNativeError("Expected argument (2) for Float[3] storage");
}
if (EncodeValveParam(pContext, params[retparam], vc->retinfo->vtype, vc->retinfo->type, vc->retbuf)
if (EncodeValveParam(pContext, params[retparam], vc->retinfo, vc->retbuf)
== Data_Fail)
{
return 0;
@ -351,6 +347,13 @@ static cell_t SDKCall(IPluginContext *pContext, const cell_t *params)
return -1;
}
return engine->IndexOfEdict(pEdict);
} else if (vc->retinfo->vtype == Valve_Bool) {
bool *addr = (bool *)vc->retbuf;
if (vc->retinfo->flags & PASSFLAG_BYREF)
{
addr = *(bool **)addr;
}
return *addr ? 1 : 0;
} else {
cell_t *addr = (cell_t *)vc->retbuf;
if (vc->retinfo->flags & PASSFLAG_BYREF)

View File

@ -68,12 +68,10 @@ size_t ValveParamToBinParam(ValveType type,
}
case Valve_CBaseEntity:
case Valve_CBasePlayer:
case Valve_POD:
case Valve_Edict:
case Valve_String:
{
if (pass != PassType_Basic
|| (info->flags & PASSFLAG_BYREF))
if (pass != PassType_Basic || (info->flags & PASSFLAG_BYREF))
{
return 0;
}
@ -82,34 +80,65 @@ size_t ValveParamToBinParam(ValveType type,
info->size = sizeof(void *);
return sizeof(void *);
}
case Valve_POD:
{
info->type = PassType_Basic;
info->flags = flags;
if (flags & PASSFLAG_ASPOINTER)
{
info->size = sizeof(int *);
return sizeof(int *) + sizeof(int);
} else {
info->size = sizeof(int);
return sizeof(int);
}
}
case Valve_Bool:
{
info->type = PassType_Basic;
info->flags = flags;
if (flags & PASSFLAG_ASPOINTER)
{
info->size = sizeof(bool *);
return sizeof(bool *) + sizeof(bool);
} else {
info->size = sizeof(bool);
return sizeof(bool);
}
}
case Valve_Float:
{
info->type = PassType_Float;
info->flags = flags;
if (flags & PASSFLAG_ASPOINTER)
{
info->size = sizeof(float *);
return sizeof(float *) + sizeof(float);
} else {
info->size = sizeof(float);
return sizeof(float);
}
}
}
return 0;
}
DataStatus EncodeValveParam(IPluginContext *pContext,
cell_t param,
ValveType type,
PassType pass,
const ValvePassInfo *data,
const void *buffer)
{
switch (type)
switch (data->vtype)
{
case Valve_Vector:
{
Vector *v = NULL;
if (pass == PassType_Basic)
if (data->type == PassType_Basic)
{
v = *(Vector **)((unsigned char *)buffer + sizeof(Vector *));
} else if (pass == PassType_Object) {
} else if (data->type == PassType_Object) {
v = (Vector *)buffer;
}
@ -126,10 +155,10 @@ DataStatus EncodeValveParam(IPluginContext *pContext,
{
QAngle *q = NULL;
if (pass == PassType_Basic)
if (data->type == PassType_Basic)
{
q = *(QAngle **)((unsigned char *)buffer + sizeof(QAngle *));
} else if (pass == PassType_Object) {
} else if (data->type == PassType_Object) {
q = (QAngle *)buffer;
}
@ -180,8 +209,27 @@ DataStatus EncodeValveParam(IPluginContext *pContext,
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
if (data->flags & PASSFLAG_ASPOINTER)
{
buffer = (char *)buffer + sizeof(void *);
}
*addr = *(cell_t *)buffer;
return Data_Okay;
}
case Valve_Bool:
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
if (data->flags & PASSFLAG_ASPOINTER)
{
buffer = (char *)buffer + sizeof(bool *);
}
*addr = *(bool *)buffer ? 1 : 0;
return Data_Okay;
}
}
@ -191,12 +239,10 @@ DataStatus EncodeValveParam(IPluginContext *pContext,
DataStatus DecodeValveParam(IPluginContext *pContext,
cell_t param,
ValveType vtype,
unsigned int vflags,
PassType type,
const ValvePassInfo *data,
void *buffer)
{
switch (vtype)
switch (data->vtype)
{
case Valve_Vector:
{
@ -205,7 +251,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
err = pContext->LocalToPhysAddr(param, &addr);
unsigned char *mem = (unsigned char *)buffer;
if (type == PassType_Basic)
if (data->type == PassType_Basic)
{
/* Store the object in the next N bytes, and store
* a pointer to that object right beforehand.
@ -214,7 +260,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
if (addr == pContext->GetNullRef(SP_NULL_VECTOR))
{
if (vflags & VDECODE_FLAG_ALLOWNULL)
if (data->decflags & VDECODE_FLAG_ALLOWNULL)
{
*realPtr = NULL;
return Data_Okay;
@ -252,7 +298,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
err = pContext->LocalToPhysAddr(param, &addr);
unsigned char *mem = (unsigned char *)buffer;
if (type == PassType_Basic)
if (data->type == PassType_Basic)
{
/* Store the object in the next N bytes, and store
* a pointer to that object right beforehand.
@ -261,7 +307,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
if (addr == pContext->GetNullRef(SP_NULL_VECTOR))
{
if (!(vflags & VDECODE_FLAG_ALLOWNULL))
if (!(data->decflags & VDECODE_FLAG_ALLOWNULL))
{
pContext->ThrowNativeError("NULL not allowed");
return Data_Fail;
@ -295,7 +341,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
case Valve_CBasePlayer:
{
edict_t *pEdict;
if (vflags & VDECODE_FLAG_BYREF)
if (data->decflags & VDECODE_FLAG_BYREF)
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
@ -304,7 +350,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
if (param >= 1 && param <= playerhelpers->GetMaxClients())
{
IGamePlayer *player = playerhelpers->GetGamePlayer(param);
if ((vflags & VDECODE_FLAG_ALLOWNOTINGAME)
if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
&& !player->IsConnected())
{
pContext->ThrowNativeError("Client %d is not connected", param);
@ -315,7 +361,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
}
pEdict = player->GetEdict();
} else if (param == -1) {
if (vflags & VDECODE_FLAG_ALLOWNULL)
if (data->decflags & VDECODE_FLAG_ALLOWNULL)
{
pEdict = NULL;
} else {
@ -323,7 +369,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
return Data_Fail;
}
} else if (param == 0) {
if (vflags & VDECODE_FLAG_ALLOWWORLD)
if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
{
pEdict = engine->PEntityOfEntIndex(0);
} else {
@ -361,7 +407,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
case Valve_CBaseEntity:
{
edict_t *pEdict;
if (vflags & VDECODE_FLAG_BYREF)
if (data->decflags & VDECODE_FLAG_BYREF)
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
@ -370,7 +416,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
if (param >= 1 && param <= playerhelpers->GetMaxClients())
{
IGamePlayer *player = playerhelpers->GetGamePlayer(param);
if ((vflags & VDECODE_FLAG_ALLOWNOTINGAME)
if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
&& !player->IsConnected())
{
pContext->ThrowNativeError("Client %d is not connected", param);
@ -381,7 +427,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
}
pEdict = player->GetEdict();
} else if (param == -1) {
if (vflags & VDECODE_FLAG_ALLOWNULL)
if (data->decflags & VDECODE_FLAG_ALLOWNULL)
{
pEdict = NULL;
} else {
@ -389,7 +435,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
return Data_Fail;
}
} else if (param == 0) {
if (vflags & VDECODE_FLAG_ALLOWWORLD)
if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
{
pEdict = engine->PEntityOfEntIndex(0);
} else {
@ -431,7 +477,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
case Valve_Edict:
{
edict_t *pEdict;
if (vflags & VDECODE_FLAG_BYREF)
if (data->decflags & VDECODE_FLAG_BYREF)
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
@ -440,7 +486,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
if (param >= 1 && param <= playerhelpers->GetMaxClients())
{
IGamePlayer *player = playerhelpers->GetGamePlayer(param);
if ((vflags & VDECODE_FLAG_ALLOWNOTINGAME)
if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
&& !player->IsConnected())
{
pContext->ThrowNativeError("Client %d is not connected", param);
@ -451,7 +497,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
}
pEdict = player->GetEdict();
} else if (param == -1) {
if (vflags & VDECODE_FLAG_ALLOWNULL)
if (data->decflags & VDECODE_FLAG_ALLOWNULL)
{
pEdict = NULL;
} else {
@ -459,7 +505,7 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
return Data_Fail;
}
} else if (param == 0) {
if (vflags & VDECODE_FLAG_ALLOWWORLD)
if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
{
pEdict = engine->PEntityOfEntIndex(0);
} else {
@ -483,15 +529,36 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
case Valve_POD:
case Valve_Float:
{
if (vflags & VDECODE_FLAG_BYREF)
if (data->decflags & VDECODE_FLAG_BYREF)
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
param = *addr;
}
if (data->flags & PASSFLAG_ASPOINTER)
{
*(void **)buffer = (char *)buffer + sizeof(void *);
buffer = *(void **)buffer;
}
*(cell_t *)buffer = param;
return Data_Okay;
}
case Valve_Bool:
{
if (data->decflags & VDECODE_FLAG_BYREF)
{
cell_t *addr;
pContext->LocalToPhysAddr(param, &addr);
param = *addr;
}
if (data->flags & PASSFLAG_ASPOINTER)
{
*(bool **)buffer = (bool *)((char *)buffer + sizeof(bool *));
buffer = *(bool **)buffer;
}
*(bool *)buffer = param ? true : false;
return Data_Okay;
}
case Valve_String:
{
char *addr;

View File

@ -21,6 +21,7 @@ enum ValveType
Valve_Float, /**< Float */
Valve_Edict, /**< Edict */
Valve_String, /**< String */
Valve_Bool, /**< Boolean */
};
enum DataStatus
@ -36,6 +37,31 @@ enum DataStatus
#define VENCODE_FLAG_COPYBACK (1<<0) /**< Copy back data */
#define PASSFLAG_ASPOINTER (1<<30) /**< Not an actual passflag, used internally */
/**
* @brief Valve pre-defined calling types
*/
enum ValveCallType
{
ValveCall_Static, /**< Static call */
ValveCall_Entity, /**< Thiscall (CBaseEntity implicit first parameter) */
ValveCall_Player, /**< Thiscall (CBasePlayer implicit first parameter) */
};
/**
* @brief Valve parameter info
*/
struct ValvePassInfo
{
ValveType vtype; /**< IN: Valve type */
unsigned int decflags; /**< IN: VDECODE_FLAG_* */
unsigned int encflags; /**< IN: VENCODE_FLAG_* */
PassType type; /**< IN: Pass information */
unsigned int flags; /**< IN: Pass flags */
size_t offset; /**< OUT: stack offset */
};
/**
* @brief Converts a valve parameter to a bintools parameter.
*
@ -59,16 +85,12 @@ size_t ValveParamToBinParam(ValveType type,
*
* @param pContext Plugin context.
* @param param Parameter value from params array.
* @param type Valve type.
* @param pass Pass info from bin tools.
* @param buffer Buffer space in the virutal stack.
* @return True on success, false otherwise.
*/
DataStatus DecodeValveParam(IPluginContext *pContext,
cell_t param,
ValveType type,
unsigned int vflags,
PassType pass,
const ValvePassInfo *vdata,
void *buffer);
/**
@ -79,15 +101,12 @@ DataStatus DecodeValveParam(IPluginContext *pContext,
*
* @param pContext Plugin context.
* @param param Parameter value from params array.
* @param type Valve type.
* @param pass Pass info from bin tools.
* @param buffer Buffer space in the virutal stack.
* @return True on success, false otherwise.
*/
DataStatus EncodeValveParam(IPluginContext *pContext,
cell_t param,
ValveType type,
PassType pass,
const ValvePassInfo *vdata,
const void *buffer);
#endif //_INCLUDE_SOURCEMOD_VDECODER_H_

View File

@ -0,0 +1,182 @@
#include "extension.h"
#include "vcallbuilder.h"
#include "vnatives.h"
List<ValveCall *> g_RegCalls;
inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags)
{
info.decflags = 0;
info.encflags = 0;
info.flags = flags;
info.type = type;
info.vtype = vtype;
}
#define START_CALL() \
unsigned char *vptr = pCall->stk_get();
#define FINISH_CALL_SIMPLE(vret) \
pCall->call->Execute(vptr, vret); \
pCall->stk_put(vptr);
#define ENCODE_VALVE_PARAM(num, which, vnum) \
if (EncodeValveParam(pContext, \
params[num], \
&pCall->which[vnum], \
vptr + pCall->which[vnum].offset) \
== Data_Fail) \
{ \
return 0; \
}
#define DECODE_VALVE_PARAM(num, which, vnum) \
if (DecodeValveParam(pContext, \
params[num], \
&pCall->which[vnum], \
vptr + pCall->which[vnum].offset) \
== Data_Fail) \
{ \
return 0; \
}
bool CreateBaseCall(const char *name,
ValveCallType vcalltype,
const ValvePassInfo *retinfo,
const ValvePassInfo params[],
unsigned int numParams,
ValveCall **vaddr)
{
int offset;
ValveCall *call;
if (g_pGameConf->GetOffset(name, &offset))
{
call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams);
if (call)
{
g_RegCalls.push_back(call);
}
*vaddr = call;
return true;
} else {
void *addr;
if (g_pGameConf->GetMemSig(name, &addr))
{
call = CreateValveCall(addr, vcalltype, retinfo, params, numParams);
if (call)
{
g_RegCalls.push_back(call);
}
*vaddr = call;
return true;
}
}
return false;
}
static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
if (!pCall)
{
ValvePassInfo pass[2];
InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, 0);
InitPass(pass[1], Valve_Bool, PassType_Basic, 0);
if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], &pass[0], 1, &pCall))
{
return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod");
} else if (!pCall) {
return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized");
}
}
bool ret;
START_CALL();
DECODE_VALVE_PARAM(1, thisinfo, 0);
DECODE_VALVE_PARAM(2, vparams, 0);
FINISH_CALL_SIMPLE(&ret);
return ret ? 1 : 0;
}
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
if (!pCall)
{
ValvePassInfo pass[3];
InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall))
{
return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod");
} else if (!pCall) {
return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized");
}
}
CBaseEntity *pEntity = NULL;
START_CALL();
DECODE_VALVE_PARAM(1, thisinfo, 0);
DECODE_VALVE_PARAM(2, vparams, 0);
DECODE_VALVE_PARAM(3, vparams, 1);
FINISH_CALL_SIMPLE(&pEntity);
if (pEntity == NULL)
{
return -1;
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
return -1;
}
return engine->IndexOfEdict(pEdict);
}
static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
if (!pCall)
{
ValvePassInfo pass[2];
InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall))
{
return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod");
} else if (!pCall) {
return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized");
}
}
CBaseEntity *pEntity;
START_CALL();
DECODE_VALVE_PARAM(1, thisinfo, 0);
DECODE_VALVE_PARAM(2, vparams, 0);
FINISH_CALL_SIMPLE(&pEntity);
if (pEntity == NULL)
{
return -1;
}
edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
if (!pEdict)
{
return -1;
}
return engine->IndexOfEdict(pEdict);
}
sp_nativeinfo_t g_Natives[] =
{
{"RemovePlayerItem", RemovePlayerItem},
{"GivePlayerItem", GiveNamedItem},
{"GetPlayerWeaponSlot", GetPlayerWeaponSlot},
{NULL, NULL},
};

View File

@ -0,0 +1,9 @@
#ifndef _INCLUDE_SDKTOOLS_VNATIVES_H_
#define _INCLUDE_SDKTOOLS_VNATIVES_H_
#include <sh_list.h>
extern List<ValveCall *> g_RegCalls;
extern sp_nativeinfo_t g_Natives[];
#endif //_INCLUDE_SDKTOOLS_VNATIVES_H_

View File

@ -14,6 +14,16 @@
"windows" "329"
"linux" "330"
}
"RemovePlayerItem"
{
"windows" "226"
"linux" "227"
}
"Weapon_GetSlot"
{
"windows" "224"
"linux" "225"
}
}
}
}

View File

@ -0,0 +1,179 @@
/**
* vim: set ts=4 :
* ===============================================================
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
* ===============================================================
*
* This file is part of the SourceMod/SourcePawn SDK. This file may only be used
* or modified under the Terms and Conditions of its License Agreement, which is found
* in LICENSE.txt. The Terms and Conditions for making SourceMod extensions/plugins
* may change at any time. To view the latest information, see:
* http://www.sourcemod.net/license.php
*
* Version: $Id$
*/
#if defined _sdktools_included
#endinput
#endif
#define _sdktools_included
#include <core>
#include <sdktools_functions>
enum SDKCallType
{
SDKCall_Static, /**< Static call */
SDKCall_Entity, /**< CBaseEntity call */
SDKCall_Player, /**< CBasePlayer call */
};
enum SDKLibrary
{
SDKLibrary_Server, /**< server.dll/server_i486.so */
SDKLibrary_Engine, /**< engine.dll/engine_*.so */
};
enum SDKFuncConfSource
{
SDKConf_Virtual = 0, /**< Read a virtual index from the Offsets section */
SDKConf_Signature = 1, /**< Read a signature from the Signatures section */
};
enum SDKType
{
SDKType_CBaseEntity, /**< CBaseEntity (always as pointer) */
SDKType_CBasePlayer, /**< CBasePlayer (always as pointer) */
SDKType_Vector, /**< Vector (pointer, byval, or byref) */
SDKType_QAngle, /**< QAngles (pointer, byval, or byref) */
SDKType_PlainOldData, /**< Integer/generic data <=32bit (any) */
SDKType_Float, /**< Float (any) */
SDKType_Edict, /**< edict_t (always as pointer) */
SDKType_String, /**< NULL-terminated string (always as pointer) */
};
enum SDKPassMethod
{
SDKPass_Pointer, /**< Pass as a pointer */
SDKPass_Plain, /**< Pass as plain data */
SDKPass_ByValue, /**< Pass an object by value */
SDKPass_ByRef, /**< Pass an object by reference */
};
#define VDECODE_FLAG_ALLOWNULL (1<<0) /**< Allow NULL for pointers */
#define VDECODE_FLAG_ALLOWNOTINGAME (1<<1) /**< Allow players not in game */
#define VDECODE_FLAG_ALLOWWORLD (1<<2) /**< Allow World entity */
#define VDECODE_FLAG_BYREF (1<<3) /**< Floats/ints by reference */
#define VENCODE_FLAG_COPYBACK (1<<0) /**< Copy back data once done */
/**
* Starts the preparation of an SDK call.
*
* @param type Type of function call this will be.
* @noreturn
*/
native StartPrepSDKCall(SDKCallType:type);
/**
* Sets the virtual index of the SDK call if it is virtual.
*
* @param vtblidx Virtual table index.
* @noreturn
*/
native PrepSDKCall_SetVirtual(vtblidx);
/**
* Finds an address in a library and sets it as the address to use for the SDK call.
*
* @param lib Library to use.
* @param signature Binary data to search for in the library. If it starts with '@',
* the bytes parameter is ignored and the signature is interpreted
* as a symbol lookup in the library.
* @param bytes Number of bytes in the binary search string.
* @return True on success, false if nothing was found.
*/
native bool:PrepSDKCall_SetSignature(SDKLibrary:lib, const String:signature[], bytes);
/**
* Finds an address or virtual function index in a GameConfig file and sets it as
* the calling information for the SDK call.
*
* @param gameconf GameConfig Handle, or INVALID_HANDLE to use sdktools.games.txt.
* @param source Whether to look in Offsets or Signatures.
* @param name Name of the property to find.
* @return True on success, false if nothing was found.
*/
native bool:PrepSDKCall_SetFromConf(Handle:gameconf, SDKFuncConfSource:source, const String:name[]);
/**
* Sets the return information of an SDK call. Do not call this if there is no return data.
* This must be called if there is a return value (i.e. it is not necessarily safe to ignore
* the data).
*
* @param type Data type to convert to/from.
* @param pass How the data is passed in C++.
* @param decflags Flags on decoding from the plugin to C++.
* @param encflags Flags on encoding from C++ to the plugin.
* @noreturn
*/
native PrepSDKCall_SetReturnInfo(SDKType:type, SDKPassMethod:pass, decflags=0, encflags=0);
/**
* Adds a parameter to the calling convention. This should be called in normal ascending order.
*
* @param type Data type to convert to/from.
* @param pass How the data is passed in C++.
* @param decflags Flags on decoding from the plugin to C++.
* @param encflags Flags on encoding from C++ to the plugin.
* @noreturn
*/
native PrepSDKCall_AddParameter(SDKType:type, SDKPassMethod:pass, decflags=0, encflags=0);
/**
* Finalizes an SDK call preparation and returns the resultant Handle.
*
* @return A new SDKCall Handle on success, or INVALID_HANDLE on failure.
*/
native Handle:EndPrepSDKCall();
/**
* Calls an SDK function with the given parameters.
*
* If the call type is Entity or Player, the index MUST ALWAYS be the FIRST parameter passed.
* If the return value is a Vector or QAngles, the SECOND parameter must be a Float[3].
* If the return value is a string, the THIRD parameter must be a String buffer, and the
* FOURTH parameter must be the maximum length.
* All parameters must be passed after the above is followed. Failure to follow these
* rules will result in crashes or wildly unexpected behavior!
*
* If the return value is a float or integer, the return value will be this value.
* If the return value is a CBaseEntity, CBasePlayer, or edict, the return value will
* always be the entity index, or -1 for NULL.
*
* @param call SDKCall Handle.
* @param ... Call Parameters.
* @return Simple return value, if any.
* @error Invalid Handle or internal decoding error.
*/
native any:SDKCall(Handle:call, any:...);
/**
* Do not edit below this line!
*/
public Extension:__ext_sdktools =
{
name = "SDKTools",
file = "sdktools.ext",
#if defined AUTOLOAD_EXTENSIONS
autoload = 1,
#else
autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
required = 1,
#else
required = 0,
#endif
};

View File

@ -0,0 +1,51 @@
/**
* vim: set ts=4 :
* ===============================================================
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
* ===============================================================
*
* This file is part of the SourceMod/SourcePawn SDK. This file may only be used
* or modified under the Terms and Conditions of its License Agreement, which is found
* in LICENSE.txt. The Terms and Conditions for making SourceMod extensions/plugins
* may change at any time. To view the latest information, see:
* http://www.sourcemod.net/license.php
*
* Version: $Id$
*/
#if defined _sdktools_functions_included
#endinput
#endif
#define _sdktools_functions_included
/**
* Removes a player's item.
*
* @param client Client index.
* @param item CBaseCombatWeapon entity index.
* @return True on success, false otherwise.
* @error Invalid client or entity, lack of mod support, or client not in
* game.
*/
native bool:RemovePlayerItem(client, item);
/**
* Gives a named item to a player.
*
* @param client Client index.
* @param item Item classname (such as weapon_ak47).
* @param iSubType Unknown.
* @return Entity index on success, or -1 on failure.
* @error Invalid client or client not in game, or lack of mod support.
*/
native GivePlayerItem(client, const String:item[], iSubType=0);
/**
* Returns the weapon in a player's slot.
*
* @param client Client index.
* @param slot Slot index (mod specific).
* @return Entity index on success, -1 if no weapon existed.
* @error Invalid client or client notin game, or lack of mod support.
*/
native GetPlayerWeaponSlot(client, slot);