initial implementation of KV natives
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40660
This commit is contained in:
parent
bb92fc06a6
commit
08ec195e27
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Version="8,00"
|
||||
Name="sourcemod_mm"
|
||||
ProjectGUID="{E39527CD-7CAB-4420-97CC-DA1B93B260BC}"
|
||||
RootNamespace="sourcemod_mm"
|
||||
@ -737,6 +737,10 @@
|
||||
RelativePath="..\smn_handles.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\smn_keyvalues.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\smn_lang.cpp"
|
||||
>
|
||||
|
639
core/smn_keyvalues.cpp
Normal file
639
core/smn_keyvalues.cpp
Normal file
@ -0,0 +1,639 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* ===============================================================
|
||||
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||
* ===============================================================
|
||||
*
|
||||
* This file is not open source and may not be copied without explicit
|
||||
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||
* in whole or significant part.
|
||||
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include "sourcemod.h"
|
||||
#include "sourcemm_api.h"
|
||||
#include "sm_stringutil.h"
|
||||
#include "HandleSys.h"
|
||||
#include <KeyValues.h>
|
||||
|
||||
HandleType_t g_KeyValueType;
|
||||
|
||||
struct KeyValueStack
|
||||
{
|
||||
KeyValues *pBase;
|
||||
CStack<KeyValues *> pCurRoot;
|
||||
};
|
||||
|
||||
class KeyValuekNatives :
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch
|
||||
{
|
||||
public:
|
||||
void OnSourceModAllInitialized()
|
||||
{
|
||||
g_KeyValueType = g_HandleSys.CreateType("KeyValues", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
}
|
||||
void OnSourceModShutdown()
|
||||
{
|
||||
g_HandleSys.RemoveType(g_KeyValueType, g_pCoreIdent);
|
||||
g_KeyValueType = 0;
|
||||
}
|
||||
void OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
KeyValueStack *pStk = reinterpret_cast<KeyValueStack *>(object);
|
||||
pStk->pBase->deleteThis();
|
||||
delete pStk;
|
||||
}
|
||||
};
|
||||
|
||||
static cell_t smn_KvSetString(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *key, *value;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
pCtx->LocalToString(params[3], &value);
|
||||
|
||||
pStk->pCurRoot.front()->SetString(key, value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvSetNum(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *key;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
|
||||
pStk->pCurRoot.front()->SetInt(key, params[3]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvSetUint64(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *key;
|
||||
cell_t *addr;
|
||||
uint64 value;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
pCtx->LocalToPhysAddr(params[3], &addr);
|
||||
|
||||
value = static_cast<uint64>(*addr);
|
||||
pStk->pCurRoot.front()->SetUint64(key, value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvSetFloat(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *key;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
|
||||
pStk->pCurRoot.front()->SetFloat(key, sp_ctof(params[3]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvSetColor(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *key;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
|
||||
Color color(params[3], params[4], params[5], params[6]);
|
||||
pStk->pCurRoot.front()->SetColor(key, color);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvGetString(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
const char *value;
|
||||
char *key, *defvalue;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
pCtx->LocalToString(params[5], &defvalue);
|
||||
|
||||
value = pStk->pCurRoot.front()->GetString(key, defvalue);
|
||||
pCtx->StringToLocalUTF8(params[3], params[4], value, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvGetNum(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
int value;
|
||||
char *key;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
|
||||
value = pStk->pCurRoot.front()->GetInt(key, params[3]);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static cell_t smn_KvGetFloat(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
float value;
|
||||
char *key;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
|
||||
value = pStk->pCurRoot.front()->GetFloat(key, sp_ctof(params[3]));
|
||||
|
||||
return sp_ftoc(value);
|
||||
}
|
||||
|
||||
static cell_t smn_KvGetColor(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
Color color;
|
||||
char *key;
|
||||
cell_t *r, *g, *b, *a;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
pCtx->LocalToPhysAddr(params[3], &r);
|
||||
pCtx->LocalToPhysAddr(params[4], &g);
|
||||
pCtx->LocalToPhysAddr(params[5], &b);
|
||||
pCtx->LocalToPhysAddr(params[6], &a);
|
||||
|
||||
color = pStk->pCurRoot.front()->GetColor(key);
|
||||
*r = color.r();
|
||||
*g = color.g();
|
||||
*b = color.b();
|
||||
*a = color.a();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvGetUint64(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *key;
|
||||
cell_t *addr, *defvalue;
|
||||
uint64 value;
|
||||
pCtx->LocalToString(params[2], &key);
|
||||
pCtx->LocalToPhysAddr(params[3], &addr);
|
||||
pCtx->LocalToPhysAddr(params[4], &defvalue);
|
||||
|
||||
value = pStk->pCurRoot.front()->GetUint64(key, static_cast<uint64>(*defvalue));
|
||||
*reinterpret_cast<uint64 *>(addr) = value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_CreateKeyValues(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
KeyValueStack *pStk;
|
||||
char *name, *firstkey, *firstvalue;
|
||||
bool is_empty;
|
||||
|
||||
pCtx->LocalToString(params[1], &name);
|
||||
pCtx->LocalToString(params[2], &firstkey);
|
||||
pCtx->LocalToString(params[3], &firstvalue);
|
||||
|
||||
is_empty = (firstkey[0] == '\0');
|
||||
pStk = new KeyValueStack;
|
||||
pStk->pBase = new KeyValues(name, is_empty ? NULL : firstkey, (is_empty||(firstvalue[0]=='\0')) ? NULL : firstvalue);
|
||||
pStk->pCurRoot.push(pStk->pBase);
|
||||
|
||||
return g_HandleSys.CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
|
||||
}
|
||||
|
||||
static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
char *name;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pCtx->LocalToString(params[2], &name);
|
||||
|
||||
KeyValues *pSubKey = pStk->pBase->FindKey(name, (params[3]) ? true : false);
|
||||
if (!pSubKey)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pStk->pCurRoot.push(pSubKey);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvJumpFirstSubKey(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
KeyValues *pSubKey = pStk->pCurRoot.front();
|
||||
KeyValues *pFirstSubKey = pSubKey->GetFirstSubKey();
|
||||
if (!pFirstSubKey)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pStk->pCurRoot.push(pFirstSubKey);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvJumpNextSubKey(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
KeyValues *pSubKey = pStk->pCurRoot.front();
|
||||
KeyValues *pNextKey = pSubKey->GetNextKey();
|
||||
if (!pNextKey)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pStk->pCurRoot.push(pNextKey);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvGoBack(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (pStk->pCurRoot.size() == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pStk->pCurRoot.pop();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvRewind(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
while (pStk->pCurRoot.size() > 1)
|
||||
{
|
||||
pStk->pCurRoot.pop();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvGetSectionName(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
KeyValues *pSection = pStk->pCurRoot.front();
|
||||
const char *name = pSection->GetName();
|
||||
if (!name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pCtx->StringToLocalUTF8(params[2], params[3], name, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvSetSectionName(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
char *name;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pCtx->LocalToString(params[2], &name);
|
||||
|
||||
KeyValues *pSection = pStk->pCurRoot.front();
|
||||
pSection->SetName(name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_KvGetDataType(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
char *name;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pCtx->LocalToString(params[2], &name);
|
||||
|
||||
return pStk->pCurRoot.front()->GetDataType(name);
|
||||
}
|
||||
|
||||
static cell_t smn_KeyValuesToFile(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
char *path;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pCtx->LocalToString(params[2], &path);
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||
|
||||
return pStk->pCurRoot.front()->SaveToFile(basefilesystem, realpath);
|
||||
}
|
||||
|
||||
static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
char *path;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pCtx->LocalToString(params[2], &path);
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||
|
||||
return pStk->pCurRoot.front()->LoadFromFile(basefilesystem, realpath);
|
||||
}
|
||||
|
||||
static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
KeyValueStack *pStk;
|
||||
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pStk->pCurRoot.front()->UsesEscapeSequences(params[2] ? true : false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static KeyValuekNatives s_KeyValuekNatives;
|
||||
|
||||
REGISTER_NATIVES(keyvaluenatives)
|
||||
{
|
||||
{"KvSetString", smn_KvSetString},
|
||||
{"KvSetNum", smn_KvSetNum},
|
||||
{"KvSetUint64", smn_KvSetUint64},
|
||||
{"KvSetFloat", smn_KvSetFloat},
|
||||
{"KvSetColor", smn_KvSetColor},
|
||||
{"KvGetString", smn_KvGetString},
|
||||
{"KvGetNum", smn_KvGetNum},
|
||||
{"KvGetFloat", smn_KvGetFloat},
|
||||
{"KvGetColor", smn_KvGetColor},
|
||||
{"KvGetUint64", smn_KvGetUint64},
|
||||
{"CreateKeyValues", smn_CreateKeyValues},
|
||||
{"KvJumpToKey", smn_KvJumpToKey},
|
||||
{"KvJumpFirstSubKey", smn_KvJumpFirstSubKey},
|
||||
{"KvJumpNextSubKey", smn_KvJumpNextSubKey},
|
||||
{"KvGoBack", smn_KvGoBack},
|
||||
{"KvRewind", smn_KvRewind},
|
||||
{"KvGetSectionName", smn_KvGetSectionName},
|
||||
{"KvSetSectionName", smn_KvSetSectionName},
|
||||
{"KvGetDataType", smn_KvGetDataType},
|
||||
{"KeyValuesToFile", smn_KeyValuesToFile},
|
||||
{"FileToKeyValues", smn_FileToKeyValues},
|
||||
{"KvSetEscapeSequences", smn_KvSetEscapeSequences},
|
||||
{NULL, NULL}
|
||||
};
|
@ -29,6 +29,7 @@ IUniformRandomStream *engrandom = NULL;
|
||||
CallClass<IVEngineServer> *enginePatch = NULL;
|
||||
CallClass<IServerGameDLL> *gamedllPatch = NULL;
|
||||
IPlayerInfoManager *playerinfo = NULL;
|
||||
IBaseFileSystem *basefilesystem;
|
||||
|
||||
PLUGIN_EXPOSE(SourceMod, g_SourceMod_Core);
|
||||
|
||||
@ -42,6 +43,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
|
||||
GET_V_IFACE_CURRENT(engineFactory, icvar, ICvar, VENGINE_CVAR_INTERFACE_VERSION);
|
||||
GET_V_IFACE_CURRENT(engineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
|
||||
GET_V_IFACE_CURRENT(engineFactory, engrandom, IUniformRandomStream, VENGINE_SERVER_RANDOM_INTERFACE_VERSION);
|
||||
GET_V_IFACE_CURRENT(fileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION);
|
||||
|
||||
/* :TODO: Make this optional and... make it find earlier versions [?] */
|
||||
GET_V_IFACE_CURRENT(serverFactory, playerinfo, IPlayerInfoManager, INTERFACEVERSION_PLAYERINFOMANAGER);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <igameevents.h>
|
||||
#include <iplayerinfo.h>
|
||||
#include <random.h>
|
||||
#include <filesystem.h>
|
||||
|
||||
/**
|
||||
* @file Contains wrappers around required Metamod:Source API exports
|
||||
@ -57,6 +58,7 @@ extern SourceHook::CallClass<IVEngineServer> *enginePatch;
|
||||
extern SourceHook::CallClass<IServerGameDLL> *gamedllPatch;
|
||||
extern IUniformRandomStream *engrandom;
|
||||
extern IPlayerInfoManager *playerinfo;
|
||||
extern IBaseFileSystem *basefilesystem;
|
||||
|
||||
#define ENGINE_CALL(func) SH_CALL(enginePatch, &IVEngineServer::func)
|
||||
#define SERVER_CALL(func) SH_CALL(gamedllPatch, &IServerGameDLL::func)
|
||||
|
280
plugins/include/keyvalues.inc
Normal file
280
plugins/include/keyvalues.inc
Normal file
@ -0,0 +1,280 @@
|
||||
/**
|
||||
* 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 _keyvalues_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _keyvalues_included
|
||||
|
||||
/**
|
||||
* KeyValue data value types
|
||||
*/
|
||||
enum KvDataTypes
|
||||
{
|
||||
KvData_None = 0, /**< Type could not be identified, or no type */
|
||||
KvData_String, /**< String value */
|
||||
KvData_Int, /**< Integer value */
|
||||
KvData_Float, /**< Floating point value */
|
||||
KvData_Ptr, /**< Pointer value (sometimes called "long") */
|
||||
KvData_WString, /**< Wide string value */
|
||||
KvData_Color, /**< Color value */
|
||||
KvData_UInt64, /**< Large integer value */
|
||||
/* --- */
|
||||
KvData_NUMTYPES,
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new KeyValues structure. The Handle must always be closed.
|
||||
*
|
||||
* @param name Name of the root section.
|
||||
* @param firstKey If non-empty, specifies the first key value.
|
||||
* @param firstValue If firstKey is non-empty, specifies the first key's value.
|
||||
* @return A Handle to a new KeyValues structure.
|
||||
*/
|
||||
native Handle:CreateKeyValues(const String:name[], const String:firstkey[], const String:firstValue[]);
|
||||
|
||||
/**
|
||||
* Sets a string value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param value String value.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetString(Handle:kv, const String:key[], const String:value[]);
|
||||
|
||||
/**
|
||||
* Sets an integer value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param value Value number.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetNum(Handle:kv, const String:key[], value);
|
||||
|
||||
/**
|
||||
* Sets a large integer value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param value Large integer value (0=High bits, 1=Low bits)
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetUint64(Handle:kv, const String:key[], const value[2]);
|
||||
|
||||
/**
|
||||
* Sets a floating point value of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param value Floating point value.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetFloat(Handle:kv, const String:key[], Float:value);
|
||||
|
||||
/**
|
||||
* Sets a set of color values of a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param r Red value.
|
||||
* @param g Green value.
|
||||
* @param b Blue value.
|
||||
* @param a Alpha value.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetColor(Handle:kv, const String:key[], r, g, b, a=0);
|
||||
|
||||
/**
|
||||
* Retrieves a string value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param value Buffer to store key value in.
|
||||
* @param maxlength Maximum length of the value buffer.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetString(Handle:kv, const String:key[], String:value[], maxlength, const String:defvalue[]="");
|
||||
|
||||
/**
|
||||
* Retrieves an integer value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @return Integer value of the key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetNum(Handle:kv, const String:key[], defvalue=0);
|
||||
|
||||
/**
|
||||
* Retrieves a floating point value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @return Floating point value of the key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native Float:KvGetFloat(Handle:kv, const String:key[], Float:defvalue=0.0);
|
||||
|
||||
/**
|
||||
* Retrieves a set of color values from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param r Red value, set by reference.
|
||||
* @param g Green value, set by reference.
|
||||
* @param b Blue value, set by reference.
|
||||
* @param a Alpha value, set by reference.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetColor(Handle:kv, const String:key[], &r, &g, &b, &a);
|
||||
|
||||
/**
|
||||
* Retrieves a large integer value from a KeyValues key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param value Array to represent the large integer.
|
||||
* @param defvalue Optional default value to use if the key is not found.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvGetUint64(Handle:kv, const String:key[], value[2], defvalue[2]={0,0});
|
||||
|
||||
/**
|
||||
* Sets the current position in the KeyValues tree to the given key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Name of the key.
|
||||
* @param create If true, and the key does not exist, it will be created.
|
||||
* @return True if the key exists, false if it does not and was not created.
|
||||
*/
|
||||
native bool:KvJumpToKey(Handle:kv, const String:key[], bool:create=false);
|
||||
|
||||
/**
|
||||
* Sets the current position in the KeyValues tree to the first sub key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @return True on success, false if there was no first sub key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvJumpFirstSubKey(Handle:kv);
|
||||
|
||||
/**
|
||||
* Sets the current position in the KeyValues tree to the next sub key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @return True on success, false if there was no next sub key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvJumpNextSubKey(Handle:kv);
|
||||
|
||||
/**
|
||||
* Jumps back to the previous position. Returns false if there are no
|
||||
* previous positions (i.e., at the root node). This should be called
|
||||
* once for each successful Jump call, in order to return to the top node.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @return True on success, false if there is no higher node.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGoBack(Handle:kv);
|
||||
|
||||
/**
|
||||
* Sets the position back to the top node, emptying the entire node
|
||||
* traversal history. This can be used instead of looping KvGoBack()
|
||||
* if recursive iteration is not important.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvRewind(Handle:kv);
|
||||
|
||||
/**
|
||||
* Retrieves the current section name.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param section Buffer to store the section name.
|
||||
* @param maxlength Maximum length of the name buffer.
|
||||
* @return True on success, false on failure.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KvGetSectionName(Handle:kv, String:section[], maxlength);
|
||||
|
||||
/**
|
||||
* Sets the current section name.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param section Section name.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetSectionName(Handle:kv, const String:section[]);
|
||||
|
||||
/**
|
||||
* Returns the data type at a key.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param key Key name.
|
||||
* @return KvDataType value of the key.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvDataTypes:KvGetDataType(Handle:kv, const String:key[]);
|
||||
|
||||
/**
|
||||
* Converts a KeyValues tree to a file. The tree is dumped
|
||||
* from the current position.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param file File to dump write to.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:KeyValuesToFile(Handle:kv, const String:file[]);
|
||||
|
||||
/**
|
||||
* Converts a file to a KeyValues tree. The file is read into
|
||||
* the current position of the tree.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param file File to read from.
|
||||
* @return True on success, false otherwise.
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native bool:FileToKeyValues(Handle:kv, const String:file[]);
|
||||
|
||||
/**
|
||||
* Sets whether or not the KeyValues parser will read escape sequences.
|
||||
* For example, \n would be read as a literal newline. This defaults
|
||||
* to false for new KeyValues structures.
|
||||
*
|
||||
* @param kv KeyValues Handle.
|
||||
* @param useEscapes Whether or not to read escape sequences.
|
||||
* @noreturn
|
||||
* @error Invalid Handle.
|
||||
*/
|
||||
native KvSetEscapeSequences(Handle:kv, bool:useEscapes);
|
Loading…
Reference in New Issue
Block a user