3 * =============================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "sourcemod.h"
33 #include "sourcemm_api.h"
34 #include "sm_stringutil.h"
35 #include "HandleSys.h"
36 #include <KeyValues.h>
37 #include "utlbuffer.h"
39 HandleType_t g_KeyValueType;
44 CStack<KeyValues *> pCurRoot;
47 class KeyValueNatives :
49 public IHandleTypeDispatch
52 void OnSourceModAllInitialized()
54 g_KeyValueType = g_HandleSys.CreateType("KeyValues", this, 0, NULL, NULL, g_pCoreIdent, NULL);
56 void OnSourceModShutdown()
58 g_HandleSys.RemoveType(g_KeyValueType, g_pCoreIdent);
61 void OnHandleDestroy(HandleType_t type, void *object)
63 KeyValueStack *pStk = reinterpret_cast<KeyValueStack *>(object);
64 pStk->pBase->deleteThis();
67 int CalcKVSizeR(KeyValues *pv)
72 pv->RecursiveSaveToFile(buf, 0);
73 size = buf.TellMaxPut();
79 bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
81 KeyValueStack *pStk = (KeyValueStack *)object;
82 unsigned int size = sizeof(KeyValueStack) + (pStk->pCurRoot.size() * sizeof(KeyValues *));
84 /* Check how much memory the actual thing takes up */
85 size += CalcKVSizeR(pStk->pBase);
93 KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
100 sec.pIdentity = g_pCoreIdent;
102 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
114 *err = HandleError_None;
117 return (root) ? pStk->pBase : pStk->pCurRoot.front();
120 static cell_t smn_KvSetString(IPluginContext *pCtx, const cell_t *params)
122 Handle_t hndl = static_cast<Handle_t>(params[1]);
128 sec.pIdentity = g_pCoreIdent;
130 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
133 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
137 pCtx->LocalToStringNULL(params[2], &key);
138 pCtx->LocalToString(params[3], &value);
140 pStk->pCurRoot.front()->SetString(key, value);
145 static cell_t smn_KvSetNum(IPluginContext *pCtx, const cell_t *params)
147 Handle_t hndl = static_cast<Handle_t>(params[1]);
153 sec.pIdentity = g_pCoreIdent;
155 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
158 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
162 pCtx->LocalToStringNULL(params[2], &key);
164 pStk->pCurRoot.front()->SetInt(key, params[3]);
169 static cell_t smn_KvSetUInt64(IPluginContext *pCtx, const cell_t *params)
171 Handle_t hndl = static_cast<Handle_t>(params[1]);
177 sec.pIdentity = g_pCoreIdent;
179 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
182 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
188 pCtx->LocalToStringNULL(params[2], &key);
189 pCtx->LocalToPhysAddr(params[3], &addr);
191 value = static_cast<uint64>(*addr);
192 pStk->pCurRoot.front()->SetUint64(key, value);
197 static cell_t smn_KvSetFloat(IPluginContext *pCtx, const cell_t *params)
199 Handle_t hndl = static_cast<Handle_t>(params[1]);
205 sec.pIdentity = g_pCoreIdent;
207 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
210 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
214 pCtx->LocalToStringNULL(params[2], &key);
216 pStk->pCurRoot.front()->SetFloat(key, sp_ctof(params[3]));
221 static cell_t smn_KvSetColor(IPluginContext *pCtx, const cell_t *params)
223 Handle_t hndl = static_cast<Handle_t>(params[1]);
229 sec.pIdentity = g_pCoreIdent;
231 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
234 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
238 pCtx->LocalToStringNULL(params[2], &key);
240 Color color(params[3], params[4], params[5], params[6]);
241 pStk->pCurRoot.front()->SetColor(key, color);
246 static cell_t smn_KvSetVector(IPluginContext *pCtx, const cell_t *params)
248 Handle_t hndl = static_cast<Handle_t>(params[1]);
254 sec.pIdentity = g_pCoreIdent;
256 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
259 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
265 pCtx->LocalToStringNULL(params[2], &key);
266 pCtx->LocalToPhysAddr(params[3], &vector);
268 UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(vector[0]), sp_ctof(vector[1]), sp_ctof(vector[2]));
270 pStk->pCurRoot.front()->SetString(key, buffer);
275 static cell_t smn_KvGetString(IPluginContext *pCtx, const cell_t *params)
277 Handle_t hndl = static_cast<Handle_t>(params[1]);
283 sec.pIdentity = g_pCoreIdent;
285 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
288 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
292 char *key, *defvalue;
293 pCtx->LocalToStringNULL(params[2], &key);
294 pCtx->LocalToString(params[5], &defvalue);
296 value = pStk->pCurRoot.front()->GetString(key, defvalue);
297 pCtx->StringToLocalUTF8(params[3], params[4], value, NULL);
302 static cell_t smn_KvGetNum(IPluginContext *pCtx, const cell_t *params)
304 Handle_t hndl = static_cast<Handle_t>(params[1]);
310 sec.pIdentity = g_pCoreIdent;
312 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
315 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
320 pCtx->LocalToStringNULL(params[2], &key);
322 value = pStk->pCurRoot.front()->GetInt(key, params[3]);
327 static cell_t smn_KvGetFloat(IPluginContext *pCtx, const cell_t *params)
329 Handle_t hndl = static_cast<Handle_t>(params[1]);
335 sec.pIdentity = g_pCoreIdent;
337 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
340 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
345 pCtx->LocalToStringNULL(params[2], &key);
347 value = pStk->pCurRoot.front()->GetFloat(key, sp_ctof(params[3]));
349 return sp_ftoc(value);
352 static cell_t smn_KvGetColor(IPluginContext *pCtx, const cell_t *params)
354 Handle_t hndl = static_cast<Handle_t>(params[1]);
360 sec.pIdentity = g_pCoreIdent;
362 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
365 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
370 cell_t *r, *g, *b, *a;
371 pCtx->LocalToStringNULL(params[2], &key);
372 pCtx->LocalToPhysAddr(params[3], &r);
373 pCtx->LocalToPhysAddr(params[4], &g);
374 pCtx->LocalToPhysAddr(params[5], &b);
375 pCtx->LocalToPhysAddr(params[6], &a);
377 color = pStk->pCurRoot.front()->GetColor(key);
386 static cell_t smn_KvGetUInt64(IPluginContext *pCtx, const cell_t *params)
388 Handle_t hndl = static_cast<Handle_t>(params[1]);
394 sec.pIdentity = g_pCoreIdent;
396 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
399 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
403 cell_t *addr, *defvalue;
405 pCtx->LocalToStringNULL(params[2], &key);
406 pCtx->LocalToPhysAddr(params[3], &addr);
407 pCtx->LocalToPhysAddr(params[4], &defvalue);
409 value = pStk->pCurRoot.front()->GetUint64(key, static_cast<uint64>(*defvalue));
410 *reinterpret_cast<uint64 *>(addr) = value;
415 static cell_t smn_KvGetVector(IPluginContext *pCtx, const cell_t *params)
417 Handle_t hndl = static_cast<Handle_t>(params[1]);
423 sec.pIdentity = g_pCoreIdent;
425 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
428 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
433 cell_t *defvector, *outvector;
435 pCtx->LocalToStringNULL(params[2], &key);
436 pCtx->LocalToPhysAddr(params[3], &outvector);
437 pCtx->LocalToPhysAddr(params[4], &defvector);
439 UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(defvector[0]), sp_ctof(defvector[1]), sp_ctof(defvector[2]));
441 value = pStk->pCurRoot.front()->GetString(key, buffer);
445 while (*value && components < 3)
447 while ((*value) && (*value == ' '))
464 for (; *value && isdigit(*value); ++value)
474 for (; *value && isdigit(*value); ++value)
476 out += (*value - '0') * factor;
481 out = (isnegative) ? -out : out;
482 outvector[components++] = sp_ftoc(out);
488 static cell_t smn_CreateKeyValues(IPluginContext *pCtx, const cell_t *params)
491 char *name, *firstkey, *firstvalue;
494 pCtx->LocalToString(params[1], &name);
495 pCtx->LocalToString(params[2], &firstkey);
496 pCtx->LocalToString(params[3], &firstvalue);
498 is_empty = (firstkey[0] == '\0');
499 pStk = new KeyValueStack;
500 pStk->pBase = new KeyValues(name, is_empty ? NULL : firstkey, (is_empty||(firstvalue[0]=='\0')) ? NULL : firstvalue);
501 pStk->pCurRoot.push(pStk->pBase);
503 return g_HandleSys.CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
506 static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
508 Handle_t hndl = static_cast<Handle_t>(params[1]);
515 sec.pIdentity = g_pCoreIdent;
517 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
520 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
523 pCtx->LocalToString(params[2], &name);
525 KeyValues *pSubKey = pStk->pCurRoot.front();
526 pSubKey = pSubKey->FindKey(name, (params[3]) ? true : false);
531 pStk->pCurRoot.push(pSubKey);
536 static cell_t smn_KvJumpToKeySymbol(IPluginContext *pCtx, const cell_t *params)
538 Handle_t hndl = static_cast<Handle_t>(params[1]);
544 sec.pIdentity = g_pCoreIdent;
546 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
549 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
552 KeyValues *pSubKey = pStk->pCurRoot.front();
553 pSubKey = pSubKey->FindKey(params[2]);
558 pStk->pCurRoot.push(pSubKey);
563 static cell_t smn_KvGotoFirstSubKey(IPluginContext *pCtx, const cell_t *params)
565 Handle_t hndl = static_cast<Handle_t>(params[1]);
571 sec.pIdentity = g_pCoreIdent;
573 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
576 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
579 KeyValues *pSubKey = pStk->pCurRoot.front();
580 KeyValues *pFirstSubKey;
583 pFirstSubKey = pSubKey->GetFirstTrueSubKey();
585 pFirstSubKey = pSubKey->GetFirstSubKey();
592 pStk->pCurRoot.push(pFirstSubKey);
597 static cell_t smn_KvGotoNextKey(IPluginContext *pCtx, const cell_t *params)
599 Handle_t hndl = static_cast<Handle_t>(params[1]);
605 sec.pIdentity = g_pCoreIdent;
607 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
610 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
613 KeyValues *pSubKey = pStk->pCurRoot.front();
616 pSubKey = pSubKey->GetNextTrueSubKey();
618 pSubKey = pSubKey->GetNextKey();
624 pStk->pCurRoot.pop();
625 pStk->pCurRoot.push(pSubKey);
630 static cell_t smn_KvJumpNextSubKey(IPluginContext *pCtx, const cell_t *params)
632 Handle_t hndl = static_cast<Handle_t>(params[1]);
638 sec.pIdentity = g_pCoreIdent;
640 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
643 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
646 KeyValues *pSubKey = pStk->pCurRoot.front();
647 KeyValues *pNextKey = pSubKey->GetNextKey();
652 pStk->pCurRoot.push(pNextKey);
657 static cell_t smn_KvGoBack(IPluginContext *pCtx, const cell_t *params)
659 Handle_t hndl = static_cast<Handle_t>(params[1]);
665 sec.pIdentity = g_pCoreIdent;
667 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
670 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
673 if (pStk->pCurRoot.size() == 1)
677 pStk->pCurRoot.pop();
682 static cell_t smn_KvRewind(IPluginContext *pCtx, const cell_t *params)
684 Handle_t hndl = static_cast<Handle_t>(params[1]);
690 sec.pIdentity = g_pCoreIdent;
692 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
695 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
698 while (pStk->pCurRoot.size() > 1)
700 pStk->pCurRoot.pop();
706 static cell_t smn_KvGetSectionName(IPluginContext *pCtx, const cell_t *params)
708 Handle_t hndl = static_cast<Handle_t>(params[1]);
714 sec.pIdentity = g_pCoreIdent;
716 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
719 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
722 KeyValues *pSection = pStk->pCurRoot.front();
723 const char *name = pSection->GetName();
728 pCtx->StringToLocalUTF8(params[2], params[3], name, NULL);
733 static cell_t smn_KvSetSectionName(IPluginContext *pCtx, const cell_t *params)
735 Handle_t hndl = static_cast<Handle_t>(params[1]);
742 sec.pIdentity = g_pCoreIdent;
744 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
747 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
750 pCtx->LocalToString(params[2], &name);
752 KeyValues *pSection = pStk->pCurRoot.front();
753 pSection->SetName(name);
758 static cell_t smn_KvGetDataType(IPluginContext *pCtx, const cell_t *params)
760 Handle_t hndl = static_cast<Handle_t>(params[1]);
767 sec.pIdentity = g_pCoreIdent;
769 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
772 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
775 pCtx->LocalToString(params[2], &name);
777 return pStk->pCurRoot.front()->GetDataType(name);
780 static cell_t smn_KeyValuesToFile(IPluginContext *pCtx, const cell_t *params)
782 Handle_t hndl = static_cast<Handle_t>(params[1]);
789 sec.pIdentity = g_pCoreIdent;
791 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
794 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
797 pCtx->LocalToString(params[2], &path);
799 char realpath[PLATFORM_MAX_PATH];
800 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
802 return pStk->pCurRoot.front()->SaveToFile(basefilesystem, realpath);
805 static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
807 Handle_t hndl = static_cast<Handle_t>(params[1]);
814 sec.pIdentity = g_pCoreIdent;
816 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
819 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
822 pCtx->LocalToString(params[2], &path);
824 char realpath[PLATFORM_MAX_PATH];
825 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
827 return pStk->pCurRoot.front()->LoadFromFile(basefilesystem, realpath);
830 static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
832 Handle_t hndl = static_cast<Handle_t>(params[1]);
838 sec.pIdentity = g_pCoreIdent;
840 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
843 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
846 pStk->pCurRoot.front()->UsesEscapeSequences(params[2] ? true : false);
851 static cell_t smn_KvNodesInStack(IPluginContext *pCtx, const cell_t *params)
853 Handle_t hndl = static_cast<Handle_t>(params[1]);
859 sec.pIdentity = g_pCoreIdent;
861 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
864 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
867 return pStk->pCurRoot.size() - 1;
870 static cell_t smn_KvDeleteThis(IPluginContext *pContext, const cell_t *params)
872 Handle_t hndl = static_cast<Handle_t>(params[1]);
878 sec.pIdentity = g_pCoreIdent;
880 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
883 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
886 if (pStk->pCurRoot.size() < 2)
891 KeyValues *pValues = pStk->pCurRoot.front();
892 pStk->pCurRoot.pop();
893 KeyValues *pRoot = pStk->pCurRoot.front();
895 /* We have to manually verify this since Valve sucks
896 * :TODO: make our own KeyValues.h file and make
897 * the sub stuff private so we can do this ourselves!
899 KeyValues *sub = pRoot->GetFirstSubKey();
904 KeyValues *pNext = pValues->GetNextKey();
905 pRoot->RemoveSubKey(pValues);
906 pValues->deleteThis();
909 pStk->pCurRoot.push(pNext);
915 sub = sub->GetNextKey();
918 /* Push this back on :( */
919 pStk->pCurRoot.push(pValues);
924 static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
926 Handle_t hndl = static_cast<Handle_t>(params[1]);
932 sec.pIdentity = g_pCoreIdent;
934 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
937 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
940 if (pStk->pCurRoot.size() < 2)
946 pContext->LocalToString(params[2], &keyName);
948 KeyValues *pRoot = pStk->pCurRoot.front();
949 KeyValues *pValues = pRoot->FindKey(keyName);
955 pRoot->RemoveSubKey(pValues);
956 pValues->deleteThis();
961 static cell_t smn_KvSavePosition(IPluginContext *pContext, const cell_t *params)
963 Handle_t hndl = static_cast<Handle_t>(params[1]);
969 sec.pIdentity = g_pCoreIdent;
971 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
974 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
977 if (pStk->pCurRoot.size() < 2)
982 KeyValues *pValues = pStk->pCurRoot.front();
983 pStk->pCurRoot.push(pValues);
988 static cell_t smn_CopySubkeys(IPluginContext *pContext, const cell_t *params)
990 Handle_t hndl_copied = static_cast<Handle_t>(params[1]);
991 Handle_t hndl_parent = static_cast<Handle_t>(params[2]);
994 KeyValueStack *pStk_copied, *pStk_parent;
997 sec.pIdentity = g_pCoreIdent;
999 if ((herr=g_HandleSys.ReadHandle(hndl_copied, g_KeyValueType, &sec, (void **)&pStk_copied))
1000 != HandleError_None)
1002 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_copied, herr);
1004 if ((herr=g_HandleSys.ReadHandle(hndl_parent, g_KeyValueType, &sec, (void **)&pStk_parent))
1005 != HandleError_None)
1007 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_parent, herr);
1010 pStk_copied->pCurRoot.front()->CopySubkeys(pStk_parent->pCurRoot.front());
1015 static cell_t smn_GetNameSymbol(IPluginContext *pContext, const cell_t *params)
1017 Handle_t hndl = static_cast<Handle_t>(params[1]);
1020 KeyValueStack *pStk;
1025 sec.pIdentity = g_pCoreIdent;
1027 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
1028 != HandleError_None)
1030 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
1033 if (pStk->pCurRoot.size() < 2)
1038 pContext->LocalToString(params[2], &key);
1040 KeyValues *pKv = pStk->pCurRoot.front()->FindKey(key);
1045 pContext->LocalToPhysAddr(params[3], &val);
1046 *val = pKv->GetNameSymbol();
1051 static cell_t smn_FindKeyById(IPluginContext *pContext, const cell_t *params)
1053 Handle_t hndl = static_cast<Handle_t>(params[1]);
1056 KeyValueStack *pStk;
1059 sec.pIdentity = g_pCoreIdent;
1061 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
1062 != HandleError_None)
1064 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
1067 KeyValues *pKv = pStk->pCurRoot.front()->FindKey(params[2]);
1073 pContext->StringToLocalUTF8(params[3], params[4], pKv->GetName(), NULL);
1078 static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
1080 Handle_t hndl = static_cast<Handle_t>(params[1]);
1083 KeyValueStack *pStk;
1087 sec.pIdentity = g_pCoreIdent;
1089 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
1090 != HandleError_None)
1092 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
1095 KeyValues *pSection = pStk->pCurRoot.front();
1097 pCtx->LocalToPhysAddr(params[2], &val);
1098 *val = pSection->GetNameSymbol();
1108 static KeyValueNatives s_KeyValueNatives;
1110 REGISTER_NATIVES(keyvaluenatives)
1112 {"KvSetString", smn_KvSetString},
1113 {"KvSetNum", smn_KvSetNum},
1114 {"KvSetUInt64", smn_KvSetUInt64},
1115 {"KvSetFloat", smn_KvSetFloat},
1116 {"KvSetColor", smn_KvSetColor},
1117 {"KvGetString", smn_KvGetString},
1118 {"KvGetNum", smn_KvGetNum},
1119 {"KvGetFloat", smn_KvGetFloat},
1120 {"KvGetColor", smn_KvGetColor},
1121 {"KvGetUInt64", smn_KvGetUInt64},
1122 {"CreateKeyValues", smn_CreateKeyValues},
1123 {"KvJumpToKey", smn_KvJumpToKey},
1124 {"KvJumpToKeySymbol", smn_KvJumpToKeySymbol},
1125 {"KvGotoNextKey", smn_KvGotoNextKey},
1126 {"KvJumpFirstSubKey", smn_KvGotoFirstSubKey}, /* BACKWARDS COMPAT SHIM */
1127 {"KvGotoFirstSubKey", smn_KvGotoFirstSubKey},
1128 {"KvJumpNextSubKey", smn_KvJumpNextSubKey}, /* BACKWARDS COMPAT SHIM */
1129 {"KvGoBack", smn_KvGoBack},
1130 {"KvRewind", smn_KvRewind},
1131 {"KvGetSectionName", smn_KvGetSectionName},
1132 {"KvSetSectionName", smn_KvSetSectionName},
1133 {"KvGetDataType", smn_KvGetDataType},
1134 {"KeyValuesToFile", smn_KeyValuesToFile},
1135 {"FileToKeyValues", smn_FileToKeyValues},
1136 {"KvSetEscapeSequences", smn_KvSetEscapeSequences},
1137 {"KvDeleteThis", smn_KvDeleteThis},
1138 {"KvDeleteKey", smn_KvDeleteKey},
1139 {"KvNodesInStack", smn_KvNodesInStack},
1140 {"KvSavePosition", smn_KvSavePosition},
1141 {"KvCopySubkeys", smn_CopySubkeys},
1142 {"KvFindKeyById", smn_FindKeyById},
1143 {"KvGetNameSymbol", smn_GetNameSymbol},
1144 {"KvGetSectionSymbol", smn_KvGetSectionSymbol},
1145 {"KvGetVector", smn_KvGetVector},
1146 {"KvSetVector", smn_KvSetVector},