1117 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1117 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * vim: set ts=4 :
 | 
						|
 * =============================================================================
 | 
						|
 * SourceMod
 | 
						|
 * 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 "sourcemod.h"
 | 
						|
#include "sourcemm_api.h"
 | 
						|
#include "sm_stringutil.h"
 | 
						|
#include "HandleSys.h"
 | 
						|
#include "HalfLife2.h"
 | 
						|
#include <KeyValues.h>
 | 
						|
#include "utlbuffer.h"
 | 
						|
 | 
						|
HandleType_t g_KeyValueType;
 | 
						|
 | 
						|
struct KeyValueStack 
 | 
						|
{
 | 
						|
	KeyValues *pBase;
 | 
						|
	CStack<KeyValues *> pCurRoot;
 | 
						|
};
 | 
						|
 | 
						|
class KeyValueNatives : 
 | 
						|
	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;
 | 
						|
	}
 | 
						|
	int CalcKVSizeR(KeyValues *pv)
 | 
						|
	{
 | 
						|
		CUtlBuffer buf;
 | 
						|
		int size;
 | 
						|
 | 
						|
		pv->RecursiveSaveToFile(buf, 0);
 | 
						|
		size = buf.TellMaxPut();
 | 
						|
 | 
						|
		buf.Purge();
 | 
						|
 | 
						|
		return size;
 | 
						|
	}
 | 
						|
	bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
 | 
						|
	{
 | 
						|
		KeyValueStack *pStk = (KeyValueStack *)object;
 | 
						|
		unsigned int size = sizeof(KeyValueStack) + (pStk->pCurRoot.size() * sizeof(KeyValues *));
 | 
						|
 | 
						|
		/* Check how much memory the actual thing takes up */		
 | 
						|
		size += CalcKVSizeR(pStk->pBase);
 | 
						|
 | 
						|
		*pSize = size;
 | 
						|
 | 
						|
		return true;
 | 
						|
	}
 | 
						|
};
 | 
						|
 | 
						|
KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
 | 
						|
{
 | 
						|
	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)
 | 
						|
	{
 | 
						|
		if (err)
 | 
						|
		{
 | 
						|
			*err = herr;
 | 
						|
		}
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (err)
 | 
						|
	{
 | 
						|
		*err = HandleError_None;
 | 
						|
	}
 | 
						|
 | 
						|
	return (root) ? pStk->pBase : pStk->pCurRoot.front();
 | 
						|
}
 | 
						|
 | 
						|
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->LocalToStringNULL(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->LocalToStringNULL(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->LocalToStringNULL(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->LocalToStringNULL(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->LocalToStringNULL(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_KvSetVector(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;
 | 
						|
	char buffer[64];
 | 
						|
	cell_t *vector;
 | 
						|
	pCtx->LocalToStringNULL(params[2], &key);
 | 
						|
	pCtx->LocalToPhysAddr(params[3], &vector);
 | 
						|
 | 
						|
	UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(vector[0]), sp_ctof(vector[1]), sp_ctof(vector[2]));
 | 
						|
 | 
						|
	pStk->pCurRoot.front()->SetString(key, buffer);
 | 
						|
 | 
						|
	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->LocalToStringNULL(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->LocalToStringNULL(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->LocalToStringNULL(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->LocalToStringNULL(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->LocalToStringNULL(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_KvGetVector(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;
 | 
						|
	const char *value;
 | 
						|
	cell_t *defvector, *outvector;
 | 
						|
	char buffer[64];
 | 
						|
	pCtx->LocalToStringNULL(params[2], &key);
 | 
						|
	pCtx->LocalToPhysAddr(params[3], &outvector);
 | 
						|
	pCtx->LocalToPhysAddr(params[4], &defvector);
 | 
						|
 | 
						|
	UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(defvector[0]), sp_ctof(defvector[1]), sp_ctof(defvector[2]));
 | 
						|
 | 
						|
	value = pStk->pCurRoot.front()->GetString(key, buffer);
 | 
						|
 | 
						|
	float out;
 | 
						|
	int components = 0;
 | 
						|
	while (*value && components < 3)
 | 
						|
	{
 | 
						|
		while ((*value) && (*value == ' '))
 | 
						|
		{
 | 
						|
			value++;
 | 
						|
		}
 | 
						|
 | 
						|
		out = 0.0f;
 | 
						|
		bool isnegative;
 | 
						|
		if (*value == '-')
 | 
						|
		{
 | 
						|
			isnegative = true;
 | 
						|
			value++;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			isnegative = false;
 | 
						|
		}
 | 
						|
 | 
						|
		for (; *value && isdigit(*value); ++value)
 | 
						|
		{
 | 
						|
			out *= 10.0f;
 | 
						|
			out += *value - '0';
 | 
						|
		}
 | 
						|
 | 
						|
		if (*value == '.')
 | 
						|
		{
 | 
						|
			value++;
 | 
						|
			float factor = 0.1f;
 | 
						|
			for (; *value && isdigit(*value); ++value)
 | 
						|
			{
 | 
						|
				out += (*value - '0') * factor;
 | 
						|
				factor *= 0.1f;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		out = (isnegative) ? -out : out;
 | 
						|
		outvector[components++] = sp_ftoc(out);
 | 
						|
	}
 | 
						|
 | 
						|
	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->pCurRoot.front();
 | 
						|
	pSubKey = pSubKey->FindKey(name, (params[3]) ? true : false);
 | 
						|
	if (!pSubKey)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	pStk->pCurRoot.push(pSubKey);
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_KvJumpToKeySymbol(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();
 | 
						|
	pSubKey = pSubKey->FindKey(params[2]);
 | 
						|
	if (!pSubKey)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	pStk->pCurRoot.push(pSubKey);
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_KvGotoFirstSubKey(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;
 | 
						|
	if (params[2])
 | 
						|
	{
 | 
						|
		pFirstSubKey = pSubKey->GetFirstTrueSubKey();
 | 
						|
	} else {
 | 
						|
		pFirstSubKey = pSubKey->GetFirstSubKey();
 | 
						|
	}
 | 
						|
 | 
						|
	if (!pFirstSubKey)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	pStk->pCurRoot.push(pFirstSubKey);
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_KvGotoNextKey(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();
 | 
						|
	if (params[2])
 | 
						|
	{
 | 
						|
		pSubKey = pSubKey->GetNextTrueSubKey();
 | 
						|
	} else {
 | 
						|
		pSubKey = pSubKey->GetNextKey();
 | 
						|
	}
 | 
						|
	if (!pSubKey)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	pStk->pCurRoot.pop();
 | 
						|
	pStk->pCurRoot.push(pSubKey);
 | 
						|
 | 
						|
	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);
 | 
						|
 | 
						|
	return pStk->pCurRoot.front()->SaveToFile(basefilesystem, path);
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
	KeyValues *kv;
 | 
						|
 | 
						|
	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);
 | 
						|
 | 
						|
	kv = pStk->pCurRoot.front();
 | 
						|
	return g_HL2.KVLoadFromFile(kv, basefilesystem, path);
 | 
						|
}
 | 
						|
 | 
						|
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 cell_t smn_KvNodesInStack(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);
 | 
						|
	}
 | 
						|
 | 
						|
	return pStk->pCurRoot.size() - 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_KvDeleteThis(IPluginContext *pContext, 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 pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
 | 
						|
	}
 | 
						|
 | 
						|
	if (pStk->pCurRoot.size() < 2)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	KeyValues *pValues = pStk->pCurRoot.front();
 | 
						|
	pStk->pCurRoot.pop();
 | 
						|
	KeyValues *pRoot = pStk->pCurRoot.front();
 | 
						|
 | 
						|
	/* We have to manually verify this since Valve sucks
 | 
						|
	 * :TODO: make our own KeyValues.h file and make
 | 
						|
	 * the sub stuff private so we can do this ourselves!
 | 
						|
 	 */
 | 
						|
	KeyValues *sub = pRoot->GetFirstSubKey();
 | 
						|
	while (sub)
 | 
						|
	{
 | 
						|
		if (sub == pValues)
 | 
						|
		{
 | 
						|
			KeyValues *pNext = pValues->GetNextKey();
 | 
						|
			pRoot->RemoveSubKey(pValues);
 | 
						|
			pValues->deleteThis();
 | 
						|
			if (pNext)
 | 
						|
			{
 | 
						|
				pStk->pCurRoot.push(pNext);
 | 
						|
				return 1;
 | 
						|
			} else {
 | 
						|
				return -1;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		sub = sub->GetNextKey();
 | 
						|
	}
 | 
						|
 | 
						|
	/* Push this back on :( */
 | 
						|
	pStk->pCurRoot.push(pValues);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_KvDeleteKey(IPluginContext *pContext, 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 pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
 | 
						|
	}
 | 
						|
 | 
						|
	if (pStk->pCurRoot.size() < 2)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	char *keyName;
 | 
						|
	pContext->LocalToString(params[2], &keyName);
 | 
						|
 | 
						|
	KeyValues *pRoot = pStk->pCurRoot.front();
 | 
						|
	KeyValues *pValues = pRoot->FindKey(keyName);
 | 
						|
	if (!pValues)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	pRoot->RemoveSubKey(pValues);
 | 
						|
	pValues->deleteThis();
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_KvSavePosition(IPluginContext *pContext, 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 pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
 | 
						|
	}
 | 
						|
 | 
						|
	if (pStk->pCurRoot.size() < 2)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	KeyValues *pValues = pStk->pCurRoot.front();
 | 
						|
	pStk->pCurRoot.push(pValues);
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_CopySubkeys(IPluginContext *pContext, const cell_t *params)
 | 
						|
{
 | 
						|
	Handle_t hndl_copied = static_cast<Handle_t>(params[1]);
 | 
						|
	Handle_t hndl_parent = static_cast<Handle_t>(params[2]);
 | 
						|
	HandleError herr;
 | 
						|
	HandleSecurity sec;
 | 
						|
	KeyValueStack *pStk_copied, *pStk_parent;
 | 
						|
 | 
						|
	sec.pOwner = NULL;
 | 
						|
	sec.pIdentity = g_pCoreIdent;
 | 
						|
 | 
						|
	if ((herr=g_HandleSys.ReadHandle(hndl_copied, g_KeyValueType, &sec, (void **)&pStk_copied))
 | 
						|
		!= HandleError_None)
 | 
						|
	{
 | 
						|
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_copied, herr);
 | 
						|
	}
 | 
						|
	if ((herr=g_HandleSys.ReadHandle(hndl_parent, g_KeyValueType, &sec, (void **)&pStk_parent))
 | 
						|
		!= HandleError_None)
 | 
						|
	{
 | 
						|
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_parent, herr);
 | 
						|
	}
 | 
						|
 | 
						|
	pStk_copied->pCurRoot.front()->CopySubkeys(pStk_parent->pCurRoot.front());
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_GetNameSymbol(IPluginContext *pContext, const cell_t *params)
 | 
						|
{
 | 
						|
	Handle_t hndl = static_cast<Handle_t>(params[1]);
 | 
						|
	HandleError herr;
 | 
						|
	HandleSecurity sec;
 | 
						|
	KeyValueStack *pStk;
 | 
						|
	cell_t *val;
 | 
						|
	char *key;
 | 
						|
 | 
						|
	sec.pOwner = NULL;
 | 
						|
	sec.pIdentity = g_pCoreIdent;
 | 
						|
 | 
						|
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
 | 
						|
		!= HandleError_None)
 | 
						|
	{
 | 
						|
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
 | 
						|
	}
 | 
						|
 | 
						|
	if (pStk->pCurRoot.size() < 2)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	pContext->LocalToString(params[2], &key);
 | 
						|
 | 
						|
	KeyValues *pKv = pStk->pCurRoot.front()->FindKey(key);
 | 
						|
	if (!pKv)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
	pContext->LocalToPhysAddr(params[3], &val);
 | 
						|
	*val = pKv->GetNameSymbol();
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_FindKeyById(IPluginContext *pContext, 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 pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
 | 
						|
	}
 | 
						|
 | 
						|
	KeyValues *pKv = pStk->pCurRoot.front()->FindKey(params[2]);
 | 
						|
	if (!pKv)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	pContext->StringToLocalUTF8(params[3], params[4], pKv->GetName(), NULL);
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
 | 
						|
{
 | 
						|
	Handle_t hndl = static_cast<Handle_t>(params[1]);
 | 
						|
	HandleError herr;
 | 
						|
	HandleSecurity sec;
 | 
						|
	KeyValueStack *pStk;
 | 
						|
	cell_t *val;
 | 
						|
 | 
						|
	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();
 | 
						|
 | 
						|
	pCtx->LocalToPhysAddr(params[2], &val);
 | 
						|
	*val = pSection->GetNameSymbol();
 | 
						|
 | 
						|
	if (!*val)
 | 
						|
	{
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static KeyValueNatives s_KeyValueNatives;
 | 
						|
 | 
						|
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},
 | 
						|
	{"KvJumpToKeySymbol",		smn_KvJumpToKeySymbol},
 | 
						|
	{"KvGotoNextKey",			smn_KvGotoNextKey},
 | 
						|
	{"KvGotoFirstSubKey",		smn_KvGotoFirstSubKey},
 | 
						|
	{"KvGoBack",				smn_KvGoBack},
 | 
						|
	{"KvRewind",				smn_KvRewind},
 | 
						|
	{"KvGetSectionName",		smn_KvGetSectionName},
 | 
						|
	{"KvSetSectionName",		smn_KvSetSectionName},
 | 
						|
	{"KvGetDataType",			smn_KvGetDataType},
 | 
						|
	{"KeyValuesToFile",			smn_KeyValuesToFile},
 | 
						|
	{"FileToKeyValues",			smn_FileToKeyValues},
 | 
						|
	{"KvSetEscapeSequences",	smn_KvSetEscapeSequences},
 | 
						|
	{"KvDeleteThis",			smn_KvDeleteThis},
 | 
						|
	{"KvDeleteKey",				smn_KvDeleteKey},
 | 
						|
	{"KvNodesInStack",			smn_KvNodesInStack},
 | 
						|
	{"KvSavePosition",			smn_KvSavePosition},
 | 
						|
	{"KvCopySubkeys",			smn_CopySubkeys},
 | 
						|
	{"KvFindKeyById",			smn_FindKeyById},
 | 
						|
	{"KvGetNameSymbol",			smn_GetNameSymbol},
 | 
						|
	{"KvGetSectionSymbol",		smn_KvGetSectionSymbol},
 | 
						|
	{"KvGetVector",				smn_KvGetVector},
 | 
						|
	{"KvSetVector",				smn_KvSetVector},
 | 
						|
	{NULL,						NULL}
 | 
						|
};
 |