faluco@654: /**
faluco@654: * vim: set ts=4 :
ds@1330: * =============================================================================
dvander@1231: * SourceMod
dvander@1231: * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
ds@1330: * =============================================================================
faluco@654: *
ds@1330: * This program is free software; you can redistribute it and/or modify it under
ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330: * Free Software Foundation.
dvander@1231: *
ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
ds@1330: * details.
dvander@1231: *
ds@1330: * You should have received a copy of the GNU General Public License along with
ds@1330: * this program. If not, see .
dvander@1231: *
ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in
ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants
ds@1330: * this exception to all derivative works. AlliedModders LLC defines further
ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330: * or .
faluco@654: *
faluco@654: * Version: $Id$
faluco@654: */
faluco@654:
faluco@654: #include "sourcemod.h"
faluco@654: #include "sourcemm_api.h"
faluco@654: #include "sm_stringutil.h"
faluco@654: #include "HandleSys.h"
faluco@654: #include
faluco@654:
faluco@654: HandleType_t g_KeyValueType;
faluco@654:
faluco@654: struct KeyValueStack
faluco@654: {
faluco@654: KeyValues *pBase;
faluco@654: CStack pCurRoot;
faluco@654: };
faluco@654:
faluco@703: class KeyValueNatives :
faluco@654: public SMGlobalClass,
faluco@654: public IHandleTypeDispatch
faluco@654: {
faluco@654: public:
faluco@654: void OnSourceModAllInitialized()
faluco@654: {
faluco@654: g_KeyValueType = g_HandleSys.CreateType("KeyValues", this, 0, NULL, NULL, g_pCoreIdent, NULL);
faluco@654: }
faluco@654: void OnSourceModShutdown()
faluco@654: {
faluco@654: g_HandleSys.RemoveType(g_KeyValueType, g_pCoreIdent);
faluco@654: g_KeyValueType = 0;
faluco@654: }
faluco@654: void OnHandleDestroy(HandleType_t type, void *object)
faluco@654: {
faluco@654: KeyValueStack *pStk = reinterpret_cast(object);
faluco@654: pStk->pBase->deleteThis();
faluco@654: delete pStk;
faluco@654: }
faluco@654: };
faluco@654:
faluco@682: KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
faluco@682: {
faluco@682: HandleError herr;
faluco@682: HandleSecurity sec;
faluco@682: KeyValueStack *pStk;
faluco@682:
faluco@682: sec.pOwner = NULL;
faluco@682: sec.pIdentity = g_pCoreIdent;
faluco@682:
faluco@682: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@682: != HandleError_None)
faluco@682: {
faluco@682: if (err)
faluco@682: {
faluco@682: *err = herr;
faluco@682: }
faluco@682: return NULL;
faluco@682: }
faluco@682:
faluco@682: if (err)
faluco@682: {
faluco@682: *err = HandleError_None;
faluco@682: }
faluco@682:
faluco@682: return (root) ? pStk->pBase : pStk->pCurRoot.front();
faluco@682: }
faluco@682:
faluco@654: static cell_t smn_KvSetString(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: char *key, *value;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654: pCtx->LocalToString(params[3], &value);
faluco@654:
faluco@654: pStk->pCurRoot.front()->SetString(key, value);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvSetNum(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: char *key;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654:
faluco@654: pStk->pCurRoot.front()->SetInt(key, params[3]);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
dvander@816: static cell_t smn_KvSetUInt64(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: char *key;
faluco@654: cell_t *addr;
faluco@654: uint64 value;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654: pCtx->LocalToPhysAddr(params[3], &addr);
faluco@654:
faluco@654: value = static_cast(*addr);
faluco@654: pStk->pCurRoot.front()->SetUint64(key, value);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvSetFloat(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: char *key;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654:
faluco@654: pStk->pCurRoot.front()->SetFloat(key, sp_ctof(params[3]));
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvSetColor(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: char *key;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654:
faluco@654: Color color(params[3], params[4], params[5], params[6]);
faluco@654: pStk->pCurRoot.front()->SetColor(key, color);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvGetString(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: const char *value;
faluco@654: char *key, *defvalue;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654: pCtx->LocalToString(params[5], &defvalue);
faluco@654:
faluco@654: value = pStk->pCurRoot.front()->GetString(key, defvalue);
faluco@654: pCtx->StringToLocalUTF8(params[3], params[4], value, NULL);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvGetNum(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: int value;
faluco@654: char *key;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654:
faluco@654: value = pStk->pCurRoot.front()->GetInt(key, params[3]);
faluco@654:
faluco@654: return value;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvGetFloat(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: float value;
faluco@654: char *key;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654:
faluco@654: value = pStk->pCurRoot.front()->GetFloat(key, sp_ctof(params[3]));
faluco@654:
faluco@654: return sp_ftoc(value);
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvGetColor(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: Color color;
faluco@654: char *key;
faluco@654: cell_t *r, *g, *b, *a;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654: pCtx->LocalToPhysAddr(params[3], &r);
faluco@654: pCtx->LocalToPhysAddr(params[4], &g);
faluco@654: pCtx->LocalToPhysAddr(params[5], &b);
faluco@654: pCtx->LocalToPhysAddr(params[6], &a);
faluco@654:
faluco@654: color = pStk->pCurRoot.front()->GetColor(key);
faluco@654: *r = color.r();
faluco@654: *g = color.g();
faluco@654: *b = color.b();
faluco@654: *a = color.a();
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
dvander@816: static cell_t smn_KvGetUInt64(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: char *key;
faluco@654: cell_t *addr, *defvalue;
faluco@654: uint64 value;
dvander@1000: pCtx->LocalToStringNULL(params[2], &key);
faluco@654: pCtx->LocalToPhysAddr(params[3], &addr);
faluco@654: pCtx->LocalToPhysAddr(params[4], &defvalue);
faluco@654:
faluco@654: value = pStk->pCurRoot.front()->GetUint64(key, static_cast(*defvalue));
faluco@654: *reinterpret_cast(addr) = value;
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_CreateKeyValues(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: KeyValueStack *pStk;
faluco@654: char *name, *firstkey, *firstvalue;
faluco@654: bool is_empty;
faluco@654:
faluco@654: pCtx->LocalToString(params[1], &name);
faluco@654: pCtx->LocalToString(params[2], &firstkey);
faluco@654: pCtx->LocalToString(params[3], &firstvalue);
faluco@654:
faluco@654: is_empty = (firstkey[0] == '\0');
faluco@654: pStk = new KeyValueStack;
faluco@654: pStk->pBase = new KeyValues(name, is_empty ? NULL : firstkey, (is_empty||(firstvalue[0]=='\0')) ? NULL : firstvalue);
faluco@654: pStk->pCurRoot.push(pStk->pBase);
faluco@654:
faluco@654: return g_HandleSys.CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: char *name;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: pCtx->LocalToString(params[2], &name);
faluco@654:
dvander@726: KeyValues *pSubKey = pStk->pCurRoot.front();
dvander@726: pSubKey = pSubKey->FindKey(name, (params[3]) ? true : false);
faluco@654: if (!pSubKey)
faluco@654: {
faluco@654: return 0;
faluco@654: }
faluco@654: pStk->pCurRoot.push(pSubKey);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
dvander@753: static cell_t smn_KvGotoFirstSubKey(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: KeyValues *pSubKey = pStk->pCurRoot.front();
dvander@753: KeyValues *pFirstSubKey;
dvander@753: if (params[2])
dvander@753: {
dvander@753: pFirstSubKey = pSubKey->GetFirstTrueSubKey();
dvander@753: } else {
dvander@753: pFirstSubKey = pSubKey->GetFirstSubKey();
dvander@753: }
dvander@753:
faluco@654: if (!pFirstSubKey)
faluco@654: {
faluco@654: return 0;
faluco@654: }
faluco@654: pStk->pCurRoot.push(pFirstSubKey);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
dvander@753: static cell_t smn_KvGotoNextKey(IPluginContext *pCtx, const cell_t *params)
dvander@753: {
dvander@753: Handle_t hndl = static_cast(params[1]);
dvander@753: HandleError herr;
dvander@753: HandleSecurity sec;
dvander@753: KeyValueStack *pStk;
dvander@753:
dvander@753: sec.pOwner = NULL;
dvander@753: sec.pIdentity = g_pCoreIdent;
dvander@753:
dvander@753: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@753: != HandleError_None)
dvander@753: {
dvander@753: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@753: }
dvander@753:
dvander@753: KeyValues *pSubKey = pStk->pCurRoot.front();
dvander@753: if (params[2])
dvander@753: {
dvander@1002: pSubKey = pSubKey->GetNextTrueSubKey();
dvander@753: } else {
dvander@1002: pSubKey = pSubKey->GetNextKey();
dvander@753: }
dvander@753: if (!pSubKey)
dvander@753: {
dvander@753: return 0;
dvander@753: }
dvander@753: pStk->pCurRoot.pop();
dvander@753: pStk->pCurRoot.push(pSubKey);
dvander@753:
dvander@753: return 1;
dvander@753: }
dvander@753:
faluco@654: static cell_t smn_KvJumpNextSubKey(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: KeyValues *pSubKey = pStk->pCurRoot.front();
faluco@654: KeyValues *pNextKey = pSubKey->GetNextKey();
faluco@654: if (!pNextKey)
faluco@654: {
faluco@654: return 0;
faluco@654: }
faluco@654: pStk->pCurRoot.push(pNextKey);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvGoBack(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: if (pStk->pCurRoot.size() == 1)
faluco@654: {
faluco@654: return 0;
faluco@654: }
faluco@654: pStk->pCurRoot.pop();
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvRewind(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: while (pStk->pCurRoot.size() > 1)
faluco@654: {
faluco@654: pStk->pCurRoot.pop();
faluco@654: }
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvGetSectionName(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: KeyValues *pSection = pStk->pCurRoot.front();
faluco@654: const char *name = pSection->GetName();
faluco@654: if (!name)
faluco@654: {
faluco@654: return 0;
faluco@654: }
faluco@654: pCtx->StringToLocalUTF8(params[2], params[3], name, NULL);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvSetSectionName(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: char *name;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: pCtx->LocalToString(params[2], &name);
faluco@654:
faluco@654: KeyValues *pSection = pStk->pCurRoot.front();
faluco@654: pSection->SetName(name);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvGetDataType(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: char *name;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: pCtx->LocalToString(params[2], &name);
faluco@654:
faluco@654: return pStk->pCurRoot.front()->GetDataType(name);
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KeyValuesToFile(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: char *path;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: pCtx->LocalToString(params[2], &path);
faluco@654:
faluco@654: char realpath[PLATFORM_MAX_PATH];
faluco@654: g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
faluco@654:
faluco@654: return pStk->pCurRoot.front()->SaveToFile(basefilesystem, realpath);
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: char *path;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: pCtx->LocalToString(params[2], &path);
faluco@654:
faluco@654: char realpath[PLATFORM_MAX_PATH];
faluco@654: g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
faluco@654:
faluco@654: return pStk->pCurRoot.front()->LoadFromFile(basefilesystem, realpath);
faluco@654: }
faluco@654:
faluco@654: static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
faluco@654: {
faluco@654: Handle_t hndl = static_cast(params[1]);
faluco@654: HandleError herr;
faluco@654: HandleSecurity sec;
faluco@654: KeyValueStack *pStk;
faluco@654:
faluco@654: sec.pOwner = NULL;
faluco@654: sec.pIdentity = g_pCoreIdent;
faluco@654:
faluco@654: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654: != HandleError_None)
faluco@654: {
faluco@654: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654: }
faluco@654:
faluco@654: pStk->pCurRoot.front()->UsesEscapeSequences(params[2] ? true : false);
faluco@654:
faluco@654: return 1;
faluco@654: }
faluco@654:
dvander@750: static cell_t smn_KvNodesInStack(IPluginContext *pCtx, const cell_t *params)
dvander@750: {
dvander@750: Handle_t hndl = static_cast(params[1]);
dvander@750: HandleError herr;
dvander@750: HandleSecurity sec;
dvander@750: KeyValueStack *pStk;
dvander@750:
dvander@750: sec.pOwner = NULL;
dvander@750: sec.pIdentity = g_pCoreIdent;
dvander@750:
dvander@750: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@750: != HandleError_None)
dvander@750: {
dvander@750: return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@750: }
dvander@750:
dvander@751: return pStk->pCurRoot.size() - 1;
dvander@750: }
dvander@750:
dvander@743: static cell_t smn_KvDeleteThis(IPluginContext *pContext, const cell_t *params)
dvander@743: {
dvander@743: Handle_t hndl = static_cast(params[1]);
dvander@743: HandleError herr;
dvander@743: HandleSecurity sec;
dvander@743: KeyValueStack *pStk;
dvander@743:
dvander@743: sec.pOwner = NULL;
dvander@743: sec.pIdentity = g_pCoreIdent;
dvander@743:
dvander@743: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@743: != HandleError_None)
dvander@743: {
dvander@743: return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@743: }
dvander@743:
dvander@743: if (pStk->pCurRoot.size() < 2)
dvander@743: {
dvander@743: return 0;
dvander@743: }
dvander@743:
dvander@743: KeyValues *pValues = pStk->pCurRoot.front();
dvander@743: pStk->pCurRoot.pop();
dvander@753: KeyValues *pRoot = pStk->pCurRoot.front();
dvander@743:
dvander@753: /* We have to manually verify this since Valve sucks
dvander@753: * :TODO: make our own KeyValues.h file and make
dvander@753: * the sub stuff private so we can do this ourselves!
dvander@753: */
dvander@753: KeyValues *sub = pRoot->GetFirstSubKey();
dvander@753: while (sub)
dvander@753: {
dvander@753: if (sub == pValues)
dvander@753: {
dvander@753: KeyValues *pNext = pValues->GetNextKey();
dvander@753: pRoot->RemoveSubKey(pValues);
dvander@753: pValues->deleteThis();
dvander@753: if (pNext)
dvander@753: {
dvander@753: pStk->pCurRoot.push(pNext);
dvander@753: return 1;
dvander@753: } else {
dvander@753: return -1;
dvander@753: }
dvander@753: }
dvander@753: sub = sub->GetNextKey();
dvander@753: }
dvander@753:
dvander@753: /* Push this back on :( */
dvander@753: pStk->pCurRoot.push(pValues);
dvander@753:
dvander@753: return 0;
dvander@743: }
dvander@743:
dvander@743: static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
dvander@743: {
dvander@743: Handle_t hndl = static_cast(params[1]);
dvander@743: HandleError herr;
dvander@743: HandleSecurity sec;
dvander@743: KeyValueStack *pStk;
dvander@743:
dvander@743: sec.pOwner = NULL;
dvander@743: sec.pIdentity = g_pCoreIdent;
dvander@743:
dvander@743: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@743: != HandleError_None)
dvander@743: {
dvander@743: return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@743: }
dvander@743:
dvander@743: if (pStk->pCurRoot.size() < 2)
dvander@743: {
dvander@743: return 0;
dvander@743: }
dvander@743:
dvander@743: char *keyName;
dvander@743: pContext->LocalToString(params[2], &keyName);
dvander@743:
dvander@743: KeyValues *pRoot = pStk->pCurRoot.front();
dvander@743: KeyValues *pValues = pRoot->FindKey(keyName);
dvander@743: if (!pValues)
dvander@743: {
dvander@743: return 0;
dvander@743: }
dvander@743:
dvander@743: pRoot->RemoveSubKey(pValues);
dvander@743: pValues->deleteThis();
dvander@743:
dvander@743: return 1;
dvander@743: }
dvander@743:
dvander@753: static cell_t smn_KvSavePosition(IPluginContext *pContext, const cell_t *params)
dvander@753: {
dvander@753: Handle_t hndl = static_cast(params[1]);
dvander@753: HandleError herr;
dvander@753: HandleSecurity sec;
dvander@753: KeyValueStack *pStk;
dvander@753:
dvander@753: sec.pOwner = NULL;
dvander@753: sec.pIdentity = g_pCoreIdent;
dvander@753:
dvander@753: if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@753: != HandleError_None)
dvander@753: {
dvander@753: return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@753: }
dvander@753:
dvander@753: if (pStk->pCurRoot.size() < 2)
dvander@753: {
dvander@753: return 0;
dvander@753: }
dvander@753:
dvander@753: KeyValues *pValues = pStk->pCurRoot.front();
dvander@753: pStk->pCurRoot.push(pValues);
dvander@753:
dvander@753: return 1;
dvander@753: }
dvander@753:
faluco@703: static KeyValueNatives s_KeyValueNatives;
faluco@654:
faluco@654: REGISTER_NATIVES(keyvaluenatives)
faluco@654: {
faluco@654: {"KvSetString", smn_KvSetString},
faluco@654: {"KvSetNum", smn_KvSetNum},
dvander@816: {"KvSetUInt64", smn_KvSetUInt64},
faluco@654: {"KvSetFloat", smn_KvSetFloat},
faluco@654: {"KvSetColor", smn_KvSetColor},
faluco@654: {"KvGetString", smn_KvGetString},
faluco@654: {"KvGetNum", smn_KvGetNum},
faluco@654: {"KvGetFloat", smn_KvGetFloat},
faluco@654: {"KvGetColor", smn_KvGetColor},
dvander@816: {"KvGetUInt64", smn_KvGetUInt64},
faluco@654: {"CreateKeyValues", smn_CreateKeyValues},
faluco@654: {"KvJumpToKey", smn_KvJumpToKey},
dvander@753: {"KvGotoNextKey", smn_KvGotoNextKey},
dvander@753: {"KvJumpFirstSubKey", smn_KvGotoFirstSubKey}, /* BACKWARDS COMPAT SHIM */
dvander@753: {"KvGotoFirstSubKey", smn_KvGotoFirstSubKey},
dvander@753: {"KvJumpNextSubKey", smn_KvJumpNextSubKey}, /* BACKWARDS COMPAT SHIM */
faluco@654: {"KvGoBack", smn_KvGoBack},
faluco@654: {"KvRewind", smn_KvRewind},
faluco@654: {"KvGetSectionName", smn_KvGetSectionName},
faluco@654: {"KvSetSectionName", smn_KvSetSectionName},
faluco@654: {"KvGetDataType", smn_KvGetDataType},
faluco@654: {"KeyValuesToFile", smn_KeyValuesToFile},
faluco@654: {"FileToKeyValues", smn_FileToKeyValues},
faluco@654: {"KvSetEscapeSequences", smn_KvSetEscapeSequences},
dvander@743: {"KvDeleteThis", smn_KvDeleteThis},
dvander@743: {"KvDeleteKey", smn_KvDeleteKey},
dvander@750: {"KvNodesInStack", smn_KvNodesInStack},
dvander@753: {"KvSavePosition", smn_KvSavePosition},
faluco@654: {NULL, NULL}
faluco@654: };