faluco@654: /** faluco@654: * vim: set ts=4 : faluco@654: * =============================================================== faluco@654: * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. faluco@654: * =============================================================== faluco@654: * faluco@654: * This file is not open source and may not be copied without explicit faluco@654: * written permission of AlliedModders LLC. This file may not be redistributed faluco@654: * in whole or significant part. faluco@654: * For information, see LICENSE.txt or http://www.sourcemod.net/license.php 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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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; faluco@654: pCtx->LocalToString(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@753: pSubKey = pSubKey->GetNextKey(); dvander@753: } else { dvander@753: pSubKey = pSubKey->GetNextTrueSubKey(); 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: };